@ceed/ads 1.23.3 → 1.23.4

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 (43) hide show
  1. package/dist/components/data-display/Badge.md +71 -39
  2. package/dist/components/data-display/InfoSign.md +74 -98
  3. package/dist/components/data-display/Typography.md +310 -61
  4. package/dist/components/feedback/CircularProgress.md +257 -0
  5. package/dist/components/feedback/Skeleton.md +280 -0
  6. package/dist/components/feedback/llms.txt +2 -0
  7. package/dist/components/inputs/ButtonGroup.md +115 -106
  8. package/dist/components/inputs/Calendar.md +98 -459
  9. package/dist/components/inputs/CurrencyInput.md +181 -8
  10. package/dist/components/inputs/DatePicker.md +108 -436
  11. package/dist/components/inputs/DateRangePicker.md +130 -496
  12. package/dist/components/inputs/FilterMenu.md +169 -19
  13. package/dist/components/inputs/FilterableCheckboxGroup.md +119 -24
  14. package/dist/components/inputs/FormControl.md +368 -0
  15. package/dist/components/inputs/IconButton.md +137 -88
  16. package/dist/components/inputs/MonthPicker.md +95 -427
  17. package/dist/components/inputs/MonthRangePicker.md +89 -471
  18. package/dist/components/inputs/PercentageInput.md +183 -19
  19. package/dist/components/inputs/RadioButton.md +163 -35
  20. package/dist/components/inputs/RadioList.md +241 -0
  21. package/dist/components/inputs/RadioTileGroup.md +146 -62
  22. package/dist/components/inputs/Select.md +219 -328
  23. package/dist/components/inputs/Slider.md +334 -0
  24. package/dist/components/inputs/Switch.md +136 -376
  25. package/dist/components/inputs/Textarea.md +209 -11
  26. package/dist/components/inputs/Uploader/Uploader.md +145 -66
  27. package/dist/components/inputs/llms.txt +3 -0
  28. package/dist/components/navigation/Breadcrumbs.md +80 -322
  29. package/dist/components/navigation/Dropdown.md +92 -221
  30. package/dist/components/navigation/IconMenuButton.md +40 -502
  31. package/dist/components/navigation/InsetDrawer.md +68 -738
  32. package/dist/components/navigation/Link.md +39 -298
  33. package/dist/components/navigation/Menu.md +92 -285
  34. package/dist/components/navigation/MenuButton.md +55 -448
  35. package/dist/components/navigation/Pagination.md +47 -338
  36. package/dist/components/navigation/ProfileMenu.md +45 -268
  37. package/dist/components/navigation/Stepper.md +160 -28
  38. package/dist/components/navigation/Tabs.md +57 -316
  39. package/dist/components/surfaces/Sheet.md +150 -333
  40. package/dist/guides/ThemeProvider.md +116 -0
  41. package/dist/guides/llms.txt +9 -0
  42. package/dist/llms.txt +8 -0
  43. package/package.json +1 -1
@@ -2,7 +2,9 @@
2
2
 
3
3
  ## Introduction
4
4
 
5
- Switch 컴포넌트는 사용자가 옵션을 켜고 있는 토글 형태의 입력 요소입니다. Joy UI Switch 기반으로 하며, 다양한 크기, 색상, 장식 요소를 지원합니다. 설정 화면, 기능 활성화/비활성화, 모드 전환 등에 주로 사용됩니다.
5
+ The Switch component is a toggle input that lets users turn an option on or off. It is built on Joy UI's Switch and provides a variety of sizes, colors, variants, and decorator slots for icons or text.
6
+
7
+ Switches are best suited for binary settings that take effect immediately, such as enabling notifications, toggling dark mode, or activating a feature. Unlike a checkbox (which is often part of a form submission), a switch communicates an instant state change.
6
8
 
7
9
  ```tsx
8
10
  <Switch />
@@ -34,19 +36,9 @@ function MyComponent() {
34
36
  }
35
37
  ```
