@ceed/ads 1.23.0 → 1.23.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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Introduction
4
4
 
5
- Typography 컴포넌트는 텍스트를 표시하기 위한 핵심 컴포넌트입니다. Joy UI Typography 기반으로 하며, 다양한 텍스트 레벨과 스타일을 제공합니다. 제목, 본문, 라벨 모든 텍스트 요소에 일관된 타이포그래피를 적용할 있습니다.
5
+ The Typography component is a core component for displaying text. It is based on Joy UI Typography and provides a variety of text levels and styles. You can apply consistent typography across all text elements such as headings, body text, and labels.
6
6
 
7
7
  ```tsx
8
8
  <Typography children="Typography" />
@@ -21,10 +21,10 @@ import { Typography } from '@ceed/ads';
21
21
  function MyComponent() {
22
22
  return (
23
23
  <div>
24
- <Typography level="h1">메인 제목</Typography>
25
- <Typography level="body-md">본문 텍스트입니다.</Typography>
24
+ <Typography level="h1">Main Heading</Typography>
25
+ <Typography level="body-md">This is body text.</Typography>
26
26
  <Typography level="body-sm" color="neutral">
27
- 보조 설명 텍스트입니다.
27
+ This is supporting description text.
28
28
  </Typography>
29
29
  </div>
30
30
  );
@@ -35,18 +35,18 @@ function MyComponent() {
35
35
 
36
36
  ### Headings
37
37
 
38
- 제목을 위한 레벨들입니다. 페이지 구조를 명확하게 나타내는 사용됩니다.
38
+ Levels for headings. Use them to clearly define page structure.
39
39
 
40
40
  ```tsx
41
- <Typography level="h1">H1 - 페이지 메인 제목</Typography>
42
- <Typography level="h2">H2 - 섹션 제목</Typography>
43
- <Typography level="h3">H3 - 하위 섹션 제목</Typography>
44
- <Typography level="h4">H4 - 세부 제목</Typography>
41
+ <Typography level="h1">H1 - Main page heading</Typography>
42
+ <Typography level="h2">H2 - Section heading</Typography>
43
+ <Typography level="h3">H3 - Subsection heading</Typography>
44
+ <Typography level="h4">H4 - Detailed heading</Typography>
45
45
  ```
46
46
 
47
47
  ### Titles
48
48
 
49
- 중요한 제목이나 강조할 텍스트에 사용됩니다.
49
+ Used for important titles or emphasized text.
50
50
 
51
51
  ```tsx
52
52
  <Typography level="title-lg">Large Title</Typography>
