@ceed/cds 1.28.0 → 1.29.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/components/CurrencyInput/CurrencyInput.d.ts +1 -1
  2. package/dist/components/CurrencyInput/hooks/use-currency-setting.d.ts +2 -2
  3. package/dist/components/DataTable/hooks.d.ts +2 -1
  4. package/dist/components/DataTable/utils.d.ts +1 -0
  5. package/dist/components/SearchBar/SearchBar.d.ts +21 -0
  6. package/dist/components/SearchBar/index.d.ts +3 -0
  7. package/dist/components/data-display/DataTable.md +1 -1
  8. package/dist/components/data-display/InfoSign.md +91 -74
  9. package/dist/components/data-display/Typography.md +94 -411
  10. package/dist/components/feedback/Dialog.md +62 -76
  11. package/dist/components/feedback/Modal.md +138 -430
  12. package/dist/components/feedback/llms.txt +0 -2
  13. package/dist/components/index.d.ts +2 -1
  14. package/dist/components/inputs/Autocomplete.md +107 -356
  15. package/dist/components/inputs/ButtonGroup.md +104 -115
  16. package/dist/components/inputs/CurrencyInput.md +5 -183
  17. package/dist/components/inputs/DatePicker.md +431 -108
  18. package/dist/components/inputs/DateRangePicker.md +492 -131
  19. package/dist/components/inputs/FilterableCheckboxGroup.md +19 -145
  20. package/dist/components/inputs/IconButton.md +88 -137
  21. package/dist/components/inputs/Input.md +73 -204
  22. package/dist/components/inputs/MonthPicker.md +422 -95
  23. package/dist/components/inputs/MonthRangePicker.md +466 -89
  24. package/dist/components/inputs/PercentageInput.md +16 -185
  25. package/dist/components/inputs/RadioButton.md +35 -163
  26. package/dist/components/inputs/SearchBar.md +44 -0
  27. package/dist/components/inputs/Select.md +326 -222
  28. package/dist/components/inputs/Switch.md +376 -143
  29. package/dist/components/inputs/Textarea.md +10 -213
  30. package/dist/components/inputs/Uploader/Uploader.md +66 -145
  31. package/dist/components/inputs/llms.txt +1 -4
  32. package/dist/components/navigation/Breadcrumbs.md +308 -57
  33. package/dist/components/navigation/Drawer.md +0 -180
  34. package/dist/components/navigation/Dropdown.md +215 -98
  35. package/dist/components/navigation/IconMenuButton.md +502 -40
  36. package/dist/components/navigation/InsetDrawer.md +650 -281
  37. package/dist/components/navigation/Link.md +348 -31
  38. package/dist/components/navigation/Menu.md +285 -92
  39. package/dist/components/navigation/MenuButton.md +448 -55
  40. package/dist/components/navigation/Pagination.md +338 -47
  41. package/dist/components/navigation/Stepper.md +28 -160
  42. package/dist/components/navigation/Tabs.md +316 -57
  43. package/dist/components/surfaces/Accordions.md +804 -49
  44. package/dist/components/surfaces/Card.md +157 -97
  45. package/dist/components/surfaces/Divider.md +234 -83
  46. package/dist/components/surfaces/Sheet.md +328 -153
  47. package/dist/index.cjs +435 -577
  48. package/dist/index.d.ts +1 -1
  49. package/dist/index.js +424 -510
  50. package/dist/llms.txt +1 -9
  51. package/framer/index.js +1 -1
  52. package/package.json +17 -22
  53. package/dist/chunks/rehype-accent-FZRUD7VI.js +0 -39
  54. package/dist/components/RadioTileGroup/RadioTileGroup.d.ts +0 -56
  55. package/dist/components/RadioTileGroup/index.d.ts +0 -3
  56. package/dist/components/feedback/CircularProgress.md +0 -257
  57. package/dist/components/feedback/Skeleton.md +0 -280
  58. package/dist/components/inputs/FormControl.md +0 -361
  59. package/dist/components/inputs/RadioList.md +0 -241
  60. package/dist/components/inputs/RadioTileGroup.md +0 -507
  61. package/dist/components/inputs/Slider.md +0 -334
  62. package/dist/guides/ThemeProvider.md +0 -89
  63. package/dist/guides/llms.txt +0 -9
  64. package/dist/index.browser.js +0 -224
  65. package/dist/index.browser.js.map +0 -7
