@kaizen/components 1.48.0 → 1.49.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/DateInput/DateInput/DateInput.cjs +1 -0
- package/dist/cjs/DatePicker/DatePicker.cjs +7 -3
- package/dist/cjs/DateRangePicker/DateRangePicker.cjs +7 -2
- package/dist/cjs/EmptyState/EmptyState.cjs +0 -1
- package/dist/cjs/RichTextEditor/EditableRichTextContent/EditableRichTextContent.cjs +1 -0
- package/dist/cjs/RichTextEditor/EditableRichTextContent/EditableRichTextContent.module.scss.cjs +1 -0
- package/dist/cjs/RichTextEditor/RichTextEditor/RichTextEditor.cjs +1 -0
- package/dist/cjs/RichTextEditor/RichTextEditor/RichTextEditor.module.scss.cjs +1 -0
- package/dist/cjs/RichTextEditor/utils/plugins/LinkManager/components/LinkModal/LinkModal.cjs +5 -1
- package/dist/cjs/RichTextEditor/utils/plugins/LinkManager/components/LinkModal/LinkModal.module.scss.cjs +6 -0
- package/dist/cjs/RichTextEditor/utils/plugins/LinkManager/validation.cjs +8 -1
- package/dist/cjs/Select/Select.cjs +6 -2
- package/dist/cjs/__future__/Select/Select.cjs +12 -11
- package/dist/esm/DateInput/DateInput/DateInput.mjs +1 -0
- package/dist/esm/DatePicker/DatePicker.mjs +7 -3
- package/dist/esm/DateRangePicker/DateRangePicker.mjs +7 -2
- package/dist/esm/EmptyState/EmptyState.mjs +0 -1
- package/dist/esm/RichTextEditor/EditableRichTextContent/EditableRichTextContent.mjs +3 -2
- package/dist/esm/RichTextEditor/EditableRichTextContent/EditableRichTextContent.module.scss.mjs +1 -0
- package/dist/esm/RichTextEditor/RichTextEditor/RichTextEditor.mjs +3 -2
- package/dist/esm/RichTextEditor/RichTextEditor/RichTextEditor.module.scss.mjs +1 -0
- package/dist/esm/RichTextEditor/utils/plugins/LinkManager/components/LinkModal/LinkModal.mjs +5 -1
- package/dist/esm/RichTextEditor/utils/plugins/LinkManager/components/LinkModal/LinkModal.module.scss.mjs +4 -0
- package/dist/esm/RichTextEditor/utils/plugins/LinkManager/validation.mjs +2 -1
- package/dist/esm/Select/Select.mjs +6 -2
- package/dist/esm/__future__/Select/Select.mjs +12 -11
- package/dist/styles.css +9 -8
- package/dist/types/Input/Input/Input.d.ts +5 -0
- package/dist/types/RichTextEditor/utils/plugins/LinkManager/validation.d.ts +1 -0
- package/dist/types/Select/Select.d.ts +10 -0
- package/dist/types/TextArea/TextArea.d.ts +5 -0
- package/dist/types/__future__/Select/Select.d.ts +5 -0
- package/dist/types/__future__/Select/subcomponents/SelectToggle/SelectToggle.d.ts +8 -0
- package/package.json +6 -6
- package/src/DateInput/DateInput/DateInput.tsx +1 -0
- package/src/DatePicker/DatePicker.spec.tsx +14 -14
- package/src/DatePicker/DatePicker.tsx +20 -11
- package/src/DateRangePicker/DateRangePicker.tsx +14 -2
- package/src/DateRangePicker/_docs/DateRangePicker.mdx +5 -1
- package/src/DateRangePicker/_docs/DateRangePicker.stories.tsx +99 -3
- package/src/EmptyState/EmptyState.tsx +1 -4
- package/src/FieldGroup/_docs/FieldGroup.stickersheet.stories.tsx +2 -12
- package/src/FieldGroup/_docs/FieldGroup.stories.tsx +4 -9
- package/src/Input/Input/Input.tsx +5 -0
- package/src/Input/InputSearch/InputSearch.spec.tsx +10 -7
- package/src/Notification/ToastNotification/ToastNotificationsList/ToastNotificationsList.module.scss +1 -1
- package/src/RichTextEditor/EditableRichTextContent/EditableRichTextContent.module.scss +25 -7
- package/src/RichTextEditor/EditableRichTextContent/EditableRichTextContent.tsx +3 -1
- package/src/RichTextEditor/EditableRichTextContent/_docs/EditableRichTextContent.mdx +6 -4
- package/src/RichTextEditor/EditableRichTextContent/_docs/EditableRichTextContent.stickersheet.stories.tsx +98 -0
- package/src/RichTextEditor/EditableRichTextContent/_docs/EditableRichTextContent.stories.tsx +8 -5
- package/src/RichTextEditor/EditableRichTextContent/_docs/defaultContent.json +11 -0
- package/src/RichTextEditor/EditableRichTextContent/_docs/dummyContent.json +44 -39
- package/src/RichTextEditor/RichTextContent/_docs/RichTextContent.mdx +11 -1
- package/src/RichTextEditor/RichTextContent/_docs/RichTextContent.stories.tsx +47 -2
- package/src/RichTextEditor/RichTextEditor/RichTextEditor.module.scss +6 -1
- package/src/RichTextEditor/RichTextEditor/RichTextEditor.spec.stories.tsx +48 -0
- package/src/RichTextEditor/RichTextEditor/RichTextEditor.tsx +7 -2
- package/src/RichTextEditor/RichTextEditor/_docs/RichTextEditor.mdx +66 -7
- package/src/RichTextEditor/RichTextEditor/_docs/RichTextEditor.stories.tsx +60 -7
- package/src/RichTextEditor/_mixins.scss +1 -0
- package/src/RichTextEditor/utils/plugins/LinkManager/components/LinkModal/LinkModal.module.scss +5 -0
- package/src/RichTextEditor/utils/plugins/LinkManager/components/LinkModal/LinkModal.spec.stories.tsx +37 -0
- package/src/RichTextEditor/utils/plugins/LinkManager/components/LinkModal/LinkModal.stories.tsx +33 -0
- package/src/RichTextEditor/utils/plugins/LinkManager/components/LinkModal/LinkModal.tsx +9 -1
- package/src/RichTextEditor/utils/plugins/LinkManager/{validation.ts → validation.tsx} +11 -1
- package/src/Select/Select.tsx +9 -1
- package/src/Select/_docs/Select.stories.tsx +0 -3
- package/src/TextArea/TextArea.tsx +5 -0
- package/src/__future__/Select/Select.tsx +6 -1
- package/src/__future__/Select/_docs/Select.stickersheet.stories.tsx +0 -9
- package/src/__future__/Select/subcomponents/SelectToggle/SelectToggle.tsx +4 -0
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
setFocusInCalendar,
|
|
17
17
|
} from "~components/Calendar"
|
|
18
18
|
import { CalendarPopover } from "~components/Calendar/CalendarPopover"
|
|
19
|
+
import { VisuallyHidden } from "~components/VisuallyHidden"
|
|
19
20
|
import {
|
|
20
21
|
DateInputField,
|
|
21
22
|
DateInputFieldProps,
|
|
@@ -305,17 +306,25 @@ export const DatePicker = ({
|
|
|
305
306
|
</div>
|
|
306
307
|
|
|
307
308
|
{isOpen && (
|
|
308
|
-
<CalendarPopover
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
309
|
+
<CalendarPopover
|
|
310
|
+
referenceElement={containerRef.current}
|
|
311
|
+
aria-labelledby={`${id}-calendar-label ${id}-input-label`}
|
|
312
|
+
>
|
|
313
|
+
<>
|
|
314
|
+
<VisuallyHidden id={`${id}-calendar-label`}>
|
|
315
|
+
Select date from calendar for:
|
|
316
|
+
</VisuallyHidden>
|
|
317
|
+
<CalendarSingle
|
|
318
|
+
id={calendarId}
|
|
319
|
+
selected={selectedDay}
|
|
320
|
+
defaultMonth={defaultMonth}
|
|
321
|
+
weekStartsOn={weekStartsOn}
|
|
322
|
+
disabled={disabledDays}
|
|
323
|
+
locale={locale}
|
|
324
|
+
onDayClick={handleCalendarDayChange}
|
|
325
|
+
onMount={handleCalendarMount}
|
|
326
|
+
/>
|
|
327
|
+
</>
|
|
319
328
|
</CalendarPopover>
|
|
320
329
|
)}
|
|
321
330
|
</FocusOn>
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from "~components/Calendar/LegacyCalendarRange"
|
|
16
16
|
import { DateStartIcon } from "~components/Icon"
|
|
17
17
|
import { Label } from "~components/Label"
|
|
18
|
+
import { VisuallyHidden } from "~components/VisuallyHidden"
|
|
18
19
|
import styles from "./DateRangePicker.module.scss"
|
|
19
20
|
|
|
20
21
|
export type DateRangePickerProps = {
|
|
@@ -146,7 +147,12 @@ export const DateRangePicker = ({
|
|
|
146
147
|
return (
|
|
147
148
|
<div>
|
|
148
149
|
<div ref={containerRef} className={classNameOverride}>
|
|
149
|
-
<Label
|
|
150
|
+
<Label
|
|
151
|
+
id={`${id}-input-label`}
|
|
152
|
+
disabled={isDisabled}
|
|
153
|
+
htmlFor={id}
|
|
154
|
+
labelText={labelText}
|
|
155
|
+
/>
|
|
150
156
|
<button
|
|
151
157
|
type="button"
|
|
152
158
|
id={id}
|
|
@@ -178,7 +184,13 @@ export const DateRangePicker = ({
|
|
|
178
184
|
onEscapeKey={handleOpenClose}
|
|
179
185
|
enabled={isOpen}
|
|
180
186
|
>
|
|
181
|
-
<CalendarPopover
|
|
187
|
+
<CalendarPopover
|
|
188
|
+
referenceElement={containerRef.current}
|
|
189
|
+
aria-labelledby={`${id}-calendar-label ${id}-input-label`}
|
|
190
|
+
>
|
|
191
|
+
<VisuallyHidden id={`${id}-calendar-label`}>
|
|
192
|
+
Select dates from calendar for:
|
|
193
|
+
</VisuallyHidden>
|
|
182
194
|
<LegacyCalendarRange
|
|
183
195
|
selectedRange={selectedDateRange}
|
|
184
196
|
defaultMonth={defaultMonth}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Canvas, Controls, Meta } from "@storybook/blocks"
|
|
1
|
+
import { Canvas, DocsStory, Controls, Meta } from "@storybook/blocks"
|
|
2
2
|
import { ResourceLinks, KAIOInstallation } from "~storybook/components"
|
|
3
3
|
import * as DateRangePickerStories from "./DateRangePicker.stories"
|
|
4
4
|
|
|
@@ -28,3 +28,7 @@ Date range picker form field.
|
|
|
28
28
|
## Responsive behaviour
|
|
29
29
|
|
|
30
30
|
As both the `DatePicker` and `DateRangePicker` use the `CalendarPopover` component under the hood, they share the same responsive behaviour. You can read more on this [here](/docs/components-date-controls-datepicker--docs#responsive-behaviour).
|
|
31
|
+
|
|
32
|
+
<DocsStory of={DateRangePickerStories.AboveIfAvailable} />
|
|
33
|
+
<DocsStory of={DateRangePickerStories.LimitedViewportHeight} />
|
|
34
|
+
<DocsStory of={DateRangePickerStories.FullViewportHeight} />
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useState } from "react"
|
|
2
2
|
import { Meta, StoryObj } from "@storybook/react"
|
|
3
|
-
import { fn } from "@storybook/test"
|
|
3
|
+
import { userEvent, within, expect, fn } from "@storybook/test"
|
|
4
4
|
import { DateRange } from "react-day-picker"
|
|
5
5
|
import { DateRangePicker, formatDateRangeValue } from "../index"
|
|
6
6
|
|
|
@@ -20,8 +20,8 @@ type Story = StoryObj<typeof meta>
|
|
|
20
20
|
const DateRangePickerTemplate: Story = {
|
|
21
21
|
render: args => {
|
|
22
22
|
const [selectedDateRange, setSelectedDateRange] = useState<DateRange>({
|
|
23
|
-
from:
|
|
24
|
-
to:
|
|
23
|
+
from: args?.selectedDateRange?.from,
|
|
24
|
+
to: args?.selectedDateRange?.to,
|
|
25
25
|
})
|
|
26
26
|
const [value, setValue] = useState(args.value)
|
|
27
27
|
|
|
@@ -58,3 +58,99 @@ export const Playground: Story = {
|
|
|
58
58
|
},
|
|
59
59
|
},
|
|
60
60
|
}
|
|
61
|
+
|
|
62
|
+
const selectedDateRange = {
|
|
63
|
+
from: new Date(2022, 2, 6),
|
|
64
|
+
to: new Date(2022, 2, 15),
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const AboveIfAvailable: Story = {
|
|
68
|
+
...DateRangePickerTemplate,
|
|
69
|
+
name: "Limited viewport autoplacement above",
|
|
70
|
+
args: {
|
|
71
|
+
labelText: "Calendar with space above",
|
|
72
|
+
selectedDateRange,
|
|
73
|
+
},
|
|
74
|
+
parameters: {
|
|
75
|
+
viewport: {
|
|
76
|
+
viewports: {
|
|
77
|
+
LimitedViewportAutoPlace: {
|
|
78
|
+
name: "Limited vertical space",
|
|
79
|
+
styles: {
|
|
80
|
+
width: "1024px",
|
|
81
|
+
height: "500px",
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
defaultViewport: "LimitedViewportAutoPlace",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
decorators: [
|
|
89
|
+
Story => (
|
|
90
|
+
<div className="mt-[350px]">
|
|
91
|
+
<Story />
|
|
92
|
+
</div>
|
|
93
|
+
),
|
|
94
|
+
],
|
|
95
|
+
play: async ({ canvasElement }) => {
|
|
96
|
+
const canvas = within(canvasElement)
|
|
97
|
+
await userEvent.click(canvas.getByRole("button", { name: /Change date:/ }))
|
|
98
|
+
await expect(canvas.getByRole("dialog")).toBeInTheDocument()
|
|
99
|
+
},
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export const LimitedViewportHeight: Story = {
|
|
103
|
+
...DateRangePickerTemplate,
|
|
104
|
+
name: "Limited viewport height",
|
|
105
|
+
args: {
|
|
106
|
+
labelText: "Calendar with reduced space below",
|
|
107
|
+
selectedDateRange,
|
|
108
|
+
},
|
|
109
|
+
parameters: {
|
|
110
|
+
viewport: {
|
|
111
|
+
viewports: {
|
|
112
|
+
LimitedViewportHeight: {
|
|
113
|
+
name: "Limited vertical space",
|
|
114
|
+
styles: {
|
|
115
|
+
width: "1024px",
|
|
116
|
+
height: "300px",
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
defaultViewport: "LimitedViewportHeight",
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
decorators: [
|
|
124
|
+
Story => (
|
|
125
|
+
<div className="mb-[150px]">
|
|
126
|
+
<Story />
|
|
127
|
+
</div>
|
|
128
|
+
),
|
|
129
|
+
],
|
|
130
|
+
play: async ({ canvasElement }) => {
|
|
131
|
+
const canvas = within(canvasElement)
|
|
132
|
+
await userEvent.click(canvas.getByRole("button", { name: /Change date:/ }))
|
|
133
|
+
await expect(canvas.getByRole("dialog")).toBeInTheDocument()
|
|
134
|
+
},
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export const FullViewportHeight: Story = {
|
|
138
|
+
...DateRangePickerTemplate,
|
|
139
|
+
name: "Full viewport height",
|
|
140
|
+
args: {
|
|
141
|
+
labelText: "Calendar with full space below",
|
|
142
|
+
selectedDateRange,
|
|
143
|
+
},
|
|
144
|
+
decorators: [
|
|
145
|
+
Story => (
|
|
146
|
+
<div className="mb-[350px]">
|
|
147
|
+
<Story />
|
|
148
|
+
</div>
|
|
149
|
+
),
|
|
150
|
+
],
|
|
151
|
+
play: async ({ canvasElement }) => {
|
|
152
|
+
const canvas = within(canvasElement)
|
|
153
|
+
await userEvent.click(canvas.getByRole("button", { name: /Change date:/ }))
|
|
154
|
+
await expect(canvas.getByRole("dialog")).toBeInTheDocument()
|
|
155
|
+
},
|
|
156
|
+
}
|
|
@@ -84,10 +84,7 @@ export const EmptyState = ({
|
|
|
84
84
|
classNameOverride={styles.illustration}
|
|
85
85
|
/>
|
|
86
86
|
) : (
|
|
87
|
-
<IllustrationComponent
|
|
88
|
-
alt={illustrationType}
|
|
89
|
-
classNameOverride={styles.illustration}
|
|
90
|
-
/>
|
|
87
|
+
<IllustrationComponent classNameOverride={styles.illustration} />
|
|
91
88
|
)}
|
|
92
89
|
</div>
|
|
93
90
|
<div className={styles.textSide}>
|
|
@@ -25,21 +25,11 @@ const FieldGroupTemplate = ({
|
|
|
25
25
|
<div>
|
|
26
26
|
<FieldGroup inline={inline} classNameOverride="mr-6">
|
|
27
27
|
<Label htmlFor={`id--field-${id}`}>Email</Label>
|
|
28
|
-
<input
|
|
29
|
-
className="border border-gray-500"
|
|
30
|
-
placeholder="Native text input..."
|
|
31
|
-
type="text"
|
|
32
|
-
id="id--field-2"
|
|
33
|
-
/>
|
|
28
|
+
<input className="border border-gray-500" type="text" id="id--field-2" />
|
|
34
29
|
</FieldGroup>
|
|
35
30
|
<FieldGroup inline={inline}>
|
|
36
31
|
<Label htmlFor={`id--field-${id}`}>Username</Label>
|
|
37
|
-
<input
|
|
38
|
-
className="border border-gray-500"
|
|
39
|
-
placeholder="Native text input..."
|
|
40
|
-
type="text"
|
|
41
|
-
id="id--field-2"
|
|
42
|
-
/>
|
|
32
|
+
<input className="border border-gray-500" type="text" id="id--field-2" />
|
|
43
33
|
</FieldGroup>
|
|
44
34
|
</div>
|
|
45
35
|
)
|
|
@@ -12,7 +12,6 @@ const meta = {
|
|
|
12
12
|
<Label htmlFor="id--field-1">Email</Label>
|
|
13
13
|
<input
|
|
14
14
|
className="ms-6 border border-gray-500"
|
|
15
|
-
placeholder="Native text input..."
|
|
16
15
|
type="text"
|
|
17
16
|
id="id--field-1"
|
|
18
17
|
/>
|
|
@@ -42,16 +41,14 @@ export const Inline: Story = {
|
|
|
42
41
|
<Label htmlFor="id--field-1">Email</Label>
|
|
43
42
|
<input
|
|
44
43
|
className="ms-6 border border-gray-500"
|
|
45
|
-
placeholder="Native text input..."
|
|
46
44
|
type="text"
|
|
47
|
-
id="id--field-
|
|
45
|
+
id="id--field-1"
|
|
48
46
|
/>
|
|
49
47
|
</FieldGroup>
|
|
50
48
|
<FieldGroup inline>
|
|
51
|
-
<Label htmlFor="id--field-
|
|
49
|
+
<Label htmlFor="id--field-2">Username</Label>
|
|
52
50
|
<input
|
|
53
51
|
className="ms-6 border border-gray-500"
|
|
54
|
-
placeholder="Native text input..."
|
|
55
52
|
type="text"
|
|
56
53
|
id="id--field-2"
|
|
57
54
|
/>
|
|
@@ -67,16 +64,14 @@ export const Default: Story = {
|
|
|
67
64
|
<Label htmlFor="id--field-1">Email</Label>
|
|
68
65
|
<input
|
|
69
66
|
className="ms-6 border border-gray-500"
|
|
70
|
-
placeholder="Native text input..."
|
|
71
67
|
type="text"
|
|
72
|
-
id="id--field-
|
|
68
|
+
id="id--field-1"
|
|
73
69
|
/>
|
|
74
70
|
</FieldGroup>
|
|
75
71
|
<FieldGroup>
|
|
76
|
-
<Label htmlFor="id--field-
|
|
72
|
+
<Label htmlFor="id--field-2">Username</Label>
|
|
77
73
|
<input
|
|
78
74
|
className="ms-6 border border-gray-500"
|
|
79
|
-
placeholder="Native text input..."
|
|
80
75
|
type="text"
|
|
81
76
|
id="id--field-2"
|
|
82
77
|
/>
|
|
@@ -14,6 +14,11 @@ export type InputProps = {
|
|
|
14
14
|
endIconAdornment?: React.ReactNode
|
|
15
15
|
reversed?: boolean
|
|
16
16
|
type?: InputType
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated Use of placeholder text goes against our a11y standards.
|
|
19
|
+
* Use the `labelText` prop to provide a concise name, and the `description` prop for any help text.
|
|
20
|
+
*/
|
|
21
|
+
placeholder?: string
|
|
17
22
|
} & OverrideClassName<InputHTMLAttributes<HTMLInputElement>>
|
|
18
23
|
|
|
19
24
|
export const Input = ({
|
|
@@ -12,10 +12,12 @@ const defaultInputProps = {
|
|
|
12
12
|
onChange: jest.fn(),
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const renderInput = (
|
|
15
|
+
const renderInput = (
|
|
16
|
+
props?: Omit<InputSearchProps, "id">
|
|
17
|
+
): ReturnType<typeof render> => {
|
|
16
18
|
const mergedInputProps = { ...defaultInputProps, ...props }
|
|
17
19
|
|
|
18
|
-
return render(<InputSearch {...mergedInputProps} />)
|
|
20
|
+
return render(<InputSearch {...mergedInputProps} data-testid="someInputId" />)
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
describe("<InputSearch />", () => {
|
|
@@ -28,9 +30,10 @@ describe("<InputSearch />", () => {
|
|
|
28
30
|
})
|
|
29
31
|
|
|
30
32
|
it("should call the `onChange` event when text value is updated", async () => {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
const utils = renderInput({
|
|
34
|
+
value: "",
|
|
35
|
+
})
|
|
36
|
+
const input = utils.getByTestId("someInputId")
|
|
34
37
|
|
|
35
38
|
await user.type(input, "Hello")
|
|
36
39
|
await waitFor(() => {
|
|
@@ -39,12 +42,12 @@ describe("<InputSearch />", () => {
|
|
|
39
42
|
})
|
|
40
43
|
|
|
41
44
|
it("should render a disabled inside of input", () => {
|
|
42
|
-
const { container } = renderInput({ disabled: true
|
|
45
|
+
const { container } = renderInput({ disabled: true })
|
|
43
46
|
expect(container.querySelector("[disabled]")).toBeTruthy()
|
|
44
47
|
})
|
|
45
48
|
|
|
46
49
|
it("should render a reversed input", () => {
|
|
47
|
-
const { container } = renderInput({ reversed: true
|
|
50
|
+
const { container } = renderInput({ reversed: true })
|
|
48
51
|
expect(container.querySelector(".reversed")).toBeTruthy()
|
|
49
52
|
})
|
|
50
53
|
})
|
|
@@ -2,25 +2,43 @@
|
|
|
2
2
|
@import "~@kaizen/design-tokens/sass/border";
|
|
3
3
|
@import "~@kaizen/design-tokens/sass/color";
|
|
4
4
|
@import "~@kaizen/design-tokens/sass/spacing";
|
|
5
|
+
@import "~@kaizen/design-tokens/sass/typography";
|
|
6
|
+
|
|
7
|
+
.editorLabel {
|
|
8
|
+
margin-bottom: $spacing-6;
|
|
9
|
+
display: inline-block;
|
|
10
|
+
}
|
|
5
11
|
|
|
6
12
|
.editableContainer :global(.ProseMirror) {
|
|
7
|
-
padding: $spacing-
|
|
13
|
+
padding: calc($spacing-12 - $border-solid-border-width);
|
|
8
14
|
position: relative;
|
|
9
15
|
border-radius: $border-solid-border-radius;
|
|
10
|
-
border: $border-
|
|
11
|
-
transparent;
|
|
16
|
+
border: $border-solid-border-width $border-solid-border-style $color-gray-500;
|
|
12
17
|
transition:
|
|
13
18
|
background-color $animation-duration-immediate,
|
|
14
19
|
border-color $animation-duration-immediate;
|
|
15
|
-
background-color: $color-
|
|
20
|
+
background-color: $color-white;
|
|
21
|
+
min-height: $typography-paragraph-body-line-height;
|
|
16
22
|
}
|
|
17
23
|
|
|
18
24
|
.editableContainer:hover :global(.ProseMirror) {
|
|
19
25
|
background-color: $color-gray-200;
|
|
20
|
-
border-color: $color-blue-500;
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
.editableContainer .hiddenButton:focus-within + * > :global(.ProseMirror) {
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
background-color: $color-gray-200;
|
|
30
|
+
|
|
31
|
+
&::before {
|
|
32
|
+
$focus-ring-offset: calc((#{$border-focus-ring-border-width} * 2) + 1px);
|
|
33
|
+
|
|
34
|
+
pointer-events: none;
|
|
35
|
+
content: "";
|
|
36
|
+
position: absolute;
|
|
37
|
+
background: transparent;
|
|
38
|
+
border: $border-focus-ring-border-width $border-focus-ring-border-style
|
|
39
|
+
$color-blue-500;
|
|
40
|
+
border-radius: 10px;
|
|
41
|
+
inset: calc(-1 * #{$focus-ring-offset});
|
|
42
|
+
z-index: 1;
|
|
43
|
+
}
|
|
26
44
|
}
|
|
@@ -37,7 +37,9 @@ export const EditableRichTextContent = ({
|
|
|
37
37
|
...restProps
|
|
38
38
|
}: EditableRichTextContentProps): JSX.Element => (
|
|
39
39
|
<>
|
|
40
|
-
{!isLabelHidden &&
|
|
40
|
+
{!isLabelHidden && (
|
|
41
|
+
<Label classNameOverride={styles.editorLabel} labelText={labelText} />
|
|
42
|
+
)}
|
|
41
43
|
{/* Disabling these a11y linting errors because there is a <button> that mitigates these concerns. The onClick here is just an additional layer. */}
|
|
42
44
|
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */}
|
|
43
45
|
<div
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Canvas, Controls, Meta } from "@storybook/blocks"
|
|
2
|
-
import { ResourceLinks, KAIOInstallation
|
|
2
|
+
import { ResourceLinks, KAIOInstallation } from "~storybook/components"
|
|
3
3
|
import * as EditableRichTextContentStories from "./EditableRichTextContent.stories"
|
|
4
4
|
|
|
5
5
|
<Meta of={EditableRichTextContentStories} />
|
|
@@ -15,15 +15,17 @@ import * as EditableRichTextContentStories from "./EditableRichTextContent.stori
|
|
|
15
15
|
|
|
16
16
|
## Overview
|
|
17
17
|
|
|
18
|
-
To render the contents of your
|
|
18
|
+
To render the contents of your [RichTextEditor](/docs/components-richtexteditor-richtexteditor--docs) using the same structure for both components.
|
|
19
19
|
|
|
20
20
|
<Canvas of={EditableRichTextContentStories.Playground} />
|
|
21
21
|
<Controls of={EditableRichTextContentStories.Playground} />
|
|
22
22
|
|
|
23
23
|
## Usage
|
|
24
24
|
|
|
25
|
-
The
|
|
26
|
-
|
|
25
|
+
The `EditableRichTextContent` indicates interactivity similar to a `text` or `textarea` input and should be used in combination with the [RichTextEditor](/docs/components-richtexteditor-richtexteditor--docs) to toggle between inactive and editable states.
|
|
26
|
+
|
|
27
|
+
This differs from the [RichTextContent](/docs/components-richtexteditor-richtextcontent--docs) component, which is used to render `RichTextEditor` content as read-only text.
|
|
28
|
+
|
|
27
29
|
|
|
28
30
|
```tsx
|
|
29
31
|
const [editMode, setEditMode] = useState<boolean>(false);
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import { action } from "@storybook/addon-actions"
|
|
3
|
+
import { Meta } from "@storybook/react"
|
|
4
|
+
import {
|
|
5
|
+
StickerSheet,
|
|
6
|
+
StickerSheetStory,
|
|
7
|
+
} from "~storybook/components/StickerSheet"
|
|
8
|
+
import { EditableRichTextContent } from "../index"
|
|
9
|
+
import defaultContent from "./defaultContent.json"
|
|
10
|
+
|
|
11
|
+
const meta = {
|
|
12
|
+
title: "Components/RichTextEditor/EditableRichTextContent",
|
|
13
|
+
component: EditableRichTextContent,
|
|
14
|
+
} satisfies Meta<typeof EditableRichTextContent>
|
|
15
|
+
|
|
16
|
+
export default meta
|
|
17
|
+
|
|
18
|
+
const StickerSheetTemplate: StickerSheetStory = {
|
|
19
|
+
render: () => (
|
|
20
|
+
<div>
|
|
21
|
+
<StickerSheet className="" heading="Pseudo states">
|
|
22
|
+
<StickerSheet.Body>
|
|
23
|
+
<StickerSheet.Row rowTitle="Default">
|
|
24
|
+
<StickerSheet.Cell className=" w-1/2">
|
|
25
|
+
<EditableRichTextContent
|
|
26
|
+
onClick={action("Toggle RTE")}
|
|
27
|
+
content={[]}
|
|
28
|
+
labelText="Label"
|
|
29
|
+
/>
|
|
30
|
+
</StickerSheet.Cell>
|
|
31
|
+
<StickerSheet.Cell className=" w-1/2">
|
|
32
|
+
<EditableRichTextContent
|
|
33
|
+
onClick={action("Toggle RTE")}
|
|
34
|
+
content={defaultContent}
|
|
35
|
+
labelText="Label"
|
|
36
|
+
/>
|
|
37
|
+
</StickerSheet.Cell>
|
|
38
|
+
</StickerSheet.Row>
|
|
39
|
+
<StickerSheet.Row rowTitle="Hover">
|
|
40
|
+
<StickerSheet.Cell className=" w-1/2">
|
|
41
|
+
<EditableRichTextContent
|
|
42
|
+
onClick={action("Toggle RTE")}
|
|
43
|
+
data-sb-pseudo-styles="hover"
|
|
44
|
+
content={[]}
|
|
45
|
+
labelText="Label"
|
|
46
|
+
/>
|
|
47
|
+
</StickerSheet.Cell>
|
|
48
|
+
<StickerSheet.Cell className=" w-1/2">
|
|
49
|
+
<EditableRichTextContent
|
|
50
|
+
onClick={action("Toggle RTE")}
|
|
51
|
+
data-sb-pseudo-styles="hover"
|
|
52
|
+
content={defaultContent}
|
|
53
|
+
labelText="Label"
|
|
54
|
+
/>
|
|
55
|
+
</StickerSheet.Cell>
|
|
56
|
+
</StickerSheet.Row>
|
|
57
|
+
<StickerSheet.Row rowTitle="Focus">
|
|
58
|
+
<StickerSheet.Cell className=" w-1/2">
|
|
59
|
+
<EditableRichTextContent
|
|
60
|
+
onClick={action("Toggle RTE")}
|
|
61
|
+
data-sb-pseudo-styles="focusWithin"
|
|
62
|
+
content={[]}
|
|
63
|
+
labelText="Label"
|
|
64
|
+
/>
|
|
65
|
+
</StickerSheet.Cell>
|
|
66
|
+
<StickerSheet.Cell className=" w-1/2">
|
|
67
|
+
<EditableRichTextContent
|
|
68
|
+
onClick={action("Toggle RTE")}
|
|
69
|
+
data-sb-pseudo-styles="focusWithin"
|
|
70
|
+
content={defaultContent}
|
|
71
|
+
labelText="Label"
|
|
72
|
+
/>
|
|
73
|
+
</StickerSheet.Cell>
|
|
74
|
+
</StickerSheet.Row>
|
|
75
|
+
</StickerSheet.Body>
|
|
76
|
+
</StickerSheet>
|
|
77
|
+
</div>
|
|
78
|
+
),
|
|
79
|
+
parameters: {
|
|
80
|
+
pseudo: {
|
|
81
|
+
hover: ['[data-sb-pseudo-styles="hover"]'],
|
|
82
|
+
focusWithin: [
|
|
83
|
+
'[data-sb-pseudo-styles="focusWithin"] > [class^="VisuallyHidden"]',
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export const StickerSheetDefault: StickerSheetStory = {
|
|
90
|
+
...StickerSheetTemplate,
|
|
91
|
+
name: "Sticker Sheet (Default)",
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export const StickerSheetRTL: StickerSheetStory = {
|
|
95
|
+
...StickerSheetTemplate,
|
|
96
|
+
name: "Sticker Sheet (RTL)",
|
|
97
|
+
parameters: { textDirection: "rtl" },
|
|
98
|
+
}
|
package/src/RichTextEditor/EditableRichTextContent/_docs/EditableRichTextContent.stories.tsx
CHANGED
|
@@ -8,14 +8,14 @@ import {
|
|
|
8
8
|
RichTextEditorProps,
|
|
9
9
|
} from "../../index"
|
|
10
10
|
import { EditableRichTextContent } from "../index"
|
|
11
|
-
import
|
|
11
|
+
import defaultContent from "./defaultContent.json"
|
|
12
12
|
|
|
13
13
|
const meta = {
|
|
14
14
|
title: "Components/RichTextEditor/EditableRichTextContent",
|
|
15
15
|
component: EditableRichTextContent,
|
|
16
16
|
args: {
|
|
17
|
-
content:
|
|
18
|
-
labelText: "
|
|
17
|
+
content: [],
|
|
18
|
+
labelText: "Label",
|
|
19
19
|
onClick: fn(),
|
|
20
20
|
},
|
|
21
21
|
argTypes: {
|
|
@@ -32,7 +32,7 @@ const EditableRichTextContentTemplate: Story = {
|
|
|
32
32
|
render: props => {
|
|
33
33
|
const [editMode, setEditMode] = useState<boolean>(false)
|
|
34
34
|
const [readRteData, setReadRTEData] = useState<EditorContentArray>(
|
|
35
|
-
props.content
|
|
35
|
+
props.content
|
|
36
36
|
)
|
|
37
37
|
const [editRteData, setEditRTEData] = useState<EditorContentArray>([])
|
|
38
38
|
|
|
@@ -65,7 +65,7 @@ const EditableRichTextContentTemplate: Story = {
|
|
|
65
65
|
defaultValue={editRteData}
|
|
66
66
|
onChange={handleOnChange}
|
|
67
67
|
/>
|
|
68
|
-
<div className="flex justify-end mt-8">
|
|
68
|
+
<div className="flex justify-end mt-12 gap-8">
|
|
69
69
|
<Button label="Cancel" secondary onClick={handleCancel} />
|
|
70
70
|
<Button label="Save" primary onClick={handleSave} />
|
|
71
71
|
</div>
|
|
@@ -81,6 +81,9 @@ const EditableRichTextContentTemplate: Story = {
|
|
|
81
81
|
/>
|
|
82
82
|
)
|
|
83
83
|
},
|
|
84
|
+
args: {
|
|
85
|
+
content: defaultContent,
|
|
86
|
+
},
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
export const Playground: Story = {
|