@ceed/ads 1.22.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.
@@ -43,9 +43,7 @@ function ConfirmationDialog({ open, onClose, onConfirm }) {
43
43
  <Button variant="plain" color="neutral" onClick={onClose}>
44
44
  Cancel
45
45
  </Button>
46
- <Button onClick={onConfirm}>
47
- Confirm
48
- </Button>
46
+ <Button onClick={onConfirm}>Confirm</Button>
49
47
  </>
50
48
  }
51
49
  >
@@ -94,6 +92,57 @@ Dialog Content
94
92
  </DialogFrame>
95
93
  ```
96
94
 
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** provide explicit `width` and `height` values.
102
+ > DialogFrame inherits its dimensions from `ModalDialog`, which normally receives sizing from the Modal overlay.
103
+ > Without these constraints, the component will not render with correct dimensions.
104
+
105
+ ```tsx
106
+ <Box sx={{
107
+ width: 480,
108
+ height: 300
109
+ }}>
110
+ <DialogFrame {...args} title="Standalone Dialog" actions={<>
111
+ <Button variant="plain" color="neutral">
112
+ Cancel
113
+ </Button>
114
+ <Button variant="plain">Confirm</Button>
115
+ </>}>
116
+ DialogFrame used without Modal. The parent container must provide explicit width and height.
117
+ </DialogFrame>
118
+ </Box>
119
+ ```
120
+
121
+ ```tsx
122
+ import { DialogFrame, Button, Box } from '@ceed/ads';
123
+
124
+ // Standalone usage requires explicit container dimensions
125
+ function EmbeddedDialog() {
126
+ return (
127
+ <Box sx={{ width: 480, height: 300 }}>
128
+ <DialogFrame
129
+ title="Settings"
130
+ actions={
131
+ <>
132
+ <Button variant="plain" color="neutral">
133
+ Cancel
134
+ </Button>
135
+ <Button>Save</Button>
136
+ </>
137
+ }
138
+ >
139
+ This dialog is embedded directly in the page layout.
140
+ </DialogFrame>
141
+ </Box>
142
+ );
143
+ }
144
+ ```
145
+
97
146
  ## When to Use
98
147
 
99
148
  ### ✅ Good Use Cases
@@ -177,21 +226,11 @@ function QuickAddDialog({ open, onClose, onSubmit }) {
177
226
  <Stack gap={2}>
178
227
  <FormControl>
179
228
  <FormLabel>Name</FormLabel>
180
- <Input
181
- value={name}
182
- onChange={(e) => setName(e.target.value)}
183
- placeholder="Enter name"
184
- autoFocus
185
- />
229
+ <Input value={name} onChange={(e) => setName(e.target.value)} placeholder="Enter name" autoFocus />
186
230
  </FormControl>
187
231
  <FormControl>
188
232
  <FormLabel>Email</FormLabel>
189
- <Input
190
- type="email"
191
- value={email}
192
- onChange={(e) => setEmail(e.target.value)}
193
- placeholder="Enter email"
194
- />
233
+ <Input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Enter email" />
195
234
  </FormControl>
196
235
  </Stack>
197
236
  </DialogFrame>
@@ -216,15 +255,11 @@ function UnsavedChangesDialog({ open, onClose, onDiscard, onSave }) {
216
255
  <Button variant="outlined" color="danger" onClick={onDiscard}>
217
256
  Discard
218
257
  </Button>
219
- <Button onClick={onSave}>
220
- Save Changes
221
- </Button>
258
+ <Button onClick={onSave}>Save Changes</Button>
222
259
  </>
223
260
  }
224
261
  >
225
- <Typography>
226
- You have unsaved changes. Would you like to save them before leaving?
227
- </Typography>
262
+ <Typography>You have unsaved changes. Would you like to save them before leaving?</Typography>
228
263
  </DialogFrame>
229
264
  </Modal>
230
265
  );
@@ -237,14 +272,7 @@ function UnsavedChangesDialog({ open, onClose, onDiscard, onSave }) {
237
272
  function InfoDialog({ open, onClose, title, message }) {
238
273
  return (
239
274
  <Modal open={open} onClose={onClose}>
240
- <DialogFrame
241
- title={title}
242
- actions={
243
- <Button onClick={onClose}>
244
- Got it
245
- </Button>
246
- }
247
- >
275
+ <DialogFrame title={title} actions={<Button onClick={onClose}>Got it</Button>}>
248
276
  <Typography>{message}</Typography>
249
277
  </DialogFrame>
250
278
  </Modal>
@@ -301,18 +329,8 @@ function ProcessingDialog({ open, status, onClose }) {
301
329
  return (
302
330
  <Modal open={open} onClose={isProcessing ? undefined : onClose}>
303
331
  <DialogFrame
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
- }
332
+ title={isProcessing ? 'Processing...' : isSuccess ? 'Success!' : 'Error'}
333
+ actions={!isProcessing && <Button onClick={onClose}>{isSuccess ? 'Done' : 'Try Again'}</Button>}
316
334
  >
317
335
  <Box sx={{ textAlign: 'center', py: 2 }}>
318
336
  {isProcessing && <CircularProgress />}
@@ -457,9 +475,7 @@ DialogFrame should be wrapped in Modal for proper behavior:
457
475
  // Fullscreen for complex content or mobile
458
476
  <Modal open={open} onClose={onClose}>
459
477
  <DialogFrame fullscreen title="Edit Profile">
460
- <Box sx={{ p: 2 }}>
461
- {/* Large form or content */}
462
- </Box>
478
+ <Box sx={{ p: 2 }}>{/* Large form or content */}</Box>
463
479
  </DialogFrame>
464
480
  </Modal>
465
481
  ```
