@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.
- package/dist/design-system.cjs +9 -5
- package/dist/design-system.js +14 -6
- package/dist/packages/components/Accordion/doc.md +342 -0
- package/dist/packages/components/Badge/doc.md +192 -0
- package/dist/packages/components/Breadcrumbs/doc.md +332 -0
- package/dist/packages/components/Button/doc.md +425 -0
- package/dist/packages/components/Calendar/doc.md +465 -0
- package/dist/packages/components/ChartLegend/doc.md +151 -0
- package/dist/packages/components/ChartTooltip/doc.md +124 -0
- package/dist/packages/components/Checkbox/doc.md +329 -0
- package/dist/packages/components/CheckboxGroup/doc.md +242 -0
- package/dist/packages/components/Chip/doc.md +99 -0
- package/dist/packages/components/Combobox/Combobox.d.ts +8 -0
- package/dist/packages/components/Combobox/doc.md +680 -0
- package/dist/packages/components/DataTable/doc.md +1124 -0
- package/dist/packages/components/DatePicker/doc.md +579 -0
- package/dist/packages/components/DateRangePicker/doc.md +638 -0
- package/dist/packages/components/Drawer/doc.md +338 -0
- package/dist/packages/components/Dropdown/Dropdown.d.ts +4 -0
- package/dist/packages/components/Dropdown/doc.md +205 -0
- package/dist/packages/components/EmptyState/doc.md +101 -0
- package/dist/packages/components/FileUpload/doc.md +449 -0
- package/dist/packages/components/Filter/doc.md +196 -0
- package/dist/packages/components/Header/doc.md +373 -0
- package/dist/packages/components/I18nProvider/doc.md +187 -0
- package/dist/packages/components/Icon/doc.md +63 -0
- package/dist/packages/components/Label/doc.md +60 -0
- package/dist/packages/components/LinearProgressBar/doc.md +148 -0
- package/dist/packages/components/Link/doc.md +206 -0
- package/dist/packages/components/List/doc.md +481 -0
- package/dist/packages/components/Loader/doc.md +53 -0
- package/dist/packages/components/Menu/Menu.d.ts +5 -1
- package/dist/packages/components/Menu/doc.md +231 -0
- package/dist/packages/components/Message/doc.md +166 -0
- package/dist/packages/components/Modal/doc.md +289 -0
- package/dist/packages/components/Navigation/doc.md +992 -0
- package/dist/packages/components/NavigationItem/doc.md +167 -0
- package/dist/packages/components/NotificationCard/doc.md +206 -0
- package/dist/packages/components/Notifications/doc.md +240 -0
- package/dist/packages/components/NumberField/doc.md +582 -0
- package/dist/packages/components/PageLayout/doc.md +651 -0
- package/dist/packages/components/Pagination/doc.md +227 -0
- package/dist/packages/components/Popover/doc.md +245 -0
- package/dist/packages/components/Radio/doc.md +370 -0
- package/dist/packages/components/RouterProvider/doc.md +64 -0
- package/dist/packages/components/SearchBar/doc.md +504 -0
- package/dist/packages/components/SegmentedControl/doc.md +398 -0
- package/dist/packages/components/Select/Select.d.ts +4 -0
- package/dist/packages/components/Select/doc.md +1133 -0
- package/dist/packages/components/Skeleton/doc.md +129 -0
- package/dist/packages/components/Slider/doc.md +362 -0
- package/dist/packages/components/Stepper/doc.md +104 -0
- package/dist/packages/components/Switch/doc.md +296 -0
- package/dist/packages/components/Tabs/doc.md +295 -0
- package/dist/packages/components/Tag/doc.md +81 -0
- package/dist/packages/components/TextInput/doc.md +490 -0
- package/dist/packages/components/TimeField/doc.md +353 -0
- package/dist/packages/components/Timeline/doc.md +1046 -0
- package/dist/packages/components/Toaster/doc.md +263 -0
- package/dist/packages/components/ToggleButton/doc.md +108 -0
- package/dist/packages/components/ToggleButtonGroup/doc.md +307 -0
- package/dist/packages/components/Tooltip/doc.md +206 -0
- package/dist/packages/components/YearMonthPicker/YearMonthPicker.d.ts +8 -0
- package/dist/packages/components/YearMonthPicker/doc.md +638 -0
- package/dist/public_docs/components.md +68 -0
- package/dist/public_docs/index.md +30 -0
- package/dist/public_docs/tokens.md +121 -0
- 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
|
+
```
|