@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,353 @@
|
|
|
1
|
+
# TimeField
|
|
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/TimeField/TimeField.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 TimeField from "./TimeField";
|
|
18
|
+
import { I18nProvider } from "react-aria-components";
|
|
19
|
+
import { fn } from "storybook/test";
|
|
20
|
+
|
|
21
|
+
const meta: Meta<typeof TimeField> = {
|
|
22
|
+
component: TimeField,
|
|
23
|
+
argTypes: {
|
|
24
|
+
label: { control: "text" },
|
|
25
|
+
value: { control: false },
|
|
26
|
+
description: { control: "text" },
|
|
27
|
+
helperText: { control: "text" },
|
|
28
|
+
errorHelperText: { control: "text" },
|
|
29
|
+
successHelperText: { control: "text" },
|
|
30
|
+
},
|
|
31
|
+
parameters: {
|
|
32
|
+
layout: "centered",
|
|
33
|
+
},
|
|
34
|
+
decorators: [
|
|
35
|
+
(Story, context) => (
|
|
36
|
+
<I18nProvider locale={context.parameters.locale || "en-EN"}>
|
|
37
|
+
<Story />
|
|
38
|
+
</I18nProvider>
|
|
39
|
+
),
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
export default meta;
|
|
43
|
+
|
|
44
|
+
export const Playground: StoryObj<typeof TimeField> = {
|
|
45
|
+
args: {
|
|
46
|
+
label: "Time Field",
|
|
47
|
+
id: "time-field",
|
|
48
|
+
defaultValue: "12:34:56",
|
|
49
|
+
onChange: fn(),
|
|
50
|
+
labelIconRight: "help_outline",
|
|
51
|
+
labelIconRightTooltip: "Additional information",
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const Empty: StoryObj<typeof TimeField> = {
|
|
56
|
+
args: {
|
|
57
|
+
...Playground.args,
|
|
58
|
+
defaultValue: undefined,
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const OnlyHour: StoryObj<typeof TimeField> = {
|
|
63
|
+
args: {
|
|
64
|
+
...Playground.args,
|
|
65
|
+
defaultValue: "12",
|
|
66
|
+
granularity: "hour",
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const HourMinute: StoryObj<typeof TimeField> = {
|
|
71
|
+
args: {
|
|
72
|
+
...Playground.args,
|
|
73
|
+
defaultValue: "12:34",
|
|
74
|
+
granularity: "minute",
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const HourMinuteSecond: StoryObj<typeof TimeField> = {
|
|
79
|
+
args: {
|
|
80
|
+
...Playground.args,
|
|
81
|
+
defaultValue: "12:34:56",
|
|
82
|
+
granularity: "second",
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const LocaleFR: StoryObj<typeof TimeField> = {
|
|
87
|
+
parameters: {
|
|
88
|
+
locale: "fr-FR",
|
|
89
|
+
},
|
|
90
|
+
args: {
|
|
91
|
+
...HourMinuteSecond.args,
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const Disabled: StoryObj<typeof TimeField> = {
|
|
96
|
+
args: {
|
|
97
|
+
...Playground.args,
|
|
98
|
+
isDisabled: true,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export const WithError: StoryObj<typeof TimeField> = {
|
|
103
|
+
args: {
|
|
104
|
+
...Playground.args,
|
|
105
|
+
helperText: undefined,
|
|
106
|
+
errorHelperText: "Error message",
|
|
107
|
+
errorHelperTextIcon: "error_outline",
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const WithSuccess: StoryObj<typeof TimeField> = {
|
|
112
|
+
args: {
|
|
113
|
+
...Playground.args,
|
|
114
|
+
helperText: undefined,
|
|
115
|
+
successHelperText: "Success message",
|
|
116
|
+
successHelperTextIcon: "check",
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export const WithWarning: StoryObj<typeof TimeField> = {
|
|
121
|
+
args: {
|
|
122
|
+
...Playground.args,
|
|
123
|
+
helperText: undefined,
|
|
124
|
+
warningHelperText: "Warning message",
|
|
125
|
+
warningHelperTextIcon: "warning_amber",
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export const WithHorizontalOrientation: StoryObj<typeof TimeField> = {
|
|
130
|
+
args: {
|
|
131
|
+
...Playground.args,
|
|
132
|
+
orientation: "horizontal",
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export const FullWidth: StoryObj<typeof TimeField> = {
|
|
137
|
+
parameters: {
|
|
138
|
+
layout: "padded",
|
|
139
|
+
},
|
|
140
|
+
args: {
|
|
141
|
+
...Playground.args,
|
|
142
|
+
fullWidth: true,
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## How to test this component
|
|
148
|
+
|
|
149
|
+
Here are some more advanced stories with more testing coverage and examples that you can read to understand how to test this component.
|
|
150
|
+
|
|
151
|
+
```tsx
|
|
152
|
+
import { Meta, StoryObj } from "@storybook/react-vite";
|
|
153
|
+
import TimeField from "../TimeField";
|
|
154
|
+
import { userEvent, within, expect, fn } from "storybook/test";
|
|
155
|
+
import { I18nProvider } from "react-aria-components";
|
|
156
|
+
import { useState } from "react";
|
|
157
|
+
import { Playground } from "../TimeField.stories";
|
|
158
|
+
|
|
159
|
+
const meta: Meta<typeof TimeField> = {
|
|
160
|
+
component: TimeField,
|
|
161
|
+
argTypes: {
|
|
162
|
+
label: { control: "text" },
|
|
163
|
+
},
|
|
164
|
+
parameters: {
|
|
165
|
+
layout: "centered",
|
|
166
|
+
chromatic: { disableSnapshot: true },
|
|
167
|
+
},
|
|
168
|
+
decorators: [
|
|
169
|
+
(Story) => (
|
|
170
|
+
<I18nProvider locale="en-EN">
|
|
171
|
+
<Story />
|
|
172
|
+
</I18nProvider>
|
|
173
|
+
),
|
|
174
|
+
],
|
|
175
|
+
};
|
|
176
|
+
export default meta;
|
|
177
|
+
|
|
178
|
+
export const ShouldSelectAValue: StoryObj<typeof TimeField> = {
|
|
179
|
+
args: {
|
|
180
|
+
...Playground.args,
|
|
181
|
+
defaultValue: "12:34",
|
|
182
|
+
onChange: fn(),
|
|
183
|
+
},
|
|
184
|
+
play: async ({ canvasElement, args }) => {
|
|
185
|
+
const canvas = within(canvasElement);
|
|
186
|
+
const user = userEvent.setup({ delay: 50 });
|
|
187
|
+
await expect(canvas.getByLabelText("hour, Time Field")).toHaveTextContent(
|
|
188
|
+
"12",
|
|
189
|
+
);
|
|
190
|
+
await expect(canvas.getByLabelText("minute, Time Field")).toHaveTextContent(
|
|
191
|
+
"34",
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
await user.type(canvas.getByLabelText("hour, Time Field"), "11");
|
|
195
|
+
await expect(canvas.getByLabelText("hour, Time Field")).toHaveTextContent(
|
|
196
|
+
"11",
|
|
197
|
+
);
|
|
198
|
+
await user.type(canvas.getByLabelText("minute, Time Field"), "59");
|
|
199
|
+
await expect(canvas.getByLabelText("minute, Time Field")).toHaveTextContent(
|
|
200
|
+
"59",
|
|
201
|
+
);
|
|
202
|
+
await user.type(canvas.getByLabelText("AM/PM, Time Field"), "A");
|
|
203
|
+
|
|
204
|
+
await expect(args.onChange).toHaveBeenCalledWith("11:59:00");
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
export const ExampleControlled: StoryObj<typeof TimeField> = {
|
|
209
|
+
render: () => {
|
|
210
|
+
const ParentComponent = () => {
|
|
211
|
+
const [value, setValue] = useState("12:34");
|
|
212
|
+
|
|
213
|
+
return (
|
|
214
|
+
<>
|
|
215
|
+
<div>Selected time : {value}</div>
|
|
216
|
+
<TimeField
|
|
217
|
+
value={value}
|
|
218
|
+
onChange={setValue}
|
|
219
|
+
id="example-controlled time field"
|
|
220
|
+
label="Time Field"
|
|
221
|
+
/>
|
|
222
|
+
</>
|
|
223
|
+
);
|
|
224
|
+
};
|
|
225
|
+
return <ParentComponent />;
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export const ControlledShouldSelectAValue: StoryObj<typeof TimeField> = {
|
|
230
|
+
render: ExampleControlled.render,
|
|
231
|
+
play: async ({ canvasElement }) => {
|
|
232
|
+
const canvas = within(canvasElement);
|
|
233
|
+
const user = userEvent.setup({ delay: 50 });
|
|
234
|
+
await canvas.findByText("Selected time : 12:34");
|
|
235
|
+
await user.type(canvas.getByLabelText("hour, Time Field"), "11");
|
|
236
|
+
await user.type(canvas.getByLabelText("minute, Time Field"), "59");
|
|
237
|
+
await user.type(canvas.getByLabelText("AM/PM, Time Field"), "A");
|
|
238
|
+
await canvas.findByText("Selected time : 11:59:00");
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
export const ExampleGranularity: StoryObj<typeof TimeField> = {
|
|
243
|
+
render: () => {
|
|
244
|
+
function Example() {
|
|
245
|
+
const [time, setDate] = useState("12:34");
|
|
246
|
+
|
|
247
|
+
return (
|
|
248
|
+
<>
|
|
249
|
+
<TimeField
|
|
250
|
+
id="time-and-time"
|
|
251
|
+
label="Date and time"
|
|
252
|
+
granularity="second"
|
|
253
|
+
value={time}
|
|
254
|
+
onChange={setDate}
|
|
255
|
+
/>
|
|
256
|
+
<TimeField
|
|
257
|
+
id="time"
|
|
258
|
+
label="Date"
|
|
259
|
+
granularity="hour"
|
|
260
|
+
value={time}
|
|
261
|
+
onChange={setDate}
|
|
262
|
+
/>
|
|
263
|
+
</>
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
return <Example />;
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
export const ExampleGranularity2: StoryObj<typeof TimeField> = {
|
|
271
|
+
render: () => {
|
|
272
|
+
function Example() {
|
|
273
|
+
return (
|
|
274
|
+
<>
|
|
275
|
+
<TimeField id="second" label="Event time" granularity="second" />
|
|
276
|
+
<TimeField id="hour" label="Event time" granularity="hour" />
|
|
277
|
+
</>
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
return <Example />;
|
|
281
|
+
},
|
|
282
|
+
};
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## Developer notes
|
|
286
|
+
|
|
287
|
+
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.
|
|
288
|
+
|
|
289
|
+
```mdx
|
|
290
|
+
import {
|
|
291
|
+
Canvas,
|
|
292
|
+
Meta,
|
|
293
|
+
Stories,
|
|
294
|
+
Controls,
|
|
295
|
+
Source,
|
|
296
|
+
Story,
|
|
297
|
+
} from "@storybook/addon-docs/blocks";
|
|
298
|
+
|
|
299
|
+
import * as TimeField from "./TimeField.stories";
|
|
300
|
+
import * as TimeFieldTests from "./tests/TimeField.stories";
|
|
301
|
+
|
|
302
|
+
<Meta of={TimeField} />
|
|
303
|
+
|
|
304
|
+
# TimeField
|
|
305
|
+
|
|
306
|
+
A time field allows users to enter and edit time values using a keyboard. Each part of a time value is displayed in an individually editable segment.
|
|
307
|
+
|
|
308
|
+
<Canvas of={TimeField.Playground} />
|
|
309
|
+
<Controls of={TimeField.Playground} />
|
|
310
|
+
|
|
311
|
+
## Example
|
|
312
|
+
|
|
313
|
+
<Source of={TimeFieldTests.ExampleControlled} type="code" dark />
|
|
314
|
+
|
|
315
|
+
A time field can be built using `<input type="time">`, but this is very limited in functionality, lacking in internationalization capabilities, inconsistent between browsers, and difficult to style.
|
|
316
|
+
TimeField helps achieve accessible and international time fields that can be styled as needed.
|
|
317
|
+
|
|
318
|
+
- **International** – Support for locale-specific formatting, number systems, hour cycles, and right-to-left layout.
|
|
319
|
+
- **Accessible** – Each time unit is displayed as an individually focusable and editable segment, which allows users an easy way to edit times using the keyboard, in any format and locale.
|
|
320
|
+
- **Touch friendly** – Time segments are editable using an easy to use numeric keypad, and all interactions are accessible using touch-based screen readers.
|
|
321
|
+
|
|
322
|
+
Read [the React Aria blog post](https://react-spectrum.adobe.com/blog/date-and-time-pickers-for-all.html) for more details about the internationalization, accessibility, and user experience features implemented by TimeField.
|
|
323
|
+
|
|
324
|
+
## Value
|
|
325
|
+
|
|
326
|
+
A `TimeField` displays a placeholder by default. An initial, uncontrolled value can be provided to the `TimeField` using the `defaultValue` prop.
|
|
327
|
+
Alternatively, a controlled value can be provided using the `value` and `onchange` props.
|
|
328
|
+
|
|
329
|
+
Time values are provided as string.
|
|
330
|
+
This component handles correct international time manipulation across time zones and other localization concerns.
|
|
331
|
+
TimeField supports values of the following string formats:
|
|
332
|
+
|
|
333
|
+
- `hh` -> only the hour is displayed
|
|
334
|
+
- `hh:mm` -> only the hour and minute are displayed
|
|
335
|
+
- `hh:mm:ss` -> only the hour, minute and second are displayed
|
|
336
|
+
- `hh:mm:ss.sss` -> the hour, minute, second and millisecond are displayed (millisecond are not selectable by the user and will not change when the rest of the time is changed)
|
|
337
|
+
|
|
338
|
+
## Granularity
|
|
339
|
+
|
|
340
|
+
The granularity prop allows you to control the smallest unit that is displayed by TimeField. By default, times are displayed with "minute" granularity.
|
|
341
|
+
More granular time values can be displayed by setting the granularity prop to "second".
|
|
342
|
+
|
|
343
|
+
<Canvas of={TimeFieldTests.ExampleGranularity} sourceState="shown" />
|
|
344
|
+
|
|
345
|
+
## How to test this component
|
|
346
|
+
|
|
347
|
+
The fields to type the hours/minute/seconds are not real inputs, but you can still fill them with `userEvent.type` as well.
|
|
348
|
+
Just inspect the rendered HTML and you will see that every targetable element has a dedicated aria-label that you can target with `getByLabelText`.
|
|
349
|
+
|
|
350
|
+
Here is a complete example of one of our tests using Storybook and Testing Library:
|
|
351
|
+
|
|
352
|
+
<Source of={TimeFieldTests.ShouldSelectAValue} type="code" dark />
|
|
353
|
+
```
|