36
38
 
37
- ## Examples
38
-
39
- ### Basic Usage
40
-
41
- 가장 기본적인 Switch 사용법입니다.
42
-
43
- ```tsx
44
- <Switch />
45
- ```
46
-
47
- ### With Labels
39
+ ## With Labels
48
40
 
49
- 라벨과 함께 사용하는 Switch입니다. 컨트롤 내에서 설명과 함께 사용할 있습니다.
41
+ Use `FormControl` with `FormLabel` and `FormHelperText` to provide a label and description alongside the switch. The `orientation="horizontal"` layout places the label on the left and the switch on the right.
50
42
 
51
43
  ```tsx
52
44
  <FormControl orientation="horizontal" sx={{
@@ -69,9 +61,9 @@ function MyComponent() {
69
61
  </FormControl>
70
62
  ```
71
63
 
72
- ### Inline Labels
64
+ ## Inline Labels
73
65
 
74
- 인라인 형태로 텍스트와 함께 사용할 있습니다.
66
+ For simpler cases, wrap the switch inside a `Typography` component rendered as a `<label>`. This connects the text and switch semantically without requiring a `FormControl`.
75
67
 
76
68
  ```tsx
77
69
  <Typography component="label" endDecorator={<Switch sx={{
@@ -81,9 +73,9 @@ Turn alarm on
81
73
  </Typography>
82
74
  ```
83
75
 
84
- ### With Decorators
76
+ ## With Decorators
85
77
 
86
- 아이콘이나 다른 요소를 장식으로 추가할 있습니다.
78
+ Use `startDecorator` and `endDecorator` to place icons or text around the switch. This is particularly useful for theme toggles or any context where visual cues reinforce the on/off meaning.
87
79
 
88
80
  ```tsx
89
81
  <Switch color={dark ? 'primary' : 'danger'} slotProps={{
@@ -97,9 +89,9 @@ Turn alarm on
97
89
  })} />} checked={dark} onChange={event => setDark(event.target.checked)} />
98
90
  ```
99
91
 
100
- ### Track Children
92
+ ## Track Children
101
93
 
102
- 트랙 내부에 텍스트나 다른 요소를 표시할 있습니다.
94
+ Display text or symbols inside the switch track using `slotProps.track.children`. This provides an always-visible label (e.g., "On" / "Off" or "I" / "0") directly on the track.
103
95
 
104
96
  ```tsx
105
97
  <Stack direction="row" spacing={4}>
@@ -141,9 +133,9 @@ Turn alarm on
141
133
  </Stack>
142
134
  ```
143
135
 
144
- ### Thumb Children
136
+ ## Thumb Children
145
137
 
146
- 썸(토글 버튼) 내부에 아이콘을 표시할 있습니다.
138
+ Place an icon inside the switch thumb using `slotProps.thumb.children`. This is useful for adding a small visual indicator that moves with the toggle.
147
139
 
148
140
  ```tsx
149
141
  <Switch size="lg" slotProps={{
@@ -158,47 +150,96 @@ Turn alarm on
158
150
  }} />
159
151
  ```
160
152
 
153
+ ## All Variants Overview
154
+
155
+ A comprehensive view of all color and decoration combinations.
156
+
157
+ ```tsx
158
+ <Stack direction="row" spacing={4}>
159
+ {([undefined, 'primary', 'warning', 'success', 'danger', 'neutral'] as const).map(color => <Stack key={color} spacing={2}>
160
+ <Switch color={color} />
161
+ <Switch color={color} checked />
162
+ <Switch color={color} startDecorator={<LightModeIcon />} endDecorator={<DarkModeIcon />} />
163
+ <Switch color={color} slotProps={{
164
+ input: {
165
+ 'aria-label': 'Dark mode'
166
+ },
167
+ thumb: {
168
+ children: <DarkModeIcon fontSize="inherit" />
169
+ },
170
+ track: {
171
+ children: <React.Fragment>
172
+ <span>I</span>
173
+ <span>0</span>
174
+ </React.Fragment>,
175
+ sx: {
176
+ justifyContent: 'space-around'
177
+ }
178
+ }
179
+ }} sx={{
180
+ '--Switch-thumbSize': '27px',
181
+ '--Switch-trackWidth': '52px',
182
+ '--Switch-trackHeight': '31px'
183
+ }} />
184
+ <Typography component="label" startDecorator={<Switch sx={{
185
+ ml: 1
186
+ }} color={color} />}>
187
+ Label
188
+ </Typography>
189
+ </Stack>)}
190
+ </Stack>
191
+ ```
192
+
161
193
  ## Common Use Cases