@@ -2,14 +2,7 @@
2
2
 
3
3
  ## Introduction
4
4
 
5
- FilterableCheckboxGroup is a multi-select component that combines a search input with a scrollable list of checkboxes. It is designed for scenarios where users need to select multiple items from a potentially large dataset. The built-in search filter narrows down visible options in real time, and virtual scrolling ensures smooth performance even with hundreds of items.
6
-
7
- Key capabilities include a "Select all" toggle for bulk selection, automatic sorting (selected items first, then alphabetical), customizable list height, and built-in form integration via `label`, `helperText`, and `required` props. The component accepts options as either simple strings or `{ value, label }` objects.
8
-
9
- > **Form 구성 시 내장 prop 사용을 권장합니다**
10
- >
11
- > 이 컴포넌트는 `label`, `helperText` 등의 Form 요소를 자체적으로 지원합니다.
12
- > Form을 구성할 때 Typography로 별도의 label이나 helperText를 만드는 대신, 컴포넌트의 내장 prop을 사용하세요.
5
+ FilterableCheckboxGroup 컴포넌트는 대량의 옵션 중에서 여러 항목을 선택할 있는 검색 가능한 체크박스 그룹입니다. 검색 필터링과 가상 스크롤링을 통해 많은 수의 옵션을 효율적으로 처리할 있으며, "Select all" 기능으로 일괄 선택이 가능합니다. 필터링, 다중 선택 폼, 설정 화면 등에서 유용하게 사용됩니다.
13
6
 
14
7
  ```tsx
15
8
  <FilterableCheckboxGroup
@@ -34,7 +27,7 @@ Key capabilities include a "Select all" toggle for bulk selection, automatic sor
34
27
  ## Usage
35
28
 
36
29
  ```tsx
37
- import { FilterableCheckboxGroup } from '@ceed/cds';
30
+ import { FilterableCheckboxGroup } from '@ceed/ads';
38
31
 
