@agregio-solutions/design-system 1.90.1 → 1.92.0

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.
Files changed (68) hide show
  1. package/dist/design-system.cjs +9 -5
  2. package/dist/design-system.js +14 -6
  3. package/dist/packages/components/Accordion/doc.md +342 -0
  4. package/dist/packages/components/Badge/doc.md +192 -0
  5. package/dist/packages/components/Breadcrumbs/doc.md +332 -0
  6. package/dist/packages/components/Button/doc.md +425 -0
  7. package/dist/packages/components/Calendar/doc.md +465 -0
  8. package/dist/packages/components/ChartLegend/doc.md +151 -0
  9. package/dist/packages/components/ChartTooltip/doc.md +124 -0
  10. package/dist/packages/components/Checkbox/doc.md +329 -0
  11. package/dist/packages/components/CheckboxGroup/doc.md +242 -0
  12. package/dist/packages/components/Chip/doc.md +99 -0
  13. package/dist/packages/components/Combobox/Combobox.d.ts +8 -0
  14. package/dist/packages/components/Combobox/doc.md +680 -0
  15. package/dist/packages/components/DataTable/doc.md +1124 -0
  16. package/dist/packages/components/DatePicker/doc.md +579 -0
  17. package/dist/packages/components/DateRangePicker/doc.md +638 -0
  18. package/dist/packages/components/Drawer/doc.md +338 -0
  19. package/dist/packages/components/Dropdown/Dropdown.d.ts +4 -0
  20. package/dist/packages/components/Dropdown/doc.md +205 -0
  21. package/dist/packages/components/EmptyState/doc.md +101 -0
  22. package/dist/packages/components/FileUpload/doc.md +449 -0
  23. package/dist/packages/components/Filter/doc.md +196 -0
  24. package/dist/packages/components/Header/doc.md +373 -0
  25. package/dist/packages/components/I18nProvider/doc.md +187 -0
  26. package/dist/packages/components/Icon/doc.md +63 -0
  27. package/dist/packages/components/Label/doc.md +60 -0
  28. package/dist/packages/components/LinearProgressBar/doc.md +148 -0
  29. package/dist/packages/components/Link/doc.md +206 -0
  30. package/dist/packages/components/List/doc.md +481 -0
  31. package/dist/packages/components/Loader/doc.md +53 -0
  32. package/dist/packages/components/Menu/Menu.d.ts +5 -1
  33. package/dist/packages/components/Menu/doc.md +231 -0
  34. package/dist/packages/components/Message/doc.md +166 -0
  35. package/dist/packages/components/Modal/doc.md +289 -0
  36. package/dist/packages/components/Navigation/doc.md +992 -0
  37. package/dist/packages/components/NavigationItem/doc.md +167 -0
  38. package/dist/packages/components/NotificationCard/doc.md +206 -0
  39. package/dist/packages/components/Notifications/doc.md +240 -0
  40. package/dist/packages/components/NumberField/doc.md +582 -0
  41. package/dist/packages/components/PageLayout/doc.md +651 -0
  42. package/dist/packages/components/Pagination/doc.md +227 -0
  43. package/dist/packages/components/Popover/doc.md +245 -0
  44. package/dist/packages/components/Radio/doc.md +370 -0
  45. package/dist/packages/components/RouterProvider/doc.md +64 -0
  46. package/dist/packages/components/SearchBar/doc.md +504 -0
  47. package/dist/packages/components/SegmentedControl/doc.md +398 -0
  48. package/dist/packages/components/Select/Select.d.ts +4 -0
  49. package/dist/packages/components/Select/doc.md +1133 -0
  50. package/dist/packages/components/Skeleton/doc.md +129 -0
  51. package/dist/packages/components/Slider/doc.md +362 -0
  52. package/dist/packages/components/Stepper/doc.md +104 -0
  53. package/dist/packages/components/Switch/doc.md +296 -0
  54. package/dist/packages/components/Tabs/doc.md +295 -0
  55. package/dist/packages/components/Tag/doc.md +81 -0
  56. package/dist/packages/components/TextInput/doc.md +490 -0
  57. package/dist/packages/components/TimeField/doc.md +353 -0
  58. package/dist/packages/components/Timeline/doc.md +1046 -0
  59. package/dist/packages/components/Toaster/doc.md +263 -0
  60. package/dist/packages/components/ToggleButton/doc.md +108 -0
  61. package/dist/packages/components/ToggleButtonGroup/doc.md +307 -0
  62. package/dist/packages/components/Tooltip/doc.md +206 -0
  63. package/dist/packages/components/YearMonthPicker/YearMonthPicker.d.ts +8 -0
  64. package/dist/packages/components/YearMonthPicker/doc.md +638 -0
  65. package/dist/public_docs/components.md +68 -0
  66. package/dist/public_docs/index.md +30 -0
  67. package/dist/public_docs/tokens.md +121 -0
  68. package/package.json +3 -2