@@ -56,13 +56,13 @@ function MyComponent() {
56
56
 
57
57
  ### Body Text
58
58
 
59
- 본문 텍스트를 위한 레벨들입니다. 대부분의 읽기 내용에 사용됩니다.
59
+ Levels for body text. Use these for most readable content.
60
60
 
61
61
  ```tsx
62
- <Typography level="body-lg">큰 본문 텍스트</Typography>
63
- <Typography level="body-md">일반 본문 텍스트</Typography>
64
- <Typography level="body-sm">작은 본문 텍스트</Typography>
65
- <Typography level="body-xs">매우 작은 텍스트</Typography>
62
+ <Typography level="body-lg">Large body text</Typography>
63
+ <Typography level="body-md">Regular body text</Typography>
64
+ <Typography level="body-sm">Small body text</Typography>
65
+ <Typography level="body-xs">Extra small text</Typography>
66
66
  ```
67
67
 
68
68
  ## Common Use Cases
@@ -74,24 +74,24 @@ function ArticlePage() {
74
74
  return (
75
75
  <article>
76
76
  <Typography level="h1" sx={{ mb: 2 }}>
77
- 기사 제목
77
+ Article Title
78
78
  </Typography>
79
79
 
80
80
  <Typography level="body-sm" color="neutral" sx={{ mb: 3 }}>
81
- 2024년 1월 15 · 김철수 작성
81
+ January 15, 2024 · Written by John Doe
82
82
  </Typography>
83
83
 
84
84
  <Typography level="body-md" sx={{ mb: 2 }}>
85
- 기사의 본문 내용이 여기에 들어갑니다. 텍스트는 읽기 쉬운
86
- 크기와 간격을 가지고 있습니다.
85
+ The main content of the article goes here. This text uses a readable size
86
+ and line spacing.
87
87
  </Typography>
88
88
 
89
89
  <Typography level="h2" sx={{ mt: 4, mb: 2 }}>
90
- 섹션 제목
90
+ Section Title
91
91
  </Typography>
92
92
 
93
93
  <Typography level="body-md">
94
- 섹션의 내용이 계속됩니다.
94
+ The section content continues here.
95
95
  </Typography>
96
96
  </article>
97
97
  );
@@ -104,15 +104,15 @@ function ArticlePage() {
104
104
  <Card>
105
105
  <CardContent>
106
106
  <Typography level="title-md" sx={{ mb: 1 }}>
107
- 제품명
107
+ Product Name
108
108
  </Typography>
109
109
 
110
110
  <Typography level="body-sm" color="neutral" sx={{ mb: 2 }}>
111
- 카테고리: 전자제품
111
+ Category: Electronics
112
112
  </Typography>
113
113
 
114
114
  <Typography level="body-md" sx={{ mb: 2 }}>
115
- 제품에 대한 상세 설명이 여기에 들어갑니다.
115
+ A detailed description of the product goes here.
116
116
  </Typography>
117
117
 
118
118
  <Typography level="title-lg" color="primary">
@@ -128,21 +128,21 @@ function ArticlePage() {
128
128
  <Stack spacing={2}>
129
129
  <FormControl>
130
130
  <Typography level="title-sm" component="label">
131
- 사용자 이름
131
+ Username
132
132
  </Typography>
133
- <Input placeholder="이름을 입력하세요" />
133
+ <Input placeholder="Enter your name" />
134
134
  <Typography level="body-xs" color="neutral">
135
- 실명으로 입력해 주세요.
135
+ Please enter your real name.
136
136
  </Typography>
137
137
  </FormControl>
138
138
 
139
139
  <FormControl error>
140
140
  <Typography level="title-sm" component="label">
141
- 이메일 주소
141
+ Email Address
142
142
  </Typography>
143
143
  <Input placeholder="email@example.com" />
144
144
  <Typography level="body-xs" color="danger">
145
- 올바른 이메일 형식이 아닙니다.
145
+ The email format is invalid.
146
146
  </Typography>
147
147
  </FormControl>
148
148
  </Stack>
@@ -153,16 +153,16 @@ function ArticlePage() {
153
153
  ```tsx
154
154
  <Stack spacing={2}>
155
155
  <Box>
156
- <Typography level="body-md">서버 상태:</Typography>
156
+ <Typography level="body-md">Server Status:</Typography>
157
157
  <Typography level="body-md" color="success">
158
- 정상 운영 중
158
+ Operating Normally
159
159
  </Typography>
160
160
  </Box>
161
161
 
162
162
  <Box>
163
- <Typography level="body-md">마지막 업데이트:</Typography>
163
+ <Typography level="body-md">Last Updated:</Typography>
164
164
  <Typography level="body-sm" color="neutral">
165
- 2
165
+ 2 minutes ago
166
166
  </Typography>
167
167
  </Box>
168
168
  </Stack>
@@ -172,7 +172,7 @@ function ArticlePage() {
172
172
 
173
173
  ```tsx
174
174
  <Stack spacing={1}>
175
- <Typography level="title-md">할 일 목록</Typography>
175
+ <Typography level="title-md">Todo List</Typography>
176
176
 
177
177
  {todoItems.map((item) => (
178
178
  <Box key={item.id} sx={{ pl: 2 }}>
@@ -195,39 +195,39 @@ function ArticlePage() {
195
195
 
196
196
  ## Colors
197
197
 
198
- Typography 다양한 색상을 지원합니다:
198
+ Typography supports various colors:
199
199
 
200
200
  ```tsx
201
201
  <Stack spacing={1}>
202
- <Typography color="primary">Primary 색상</Typography>
203
- <Typography color="neutral">Neutral 색상</Typography>
204
- <Typography color="danger">Danger 색상</Typography>
205
- <Typography color="success">Success 색상</Typography>
206
- <Typography color="warning">Warning 색상</Typography>
202
+ <Typography color="primary">Primary color</Typography>
203
+ <Typography color="neutral">Neutral color</Typography>
204
+ <Typography color="danger">Danger color</Typography>
205
+ <Typography color="success">Success color</Typography>
206
+ <Typography color="warning">Warning color</Typography>
207
207
  </Stack>
208
208
  ```
209
209
 
210
210
  ## Component Prop
211
211
 
212
- 다른 HTML 요소나 React 컴포넌트로 렌더링할 있습니다:
212
+ You can render it as a different HTML element or React component:
213
213
 
214
214
  ```tsx
215
215
  <Typography level="h1" component="h2">
216
- h2 태그로 렌더링되는 h1 스타일
216
+ h1 style rendered as an h2 tag
217
217
  </Typography>
218
218
 
219
219
  <Typography level="body-md" component="span">
220
- 인라인 텍스트
220
+ Inline text
221
221
  </Typography>
222
222
 
223
223
  <Typography level="title-md" component={Link} href="/page">
224
- 링크 컴포넌트로 렌더링
224
+ Rendered as a Link component
225
225
  </Typography>
226
226
  ```
227
227
 
228
228
  ## Responsive Typography
229
229
 
230
- 반응형 레벨을 사용할 있습니다:
230
+ You can use responsive levels:
231
231
 
232
232
  ```tsx
233
233
  <Typography
@@ -236,36 +236,36 @@ Typography는 다양한 색상을 지원합니다:
236
236
  fontSize: { xs: '1.5rem', sm: '2rem', md: '2.5rem' }
237
237
  }}
238
238
  >
239
- 반응형 제목
239
+ Responsive Heading
240
240
  </Typography>
241
241
  ```
242
242
 
243
243
  ## Best Practices
244
244
 
245
- 1. **의미적 구조**: 제목 레벨을 순서대로 사용하여 명확한 문서 구조를 만드세요.
245
+ 1. **Semantic Structure**: Use heading levels in order to create a clear document structure.
246
246
 
247
247
  ```tsx
248
- // ✅ 올바른 순서
249
- <Typography level="h1">메인 제목</Typography>
250
- <Typography level="h2">섹션 제목</Typography>
251
- <Typography level="h3">하위 섹션</Typography>
252
-
253
- // ❌ 잘못된 순서
254
- <Typography level="h1">메인 제목</Typography>
255
- <Typography level="h3">섹션 제목</Typography>
248
+ // ✅ Correct order
249
+ <Typography level="h1">Main heading</Typography>
250
+ <Typography level="h2">Section heading</Typography>
251
+ <Typography level="h3">Subsection</Typography>
252
+
253
+ // ❌ Incorrect order
254
+ <Typography level="h1">Main heading</Typography>
255
+ <Typography level="h3">Section heading</Typography>
256
256
  ```
257
257
 
258
- 2. **일관성**: 같은 용도의 텍스트에는 같은 레벨을 사용하세요.
258
+ 2. **Consistency**: Use the same level for text serving the same purpose.
259
259
 
260
- 3. **가독성**: 본문 텍스트에는 적절한 간격과 문단 구분을 제공하세요.
260
+ 3. **Readability**: Provide proper line spacing and paragraph separation for body text.
261
261
 
262
- 4. **색상 대비**: 충분한 색상 대비를 유지하여 접근성을 보장하세요.
262
+ 4. **Color Contrast**: Maintain sufficient color contrast to ensure accessibility.
263
263
 
264
264
  ## Accessibility
265
265
 
266
- - 적절한 HTML 시맨틱 태그 사용
267
- - 스크린 리더 지원
268
- - 키보드 탐색 가능 (링크나 버튼으로 사용될 )
269
- - 충분한 색상 대비
266
+ - Use appropriate semantic HTML tags
267
+ - Support screen readers
268
+ - Ensure keyboard navigation (when used as a link or button)
269
+ - Maintain sufficient color contrast
270
270
 
271
- Typography 사용자 인터페이스에서 정보를 효과적으로 전달하고 시각적 계층 구조를 만드는 핵심적인 역할을 합니다. 적절한 레벨과 스타일을 선택하여 읽기 쉽고 접근 가능한 콘텐츠를 만들 있습니다.
271
+ Typography plays a key role in effectively conveying information and creating visual hierarchy in user interfaces. By choosing appropriate levels and styles, you can create content that is easy to read and accessible.
@@ -41,15 +41,7 @@ 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 {
45
- Modal,
46
- ModalDialog,
47
- ModalClose,
48
- DialogTitle,
49
- DialogContent,
50
- DialogActions,
51
- Button,
52
- } from '@ceed/ads';
44
+ import { Modal, ModalDialog, ModalClose, DialogTitle, DialogContent, DialogActions, Button } from '@ceed/ads';
53
45
 
54
46
  function MyComponent() {
55
47
  const [open, setOpen] = useState(false);
@@ -61,9 +53,7 @@ function MyComponent() {
61
53
  <ModalDialog>
62
54
  <ModalClose />
63
55
  <DialogTitle>Modal Title</DialogTitle>
64
- <DialogContent>
65
- Place your content here.
66
- </DialogContent>
56
+ <DialogContent>Place your content here.</DialogContent>
67
57
  <DialogActions>
68
58
  <Button onClick={() => setOpen(false)}>Close</Button>
69
59
  </DialogActions>
@@ -74,6 +64,28 @@ function MyComponent() {
74
64
  }
75
65
  ```
76
66
 
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
+
77
89
  ## Examples
78
90
 
79
91
  ### Basic Modal
@@ -292,6 +304,162 @@ Modals can be stacked on top of each other when necessary.
292
304
  </>
293
305
  ```
294
306
 
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** provide explicit `width` and `height` values.
446
+ > ModalFrame inherits its dimensions from `ModalDialog`, which normally receives sizing from the Modal overlay.
447
+ > Without these constraints, the component will not render with correct dimensions.
448
+
449
+ ```tsx
450
+ <Box sx={{
451
+ width: 480,
452
+ height: 300
453
+ }}>
454
+ <ModalFrame title="Standalone ModalFrame" onClose={() => console.log('close')}>
455
+ <Typography>
456
+ ModalFrame used without Modal. The parent container must provide
457
+ explicit width and height.
458
+ </Typography>
459
+ </ModalFrame>
460
+ </Box>
461
+ ```
462
+
295
463
  ## When to Use
296
464
 
297
465
  ### ✅ Good Use Cases
@@ -327,8 +495,7 @@ function DeleteConfirmation({ item, onDelete, onCancel }) {
327
495
  </DialogTitle>
328
496
  <Divider />
329
497
  <DialogContent>
330
- This action cannot be undone. All data associated with this item
331
- will be permanently removed.
498
+ This action cannot be undone. All data associated with this item will be permanently removed.
332
499
  </DialogContent>
333
500
  <DialogActions>
334
501
  <Button variant="solid" color="danger" onClick={onDelete}>
@@ -404,8 +571,7 @@ function TermsModal({ open, onAccept, onDecline }) {
404
571
  <DialogTitle>Terms of Service</DialogTitle>
405
572
  <DialogContent>
406
573
  <Typography level="body-sm">
407
- Please read and accept the following terms and conditions before
408
- proceeding...
574
+ Please read and accept the following terms and conditions before proceeding...
409
575
  </Typography>
410
576
  {/* Terms content */}
411
577
  </DialogContent>
@@ -433,11 +599,7 @@ function ImagePreviewModal({ image, open, onClose }) {
433
599
  <Modal open={open} onClose={onClose}>
434
600
  <ModalDialog layout="center" sx={{ p: 0, overflow: 'hidden' }}>
435
601
  <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
- />
602
+ <img src={image.src} alt={image.alt} style={{ maxWidth: '90vw', maxHeight: '90vh', objectFit: 'contain' }} />
441
603
  </ModalDialog>
442
604
  </Modal>
443
605
  );
@@ -468,22 +630,69 @@ function LoadingModal({ open, message }) {
468
630
  Modal uses a composition pattern with multiple sub-components:
469
631
 
470
632
  ```tsx
471
- <Modal> {/* Overlay and backdrop */}
472
- <ModalDialog> {/* Dialog container */}
473
- <ModalClose /> {/* Close button (optional) */}
474
- <DialogTitle> {/* Header */}
633
+ <Modal>
634
+ {/* Overlay and backdrop */}
635
+ <ModalDialog>
636
+ {/* Dialog container */}
637
+ <ModalClose /> {/* Close button (optional) */}
638
+ <DialogTitle>
639
+ {/* Header */}
475
640
  Title
476
641
  </DialogTitle>
477
- <DialogContent> {/* Body */}
642
+ <DialogContent>
643
+ {/* Body */}
478
644
  Content goes here
479
645
  </DialogContent>
480
- <DialogActions> {/* Footer */}
646
+ <DialogActions>
647
+ {/* Footer */}
481
648
  <Button>Action</Button>
482
649
  </DialogActions>
483
650
  </ModalDialog>
484
651
  </Modal>
485
652
  ```
486
653
 
654
+ ## Component Roles
655
+
656
+ | Component | Role | When to Use |
657
+ | ----------------- | --------------------------------------------------------------- | ---------------------------------------------------------------- |
658
+ | **Modal** | Overlay backdrop, open/close state management | Always required as the outermost wrapper |
659
+ | **ModalDialog** | Dialog container (variant/size/layout) | When you need direct control over layout |
660
+ | **ModalClose** | Close (X) button in the top-right corner | When users should be able to close via a button |
661
+ | **ModalOverflow** | Scrollable area | When content exceeds the viewport |
662
+ | **ModalFrame** | Combines ModalDialog + ModalClose + DialogTitle + DialogContent | When you only need a title + close + content (no action buttons) |
663
+ | **DialogTitle** | Header area (styled padding) | When composing manually |
664
+ | **DialogContent** | Body area (styled padding) | When composing manually |
665
+ | **DialogActions** | Footer action button area | When confirm/cancel buttons are needed |
666
+
667
+ ## Choosing the Right Component
668
+
669
+ ### ModalFrame vs DialogFrame
670
+
671
+ | | ModalFrame | DialogFrame |
672
+ | ------------------ | ----------------------------------------------- | --------------------------------------- |
673
+ | Close (X) button | Built-in | None |
674
+ | Title decorator | `titleStartDecorator` | None |
675
+ | Action button area | None | `actions` prop (required) |
676
+ | Fullscreen | `layout="fullscreen"` | `fullscreen` prop |
677
+ | Best for | Information display, detail views, inline forms | Confirm/cancel dialogs, decision-making |
678
+
679
+ ### Use ModalFrame when
680
+
681
+ - You need an informational modal with a close button (detail views, previews)
682
+ - The form's submit button lives inside the content area
683
+ - You need an icon next to the title
684
+
685
+ ### Use DialogFrame when
686
+
687
+ - Explicit action buttons (confirm/cancel) must be pinned to the bottom
688
+ - User decisions are required (delete confirmation, save confirmation)
689
+ - Only explicit choices should be allowed without a close (X) button
690
+
691
+ ### Use manual composition when
692
+
693
+ - You need a custom layout that doesn't fit the ModalFrame/DialogFrame pattern
694
+ - You want to use both ModalClose and DialogActions together
695
+
487
696
  ## Props and Customization
488
697
 
489
698
  ### Modal Props
@@ -505,6 +714,17 @@ Modal uses a composition pattern with multiple sub-components:
505
714
  | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Dialog size |
506
715
  | `layout` | `'center' \| 'fullscreen'` | `'center'` | Layout mode |
507
716
 
717
+ ### ModalFrame Props
718
+
719
+ | Prop | Type | Default | Description |
720
+ | --------------------- | ------------ | ------- | ------------------------------------------ |
721
+ | `title` | `ReactNode` | - | Title displayed in the header |
722
+ | `children` | `ReactNode` | - | Body content |
723
+ | `titleStartDecorator` | `ReactNode` | - | Icon or element displayed before the title |
724
+ | `onClose` | `() => void` | - | Callback when the close button is clicked |
725
+
726
+ ModalFrame accepts all ModalDialog props (`variant`, `color`, `size`, `layout`, `sx`, etc.).
727
+
508
728
  ### Custom Styling
509
729
 
510
730
  ```tsx
@@ -543,17 +763,10 @@ Modal components include comprehensive accessibility features:
543
763
  - `aria-describedby` connects to DialogContent
544
764
 
545
765
  ```tsx
546
- <Modal
547
- open={open}
548
- onClose={onClose}
549
- aria-labelledby="modal-title"
550
- aria-describedby="modal-description"
551
- >
766
+ <Modal open={open} onClose={onClose} aria-labelledby="modal-title" aria-describedby="modal-description">
552
767
  <ModalDialog>
553
768
  <DialogTitle id="modal-title">Accessible Title</DialogTitle>
554
- <DialogContent id="modal-description">
555
- This content is read by screen readers.
556
- </DialogContent>
769
+ <DialogContent id="modal-description">This content is read by screen readers.</DialogContent>
557
770
  </ModalDialog>
558
771
  </Modal>
559
772
  ```
@@ -582,7 +795,9 @@ Modal components include comprehensive accessibility features:
582
795
  ```tsx
583
796
  // ✅ Good: Clear action buttons
584
797
  <DialogActions>
585
- <Button variant="solid" color="danger">Delete</Button>
798
+ <Button variant="solid" color="danger">
799
+ Delete
800
+ </Button>
586
801
  <Button variant="plain">Cancel</Button>
587
802
  </DialogActions>
588
803
  ```
@@ -657,15 +872,11 @@ Use `keepMounted` only when the modal needs to preserve state between openings:
657
872
  Memoize modal content when it depends on complex data:
658
873
 
659
874
  ```tsx
660
- const modalContent = useMemo(() => (
661
- <ComplexContent data={data} />
662
- ), [data]);
875
+ const modalContent = useMemo(() => <ComplexContent data={data} />, [data]);
663
876
 
664
877
  <Modal open={open} onClose={onClose}>
665
- <ModalDialog>
666
- {modalContent}
667
- </ModalDialog>
668
- </Modal>
878
+ <ModalDialog>{modalContent}</ModalDialog>
879
+ </Modal>;
669
880
  ```
670
881
 
671
882
  Modal is a powerful component for focused user interactions. Use it thoughtfully to maintain a smooth user experience while capturing important decisions and inputs.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ceed/ads",
3
- "version": "1.23.0",
3
+ "version": "1.23.1",
4
4
  "main": "dist/index.cjs",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",