39
32
  function MyComponent() {
40
33
  const [selectedValues, setSelectedValues] = useState<string[]>([]);
@@ -57,9 +50,11 @@ function MyComponent() {
57
50
  }
58
51
  ```
59
52
 
60
- ## Sizes
53
+ ## Examples
61
54
 
62
- Three sizes are available: `sm`, `md`, and `lg`. The size affects the search input, checkboxes, and overall spacing.
55
+ ### Sizes
56
+
57
+ 다양한 크기의 FilterableCheckboxGroup을 사용할 수 있습니다.
63
58
 
64
59
  ```tsx
65
60
  <Stack spacing={3}>
@@ -69,11 +64,9 @@ Three sizes are available: `sm`, `md`, and `lg`. The size affects the search inp
69
64
  </Stack>
70
65
  ```
71
66
 
72
- ## Label and Helper Text
73
-
74
67
  ### With Label
75
68
 
76
- Use the `label` prop to describe the purpose of the checkbox group.
69
+ 라벨을 추가할 있습니다.
77
70
 
78
71
  ```tsx
79
72
  <FilterableCheckboxGroup
@@ -85,7 +78,7 @@ Use the `label` prop to describe the purpose of the checkbox group.
85
78
 
86
79
  ### With Helper Text
87
80
 
88
- Add a `helperText` prop to provide additional guidance below the component.
81
+ 도움말 텍스트를 추가할 있습니다.
89
82
 
90
83
  ```tsx
91
84
  <FilterableCheckboxGroup
@@ -98,7 +91,7 @@ Add a `helperText` prop to provide additional guidance below the component.
98
91
 
99
92
  ### Required Field
100
93
 
101
- Set `required` to append a required indicator to the label.
94
+ 필수 입력 필드로 표시할 있습니다.
102
95
 
103
96
  ```tsx
104
97
  <FilterableCheckboxGroup
@@ -110,9 +103,9 @@ Set `required` to append a required indicator to the label.
110
103
  />
111
104
  ```
112
105
 
113
- ## Custom Max Height
106
+ ### Custom Max Height
114
107
 
115
- Control the visible height of the options list with the `maxHeight` prop (default: 300px). A smaller height is useful when screen space is limited.
108
+ 목록의 최대 높이를 커스터마이징할 있습니다.
116
109
 
117
110
  ```tsx
118
111
  <Stack spacing={3}>
@@ -121,9 +114,9 @@ Control the visible height of the options list with the `maxHeight` prop (defaul
121
114
  </Stack>
122
115
  ```
123
116
 
124
- ## Long List with Virtual Scrolling
117
+ ### Long List
125
118
 
126
- When the options list is large, the component uses virtual scrolling to render only the visible items. This keeps the UI performant regardless of the total number of options.
119
+ 많은 수의 옵션을 가상 스크롤링으로 효율적으로 표시합니다.
127
120
 
128
121
  ```tsx
129
122
  <FilterableCheckboxGroup
@@ -136,9 +129,9 @@ When the options list is large, the component uses virtual scrolling to render o
136
129
  />
137
130
  ```
138
131
 
139
- ## Empty State
132
+ ### No Options
140
133
 
141
- When no options are provided, the component displays an empty state. This is useful for dynamically loaded option lists that may start empty.
134
+ 옵션이 없을 때의 상태입니다.
142
135
 
143
136
  ```tsx
144
137
  <FilterableCheckboxGroup
@@ -148,9 +141,9 @@ When no options are provided, the component displays an empty state. This is use
148
141
  />
149
142
  ```
150
143
 
151
- ## Controlled Mode
144
+ ### Controlled
152
145
 
153
- Pass `value` and `onChange` to manage the selection state externally. This is the recommended approach when the component is part of a form or when the selected values need to be used by other parts of the UI.
146
+ 외부에서 값을 제어하는 예제입니다.
154
147
 
155
148
  ```tsx
156
149
  <Stack spacing={2}>
@@ -162,9 +155,9 @@ Pass `value` and `onChange` to manage the selection state externally. This is th
162
155
  </Stack>
163
156
  ```
164
157
 
165
- ## Sorting Behavior
158
+ ### Sorting
166
159
 
167
- The component automatically sorts options on initial render: selected items appear first, followed by unselected items in alphabetical order. When new options are added dynamically, they are inserted in the correct sorted position.
160
+ 정렬 동작을 확인할 있는 예제입니다. 초기 렌더링 선택된 항목이 먼저 표시되고, 다음 알파벳 순으로 정렬됩니다.
168
161
 
169
162
  ```tsx
170
163
  <Stack spacing={2}>
@@ -197,122 +190,3 @@ The component automatically sorts options on initial render: selected items appe
197
190
  </Typography>
198
191
  </Stack>
199
192
  ```
200
-
201
- ## Disabled State
202
-
203
- The component supports both full and partial disabling.
204
-
205
- - **Full disable**: Set `disabled` on the component to disable the search input, "Select all" toggle, and all checkboxes.
206
- - **Partial disable**: Set `disabled: true` on individual option objects to disable specific items while keeping the rest interactive.
207
- - **"Select all" behavior**: Disabled options are excluded from the "Select all" toggle. Their selected state is preserved regardless of bulk actions.
208
-
209
- ```tsx
210
- <Stack spacing={3}>
211
- <FilterableCheckboxGroup label="Entirely Disabled" placeholder="Search..." helperText="All inputs are disabled" options={defaultOptions.slice(0, 5)} disabled />
212
- <FilterableCheckboxGroup label="Partially Disabled Options" placeholder="Search..." helperText="Some options are disabled" options={disabledOptions} />
213
- <Stack spacing={2}>
214
- <FilterableCheckboxGroup label="Controlled + Partially Disabled" placeholder="Search..." helperText="Disabled options (Banana, Date) maintain their selected state" options={disabledOptions} value={controlledValue} onChange={setControlledValue} />
215
- <Typography level="body-sm">
216
- Selected: {controlledValue.length > 0 ? controlledValue.join(', ') : 'None'}
217
- </Typography>
218
- <Typography level="body-sm" sx={{
219
- color: 'text.secondary'
220
- }}>
221
- Try "Select all" - it will only affect enabled options (Apple, Cherry, Elderberry)
222
- </Typography>
223
- </Stack>
224
- </Stack>
225
- ```
226
-
227
- ## Common Use Cases
228
-
229
- ### Filter Panel
230
-
231
- Use FilterableCheckboxGroup in a sidebar or panel to let users filter a data table or list by multiple criteria.
232
-
233
- ```tsx
234
- import { FilterableCheckboxGroup } from '@ceed/cds';
235
-
236
- function FilterPanel({ categories, onFilterChange }) {
237
- const [selected, setSelected] = useState<string[]>([]);
238
-
239
- const handleChange = (values: string[]) => {
240
- setSelected(values);
241
- onFilterChange(values);
242
- };
243
-
244
- return (
245
- <FilterableCheckboxGroup
246
- label="Categories"
247
- placeholder="Search categories..."
248
- options={categories}
249
- value={selected}
250
- onChange={handleChange}
251
- maxHeight={200}
252
- />
253
- );
254
- }
255
- ```
256
-
257
- ### User Role Assignment
258
-
259
- Assign multiple roles to a user from a searchable list.
260
-
261
- ```tsx
262
- <FilterableCheckboxGroup
263
- label="Assign Roles"
264
- placeholder="Search roles..."
265
- helperText="Select all roles that apply to this user"
266
- options={[
267
- { value: 'admin', label: 'Administrator' },
268
- { value: 'editor', label: 'Editor' },
269
- { value: 'viewer', label: 'Viewer' },
270
- { value: 'moderator', label: 'Moderator' },
271
- { value: 'billing', label: 'Billing Manager' },
272
- ]}
273
- required
274
- value={selectedRoles}
275
- onChange={setSelectedRoles}
276
- />
277
- ```
278
-
279
- ### Region / Country Selection
280
-
281
- When dealing with a large set of options like countries, the search filter and virtual scrolling work together for fast selection.
282
-
283
- ```tsx
284
- <FilterableCheckboxGroup
285
- label="Service Regions"
286
- placeholder="Search countries..."
287
- options={allCountries.map((c) => ({ value: c.code, label: c.name }))}
288
- value={selectedCountries}
289
- onChange={setSelectedCountries}
290
- />
291
- ```
292
-
293
- ## Best Practices
294
-
295
- 1. **Provide a meaningful placeholder.** The search input placeholder should hint at the type of content being filtered (e.g., "Search countries..." instead of a generic "Search...").
296
-
297
- ```tsx
298
- // ✅ Specific and helpful
299
- <FilterableCheckboxGroup placeholder="Search countries..." />
300
-
301
- // ❌ Too generic
302
- <FilterableCheckboxGroup placeholder="Type here..." />
303
- ```
304
-
305
- 2. **Use `maxHeight` to fit the layout.** In tight spaces like sidebars or modals, set a smaller `maxHeight` to prevent the component from dominating the layout.
306
-
307
- 3. **Prefer controlled mode for form integration.** Always pass `value` and `onChange` when the selected values participate in form submission or affect other UI state.
308
-
309
- 4. **Leverage individual `disabled` for permissions.** When some options should be visible but not selectable (e.g., due to user permissions), disable them individually rather than hiding them. This communicates availability without surprising users.
310
-
311
- 5. **Keep option labels concise.** Long labels will be truncated with an ellipsis. If detailed descriptions are needed, consider using a tooltip or a separate detail view.
312
-
313
- ## Accessibility
314
-
315
- - The search input is labeled by the component's `label` prop, ensuring screen readers announce its purpose.
316
- - Each checkbox option uses a native `<input type="checkbox">` with an associated `<label>`, enabling click-on-label and proper screen reader announcements.
317
- - The "Select all" toggle clearly communicates its tri-state behavior (all, none, indeterminate) to assistive technologies.
318
- - Keyboard navigation is fully supported: Tab to move between the search input and the checkbox list, Space to toggle individual checkboxes, and standard arrow keys to navigate within the list.
@@ -2,9 +2,7 @@
2
2
 
3
3
  ## Introduction
4
4
 
5
- IconButton is a compact, icon-only button component designed for actions where a visual symbol alone is sufficient to communicate meaning. It is ideal for toolbars, table row actions, card headers, navigation bars, and any context where space efficiency is critical.
6
-
7
- Because IconButton omits visible text, it relies entirely on the icon's clarity and supplementary accessibility attributes to convey its purpose. Always pair it with `aria-label` or a Tooltip to ensure all users can understand the button's function.
5
+ IconButton 컴포넌트는 아이콘만으로 구성된 버튼입니다. 공간 효율적이며, 직관적인 액션을 제공하는 UI 요소로 주로 툴바, 헤더, 카드 등에서 사용됩니다. 텍스트 없이도 의미를 전달할 있는 명확한 아이콘과 함께 사용하세요.
8
6
 
9
7
  ```tsx
10
8
  <IconButton {...args} />
@@ -24,26 +22,56 @@ Because IconButton omits visible text, it relies entirely on the icon's clarity
24
22
  ```tsx
25
23
  import { IconButton } from '@ceed/cds';
26
24
  import AddIcon from '@mui/icons-material/Add';
27
- import DeleteIcon from '@mui/icons-material/Delete';
28
25
 
29
26
  function MyComponent() {
30
27
  return (
31
- <div style={{ display: 'flex', gap: '0.5rem' }}>
32
- <IconButton aria-label="Add item" onClick={handleAdd}>
28
+ <div>
29
+ <IconButton onClick={() => console.log('clicked')}>
33
30
  <AddIcon />
34
31
  </IconButton>
35
32
 
36
- <IconButton color="danger" aria-label="Delete item" onClick={handleDelete}>
33
+ <IconButton color="danger" onClick={() => console.log('delete')}>
37
34
  <DeleteIcon />
38
35
  </IconButton>
36
+
37
+ <IconButton disabled>
38
+ <EditIcon />
39
+ </IconButton>
39
40
  </div>
40
41
  );
41
42
  }
42
43
  ```
43
44
 
44
- ## Colors
45
+ ## Examples
46
+
47
+ ### Basic Usage
48
+
49
+ 기본적인 IconButton 사용법입니다.
50
+
51
+ ```tsx
52
+ <div style={{
53
+ display: 'flex',
54
+ gap: '1rem',
55
+ alignItems: 'center'
56
+ }}>
57
+ <IconButton>
58
+ <Add />
59
+ </IconButton>
60
+ <IconButton>
61
+ <Edit />
62
+ </IconButton>
63
+ <IconButton>
64
+ <Delete />
65
+ </IconButton>
66
+ <IconButton>
67
+ <Settings />
68
+ </IconButton>
69
+ </div>
70
+ ```
71
+
72
+ ### Colors
45
73
 
46
- IconButton supports five semantic colors: `primary` (default), `neutral`, `danger`, `success`, and `warning`. Choose a color that reflects the nature of the action.
74
+ 다양한 색상을 적용할 있습니다.
47
75
 
48
76
  ```tsx
49
77
  <div style={{
@@ -69,9 +97,9 @@ IconButton supports five semantic colors: `primary` (default), `neutral`, `dange
69
97
  </div>
70
98
  ```
71
99
 
72
- ## Variants
100
+ ### Variants
73
101
 
74
- Four visual variants are available: `solid` (filled background), `soft` (tinted background), `outlined` (border only), and `plain` (no background). Use `outlined` or `plain` for secondary actions, and `solid` for primary or high-emphasis actions.
102
+ 다양한 스타일 변형을 제공합니다.
75
103
 
76
104
  ```tsx
77
105
  <div style={{
@@ -94,9 +122,9 @@ Four visual variants are available: `solid` (filled background), `soft` (tinted
94
122
  </div>
95
123
  ```
96
124
 
97
- ## Sizes
125
+ ### Sizes
98
126
 
99
- The `size` prop controls the button dimensions. Available sizes are `sm`, `md` (default), and `lg`. Ensure touch targets meet the minimum 44px recommended size for touch interfaces.
127
+ 크기를 조절할 있습니다.
100
128
 
101
129
  ```tsx
102
130
  <div style={{
@@ -116,9 +144,9 @@ The `size` prop controls the button dimensions. Available sizes are `sm`, `md` (
116
144
  </div>
117
145
  ```
118
146
 
119
- ## States
147
+ ### States
120
148
 
121
- IconButton supports multiple interactive states including normal, disabled, and loading. Use `disabled` to prevent interaction and `loading` to indicate an in-progress async operation.
149
+ 다양한 상태를 표현할 있습니다.
122
150
 
123
151
  ```tsx
124
152
  <div style={{
@@ -174,9 +202,9 @@ IconButton supports multiple interactive states including normal, disabled, and
174
202
  </div>
175
203
  ```
176
204
 
177
- ## With Badge
205
+ ### With Badge
178
206
 
179
- Combine IconButton with Badge to display notification counts, status indicators, or unread markers alongside the button.
207
+ Badge 함께 사용하여 알림 수나 상태를 표시할 있습니다.
180
208
 
181
209
  ```tsx
182
210
  <div style={{
@@ -202,9 +230,9 @@ Combine IconButton with Badge to display notification counts, status indicators,
202
230
  </div>
203
231
  ```
204
232
 
205
- ## With Tooltip
233
+ ### With Tooltip
206
234
 
207
- Wrap IconButton in a Tooltip to provide a text description on hover. This is especially important for icon-only buttons since the icon alone may not be self-explanatory for all users.
235
+ Tooltip 함께 사용하여 버튼의 기능을 설명할 있습니다.
208
236
 
209
237
  ```tsx
210
238
  <div style={{
@@ -235,40 +263,9 @@ Wrap IconButton in a Tooltip to provide a text description on hover. This is esp
235
263
  </div>
236
264
  ```
237
265
 
238
- ## Circular Variants
239
-
240
- IconButton renders as a circular shape by default, making it visually distinct from rectangular text buttons and well-suited for floating action buttons and compact action rows.
241
-
242
- ```tsx
243
- <div style={{
244
- display: 'flex',
245
- gap: '2rem',
246
- alignItems: 'center'
247
- }}>
248
- <div>
249
- <h4>Default</h4>
250
- <div style={{
251
- display: 'flex',
252
- gap: '1rem',
253
- alignItems: 'center'
254
- }}>
255
- <IconButton>
256
- <Add />
257
- </IconButton>
258
- <IconButton variant="outlined">
259
- <Edit />
260
- </IconButton>
261
- <IconButton variant="soft">
262
- <Delete />
263
- </IconButton>
264
- </div>
265
- </div>
266
- </div>
267
- ```
268
-
269
- ## Action Buttons
266
+ ### Action Buttons
270
267
 
271
- A practical example of IconButton used for common CRUD operations with distinct colors signaling the nature of each action.
268
+ 실제 액션을 수행하는 버튼들의 예제입니다.
272
269
 
273
270
  ```tsx
274
271
  <div style={{
@@ -296,115 +293,69 @@ A practical example of IconButton used for common CRUD operations with distinct
296
293
 
297
294
  ## Common Use Cases
298
295
 
299
- ### Table Row Actions
300
-
301
- ```tsx
302
- import { IconButton, Tooltip } from '@ceed/cds';
303
- import EditIcon from '@mui/icons-material/Edit';
304
- import DeleteIcon from '@mui/icons-material/Delete';
305
- import VisibilityIcon from '@mui/icons-material/Visibility';
306
-
307
- function RowActions({ onView, onEdit, onDelete }) {
308
- return (
309
- <div style={{ display: 'flex', gap: '0.25rem' }}>
310
- <Tooltip title="View details">
311
- <IconButton size="sm" variant="plain" color="neutral" onClick={onView}>
312
- <VisibilityIcon />
313
- </IconButton>
314
- </Tooltip>
315
- <Tooltip title="Edit">
316
- <IconButton size="sm" variant="plain" color="neutral" onClick={onEdit}>
317
- <EditIcon />
318
- </IconButton>
319
- </Tooltip>
320
- <Tooltip title="Delete">
321
- <IconButton size="sm" variant="plain" color="danger" onClick={onDelete}>
322
- <DeleteIcon />
323
- </IconButton>
324
- </Tooltip>
325
- </div>
326
- );
327
- }
328
- ```
329
-
330
- ### Dialog Close Button
296
+ ### Toolbar Actions
331
297
 
332
298
  ```tsx
333
- import CloseIcon from '@mui/icons-material/Close';
334
-
335
- <IconButton
336
- variant="plain"
337
- color="neutral"
338
- size="sm"
339
- aria-label="Close dialog"
340
- onClick={onClose}
341
- sx={{ position: 'absolute', top: 8, right: 8 }}
342
- >
343
- <CloseIcon />
344
- </IconButton>
299
+ <div style={{ display: 'flex', gap: '0.5rem' }}>
300
+ <IconButton onClick={handleAdd} title="Add item">
301
+ <AddIcon />
302
+ </IconButton>
303
+ <IconButton onClick={handleEdit} color="neutral" title="Edit">
304
+ <EditIcon />
305
+ </IconButton>
306
+ <IconButton onClick={handleDelete} color="danger" title="Delete">
307
+ <DeleteIcon />
308
+ </IconButton>
309
+ </div>
345
310
  ```
346
311
 
347
- ### Navigation Back Button
312
+ ### Navigation
348
313
 
349
314
  ```tsx
350
- import ArrowBackIcon from '@mui/icons-material/ArrowBack';
351
-
352
- <IconButton
353
- variant="outlined"
354
- color="neutral"
355
- aria-label="Go back"
356
- onClick={() => router.back()}
357
- >
315
+ <IconButton onClick={() => router.back()} variant="outlined">
358
316
  <ArrowBackIcon />
359
317
  </IconButton>
360
318
  ```
361
319
 
362
- ## Best Practices
363
-
364
- 1. **Always provide an accessible label.** Since there is no visible text, use `aria-label` or wrap with a Tooltip to describe the action.
320
+ ### Settings & More Options
365
321
 
366
322
  ```tsx
367
- // Accessible icon button
368
- <IconButton aria-label="Delete item" color="danger">
369
- <DeleteIcon />
323
+ <IconButton onClick={handleSettings} color="neutral">
324
+ <SettingsIcon />
370
325
  </IconButton>
371
-
372
- // ❌ No accessible label
373
- <IconButton color="danger">
374
- <DeleteIcon />
326
+ <IconButton onClick={handleMoreOptions}>
327
+ <MoreVertIcon />
375
328
  </IconButton>
376
329
  ```
377
330
 
378
- 2. **Use semantic colors to convey intent.** Match the color to the action's nature: `danger` for destructive actions, `success` for confirmations, `neutral` for general-purpose actions.
331
+ ### Social Actions
379
332
 
380
333
  ```tsx
381
- // Color matches the action
382
- <IconButton color="danger" aria-label="Delete">
383
- <DeleteIcon />
334
+ <IconButton onClick={handleLike} color="danger">
335
+ <FavoriteIcon />
384
336
  </IconButton>
385
-
386
- // ❌ Misleading color
387
- <IconButton color="success" aria-label="Delete">
388
- <DeleteIcon />
337
+ <IconButton onClick={handleShare} color="primary">
338
+ <ShareIcon />
389
339
  </IconButton>
390
340
  ```
391
341
 
392
- 3. **Use the `loading` prop for async operations.** This prevents double-clicks and provides visual feedback during network requests or processing.
342
+ ## Best Practices
393
343
 
394
- ```tsx
395
- // ✅ Shows loading spinner during async action
396
- <IconButton loading={isSaving} aria-label="Save" onClick={handleSave}>
397
- <SaveIcon />
398
- </IconButton>
399
- ```
344
+ 1. **명확한 아이콘**: 사용자가 쉽게 이해할 수 있는 명확하고 직관적인 아이콘을 사용하세요.
345
+
346
+ 2. **적절한 크기**: 터치 인터페이스를 고려하여 최소 44px 이상의 터치 영역을 확보하세요.
347
+
348
+ 3. **접근성**:
349
+ - `title` 속성이나 `aria-label`을 제공하여 스크린 리더 사용자를 위한 설명을 추가하세요.
350
+ - Tooltip과 함께 사용하여 기능을 명확히 설명하세요.
400
351
 
401
- 4. **Prefer universally recognized icons.** Choose icons that are widely understood (e.g., trash can for delete, pencil for edit, plus for add). Avoid ambiguous symbols without a Tooltip.
352
+ 4. **일관된 스타일**: 같은 맥락에서는 일관된 variant와 색상을 사용하세요.
402
353
 
403
- 5. **Maintain consistent sizing within the same context.** Use the same `size` and `variant` for all IconButtons in a toolbar or action group to keep the interface clean and predictable.
354
+ 5. **의미 있는 색상**:
355
+ - 빨간색(danger): 삭제, 취소 등의 위험한 액션
356
+ - 초록색(success): 저장, 승인 등의 긍정적인 액션
357
+ - 회색(neutral): 일반적인 액션
404
358
 
405
- ## Accessibility
359
+ 6. **피드백 제공**: 클릭 시 명확한 피드백을 제공하여 사용자가 액션이 실행되었음을 알 수 있도록 하세요.
406
360
 
407
- - **`aria-label` is essential**: Every IconButton must have either an `aria-label`, `aria-labelledby`, or a wrapping Tooltip with `title` to provide a text alternative for screen readers.
408
- - **Keyboard interaction**: IconButton is focusable via `Tab` and can be activated with `Enter` or `Space`. Focus indicators are displayed by default.
409
- - **Disabled state**: When `disabled` is set, the button receives `aria-disabled="true"` and becomes non-interactive. It remains visible in the DOM for screen readers to announce.
410
- - **Touch targets**: Ensure the rendered button is at least 44x44 pixels for touch accessibility. The `sm` size may need additional padding in touch-heavy interfaces.
361
+ 7. **로딩 상태**: 비동기 작업 `loading` prop을 사용하여 사용자에게 진행 상황을 알려주세요.