162
194
 
163
195
  ### Settings Panel
164
196
 
165
- 설정 패널에서 기능을 활성화/비활성화할 때 사용합니다.
166
-
167
197
  ```tsx
168
- <Stack spacing={3}>
169
- <FormControl orientation="horizontal" sx={{ width: 400, justifyContent: 'space-between' }}>
170
- <div>
171
- <FormLabel>알림 받기</FormLabel>
172
- <FormHelperText sx={{ mt: 0 }}>
173
- 새로운 메시지가 도착했을 때 알림을 받습니다.
174
- </FormHelperText>
175
- </div>
176
- <Switch
177
- checked={notifications}
178
- onChange={(e) => setNotifications(e.target.checked)}
179
- color="success"
180
- />
181
- </FormControl>
182
-
183
- <FormControl orientation="horizontal" sx={{ width: 400, justifyContent: 'space-between' }}>
184
- <div>
185
- <FormLabel>자동 저장</FormLabel>
186
- <FormHelperText sx={{ mt: 0 }}>
187
- 작업 내용을 자동으로 저장합니다.
188
- </FormHelperText>
189
- </div>
190
- <Switch
191
- checked={autoSave}
192
- onChange={(e) => setAutoSave(e.target.checked)}
193
- />
194
- </FormControl>
195
- </Stack>
198
+ function SettingsPanel() {
199
+ const [notifications, setNotifications] = useState(true);
200
+ const [autoSave, setAutoSave] = useState(false);
201
+
202
+ return (
203
+ <Stack spacing={3}>
204
+ <FormControl
205
+ orientation="horizontal"
206
+ sx={{ width: 400, justifyContent: 'space-between' }}
207
+ >
208
+ <div>
209
+ <FormLabel>Notifications</FormLabel>
210
+ <FormHelperText sx={{ mt: 0 }}>
211
+ Receive alerts when new messages arrive.
212
+ </FormHelperText>
213
+ </div>
214
+ <Switch
215
+ checked={notifications}
216
+ onChange={(e) => setNotifications(e.target.checked)}
217
+ color={notifications ? 'success' : 'neutral'}
218
+ />
219
+ </FormControl>
220
+
221
+ <FormControl
222
+ orientation="horizontal"
223
+ sx={{ width: 400, justifyContent: 'space-between' }}
224
+ >
225
+ <div>
226
+ <FormLabel>Auto Save</FormLabel>
227
+ <FormHelperText sx={{ mt: 0 }}>
228
+ Automatically save your work every 30 seconds.
229
+ </FormHelperText>
230
+ </div>
231
+ <Switch
232
+ checked={autoSave}
233
+ onChange={(e) => setAutoSave(e.target.checked)}
234
+ />
235
+ </FormControl>
236
+ </Stack>
237
+ );
238
+ }
196
239
  ```
197
240
 
198
241
  ### Theme Toggle
199
242
 
