@ceed/ads 1.23.3 → 1.23.5

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 +361 -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
@@ -1,8 +1,8 @@
1
1
  # Dropdown
2
2
 
3
- ## Introduction
3
+ Dropdown is the stateful container that orchestrates the open/close behavior of a menu system. It acts as the invisible glue between a trigger element (such as MenuButton or IconMenuButton) and the Menu that appears when activated. Dropdown itself renders no visible UI -- it provides context so that its children can coordinate with each other.
4
4
 
5
- Dropdown 컴포넌트는 메뉴나 옵션 목록을 표시하는 컨테이너 역할을 하는 컴포넌트입니다. Joy UI의 Dropdown을 그대로 사용하며, MenuButton Menu 컴포넌트와 함께 사용하여 사용자가 클릭할 선택 가능한 옵션들을 보여줍니다. 네비게이션 메뉴, 필터 옵션, 사용자 프로필 메뉴 다양한 용도로 활용할 있습니다.
5
+ Dropdown is part of a **composition pattern** together with Menu, MenuItem, MenuButton, and IconMenuButton. While MenuButton and IconMenuButton are higher-level convenience components that bundle trigger + menu into a single prop-driven API, Dropdown gives you full control over the trigger element, menu content, and layout when you need custom compositions.
6
6
 
7
7
  ```tsx
8
8
  <Dropdown>
@@ -24,27 +24,39 @@ Dropdown 컴포넌트는 메뉴나 옵션 목록을 표시하는 컨테이너
24
24
  ## Usage
25
25
 
26
26
  ```tsx
27
- import { Dropdown, MenuButton, Menu, MenuItem } from '@ceed/ads';
27
+ import { Dropdown, Menu, MenuItem } from '@ceed/ads';
28
+ import { MenuButton } from '@ceed/ads';
28
29
 
29
30
  function MyComponent() {
30
31
  return (
31
32
  <Dropdown>
32
- <MenuButton>메뉴 열기</MenuButton>
33
+ <MenuButton>Open Menu</MenuButton>
33
34
  <Menu>
34
- <MenuItem>옵션 1</MenuItem>
35
- <MenuItem>옵션 2</MenuItem>
36
- <MenuItem>옵션 3</MenuItem>
35
+ <MenuItem>Option 1</MenuItem>
36
+ <MenuItem>Option 2</MenuItem>
37
+ <MenuItem>Option 3</MenuItem>
37
38
  </Menu>
38
39
  </Dropdown>
39
40
  );
40
41
  }
41
42
  ```
42
43
 
43
- ## Examples
44
+ ## Composition Pattern
45
+
46
+ Dropdown, Menu, MenuItem, MenuButton, and IconMenuButton form a **menu component family**. Choose the right level of abstraction for your use case:
47
+
48
+ | Approach | When to use |
49
+ | ------------------------------------ | ------------------------------------------------------- |
50
+ | `MenuButton` (standalone) | Simple text-triggered menus with a list of items |
51
+ | `IconMenuButton` (standalone) | Icon-only triggers in space-constrained areas |
52
+ | `Dropdown` + `MenuButton` + `Menu` | Custom menu content (headers, dividers, mixed elements) |
53
+ | `Dropdown` + custom trigger + `Menu` | Fully custom trigger elements |
54
+
55
+ ## Features
44
56
 
45
57
  ### Basic Dropdown
46
58
 
47
- 가장 기본적인 Dropdown 사용법입니다.
59
+ The simplest Dropdown pairs a MenuButton trigger with a Menu of items.
48
60
 
49
61
  ```tsx
50
62
  <Stack direction="row" spacing={2}>
