@ceed/ads 1.20.0 → 1.20.1-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 (30) hide show
  1. package/dist/components/ProfileMenu/ProfileMenu.d.ts +1 -1
  2. package/dist/components/data-display/Markdown.md +832 -0
  3. package/dist/components/feedback/Dialog.md +605 -3
  4. package/dist/components/feedback/Modal.md +656 -24
  5. package/dist/components/feedback/llms.txt +1 -1
  6. package/dist/components/inputs/Autocomplete.md +734 -2
  7. package/dist/components/inputs/Calendar.md +655 -1
  8. package/dist/components/inputs/DatePicker.md +699 -3
  9. package/dist/components/inputs/DateRangePicker.md +815 -1
  10. package/dist/components/inputs/MonthPicker.md +626 -4
  11. package/dist/components/inputs/MonthRangePicker.md +682 -4
  12. package/dist/components/inputs/Select.md +600 -0
  13. package/dist/components/layout/Container.md +507 -0
  14. package/dist/components/navigation/Breadcrumbs.md +582 -0
  15. package/dist/components/navigation/IconMenuButton.md +693 -0
  16. package/dist/components/navigation/InsetDrawer.md +1150 -3
  17. package/dist/components/navigation/Link.md +526 -0
  18. package/dist/components/navigation/MenuButton.md +632 -0
  19. package/dist/components/navigation/NavigationGroup.md +401 -1
  20. package/dist/components/navigation/NavigationItem.md +311 -0
  21. package/dist/components/navigation/Navigator.md +373 -0
  22. package/dist/components/navigation/Pagination.md +521 -0
  23. package/dist/components/navigation/ProfileMenu.md +605 -0
  24. package/dist/components/navigation/Tabs.md +609 -7
  25. package/dist/components/surfaces/Accordions.md +947 -3
  26. package/dist/index.cjs +3 -1
  27. package/dist/index.js +3 -1
  28. package/dist/llms.txt +1 -1
  29. package/framer/index.js +1 -1
  30. package/package.json +3 -2
@@ -2,38 +2,670 @@
2
2
 
3
3
  ## Introduction
4
4
 
5
+ The Modal component is a dialog overlay that appears on top of the main content, demanding user attention and interaction. Built on Joy UI's Modal, it is used for displaying critical information, capturing user input, or requiring confirmation before proceeding. Modals block interaction with the underlying page until dismissed, making them ideal for important actions that require focused attention.
6
+
5
7
  ```tsx
6
- <Modal aria-labelledby="modal-title" aria-describedby="modal-desc" open sx={{
7
- display: 'flex',
8
- justifyContent: 'center',
9
- alignItems: 'center'
10
- }}>
11
- <Sheet variant="outlined" sx={{
12
- maxWidth: 500,
13
- borderRadius: 'md',
14
- p: 3,
15
- boxShadow: 'lg'
16
- }}>
17
- <ModalClose variant="plain" sx={{
18
- m: 1
19
- }} />
20
- <Typography component="h2" id="modal-title" level="h4" textColor="inherit" fontWeight="lg" mb={2}>
21
- This is the modal title
22
- </Typography>
23
- <Typography id="modal-desc" textColor="text.tertiary">
24
- Make sure to use <code>aria-labelledby</code> on the modal dialog with an optional{' '}
25
- <code>aria-describedby</code> attribute.
26
- </Typography>
27
- </Sheet>
28
- </Modal>
8
+ <>
9
+ <Button onClick={() => setOpen(true)}>Open Modal</Button>
10
+ <Modal open={open} onClose={() => setOpen(false)}>
11
+ <ModalDialog>
12
+ <ModalClose />
13
+ <DialogTitle>Modal Title</DialogTitle>
14
+ <DialogContent>This is the modal content. You can place any content here.</DialogContent>
15
+ <DialogActions>
16
+ <Button variant="solid" onClick={() => setOpen(false)}>
17
+ Confirm
18
+ </Button>
19
+ <Button variant="plain" color="neutral" onClick={() => setOpen(false)}>
20
+ Cancel
21
+ </Button>
22
+ </DialogActions>
23
+ </ModalDialog>
24
+ </Modal>
25
+ </>
29
26
  ```