200
- 다크 모드/라이트 모드 전환에 자주 사용됩니다.
201
-
202
243
  ```tsx
203
244
  function ThemeToggle() {
204
245
  const [darkMode, setDarkMode] = useState(false);
@@ -211,367 +252,86 @@ function ThemeToggle() {
211
252
  startDecorator={<LightModeIcon />}
212
253
  endDecorator={<DarkModeIcon />}
213
254
  slotProps={{
214
- input: { 'aria-label': '다크 모드 토글' },
255
+ input: { 'aria-label': 'Toggle dark mode' },
215
256
  }}
216
257
  />
217
258
  );
218
259
  }
219
260
  ```
220
261
 
221
- ### Feature Flags
222
-
223
- 기능의 활성화/비활성화를 제어할 때 사용합니다.
262
+ ### Feature Flag with Status Text
224
263
 
225
264
  ```tsx
226
- <Card>
227
- <CardContent>
228
- <Typography level="title-md" sx={{ mb: 2 }}>
229
- 실험적 기능
230
- </Typography>
231
-
232
- <Stack spacing={2}>
233
- <FormControl orientation="horizontal" sx={{ justifyContent: 'space-between' }}>
234
- <FormLabel>베타 기능 활성화</FormLabel>
235
- <Switch
236
- checked={betaFeatures}
237
- onChange={(e) => setBetaFeatures(e.target.checked)}
238
- color="warning"
239
- endDecorator={betaFeatures ? 'On' : 'Off'}
240
- />
241
- </FormControl>
242
-
243
- <FormControl orientation="horizontal" sx={{ justifyContent: 'space-between' }}>
244
- <FormLabel>고급 모드</FormLabel>
245
- <Switch
246
- checked={advancedMode}
247
- onChange={(e) => setAdvancedMode(e.target.checked)}
248
- disabled={!betaFeatures}
249
- />
250
- </FormControl>
251
- </Stack>
252
- </CardContent>
253
- </Card>
254
- ```
255
-
256
- ### List Items with Switches
257
-
258
- 목록 아이템에서 각 항목을 개별적으로 제어할 때 사용합니다.
265
+ function FeatureToggle() {
266
+ const [betaEnabled, setBetaEnabled] = useState(false);
259
267
 
260
- ```tsx
261
- <List>
262
- {permissions.map((permission) => (
263
- <ListItem key={permission.id} endAction={
268
+ return (
269
+ <FormControl
270
+ orientation="horizontal"
271
+ sx={{ justifyContent: 'space-between' }}
272
+ >
273
+ <FormLabel>Enable Beta Features</FormLabel>
264
274
  <Switch
265
- checked={permission.enabled}
266
- onChange={(e) => handlePermissionToggle(permission.id, e.target.checked)}
267
- size="sm"
268
- color={permission.enabled ? 'success' : 'neutral'}
275
+ checked={betaEnabled}
276
+ onChange={(e) => setBetaEnabled(e.target.checked)}
277
+ color="warning"
278
+ endDecorator={betaEnabled ? 'On' : 'Off'}
269
279
  />
270
- }>
271
- <ListItemContent>
272
- <Typography level="title-sm">{permission.name}</Typography>
273
- <Typography level="body-sm" color="neutral">
274
- {permission.description}
275
- </Typography>
276
- </ListItemContent>
277
- </ListItem>
278
- ))}
279
- </List>
280
- ```
281
-
282
- ### Controlled Form
283
-
284
- 폼 상태 관리와 함께 사용하는 예제입니다.
285
-
286
- ```tsx
287
- function UserPreferences() {
288
- const [preferences, setPreferences] = useState({
289
- emailNotifications: true,
290
- smsNotifications: false,
291
- pushNotifications: true,
292
- darkMode: false,
293
- });
294
-
295
- const handleToggle = (key: keyof typeof preferences) => (
296
- event: React.ChangeEvent<HTMLInputElement>
297
- ) => {
298
- setPreferences(prev => ({
299
- ...prev,
300
- [key]: event.target.checked
301
- }));
302
- };
303
-
304
- return (
305
- <form onSubmit={handleSubmit}>
306
- <Stack spacing={3}>
307
- <Typography level="h4">알림 설정</Typography>
308
-
309
- <Stack spacing={2}>
310
- <Typography component="label" endDecorator={
311
- <Switch
312
- checked={preferences.emailNotifications}
313
- onChange={handleToggle('emailNotifications')}
314
- sx={{ ml: 1 }}
315
- />
316
- }>
317
- 이메일 알림
318
- </Typography>
319
-
320
- <Typography component="label" endDecorator={
321
- <Switch
322
- checked={preferences.smsNotifications}
323
- onChange={handleToggle('smsNotifications')}
324
- sx={{ ml: 1 }}
325
- />
326
- }>
327
- SMS 알림
328
- </Typography>
329
-
330
- <Typography component="label" endDecorator={
331
- <Switch
332
- checked={preferences.pushNotifications}
333
- onChange={handleToggle('pushNotifications')}
334
- sx={{ ml: 1 }}
335
- />
336
- }>
337
- 푸시 알림
338
- </Typography>
339
- </Stack>
340
-
341
- <Divider />
342
-
343
- <Typography component="label" endDecorator={
344
- <Switch
345
- checked={preferences.darkMode}
346
- onChange={handleToggle('darkMode')}
347
- startDecorator={<LightModeIcon />}
348
- endDecorator={<DarkModeIcon />}
349
- sx={{ ml: 1 }}
350
- />
351
- }>
352
- 다크 모드
353
- </Typography>
354
-
355
- <Button type="submit">설정 저장</Button>
356
- </Stack>
357
- </form>
280
+ </FormControl>
358
281
  );
359
282
  }
360
283
  ```
361
284
 
362
- ## Props and Customization
363
-
364
- ### Colors
365
-
366
- 다양한 색상을 적용할 수 있습니다.
367
-
368
- ```tsx
369
- <Stack direction="row" spacing={2}>
370
- <Switch color="primary" checked />
371
- <Switch color="success" checked />
372
- <Switch color="warning" checked />
373
- <Switch color="danger" checked />
374
- <Switch color="neutral" checked />
375
- </Stack>
376
- ```
377
-
378
- ### Sizes
379
-
380
- 스위치의 크기를 조절할 수 있습니다.
381
-
382
- ```tsx
383
- <Stack direction="row" spacing={2} alignItems="center">
384
- <Switch size="sm" checked />
385
- <Switch size="md" checked />
386
- <Switch size="lg" checked />
387
- </Stack>
388
- ```
389
-
390
- ### Variants
391
-
392
- 다양한 시각적 스타일을 적용할 수 있습니다.
393
-
394
- ```tsx
395
- <Stack direction="row" spacing={2}>
396
- <Switch variant="solid" checked />
397
- <Switch variant="soft" checked />
398
- <Switch variant="outlined" checked />
399
- <Switch variant="plain" checked />
400
- </Stack>
401
- ```
402
-
403
- ### Custom Styling
285
+ ## Best Practices
404
286
 
405
- CSS 변수를 통해 세밀한 커스터마이징이 가능합니다.
287
+ 1. **Use switches for immediate effects**: Switches should apply their change instantly without requiring a "Save" button. If the setting requires a form submission, use a checkbox instead.
406
288
 
407
289
  ```tsx
290
+ // ✅ Immediate effect -- toggling notifications on/off
408
291
  <Switch
409
- checked={customSwitch}
410
- onChange={(e) => setCustomSwitch(e.target.checked)}
411
- sx={{
412
- '--Switch-thumbSize': '24px',
413
- '--Switch-trackWidth': '60px',
414
- '--Switch-trackHeight': '32px',
415
- '--Switch-trackRadius': '16px',
416
- '--Switch-thumbRadius': '12px',
417
- }}
292
+ checked={notificationsEnabled}
293
+ onChange={(e) => toggleNotifications(e.target.checked)}
418
294
  />
419
- ```
420
-
421
- ## States
422
-
423
- ### Disabled State
424
295
 
425
- 비활성 상태의 스위치입니다.
426
-
427
- ```tsx
428
- <Stack direction="row" spacing={2}>
429
- <Switch disabled />
430
- <Switch disabled checked />
431
- </Stack>
296
+ // Deferred effect requiring form submission -- use Checkbox instead
297
+ <form onSubmit={handleSubmit}>
298
+ <Switch checked={agreed} onChange={(e) => setAgreed(e.target.checked)} />
299
+ <Button type="submit">Save</Button>
300
+ </form>
432
301
  ```
433
302
 
434
- ### Loading/Processing State
435
-
436
- 처리 중일 때의 시각적 피드백을 제공할 수 있습니다.
303
+ 2. **Always provide a label**: Every switch needs a visible text label or an `aria-label` so users understand what it controls.
437
304
 
438
305
  ```tsx
439
- function ProcessingSwitch() {
440
- const [processing, setProcessing] = useState(false);
441
- const [enabled, setEnabled] = useState(false);
442
-
443
- const handleToggle = async (event: React.ChangeEvent<HTMLInputElement>) => {
444
- setProcessing(true);
445
- try {
446
- // API 호출 시뮬레이션
447
- await new Promise(resolve => setTimeout(resolve, 1000));
448
- setEnabled(event.target.checked);
449
- } finally {
450
- setProcessing(false);
451
- }
452
- };
453
-
454
- return (
455
- <Switch
456
- checked={enabled}
457
- onChange={handleToggle}
458
- disabled={processing}
459
- endDecorator={processing ? 'Processing...' : (enabled ? 'On' : 'Off')}
460
- />
461
- );
462
- }
463
- ```
464
-
465
- ## Best Practices
466
-
467
- 1. **명확한 라벨**: 스위치가 무엇을 제어하는지 명확하게 표시하세요.
468
-
469
- ```tsx
470
- // ✅ 명확한 라벨
471
- <Typography component="label" endDecorator={<Switch />}>
472
- 이메일 알림 받기
473
- </Typography>
306
+ // Clear label via FormControl
307
+ <FormControl orientation="horizontal">
308
+ <FormLabel>Email Notifications</FormLabel>
309
+ <Switch checked={enabled} onChange={handleChange} />
310
+ </FormControl>
474
311
 
475
- // ❌ 모호한 라벨
476
- <Typography component="label" endDecorator={<Switch />}>
477
- 설정
478
- </Typography>
312
+ // ❌ No label -- unclear what the switch does
313
+ <Switch checked={enabled} onChange={handleChange} />
479
314
  ```
480
315
 
481
- 2. **즉시 효과**: 스위치 토글은 즉시 효과가 나타나야 합니다.
482
-
483
- 3. **적절한 색상 사용**:
484
- - 일반적인 기능: `primary` 또는 기본 색상
485
- - 성공/활성화: `success`
486
- - 주의사항: `warning`
487
- - 위험한 기능: `danger`
488
-
489
- 4. **상태 표시**: 현재 상태를 명확히 보여주는 장식 요소를 활용하세요.
316
+ 3. **Use semantic colors to reinforce meaning**: Apply `color="success"` for active/enabled states and `color="danger"` for risky toggles. Avoid using color as the sole indicator -- pair it with text.
490
317
 
491
318
  ```tsx
319
+ // ✅ Color + text indicator
492
320
  <Switch
493
321
  checked={enabled}
494
322
  onChange={handleChange}
495
- endDecorator={enabled ? '켜짐' : '꺼짐'}
496
323
  color={enabled ? 'success' : 'neutral'}
324
+ endDecorator={enabled ? 'On' : 'Off'}
497
325
  />
498
326
  ```
499
327
 
500
- 5. **그룹화**: 관련된 스위치들은 논리적으로 그룹화하세요.
328
+ 4. **Handle async operations gracefully**: If toggling triggers an API call, disable the switch and show a processing indicator until the operation completes.
501
329
 
502
- ```tsx
503
- <Stack spacing={3}>
504
- <Typography level="title-md">알림 설정</Typography>
505
- <Stack spacing={1} sx={{ pl: 1 }}>
506
- <Switch label="이메일 알림" />
507
- <Switch label="SMS 알림" />
508
- <Switch label="푸시 알림" />
509
- </Stack>
510
- </Stack>
511
- ```
330
+ 5. **Group related switches logically**: Place related switches under a shared heading and use consistent spacing to create a scannable settings layout.
512
331
 
513
332
  ## Accessibility
514
333
 
515
- Switch 컴포넌트는 다음과 같은 접근성 기능을 제공합니다:
516
-
517
- ### 키보드 탐색
518
-
519
- - **Tab**: 스위치로 포커스 이동
520
- - **Space**: 스위치 토글
521
- - **Enter**: 스위치 토글 (라벨이 연결된 경우)
522
-
523
- ### ARIA 속성
524
-
525
- - `role="switch"`: 스위치 역할 정의
526
- - `aria-checked`: 현재 상태 표시
527
- - `aria-label` 또는 `aria-labelledby`: 접근 가능한 이름 제공
528
-
529
- ### 추가 접근성 고려사항
530
-
531
- ```tsx
532
- <Switch
533
- slotProps={{
534
- input: {
535
- 'aria-label': '다크 모드 활성화',
536
- 'aria-describedby': 'dark-mode-description',
537
- },
538
- }}
539
- />
540
- <FormHelperText id="dark-mode-description">
541
- 화면을 어둡게 표시하여 눈의 피로를 줄입니다.
542
- </FormHelperText>
543
- ```
544
-
545
- ### 색상 대비 및 시각적 표시
546
-
547
- ```tsx
548
- // 색상에만 의존하지 않고 텍스트 표시도 함께 제공
549
- <Switch
550
- checked={enabled}
551
- onChange={handleChange}
552
- endDecorator={
553
- <Typography level="body-xs" sx={{ minWidth: 32 }}>
554
- {enabled ? 'ON' : 'OFF'}
555
- </Typography>
556
- }
557
- />
558
- ```
559
-
560
- ## Performance Considerations
561
-
562
- 1. **상태 최적화**: 불필요한 리렌더링을 방지하기 위해 상태를 적절히 관리하세요.
563
-
564
- ```tsx
565
- // ✅ 개별 상태 관리
566
- const [emailNotify, setEmailNotify] = useState(false);
567
- const [smsNotify, setSmsNotify] = useState(false);
568
-
569
- // ❌ 전체 객체 업데이트로 인한 불필요한 리렌더링
570
- const [settings, setSettings] = useState({ email: false, sms: false });
571
- ```
572
-
573
- 2. **비동기 처리**: API 호출이 필요한 경우 적절한 로딩 상태를 제공하세요.
574
-
575
- 3. **메모이제이션**: 복잡한 핸들러는 useCallback으로 메모이제이션하세요.
576
-
577
- Switch는 직관적이고 접근 가능한 토글 인터페이스를 제공하는 핵심 입력 컴포넌트입니다. 적절한 라벨링과 시각적 피드백을 통해 사용자 친화적인 설정 및 제어 인터페이스를 만들 수 있습니다.
334
+ - **Role and state**: The Switch renders an `<input type="checkbox" role="switch">` with `aria-checked` reflecting the current state. Screen readers announce it as a switch, not a checkbox.
335
+ - **Keyboard interaction**: `Tab` moves focus to the switch. `Space` toggles the state. No additional key bindings are needed.
336
+ - **Labeling**: Use `FormLabel`, a `<label>` wrapper (via `Typography component="label"`), or `slotProps.input['aria-label']` to provide an accessible name. Use `aria-describedby` to connect supplementary descriptions.
337
+ - **Visual indicators beyond color**: Do not rely solely on color to communicate state. Use `endDecorator` text (e.g., "On" / "Off") or track children to ensure the state is perceivable without color vision.