@ceed/ads 1.29.0 → 1.30.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.
Files changed (64) hide show
  1. package/dist/components/CurrencyInput/CurrencyInput.d.ts +1 -1
  2. package/dist/components/CurrencyInput/hooks/use-currency-setting.d.ts +2 -2
  3. package/dist/components/DataTable/hooks.d.ts +2 -1
  4. package/dist/components/DataTable/utils.d.ts +1 -0
  5. package/dist/components/ProfileMenu/ProfileMenu.d.ts +1 -1
  6. package/dist/components/SearchBar/SearchBar.d.ts +21 -0
  7. package/dist/components/SearchBar/index.d.ts +3 -0
  8. package/dist/components/data-display/Badge.md +39 -71
  9. package/dist/components/data-display/DataTable.md +1 -1
  10. package/dist/components/data-display/InfoSign.md +98 -74
  11. package/dist/components/data-display/Typography.md +97 -363
  12. package/dist/components/feedback/Dialog.md +62 -76
  13. package/dist/components/feedback/Modal.md +44 -259
  14. package/dist/components/feedback/llms.txt +0 -2
  15. package/dist/components/index.d.ts +2 -0
  16. package/dist/components/inputs/Autocomplete.md +107 -356
  17. package/dist/components/inputs/ButtonGroup.md +106 -115
  18. package/dist/components/inputs/Calendar.md +459 -98
  19. package/dist/components/inputs/CurrencyInput.md +5 -183
  20. package/dist/components/inputs/DatePicker.md +431 -108
  21. package/dist/components/inputs/DateRangePicker.md +492 -131
  22. package/dist/components/inputs/FilterMenu.md +19 -169
  23. package/dist/components/inputs/FilterableCheckboxGroup.md +23 -123
  24. package/dist/components/inputs/IconButton.md +88 -137
  25. package/dist/components/inputs/Input.md +0 -5
  26. package/dist/components/inputs/MonthPicker.md +422 -95
  27. package/dist/components/inputs/MonthRangePicker.md +466 -89
  28. package/dist/components/inputs/PercentageInput.md +16 -185
  29. package/dist/components/inputs/RadioButton.md +35 -163
  30. package/dist/components/inputs/RadioTileGroup.md +61 -150
  31. package/dist/components/inputs/SearchBar.md +44 -0
  32. package/dist/components/inputs/Select.md +326 -222
  33. package/dist/components/inputs/Switch.md +376 -136
  34. package/dist/components/inputs/Textarea.md +10 -213
  35. package/dist/components/inputs/Uploader/Uploader.md +66 -145
  36. package/dist/components/inputs/llms.txt +1 -3
  37. package/dist/components/navigation/Breadcrumbs.md +322 -80
  38. package/dist/components/navigation/Dropdown.md +221 -92
  39. package/dist/components/navigation/IconMenuButton.md +502 -40
  40. package/dist/components/navigation/InsetDrawer.md +738 -68
  41. package/dist/components/navigation/Link.md +298 -39
  42. package/dist/components/navigation/Menu.md +285 -92
  43. package/dist/components/navigation/MenuButton.md +448 -55
  44. package/dist/components/navigation/Pagination.md +338 -47
  45. package/dist/components/navigation/ProfileMenu.md +268 -45
  46. package/dist/components/navigation/Stepper.md +28 -160
  47. package/dist/components/navigation/Tabs.md +316 -57
  48. package/dist/components/surfaces/Sheet.md +334 -151
  49. package/dist/index.browser.js +15 -13
  50. package/dist/index.browser.js.map +4 -4
  51. package/dist/index.cjs +313 -291
  52. package/dist/index.d.ts +1 -1
  53. package/dist/index.js +450 -372
  54. package/dist/llms.txt +1 -8
  55. package/framer/index.js +1 -1
  56. package/package.json +16 -15
  57. package/dist/chunks/rehype-accent-FZRUD7VI.js +0 -39
  58. package/dist/components/feedback/CircularProgress.md +0 -257
  59. package/dist/components/feedback/Skeleton.md +0 -280
  60. package/dist/components/inputs/FormControl.md +0 -361
  61. package/dist/components/inputs/RadioList.md +0 -241
  62. package/dist/components/inputs/Slider.md +0 -334
  63. package/dist/guides/ThemeProvider.md +0 -116
  64. package/dist/guides/llms.txt +0 -9