@@ -0,0 +1,263 @@
1
+ # Toaster
2
+
3
+ ## Props
4
+
5
+ The complete Props documentation with JS doc for this component is available at this path:
6
+
7
+ node_modules/@agregio-solutions/design-system/dist/packages/components/Toaster/Toaster.d.ts
8
+
9
+ ## Example usage
10
+
11
+ Here are the Storybook Stories.
12
+
13
+ Base stories:
14
+
15
+ ```tsx
16
+ import { Meta, StoryObj } from "@storybook/react-vite";
17
+ import { screen } from "storybook/test";
18
+ import Toaster from "./Toaster";
19
+ import { toast } from "sonner";
20
+ import { useEffect } from "react";
21
+ import Button from "../Button/Button";
22
+
23
+ const meta: Meta<typeof Toaster> = {
24
+ component: Toaster,
25
+ parameters: {
26
+ layout: "centered",
27
+ },
28
+ decorators: [
29
+ (Story) => (
30
+ <>
31
+ <Toaster />
32
+ <Story />
33
+ </>
34
+ ),
35
+ ],
36
+ };
37
+ export default meta;
38
+
39
+ type Story = StoryObj<typeof meta>;
40
+
41
+ export const Default: Story = {
42
+ render: () => {
43
+ const ParentComponent = () => {
44
+ useEffect(() => {
45
+ toast("Default message");
46
+ toast("With action", {
47
+ action: <Button nature="informative" text="Click me" />,
48
+ });
49
+ }, []);
50
+ return <div />;
51
+ };
52
+ return <ParentComponent />;
53
+ },
54
+ play: async () => {
55
+ await screen.findByText("Default message");
56
+ },
57
+ };
58
+
59
+ export const Success: Story = {
60
+ render: () => {
61
+ const ParentComponent = () => {
62
+ useEffect(() => {
63
+ toast.success("Success message");
64
+ toast.success("With action", {
65
+ action: <Button nature="positive" text="Click me" />,
66
+ });
67
+ }, []);
68
+ return <div />;
69
+ };
70
+ return <ParentComponent />;
71
+ },
72
+ };
73
+
74
+ export const Error: Story = {
75
+ render: () => {
76
+ const ParentComponent = () => {
77
+ useEffect(() => {
78
+ toast.error("Error message");
79
+ toast.error("With action", {
80
+ action: <Button nature="negative" text="Click me" />,
81
+ });
82
+ }, []);
83
+ return <div />;
84
+ };
85
+ return <ParentComponent />;
86
+ },
87
+ };
88
+
89
+ export const Warning: Story = {
90
+ render: () => {
91
+ const ParentComponent = () => {
92
+ useEffect(() => {
93
+ toast.warning("Warning message");
94
+ toast.warning("With action", {
95
+ action: <Button nature="warning" text="Click me" />,
96
+ });
97
+ }, []);
98
+ return <div />;
99
+ };
100
+ return <ParentComponent />;
101
+ },
102
+ };
103
+
104
+ export const WithPromise: Story = {
105
+ render: () => {
106
+ const fakePromise = new Promise((resolve) => {
107
+ setTimeout(() => resolve({ name: "Promise" }), 2000);
108
+ });
109
+
110
+ const ParentComponent = () => {
111
+ useEffect(() => {
112
+ toast.promise(fakePromise, {
113
+ loading: "Loading...",
114
+ success: (data: any) => {
115
+ return `${data.name} toast has been added`;
116
+ },
117
+ error: "Error text",
118
+ });
119
+ }, []);
120
+ return <div />;
121
+ };
122
+ return <ParentComponent />;
123
+ },
124
+ };
125
+
126
+ export const Custom: Story = {
127
+ render: () => {
128
+ const ParentComponent = () => {
129
+ useEffect(() => {
130
+ toast(<div>A custom toast with default styling</div>, {
131
+ duration: 5000,
132
+ unstyled: true,
133
+ closeButton: false,
134
+ });
135
+ }, []);
136
+ return <div />;
137
+ };
138
+ return <ParentComponent />;
139
+ },
140
+ };
141
+
142
+ export const VeryLongText: Story = {
143
+ render: () => {
144
+ const ParentComponent = () => {
145
+ useEffect(() => {
146
+ toast(
147
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
148
+ );
149
+ }, []);
150
+ return <div />;
151
+ };
152
+ return <ParentComponent />;
153
+ },
154
+ };
155
+
156
+ export const OverflowingText: Story = {
157
+ render: () => {
158
+ const ParentComponent = () => {
159
+ useEffect(() => {
160
+ toast("text-that-will-overflow-if-not-cutted-off-by-the-css");
161
+ }, []);
162
+ return <div />;
163
+ };
164
+ return <ParentComponent />;
165
+ },
166
+ };
167
+ ```
168
+
169
+ ## Developer notes
170
+
171
+ Here are the notes available for the developer on the built Storybook, you can read them to understand the component and how to use it.
172
+
173
+ ````mdx
174
+ import {
175
+ Canvas,
176
+ Meta,
177
+ Stories,
178
+ Controls,
179
+ Source,
180
+ } from "@storybook/addon-docs/blocks";
181
+
182
+ import * as Toaster from "./Toaster.stories";
183
+
184
+ <Meta of={Toaster} />
185
+
186
+ # Toaster
187
+
188
+ ## Installation
189
+
190
+ The Toaster component will allow you to add toasts to your application.
191
+
192
+ **First, you need to provide the Toaster component in your application.**
193
+
194
+ Only import it in a single place in your app, typically in your root component or main layout component (same as any other Provider component).
195
+
196
+ ```tsx
197
+ import { Toaster } from "@agregio-solutions/design-system";
198
+
199
+ function App() {
200
+ return (
201
+ <ProviderXYZ>
202
+ {/* 👇 place the Toaster component in the same location as the global providers */}
203
+ <Toaster />
204
+ <YourApp />
205
+ </ProviderXYZ>
206
+ );
207
+ }
208
+ ```
209
+
210
+ ## Usage
211
+
212
+ Then, any time you want to display a toast, you can use the `toast` function.
213
+
214
+ ```tsx
215
+ import { toast, Button } from "@agregio-solutions/design-system";
216
+
217
+ function Page() {
218
+ return (
219
+ <div>
220
+ <Button onClick={() => toast("Hello world")} text="Toast me" />
221
+ </div>
222
+ );
223
+ }
224
+ ```
225
+
226
+ ## Examples
227
+
228
+ ### Default and with action button
229
+
230
+ <Source of={Toaster.Default} type="code" dark />
231
+
232
+ ### Success
233
+
234
+ <Source of={Toaster.Success} type="code" dark />
235
+
236
+ ### Error
237
+
238
+ <Source of={Toaster.Error} type="code" dark />
239
+
240
+ ### Warning
241
+
242
+ <Source of={Toaster.Warning} type="code" dark />
243
+
244
+ ### With promise
245
+
246
+ <Source of={Toaster.WithPromise} type="code" dark />
247
+
248
+ ### Custom toast component
249
+
250
+ <Source of={Toaster.Custom} type="code" dark />
251
+
252
+ ## Toaster Props
253
+
254
+ The Design System provides strong defaults for the Toaster component, but you can still customize it with the following props:
255
+
256
+ <Controls of={Toaster.Default} />
257
+
258
+ ## Going further with the toast function
259
+
260
+ This documentation should cover most of your needs.
261
+
262
+ But if you need to go deeper with the toast function, you can refer to the [sonner documentation](https://sonner.emilkowal.ski/toast), which is the library that is used internally.
263
+ ````
@@ -0,0 +1,108 @@
1
+ # ToggleButton
2
+
3
+ ## Props
4
+
5
+ The complete Props documentation with JS doc for this component is available at this path:
6
+
7
+ node_modules/@agregio-solutions/design-system/dist/packages/components/ToggleButton/ToggleButton.d.ts
8
+
9
+ ## Example usage
10
+
11
+ Here are the Storybook Stories.
12
+
13
+ Base stories:
14
+
15
+ ```tsx
16
+ import { Meta, StoryObj } from "@storybook/react-vite";
17
+ import ToggleButton from "./ToggleButton";
18
+ import { expect, userEvent, within, fn } from "storybook/test";
19
+
20
+ const meta: Meta<typeof ToggleButton> = {
21
+ component: ToggleButton,
22
+ tags: ["autodocs"],
23
+ globals: {
24
+ backgrounds: { value: "dark" },
25
+ },
26
+ argTypes: {
27
+ children: {
28
+ control: "text",
29
+ },
30
+ },
31
+ parameters: {
32
+ layout: "centered",
33
+ },
34
+ };
35
+
36
+ export default meta;
37
+
38
+ export const Playground: StoryObj<typeof ToggleButton> = {
39
+ args: {
40
+ id: "December",
41
+ children: "D",
42
+ onChange: fn(),
43
+ tooltip: "December",
44
+ },
45
+ };
46
+
47
+ export const DefaultSelected: StoryObj<typeof ToggleButton> = {
48
+ args: {
49
+ ...Playground.args,
50
+ defaultSelected: true,
51
+ },
52
+ play: async ({ canvasElement }) => {
53
+ const canvas = within(canvasElement);
54
+ const button = canvas.getByRole("button");
55
+ await expect(button).toHaveAttribute("aria-pressed", "true");
56
+ },
57
+ };
58
+
59
+ export const Disabled: StoryObj<typeof ToggleButton> = {
60
+ args: {
61
+ ...Playground.args,
62
+ isDisabled: true,
63
+ },
64
+ play: async ({ canvasElement }) => {
65
+ const canvas = within(canvasElement);
66
+ const button = canvas.getByRole("button");
67
+ await expect(button).toBeDisabled();
68
+ await userEvent.click(button);
69
+ await expect(button).toHaveAttribute("aria-pressed", "false");
70
+ },
71
+ };
72
+
73
+ export const WarningMode: StoryObj<typeof ToggleButton> = {
74
+ args: {
75
+ ...Playground.args,
76
+ mode: "warning",
77
+ defaultSelected: true,
78
+ },
79
+ };
80
+
81
+ export const WithIcon: StoryObj<typeof ToggleButton> = {
82
+ args: {
83
+ ...Playground.args,
84
+ iconName: "phone_1_full",
85
+ tooltip: "By phone",
86
+ },
87
+ };
88
+
89
+ export const Interaction: StoryObj<typeof ToggleButton> = {
90
+ args: {
91
+ ...Playground.args,
92
+ },
93
+ play: async ({ canvasElement, args }) => {
94
+ const canvas = within(canvasElement);
95
+ const button = canvas.getByRole("button");
96
+
97
+ await expect(button).toHaveAttribute("aria-pressed", "false");
98
+
99
+ await userEvent.click(button);
100
+ await expect(button).toHaveAttribute("aria-pressed", "true");
101
+ expect(args.onChange).toHaveBeenCalledWith(true);
102
+
103
+ await userEvent.click(button);
104
+ await expect(button).toHaveAttribute("aria-pressed", "false");
105
+ expect(args.onChange).toHaveBeenCalledWith(false);
106
+ },
107
+ };
108
+ ```
@@ -0,0 +1,307 @@
1
+ # ToggleButtonGroup
2
+
3
+ ## Props
4
+
5
+ The complete Props documentation with JS doc for this component is available at this path:
6
+
7
+ node_modules/@agregio-solutions/design-system/dist/packages/components/ToggleButtonGroup/ToggleButtonGroup.d.ts
8
+
9
+ ## Example usage
10
+
11
+ Here are the Storybook Stories.
12
+
13
+ Base stories:
14
+
15
+ ```tsx
16
+ import { Meta, StoryObj } from "@storybook/react-vite";
17
+ import { useState } from "react";
18
+ import ToggleButtonGroup from "./ToggleButtonGroup";
19
+ import ToggleButton from "../ToggleButton/ToggleButton";
20
+ import { expect, userEvent, within, fn } from "storybook/test";
21
+ import { ICON_NAMES_ARRAY } from "../Icon/Icon";
22
+
23
+ const meta: Meta<typeof ToggleButtonGroup> = {
24
+ component: ToggleButtonGroup,
25
+ tags: ["autodocs"],
26
+ argTypes: {
27
+ orientation: {
28
+ control: "select",
29
+ options: ["vertical", "horizontal"],
30
+ },
31
+ labelIconRight: {
32
+ control: "select",
33
+ options: ["", ...ICON_NAMES_ARRAY],
34
+ },
35
+ helperTextIcon: {
36
+ control: "select",
37
+ options: ["", ...ICON_NAMES_ARRAY],
38
+ },
39
+ errorHelperTextIcon: {
40
+ control: "select",
41
+ options: ["", ...ICON_NAMES_ARRAY],
42
+ },
43
+ successHelperTextIcon: {
44
+ control: "select",
45
+ options: ["", ...ICON_NAMES_ARRAY],
46
+ },
47
+ warningHelperTextIcon: {
48
+ control: "select",
49
+ options: ["", ...ICON_NAMES_ARRAY],
50
+ },
51
+ children: { control: false },
52
+ selectedKeys: { control: false },
53
+ defaultSelectedKeys: { control: false },
54
+ },
55
+ };
56
+
57
+ export default meta;
58
+
59
+ type Story = StoryObj<typeof ToggleButtonGroup>;
60
+
61
+ const isChecked = async (button: HTMLElement) => {
62
+ await expect(button).toHaveAttribute("data-selected", "true");
63
+ };
64
+
65
+ export const Playground: Story = {
66
+ args: {
67
+ orientation: "vertical",
68
+ label: "[Insert label]",
69
+ required: true,
70
+ labelIconRight: "help_outline",
71
+ labelIconRightTooltip: "Additional information",
72
+ helperText: "[Insert description]",
73
+ helperTextIcon: "help_outline",
74
+ onSelectionChange: fn(),
75
+ errorHelperText: "",
76
+ errorHelperTextIcon: "error_outline",
77
+ successHelperText: "",
78
+ successHelperTextIcon: "check_circle_outline",
79
+ warningHelperText: "",
80
+ warningHelperTextIcon: "warning_amber",
81
+ defaultSelectedKeys: [],
82
+ isDisabled: false,
83
+ selectionMode: "multiple",
84
+ style: {},
85
+ className: "",
86
+ },
87
+ render: (args) => (
88
+ <ToggleButtonGroup {...args}>
89
+ <ToggleButton id="Monday" tooltip="Lundi">
90
+ L
91
+ </ToggleButton>
92
+ <ToggleButton id="Tuesday" tooltip="Mardi">
93
+ M
94
+ </ToggleButton>
95
+ <ToggleButton id="Wednesday" tooltip="Mercredi">
96
+ M
97
+ </ToggleButton>
98
+ <ToggleButton id="Thursday" tooltip="Jeudi">
99
+ J
100
+ </ToggleButton>
101
+ <ToggleButton id="Friday" tooltip="Vendredi">
102
+ V
103
+ </ToggleButton>
104
+ <ToggleButton id="Saturday" mode="warning" tooltip="Samedi">
105
+ S
106
+ </ToggleButton>
107
+ <ToggleButton id="Sunday" isDisabled tooltip="Dimanche">
108
+ D
109
+ </ToggleButton>
110
+ </ToggleButtonGroup>
111
+ ),
112
+ };
113
+
114
+ export const SingleSelection: Story = {
115
+ args: {
116
+ ...Playground.args,
117
+ selectionMode: "single",
118
+ },
119
+ render: Playground.render,
120
+ };
121
+
122
+ export const WithDefaultSelectedKey: Story = {
123
+ args: {
124
+ ...Playground.args,
125
+ defaultSelectedKeys: ["Monday", "Thursday"],
126
+ warningHelperText: "[Insert warning text]",
127
+ },
128
+ render: Playground.render,
129
+ play: async ({ canvasElement }) => {
130
+ const canvas = within(canvasElement);
131
+ const mondayButton = canvas.getByText("L", { selector: "button" });
132
+ const thursdayButton = canvas.getByText("J", { selector: "button" });
133
+
134
+ await isChecked(mondayButton);
135
+ await isChecked(thursdayButton);
136
+ },
137
+ };
138
+
139
+ export const Disabled: Story = {
140
+ args: {
141
+ ...Playground.args,
142
+ isDisabled: true,
143
+ onSelectionChange: fn(),
144
+ },
145
+ render: (args) => (
146
+ <ToggleButtonGroup {...args}>
147
+ <ToggleButton id="left" tooltip="Left">
148
+ A
149
+ </ToggleButton>
150
+ <ToggleButton id="center" tooltip="Center">
151
+ B
152
+ </ToggleButton>
153
+ <ToggleButton id="right" tooltip="Right">
154
+ C
155
+ </ToggleButton>
156
+ </ToggleButtonGroup>
157
+ ),
158
+ play: async ({ canvasElement, args }) => {
159
+ const canvas = within(canvasElement);
160
+
161
+ await expect(canvas.getByText("A", { selector: "button" })).toBeDisabled();
162
+ await expect(canvas.getByText("B", { selector: "button" })).toBeDisabled();
163
+ await expect(canvas.getByText("C", { selector: "button" })).toBeDisabled();
164
+ await userEvent.click(canvas.getByText("A", { selector: "button" }));
165
+ await expect(args.onSelectionChange).not.toHaveBeenCalled();
166
+ },
167
+ };
168
+
169
+ export const WithIcons: Story = {
170
+ args: {
171
+ ...Playground.args,
172
+ selectionMode: "multiple",
173
+ onSelectionChange: fn(),
174
+ },
175
+ render: (args) => (
176
+ <ToggleButtonGroup {...args}>
177
+ <ToggleButton id="phone" iconName="phone_2_full" tooltip="By phone" />
178
+ <ToggleButton id="email" iconName="mail_full" tooltip="By email" />
179
+ <ToggleButton id="sms" iconName="phone_1_full" tooltip="By SMS" />
180
+ <ToggleButton
181
+ id="notifications"
182
+ iconName="notifications_none"
183
+ tooltip="By notifications"
184
+ />
185
+ </ToggleButtonGroup>
186
+ ),
187
+ };
188
+
189
+ export const HorizontalOrientation: Story = {
190
+ args: {
191
+ ...Playground.args,
192
+ orientation: "horizontal",
193
+ },
194
+ render: Playground.render,
195
+ };
196
+
197
+ export const ControlledSelection: Story = {
198
+ render: function ControlledExample() {
199
+ const [selected, setSelected] = useState<string[]>(["center"]);
200
+
201
+ const handleSelectionChange = (keys: string[]) => {
202
+ setSelected(keys);
203
+ };
204
+
205
+ return (
206
+ <div>
207
+ <ToggleButtonGroup
208
+ {...Playground.args}
209
+ selectedKeys={selected}
210
+ onSelectionChange={handleSelectionChange}
211
+ >
212
+ <ToggleButton id="A" tooltip="A">
213
+ A
214
+ </ToggleButton>
215
+ <ToggleButton id="B" tooltip="B">
216
+ B
217
+ </ToggleButton>
218
+ <ToggleButton id="C" tooltip="C">
219
+ C
220
+ </ToggleButton>
221
+ </ToggleButtonGroup>
222
+
223
+ <p>Selected: {selected.join(", ") || "none"}</p>
224
+ </div>
225
+ );
226
+ },
227
+ };
228
+ ```
229
+
230
+ ## How to test this component
231
+
232
+ Here are some more advanced stories with more testing coverage and examples that you can read to understand how to test this component.
233
+
234
+ ```tsx
235
+ import { Meta, StoryObj } from "@storybook/react-vite";
236
+ import ToggleButtonGroup from "../ToggleButtonGroup";
237
+ import { expect, userEvent, within } from "storybook/test";
238
+ import * as ToggleButtonGroupStories from "../ToggleButtonGroup.stories";
239
+
240
+ const meta: Meta<typeof ToggleButtonGroup> = {
241
+ ...ToggleButtonGroupStories.default,
242
+ component: ToggleButtonGroup,
243
+ };
244
+
245
+ export default meta;
246
+
247
+ type Story = StoryObj<typeof ToggleButtonGroup>;
248
+
249
+ const isChecked = async (button: HTMLElement) => {
250
+ await expect(button).toHaveAttribute("data-selected", "true");
251
+ };
252
+
253
+ const isNotChecked = async (button: HTMLElement) => {
254
+ await expect(button).not.toHaveAttribute("data-selected", "true");
255
+ };
256
+
257
+ export const MultipleSelectionTests: Story = {
258
+ ...ToggleButtonGroupStories.Playground,
259
+ play: async ({ canvasElement, args }) => {
260
+ const canvas = within(canvasElement);
261
+ const mondayButton = canvas.getByText("L", { selector: "button" });
262
+ const thursdayButton = canvas.getByText("J", { selector: "button" });
263
+
264
+ await isNotChecked(mondayButton);
265
+ await isNotChecked(thursdayButton);
266
+
267
+ await userEvent.click(mondayButton);
268
+ await isChecked(mondayButton);
269
+ await expect(args.onSelectionChange).toHaveBeenCalledWith(["Monday"]);
270
+ await isNotChecked(thursdayButton);
271
+
272
+ await userEvent.click(thursdayButton);
273
+ await isChecked(mondayButton);
274
+ await isChecked(thursdayButton);
275
+ await expect(args.onSelectionChange).toHaveBeenCalledWith([
276
+ "Monday",
277
+ "Thursday",
278
+ ]);
279
+ },
280
+ };
281
+
282
+ export const SingleSelectionTests: Story = {
283
+ ...ToggleButtonGroupStories.SingleSelection,
284
+ play: async ({ canvasElement, args }) => {
285
+ const canvas = within(canvasElement);
286
+ const mondayButton = canvas.getByText("L", { selector: "button" });
287
+ const thursdayButton = canvas.getByText("J", { selector: "button" });
288
+
289
+ await isNotChecked(mondayButton);
290
+ await isNotChecked(thursdayButton);
291
+
292
+ await userEvent.click(mondayButton);
293
+ await isChecked(mondayButton);
294
+ await expect(args.onSelectionChange).toHaveBeenCalledWith(["Monday"]);
295
+ await isNotChecked(thursdayButton);
296
+
297
+ await userEvent.click(thursdayButton);
298
+ await isChecked(thursdayButton);
299
+ await expect(args.onSelectionChange).toHaveBeenCalledWith(["Thursday"]);
300
+ await isNotChecked(mondayButton);
301
+ },
302
+ };
303
+
304
+ export const WithDefaultSelectedKeyTests: Story = {
305
+ ...ToggleButtonGroupStories.WithDefaultSelectedKey,
306
+ };
307
+ ```