Skip to content

Commit

Permalink
NEXT-38863 - implement new text editor component
Browse files Browse the repository at this point in the history
  • Loading branch information
jleifeld committed Dec 10, 2024
1 parent 824ee5a commit a25a47b
Show file tree
Hide file tree
Showing 25 changed files with 4,138 additions and 16 deletions.
6 changes: 6 additions & 0 deletions packages/component-library/.storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ const preview: Preview = {
{ name: "dark", value: DARK_THEME_BACKGROUND_VALUE },
],
},
options: {
storySort: (a, b) => {
// Sort the stories by their id alphabetically
return a.id === b.id ? 0 : a.id.localeCompare(b.id, undefined, { numeric: true });
}
}
},
decorators: [
ThemeProvider,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions packages/component-library/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,36 @@
"test:storybook": "test-storybook"
},
"dependencies": {
"@codemirror/lang-html": "^6.4.9",
"@floating-ui/dom": "^1.4.3",
"@shopware-ag/meteor-icon-kit": "workspace:*",
"@shopware-ag/meteor-tokens": "workspace:*",
"@storybook/addon-a11y": "^8.1.1",
"@testing-library/jest-dom": "^6.4.6",
"@testing-library/vue": "^8.1.0",
"@tiptap/extension-bubble-menu": "^2.10.0",
"@tiptap/extension-bullet-list": "^2.10.0",
"@tiptap/extension-character-count": "^2.10.0",
"@tiptap/extension-color": "^2.9.1",
"@tiptap/extension-highlight": "^2.10.3",
"@tiptap/extension-link": "^2.10.0",
"@tiptap/extension-list-item": "^2.10.0",
"@tiptap/extension-ordered-list": "^2.10.0",
"@tiptap/extension-subscript": "^2.9.1",
"@tiptap/extension-superscript": "^2.9.1",
"@tiptap/extension-table": "^2.10.3",
"@tiptap/extension-table-cell": "^2.10.3",
"@tiptap/extension-table-header": "^2.10.3",
"@tiptap/extension-table-row": "^2.10.3",
"@tiptap/extension-text-align": "^2.9.1",
"@tiptap/extension-text-style": "^2.9.1",
"@tiptap/extension-underline": "^2.9.1",
"@tiptap/pm": "^2.9.1",
"@tiptap/starter-kit": "^2.9.1",
"@tiptap/vue-3": "^2.9.1",
"@vueuse/components": "^10.7.2",
"@vueuse/core": "^10.7.2",
"codemirror": "^6.0.1",
"date-fns": "^2.30.0",
"date-fns-tz": "^2.0.0",
"flatpickr": "4.6.13",
Expand All @@ -45,6 +67,7 @@
"lodash-es": "^4.17.21",
"nanoid": "^5.0.7",
"vue": "3.4.21",
"vue-codemirror6": "^1.3.8",
"vue-i18n": "^9.9.1",
"vue-smooth-reflow": "^0.1.12"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,10 @@ $mt-field-transition:
margin-bottom: 12px;
}
&.is--disabled {
cursor: not-allowed;
}
&__hint-wrapper {
display: flex;
justify-content: space-between;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { within, userEvent, fireEvent } from "@storybook/test";
import { expect } from "@storybook/test";

import meta, { type MtColorpickerMeta, type MtColorpickerStory } from "./mt-colorpicker.stories";
import { waitUntil } from "@/_internal/test-helper";

export default {
...meta,
Expand Down Expand Up @@ -56,6 +57,186 @@ export const VisualTestOpenColorpicker: MtColorpickerStory = {
},
};

export const VisualTestOpenColorpickerWithApplyMode: MtColorpickerStory = {
name: "Open colorpicker with apply mode",
args: {
modelValue: "rgba(72, 228, 37, 0.81)",
applyMode: true,
colorOutput: "rgb",
},
play: async ({ canvasElement, args }) => {
const canvas = within(canvasElement);

const pickerToggle = canvas.getByLabelText("colorpicker-toggle");

await userEvent.click(pickerToggle);

// Look inside the popover
const popover = within(
document.getElementsByClassName("mt-floating-ui__content")[0] as HTMLElement,
);

const colorRange = popover.getByLabelText("colorpicker-color-range") as HTMLInputElement;
const alphaRange = popover.getByLabelText("colorpicker-alpha-range") as HTMLInputElement;
const hexInput = popover.getByLabelText("hex-value") as HTMLInputElement;
const redInput = popover.getByLabelText("red-value") as HTMLInputElement;
const greenInput = popover.getByLabelText("green-value") as HTMLInputElement;
const blueInput = popover.getByLabelText("blue-value") as HTMLInputElement;
const alphaInput = popover.getByLabelText("alpha-value") as HTMLInputElement;

expect(colorRange).toBeDefined();
expect(colorRange.value).toEqual("109");
expect(alphaRange).toBeDefined();
expect(alphaRange.value).toEqual("0.81");

expect(hexInput).toBeDefined();
expect(hexInput.value).toEqual("#48e425cf");
expect(redInput).toBeDefined();
expect(redInput.value).toEqual("72");
expect(greenInput).toBeDefined();
expect(greenInput.value).toEqual("228");
expect(blueInput).toBeDefined();
expect(blueInput.value).toEqual("37");
expect(alphaInput).toBeDefined();
expect(alphaInput.value).toEqual("81");

// Check for apply button
const applyButton = popover.getByLabelText("colorpicker-apply-color") as HTMLButtonElement;
expect(applyButton).toBeDefined();
},
};

export const TestOpenColorpickerWithApplyMode: MtColorpickerStory = {
name: "Use colorpicker with apply mode",
args: {
modelValue: "rgba(72, 228, 37, 0.81)",
applyMode: true,
colorOutput: "rgb",
},
play: async ({ canvasElement, args }) => {
const canvas = within(canvasElement);

const pickerToggle = canvas.getByLabelText("colorpicker-toggle");

await userEvent.click(pickerToggle);

// Look inside the popover
const popover = within(
document.getElementsByClassName("mt-floating-ui__content")[0] as HTMLElement,
);

const colorRange = popover.getByLabelText("colorpicker-color-range") as HTMLInputElement;
const alphaRange = popover.getByLabelText("colorpicker-alpha-range") as HTMLInputElement;
const hexInput = popover.getByLabelText("hex-value") as HTMLInputElement;
const redInput = popover.getByLabelText("red-value") as HTMLInputElement;
const greenInput = popover.getByLabelText("green-value") as HTMLInputElement;
const blueInput = popover.getByLabelText("blue-value") as HTMLInputElement;
const alphaInput = popover.getByLabelText("alpha-value") as HTMLInputElement;

expect(colorRange).toBeDefined();
expect(colorRange.value).toEqual("109");
expect(alphaRange).toBeDefined();
expect(alphaRange.value).toEqual("0.81");

expect(hexInput).toBeDefined();
expect(hexInput.value).toEqual("#48e425cf");
expect(redInput).toBeDefined();
expect(redInput.value).toEqual("72");
expect(greenInput).toBeDefined();
expect(greenInput.value).toEqual("228");
expect(blueInput).toBeDefined();
expect(blueInput.value).toEqual("37");
expect(alphaInput).toBeDefined();
expect(alphaInput.value).toEqual("81");

// Check for apply button
const applyButton = popover.getByLabelText("colorpicker-apply-color") as HTMLButtonElement;
expect(applyButton).toBeDefined();

// Change colors
fireEvent.input(colorRange, { target: { value: 300 } });
fireEvent.input(alphaRange, { target: { value: 0.5 } });

// Apply changes
await userEvent.click(applyButton);

// Wait until the popover is closed
await waitUntil(() => {
return document.getElementsByClassName("mt-floating-ui__content").length === 0;
});

// Check if the color is applied
expect(args.updateModelValue).toHaveBeenCalledWith("rgba(228, 37, 228, 0.5)");
},
};

export const ResetsColorInApplyMode: MtColorpickerStory = {
name: "Resets color in apply mode when closed without applying",
args: {
modelValue: "rgba(72, 228, 37, 0.81)",
applyMode: true,
colorOutput: "rgb",
},
play: async ({ canvasElement, args }) => {
const canvas = within(canvasElement);

const pickerToggle = canvas.getByLabelText("colorpicker-toggle");

await userEvent.click(pickerToggle);

// Look inside the popover
const popover = within(
document.getElementsByClassName("mt-floating-ui__content")[0] as HTMLElement,
);

const colorRange = popover.getByLabelText("colorpicker-color-range") as HTMLInputElement;
const alphaRange = popover.getByLabelText("colorpicker-alpha-range") as HTMLInputElement;
const hexInput = popover.getByLabelText("hex-value") as HTMLInputElement;
const redInput = popover.getByLabelText("red-value") as HTMLInputElement;
const greenInput = popover.getByLabelText("green-value") as HTMLInputElement;
const blueInput = popover.getByLabelText("blue-value") as HTMLInputElement;
const alphaInput = popover.getByLabelText("alpha-value") as HTMLInputElement;

expect(colorRange).toBeDefined();
expect(colorRange.value).toEqual("109");
expect(alphaRange).toBeDefined();
expect(alphaRange.value).toEqual("0.81");

expect(hexInput).toBeDefined();
expect(hexInput.value).toEqual("#48e425cf");
expect(redInput).toBeDefined();
expect(redInput.value).toEqual("72");
expect(greenInput).toBeDefined();
expect(greenInput.value).toEqual("228");
expect(blueInput).toBeDefined();
expect(blueInput.value).toEqual("37");
expect(alphaInput).toBeDefined();
expect(alphaInput.value).toEqual("81");

// Check for apply button
const applyButton = popover.getByLabelText("colorpicker-apply-color") as HTMLButtonElement;
expect(applyButton).toBeDefined();

// Change colors
fireEvent.input(colorRange, { target: { value: 300 } });
fireEvent.input(alphaRange, { target: { value: 0.5 } });

const colorpickerInputField = (canvas.getByLabelText("colorpicker-color-value") as HTMLInputElement)

// Close popover without applying
await userEvent.click(colorpickerInputField);

// Wait until the popover is closed
await waitUntil(() => {
return document.getElementsByClassName("mt-floating-ui__content").length === 0;
});

// Check if the color is resetted
expect(args.updateModelValue).not.toHaveBeenCalled();
expect(colorpickerInputField.value).toEqual("rgba(72, 228, 37, 0.81)");
},
};

export const VisualTestChangeColorpickerColor: MtColorpickerStory = {
name: "Change colorpicker color",
args: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
import MtColorpicker from "./mt-colorpicker.vue";
import type { StoryObj } from "@storybook/vue3";
import type { SlottedMeta } from "@/_internal/story-helper";
import { ref } from "vue";

export type MtColorpickerMeta = SlottedMeta<typeof MtColorpicker, "default">;
export type MtColorpickerMeta = SlottedMeta<typeof MtColorpicker, "default" | "updateModelValue">;

export default {
title: "Components/Form/mt-colorpicker",
component: MtColorpicker,
render: (args) => ({
components: { MtColorpicker },
template: '<mt-colorpicker v-bind="args"></mt-colorpicker>',
template: `<mt-colorpicker
v-bind="args"
:modelValue="currentModelValue"
@update:modelValue="onUpdateModelValue"
></mt-colorpicker>`,
setup: () => {
const currentModelValue = ref(args.modelValue);
const onUpdateModelValue = (value: string) => {
currentModelValue.value = value;
args.updateModelValue(value);
}

return {
args,
currentModelValue,
onUpdateModelValue,
};
},
}),
Expand All @@ -30,7 +43,16 @@ export default {
isInherited: false,
isInheritanceField: false,
disableInheritanceToggle: false,
compact: false,
},
argTypes: {
updateModelValue: {
action: "updateModelValue",
table: {
category: "Events",
},
},
}
} as MtColorpickerMeta;

export type MtColorpickerStory = StoryObj<MtColorpickerMeta>;
Expand Down
Loading

0 comments on commit a25a47b

Please sign in to comment.