@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,338 @@
|
|
|
1
|
+
# Drawer
|
|
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/Drawer/Drawer.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 Drawer, { Props } from "./Drawer";
|
|
18
|
+
import { screen, fn } from "storybook/test";
|
|
19
|
+
import { useState } from "react";
|
|
20
|
+
import Button from "@components/Button/Button";
|
|
21
|
+
import {
|
|
22
|
+
expectNotPresent,
|
|
23
|
+
STORYBOOK_VIEWPORTS,
|
|
24
|
+
} from "@internal/test-utils-storybook/test-utils-storybook";
|
|
25
|
+
|
|
26
|
+
const meta: Meta<typeof Drawer> = {
|
|
27
|
+
component: Drawer,
|
|
28
|
+
argTypes: {
|
|
29
|
+
children: { control: false },
|
|
30
|
+
},
|
|
31
|
+
parameters: {
|
|
32
|
+
layout: "none",
|
|
33
|
+
},
|
|
34
|
+
render: (args) => {
|
|
35
|
+
function ParentComponent(props: Props) {
|
|
36
|
+
const [isOpen, setIsOpen] = useState(props.isOpen);
|
|
37
|
+
|
|
38
|
+
// Trick to make the drawer close on button with text "Close" (to avoid generating a lot of render stories)
|
|
39
|
+
const onPrimaryClick =
|
|
40
|
+
props.primaryLabel === "Close"
|
|
41
|
+
? () => setIsOpen(false)
|
|
42
|
+
: props.onPrimaryClick;
|
|
43
|
+
|
|
44
|
+
const onSecondaryClick =
|
|
45
|
+
props.secondaryLabel === "Close"
|
|
46
|
+
? () => setIsOpen(false)
|
|
47
|
+
: props.onSecondaryClick;
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<div
|
|
51
|
+
style={{
|
|
52
|
+
display: "flex",
|
|
53
|
+
alignItems: "center",
|
|
54
|
+
justifyContent: "center",
|
|
55
|
+
height: "100vh",
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
58
|
+
<Drawer
|
|
59
|
+
{...props}
|
|
60
|
+
onPrimaryClick={onPrimaryClick}
|
|
61
|
+
onSecondaryClick={onSecondaryClick}
|
|
62
|
+
isOpen={isOpen}
|
|
63
|
+
onOpenChange={setIsOpen}
|
|
64
|
+
>
|
|
65
|
+
{props.children}
|
|
66
|
+
</Drawer>
|
|
67
|
+
|
|
68
|
+
<div style={{ textAlign: "center" }}>
|
|
69
|
+
<Button onClick={() => setIsOpen(true)} text="Open drawer" />
|
|
70
|
+
<div style={{ marginTop: 16 }}>
|
|
71
|
+
The drawer is {isOpen ? "open" : "closed"}
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return <ParentComponent {...args}>{args.children}</ParentComponent>;
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
export default meta;
|
|
82
|
+
|
|
83
|
+
export const Playground: StoryObj<typeof Drawer> = {
|
|
84
|
+
args: {
|
|
85
|
+
title: "[Insert drawer title]",
|
|
86
|
+
children: <div>The content</div>,
|
|
87
|
+
isOpen: true,
|
|
88
|
+
primaryLabel: "Close",
|
|
89
|
+
onPrimaryClick: fn(),
|
|
90
|
+
onSecondaryClick: fn(),
|
|
91
|
+
onOpenChange: fn(),
|
|
92
|
+
},
|
|
93
|
+
play: async ({ args }) => {
|
|
94
|
+
await screen.findByText(args.title);
|
|
95
|
+
await screen.findByText("The content");
|
|
96
|
+
await screen.findByText("Close");
|
|
97
|
+
await screen.findByLabelText("Close");
|
|
98
|
+
await expectNotPresent(() => screen.queryByText("Submit"));
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export const WithSecondaryAction: StoryObj<typeof Drawer> = {
|
|
103
|
+
args: {
|
|
104
|
+
...Playground.args,
|
|
105
|
+
primaryLabel: "Send",
|
|
106
|
+
secondaryLabel: "Close",
|
|
107
|
+
},
|
|
108
|
+
play: async () => {
|
|
109
|
+
await screen.findByText("Send");
|
|
110
|
+
await screen.findByText("Close");
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export const OverflowingContent: StoryObj<typeof Drawer> = {
|
|
115
|
+
args: {
|
|
116
|
+
...Playground.args,
|
|
117
|
+
children: "The content. ".repeat(300),
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const Mobile: StoryObj<typeof Drawer> = {
|
|
122
|
+
parameters: {
|
|
123
|
+
...STORYBOOK_VIEWPORTS,
|
|
124
|
+
layout: "none",
|
|
125
|
+
},
|
|
126
|
+
globals: {
|
|
127
|
+
viewport: { value: "iphone6", isRotated: false },
|
|
128
|
+
},
|
|
129
|
+
args: {
|
|
130
|
+
...Playground.args,
|
|
131
|
+
children: "The content. ".repeat(300),
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export const WithCustomActionsBar: StoryObj<typeof Drawer> = {
|
|
136
|
+
args: {
|
|
137
|
+
...Playground.args,
|
|
138
|
+
customActionsBar: (
|
|
139
|
+
<>
|
|
140
|
+
<Button text="Close" mode="secondary" />
|
|
141
|
+
<Button text="Validate" isLoading />
|
|
142
|
+
</>
|
|
143
|
+
),
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## How to test this component
|
|
149
|
+
|
|
150
|
+
Here are some more advanced stories with more testing coverage and examples that you can read to understand how to test this component.
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
import { Meta, StoryObj } from "@storybook/react-vite";
|
|
154
|
+
import Drawer from "../Drawer";
|
|
155
|
+
import { userEvent, within, screen, expect } from "storybook/test";
|
|
156
|
+
import { useState } from "react";
|
|
157
|
+
import Button from "@components/Button/Button";
|
|
158
|
+
import { expectNotPresent } from "@internal/test-utils-storybook/test-utils-storybook";
|
|
159
|
+
import { Playground, WithSecondaryAction } from "../Drawer.stories";
|
|
160
|
+
import baseMeta from "../Drawer.stories";
|
|
161
|
+
import { useForm } from "react-hook-form";
|
|
162
|
+
import TextInput from "@packages/components/TextInput/TextInput";
|
|
163
|
+
|
|
164
|
+
const meta: Meta<typeof Drawer> = {
|
|
165
|
+
component: Drawer,
|
|
166
|
+
parameters: {
|
|
167
|
+
layout: "none",
|
|
168
|
+
chromatic: { disableSnapshot: true },
|
|
169
|
+
},
|
|
170
|
+
render: baseMeta.render,
|
|
171
|
+
};
|
|
172
|
+
export default meta;
|
|
173
|
+
|
|
174
|
+
export const TestCloseButtonNextTitleShouldCloseDrawer: StoryObj<
|
|
175
|
+
typeof Drawer
|
|
176
|
+
> = {
|
|
177
|
+
args: {
|
|
178
|
+
...Playground.args,
|
|
179
|
+
},
|
|
180
|
+
play: async ({ canvasElement, args }) => {
|
|
181
|
+
const canvas = within(canvasElement);
|
|
182
|
+
const user = userEvent.setup({ delay: 50 });
|
|
183
|
+
await canvas.findByText("The drawer is open");
|
|
184
|
+
await screen.findByText(args.title);
|
|
185
|
+
await user.click(screen.getByLabelText("Close"));
|
|
186
|
+
await canvas.findByText("The drawer is closed");
|
|
187
|
+
await expectNotPresent(() => screen.queryByText(args.title));
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
export const TestFooterCloseButtonShouldCloseDrawer: StoryObj<typeof Drawer> = {
|
|
192
|
+
args: {
|
|
193
|
+
...Playground.args,
|
|
194
|
+
},
|
|
195
|
+
play: async ({ canvasElement, args }) => {
|
|
196
|
+
const canvas = within(canvasElement);
|
|
197
|
+
const user = userEvent.setup({ delay: 50 });
|
|
198
|
+
await canvas.findByText("The drawer is open");
|
|
199
|
+
await screen.findByText(args.title);
|
|
200
|
+
await user.click(screen.getByText("Close"));
|
|
201
|
+
await canvas.findByText("The drawer is closed");
|
|
202
|
+
await expectNotPresent(() => screen.queryByText(args.title));
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export const TestShouldShowASecondaryButtonIfGiven: StoryObj<typeof Drawer> = {
|
|
207
|
+
args: {
|
|
208
|
+
...WithSecondaryAction.args,
|
|
209
|
+
secondaryLabel: "Dismiss",
|
|
210
|
+
},
|
|
211
|
+
play: async ({ args }) => {
|
|
212
|
+
const user = userEvent.setup({ delay: 50 });
|
|
213
|
+
await screen.findByText(args.title);
|
|
214
|
+
await user.click(screen.getByText("Send"));
|
|
215
|
+
await expect(args.onPrimaryClick).toHaveBeenCalledTimes(1);
|
|
216
|
+
await user.click(screen.getByText("Dismiss"));
|
|
217
|
+
await expect(args.onSecondaryClick).toHaveBeenCalledTimes(1);
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
export const ExampleUsage: StoryObj<typeof Drawer> = {
|
|
222
|
+
render: () => {
|
|
223
|
+
function ParentComponent() {
|
|
224
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
225
|
+
|
|
226
|
+
return (
|
|
227
|
+
<div>
|
|
228
|
+
<div>
|
|
229
|
+
<Button onClick={() => setIsOpen(true)} text="Open drawer" />
|
|
230
|
+
</div>
|
|
231
|
+
<Drawer
|
|
232
|
+
isOpen={isOpen}
|
|
233
|
+
onOpenChange={setIsOpen}
|
|
234
|
+
title="Drawer title"
|
|
235
|
+
primaryLabel="Close"
|
|
236
|
+
onPrimaryClick={() => setIsOpen(false)}
|
|
237
|
+
>
|
|
238
|
+
<div>Drawer content</div>
|
|
239
|
+
</Drawer>
|
|
240
|
+
</div>
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return <ParentComponent />;
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
export const ExampleWithReactHookForm: StoryObj<typeof Drawer> = {
|
|
249
|
+
render: () => {
|
|
250
|
+
type Form = {
|
|
251
|
+
name: string;
|
|
252
|
+
email: string;
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
function ParentComponent() {
|
|
256
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
257
|
+
const form = useForm<Form>();
|
|
258
|
+
|
|
259
|
+
const onSubmit = form.handleSubmit(async (data: Form) => {
|
|
260
|
+
// API call for example
|
|
261
|
+
console.log(data); // eslint-disable-line no-console
|
|
262
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
263
|
+
form.reset();
|
|
264
|
+
setIsOpen(false);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
return (
|
|
268
|
+
<>
|
|
269
|
+
<Button
|
|
270
|
+
onClick={() => setIsOpen(true)}
|
|
271
|
+
text="Open create user form"
|
|
272
|
+
/>
|
|
273
|
+
|
|
274
|
+
<Drawer
|
|
275
|
+
isOpen={isOpen}
|
|
276
|
+
onOpenChange={setIsOpen}
|
|
277
|
+
title="Creating a new user"
|
|
278
|
+
customActionsBar={
|
|
279
|
+
<>
|
|
280
|
+
<Button
|
|
281
|
+
onClick={() => setIsOpen(false)}
|
|
282
|
+
text="Close"
|
|
283
|
+
mode="secondary"
|
|
284
|
+
/>
|
|
285
|
+
<Button
|
|
286
|
+
type="submit"
|
|
287
|
+
form="create-user-form" // <- link the form to the button (by the form id)
|
|
288
|
+
text="Create user"
|
|
289
|
+
isLoading={form.formState.isSubmitting}
|
|
290
|
+
/>
|
|
291
|
+
</>
|
|
292
|
+
}
|
|
293
|
+
>
|
|
294
|
+
<form id="create-user-form" onSubmit={onSubmit} noValidate>
|
|
295
|
+
<TextInput
|
|
296
|
+
{...form.register("name", { required: "Name is required" })}
|
|
297
|
+
id="name"
|
|
298
|
+
label="Name"
|
|
299
|
+
errorHelperText={form.formState.errors.name?.message}
|
|
300
|
+
/>
|
|
301
|
+
<TextInput {...form.register("email")} id="email" label="Email" />
|
|
302
|
+
</form>
|
|
303
|
+
</Drawer>
|
|
304
|
+
</>
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return <ParentComponent />;
|
|
309
|
+
},
|
|
310
|
+
};
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## Developer notes
|
|
314
|
+
|
|
315
|
+
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.
|
|
316
|
+
|
|
317
|
+
```mdx
|
|
318
|
+
import { Meta, Controls, Source } from "@storybook/addon-docs/blocks";
|
|
319
|
+
|
|
320
|
+
import * as Drawer from "./Drawer.stories";
|
|
321
|
+
import * as DrawerTests from "./tests/Drawer.stories";
|
|
322
|
+
|
|
323
|
+
<Meta of={Drawer} />
|
|
324
|
+
|
|
325
|
+
# Drawer
|
|
326
|
+
|
|
327
|
+
## Example usage
|
|
328
|
+
|
|
329
|
+
<Source of={DrawerTests.ExampleUsage} type="code" dark />
|
|
330
|
+
|
|
331
|
+
## Example with a form
|
|
332
|
+
|
|
333
|
+
<Source of={DrawerTests.ExampleWithReactHookForm} type="code" dark />
|
|
334
|
+
|
|
335
|
+
## Props
|
|
336
|
+
|
|
337
|
+
<Controls of={Drawer.Playground} />
|
|
338
|
+
```
|
|
@@ -18,6 +18,10 @@ export type Props = {
|
|
|
18
18
|
* The inline style for the element.
|
|
19
19
|
*/
|
|
20
20
|
style?: React.CSSProperties;
|
|
21
|
+
/**
|
|
22
|
+
* When true, increases the dropdown max-height from 200px to 400px.
|
|
23
|
+
*/
|
|
24
|
+
tallDropdown?: boolean;
|
|
21
25
|
};
|
|
22
26
|
declare const Dropdown: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLDivElement>>;
|
|
23
27
|
export default Dropdown;
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# Dropdown
|
|
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/Dropdown/Dropdown.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 Dropdown from "./Dropdown";
|
|
18
|
+
import { userEvent, within, expect } from "storybook/test";
|
|
19
|
+
import DropdownListItem, {
|
|
20
|
+
Props as DropdownListItemProps,
|
|
21
|
+
} from "@components/Dropdown/components/DropdownListItem/DropdownListItem";
|
|
22
|
+
import { useState } from "react";
|
|
23
|
+
|
|
24
|
+
const meta: Meta<typeof Dropdown> = {
|
|
25
|
+
component: Dropdown,
|
|
26
|
+
parameters: {
|
|
27
|
+
layout: "centered",
|
|
28
|
+
},
|
|
29
|
+
globals: {
|
|
30
|
+
backgrounds: { value: "light" },
|
|
31
|
+
},
|
|
32
|
+
argTypes: {
|
|
33
|
+
children: { control: false },
|
|
34
|
+
items: { control: false },
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
export default meta;
|
|
38
|
+
|
|
39
|
+
const baseItem: DropdownListItemProps = {
|
|
40
|
+
iconLeft: "help_outline",
|
|
41
|
+
iconRight: "star",
|
|
42
|
+
text: "Item 1",
|
|
43
|
+
id: "item-1",
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const generateItems = (count: number): Array<DropdownListItemProps> =>
|
|
47
|
+
new Array(count).fill(null).map((_, index) => ({
|
|
48
|
+
...baseItem,
|
|
49
|
+
id: `item-${index + 1}`,
|
|
50
|
+
text: `Item ${index + 1}`,
|
|
51
|
+
selected: index === 3,
|
|
52
|
+
disabled: index === 4,
|
|
53
|
+
}));
|
|
54
|
+
|
|
55
|
+
export const Default: StoryObj<typeof Dropdown> = {
|
|
56
|
+
args: {
|
|
57
|
+
children: generateItems(5).map((item) => (
|
|
58
|
+
<DropdownListItem {...item} key={item.id} ref={undefined} />
|
|
59
|
+
)),
|
|
60
|
+
style: {
|
|
61
|
+
width: 315,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
play: async ({ canvasElement }) => {
|
|
65
|
+
const canvas = within(canvasElement);
|
|
66
|
+
await canvas.findByText("Item 1");
|
|
67
|
+
await canvas.findByText("Item 2");
|
|
68
|
+
await canvas.findByText("Item 3");
|
|
69
|
+
await expect(canvas.queryByText("Item 4")?.parentElement).toHaveAttribute(
|
|
70
|
+
"data-selected",
|
|
71
|
+
"true",
|
|
72
|
+
);
|
|
73
|
+
await expect(canvas.queryByText("Item 5")?.parentElement).toHaveAttribute(
|
|
74
|
+
"data-disabled",
|
|
75
|
+
"true",
|
|
76
|
+
);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const WithMultipleItems: StoryObj<typeof Dropdown> = {
|
|
81
|
+
args: {
|
|
82
|
+
children: generateItems(20).map((item) => (
|
|
83
|
+
<DropdownListItem {...item} key={item.id} ref={undefined} />
|
|
84
|
+
)),
|
|
85
|
+
style: {
|
|
86
|
+
width: 315,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const WithTallDropdown: StoryObj<typeof Dropdown> = {
|
|
92
|
+
args: {
|
|
93
|
+
...WithMultipleItems.args,
|
|
94
|
+
tallDropdown: true,
|
|
95
|
+
},
|
|
96
|
+
play: async ({ canvasElement }) => {
|
|
97
|
+
await expect(
|
|
98
|
+
canvasElement.querySelector('[data-tall="true"]'),
|
|
99
|
+
).not.toBeNull();
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export const WithControlledSelectedItem: StoryObj<typeof Dropdown> = {
|
|
104
|
+
render: () => {
|
|
105
|
+
const Wrapper = () => {
|
|
106
|
+
const [selectedItemId, setSelectedItemId] = useState<string>();
|
|
107
|
+
const items = generateItems(10).map((item) => ({
|
|
108
|
+
...item,
|
|
109
|
+
selected: item.id === selectedItemId,
|
|
110
|
+
onClick: () => setSelectedItemId(item.id),
|
|
111
|
+
}));
|
|
112
|
+
|
|
113
|
+
return (
|
|
114
|
+
<Dropdown style={{ width: 315 }}>
|
|
115
|
+
{items.map((item) => (
|
|
116
|
+
<DropdownListItem {...item} key={item.id} ref={undefined} />
|
|
117
|
+
))}
|
|
118
|
+
</Dropdown>
|
|
119
|
+
);
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
return <Wrapper />;
|
|
123
|
+
},
|
|
124
|
+
play: async ({ canvasElement }) => {
|
|
125
|
+
const canvas = within(canvasElement);
|
|
126
|
+
await expect(canvas.queryByText("Item 1")?.parentElement).toHaveAttribute(
|
|
127
|
+
"data-selected",
|
|
128
|
+
"false",
|
|
129
|
+
);
|
|
130
|
+
await userEvent.click(canvas.getByText("Item 1"));
|
|
131
|
+
await expect(canvas.queryByText("Item 1")?.parentElement).toHaveAttribute(
|
|
132
|
+
"data-selected",
|
|
133
|
+
"true",
|
|
134
|
+
);
|
|
135
|
+
await userEvent.click(canvas.getByText("Item 2"));
|
|
136
|
+
await expect(canvas.queryByText("Item 1")?.parentElement).toHaveAttribute(
|
|
137
|
+
"data-selected",
|
|
138
|
+
"false",
|
|
139
|
+
);
|
|
140
|
+
await expect(canvas.queryByText("Item 2")?.parentElement).toHaveAttribute(
|
|
141
|
+
"data-selected",
|
|
142
|
+
"true",
|
|
143
|
+
);
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export const WithDeprecatedItemsProp: StoryObj<typeof Dropdown> = {
|
|
148
|
+
args: {
|
|
149
|
+
items: generateItems(5),
|
|
150
|
+
style: {
|
|
151
|
+
width: 315,
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
play: async ({ canvasElement }) => {
|
|
155
|
+
const canvas = within(canvasElement);
|
|
156
|
+
await canvas.findByText("Item 1");
|
|
157
|
+
await canvas.findByText("Item 2");
|
|
158
|
+
await canvas.findByText("Item 3");
|
|
159
|
+
await expect(canvas.queryByText("Item 4")?.parentElement).toHaveAttribute(
|
|
160
|
+
"data-selected",
|
|
161
|
+
"true",
|
|
162
|
+
);
|
|
163
|
+
await expect(canvas.queryByText("Item 5")?.parentElement).toHaveAttribute(
|
|
164
|
+
"data-disabled",
|
|
165
|
+
"true",
|
|
166
|
+
);
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Developer notes
|
|
172
|
+
|
|
173
|
+
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.
|
|
174
|
+
|
|
175
|
+
```mdx
|
|
176
|
+
import { Canvas, Meta, Stories, Controls } from "@storybook/addon-docs/blocks";
|
|
177
|
+
|
|
178
|
+
import * as Dropdown from "./Dropdown.stories";
|
|
179
|
+
import * as DropdownListItem from "./components/DropdownListItem/DropdownListItem.stories";
|
|
180
|
+
|
|
181
|
+
<Meta of={Dropdown} />
|
|
182
|
+
|
|
183
|
+
# Dropdown
|
|
184
|
+
|
|
185
|
+
The dropdown is a simple component that allows you to create a dropdown menu.
|
|
186
|
+
|
|
187
|
+
This component **does not handle it's absolute positioning**, you need to do it yourself with whatever method or lib you prefer.
|
|
188
|
+
|
|
189
|
+
There is two ways of using this component:
|
|
190
|
+
|
|
191
|
+
- ✅ **Recommended:** pass a list of `DropdownListItem` components as `children`
|
|
192
|
+
- ⚠️ **Deprecated:** pass an array of `items` which values are the same as [DropdownListItem](?path=/docs/components-dropdown-components-dropdownlistitem--docs) props. (this prop may be removed in a future version)
|
|
193
|
+
|
|
194
|
+
<Canvas of={Dropdown.Default} />
|
|
195
|
+
|
|
196
|
+
### Dropdown props
|
|
197
|
+
|
|
198
|
+
<Controls of={Dropdown.Default} />
|
|
199
|
+
|
|
200
|
+
### Dropdown `items` keys (for reference)
|
|
201
|
+
|
|
202
|
+
<Controls of={DropdownListItem.Default} />
|
|
203
|
+
|
|
204
|
+
<Stories />
|
|
205
|
+
```
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# EmptyState
|
|
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/EmptyState/EmptyState.d.ts
|
|
8
|
+
|
|
9
|
+
## Example usage
|
|
10
|
+
|
|
11
|
+
Here are the Storybook Stories.
|
|
12
|
+
|
|
13
|
+
Base stories:
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
17
|
+
import EmptyState from "./EmptyState";
|
|
18
|
+
import Button from "@components/Button/Button";
|
|
19
|
+
|
|
20
|
+
const meta: Meta<typeof EmptyState> = {
|
|
21
|
+
component: EmptyState,
|
|
22
|
+
tags: ["autodocs"],
|
|
23
|
+
parameters: {
|
|
24
|
+
layout: "centered",
|
|
25
|
+
},
|
|
26
|
+
globals: {
|
|
27
|
+
backgrounds: { value: "light" },
|
|
28
|
+
},
|
|
29
|
+
argTypes: {
|
|
30
|
+
children: { control: false },
|
|
31
|
+
description: { control: "text" },
|
|
32
|
+
},
|
|
33
|
+
decorators: [
|
|
34
|
+
(Story) => (
|
|
35
|
+
<div style={{ width: "496px" }}>
|
|
36
|
+
<Story />
|
|
37
|
+
</div>
|
|
38
|
+
),
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export default meta;
|
|
43
|
+
type Story = StoryObj<typeof meta>;
|
|
44
|
+
|
|
45
|
+
export const Default: Story = {
|
|
46
|
+
args: {
|
|
47
|
+
icon: "help_outline",
|
|
48
|
+
title: "[Insert title]",
|
|
49
|
+
description:
|
|
50
|
+
"[Change this paragraph to include any informations for user that can assit them in making decisions.]",
|
|
51
|
+
children: (
|
|
52
|
+
<>
|
|
53
|
+
<Button mode="secondary" text="[Insert name]" />
|
|
54
|
+
<Button mode="primary" text="[Insert name]" />
|
|
55
|
+
</>
|
|
56
|
+
),
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const WithoutIcon: Story = {
|
|
61
|
+
args: {
|
|
62
|
+
title: "No data available",
|
|
63
|
+
description:
|
|
64
|
+
"There are no items to display at this time. Try adjusting your filters or check back later.",
|
|
65
|
+
children: (
|
|
66
|
+
<>
|
|
67
|
+
<Button mode="secondary" text="Refresh" />
|
|
68
|
+
<Button mode="primary" text="Add Item" />
|
|
69
|
+
</>
|
|
70
|
+
),
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const WithoutActions: Story = {
|
|
75
|
+
args: {
|
|
76
|
+
icon: "help_outline",
|
|
77
|
+
title: "Coming Soon",
|
|
78
|
+
description:
|
|
79
|
+
"This feature is currently under development and will be available soon.",
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const SingleAction: Story = {
|
|
84
|
+
args: {
|
|
85
|
+
icon: "help_outline",
|
|
86
|
+
title: "Get Started",
|
|
87
|
+
description: "Welcome! Click the button below to begin your journey.",
|
|
88
|
+
children: <Button mode="primary" text="Get Started" />,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const GrayVariant: Story = {
|
|
93
|
+
globals: {
|
|
94
|
+
backgrounds: { value: "default" },
|
|
95
|
+
},
|
|
96
|
+
args: {
|
|
97
|
+
...Default.args,
|
|
98
|
+
variant: "gray",
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
```
|