@@ -43,7 +43,9 @@ function ConfirmationDialog({ open, onClose, onConfirm }) {
43
43
  <Button variant="plain" color="neutral" onClick={onClose}>
44
44
  Cancel
45
45
  </Button>
46
- <Button onClick={onConfirm}>Confirm</Button>
46
+ <Button onClick={onConfirm}>
47
+ Confirm
48
+ </Button>
47
49
  </>
48
50
  }
49
51
  >
@@ -92,61 +94,6 @@ Dialog Content
92
94
  </DialogFrame>
93
95
  ```
94
96
 
95
- ### Standalone Usage
96
-
97
- DialogFrame can be used without a Modal wrapper for embedding dialog-style layouts directly within a page.
98
-
99
- > ⚠️ **Important** ⚠️
100
- >
101
- > When using DialogFrame without Modal, the parent container **must** meet the following requirements:
102
- >
103
- > - `position: 'relative'` — DialogFrame uses absolute positioning internally
104
- > - Explicit `width` and `height` — `height` must be an absolute value (e.g., `300`, `'400px'`), not a relative value like `%` or `auto`
105
- >
106
- > DialogFrame inherits its dimensions from `ModalDialog`, which normally receives sizing from the Modal overlay. Without these constraints, the component will not render with correct dimensions.
107
-
108
- ```tsx
109
- <Box sx={{
110
- position: 'relative',
111
- width: 480,
112
- height: 300
113
- }}>
114
- <DialogFrame {...args} title="Standalone Dialog" actions={<>
115
- <Button variant="plain" color="neutral">
116
- Cancel
117
- </Button>
118
- <Button variant="plain">Confirm</Button>
119
- </>}>
120
- DialogFrame used without Modal. The parent container must provide explicit width and height.
121
- </DialogFrame>
122
- </Box>
123
- ```
124
-
125
- ```tsx
126
- import { DialogFrame, Button, Box } from '@ceed/ads';
127
-
128
- // Standalone usage requires explicit container dimensions
129
- function EmbeddedDialog() {
130
- return (
131
- <Box sx={{ position: 'relative', width: 480, height: 300 }}>
132
- <DialogFrame
133
- title="Settings"
134
- actions={
135
- <>
136
- <Button variant="plain" color="neutral">
137
- Cancel
138
- </Button>
139
- <Button>Save</Button>
140
- </>
141
- }
142
- >
143
- This dialog is embedded directly in the page layout.
144
- </DialogFrame>
145
- </Box>
146
- );
147
- }
148
- ```
149
-
150
97
  ## When to Use
151
98
 
152
99
  ### ✅ Good Use Cases
@@ -230,11 +177,21 @@ function QuickAddDialog({ open, onClose, onSubmit }) {
230
177
  <Stack gap={2}>
231
178
  <FormControl>
232
179
  <FormLabel>Name</FormLabel>
233
- <Input value={name} onChange={(e) => setName(e.target.value)} placeholder="Enter name" autoFocus />
180
+ <Input
181
+ value={name}
182
+ onChange={(e) => setName(e.target.value)}
183
+ placeholder="Enter name"
184
+ autoFocus
185
+ />
234
186
  </FormControl>
235
187
  <FormControl>
236
188
  <FormLabel>Email</FormLabel>
237
- <Input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Enter email" />
189
+ <Input
190
+ type="email"
191
+ value={email}
192
+ onChange={(e) => setEmail(e.target.value)}
193
+ placeholder="Enter email"
194
+ />
238
195
  </FormControl>
239
196
  </Stack>
240
197
  </DialogFrame>
@@ -259,11 +216,15 @@ function UnsavedChangesDialog({ open, onClose, onDiscard, onSave }) {
259
216
  <Button variant="outlined" color="danger" onClick={onDiscard}>
260
217
  Discard
261
218
  </Button>
262
- <Button onClick={onSave}>Save Changes</Button>
219
+ <Button onClick={onSave}>
220
+ Save Changes
221
+ </Button>
263
222
  </>
264
223
  }
265
224
  >
266
- <Typography>You have unsaved changes. Would you like to save them before leaving?</Typography>
225
+ <Typography>
226
+ You have unsaved changes. Would you like to save them before leaving?
227
+ </Typography>
267
228
  </DialogFrame>
268
229
  </Modal>
269
230
  );
@@ -276,7 +237,14 @@ function UnsavedChangesDialog({ open, onClose, onDiscard, onSave }) {
276
237
  function InfoDialog({ open, onClose, title, message }) {
277
238
  return (
278
239
  <Modal open={open} onClose={onClose}>
279
- <DialogFrame title={title} actions={<Button onClick={onClose}>Got it</Button>}>
240
+ <DialogFrame
241
+ title={title}
242
+ actions={
243
+ <Button onClick={onClose}>
244
+ Got it
245
+ </Button>
246
+ }
247
+ >
280
248
  <Typography>{message}</Typography>
281
249
  </DialogFrame>
282
250
  </Modal>
@@ -333,8 +301,18 @@ function ProcessingDialog({ open, status, onClose }) {
333
301
  return (
334
302
  <Modal open={open} onClose={isProcessing ? undefined : onClose}>
335
303
  <DialogFrame
336
- title={isProcessing ? 'Processing...' : isSuccess ? 'Success!' : 'Error'}
337
- actions={!isProcessing && <Button onClick={onClose}>{isSuccess ? 'Done' : 'Try Again'}</Button>}
304
+ title={
305
+ isProcessing ? 'Processing...' :
306
+ isSuccess ? 'Success!' :
307
+ 'Error'
308
+ }
309
+ actions={
310
+ !isProcessing && (
311
+ <Button onClick={onClose}>
312
+ {isSuccess ? 'Done' : 'Try Again'}
313
+ </Button>
314
+ )
315
+ }
338
316
  >
339
317
  <Box sx={{ textAlign: 'center', py: 2 }}>
340
318
  {isProcessing && <CircularProgress />}
@@ -479,7 +457,9 @@ DialogFrame should be wrapped in Modal for proper behavior:
479
457
  // Fullscreen for complex content or mobile
480
458
  <Modal open={open} onClose={onClose}>
481
459
  <DialogFrame fullscreen title="Edit Profile">
482
- <Box sx={{ p: 2 }}>{/* Large form or content */}</Box>
460
+ <Box sx={{ p: 2 }}>
461
+ {/* Large form or content */}
462
+ </Box>
483
463
  </DialogFrame>
484
464
  </Modal>
485
465
  ```
