@ceed/ads 1.35.1 → 1.37.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -95
- package/dist/components/Accordions/Accordions.d.ts +1 -0
- package/dist/components/Alert/Alert.d.ts +5 -5
- package/dist/components/Autocomplete/Autocomplete.d.ts +2 -2
- package/dist/components/Avatar/Avatar.d.ts +7 -17
- package/dist/components/Box/Box.d.ts +1 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +6 -5
- package/dist/components/Button/Button.d.ts +3 -2
- package/dist/components/Calendar/Calendar.d.ts +1 -0
- package/dist/components/Card/Card.d.ts +1 -0
- package/dist/components/Checkbox/Checkbox.d.ts +1 -0
- package/dist/components/Chip/Chip.d.ts +1 -0
- package/dist/components/Container/Container.d.ts +6 -1
- package/dist/components/DialogActions/DialogActions.d.ts +1 -0
- package/dist/components/DialogContent/DialogContent.d.ts +1 -0
- package/dist/components/DialogFrame/DialogFrame.d.ts +1 -1
- package/dist/components/DialogTitle/DialogTitle.d.ts +1 -0
- package/dist/components/Divider/Divider.d.ts +1 -0
- package/dist/components/Dropdown/Dropdown.d.ts +28 -1
- package/dist/components/FilterMenu/components/MonthRange.d.ts +11 -0
- package/dist/components/FilterMenu/types.d.ts +5 -1
- package/dist/components/FilterableCheckboxGroup/FilterableCheckboxGroup.d.ts +1 -1
- package/dist/components/FormControl/FormControl.d.ts +1 -0
- package/dist/components/FormHelperText/FormHelperText.d.ts +1 -0
- package/dist/components/FormLabel/FormLabel.d.ts +1 -0
- package/dist/components/Grid/Grid.d.ts +1 -0
- package/dist/components/IconButton/IconButton.d.ts +3 -2
- package/dist/components/IconMenuButton/IconMenuButton.d.ts +7 -6
- package/dist/components/InfoSign/InfoSign.d.ts +3 -2
- package/dist/components/Input/Input.d.ts +8 -22
- package/dist/components/InsetDrawer/InsetDrawer.d.ts +1 -0
- package/dist/components/Markdown/Markdown.d.ts +9 -24
- package/dist/components/Menu/Menu.d.ts +2 -1
- package/dist/components/MenuButton/MenuButton.d.ts +10 -8
- package/dist/components/Modal/Modal.d.ts +4 -2
- package/dist/components/NavigationGroup/NavigationGroup.d.ts +3 -2
- package/dist/components/NavigationItem/NavigationItem.d.ts +3 -2
- package/dist/components/Navigator/Navigator.d.ts +5 -4
- package/dist/components/Pagination/Pagination.d.ts +2 -2
- package/dist/components/ProfileMenu/ProfileMenu.d.ts +3 -3
- package/dist/components/Radio/Radio.d.ts +1 -0
- package/dist/components/RadioList/RadioList.d.ts +3 -2
- package/dist/components/Select/Select.d.ts +12 -10
- package/dist/components/Sheet/Sheet.d.ts +1 -0
- package/dist/components/Stack/Stack.d.ts +1 -0
- package/dist/components/Stepper/Stepper.d.ts +2 -1
- package/dist/components/Switch/Switch.d.ts +1 -0
- package/dist/components/Table/Table.d.ts +7 -5
- package/dist/components/Tabs/Tabs.d.ts +1 -0
- package/dist/components/Textarea/Textarea.d.ts +8 -20
- package/dist/components/ThemeProvider/ThemeProvider.d.ts +24 -2
- package/dist/components/Tooltip/Tooltip.d.ts +1 -0
- package/dist/components/Typography/Typography.d.ts +1 -0
- package/dist/components/Uploader/Uploader.d.ts +18 -17
- package/dist/components/data-display/Avatar.md +61 -73
- package/dist/components/data-display/Badge.md +198 -182
- package/dist/components/data-display/Chip.md +165 -143
- package/dist/components/data-display/DataTable.md +843 -338
- package/dist/components/data-display/InfoSign.md +1 -3
- package/dist/components/data-display/Markdown.md +93 -125
- package/dist/components/data-display/Table.md +1454 -1008
- package/dist/components/data-display/Tooltip.md +1 -1
- package/dist/components/data-display/Typography.md +101 -104
- package/dist/components/feedback/Alert.md +81 -87
- package/dist/components/feedback/CircularProgress.md +34 -38
- package/dist/components/feedback/Dialog.md +25 -17
- package/dist/components/feedback/Modal.md +297 -266
- package/dist/components/feedback/Skeleton.md +125 -89
- package/dist/components/index.d.ts +60 -1
- package/dist/components/inputs/Autocomplete.md +192 -96
- package/dist/components/inputs/Button.md +85 -85
- package/dist/components/inputs/ButtonGroup.md +197 -187
- package/dist/components/inputs/Calendar.md +25 -28
- package/dist/components/inputs/Checkbox.md +13 -31
- package/dist/components/inputs/CurrencyInput.md +6 -6
- package/dist/components/inputs/DatePicker.md +229 -110
- package/dist/components/inputs/DateRangePicker.md +248 -137
- package/dist/components/inputs/FilterMenu.md +138 -8
- package/dist/components/inputs/FilterableCheckboxGroup.md +116 -56
- package/dist/components/inputs/FormControl.md +76 -70
- package/dist/components/inputs/IconButton.md +231 -207
- package/dist/components/inputs/Input.md +133 -100
- package/dist/components/inputs/MonthPicker.md +186 -84
- package/dist/components/inputs/MonthRangePicker.md +73 -49
- package/dist/components/inputs/PercentageInput.md +17 -33
- package/dist/components/inputs/RadioButton.md +322 -258
- package/dist/components/inputs/RadioList.md +68 -52
- package/dist/components/inputs/RadioTileGroup.md +287 -170
- package/dist/components/inputs/SearchBar.md +82 -60
- package/dist/components/inputs/Select.md +108 -97
- package/dist/components/inputs/Slider.md +155 -104
- package/dist/components/inputs/Switch.md +194 -139
- package/dist/components/inputs/Textarea.md +17 -22
- package/dist/components/inputs/Uploader/Uploader.md +69 -40
- package/dist/components/layout/Box.md +841 -662
- package/dist/components/layout/Container.md +3 -11
- package/dist/components/layout/Grid.md +480 -394
- package/dist/components/layout/Stack.md +739 -566
- package/dist/components/navigation/Breadcrumbs.md +182 -116
- package/dist/components/navigation/Dropdown.md +732 -391
- package/dist/components/navigation/IconMenuButton.md +15 -7
- package/dist/components/navigation/InsetDrawer.md +550 -378
- package/dist/components/navigation/Link.md +104 -94
- package/dist/components/navigation/Menu.md +624 -503
- package/dist/components/navigation/MenuButton.md +19 -11
- package/dist/components/navigation/NavigationGroup.md +19 -50
- package/dist/components/navigation/NavigationItem.md +6 -6
- package/dist/components/navigation/Navigator.md +26 -28
- package/dist/components/navigation/Pagination.md +87 -76
- package/dist/components/navigation/ProfileMenu.md +67 -45
- package/dist/components/navigation/Stepper.md +2 -12
- package/dist/components/navigation/Tabs.md +210 -184
- package/dist/components/surfaces/Accordions.md +90 -173
- package/dist/components/surfaces/Card.md +1096 -711
- package/dist/components/surfaces/Divider.md +562 -412
- package/dist/components/surfaces/Sheet.md +700 -518
- package/dist/guides/ThemeProvider.md +65 -40
- package/dist/index.browser.js +5 -5
- package/dist/index.browser.js.map +4 -4
- package/dist/index.cjs +1906 -1690
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1404 -1180
- package/framer/index.js +1 -1
- package/package.json +34 -36
|
@@ -56,13 +56,7 @@ import { DateRangePicker } from '@ceed/ads';
|
|
|
56
56
|
function DateRangeForm() {
|
|
57
57
|
const [dateRange, setDateRange] = useState('');
|
|
58
58
|
|
|
59
|
-
return (
|
|
60
|
-
<DateRangePicker
|
|
61
|
-
label="Select Date Range"
|
|
62
|
-
value={dateRange}
|
|
63
|
-
onChange={(e) => setDateRange(e.target.value)}
|
|
64
|
-
/>
|
|
65
|
-
);
|
|
59
|
+
return <DateRangePicker label="Select Date Range" value={dateRange} onChange={(e) => setDateRange(e.target.value)} />;
|
|
66
60
|
}
|
|
67
61
|
```
|
|
68
62
|
|
|
@@ -72,10 +66,10 @@ DateRangePicker supports three sizes (`sm`, `md`, `lg`) to fit different layouts
|
|
|
72
66
|
|
|
73
67
|
```tsx
|
|
74
68
|
<Stack gap={2}>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
</Stack>
|
|
69
|
+
<DateRangePicker size="sm" />
|
|
70
|
+
<DateRangePicker size="md" />
|
|
71
|
+
<DateRangePicker size="lg" />
|
|
72
|
+
</Stack>
|
|
79
73
|
```
|
|
80
74
|
|
|
81
75
|
## Form Features
|
|
@@ -183,25 +177,31 @@ In controlled mode, the parent component manages the date range state via `value
|
|
|
183
177
|
|
|
184
178
|
```tsx
|
|
185
179
|
<Stack gap={2}>
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
180
|
+
<DateRangePicker
|
|
181
|
+
{...args}
|
|
182
|
+
onChange={(e) => {
|
|
183
|
+
args.onChange?.(e);
|
|
184
|
+
setValue(e.target.value);
|
|
185
|
+
}}
|
|
186
|
+
value={value}
|
|
187
|
+
/>
|
|
188
|
+
<Button
|
|
189
|
+
onClick={() => {
|
|
190
|
+
const [start, end] = value.split(" - ");
|
|
191
|
+
function shiftMonth(dateString: string) {
|
|
192
|
+
const currentValue = new Date(dateString);
|
|
193
|
+
currentValue.setMonth(currentValue.getMonth() + 1);
|
|
194
|
+
const year = currentValue.getFullYear();
|
|
195
|
+
const month = String(currentValue.getMonth() + 1).padStart(2, "0");
|
|
196
|
+
const day = String(currentValue.getDate()).padStart(2, "0");
|
|
197
|
+
return `${year}/${month}/${day}`;
|
|
198
|
+
}
|
|
199
|
+
setValue(`${shiftMonth(start)} - ${shiftMonth(end)}`);
|
|
200
|
+
}}
|
|
201
|
+
>
|
|
202
|
+
Shift Month
|
|
203
|
+
</Button>
|
|
204
|
+
</Stack>
|
|
205
205
|
```
|
|
206
206
|
|
|
207
207
|
### Uncontrolled
|
|
@@ -225,31 +225,73 @@ The `format` prop controls the format of the value returned in `onChange`. The i
|
|
|
225
225
|
|
|
226
226
|
```tsx
|
|
227
227
|
<Stack gap={2}>
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
228
|
+
<DateRangePicker
|
|
229
|
+
{...args}
|
|
230
|
+
value={value1}
|
|
231
|
+
label="YYYY.MM.DD"
|
|
232
|
+
name="YYYY.MM.DD"
|
|
233
|
+
format="YYYY.MM.DD"
|
|
234
|
+
onChange={(e) => {
|
|
235
|
+
setValue1(e.target.value);
|
|
236
|
+
args.onChange?.(e);
|
|
237
|
+
}}
|
|
238
|
+
/>
|
|
239
|
+
<DateRangePicker
|
|
240
|
+
{...args}
|
|
241
|
+
value={value2}
|
|
242
|
+
label="YYYY/MM/DD"
|
|
243
|
+
name="YYYY/MM/DD"
|
|
244
|
+
format="YYYY/MM/DD"
|
|
245
|
+
onChange={(e) => {
|
|
246
|
+
setValue2(e.target.value);
|
|
247
|
+
args.onChange?.(e);
|
|
248
|
+
}}
|
|
249
|
+
/>
|
|
250
|
+
<DateRangePicker
|
|
251
|
+
{...args}
|
|
252
|
+
value={value3}
|
|
253
|
+
label="MM/DD/YYYY"
|
|
254
|
+
name="MM/DD/YYYY"
|
|
255
|
+
format="MM/DD/YYYY"
|
|
256
|
+
onChange={(e) => {
|
|
257
|
+
setValue3(e.target.value);
|
|
258
|
+
args.onChange?.(e);
|
|
259
|
+
}}
|
|
260
|
+
/>
|
|
261
|
+
<DateRangePicker
|
|
262
|
+
{...args}
|
|
263
|
+
value={value4}
|
|
264
|
+
label="YYYY-MM-DD"
|
|
265
|
+
name="YYYY-MM-DD"
|
|
266
|
+
format="YYYY-MM-DD"
|
|
267
|
+
onChange={(e) => {
|
|
268
|
+
setValue4(e.target.value);
|
|
269
|
+
args.onChange?.(e);
|
|
270
|
+
}}
|
|
271
|
+
/>
|
|
272
|
+
<DateRangePicker
|
|
273
|
+
{...args}
|
|
274
|
+
value={value5}
|
|
275
|
+
label="DD/MM/YYYY"
|
|
276
|
+
name="DD/MM/YYYY"
|
|
277
|
+
format="DD/MM/YYYY"
|
|
278
|
+
onChange={(e) => {
|
|
279
|
+
setValue5(e.target.value);
|
|
280
|
+
args.onChange?.(e);
|
|
281
|
+
}}
|
|
282
|
+
/>
|
|
283
|
+
<DateRangePicker
|
|
284
|
+
{...args}
|
|
285
|
+
value={value6}
|
|
286
|
+
label="DD.MM.YYYY"
|
|
287
|
+
name="DD.MM.YYYY"
|
|
288
|
+
format="DD.MM.YYYY"
|
|
289
|
+
onChange={(e) => {
|
|
290
|
+
setValue6(e.target.value);
|
|
291
|
+
args.onChange?.(e);
|
|
292
|
+
}}
|
|
293
|
+
/>
|
|
294
|
+
</Stack>
|
|
253
295
|
```
|
|
254
296
|
|
|
255
297
|
### Display Format (`displayFormat`)
|
|
@@ -258,31 +300,73 @@ The `displayFormat` prop controls what the user sees in the input field. This is
|
|
|
258
300
|
|
|
259
301
|
```tsx
|
|
260
302
|
<Stack gap={2}>
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
303
|
+
<DateRangePicker
|
|
304
|
+
{...args}
|
|
305
|
+
value={value1}
|
|
306
|
+
label="YYYY.MM.DD"
|
|
307
|
+
name="YYYY.MM.DD"
|
|
308
|
+
displayFormat="YYYY.MM.DD"
|
|
309
|
+
onChange={(e) => {
|
|
310
|
+
setValue1(e.target.value);
|
|
311
|
+
args.onChange?.(e);
|
|
312
|
+
}}
|
|
313
|
+
/>
|
|
314
|
+
<DateRangePicker
|
|
315
|
+
{...args}
|
|
316
|
+
value={value2}
|
|
317
|
+
label="YYYY/MM/DD"
|
|
318
|
+
name="YYYY/MM/DD"
|
|
319
|
+
displayFormat="YYYY/MM/DD"
|
|
320
|
+
onChange={(e) => {
|
|
321
|
+
setValue2(e.target.value);
|
|
322
|
+
args.onChange?.(e);
|
|
323
|
+
}}
|
|
324
|
+
/>
|
|
325
|
+
<DateRangePicker
|
|
326
|
+
{...args}
|
|
327
|
+
value={value3}
|
|
328
|
+
label="MM/DD/YYYY"
|
|
329
|
+
name="MM/DD/YYYY"
|
|
330
|
+
displayFormat="MM/DD/YYYY"
|
|
331
|
+
onChange={(e) => {
|
|
332
|
+
setValue3(e.target.value);
|
|
333
|
+
args.onChange?.(e);
|
|
334
|
+
}}
|
|
335
|
+
/>
|
|
336
|
+
<DateRangePicker
|
|
337
|
+
{...args}
|
|
338
|
+
value={value4}
|
|
339
|
+
label="YYYY-MM-DD"
|
|
340
|
+
name="YYYY-MM-DD"
|
|
341
|
+
displayFormat="YYYY-MM-DD"
|
|
342
|
+
onChange={(e) => {
|
|
343
|
+
setValue4(e.target.value);
|
|
344
|
+
args.onChange?.(e);
|
|
345
|
+
}}
|
|
346
|
+
/>
|
|
347
|
+
<DateRangePicker
|
|
348
|
+
{...args}
|
|
349
|
+
value={value5}
|
|
350
|
+
label="DD/MM/YYYY"
|
|
351
|
+
name="DD/MM/YYYY"
|
|
352
|
+
displayFormat="DD/MM/YYYY"
|
|
353
|
+
onChange={(e) => {
|
|
354
|
+
setValue5(e.target.value);
|
|
355
|
+
args.onChange?.(e);
|
|
356
|
+
}}
|
|
357
|
+
/>
|
|
358
|
+
<DateRangePicker
|
|
359
|
+
{...args}
|
|
360
|
+
value={value6}
|
|
361
|
+
label="DD.MM.YYYY"
|
|
362
|
+
name="DD.MM.YYYY"
|
|
363
|
+
displayFormat="DD.MM.YYYY"
|
|
364
|
+
onChange={(e) => {
|
|
365
|
+
setValue6(e.target.value);
|
|
366
|
+
args.onChange?.(e);
|
|
367
|
+
}}
|
|
368
|
+
/>
|
|
369
|
+
</Stack>
|
|
286
370
|
```
|
|
287
371
|
|
|
288
372
|
**Supported format tokens:**
|
|
@@ -296,8 +380,8 @@ The `displayFormat` prop controls what the user sees in the input field. This is
|
|
|
296
380
|
```tsx
|
|
297
381
|
// format affects onChange value; displayFormat affects what users see
|
|
298
382
|
<DateRangePicker
|
|
299
|
-
format="YYYY-MM-DD"
|
|
300
|
-
displayFormat="MM/DD/YYYY"
|
|
383
|
+
format="YYYY-MM-DD" // onChange returns "2024-04-01 - 2024-04-15"
|
|
384
|
+
displayFormat="MM/DD/YYYY" // Input shows "04/01/2024 - 04/15/2024"
|
|
301
385
|
/>
|
|
302
386
|
```
|
|
303
387
|
|
|
@@ -353,25 +437,37 @@ Use the `numberOfMonths` prop to display two calendar months side by side in the
|
|
|
353
437
|
When combined with `presets`, the dual calendar provides a fast, at-a-glance interface for report and analytics date filters.
|
|
354
438
|
|
|
355
439
|
```tsx
|
|
356
|
-
<DateRangePicker
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
},
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
440
|
+
<DateRangePicker
|
|
441
|
+
{...args}
|
|
442
|
+
value={value}
|
|
443
|
+
onChange={(e) => {
|
|
444
|
+
setValue(e.target.value);
|
|
445
|
+
args.onChange?.(e);
|
|
446
|
+
}}
|
|
447
|
+
disableFuture
|
|
448
|
+
presets={[
|
|
449
|
+
{
|
|
450
|
+
label: "Today",
|
|
451
|
+
value: `${fmt(today)} - ${fmt(today)}`
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
label: "Last 7 days",
|
|
455
|
+
value: range(7)
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
label: "Last 1 month",
|
|
459
|
+
value: range(1, "months")
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
label: "Last 3 months",
|
|
463
|
+
value: range(3, "months")
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
label: "Last 6 months",
|
|
467
|
+
value: range(6, "months")
|
|
468
|
+
}
|
|
469
|
+
]}
|
|
470
|
+
/>
|
|
375
471
|
```
|
|
376
472
|
|
|
377
473
|
```tsx
|
|
@@ -394,28 +490,40 @@ Use the `presets` prop to display quick-select options alongside the calendar, s
|
|
|
394
490
|
Each preset's `value` must match the component's `format` prop and use the `-` separator (e.g., `"2026/03/01 - 2026/04/03"`). When the current value matches a preset, that preset is automatically highlighted -- regardless of whether the value was set via the preset button or by selecting the same range on the calendar.
|
|
395
491
|
|
|
396
492
|
```tsx
|
|
397
|
-
<DateRangePicker
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
},
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
493
|
+
<DateRangePicker
|
|
494
|
+
{...args}
|
|
495
|
+
value={value}
|
|
496
|
+
onChange={(e) => {
|
|
497
|
+
setValue(e.target.value);
|
|
498
|
+
args.onChange?.(e);
|
|
499
|
+
}}
|
|
500
|
+
presets={[
|
|
501
|
+
{
|
|
502
|
+
label: "Today",
|
|
503
|
+
value: `${fmt(today)} - ${fmt(today)}`
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
label: "Last 3 days",
|
|
507
|
+
value: range(3)
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
label: "Last 7 days",
|
|
511
|
+
value: range(7)
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
label: "Last 1 month",
|
|
515
|
+
value: range(1, "months")
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
label: "Last 3 months",
|
|
519
|
+
value: range(3, "months")
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
label: "Last 6 months",
|
|
523
|
+
value: range(6, "months")
|
|
524
|
+
}
|
|
525
|
+
]}
|
|
526
|
+
/>
|
|
419
527
|
```
|
|
420
528
|
|
|
421
529
|
```tsx
|
|
@@ -466,15 +574,21 @@ Remove the clear button from the calendar popup using `hideClearButton`.
|
|
|
466
574
|
Example of integrating an external reset button to clear the selected date range programmatically.
|
|
467
575
|
|
|
468
576
|
```tsx
|
|
469
|
-
<div
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
577
|
+
<div
|
|
578
|
+
style={{
|
|
579
|
+
display: "flex",
|
|
580
|
+
gap: "10px"
|
|
581
|
+
}}
|
|
582
|
+
>
|
|
583
|
+
<DateRangePicker
|
|
584
|
+
{...props}
|
|
585
|
+
value={value}
|
|
586
|
+
onChange={(event) => {
|
|
587
|
+
setValue(event.target.value);
|
|
588
|
+
}}
|
|
589
|
+
/>
|
|
590
|
+
<Button onClick={() => setValue("")}>Reset</Button>
|
|
591
|
+
</div>
|
|
478
592
|
```
|
|
479
593
|
|
|
480
594
|
## Booking Form
|
|
@@ -575,10 +689,7 @@ function DataExport() {
|
|
|
575
689
|
|
|
576
690
|
```tsx
|
|
577
691
|
// Store ISO format, display locale format
|
|
578
|
-
<DateRangePicker
|
|
579
|
-
format="YYYY-MM-DD"
|
|
580
|
-
displayFormat="MM/DD/YYYY"
|
|
581
|
-
/>
|
|
692
|
+
<DateRangePicker format="YYYY-MM-DD" displayFormat="MM/DD/YYYY" />
|
|
582
693
|
```
|
|
583
694
|
|
|
584
695
|
3. **Use `inputReadOnly` on mobile**: On touch devices, keyboard input for date ranges is error-prone. Use `inputReadOnly` to force calendar selection.
|
|
@@ -605,7 +716,7 @@ const getDuration = (value) => {
|
|
|
605
716
|
return `${days} day${days !== 1 ? 's' : ''} selected`;
|
|
606
717
|
};
|
|
607
718
|
|
|
608
|
-
<DateRangePicker helperText={getDuration(dateRange)}
|
|
719
|
+
<DateRangePicker helperText={getDuration(dateRange)} />;
|
|
609
720
|
```
|
|
610
721
|
|
|
611
722
|
## Props and Customization
|
|
@@ -7,10 +7,14 @@ FilterMenu is a comprehensive filtering component that supports multiple filter
|
|
|
7
7
|
FilterMenu is ideal for data-heavy admin interfaces such as tables, lists, and dashboards where users need to narrow down results based on multiple criteria. It supports both controlled and uncontrolled state management, allowing flexible integration with different state architectures.
|
|
8
8
|
|
|
9
9
|
```tsx
|
|
10
|
-
<FilterMenu
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
<FilterMenu
|
|
11
|
+
{...args}
|
|
12
|
+
defaultValues={values}
|
|
13
|
+
onChange={(newValues) => {
|
|
14
|
+
setValues(newValues);
|
|
15
|
+
args.onChange!(newValues);
|
|
16
|
+
}}
|
|
17
|
+
/>
|
|
14
18
|
```
|
|
15
19
|
|
|
16
20
|
| Field | Description | Default |
|
|
@@ -128,6 +132,21 @@ A date range picker filter. The value is stored as a two-element array of date s
|
|
|
128
132
|
}
|
|
129
133
|
```
|
|
130
134
|
|
|
135
|
+
### Month Range
|
|
136
|
+
|
|
137
|
+
A month range picker filter, built on `MonthRangePicker`. The value is stored as a two-element array of month strings. Both ends follow the `format` you provide (default `YYYY/MM`), so the value tuple format is fully controlled by the consumer.
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
{
|
|
141
|
+
id: 'monthRange',
|
|
142
|
+
type: 'month-range',
|
|
143
|
+
label: 'Month Range',
|
|
144
|
+
format: 'YYYY-MM',
|
|
145
|
+
displayFormat: 'MMM YYYY',
|
|
146
|
+
}
|
|
147
|
+
// value → ['2025-01', '2025-06']
|
|
148
|
+
```
|
|
149
|
+
|
|
131
150
|
### Currency Input
|
|
132
151
|
|
|
133
152
|
A single currency value input field.
|
|
@@ -204,10 +223,14 @@ A searchable single-select filter with autocomplete support.
|
|
|
204
223
|
In controlled mode, you manage the filter state externally using `values` (or `defaultValues` with an `onChange` handler).
|
|
205
224
|
|
|
206
225
|
```tsx
|
|
207
|
-
<FilterMenu
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
226
|
+
<FilterMenu
|
|
227
|
+
{...args}
|
|
228
|
+
defaultValues={values}
|
|
229
|
+
onChange={(newValues) => {
|
|
230
|
+
setValues(newValues);
|
|
231
|
+
args.onChange!(newValues);
|
|
232
|
+
}}
|
|
233
|
+
/>
|
|
211
234
|
```
|
|
212
235
|
|
|
213
236
|
## Uncontrolled FilterMenu
|
|
@@ -218,6 +241,111 @@ In uncontrolled mode, FilterMenu manages its own internal state. This is useful
|
|
|
218
241
|
<FilterMenu />
|
|
219
242
|
```
|
|
220
243
|
|
|
244
|
+
## Filter Button with Dropdown Trigger
|
|
245
|
+
|
|
246
|
+
In real applications, FilterMenu is opened from a toolbar "Filter" button rather than rendered inline. Compose it with `Dropdown` and `MenuButtonTrigger`: FilterMenu renders with `position: relative` (it is not a centered modal), so it sits naturally inside the dropdown popover. Control the `Dropdown` `open` state so the panel's **Apply** / **Reset** buttons can close the popover through `onClose`.
|
|
247
|
+
|
|
248
|
+
```tsx
|
|
249
|
+
<Dropdown open={open} onOpenChange={(_event, isOpen) => setOpen(isOpen)}>
|
|
250
|
+
<MenuButtonTrigger
|
|
251
|
+
variant="outlined"
|
|
252
|
+
startDecorator={<FilterListIcon />}
|
|
253
|
+
endDecorator={<ExpandMoreIcon />}
|
|
254
|
+
>
|
|
255
|
+
Filters
|
|
256
|
+
</MenuButtonTrigger>
|
|
257
|
+
<Menu
|
|
258
|
+
placement="bottom-start"
|
|
259
|
+
sx={{
|
|
260
|
+
p: 0,
|
|
261
|
+
border: "none",
|
|
262
|
+
boxShadow: "none",
|
|
263
|
+
bgcolor: "transparent"
|
|
264
|
+
}}
|
|
265
|
+
>
|
|
266
|
+
<FilterMenu
|
|
267
|
+
filters={[
|
|
268
|
+
{
|
|
269
|
+
id: "status",
|
|
270
|
+
type: "checkbox-group",
|
|
271
|
+
label: "Status",
|
|
272
|
+
options: [
|
|
273
|
+
{
|
|
274
|
+
label: "Active",
|
|
275
|
+
value: "active"
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
label: "Inactive",
|
|
279
|
+
value: "inactive"
|
|
280
|
+
}
|
|
281
|
+
]
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
id: "priority",
|
|
285
|
+
type: "radio-group",
|
|
286
|
+
label: "Priority",
|
|
287
|
+
options: [
|
|
288
|
+
{
|
|
289
|
+
label: "High",
|
|
290
|
+
value: "high"
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
label: "Medium",
|
|
294
|
+
value: "medium"
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
label: "Low",
|
|
298
|
+
value: "low"
|
|
299
|
+
}
|
|
300
|
+
]
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
id: "amountRange",
|
|
304
|
+
type: "currency-range",
|
|
305
|
+
label: "Amount Range",
|
|
306
|
+
currency: "USD"
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
id: "monthRange",
|
|
310
|
+
type: "month-range",
|
|
311
|
+
label: "Month Range",
|
|
312
|
+
format: "YYYY-MM",
|
|
313
|
+
displayFormat: "MMM YYYY"
|
|
314
|
+
}
|
|
315
|
+
]}
|
|
316
|
+
values={values}
|
|
317
|
+
onChange={(newValues) => setValues(newValues)}
|
|
318
|
+
onClose={() => setOpen(false)}
|
|
319
|
+
useReset
|
|
320
|
+
/>
|
|
321
|
+
</Menu>
|
|
322
|
+
</Dropdown>
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
```tsx
|
|
326
|
+
import { Dropdown, MenuButtonTrigger, Menu, FilterMenu } from '@ceed/ads';
|
|
327
|
+
import FilterListIcon from '@mui/icons-material/FilterList';
|
|
328
|
+
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
|
329
|
+
|
|
330
|
+
function ToolbarFilter() {
|
|
331
|
+
const [open, setOpen] = useState(false);
|
|
332
|
+
const [values, setValues] = useState({ status: ['active'] });
|
|
333
|
+
|
|
334
|
+
return (
|
|
335
|
+
<Dropdown open={open} onOpenChange={(_event, isOpen) => setOpen(isOpen)}>
|
|
336
|
+
<MenuButtonTrigger variant="outlined" startDecorator={<FilterListIcon />} endDecorator={<ExpandMoreIcon />}>
|
|
337
|
+
Filters
|
|
338
|
+
</MenuButtonTrigger>
|
|
339
|
+
<Menu placement="bottom-start" sx={{ p: 0, border: 'none', boxShadow: 'none', bgcolor: 'transparent' }}>
|
|
340
|
+
<FilterMenu filters={filters} values={values} onChange={setValues} onClose={() => setOpen(false)} useReset />
|
|
341
|
+
</Menu>
|
|
342
|
+
</Dropdown>
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
> **Note**: Use `MenuButtonTrigger` (the low-level composition trigger), not the high-level `MenuButton` -- the latter renders its own item list and cannot host a FilterMenu. Strip the `Menu` surface styling (`p: 0`, transparent background, no border/shadow) so only FilterMenu's own panel surface is visible inside the popover. When FilterMenu is mounted inside `Dropdown`, the dropdown automatically keeps itself open while a picker filter's calendar (e.g. `date-range`, `month-range`) takes focus, so the panel survives nested popover interaction without any custom `onOpenChange` handling.
|
|
348
|
+
|
|
221
349
|
## Table Filters
|
|
222
350
|
|
|
223
351
|
```tsx
|
|
@@ -393,6 +521,7 @@ type FilterItem =
|
|
|
393
521
|
| FilterableCheckboxGroupItem
|
|
394
522
|
| FilterRadioGroupItem
|
|
395
523
|
| FilterDateRangeItem
|
|
524
|
+
| FilterMonthRangeItem
|
|
396
525
|
| FilterCurrencyInputItem
|
|
397
526
|
| FilterCurrencyRangeItem
|
|
398
527
|
| FilterPercentageInputItem
|
|
@@ -408,6 +537,7 @@ type FilterItem =
|
|
|
408
537
|
| `'filterable-checkbox-group'` | `string[]` | Searchable multi-select with checkboxes. Supports `placeholder` and `maxHeight` |
|
|
409
538
|
| `'radio-group'` | `string \| number` | Single-select with radio buttons |
|
|
410
539
|
| `'date-range'` | `[string, string]` | Date range picker. Supports `displayFormat`, `inputReadOnly`, `hideClearButton`, `minDate`, `maxDate`, `disableFuture`, `disablePast` |
|
|
540
|
+
| `'month-range'` | `[string, string]` | Month range picker. Supports `format`, `displayFormat`, `locale`, `minDate`, `maxDate`, `disableFuture`, `disablePast` |
|
|
411
541
|
| `'currency-input'` | `number` | Single currency value. Supports `currency`, `useMinorUnit`, `max`, `placeholder` |
|
|
412
542
|
| `'currency-range'` | `[number, number]` | Currency range (min/max). Supports same props as currency-input |
|
|
413
543
|
| `'percentage-input'` | `number` | Single percentage value. Supports `useMinorUnit`, `maxDecimalScale`, `min`, `max`, `placeholder` |
|