@@ -72,7 +84,7 @@ function MyComponent() {
72
84
 
73
85
  ### Button Variants
74
86
 
75
- MenuButton 다양한 스타일 변형을 사용할 있습니다.
87
+ MenuButton supports `plain`, `outlined`, `soft`, and `solid` variants to match your design context.
76
88
 
77
89
  ```tsx
78
90
  <Stack direction="row" spacing={2} flexWrap="wrap">
@@ -112,7 +124,7 @@ MenuButton의 다양한 스타일 변형을 사용할 수 있습니다.
112
124
 
113
125
  ### Button Colors
114
126
 
115
- MenuButton에 다양한 색상을 적용할 있습니다.
127
+ Apply semantic colors to the trigger button for different emphasis levels.
116
128
 
117
129
  ```tsx
118
130
  <Stack direction="row" spacing={2} flexWrap="wrap">
@@ -170,7 +182,7 @@ MenuButton에 다양한 색상을 적용할 수 있습니다.
170
182
 
171
183
  ### Menu Placements
172
184
 
173
- 메뉴가 나타나는 위치를 설정할 있습니다.
185
+ Control where the menu appears relative to the trigger using the `placement` prop on Menu.
174
186
 
175
187
  ```tsx
176
188
  <Stack direction="row" spacing={2} sx={{
@@ -216,7 +228,7 @@ MenuButton에 다양한 색상을 적용할 수 있습니다.
216
228
 
217
229
  ### With Icons
218
230
 
219
- 아이콘이 포함된 메뉴를 만들 있습니다.
231
+ Add icons to menu items and decorators to the trigger button for richer visual communication.
220
232
 
221
233
  ```tsx
222
234
  <Dropdown>
@@ -249,7 +261,7 @@ MenuButton에 다양한 색상을 적용할 수 있습니다.
249
261
 
250
262
  ### Actions Menu
251
263
 
252
- 편집, 삭제 등의 액션 메뉴로 활용할 있습니다.
264
+ Build action menus for edit, delete, and other operations. Use `color="danger"` on destructive items.
253
265
 
254
266
  ```tsx
255
267
  <Dropdown>
@@ -280,7 +292,7 @@ MenuButton에 다양한 색상을 적용할 수 있습니다.
280
292
 
281
293
  ### Filter Menu
282
294
 
283
- 필터링 기능을 위한 드롭다운 메뉴입니다.
295
+ Use Dropdown as an interactive filter selector with state management.
284
296
 
285
297
  ```tsx
286
298
  <Dropdown>
@@ -298,7 +310,7 @@ MenuButton에 다양한 색상을 적용할 수 있습니다.
298
310
 
299
311
  ### Profile Dropdown
300
312
 
301
- 사용자 프로필 메뉴로 활용할 있습니다.
313
+ Combine custom content (user info header) with standard menu items for profile menus.
302
314
 
303
315
  ```tsx
304
316
  <Dropdown>
@@ -350,7 +362,7 @@ MenuButton에 다양한 색상을 적용할 수 있습니다.
350
362
 
351
363
  ### Nested Menus
352
364
 
353
- 여러 개의 드롭다운 메뉴를 나란히 배치할 있습니다.
365
+ Place multiple Dropdown instances side by side to create menu bar patterns.
354
366
 
355
367
  ```tsx
356
368
  <Stack direction="row" spacing={3}>
@@ -391,7 +403,7 @@ MenuButton에 다양한 색상을 적용할 수 있습니다.
391
403
 
392
404
  ### Controlled Dropdown
393
405
 
394
- 프로그래밍 방식으로 메뉴의 열림/닫힘 상태를 제어할 있습니다.
406
+ Use the `open` and `onOpenChange` props to programmatically control the menu state.
395
407
 
396
408
  ```tsx
397
409
  <Stack spacing={2}>
@@ -416,7 +428,7 @@ MenuButton에 다양한 색상을 적용할 수 있습니다.
416
428
 
417
429
  ### Disabled State
418
430
 
419
- 비활성 상태의 드롭다운과 메뉴 아이템을 표시할 있습니다.
431
+ Disable the entire trigger button or individual menu items.
420
432
 
421
433
  ```tsx
422
434
  <Stack direction="row" spacing={2}>
@@ -440,7 +452,7 @@ MenuButton에 다양한 색상을 적용할 수 있습니다.
440
452
 
441
453
  ### Long Menu
442
454
 
443
- 많은 옵션이 있는 메뉴는 스크롤을 적용할 있습니다.
455
+ Apply `maxHeight` and `overflow: 'auto'` to Menu for scrollable lists with many items.
444
456
 
445
457
  ```tsx
446
458
  <Dropdown>
@@ -460,7 +472,7 @@ MenuButton에 다양한 색상을 적용할 수 있습니다.
460
472
 
461
473
  ### Custom Styling
462
474
 
463
- CSS 스타일을 이용해 드롭다운을 커스터마이징할 있습니다.
475
+ Customize borders, shadows, border-radius, and gradients through the `sx` prop.
464
476
 
465
477
  ```tsx
466
478
  <Stack direction="row" spacing={2}>
@@ -515,89 +527,27 @@ CSS 스타일을 이용해 드롭다운을 커스터마이징할 수 있습니
515
527
  </Stack>
516
528
  ```
517
529
 
518
- ## Component Structure
519
-
520
- Dropdown은 다음 컴포넌트들과 함께 사용됩니다:
521
-
522
- ```tsx
523
- <Dropdown>
524
- <MenuButton>트리거 버튼</MenuButton>
525
- <Menu>
526
- <MenuItem>메뉴 아이템 1</MenuItem>
527
- <MenuItem>메뉴 아이템 2</MenuItem>
528
- <ListDivider /> {/* 구분선 */}
529
- <MenuItem>메뉴 아이템 3</MenuItem>
530
- </Menu>
531
- </Dropdown>
532
- ```
533
-
534
- ### MenuButton Props
535
-
536
- MenuButton 컴포넌트의 주요 props:
537
-
538
- - `variant`: `'plain' | 'outlined' | 'soft' | 'solid'`
539
- - `color`: `'primary' | 'neutral' | 'danger' | 'success' | 'warning'`
540
- - `size`: `'sm' | 'md' | 'lg'`
541
- - `startDecorator`: 앞쪽에 표시할 요소
542
- - `endDecorator`: 뒤쪽에 표시할 요소
543
- - `disabled`: 비활성 상태
544
-
545
- ### Menu Props
546
-
547
- Menu 컴포넌트의 주요 props:
548
-
549
- - `placement`: `'top-start' | 'top' | 'top-end' | 'bottom-start' | 'bottom' | 'bottom-end'`
550
- - `size`: `'sm' | 'md' | 'lg'`
551
- - `sx`: 스타일 커스터마이징
552
-
553
530
  ## Common Use Cases
554
531
 
555
532
  ### Navigation Menu
556
533
 
557
534
  ```tsx
558
535
  <Dropdown>
559
- <MenuButton variant="plain">메뉴</MenuButton>
536
+ <MenuButton variant="plain">Menu</MenuButton>
560
537
  <Menu>
561
- <MenuItem component="a" href="/home">홈</MenuItem>
562
- <MenuItem component="a" href="/about">회사소개</MenuItem>
563
- <MenuItem component="a" href="/products">제품</MenuItem>
538
+ <MenuItem component="a" href="/home">Home</MenuItem>
539
+ <MenuItem component="a" href="/about">About</MenuItem>
540
+ <MenuItem component="a" href="/products">Products</MenuItem>
564
541
  <ListDivider />
565
- <MenuItem component="a" href="/contact">문의하기</MenuItem>
542
+ <MenuItem component="a" href="/contact">Contact</MenuItem>
566
543
  </Menu>
567
544
  </Dropdown>
568
545
  ```
569
546
 
570
- ### User Profile Menu
547
+ ### Filter Selector
571
548
 
572
549
  ```tsx
573
- <Dropdown>
574
- <MenuButton
575
- variant="plain"
576
- startDecorator={<Avatar size="sm" />}
577
- endDecorator={<ExpandMoreIcon />}
578
- >
579
- 사용자명
580
- </MenuButton>
581
- <Menu>
582
- <Stack px={2} py={1}>
583
- <Typography level="title-sm">사용자명</Typography>
584
- <Typography level="body-xs" color="neutral">
585
- user@example.com
586
- </Typography>
587
- </Stack>
588
- <ListDivider />
589
- <MenuItem>프로필</MenuItem>
590
- <MenuItem>설정</MenuItem>
591
- <ListDivider />
592
- <MenuItem>로그아웃</MenuItem>
593
- </Menu>
594
- </Dropdown>
595
- ```
596
-
597
- ### Filter Dropdown
598
-
599
- ```tsx
600
- const [filter, setFilter] = useState('전체');
550
+ const [filter, setFilter] = useState('All');
601
551
 
602
552
  <Dropdown>
603
553
  <MenuButton
@@ -605,164 +555,85 @@ const [filter, setFilter] = useState('전체');
605
555
  startDecorator={<FilterListIcon />}
606
556
  endDecorator={<ExpandMoreIcon />}
607
557
  >
608
- 필터: {filter}
609
- </MenuButton>
610
- <Menu>
611
- <MenuItem onClick={() => setFilter('전체')}>전체</MenuItem>
612
- <MenuItem onClick={() => setFilter('활성')}>활성</MenuItem>
613
- <MenuItem onClick={() => setFilter('비활성')}>비활성</MenuItem>
614
- </Menu>
615
- </Dropdown>
616
- ```
617
-
618
- ### Action Menu
619
-
620
- ```tsx
621
- <Dropdown>
622
- <MenuButton variant="plain" size="sm">
623
- 작업
558
+ Filter: {filter}
624
559
  </MenuButton>
625
560
  <Menu>
626
- <MenuItem>
627
- <EditIcon sx={{ mr: 1 }} />
628
- 편집
629
- </MenuItem>
630
- <MenuItem>
631
- <CopyIcon sx={{ mr: 1 }} />
632
- 복사
633
- </MenuItem>
634
- <MenuItem color="danger">
635
- <DeleteIcon sx={{ mr: 1 }} />
636
- 삭제
637
- </MenuItem>
561
+ <MenuItem onClick={() => setFilter('All')}>All</MenuItem>
562
+ <MenuItem onClick={() => setFilter('Active')}>Active</MenuItem>
563
+ <MenuItem onClick={() => setFilter('Inactive')}>Inactive</MenuItem>
638
564
  </Menu>
639
565
  </Dropdown>
640
566
  ```
641
567
 
642
- ### Language Selector
568
+ ### Controlled State with External Toggle
643
569
 
644
570
  ```tsx
645
- const [language, setLanguage] = useState('한국어');
571
+ const [open, setOpen] = useState(false);
646
572
 
647
- <Dropdown>
648
- <MenuButton variant="soft" size="sm">
649
- {language}
650
- </MenuButton>
573
+ <Dropdown open={open} onOpenChange={(event, isOpen) => setOpen(isOpen)}>
574
+ <MenuButton>Controlled Menu</MenuButton>
651
575
  <Menu>
652
- <MenuItem onClick={() => setLanguage('한국어')}>
653
- 한국어
654
- </MenuItem>
655
- <MenuItem onClick={() => setLanguage('English')}>
656
- English
657
- </MenuItem>
658
- <MenuItem onClick={() => setLanguage('日本語')}>
659
- 日本語
660
- </MenuItem>
576
+ <MenuItem onClick={() => setOpen(false)}>Option A</MenuItem>
577
+ <MenuItem onClick={() => setOpen(false)}>Option B</MenuItem>
661
578
  </Menu>
662
579
  </Dropdown>
663
- ```
664
-
665
- ### Sort Options
666
580
 
667
- ```tsx
668
- const [sortBy, setSortBy] = useState('이름순');
669
-
670
- <Dropdown>
671
- <MenuButton
672
- variant="outlined"
673
- startDecorator={<SortIcon />}
674
- endDecorator={<ExpandMoreIcon />}
675
- >
676
- 정렬: {sortBy}
677
- </MenuButton>
678
- <Menu>
679
- <MenuItem onClick={() => setSortBy('이름순')}>이름순</MenuItem>
680
- <MenuItem onClick={() => setSortBy('날짜순')}>날짜순</MenuItem>
681
- <MenuItem onClick={() => setSortBy('크기순')}>크기순</MenuItem>
682
- </Menu>
683
- </Dropdown>
581
+ <Button onClick={() => setOpen(!open)}>
582
+ {open ? 'Close' : 'Open'} Menu
583
+ </Button>
684
584
  ```
685
585
 
686
586
  ## Best Practices
687
587
 
688
- 1. **명확한 라벨**: MenuButton 텍스트는 메뉴의 내용을 명확히 나타내야 합니다.
689
-
690
- 2. **적절한 아이콘 사용**: 드롭다운임을 나타내는 화살표 아이콘을 사용하세요.
691
- ```tsx
692
- <MenuButton endDecorator={<ExpandMoreIcon />}>
693
- ```
694
-
695
- 3. **메뉴 아이템 그룹화**: 관련된 메뉴 아이템들은 ListDivider로 구분하세요.
696
-
697
- 4. **키보드 접근성**: 키보드 탐색이 가능하도록 적절한 props를 설정하세요.
698
-
699
- 5. **적절한 배치**: 화면 공간을 고려하여 메뉴의 placement를 설정하세요.
700
-
701
- 6. **로딩 상태**: 필요한 경우 MenuButton에 loading 상태를 표시하세요.
702
-
703
- 7. **일관된 스타일**: 애플리케이션 전반에서 일관된 드롭다운 스타일을 유지하세요.
704
-
705
- 8. **모바일 고려**: 모바일에서도 사용하기 쉽도록 충분한 터치 영역을 확보하세요.
588
+ - **Use the right abstraction level.** If you only need a simple list of text items, prefer `MenuButton` or `IconMenuButton` standalone components. Use `Dropdown` + `Menu` when you need dividers, custom headers, or mixed content inside the menu.
706
589
 
707
- ## Controlled vs Uncontrolled
590
+ ```tsx
591
+ {/* ✅ Good: Simple list -- use MenuButton directly */}
592
+ <MenuButton buttonText="Actions" items={[{ text: 'Edit' }, { text: 'Delete' }]} />
708
593
 
709
- ### Uncontrolled (기본)
710
-
711
- ```tsx
712
- <Dropdown>
713
- <MenuButton>메뉴</MenuButton>
714
- <Menu>
715
- <MenuItem>옵션</MenuItem>
716
- </Menu>
717
- </Dropdown>
718
- ```
719
-
720
- ### Controlled
594
+ {/* Good: Complex content -- use Dropdown composition */}
595
+ <Dropdown>
596
+ <MenuButton>User</MenuButton>
597
+ <Menu>
598
+ <Box sx={{ px: 2, py: 1 }}>
599
+ <Typography level="title-sm">User Name</Typography>
600
+ </Box>
601
+ <ListDivider />
602
+ <MenuItem>Settings</MenuItem>
603
+ <MenuItem>Logout</MenuItem>
604
+ </Menu>
605
+ </Dropdown>
606
+ ```
721
607
 
722
- ```tsx
723
- const [open, setOpen] = useState(false);
608
+ - **Group related items with ListDivider.** Visually separate logical groups of menu items so users can scan options quickly.
724
609
 
725
- <Dropdown
726
- open={open}
727
- onOpenChange={(event, isOpen) => setOpen(isOpen)}
728
- >
729
- <MenuButton>메뉴</MenuButton>
610
+ ```tsx
611
+ {/* ✅ Good: Grouped by function */}
730
612
  <Menu>
731
- <MenuItem onClick={() => setOpen(false)}>옵션</MenuItem>
613
+ <MenuItem>Edit</MenuItem>
614
+ <MenuItem>Duplicate</MenuItem>
615
+ <ListDivider />
616
+ <MenuItem color="danger">Delete</MenuItem>
732
617
  </Menu>
733
- </Dropdown>
734
- ```
618
+ ```
735
619
 
736
- ## Accessibility
737
-
738
- Dropdown은 접근성을 위한 기본적인 기능들을 제공합니다:
739
-
740
- - **키보드 탐색**: Tab, Enter, Escape, 화살표 키 지원
741
- - **ARIA 속성**: 적절한 ARIA 라벨과 역할 자동 설정
742
- - **포커스 관리**: 메뉴가 열릴 때 첫 번째 아이템으로 포커스 이동
743
- - **스크린 리더**: 메뉴의 상태와 옵션들을 적절히 읽어줌
620
+ - **Indicate dropdown affordance.** Use `endDecorator={<ExpandMoreIcon />}` on the trigger button so users understand it opens a menu.
744
621
 
745
- 추가적인 접근성을 위해:
622
+ ```tsx
623
+ {/* ✅ Good: Clear dropdown indicator */}
624
+ <MenuButton endDecorator={<ExpandMoreIcon />}>Options</MenuButton>
746
625
 
747
- - 메뉴 아이템에 적절한 라벨 제공
748
- - 위험한 작업(삭제 등)에 대한 확인 절차 제공
749
- - 색상에만 의존하지 않는 시각적 피드백
626
+ {/* Avoid: No visual hint that a menu will appear */}
627
+ <MenuButton>Options</MenuButton>
628
+ ```
750
629
 
751
- ## When to Use Dropdown
630
+ - **Keep menu item count reasonable.** Aim for 3-7 items. For longer lists, apply `maxHeight` with scrolling or consider a different UI pattern like a dialog or searchable list.
752
631
 
753
- ### 사용하기 좋은 경우
632
+ - **Use controlled mode sparingly.** Uncontrolled mode (no `open` prop) handles most scenarios. Only use controlled mode when external events need to open or close the menu.
754
633
 
755
- - **메뉴 시스템**: 네비게이션이나 컨텍스트 메뉴가 필요할 때
756
- - **필터링**: 여러 옵션 중 하나를 선택하는 필터가 필요할 때
757
- - **액션 목록**: 특정 항목에 대한 여러 작업이 있을 때
758
- - **사용자 메뉴**: 프로필, 설정, 로그아웃 등의 사용자 관련 기능
759
- - **공간 절약**: 화면 공간이 제한적일 때 여러 옵션을 숨기고 싶을 때
760
-
761
- ### ❌ 사용하지 않는 것이 좋은 경우
762
-
763
- - **단일 액션**: 하나의 간단한 작업만 있을 때는 일반 Button 사용
764
- - **긴 폼**: 폼에서는 Select 컴포넌트가 더 적절
765
- - **항상 보여야 하는 옵션**: 중요한 옵션들은 항상 표시하는 것이 좋음
766
- - **너무 많은 옵션**: 20개 이상의 옵션이 있다면 다른 UI 패턴 고려
634
+ ## Accessibility
767
635
 
768
- Dropdown은 사용자에게 깔끔하고 직관적인 메뉴 경험을 제공하는 강력한 컴포넌트입니다. 적절히 사용하면 공간을 효율적으로 활용하면서도 풍부한 기능을 제공할 있습니다.
636
+ - **Keyboard navigation**: Tab focuses the trigger button. Enter or Space opens the menu. Arrow keys navigate between items. Escape closes the menu and returns focus to the trigger.
637
+ - **ARIA attributes**: Dropdown automatically sets `aria-haspopup`, `aria-expanded`, `role="menu"`, and `role="menuitem"` on the appropriate elements.
638
+ - **Focus management**: When the menu opens, focus moves to the first menu item. When the menu closes, focus returns to the trigger button.
639
+ - **Color is not the only indicator**: When using `color="danger"` on destructive items, pair it with a clear text label (e.g., "Delete") so the meaning is not conveyed by color alone.