@@ -520,7 +500,9 @@ DialogFrame inherits accessibility features from Modal:
520
500
 
521
501
  ```tsx
522
502
  // Title provides context
523
- <DialogFrame title="Confirm Deletion">{/* Content is read after title */}</DialogFrame>
503
+ <DialogFrame title="Confirm Deletion">
504
+ {/* Content is read after title */}
505
+ </DialogFrame>
524
506
  ```
525
507
 
526
508
  ## Best Practices
@@ -548,7 +530,9 @@ DialogFrame inherits accessibility features from Modal:
548
530
  ```tsx
549
531
  // ✅ Good: Brief, scannable content
550
532
  <DialogFrame title="Delete Project">
551
- <Typography>This will permanently delete the project and all its data.</Typography>
533
+ <Typography>
534
+ This will permanently delete the project and all its data.
535
+ </Typography>
552
536
  </DialogFrame>
553
537
  ```
554
538
 
@@ -576,7 +560,7 @@ DialogFrame inherits accessibility features from Modal:
576
560
  // ❌ Bad: Dialog for simple feedback
577
561
  <DialogFrame title="Success">
578
562
  <Typography>Item saved!</Typography>
579
- </DialogFrame>;
563
+ </DialogFrame>
580
564
 
581
565
  // ✅ Good: Use Toast