30
27
 
31
28
  | Field | Description | Default |
32
29
  | ---------------------------- | ----------- | ------- |
33
30
  | Controls resolved at runtime | — | — |
34
31
 
32
+ > ⚠️ **Usage Warning** ⚠️
33
+ >
34
+ > Modals interrupt the user's current workflow and should be used sparingly.
35
+ >
36
+ > - Use only when user confirmation or required input is absolutely necessary
37
+ > - For simple information display, consider using Alert or Toast instead
38
+ > - Complex multi-step forms should be placed on separate pages
39
+ > - Avoid using modals for content that users need to reference while interacting with the page
40
+
35
41
  ## Usage
36
42
 
37
43
  ```tsx
38
- import { Modal } from '@ceed/ads';
44
+ import {
45
+ Modal,
46
+ ModalDialog,
47
+ ModalClose,
48
+ DialogTitle,
49
+ DialogContent,
50
+ DialogActions,
51
+ Button,
52
+ } from '@ceed/ads';
53
+
54
+ function MyComponent() {
55
+ const [open, setOpen] = useState(false);
56
+
57
+ return (
58
+ <>
59
+ <Button onClick={() => setOpen(true)}>Open Modal</Button>
60
+ <Modal open={open} onClose={() => setOpen(false)}>
61
+ <ModalDialog>
62
+ <ModalClose />
63
+ <DialogTitle>Modal Title</DialogTitle>
64
+ <DialogContent>
65
+ Place your content here.
66
+ </DialogContent>
67
+ <DialogActions>
68
+ <Button onClick={() => setOpen(false)}>Close</Button>
69
+ </DialogActions>
70
+ </ModalDialog>
71
+ </Modal>
72
+ </>
73
+ );
74
+ }
75
+ ```
76
+
77
+ ## Examples
78
+
79
+ ### Basic Modal
80
+
81
+ The basic modal with a simple Sheet for custom layouts.
82
+
83
+ ```tsx
84
+ <>
85
+ <Button onClick={() => setOpen(true)}>Open Basic Modal</Button>
86
+ <Modal aria-labelledby="modal-title" aria-describedby="modal-desc" open={open} onClose={() => setOpen(false)} sx={{
87
+ display: 'flex',
88
+ justifyContent: 'center',
89
+ alignItems: 'center'
90
+ }}>
91
+ <Sheet variant="outlined" sx={{
92
+ maxWidth: 500,
93
+ borderRadius: 'md',
94
+ p: 3,
95
+ boxShadow: 'lg'
96
+ }}>
97
+ <ModalClose variant="plain" sx={{
98
+ m: 1
99
+ }} />
100
+ <Typography component="h2" id="modal-title" level="h4" textColor="inherit" fontWeight="lg" mb={2}>
101
+ This is the modal title
102
+ </Typography>
103
+ <Typography id="modal-desc" textColor="text.tertiary">
104
+ Make sure to use <code>aria-labelledby</code> on the modal dialog with an optional{' '}
105
+ <code>aria-describedby</code> attribute.
106
+ </Typography>
107
+ </Sheet>
108
+ </Modal>
109
+ </>
110
+ ```
111
+
112
+ ### Modal Dialog
113
+
114
+ Use ModalDialog for structured dialogs with title, content, and actions.
115
+
116
+ ```tsx
117
+ <>
118
+ <Button onClick={() => setOpen(true)}>Open Form Modal</Button>
119
+ <Modal open={open} onClose={() => setOpen(false)}>
120
+ <ModalDialog>
121
+ <ModalClose />
122
+ <DialogTitle>Create new project</DialogTitle>
123
+ <DialogContent>
124
+ Fill in the information of the project.
125
+ <form onSubmit={(event: React.FormEvent<HTMLFormElement>) => {
126
+ event.preventDefault();
127
+ setOpen(false);
128
+ }}>
129
+ <Stack spacing={4}>
130
+ <FormControl>
131
+ <FormLabel>Name</FormLabel>
132
+ <Input required />
133
+ </FormControl>
134
+ <FormControl>
135
+ <FormLabel>Description</FormLabel>
136
+ <Input required />
137
+ </FormControl>
138
+ <Button type="submit">Submit</Button>
139
+ </Stack>
140
+ </form>
141
+ </DialogContent>
142
+ </ModalDialog>
143
+ </Modal>
144
+ </>
145
+ ```
146
+
147
+ ### Variants
148
+
149
+ Modal dialogs support different visual variants.
150
+
151
+ #### Plain Variant
152
+
153
+ ```tsx
154
+ <>
155
+ <Button onClick={() => setOpen(true)}>Plain Variant</Button>
156
+ <Modal open={open} onClose={() => setOpen(false)}>
157
+ <ModalDialog variant="plain">
158
+ <ModalClose />
159
+ <DialogTitle>Modal Dialog</DialogTitle>
160
+ <DialogContent>This is a `plain` modal dialog.</DialogContent>
161
+ </ModalDialog>
162
+ </Modal>
163
+ </>
164
+ ```
165
+
166
+ #### Outlined Variant
167
+
168
+ ```tsx
169
+ <>
170
+ <Button onClick={() => setOpen(true)}>Outlined Variant</Button>
171
+ <Modal open={open} onClose={() => setOpen(false)}>
172
+ <ModalDialog variant="outlined">
173
+ <ModalClose />
174
+ <DialogTitle>Modal Dialog</DialogTitle>
175
+ <DialogContent>This is an `outlined` modal dialog.</DialogContent>
176
+ </ModalDialog>
177
+ </Modal>
178
+ </>
179
+ ```
180
+
181
+ #### Soft Variant
182
+
183
+ ```tsx
184
+ <>
185
+ <Button onClick={() => setOpen(true)}>Soft Variant</Button>
186
+ <Modal open={open} onClose={() => setOpen(false)}>
187
+ <ModalDialog variant="soft">
188
+ <ModalClose />
189
+ <DialogTitle>Modal Dialog</DialogTitle>
190
+ <DialogContent>This is a `soft` modal dialog.</DialogContent>
191
+ </ModalDialog>
192
+ </Modal>
193
+ </>
194
+ ```
195
+
196
+ #### Solid Variant
197
+
198
+ ```tsx
199
+ <>
200
+ <Button onClick={() => setOpen(true)}>Solid Variant</Button>
201
+ <Modal open={open} onClose={() => setOpen(false)}>
202
+ <ModalDialog variant="solid">
203
+ <ModalClose />
204
+ <DialogTitle>Modal Dialog</DialogTitle>
205
+ <DialogContent>This is a `solid` modal dialog.</DialogContent>
206
+ </ModalDialog>
207
+ </Modal>
208
+ </>
209
+ ```
210
+
211
+ ### Alert Dialog
212
+
213
+ For critical confirmations that require explicit user decision.
214
+
215
+ ```tsx
216
+ <>
217
+ <Button color="danger" onClick={() => setOpen(true)}>
218
+ Delete Item
219
+ </Button>
220
+ <Modal open={open} onClose={() => setOpen(false)}>
221
+ <ModalDialog variant="outlined" role="alertdialog">
222
+ <DialogTitle>
223
+ <WarningRoundedIcon />
224
+ Confirmation
225
+ </DialogTitle>
226
+ <Divider />
227
+ <DialogContent>Are you sure you want to discard all of your notes?</DialogContent>
228
+ <DialogActions>
229
+ <Button variant="solid" color="danger" onClick={() => setOpen(false)}>
230
+ Discard notes
231
+ </Button>
232
+ <Button variant="plain" color="neutral" onClick={() => setOpen(false)}>
233
+ Cancel
234
+ </Button>
235
+ </DialogActions>
236
+ </ModalDialog>
237
+ </Modal>
238
+ </>
239
+ ```
240
+
241
+ ### Layouts
242
+
243
+ #### Fullscreen Layout
244
+
245
+ For complex content that requires maximum screen space.
246
+
247
+ ```tsx
248
+ <>
249
+ <Button onClick={() => setOpen(true)}>Open Fullscreen Modal</Button>
250
+ <Modal open={open} onClose={() => setOpen(false)}>
251
+ <ModalDialog layout="fullscreen">
252
+ <ModalClose />
253
+ <DialogTitle>Fullscreen Modal</DialogTitle>
254
+ <DialogContent>This modal takes up the entire screen.</DialogContent>
255
+ <DialogActions>
256
+ <Button variant="solid" onClick={() => setOpen(false)}>
257
+ Save
258
+ </Button>
259
+ </DialogActions>
260
+ </ModalDialog>
261
+ </Modal>
262
+ </>
263
+ ```
264
+
265
+ ### Nested Modals
266
+
267
+ Modals can be stacked on top of each other when necessary.
268
+
269
+ ```tsx
270
+ <>
271
+ <Button onClick={() => setFirstOpen(true)}>Open First Modal</Button>
272
+ <Modal open={firstOpen} onClose={() => setFirstOpen(false)}>
273
+ <ModalDialog>
274
+ <ModalClose />
275
+ <DialogTitle>First Modal</DialogTitle>
276
+ <DialogContent>This is the first modal. Click the button below to open a nested modal.</DialogContent>
277
+ <DialogActions>
278
+ <Button onClick={() => setSecondOpen(true)}>Open Nested Modal</Button>
279
+ </DialogActions>
280
+ </ModalDialog>
281
+ </Modal>
282
+ <Modal open={secondOpen} onClose={() => setSecondOpen(false)}>
283
+ <ModalDialog>
284
+ <ModalClose />
285
+ <DialogTitle>Nested Modal</DialogTitle>
286
+ <DialogContent>This is a nested modal on top of the first one.</DialogContent>
287
+ <DialogActions>
288
+ <Button onClick={() => setSecondOpen(false)}>Close</Button>
289
+ </DialogActions>
290
+ </ModalDialog>
291
+ </Modal>
292
+ </>
293
+ ```
294
+
295
+ ## When to Use
296
+
297
+ ### ✅ Good Use Cases
298
+
299
+ - **Destructive actions**: Confirming deletion, discarding changes, or other irreversible operations
300
+ - **Critical decisions**: Actions that have significant consequences requiring explicit consent
301
+ - **Focused input**: Short forms where distraction-free input is beneficial (login, quick edit)
302
+ - **Blocking notifications**: System errors or warnings that require acknowledgment
303
+ - **Media preview**: Viewing images, videos, or documents in a focused overlay
304
+
305
+ ### ❌ When Not to Use
306
+
307
+ - **Long forms**: Multi-step wizards or complex forms belong on dedicated pages
308
+ - **Reference content**: Information users need while working on the page
309
+ - **Frequent interactions**: Actions performed repeatedly shouldn't require modal confirmation
310
+ - **Non-critical information**: Success messages or tips should use Toast or inline feedback
311
+ - **Mobile navigation**: Consider using full-page transitions instead on mobile devices
312
+
313
+ ## Common Use Cases
314
+
315
+ ### Confirmation Dialog
316
+
317
+ Confirm destructive or significant actions before executing them.
318
+
319
+ ```tsx
320
+ function DeleteConfirmation({ item, onDelete, onCancel }) {
321
+ return (
322
+ <Modal open onClose={onCancel}>
323
+ <ModalDialog variant="outlined" role="alertdialog">
324
+ <DialogTitle>
325
+ <WarningRoundedIcon />
326
+ Delete {item.name}?
327
+ </DialogTitle>
328
+ <Divider />
329
+ <DialogContent>
330
+ This action cannot be undone. All data associated with this item
331
+ will be permanently removed.
332
+ </DialogContent>
333
+ <DialogActions>
334
+ <Button variant="solid" color="danger" onClick={onDelete}>
335
+ Delete
336
+ </Button>
337
+ <Button variant="plain" color="neutral" onClick={onCancel}>
338
+ Cancel
339
+ </Button>
340
+ </DialogActions>
341
+ </ModalDialog>
342
+ </Modal>
343
+ );
344
+ }
345
+ ```
346
+
347
+ ### Form Modal
348
+
349
+ Capture user input in a focused dialog.
350
+
351
+ ```tsx
352
+ function CreateProjectModal({ open, onClose, onCreate }) {
353
+ const handleSubmit = (event) => {
354
+ event.preventDefault();
355
+ const formData = new FormData(event.target);
356
+ onCreate({
357
+ name: formData.get('name'),
358
+ description: formData.get('description'),
359
+ });
360
+ };
361
+
362
+ return (
363
+ <Modal open={open} onClose={onClose}>
364
+ <ModalDialog>
365
+ <ModalClose />
366
+ <DialogTitle>Create New Project</DialogTitle>
367
+ <form onSubmit={handleSubmit}>
368
+ <DialogContent>
369
+ <Stack spacing={2}>
370
+ <FormControl required>
371
+ <FormLabel>Project Name</FormLabel>
372
+ <Input name="name" placeholder="Enter project name" />
373
+ </FormControl>
374
+ <FormControl>
375
+ <FormLabel>Description</FormLabel>
376
+ <Textarea name="description" minRows={3} placeholder="Enter description" />
377
+ </FormControl>
378
+ </Stack>
379
+ </DialogContent>
380
+ <DialogActions>
381
+ <Button type="submit" variant="solid">
382
+ Create
383
+ </Button>
384
+ <Button variant="plain" color="neutral" onClick={onClose}>
385
+ Cancel
386
+ </Button>
387
+ </DialogActions>
388
+ </form>
389
+ </ModalDialog>
390
+ </Modal>
391
+ );
392
+ }
393
+ ```
394
+
395
+ ### Information Modal
396
+
397
+ Display detailed information that requires user acknowledgment.
398
+
399
+ ```tsx
400
+ function TermsModal({ open, onAccept, onDecline }) {
401
+ return (
402
+ <Modal open={open}>
403
+ <ModalDialog sx={{ maxWidth: 600, maxHeight: '80vh', overflow: 'auto' }}>
404
+ <DialogTitle>Terms of Service</DialogTitle>
405
+ <DialogContent>
406
+ <Typography level="body-sm">
407
+ Please read and accept the following terms and conditions before
408
+ proceeding...
409
+ </Typography>
410
+ {/* Terms content */}
411
+ </DialogContent>
412
+ <DialogActions>
413
+ <Button variant="solid" onClick={onAccept}>
414
+ Accept
415
+ </Button>
416
+ <Button variant="plain" color="neutral" onClick={onDecline}>
417
+ Decline
418
+ </Button>
419
+ </DialogActions>
420
+ </ModalDialog>
421
+ </Modal>
422
+ );
423
+ }
424
+ ```
425
+
426
+ ### Image Preview Modal
427
+
428
+ Display images or media in a focused overlay.
429
+
430
+ ```tsx
431
+ function ImagePreviewModal({ image, open, onClose }) {
432
+ return (
433
+ <Modal open={open} onClose={onClose}>
434
+ <ModalDialog layout="center" sx={{ p: 0, overflow: 'hidden' }}>
435
+ <ModalClose sx={{ top: 8, right: 8, zIndex: 1 }} />
436
+ <img
437
+ src={image.src}
438
+ alt={image.alt}
439
+ style={{ maxWidth: '90vw', maxHeight: '90vh', objectFit: 'contain' }}
440
+ />
441
+ </ModalDialog>
442
+ </Modal>
443
+ );
444
+ }
445
+ ```
446
+
447
+ ### Loading Modal
448
+
449
+ Block user interaction during async operations.
450
+
451
+ ```tsx
452
+ function LoadingModal({ open, message }) {
453
+ return (
454
+ <Modal open={open}>
455
+ <ModalDialog>
456
+ <Stack spacing={2} alignItems="center" sx={{ py: 2 }}>
457
+ <CircularProgress />
458
+ <Typography>{message || 'Processing...'}</Typography>
459
+ </Stack>
460
+ </ModalDialog>
461
+ </Modal>
462
+ );
463
+ }
464
+ ```
465
+
466
+ ## Component Structure
467
+
468
+ Modal uses a composition pattern with multiple sub-components:
469
+
470
+ ```tsx
471
+ <Modal> {/* Overlay and backdrop */}
472
+ <ModalDialog> {/* Dialog container */}
473
+ <ModalClose /> {/* Close button (optional) */}
474
+ <DialogTitle> {/* Header */}
475
+ Title
476
+ </DialogTitle>
477
+ <DialogContent> {/* Body */}
478
+ Content goes here
479
+ </DialogContent>
480
+ <DialogActions> {/* Footer */}
481
+ <Button>Action</Button>
482
+ </DialogActions>
483
+ </ModalDialog>
484
+ </Modal>
485
+ ```
486
+
487
+ ## Props and Customization
488
+
489
+ ### Modal Props
490
+
491
+ | Prop | Type | Default | Description |
492
+ | ---------------------- | ------------- | ------- | -------------------------------- |
493
+ | `open` | `boolean` | `false` | Controls modal visibility |
494
+ | `onClose` | `function` | - | Callback when modal should close |
495
+ | `disableEscapeKeyDown` | `boolean` | `false` | Disable closing on Escape key |
496
+ | `keepMounted` | `boolean` | `false` | Keep modal in DOM when closed |
497
+ | `container` | `HTMLElement` | - | Portal container element |
498
+
499
+ ### ModalDialog Props
500
+
501
+ | Prop | Type | Default | Description |
502
+ | --------- | -------------------------------------------------------------- | ------------ | ------------ |
503
+ | `variant` | `'plain' \| 'outlined' \| 'soft' \| 'solid'` | `'outlined'` | Visual style |
504
+ | `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | `'neutral'` | Color scheme |
505
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Dialog size |
506
+ | `layout` | `'center' \| 'fullscreen'` | `'center'` | Layout mode |
507
+
508
+ ### Custom Styling
509
+
510
+ ```tsx
511
+ <Modal
512
+ open={open}
513
+ onClose={onClose}
514
+ sx={{
515
+ // Customize backdrop
516
+ '& .MuiModal-backdrop': {
517
+ backdropFilter: 'blur(4px)',
518
+ },
519
+ }}
520
+ >
521
+ <ModalDialog
522
+ sx={{
523
+ minWidth: 400,
524
+ maxWidth: 600,
525
+ borderRadius: 'xl',
526
+ boxShadow: 'xl',
527
+ }}
528
+ >
529
+ {/* Content */}
530
+ </ModalDialog>
531
+ </Modal>
532
+ ```
533
+
534
+ ## Accessibility
535
+
536
+ Modal components include comprehensive accessibility features:
537
+
538
+ ### ARIA Attributes
539
+
540
+ - `role="dialog"` is automatically applied to ModalDialog
541
+ - Use `role="alertdialog"` for confirmation dialogs requiring user response
542
+ - `aria-labelledby` connects to DialogTitle
543
+ - `aria-describedby` connects to DialogContent
544
+
545
+ ```tsx
546
+ <Modal
547
+ open={open}
548
+ onClose={onClose}
549
+ aria-labelledby="modal-title"
550
+ aria-describedby="modal-description"
551
+ >
552
+ <ModalDialog>
553
+ <DialogTitle id="modal-title">Accessible Title</DialogTitle>
554
+ <DialogContent id="modal-description">
555
+ This content is read by screen readers.
556
+ </DialogContent>
557
+ </ModalDialog>
558
+ </Modal>
559
+ ```
560
+
561
+ ### Keyboard Navigation
562
+
563
+ - **Escape**: Closes the modal (unless `disableEscapeKeyDown` is true)
564
+ - **Tab**: Cycles through focusable elements within the modal
565
+ - **Focus trapping**: Focus is automatically trapped within the modal
566
+
567
+ ### Screen Reader Support
568
+
569
+ - Modal announces its presence when opened
570
+ - ModalClose should include `aria-label` for screen readers
571
+
572
+ ```tsx
573
+ <ModalClose aria-label="Close dialog" />
39
574
  ```
575
+
576
+ ## Best Practices
577
+
578
+ ### ✅ Do
579
+
580
+ 1. **Provide clear actions**: Always include explicit action buttons for user decisions
581
+
582
+ ```tsx
583
+ // ✅ Good: Clear action buttons
584
+ <DialogActions>
585
+ <Button variant="solid" color="danger">Delete</Button>
586
+ <Button variant="plain">Cancel</Button>
587
+ </DialogActions>
588
+ ```
589
+
590
+ 2. **Use appropriate variants**: Match the visual style to the action severity
591
+
592
+ ```tsx
593
+ // ✅ Good: Danger color for destructive actions
594
+ <ModalDialog color="danger" variant="outlined">
595
+ ```
596
+
597
+ 3. **Keep content focused**: Modals should contain only essential information
598
+
599
+ 4. **Handle close events**: Always provide multiple ways to close (X button, backdrop click, Escape key)
600
+
601
+ ### ❌ Don't
602
+
603
+ 1. **Don't nest complex navigation**: Avoid wizards or multi-step flows in modals
604
+
605
+ ```tsx
606
+ // ❌ Bad: Complex multi-step wizard in modal
607
+ <ModalDialog>
608
+ <Stepper activeStep={step}>
609
+ <Step>Step 1</Step>
610
+ <Step>Step 2</Step>
611
+ <Step>Step 3</Step>
612
+ </Stepper>
613
+ </ModalDialog>
614
+ ```
615
+
616
+ 2. **Don't overuse modals**: Frequent interruptions frustrate users
617
+
618
+ 3. **Don't hide important errors in modals**: Use inline validation for form errors
619
+
620
+ 4. **Don't make modals too large**: If content requires scrolling extensively, use a dedicated page
621
+
622
+ ## Performance Considerations
623
+
624
+ ### Lazy Loading
625
+
626
+ For modals with heavy content, consider lazy loading:
627
+
628
+ ```tsx
629
+ const HeavyContent = lazy(() => import('./HeavyContent'));
630
+
631
+ function OptimizedModal({ open, onClose }) {
632
+ return (
633
+ <Modal open={open} onClose={onClose}>
634
+ <ModalDialog>
635
+ <Suspense fallback={<CircularProgress />}>
636
+ <HeavyContent />
637
+ </Suspense>
638
+ </ModalDialog>
639
+ </Modal>
640
+ );
641
+ }
642
+ ```
643
+
644
+ ### Keep Mounted
645
+
646
+ Use `keepMounted` only when the modal needs to preserve state between openings:
647
+
648
+ ```tsx
649
+ // Only use when necessary
650
+ <Modal keepMounted open={open} onClose={onClose}>
651
+ {/* Content that needs to maintain state */}
652
+ </Modal>
653
+ ```
654
+
655
+ ### Avoid Unnecessary Re-renders
656
+
657
+ Memoize modal content when it depends on complex data:
658
+
659
+ ```tsx
660
+ const modalContent = useMemo(() => (
661
+ <ComplexContent data={data} />
662
+ ), [data]);
663
+
664
+ <Modal open={open} onClose={onClose}>
665
+ <ModalDialog>
666
+ {modalContent}
667
+ </ModalDialog>
668
+ </Modal>
669
+ ```
670
+
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,7 +3,7 @@
3
3
  ## Documentation
4
4
 
5
5
  - [Alert](./Alert.md)
6
- - [Dialog](./Dialog.md)
6
+ - [DialogFrame](./Dialog.md)
7
7
  - [Modal](./Modal.md)
8
8
 
9
9
  ## Parent