@ceed/ads 1.29.1 → 1.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Overview.md +5 -5
- package/dist/components/DatePicker/DatePicker.d.ts +10 -0
- package/dist/components/DateRangePicker/DateRangePicker.d.ts +10 -0
- package/dist/components/data-display/Avatar.md +85 -74
- package/dist/components/data-display/Badge.md +23 -5
- package/dist/components/data-display/Chip.md +49 -35
- package/dist/components/data-display/DataTable.md +93 -0
- package/dist/components/data-display/InfoSign.md +15 -5
- package/dist/components/data-display/Markdown.md +22 -26
- package/dist/components/data-display/Table.md +63 -53
- package/dist/components/data-display/Tooltip.md +70 -58
- package/dist/components/data-display/Typography.md +28 -11
- package/dist/components/feedback/Alert.md +86 -74
- package/dist/components/feedback/CircularProgress.md +20 -5
- package/dist/components/feedback/Dialog.md +8 -12
- package/dist/components/feedback/Modal.md +12 -16
- package/dist/components/feedback/Skeleton.md +20 -5
- package/dist/components/inputs/Autocomplete.md +8 -10
- package/dist/components/inputs/Button.md +107 -87
- package/dist/components/inputs/ButtonGroup.md +20 -5
- package/dist/components/inputs/Calendar.md +25 -5
- package/dist/components/inputs/Checkbox.md +171 -450
- package/dist/components/inputs/CurrencyInput.md +25 -5
- package/dist/components/inputs/DatePicker.md +87 -5
- package/dist/components/inputs/DateRangePicker.md +91 -5
- package/dist/components/inputs/FilterMenu.md +85 -9
- package/dist/components/inputs/FilterableCheckboxGroup.md +23 -8
- package/dist/components/inputs/FormControl.md +34 -6
- package/dist/components/inputs/IconButton.md +21 -5
- package/dist/components/inputs/Input.md +254 -68
- package/dist/components/inputs/MonthPicker.md +28 -5
- package/dist/components/inputs/MonthRangePicker.md +26 -5
- package/dist/components/inputs/PercentageInput.md +28 -5
- package/dist/components/inputs/RadioButton.md +26 -5
- package/dist/components/inputs/RadioList.md +23 -6
- package/dist/components/inputs/RadioTileGroup.md +40 -8
- package/dist/components/inputs/Select.md +59 -5
- package/dist/components/inputs/Slider.md +26 -5
- package/dist/components/inputs/Switch.md +23 -5
- package/dist/components/inputs/Textarea.md +27 -5
- package/dist/components/inputs/Uploader/Uploader.md +24 -5
- package/dist/components/layout/Box.md +66 -58
- package/dist/components/layout/Container.md +9 -13
- package/dist/components/layout/Grid.md +91 -75
- package/dist/components/layout/Stack.md +85 -70
- package/dist/components/navigation/Breadcrumbs.md +23 -14
- package/dist/components/navigation/Dropdown.md +29 -20
- package/dist/components/navigation/IconMenuButton.md +24 -11
- package/dist/components/navigation/InsetDrawer.md +16 -5
- package/dist/components/navigation/Link.md +30 -14
- package/dist/components/navigation/Menu.md +33 -20
- package/dist/components/navigation/MenuButton.md +26 -12
- package/dist/components/navigation/NavigationGroup.md +7 -11
- package/dist/components/navigation/NavigationItem.md +8 -12
- package/dist/components/navigation/Navigator.md +5 -9
- package/dist/components/navigation/Pagination.md +21 -12
- package/dist/components/navigation/ProfileMenu.md +17 -5
- package/dist/components/navigation/Stepper.md +18 -5
- package/dist/components/navigation/Tabs.md +37 -14
- package/dist/components/surfaces/Accordions.md +12 -16
- package/dist/components/surfaces/Card.md +59 -47
- package/dist/components/surfaces/Divider.md +70 -61
- package/dist/components/surfaces/Sheet.md +18 -5
- package/dist/index.browser.js +2 -2
- package/dist/index.browser.js.map +3 -3
- package/dist/index.cjs +173 -6
- package/dist/index.js +173 -6
- package/framer/index.js +1 -1
- package/package.json +1 -1
|
@@ -86,9 +86,7 @@ function DetailModal({ open, onClose }) {
|
|
|
86
86
|
> **Note**: Connect the same handler to both `Modal`'s `onClose` and `ModalFrame`'s `onClose`.
|
|
87
87
|
> `Modal` handles backdrop click and ESC key, while `ModalFrame` handles the X button click.
|
|
88
88
|
|
|
89
|
-
##
|
|
90
|
-
|
|
91
|
-
### Basic Modal
|
|
89
|
+
## Basic Modal
|
|
92
90
|
|
|
93
91
|
The basic modal with a simple Sheet for custom layouts.
|
|
94
92
|
|
|
@@ -121,7 +119,7 @@ The basic modal with a simple Sheet for custom layouts.
|
|
|
121
119
|
</>
|
|
122
120
|
```
|
|
123
121
|
|
|
124
|
-
|
|
122
|
+
## Modal Dialog
|
|
125
123
|
|
|
126
124
|
Use ModalDialog for structured dialogs with title, content, and actions.
|
|
127
125
|
|
|
@@ -156,7 +154,7 @@ Use ModalDialog for structured dialogs with title, content, and actions.
|
|
|
156
154
|
</>
|
|
157
155
|
```
|
|
158
156
|
|
|
159
|
-
|
|
157
|
+
## Modal Dialog Variants
|
|
160
158
|
|
|
161
159
|
Modal dialogs support different visual variants.
|
|
162
160
|
|
|
@@ -220,7 +218,7 @@ Modal dialogs support different visual variants.
|
|
|
220
218
|
</>
|
|
221
219
|
```
|
|
222
220
|
|
|
223
|
-
|
|
221
|
+
## Alert Dialog
|
|
224
222
|
|
|
225
223
|
For critical confirmations that require explicit user decision.
|
|
226
224
|
|
|
@@ -250,7 +248,7 @@ For critical confirmations that require explicit user decision.
|
|
|
250
248
|
</>
|
|
251
249
|
```
|
|
252
250
|
|
|
253
|
-
|
|
251
|
+
## Modal Layouts
|
|
254
252
|
|
|
255
253
|
#### Fullscreen Layout
|
|
256
254
|
|
|
@@ -274,7 +272,7 @@ For complex content that requires maximum screen space.
|
|
|
274
272
|
</>
|
|
275
273
|
```
|
|
276
274
|
|
|
277
|
-
|
|
275
|
+
## Nested Modals
|
|
278
276
|
|
|
279
277
|
Modals can be stacked on top of each other when necessary.
|
|
280
278
|
|
|
@@ -304,7 +302,7 @@ Modals can be stacked on top of each other when necessary.
|
|
|
304
302
|
</>
|
|
305
303
|
```
|
|
306
304
|
|
|
307
|
-
|
|
305
|
+
## ModalFrame Examples
|
|
308
306
|
|
|
309
307
|
ModalFrame is a convenience component that automatically provides a title, close button, and content area.
|
|
310
308
|
|
|
@@ -482,9 +480,7 @@ ModalFrame can be used without a Modal wrapper for embedding dialog-style layout
|
|
|
482
480
|
- **Non-critical information**: Success messages or tips should use Toast or inline feedback
|
|
483
481
|
- **Mobile navigation**: Consider using full-page transitions instead on mobile devices
|
|
484
482
|
|
|
485
|
-
##
|
|
486
|
-
|
|
487
|
-
### Confirmation Dialog
|
|
483
|
+
## Confirmation Dialog
|
|
488
484
|
|
|
489
485
|
Confirm destructive or significant actions before executing them.
|
|
490
486
|
|
|
@@ -515,7 +511,7 @@ function DeleteConfirmation({ item, onDelete, onCancel }) {
|
|
|
515
511
|
}
|
|
516
512
|
```
|
|
517
513
|
|
|
518
|
-
|
|
514
|
+
## Form Modal
|
|
519
515
|
|
|
520
516
|
Capture user input in a focused dialog.
|
|
521
517
|
|
|
@@ -563,7 +559,7 @@ function CreateProjectModal({ open, onClose, onCreate }) {
|
|
|
563
559
|
}
|
|
564
560
|
```
|
|
565
561
|
|
|
566
|
-
|
|
562
|
+
## Information Modal
|
|
567
563
|
|
|
568
564
|
Display detailed information that requires user acknowledgment.
|
|
569
565
|
|
|
@@ -593,7 +589,7 @@ function TermsModal({ open, onAccept, onDecline }) {
|
|
|
593
589
|
}
|
|
594
590
|
```
|
|
595
591
|
|
|
596
|
-
|
|
592
|
+
## Image Preview Modal
|
|
597
593
|
|
|
598
594
|
Display images or media in a focused overlay.
|
|
599
595
|
|
|
@@ -610,7 +606,7 @@ function ImagePreviewModal({ image, open, onClose }) {
|
|
|
610
606
|
}
|
|
611
607
|
```
|
|
612
608
|
|
|
613
|
-
|
|
609
|
+
## Loading Modal
|
|
614
610
|
|
|
615
611
|
Block user interaction during async operations.
|
|
616
612
|
|
|
@@ -183,9 +183,7 @@ Wrap existing content with Skeleton to overlay it while loading. Set the `loadin
|
|
|
183
183
|
</Typography>
|
|
184
184
|
```
|
|
185
185
|
|
|
186
|
-
##
|
|
187
|
-
|
|
188
|
-
### Page Content Loading
|
|
186
|
+
## Page Content Loading
|
|
189
187
|
|
|
190
188
|
```tsx
|
|
191
189
|
function PageSkeleton() {
|
|
@@ -205,7 +203,7 @@ function PageSkeleton() {
|
|
|
205
203
|
}
|
|
206
204
|
```
|
|
207
205
|
|
|
208
|
-
|
|
206
|
+
## User List Loading
|
|
209
207
|
|
|
210
208
|
```tsx
|
|
211
209
|
function UserListSkeleton({ count = 5 }: { count?: number }) {
|
|
@@ -225,7 +223,7 @@ function UserListSkeleton({ count = 5 }: { count?: number }) {
|
|
|
225
223
|
}
|
|
226
224
|
```
|
|
227
225
|
|
|
228
|
-
|
|
226
|
+
## Conditional Rendering
|
|
229
227
|
|
|
230
228
|
```tsx
|
|
231
229
|
function UserProfile({ loading, user }: { loading: boolean; user?: User }) {
|
|
@@ -249,6 +247,23 @@ function UserProfile({ loading, user }: { loading: boolean; user?: User }) {
|
|
|
249
247
|
}
|
|
250
248
|
```
|
|
251
249
|
|
|
250
|
+
## Props and Customization
|
|
251
|
+
|
|
252
|
+
### Key Props
|
|
253
|
+
|
|
254
|
+
| Prop | Type | Default | Description |
|
|
255
|
+
| ----------- | ---------------------------------------------------------------- | ----------- | ---------------------------------------------- |
|
|
256
|
+
| `variant` | `'rectangular' \| 'circular' \| 'text' \| 'overlay' \| 'inline'` | `'overlay'` | Skeleton shape |
|
|
257
|
+
| `animation` | `'pulse' \| 'wave' \| false` | `'pulse'` | Animation type |
|
|
258
|
+
| `width` | `number \| string` | - | Skeleton width |
|
|
259
|
+
| `height` | `number \| string` | - | Skeleton height |
|
|
260
|
+
| `level` | Typography level | - | Matches text height for `text` variant |
|
|
261
|
+
| `loading` | `boolean` | `true` | When false, shows children instead of skeleton |
|
|
262
|
+
| `children` | `ReactNode` | - | Content to show when not loading |
|
|
263
|
+
| `sx` | `SxProps` | - | Custom styles |
|
|
264
|
+
|
|
265
|
+
> **Note**: Skeleton also accepts all Joy UI Skeleton props.
|
|
266
|
+
|
|
252
267
|
## Best Practices
|
|
253
268
|
|
|
254
269
|
1. **Match the final layout**: Skeleton placeholders should closely approximate the size and position of the real content to prevent layout shifts.
|
|
@@ -423,9 +423,7 @@ These boolean props fine-tune interaction behavior. Toggle them in the Controls
|
|
|
423
423
|
- **Numeric ranges**: Use Slider or NumberInput
|
|
424
424
|
- **Date selection**: Use DatePicker
|
|
425
425
|
|
|
426
|
-
##
|
|
427
|
-
|
|
428
|
-
### Country Selector
|
|
426
|
+
## Country Selector
|
|
429
427
|
|
|
430
428
|
```tsx
|
|
431
429
|
function CountrySelector({ value, onChange }) {
|
|
@@ -452,7 +450,7 @@ function CountrySelector({ value, onChange }) {
|
|
|
452
450
|
}
|
|
453
451
|
```
|
|
454
452
|
|
|
455
|
-
|
|
453
|
+
## User Search
|
|
456
454
|
|
|
457
455
|
```tsx
|
|
458
456
|
function UserSearch({ onSelect }) {
|
|
@@ -500,7 +498,7 @@ function UserSearch({ onSelect }) {
|
|
|
500
498
|
}
|
|
501
499
|
```
|
|
502
500
|
|
|
503
|
-
|
|
501
|
+
## Product Search with Categories
|
|
504
502
|
|
|
505
503
|
```tsx
|
|
506
504
|
function ProductSearch({ products, onSelect }) {
|
|
@@ -531,7 +529,7 @@ function ProductSearch({ products, onSelect }) {
|
|
|
531
529
|
}
|
|
532
530
|
```
|
|
533
531
|
|
|
534
|
-
|
|
532
|
+
## Address Autocomplete
|
|
535
533
|
|
|
536
534
|
```tsx
|
|
537
535
|
function AddressAutocomplete({ onAddressSelect }) {
|
|
@@ -576,7 +574,7 @@ function AddressAutocomplete({ onAddressSelect }) {
|
|
|
576
574
|
}
|
|
577
575
|
```
|
|
578
576
|
|
|
579
|
-
|
|
577
|
+
## Tag Selection (Multiple)
|
|
580
578
|
|
|
581
579
|
```tsx
|
|
582
580
|
function TagSelector({ availableTags, selectedTags, onChange }) {
|
|
@@ -608,7 +606,7 @@ function TagSelector({ availableTags, selectedTags, onChange }) {
|
|
|
608
606
|
}
|
|
609
607
|
```
|
|
610
608
|
|
|
611
|
-
|
|
609
|
+
## Grouped Options
|
|
612
610
|
|
|
613
611
|
```tsx
|
|
614
612
|
function CategorySelector() {
|
|
@@ -634,7 +632,7 @@ function CategorySelector() {
|
|
|
634
632
|
}
|
|
635
633
|
```
|
|
636
634
|
|
|
637
|
-
|
|
635
|
+
## With Secondary Text
|
|
638
636
|
|
|
639
637
|
```tsx
|
|
640
638
|
function ContactSelector() {
|
|
@@ -649,7 +647,7 @@ function ContactSelector() {
|
|
|
649
647
|
}
|
|
650
648
|
```
|
|
651
649
|
|
|
652
|
-
|
|
650
|
+
## Lazy Loading Options
|
|
653
651
|
|
|
654
652
|
```tsx
|
|
655
653
|
function LazyAutocomplete({ fetchOptions }) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Introduction
|
|
4
4
|
|
|
5
|
-
Button
|
|
5
|
+
Button is the primary interactive element for triggering actions. Built on Joy UI's Button with Framer Motion animation support, it provides multiple visual variants, sizes, colors, loading states, and decorator slots. Use buttons for form submissions, navigation triggers, modal actions, and data operations.
|
|
6
6
|
|
|
7
7
|
```tsx
|
|
8
8
|
<>
|
|
@@ -26,15 +26,13 @@ Button 컴포넌트는 사용자가 클릭하여 특정 작업을 수행할 수
|
|
|
26
26
|
import { Button } from '@ceed/ads';
|
|
27
27
|
|
|
28
28
|
function MyComponent() {
|
|
29
|
-
return <Button onClick={() => console.log('
|
|
29
|
+
return <Button onClick={() => console.log('Clicked!')}>Click me</Button>;
|
|
30
30
|
}
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
##
|
|
33
|
+
## Basic Usage
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
가장 기본적인 버튼 사용법입니다.
|
|
35
|
+
The most basic button usage.
|
|
38
36
|
|
|
39
37
|
```tsx
|
|
40
38
|
<>
|
|
@@ -44,9 +42,9 @@ function MyComponent() {
|
|
|
44
42
|
</>
|
|
45
43
|
```
|
|
46
44
|
|
|
47
|
-
|
|
45
|
+
## Disabled Button
|
|
48
46
|
|
|
49
|
-
|
|
47
|
+
A disabled button cannot be clicked and is visually dimmed.
|
|
50
48
|
|
|
51
49
|
```tsx
|
|
52
50
|
<>
|
|
@@ -65,9 +63,9 @@ function MyComponent() {
|
|
|
65
63
|
</>
|
|
66
64
|
```
|
|
67
65
|
|
|
68
|
-
|
|
66
|
+
## Button Loading State
|
|
69
67
|
|
|
70
|
-
|
|
68
|
+
Shows a loading indicator during async operations. The button is automatically disabled while loading.
|
|
71
69
|
|
|
72
70
|
```tsx
|
|
73
71
|
<Button
|
|
@@ -80,11 +78,9 @@ function MyComponent() {
|
|
|
80
78
|
/>
|
|
81
79
|
```
|
|
82
80
|
|
|
83
|
-
##
|
|
84
|
-
|
|
85
|
-
### Variants
|
|
81
|
+
## Variants
|
|
86
82
|
|
|
87
|
-
|
|
83
|
+
Four visual styles are available to indicate action importance.
|
|
88
84
|
|
|
89
85
|
```tsx
|
|
90
86
|
<>
|
|
@@ -103,14 +99,14 @@ function MyComponent() {
|
|
|
103
99
|
</>
|
|
104
100
|
```
|
|
105
101
|
|
|
106
|
-
- **solid**:
|
|
107
|
-
- **soft**:
|
|
108
|
-
- **outlined**:
|
|
109
|
-
- **plain**:
|
|
102
|
+
- **solid**: High-emphasis primary actions (default)
|
|
103
|
+
- **soft**: Medium-emphasis secondary actions with a subtle background
|
|
104
|
+
- **outlined**: Low-emphasis actions with a border
|
|
105
|
+
- **plain**: Minimal actions with text only
|
|
110
106
|
|
|
111
|
-
|
|
107
|
+
## Sizes
|
|
112
108
|
|
|
113
|
-
|
|
109
|
+
Three sizes are available: `sm`, `md` (default), and `lg`.
|
|
114
110
|
|
|
115
111
|
```tsx
|
|
116
112
|
<>
|
|
@@ -126,13 +122,9 @@ function MyComponent() {
|
|
|
126
122
|
</>
|
|
127
123
|
```
|
|
128
124
|
|
|
129
|
-
|
|
130
|
-
- **md**: 중간 크기 (기본값)
|
|
131
|
-
- **lg**: 큰 크기 (강조가 필요한 경우)
|
|
132
|
-
|
|
133
|
-
### Colors
|
|
125
|
+
## Colors
|
|
134
126
|
|
|
135
|
-
|
|
127
|
+
Apply semantic colors to communicate intent.
|
|
136
128
|
|
|
137
129
|
```tsx
|
|
138
130
|
<>
|
|
@@ -154,15 +146,15 @@ function MyComponent() {
|
|
|
154
146
|
</>
|
|
155
147
|
```
|
|
156
148
|
|
|
157
|
-
- **primary**:
|
|
158
|
-
- **neutral**:
|
|
159
|
-
- **success**:
|
|
160
|
-
- **warning**:
|
|
161
|
-
- **danger**:
|
|
149
|
+
- **primary**: Main actions (default)
|
|
150
|
+
- **neutral**: Neutral actions
|
|
151
|
+
- **success**: Confirmation or positive actions
|
|
152
|
+
- **warning**: Caution-required actions
|
|
153
|
+
- **danger**: Destructive or irreversible actions
|
|
162
154
|
|
|
163
|
-
|
|
155
|
+
## Button Decorators
|
|
164
156
|
|
|
165
|
-
|
|
157
|
+
Add icons or other elements before or after the button text using `startDecorator` and `endDecorator`.
|
|
166
158
|
|
|
167
159
|
```tsx
|
|
168
160
|
<>
|
|
@@ -175,9 +167,9 @@ function MyComponent() {
|
|
|
175
167
|
</>
|
|
176
168
|
```
|
|
177
169
|
|
|
178
|
-
|
|
170
|
+
## Loading Indicator Customization
|
|
179
171
|
|
|
180
|
-
|
|
172
|
+
Customize the loading spinner with the `loadingIndicator` prop.
|
|
181
173
|
|
|
182
174
|
```tsx
|
|
183
175
|
<>
|
|
@@ -190,9 +182,9 @@ function MyComponent() {
|
|
|
190
182
|
</>
|
|
191
183
|
```
|
|
192
184
|
|
|
193
|
-
|
|
185
|
+
## Loading Position
|
|
194
186
|
|
|
195
|
-
|
|
187
|
+
Control where the loading indicator appears with `loadingPosition`.
|
|
196
188
|
|
|
197
189
|
```tsx
|
|
198
190
|
<>
|
|
@@ -205,66 +197,64 @@ function MyComponent() {
|
|
|
205
197
|
</>
|
|
206
198
|
```
|
|
207
199
|
|
|
208
|
-
##
|
|
209
|
-
|
|
210
|
-
### Form Submission
|
|
200
|
+
## Button in Form Submission
|
|
211
201
|
|
|
212
202
|
```tsx
|
|
213
203
|
<form onSubmit={handleSubmit}>
|
|
214
204
|
<Stack spacing={2}>
|
|
215
|
-
<Input placeholder="
|
|
216
|
-
<Input placeholder="
|
|
205
|
+
<Input placeholder="Enter your name" />
|
|
206
|
+
<Input placeholder="Enter your email" />
|
|
217
207
|
|
|
218
208
|
<Stack direction="row" spacing={2} justifyContent="flex-end">
|
|
219
209
|
<Button variant="outlined" type="button" onClick={handleCancel}>
|
|
220
|
-
|
|
210
|
+
Cancel
|
|
221
211
|
</Button>
|
|
222
212
|
<Button type="submit" loading={isSubmitting}>
|
|
223
|
-
{isSubmitting ? '
|
|
213
|
+
{isSubmitting ? 'Saving...' : 'Save'}
|
|
224
214
|
</Button>
|
|
225
215
|
</Stack>
|
|
226
216
|
</Stack>
|
|
227
217
|
</form>
|
|
228
218
|
```
|
|
229
219
|
|
|
230
|
-
|
|
220
|
+
## Button in Modal Actions
|
|
231
221
|
|
|
232
222
|
```tsx
|
|
233
223
|
<Modal open={open}>
|
|
234
224
|
<ModalDialog>
|
|
235
225
|
<ModalClose />
|
|
236
|
-
<DialogTitle
|
|
237
|
-
<DialogContent
|
|
226
|
+
<DialogTitle>Confirm Deletion</DialogTitle>
|
|
227
|
+
<DialogContent>Are you sure you want to delete this item? This action cannot be undone.</DialogContent>
|
|
238
228
|
|
|
239
229
|
<DialogActions>
|
|
240
230
|
<Button variant="outlined" onClick={handleClose}>
|
|
241
|
-
|
|
231
|
+
Cancel
|
|
242
232
|
</Button>
|
|
243
233
|
<Button color="danger" onClick={handleDelete}>
|
|
244
|
-
|
|
234
|
+
Delete
|
|
245
235
|
</Button>
|
|
246
236
|
</DialogActions>
|
|
247
237
|
</ModalDialog>
|
|
248
238
|
</Modal>
|
|
249
239
|
```
|
|
250
240
|
|
|
251
|
-
|
|
241
|
+
## Action Buttons with Icons
|
|
252
242
|
|
|
253
243
|
```tsx
|
|
254
244
|
<Stack direction="row" spacing={2}>
|
|
255
|
-
<Button startDecorator={<AddIcon />}
|
|
245
|
+
<Button startDecorator={<AddIcon />}>Create New</Button>
|
|
256
246
|
|
|
257
247
|
<Button variant="outlined" startDecorator={<DownloadIcon />} onClick={handleDownload}>
|
|
258
|
-
|
|
248
|
+
Download
|
|
259
249
|
</Button>
|
|
260
250
|
|
|
261
251
|
<Button variant="soft" color="success" startDecorator={<ShareIcon />}>
|
|
262
|
-
|
|
252
|
+
Share
|
|
263
253
|
</Button>
|
|
264
254
|
</Stack>
|
|
265
255
|
```
|
|
266
256
|
|
|
267
|
-
|
|
257
|
+
## Async Operation Button
|
|
268
258
|
|
|
269
259
|
```tsx
|
|
270
260
|
function AsyncButton() {
|
|
@@ -274,9 +264,6 @@ function AsyncButton() {
|
|
|
274
264
|
setLoading(true);
|
|
275
265
|
try {
|
|
276
266
|
await api.processData();
|
|
277
|
-
// 성공 처리
|
|
278
|
-
} catch (error) {
|
|
279
|
-
// 에러 처리
|
|
280
267
|
} finally {
|
|
281
268
|
setLoading(false);
|
|
282
269
|
}
|
|
@@ -284,51 +271,84 @@ function AsyncButton() {
|
|
|
284
271
|
|
|
285
272
|
return (
|
|
286
273
|
<Button loading={loading} onClick={handleAsyncAction} startDecorator={<ProcessIcon />}>
|
|
287
|
-
|
|
274
|
+
Process Data
|
|
288
275
|
</Button>
|
|
289
276
|
);
|
|
290
277
|
}
|
|
291
278
|
```
|
|
292
279
|
|
|
293
|
-
|
|
280
|
+
## Props and Customization
|
|
281
|
+
|
|
282
|
+
### Key Props
|
|
283
|
+
|
|
284
|
+
| Prop | Type | Default | Description |
|
|
285
|
+
| ------------------ | -------------------------------------------------------------- | ---------------------- | ----------------------------------------------------------------- |
|
|
286
|
+
| `children` | `ReactNode` | - | Button content (text, icons, etc.) |
|
|
287
|
+
| `variant` | `'solid' \| 'soft' \| 'outlined' \| 'plain'` | `'solid'` | Visual style |
|
|
288
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Button size |
|
|
289
|
+
| `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | `'primary'` | Color scheme |
|
|
290
|
+
| `disabled` | `boolean` | `false` | Disables the button |
|
|
291
|
+
| `loading` | `boolean` | `false` | Shows a loading indicator and disables the button |
|
|
292
|
+
| `loadingIndicator` | `ReactNode` | `<CircularProgress />` | Custom loading indicator element |
|
|
293
|
+
| `loadingPosition` | `'start' \| 'end'` | `'start'` | Where the loading indicator appears |
|
|
294
|
+
| `startDecorator` | `ReactNode` | - | Content rendered before the button text |
|
|
295
|
+
| `endDecorator` | `ReactNode` | - | Content rendered after the button text |
|
|
296
|
+
| `fullWidth` | `boolean` | `false` | Stretches the button to fill its container width |
|
|
297
|
+
| `component` | `ElementType` | `'button'` | Root element type (polymorphic — can render as `a`, `Link`, etc.) |
|
|
298
|
+
| `type` | `'button' \| 'submit' \| 'reset'` | `'button'` | HTML button type attribute |
|
|
299
|
+
| `onClick` | `(event: MouseEvent) => void` | - | Click event handler |
|
|
300
|
+
| `sx` | `SxProps` | - | Custom styles using the MUI system |
|
|
301
|
+
|
|
302
|
+
> **Note**: Button also accepts all Joy UI Button props and Framer Motion props.
|
|
303
|
+
|
|
304
|
+
## Polymorphic Button
|
|
305
|
+
|
|
306
|
+
Button supports the `component` prop to render as a different element:
|
|
294
307
|
|
|
295
308
|
```tsx
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
진행중
|
|
302
|
-
</Button>
|
|
303
|
-
<Button variant="outlined" size="sm">
|
|
304
|
-
완료
|
|
305
|
-
</Button>
|
|
306
|
-
</Stack>
|
|
309
|
+
// Render as an anchor tag
|
|
310
|
+
<Button component="a" href="/dashboard">Go to Dashboard</Button>
|
|
311
|
+
|
|
312
|
+
// Render as a React Router Link
|
|
313
|
+
<Button component={Link} to="/settings">Settings</Button>
|
|
307
314
|
```
|
|
308
315
|
|
|
309
316
|
## Best Practices
|
|
310
317
|
|
|
311
|
-
1.
|
|
318
|
+
1. **Choose the right variant for the action hierarchy**:
|
|
319
|
+
- Primary action: `solid`
|
|
320
|
+
- Secondary action: `outlined` or `soft`
|
|
321
|
+
- Tertiary/minimal action: `plain`
|
|
312
322
|
|
|
313
|
-
2.
|
|
314
|
-
-
|
|
315
|
-
-
|
|
316
|
-
-
|
|
323
|
+
2. **Use consistent color semantics**:
|
|
324
|
+
- Destructive actions: `danger`
|
|
325
|
+
- Confirmations: `success`
|
|
326
|
+
- Caution: `warning`
|
|
317
327
|
|
|
318
|
-
3.
|
|
319
|
-
- 위험한 작업: `danger`
|
|
320
|
-
- 성공/확인: `success`
|
|
321
|
-
- 주의 필요: `warning`
|
|
328
|
+
3. **Use clear, specific labels.** The button text should describe exactly what happens when clicked.
|
|
322
329
|
|
|
323
|
-
|
|
330
|
+
```tsx
|
|
331
|
+
// ✅ Good
|
|
332
|
+
<Button color="danger">Delete Account</Button>
|
|
324
333
|
|
|
325
|
-
|
|
334
|
+
// ❌ Bad
|
|
335
|
+
<Button color="danger">OK</Button>
|
|
336
|
+
```
|
|
326
337
|
|
|
327
|
-
|
|
338
|
+
4. **Show loading state during async operations** to provide user feedback.
|
|
328
339
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
340
|
+
```tsx
|
|
341
|
+
<Button loading={isSubmitting} type="submit">
|
|
342
|
+
Save Changes
|
|
343
|
+
</Button>
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
5. **Limit the number of primary buttons** in a view. Typically one `solid` primary button per section.
|
|
347
|
+
|
|
348
|
+
## Accessibility
|
|
333
349
|
|
|
334
|
-
|
|
350
|
+
- **Keyboard accessible**: Tab to focus, Space or Enter to activate.
|
|
351
|
+
- **Screen reader support**: Button text is announced as the accessible name.
|
|
352
|
+
- **Disabled state**: When `disabled`, the button is removed from the tab order.
|
|
353
|
+
- **Loading state**: When `loading`, the button is announced as disabled. Consider adding `aria-label` to describe the loading context if the loading indicator replaces the text.
|
|
354
|
+
- **Color contrast**: All color/variant combinations meet WCAG AA contrast ratios.
|
|
@@ -262,9 +262,7 @@ By dynamically switching the `variant` prop on individual buttons based on selec
|
|
|
262
262
|
</div>
|
|
263
263
|
```
|
|
264
264
|
|
|
265
|
-
##
|
|
266
|
-
|
|
267
|
-
### Toolbar Actions
|
|
265
|
+
## Toolbar Actions
|
|
268
266
|
|
|
269
267
|
```tsx
|
|
270
268
|
import { ButtonGroup, Button } from '@ceed/ads';
|
|
@@ -279,7 +277,7 @@ import RedoIcon from '@mui/icons-material/Redo';
|
|
|
279
277
|
</ButtonGroup>
|
|
280
278
|
```
|
|
281
279
|
|
|
282
|
-
|
|
280
|
+
## View Switcher
|
|
283
281
|
|
|
284
282
|
```tsx
|
|
285
283
|
const [view, setView] = useState('list');
|
|
@@ -306,7 +304,7 @@ const [view, setView] = useState('list');
|
|
|
306
304
|
</ButtonGroup>
|
|
307
305
|
```
|
|
308
306
|
|
|
309
|
-
|
|
307
|
+
## Pagination Controls
|
|
310
308
|
|
|
311
309
|
```tsx
|
|
312
310
|
<ButtonGroup variant="outlined" size="sm">
|
|
@@ -383,6 +381,23 @@ const [view, setView] = useState('list');
|
|
|
383
381
|
|
|
384
382
|
5. **Consider vertical orientation for narrow layouts.** On mobile or in sidebars, `orientation="vertical"` prevents horizontal overflow and improves usability.
|
|
385
383
|
|
|
384
|
+
## Props and Customization
|
|
385
|
+
|
|
386
|
+
### Key Props
|
|
387
|
+
|
|
388
|
+
| Prop | Type | Default | Description |
|
|
389
|
+
| ------------- | -------------------------------------------------------------- | -------------- | ----------------------------------- |
|
|
390
|
+
| `children` | `ReactNode` | - | Button elements inside the group |
|
|
391
|
+
| `variant` | `'solid' \| 'soft' \| 'outlined' \| 'plain'` | `'outlined'` | Visual style applied to all buttons |
|
|
392
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size applied to all buttons |
|
|
393
|
+
| `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | `'neutral'` | Color applied to all buttons |
|
|
394
|
+
| `disabled` | `boolean` | `false` | Disables all buttons in the group |
|
|
395
|
+
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Layout direction |
|
|
396
|
+
| `spacing` | `number \| string` | `0` | Gap between buttons |
|
|
397
|
+
| `sx` | `SxProps` | - | Custom styles using the MUI system |
|
|
398
|
+
|
|
399
|
+
> **Note**: ButtonGroup accepts all Joy UI ButtonGroup props.
|
|
400
|
+
|
|
386
401
|
## Accessibility
|
|
387
402
|
|
|
388
403
|
- **Keyboard navigation**: All buttons within the group are focusable and navigable using the `Tab` key. Each button is a standard focusable element that responds to `Enter` and `Space`.
|