582
566
  showToast({ message: 'Item saved!' });
@@ -586,7 +570,9 @@ showToast({ message: 'Item saved!' });
586
570
 
587
571
  ```tsx
588
572
  // ❌ Bad: Complex form in dialog
589
- <DialogFrame title="Create Account">{/* 20+ form fields */}</DialogFrame>
573
+ <DialogFrame title="Create Account">
574
+ {/* 20+ form fields */}
575
+ </DialogFrame>
590
576
  ```
591
577
 
592
578
  3. **Don't use vague button labels**: Be specific about actions
@@ -613,7 +599,9 @@ For dialogs with heavy content:
613
599
  function HeavyDialog({ open, onClose }) {
614
600
  return (
615
601
  <Modal open={open} onClose={onClose}>
616
- <DialogFrame title="Data Preview">{open && <HeavyDataComponent />}</DialogFrame>
602
+ <DialogFrame title="Data Preview">
603
+ {open && <HeavyDataComponent />}
604
+ </DialogFrame>
617
605
  </Modal>
618
606
  );
619
607
  }
@@ -637,13 +625,11 @@ const handleCancel = useCallback(() => {
637
625
  Unmount dialog completely when not needed:
638
626
 
639
627
  ```tsx
640
- {
641
- open && (
642
- <Modal open={open} onClose={onClose}>
643
- <DialogFrame>...</DialogFrame>
644
- </Modal>
645
- );
646
- }
628
+ {open && (
629
+ <Modal open={open} onClose={onClose}>
630
+ <DialogFrame>...</DialogFrame>
631
+ </Modal>
632
+ )}
647
633
  ```
648
634
 
649
635
  DialogFrame provides a consistent structure for dialog content. Combine it with Modal for proper overlay behavior, keep content concise and actionable, and always provide clear options for users to proceed or cancel.
@@ -41,7 +41,15 @@ The Modal component is a dialog overlay that appears on top of the main content,
41
41
  ## Usage
42
42
 
43
43
  ```tsx
44
- import { Modal, ModalDialog, ModalClose, DialogTitle, DialogContent, DialogActions, Button } from '@ceed/ads';
44
+ import {
45
+ Modal,
46
+ ModalDialog,
47
+ ModalClose,
48
+ DialogTitle,
49
+ DialogContent,
50
+ DialogActions,
51
+ Button,
52
+ } from '@ceed/ads';
45
53
 
46
54
  function MyComponent() {
47
55
  const [open, setOpen] = useState(false);
@@ -53,7 +61,9 @@ function MyComponent() {
53
61
  <ModalDialog>
54
62
  <ModalClose />
55
63
  <DialogTitle>Modal Title</DialogTitle>
56
- <DialogContent>Place your content here.</DialogContent>
64
+ <DialogContent>
65
+ Place your content here.
66
+ </DialogContent>
57
67
  <DialogActions>
58
68
  <Button onClick={() => setOpen(false)}>Close</Button>
59
69
  </DialogActions>
@@ -64,28 +74,6 @@ function MyComponent() {
64
74
  }
65
75
  ```
66
76
 
67
- ### ModalFrame Usage
68
-
69
- `ModalFrame` is a convenience component that combines `ModalDialog` + `ModalClose` + `DialogTitle` + `DialogContent` into a single composable unit.
70
- It provides a concise way to build modals with a title, close button, and content area.
71
-
72
- ```tsx
73
- import { Modal, ModalFrame } from '@ceed/ads';
74
-
75
- function DetailModal({ open, onClose }) {
76
- return (
77
- <Modal open={open} onClose={onClose}>
78
- <ModalFrame title="Detail" onClose={onClose}>
79
- Content goes here.
80
- </ModalFrame>
81
- </Modal>
82
- );
83
- }
84
- ```
85
-
86
- > **Note**: Connect the same handler to both `Modal`'s `onClose` and `ModalFrame`'s `onClose`.
87
- > `Modal` handles backdrop click and ESC key, while `ModalFrame` handles the X button click.
88
-
89
77
  ## Examples
90
78
 
91
79
  ### Basic Modal
@@ -304,166 +292,6 @@ Modals can be stacked on top of each other when necessary.
304
292
  </>
305
293
  ```
306
294
 
307
- ### ModalFrame
308
-
309
- ModalFrame is a convenience component that automatically provides a title, close button, and content area.
310
-
311
- #### ModalFrame Playground
312
-
313
- ```tsx
314
- <>
315
- <Button onClick={() => setOpen(true)}>Open ModalFrame</Button>
316
- <Modal open={open} onClose={() => setOpen(false)}>
317
- <ModalFrame title="ModalFrame Title" onClose={() => setOpen(false)}>
318
- <Typography>
319
- ModalFrame automatically composes ModalDialog, ModalClose, DialogTitle, and DialogContent. You only need
320
- to provide a title, onClose handler, and children.
321
- </Typography>
322
- </ModalFrame>
323
- </Modal>
324
- </>
325
- ```
326
-
327
- #### titleStartDecorator
328
-
329
- Display an icon or decorative element before the title.
330
-
331
- ```tsx
332
- <>
333
- <Button onClick={() => setOpen(true)}>With Decorator</Button>
334
- <Modal open={open} onClose={() => setOpen(false)}>
335
- <ModalFrame title="Details" titleStartDecorator={<InfoOutlinedIcon />} onClose={() => setOpen(false)}>
336
- <Typography>
337
- Use the <code>titleStartDecorator</code> prop to display an icon or element before the title.
338
- </Typography>
339
- </ModalFrame>
340
- </Modal>
341
- </>
342
- ```
343
-
344
- #### Form Content
345
-
346
- An inline form pattern where the submit button lives inside the content area.
347
-
348
- ```tsx
349
- <>
350
- <Button onClick={() => setOpen(true)}>Form in ModalFrame</Button>
351
- <Modal open={open} onClose={() => setOpen(false)}>
352
- <ModalFrame title="Create Project" onClose={() => setOpen(false)}>
353
- <form onSubmit={(event: React.FormEvent<HTMLFormElement>) => {
354
- event.preventDefault();
355
- setOpen(false);
356
- }}>
357
- <Stack spacing={2}>
358
- <FormControl>
359
- <FormLabel>Name</FormLabel>
360
- <Input required />
361
- </FormControl>
362
- <FormControl>
363
- <FormLabel>Description</FormLabel>
364
- <Input required />
365
- </FormControl>
366
- <Button type="submit">Submit</Button>
367
- </Stack>
368
- </form>
369
- </ModalFrame>
370
- </Modal>
371
- </>
372
- ```
373
-
374
- #### Sizes
375
-
376
- Compare sm / md / lg sizes side by side.
377
-
378
- ```tsx
379
- <Stack direction="row" spacing={2}>
380
- <Button size="sm" onClick={() => setOpenSm(true)}>
381
- Small
382
- </Button>
383
- <Button size="md" onClick={() => setOpenMd(true)}>
384
- Medium
385
- </Button>
386
- <Button size="lg" onClick={() => setOpenLg(true)}>
387
- Large
388
- </Button>
389
- <Modal open={openSm} onClose={() => setOpenSm(false)}>
390
- <ModalFrame title="Small ModalFrame" size="sm" onClose={() => setOpenSm(false)}>
391
- <Typography>This is a small ModalFrame.</Typography>
392
- </ModalFrame>
393
- </Modal>
394
- <Modal open={openMd} onClose={() => setOpenMd(false)}>
395
- <ModalFrame title="Medium ModalFrame" size="md" onClose={() => setOpenMd(false)}>
396
- <Typography>This is a medium ModalFrame.</Typography>
397
- </ModalFrame>
398
- </Modal>
399
- <Modal open={openLg} onClose={() => setOpenLg(false)}>
400
- <ModalFrame title="Large ModalFrame" size="lg" onClose={() => setOpenLg(false)}>
401
- <Typography>This is a large ModalFrame.</Typography>
402
- </ModalFrame>
403
- </Modal>
404
- </Stack>
405
- ```
406
-
407
- #### Custom Content
408
-
409
- A layout example suited for displaying detailed information.
410
-
411
- ```tsx
412
- <>
413
- <Button onClick={() => setOpen(true)}>Custom Content</Button>
414
- <Modal open={open} onClose={() => setOpen(false)}>
415
- <ModalFrame title="Order Details" onClose={() => setOpen(false)}>
416
- <Stack spacing={2}>
417
- <Box>
418
- <Typography level="title-sm">Order ID</Typography>
419
- <Typography level="body-sm">ORD-2024-00123</Typography>
420
- </Box>
421
- <Divider />
422
- <Box>
423
- <Typography level="title-sm">Customer</Typography>
424
- <Typography level="body-sm">John Doe</Typography>
425
- </Box>
426
- <Divider />
427
- <Box>
428
- <Typography level="title-sm">Status</Typography>
429
- <Typography level="body-sm" color="success">
430
- Completed
431
- </Typography>
432
- </Box>
433
- </Stack>
434
- </ModalFrame>
435
- </Modal>
436
- </>
437
- ```
438
-
439
- #### Standalone
440
-
441
- ModalFrame can be used without a Modal wrapper for embedding dialog-style layouts directly within a page.
442
-
443
- > ⚠️ **Important** ⚠️
444
- >
445
- > When using ModalFrame without Modal, the parent container **must** meet the following requirements:
446
- >
447
- > - `position: 'relative'` — ModalFrame uses absolute positioning internally
448
- > - Explicit `width` and `height` — `height` must be an absolute value (e.g., `300`, `'400px'`), not a relative value like `%` or `auto`
449
- >
450
- > ModalFrame inherits its dimensions from `ModalDialog`, which normally receives sizing from the Modal overlay. Without these constraints, the component will not render with correct dimensions.
451
-
452
- ```tsx
453
- <Box sx={{
454
- position: 'relative',
455
- width: 480,
456
- height: 300
457
- }}>
458
- <ModalFrame title="Standalone ModalFrame" onClose={() => console.log('close')}>
459
- <Typography>
460
- ModalFrame used without Modal. The parent container must provide
461
- explicit width and height.
462
- </Typography>
463
- </ModalFrame>
464
- </Box>
465
- ```
466
-
467
295
  ## When to Use
468
296
 
469
297
  ### ✅ Good Use Cases
@@ -499,7 +327,8 @@ function DeleteConfirmation({ item, onDelete, onCancel }) {
499
327
  </DialogTitle>
500
328
  <Divider />
501
329
  <DialogContent>
502
- This action cannot be undone. All data associated with this item will be permanently removed.
330
+ This action cannot be undone. All data associated with this item
331
+ will be permanently removed.
503
332
  </DialogContent>
504
333
  <DialogActions>
505
334
  <Button variant="solid" color="danger" onClick={onDelete}>
@@ -575,7 +404,8 @@ function TermsModal({ open, onAccept, onDecline }) {
575
404
  <DialogTitle>Terms of Service</DialogTitle>
576
405
  <DialogContent>
577
406
  <Typography level="body-sm">
578
- Please read and accept the following terms and conditions before proceeding...
407
+ Please read and accept the following terms and conditions before
408
+ proceeding...
579
409
  </Typography>
580
410
  {/* Terms content */}
581
411
  </DialogContent>
@@ -603,7 +433,11 @@ function ImagePreviewModal({ image, open, onClose }) {
603
433
  <Modal open={open} onClose={onClose}>
604
434
  <ModalDialog layout="center" sx={{ p: 0, overflow: 'hidden' }}>
605
435
  <ModalClose sx={{ top: 8, right: 8, zIndex: 1 }} />
606
- <img src={image.src} alt={image.alt} style={{ maxWidth: '90vw', maxHeight: '90vh', objectFit: 'contain' }} />
436
+ <img
437
+ src={image.src}
438
+ alt={image.alt}
439
+ style={{ maxWidth: '90vw', maxHeight: '90vh', objectFit: 'contain' }}
440
+ />
607
441
  </ModalDialog>
608
442
  </Modal>
609
443
  );
@@ -634,69 +468,22 @@ function LoadingModal({ open, message }) {
634
468
  Modal uses a composition pattern with multiple sub-components:
635
469
 
636
470
  ```tsx
637
- <Modal>
638
- {/* Overlay and backdrop */}
639
- <ModalDialog>
640
- {/* Dialog container */}
641
- <ModalClose /> {/* Close button (optional) */}
642
- <DialogTitle>
643
- {/* Header */}
471
+ <Modal> {/* Overlay and backdrop */}
472
+ <ModalDialog> {/* Dialog container */}
473
+ <ModalClose /> {/* Close button (optional) */}
474
+ <DialogTitle> {/* Header */}
644
475
  Title
645
476
  </DialogTitle>
646
- <DialogContent>
647
- {/* Body */}
477
+ <DialogContent> {/* Body */}
648
478
  Content goes here
649
479
  </DialogContent>
650
- <DialogActions>
651
- {/* Footer */}
480
+ <DialogActions> {/* Footer */}
652
481
  <Button>Action</Button>
653
482
  </DialogActions>
654
483
  </ModalDialog>
655
484
  </Modal>
656
485
  ```
657
486
 
658
- ## Component Roles
659
-
660
- | Component | Role | When to Use |
661
- | ----------------- | --------------------------------------------------------------- | ---------------------------------------------------------------- |
662
- | **Modal** | Overlay backdrop, open/close state management | Always required as the outermost wrapper |
663
- | **ModalDialog** | Dialog container (variant/size/layout) | When you need direct control over layout |
664
- | **ModalClose** | Close (X) button in the top-right corner | When users should be able to close via a button |
665
- | **ModalOverflow** | Scrollable area | When content exceeds the viewport |
666
- | **ModalFrame** | Combines ModalDialog + ModalClose + DialogTitle + DialogContent | When you only need a title + close + content (no action buttons) |
667
- | **DialogTitle** | Header area (styled padding) | When composing manually |
668
- | **DialogContent** | Body area (styled padding) | When composing manually |
669
- | **DialogActions** | Footer action button area | When confirm/cancel buttons are needed |
670
-
671
- ## Choosing the Right Component
672
-
673
- ### ModalFrame vs DialogFrame
674
-
675
- | | ModalFrame | DialogFrame |
676
- | ------------------ | ----------------------------------------------- | --------------------------------------- |
677
- | Close (X) button | Built-in | None |
678
- | Title decorator | `titleStartDecorator` | None |
679
- | Action button area | None | `actions` prop (required) |
680
- | Fullscreen | `layout="fullscreen"` | `fullscreen` prop |
681
- | Best for | Information display, detail views, inline forms | Confirm/cancel dialogs, decision-making |
682
-
683
- ### Use ModalFrame when
684
-
685
- - You need an informational modal with a close button (detail views, previews)
686
- - The form's submit button lives inside the content area
687
- - You need an icon next to the title
688
-
689
- ### Use DialogFrame when
690
-
691
- - Explicit action buttons (confirm/cancel) must be pinned to the bottom
692
- - User decisions are required (delete confirmation, save confirmation)
693
- - Only explicit choices should be allowed without a close (X) button
694
-
695
- ### Use manual composition when
696
-
697
- - You need a custom layout that doesn't fit the ModalFrame/DialogFrame pattern
698
- - You want to use both ModalClose and DialogActions together
699
-
700
487
  ## Props and Customization
701
488
 
702
489
  ### Modal Props
@@ -718,17 +505,6 @@ Modal uses a composition pattern with multiple sub-components:
718
505
  | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Dialog size |
719
506
  | `layout` | `'center' \| 'fullscreen'` | `'center'` | Layout mode |
720
507
 
721
- ### ModalFrame Props
722
-
723
- | Prop | Type | Default | Description |
724
- | --------------------- | ------------ | ------- | ------------------------------------------ |
725
- | `title` | `ReactNode` | - | Title displayed in the header |
726
- | `children` | `ReactNode` | - | Body content |
727
- | `titleStartDecorator` | `ReactNode` | - | Icon or element displayed before the title |
728
- | `onClose` | `() => void` | - | Callback when the close button is clicked |
729
-
730
- ModalFrame accepts all ModalDialog props (`variant`, `color`, `size`, `layout`, `sx`, etc.).
731
-
732
508
  ### Custom Styling
733
509
 
734
510
  ```tsx
@@ -767,10 +543,17 @@ Modal components include comprehensive accessibility features:
767
543
  - `aria-describedby` connects to DialogContent
768
544
 
769
545
  ```tsx
770
- <Modal open={open} onClose={onClose} aria-labelledby="modal-title" aria-describedby="modal-description">
546
+ <Modal
547
+ open={open}
548
+ onClose={onClose}
549
+ aria-labelledby="modal-title"
550
+ aria-describedby="modal-description"
551
+ >
771
552
  <ModalDialog>
772
553
  <DialogTitle id="modal-title">Accessible Title</DialogTitle>
773
- <DialogContent id="modal-description">This content is read by screen readers.</DialogContent>
554
+ <DialogContent id="modal-description">
555
+ This content is read by screen readers.
556
+ </DialogContent>
774
557
  </ModalDialog>
775
558
  </Modal>
776
559
  ```
@@ -799,9 +582,7 @@ Modal components include comprehensive accessibility features:
799
582
  ```tsx
800
583
  // ✅ Good: Clear action buttons
801
584
  <DialogActions>
802
- <Button variant="solid" color="danger">
803
- Delete
804
- </Button>
585
+ <Button variant="solid" color="danger">Delete</Button>
805
586
  <Button variant="plain">Cancel</Button>
806
587
  </DialogActions>
807
588
  ```
@@ -876,11 +657,15 @@ Use `keepMounted` only when the modal needs to preserve state between openings:
876
657
  Memoize modal content when it depends on complex data:
877
658
 
878
659
  ```tsx
879
- const modalContent = useMemo(() => <ComplexContent data={data} />, [data]);
660
+ const modalContent = useMemo(() => (
661
+ <ComplexContent data={data} />
662
+ ), [data]);
880
663
 
881
664
  <Modal open={open} onClose={onClose}>
882
- <ModalDialog>{modalContent}</ModalDialog>
883
- </Modal>;
665
+ <ModalDialog>
666
+ {modalContent}
667
+ </ModalDialog>
668
+ </Modal>
884
669
  ```
885
670
 
886
671
  Modal is a powerful component for focused user interactions. Use it thoughtfully to maintain a smooth user experience while capturing important decisions and inputs.
@@ -3,10 +3,8 @@
3
3
  ## Documentation
4
4
 
5
5
  - [Alert](./Alert.md)
6
- - [CircularProgress](./CircularProgress.md)
7
6
  - [DialogFrame](./Dialog.md)
8
7
  - [Modal](./Modal.md)
9
- - [Skeleton](./Skeleton.md)
10
8
 
11
9
  ## Parent
12
10
 
@@ -49,6 +49,8 @@ export { ProfileMenu } from './ProfileMenu';
49
49
  export { Radio, RadioGroup } from './Radio';
50
50
  export { RadioTileGroup } from './RadioTileGroup';
51
51
  export { RadioList } from './RadioList';
52
+ export { SearchBar } from './SearchBar';
53
+ export type { SearchBarOption, SearchBarProps } from './SearchBar';
52
54
  export { Select, Option } from './Select';
53
55
  export { Sheet } from './Sheet';
54
56
  export { Stack } from './Stack';