@@ -500,9 +516,7 @@ DialogFrame inherits accessibility features from Modal:
500
516
 
501
517
  ```tsx
502
518
  // Title provides context
503
- <DialogFrame title="Confirm Deletion">
504
- {/* Content is read after title */}
505
- </DialogFrame>
519
+ <DialogFrame title="Confirm Deletion">{/* Content is read after title */}</DialogFrame>
506
520
  ```
507
521
 
508
522
  ## Best Practices
@@ -530,9 +544,7 @@ DialogFrame inherits accessibility features from Modal:
530
544
  ```tsx
531
545
  // ✅ Good: Brief, scannable content
532
546
  <DialogFrame title="Delete Project">
533
- <Typography>
534
- This will permanently delete the project and all its data.
535
- </Typography>
547
+ <Typography>This will permanently delete the project and all its data.</Typography>
536
548
  </DialogFrame>
537
549
  ```
538
550
 
@@ -560,7 +572,7 @@ DialogFrame inherits accessibility features from Modal:
560
572
  // ❌ Bad: Dialog for simple feedback
561
573
  <DialogFrame title="Success">
562
574
  <Typography>Item saved!</Typography>
563
- </DialogFrame>
575
+ </DialogFrame>;
564
576
 
565
577
  // ✅ Good: Use Toast
566
578
  showToast({ message: 'Item saved!' });
@@ -570,9 +582,7 @@ showToast({ message: 'Item saved!' });
570
582
 
571
583
  ```tsx
572
584
  // ❌ Bad: Complex form in dialog
573
- <DialogFrame title="Create Account">
574
- {/* 20+ form fields */}
575
- </DialogFrame>
585
+ <DialogFrame title="Create Account">{/* 20+ form fields */}</DialogFrame>
576
586
  ```
577
587
 
578
588
  3. **Don't use vague button labels**: Be specific about actions
@@ -599,9 +609,7 @@ For dialogs with heavy content:
599
609
  function HeavyDialog({ open, onClose }) {
600
610
  return (
601
611
  <Modal open={open} onClose={onClose}>
602
- <DialogFrame title="Data Preview">
603
- {open && <HeavyDataComponent />}
604
- </DialogFrame>
612
+ <DialogFrame title="Data Preview">{open && <HeavyDataComponent />}</DialogFrame>
605
613
  </Modal>
606
614
  );
607
615
  }
@@ -625,11 +633,13 @@ const handleCancel = useCallback(() => {
625
633
  Unmount dialog completely when not needed:
626
634
 
627
635
  ```tsx
628
- {open && (
629
- <Modal open={open} onClose={onClose}>
630
- <DialogFrame>...</DialogFrame>
631
- </Modal>
632
- )}
636
+ {
637
+ open && (
638
+ <Modal open={open} onClose={onClose}>
639
+ <DialogFrame>...</DialogFrame>
640
+ </Modal>
641
+ );
642
+ }
633
643
  ```
634
644
 
635
645
  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.