@ceed/ads 1.29.0 → 1.30.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.
- package/dist/components/CurrencyInput/CurrencyInput.d.ts +1 -1
- package/dist/components/CurrencyInput/hooks/use-currency-setting.d.ts +2 -2
- package/dist/components/DataTable/hooks.d.ts +2 -1
- package/dist/components/DataTable/utils.d.ts +1 -0
- package/dist/components/ProfileMenu/ProfileMenu.d.ts +1 -1
- package/dist/components/SearchBar/SearchBar.d.ts +21 -0
- package/dist/components/SearchBar/index.d.ts +3 -0
- package/dist/components/data-display/Badge.md +39 -71
- package/dist/components/data-display/DataTable.md +1 -1
- package/dist/components/data-display/InfoSign.md +98 -74
- package/dist/components/data-display/Typography.md +97 -363
- package/dist/components/feedback/Dialog.md +62 -76
- package/dist/components/feedback/Modal.md +44 -259
- package/dist/components/feedback/llms.txt +0 -2
- package/dist/components/index.d.ts +2 -0
- package/dist/components/inputs/Autocomplete.md +107 -356
- package/dist/components/inputs/ButtonGroup.md +106 -115
- package/dist/components/inputs/Calendar.md +459 -98
- package/dist/components/inputs/CurrencyInput.md +5 -183
- package/dist/components/inputs/DatePicker.md +431 -108
- package/dist/components/inputs/DateRangePicker.md +492 -131
- package/dist/components/inputs/FilterMenu.md +19 -169
- package/dist/components/inputs/FilterableCheckboxGroup.md +23 -123
- package/dist/components/inputs/IconButton.md +88 -137
- package/dist/components/inputs/Input.md +0 -5
- package/dist/components/inputs/MonthPicker.md +422 -95
- package/dist/components/inputs/MonthRangePicker.md +466 -89
- package/dist/components/inputs/PercentageInput.md +16 -185
- package/dist/components/inputs/RadioButton.md +35 -163
- package/dist/components/inputs/RadioTileGroup.md +61 -150
- package/dist/components/inputs/SearchBar.md +44 -0
- package/dist/components/inputs/Select.md +326 -222
- package/dist/components/inputs/Switch.md +376 -136
- package/dist/components/inputs/Textarea.md +10 -213
- package/dist/components/inputs/Uploader/Uploader.md +66 -145
- package/dist/components/inputs/llms.txt +1 -3
- package/dist/components/navigation/Breadcrumbs.md +322 -80
- package/dist/components/navigation/Dropdown.md +221 -92
- package/dist/components/navigation/IconMenuButton.md +502 -40
- package/dist/components/navigation/InsetDrawer.md +738 -68
- package/dist/components/navigation/Link.md +298 -39
- package/dist/components/navigation/Menu.md +285 -92
- package/dist/components/navigation/MenuButton.md +448 -55
- package/dist/components/navigation/Pagination.md +338 -47
- package/dist/components/navigation/ProfileMenu.md +268 -45
- package/dist/components/navigation/Stepper.md +28 -160
- package/dist/components/navigation/Tabs.md +316 -57
- package/dist/components/surfaces/Sheet.md +334 -151
- package/dist/index.browser.js +15 -13
- package/dist/index.browser.js.map +4 -4
- package/dist/index.cjs +313 -291
- package/dist/index.d.ts +1 -1
- package/dist/index.js +450 -372
- package/dist/llms.txt +1 -8
- package/framer/index.js +1 -1
- package/package.json +16 -15
- package/dist/chunks/rehype-accent-FZRUD7VI.js +0 -39
- package/dist/components/feedback/CircularProgress.md +0 -257
- package/dist/components/feedback/Skeleton.md +0 -280
- package/dist/components/inputs/FormControl.md +0 -361
- package/dist/components/inputs/RadioList.md +0 -241
- package/dist/components/inputs/Slider.md +0 -334
- package/dist/guides/ThemeProvider.md +0 -116
- package/dist/guides/llms.txt +0 -9
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Menu
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Introduction
|
|
4
4
|
|
|
5
|
-
Menu
|
|
5
|
+
Menu와 MenuItem 컴포넌트는 드롭다운 메뉴의 콘텐츠를 구성하는 컴포넌트입니다. Joy UI의 Menu와 MenuItem을 기반으로 합니다.. Dropdown 컴포넌트와 함께 사용하여 사용자에게 선택 가능한 옵션들을 제공합니다. 네비게이션, 액션 메뉴, 컨텍스트 메뉴 등 다양한 용도로 활용할 수 있습니다.
|
|
6
6
|
|
|
7
7
|
```tsx
|
|
8
8
|
<Box sx={{
|
|
@@ -26,42 +26,27 @@ Menu is built on Joy UI's Menu component and supports sizes, placements, custom
|
|
|
26
26
|
## Usage
|
|
27
27
|
|
|
28
28
|
```tsx
|
|
29
|
-
import { Dropdown, Menu, MenuItem } from '@ceed/ads';
|
|
30
|
-
import { MenuButton } from '@ceed/ads';
|
|
29
|
+
import { Dropdown, MenuButton, Menu, MenuItem } from '@ceed/ads';
|
|
31
30
|
|
|
32
31
|
function MyComponent() {
|
|
33
32
|
return (
|
|
34
33
|
<Dropdown>
|
|
35
|
-
<MenuButton
|
|
34
|
+
<MenuButton>메뉴 열기</MenuButton>
|
|
36
35
|
<Menu>
|
|
37
|
-
<MenuItem
|
|
38
|
-
<MenuItem
|
|
39
|
-
<MenuItem
|
|
36
|
+
<MenuItem>옵션 1</MenuItem>
|
|
37
|
+
<MenuItem>옵션 2</MenuItem>
|
|
38
|
+
<MenuItem>옵션 3</MenuItem>
|
|
40
39
|
</Menu>
|
|
41
40
|
</Dropdown>
|
|
42
41
|
);
|
|
43
42
|
}
|
|
44
43
|
```
|
|
45
44
|
|
|
46
|
-
##
|
|
47
|
-
|
|
48
|
-
Menu is always used inside a Dropdown together with a trigger element. The full composition looks like this:
|
|
49
|
-
|
|
50
|
-
```
|
|
51
|
-
Dropdown -- state container (open/close)
|
|
52
|
-
MenuButton -- trigger element (or IconMenuButton)
|
|
53
|
-
Menu -- floating panel
|
|
54
|
-
MenuItem -- individual option
|
|
55
|
-
ListDivider -- visual separator between groups
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
See the [Dropdown](?path=/docs/components-navigation-dropdown--docs) documentation for guidance on when to use the composition pattern versus the standalone MenuButton/IconMenuButton components.
|
|
59
|
-
|
|
60
|
-
## Features
|
|
45
|
+
## Examples
|
|
61
46
|
|
|
62
47
|
### Basic Menu
|
|
63
48
|
|
|
64
|
-
|
|
49
|
+
가장 기본적인 Menu 사용법입니다.
|
|
65
50
|
|
|
66
51
|
```tsx
|
|
67
52
|
<Stack direction="row" spacing={3}>
|
|
@@ -92,7 +77,7 @@ A standard menu with simple text items, optionally separated by dividers.
|
|
|
92
77
|
|
|
93
78
|
### Menu Sizes
|
|
94
79
|
|
|
95
|
-
|
|
80
|
+
다양한 크기의 메뉴를 사용할 수 있습니다.
|
|
96
81
|
|
|
97
82
|
```tsx
|
|
98
83
|
<Stack direction="row" spacing={3}>
|
|
@@ -133,7 +118,7 @@ Menu supports `sm`, `md`, and `lg` sizes that affect the padding and font size o
|
|
|
133
118
|
|
|
134
119
|
### MenuItem States
|
|
135
120
|
|
|
136
|
-
|
|
121
|
+
MenuItem의 다양한 상태를 표현할 수 있습니다.
|
|
137
122
|
|
|
138
123
|
```tsx
|
|
139
124
|
<Dropdown>
|
|
@@ -152,7 +137,7 @@ MenuItems can be `selected`, `disabled`, or colored with semantic colors like `p
|
|
|
152
137
|
|
|
153
138
|
### MenuItem with Icons
|
|
154
139
|
|
|
155
|
-
|
|
140
|
+
메뉴 아이템에 아이콘을 추가할 수 있습니다.
|
|
156
141
|
|
|
157
142
|
```tsx
|
|
158
143
|
<Dropdown>
|
|
@@ -195,7 +180,7 @@ Add icons before item text to improve scannability. Use consistent icon sizing w
|
|
|
195
180
|
|
|
196
181
|
### Actions Menu
|
|
197
182
|
|
|
198
|
-
|
|
183
|
+
편집, 삭제 등의 액션 메뉴로 활용할 수 있습니다.
|
|
199
184
|
|
|
200
185
|
```tsx
|
|
201
186
|
<Dropdown>
|
|
@@ -238,7 +223,7 @@ Build action menus for CRUD operations. Use `color="danger"` to highlight destru
|
|
|
238
223
|
|
|
239
224
|
### Clickable Menu Items
|
|
240
225
|
|
|
241
|
-
|
|
226
|
+
메뉴 아이템에 클릭 이벤트를 연결할 수 있습니다.
|
|
242
227
|
|
|
243
228
|
```tsx
|
|
244
229
|
<Stack spacing={2}>
|
|
@@ -257,7 +242,7 @@ Attach `onClick` handlers to menu items to respond to user selections.
|
|
|
257
242
|
|
|
258
243
|
### Menu as Links
|
|
259
244
|
|
|
260
|
-
|
|
245
|
+
메뉴 아이템을 링크로 사용할 수 있습니다.
|
|
261
246
|
|
|
262
247
|
```tsx
|
|
263
248
|
<Dropdown>
|
|
@@ -281,7 +266,7 @@ Use the `component="a"` prop on MenuItem to render items as anchor links for nav
|
|
|
281
266
|
|
|
282
267
|
### Profile Menu
|
|
283
268
|
|
|
284
|
-
|
|
269
|
+
사용자 프로필 메뉴의 완성된 예제입니다.
|
|
285
270
|
|
|
286
271
|
```tsx
|
|
287
272
|
<Dropdown>
|
|
@@ -351,7 +336,7 @@ Combine custom Box content (user info header) with standard MenuItem entries for
|
|
|
351
336
|
|
|
352
337
|
### Menu Placements
|
|
353
338
|
|
|
354
|
-
|
|
339
|
+
메뉴가 나타나는 위치를 다양하게 설정할 수 있습니다.
|
|
355
340
|
|
|
356
341
|
```tsx
|
|
357
342
|
<Stack spacing={4} alignItems="center" sx={{
|
|
@@ -420,7 +405,7 @@ Control the position of the menu panel relative to the trigger using the `placem
|
|
|
420
405
|
|
|
421
406
|
### Long Scrollable Menu
|
|
422
407
|
|
|
423
|
-
|
|
408
|
+
많은 옵션이 있는 메뉴는 스크롤을 적용할 수 있습니다.
|
|
424
409
|
|
|
425
410
|
```tsx
|
|
426
411
|
<Dropdown>
|
|
@@ -438,7 +423,7 @@ For menus with many items, apply `maxHeight` and `overflow: 'auto'` through the
|
|
|
438
423
|
|
|
439
424
|
### Custom Styled Menu
|
|
440
425
|
|
|
441
|
-
|
|
426
|
+
CSS 스타일을 이용해 메뉴를 커스터마이징할 수 있습니다.
|
|
442
427
|
|
|
443
428
|
```tsx
|
|
444
429
|
<Stack direction="row" spacing={3}>
|
|
@@ -502,7 +487,7 @@ Customize the menu panel appearance with border-radius, shadows, borders, and cu
|
|
|
502
487
|
|
|
503
488
|
### Menu in Card
|
|
504
489
|
|
|
505
|
-
|
|
490
|
+
카드나 다른 컴포넌트 내에서 메뉴를 사용할 수 있습니다.
|
|
506
491
|
|
|
507
492
|
```tsx
|
|
508
493
|
<Sheet variant="outlined" sx={{
|
|
@@ -562,7 +547,7 @@ Embed a Dropdown menu inside cards or other container components for contextual
|
|
|
562
547
|
|
|
563
548
|
### Nested Content
|
|
564
549
|
|
|
565
|
-
|
|
550
|
+
메뉴 내에 복잡한 콘텐츠를 구성할 수 있습니다.
|
|
566
551
|
|
|
567
552
|
```tsx
|
|
568
553
|
<Dropdown>
|
|
@@ -646,42 +631,93 @@ Menu can contain non-MenuItem elements like Box, Typography, and progress indica
|
|
|
646
631
|
</Dropdown>
|
|
647
632
|
```
|
|
648
633
|
|
|
634
|
+
## Component Structure
|
|
635
|
+
|
|
636
|
+
Menu는 다음과 같은 구조로 구성됩니다:
|
|
637
|
+
|
|
638
|
+
```tsx
|
|
639
|
+
<Dropdown>
|
|
640
|
+
<MenuButton>트리거</MenuButton>
|
|
641
|
+
<Menu>
|
|
642
|
+
{/* 기본 메뉴 아이템 */}
|
|
643
|
+
<MenuItem>기본 아이템</MenuItem>
|
|
644
|
+
|
|
645
|
+
{/* 아이콘이 있는 메뉴 아이템 */}
|
|
646
|
+
<MenuItem>
|
|
647
|
+
<Icon sx={{ mr: 1 }} />
|
|
648
|
+
아이콘 아이템
|
|
649
|
+
</MenuItem>
|
|
650
|
+
|
|
651
|
+
{/* 구분선 */}
|
|
652
|
+
<ListDivider />
|
|
653
|
+
|
|
654
|
+
{/* 색상이 있는 메뉴 아이템 */}
|
|
655
|
+
<MenuItem color="danger">위험한 작업</MenuItem>
|
|
656
|
+
|
|
657
|
+
{/* 비활성 메뉴 아이템 */}
|
|
658
|
+
<MenuItem disabled>비활성 아이템</MenuItem>
|
|
659
|
+
|
|
660
|
+
{/* 링크 메뉴 아이템 */}
|
|
661
|
+
<MenuItem component="a" href="/link">
|
|
662
|
+
링크 아이템
|
|
663
|
+
</MenuItem>
|
|
664
|
+
|
|
665
|
+
{/* 클릭 핸들러가 있는 메뉴 아이템 */}
|
|
666
|
+
<MenuItem onClick={handleClick}>클릭 가능한 아이템</MenuItem>
|
|
667
|
+
</Menu>
|
|
668
|
+
</Dropdown>
|
|
669
|
+
```
|
|
670
|
+
|
|
649
671
|
## Common Use Cases
|
|
650
672
|
|
|
651
|
-
###
|
|
673
|
+
### Navigation Menu
|
|
652
674
|
|
|
653
675
|
```tsx
|
|
654
676
|
<Dropdown>
|
|
655
|
-
<MenuButton
|
|
677
|
+
<MenuButton>네비게이션</MenuButton>
|
|
656
678
|
<Menu>
|
|
657
|
-
<MenuItem
|
|
658
|
-
|
|
659
|
-
Edit
|
|
679
|
+
<MenuItem component="a" href="/home">
|
|
680
|
+
홈
|
|
660
681
|
</MenuItem>
|
|
661
|
-
<MenuItem
|
|
662
|
-
|
|
663
|
-
|
|
682
|
+
<MenuItem component="a" href="/products">
|
|
683
|
+
제품
|
|
684
|
+
</MenuItem>
|
|
685
|
+
<MenuItem component="a" href="/services">
|
|
686
|
+
서비스
|
|
664
687
|
</MenuItem>
|
|
665
688
|
<ListDivider />
|
|
666
|
-
<MenuItem
|
|
667
|
-
|
|
668
|
-
Delete
|
|
689
|
+
<MenuItem component="a" href="/contact">
|
|
690
|
+
문의하기
|
|
669
691
|
</MenuItem>
|
|
670
692
|
</Menu>
|
|
671
693
|
</Dropdown>
|
|
672
694
|
```
|
|
673
695
|
|
|
674
|
-
###
|
|
696
|
+
### Action Menu with Icons
|
|
675
697
|
|
|
676
698
|
```tsx
|
|
677
699
|
<Dropdown>
|
|
678
|
-
<MenuButton>
|
|
700
|
+
<MenuButton variant="plain" size="sm">
|
|
701
|
+
작업
|
|
702
|
+
</MenuButton>
|
|
679
703
|
<Menu>
|
|
680
|
-
<MenuItem
|
|
681
|
-
|
|
682
|
-
|
|
704
|
+
<MenuItem onClick={handleEdit}>
|
|
705
|
+
<EditIcon sx={{ mr: 1 }} />
|
|
706
|
+
편집
|
|
707
|
+
</MenuItem>
|
|
708
|
+
<MenuItem onClick={handleCopy}>
|
|
709
|
+
<CopyIcon sx={{ mr: 1 }} />
|
|
710
|
+
복사
|
|
711
|
+
</MenuItem>
|
|
712
|
+
<MenuItem onClick={handleShare}>
|
|
713
|
+
<ShareIcon sx={{ mr: 1 }} />
|
|
714
|
+
공유
|
|
715
|
+
</MenuItem>
|
|
683
716
|
<ListDivider />
|
|
684
|
-
<MenuItem
|
|
717
|
+
<MenuItem color="danger" onClick={handleDelete}>
|
|
718
|
+
<DeleteIcon sx={{ mr: 1 }} />
|
|
719
|
+
삭제
|
|
720
|
+
</MenuItem>
|
|
685
721
|
</Menu>
|
|
686
722
|
</Dropdown>
|
|
687
723
|
```
|
|
@@ -690,75 +726,232 @@ Menu can contain non-MenuItem elements like Box, Typography, and progress indica
|
|
|
690
726
|
|
|
691
727
|
```tsx
|
|
692
728
|
<Dropdown>
|
|
693
|
-
<MenuButton
|
|
694
|
-
|
|
695
|
-
endDecorator={<ExpandMoreIcon />}
|
|
696
|
-
>
|
|
697
|
-
Username
|
|
729
|
+
<MenuButton startDecorator={<Avatar size="sm" src="/avatar.jpg" />} endDecorator={<ExpandMoreIcon />}>
|
|
730
|
+
사용자명
|
|
698
731
|
</MenuButton>
|
|
699
732
|
<Menu>
|
|
733
|
+
{/* 프로필 헤더 */}
|
|
700
734
|
<Box sx={{ px: 2, py: 1.5 }}>
|
|
701
|
-
<Typography level="title-sm"
|
|
702
|
-
<Typography level="body-xs" color="neutral">
|
|
735
|
+
<Typography level="title-sm">사용자명</Typography>
|
|
736
|
+
<Typography level="body-xs" color="neutral">
|
|
737
|
+
user@example.com
|
|
738
|
+
</Typography>
|
|
703
739
|
</Box>
|
|
740
|
+
|
|
704
741
|
<ListDivider />
|
|
742
|
+
|
|
705
743
|
<MenuItem>
|
|
706
744
|
<PersonIcon sx={{ mr: 1 }} />
|
|
707
|
-
|
|
745
|
+
프로필 보기
|
|
708
746
|
</MenuItem>
|
|
709
747
|
<MenuItem>
|
|
710
748
|
<SettingsIcon sx={{ mr: 1 }} />
|
|
711
|
-
|
|
749
|
+
설정
|
|
712
750
|
</MenuItem>
|
|
751
|
+
|
|
713
752
|
<ListDivider />
|
|
753
|
+
|
|
714
754
|
<MenuItem>
|
|
715
755
|
<LogoutIcon sx={{ mr: 1 }} />
|
|
716
|
-
|
|
756
|
+
로그아웃
|
|
717
757
|
</MenuItem>
|
|
718
758
|
</Menu>
|
|
719
759
|
</Dropdown>
|
|
720
760
|
```
|
|
721
761
|
|
|
722
|
-
|
|
762
|
+
### Filter Menu
|
|
723
763
|
|
|
724
|
-
|
|
764
|
+
```tsx
|
|
765
|
+
const [filter, setFilter] = useState('전체');
|
|
725
766
|
|
|
726
|
-
|
|
727
|
-
{
|
|
767
|
+
<Dropdown>
|
|
768
|
+
<MenuButton startDecorator={<FilterListIcon />} endDecorator={<ExpandMoreIcon />}>
|
|
769
|
+
필터: {filter}
|
|
770
|
+
</MenuButton>
|
|
728
771
|
<Menu>
|
|
729
|
-
<MenuItem>
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
<MenuItem
|
|
772
|
+
<MenuItem selected={filter === '전체'} onClick={() => setFilter('전체')}>
|
|
773
|
+
전체
|
|
774
|
+
</MenuItem>
|
|
775
|
+
<MenuItem selected={filter === '활성'} onClick={() => setFilter('활성')}>
|
|
776
|
+
활성
|
|
777
|
+
</MenuItem>
|
|
778
|
+
<MenuItem selected={filter === '비활성'} onClick={() => setFilter('비활성')}>
|
|
779
|
+
비활성
|
|
780
|
+
</MenuItem>
|
|
733
781
|
</Menu>
|
|
734
|
-
|
|
782
|
+
</Dropdown>;
|
|
783
|
+
```
|
|
735
784
|
|
|
736
|
-
|
|
785
|
+
### Context Menu (Right-click Menu)
|
|
737
786
|
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
787
|
+
```tsx
|
|
788
|
+
const [contextMenu, setContextMenu] = useState(null);
|
|
789
|
+
|
|
790
|
+
const handleContextMenu = (event) => {
|
|
791
|
+
event.preventDefault();
|
|
792
|
+
setContextMenu({
|
|
793
|
+
mouseX: event.clientX - 2,
|
|
794
|
+
mouseY: event.clientY - 4,
|
|
795
|
+
});
|
|
796
|
+
};
|
|
797
|
+
|
|
798
|
+
<div onContextMenu={handleContextMenu}>
|
|
799
|
+
우클릭 가능한 영역
|
|
800
|
+
{contextMenu && (
|
|
801
|
+
<Menu
|
|
802
|
+
open
|
|
803
|
+
anchorReference="anchorPosition"
|
|
804
|
+
anchorPosition={{
|
|
805
|
+
top: contextMenu.mouseY,
|
|
806
|
+
left: contextMenu.mouseX,
|
|
807
|
+
}}
|
|
808
|
+
onClose={() => setContextMenu(null)}
|
|
809
|
+
>
|
|
810
|
+
<MenuItem>복사</MenuItem>
|
|
811
|
+
<MenuItem>붙여넣기</MenuItem>
|
|
812
|
+
<MenuItem>삭제</MenuItem>
|
|
813
|
+
</Menu>
|
|
814
|
+
)}
|
|
815
|
+
</div>;
|
|
816
|
+
```
|
|
742
817
|
|
|
743
|
-
|
|
744
|
-
<MenuItem><EditIcon sx={{ mr: 1 }} />Edit</MenuItem>
|
|
745
|
-
<MenuItem><DeleteIcon sx={{ mr: 2, fontSize: 'xl' }} />Delete</MenuItem>
|
|
746
|
-
```
|
|
818
|
+
### Submenu Pattern
|
|
747
819
|
|
|
748
|
-
|
|
820
|
+
```tsx
|
|
821
|
+
<Dropdown>
|
|
822
|
+
<MenuButton>파일</MenuButton>
|
|
823
|
+
<Menu>
|
|
824
|
+
<MenuItem>새 파일</MenuItem>
|
|
825
|
+
<MenuItem>열기</MenuItem>
|
|
749
826
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
827
|
+
{/* 서브메뉴는 별도 Dropdown으로 구현 */}
|
|
828
|
+
<MenuItem>
|
|
829
|
+
최근 파일
|
|
830
|
+
<Dropdown>
|
|
831
|
+
<MenuButton variant="plain" size="sm" sx={{ ml: 'auto' }}>
|
|
832
|
+
▶
|
|
833
|
+
</MenuButton>
|
|
834
|
+
<Menu placement="right-start">
|
|
835
|
+
<MenuItem>파일1.txt</MenuItem>
|
|
836
|
+
<MenuItem>파일2.txt</MenuItem>
|
|
837
|
+
<MenuItem>파일3.txt</MenuItem>
|
|
838
|
+
</Menu>
|
|
839
|
+
</Dropdown>
|
|
840
|
+
</MenuItem>
|
|
841
|
+
|
|
842
|
+
<ListDivider />
|
|
843
|
+
<MenuItem>저장</MenuItem>
|
|
844
|
+
<MenuItem>종료</MenuItem>
|
|
845
|
+
</Menu>
|
|
846
|
+
</Dropdown>
|
|
847
|
+
```
|
|
754
848
|
|
|
755
|
-
|
|
849
|
+
## Menu Placement
|
|
756
850
|
|
|
757
|
-
|
|
851
|
+
메뉴의 위치는 `placement` prop으로 조정할 수 있습니다:
|
|
852
|
+
|
|
853
|
+
```tsx
|
|
854
|
+
<Menu placement="top-start"> {/* 위쪽 왼쪽 정렬 */}
|
|
855
|
+
<Menu placement="top"> {/* 위쪽 중앙 정렬 */}
|
|
856
|
+
<Menu placement="top-end"> {/* 위쪽 오른쪽 정렬 */}
|
|
857
|
+
<Menu placement="bottom-start"> {/* 아래쪽 왼쪽 정렬 (기본값) */}
|
|
858
|
+
<Menu placement="bottom"> {/* 아래쪽 중앙 정렬 */}
|
|
859
|
+
<Menu placement="bottom-end"> {/* 아래쪽 오른쪽 정렬 */}
|
|
860
|
+
```
|
|
758
861
|
|
|
759
862
|
## Accessibility
|
|
760
863
|
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
864
|
+
Menu 컴포넌트는 다음과 같은 접근성 기능을 제공합니다:
|
|
865
|
+
|
|
866
|
+
### 키보드 탐색
|
|
867
|
+
|
|
868
|
+
- **Tab**: 메뉴 버튼으로 포커스 이동
|
|
869
|
+
- **Enter/Space**: 메뉴 열기/닫기
|
|
870
|
+
- **↑/↓**: 메뉴 아이템 간 이동
|
|
871
|
+
- **Escape**: 메뉴 닫기
|
|
872
|
+
- **Enter**: 메뉴 아이템 선택
|
|
873
|
+
|
|
874
|
+
### ARIA 속성
|
|
875
|
+
|
|
876
|
+
- `role="menu"`: 메뉴 역할 정의
|
|
877
|
+
- `role="menuitem"`: 메뉴 아이템 역할 정의
|
|
878
|
+
- `aria-expanded`: 메뉴 열림/닫힘 상태
|
|
879
|
+
- `aria-haspopup`: 팝업 메뉴 존재 표시
|
|
880
|
+
|
|
881
|
+
### 추가 접근성 고려사항
|
|
882
|
+
|
|
883
|
+
```tsx
|
|
884
|
+
<MenuItem aria-label="사용자 프로필 편집">
|
|
885
|
+
<EditIcon />
|
|
886
|
+
편집
|
|
887
|
+
</MenuItem>
|
|
888
|
+
|
|
889
|
+
<MenuItem disabled aria-label="현재 사용할 수 없는 기능">
|
|
890
|
+
사용 불가
|
|
891
|
+
</MenuItem>
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
## Best Practices
|
|
895
|
+
|
|
896
|
+
1. **명확한 라벨링**: 메뉴 아이템은 명확하고 이해하기 쉬운 텍스트를 사용하세요.
|
|
897
|
+
|
|
898
|
+
2. **아이콘 일관성**: 아이콘을 사용할 때는 일관된 크기와 스타일을 유지하세요.
|
|
899
|
+
|
|
900
|
+
```tsx
|
|
901
|
+
<MenuItem>
|
|
902
|
+
<EditIcon sx={{ mr: 1.5, fontSize: 'lg' }} />
|
|
903
|
+
편집
|
|
904
|
+
</MenuItem>
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
3. **논리적 그룹화**: 관련된 메뉴 아이템들은 ListDivider로 구분하세요.
|
|
908
|
+
|
|
909
|
+
4. **위험한 작업 구분**: 삭제와 같은 위험한 작업은 색상으로 구분하세요.
|
|
910
|
+
|
|
911
|
+
```tsx
|
|
912
|
+
<MenuItem color="danger">
|
|
913
|
+
<DeleteIcon sx={{ mr: 1 }} />
|
|
914
|
+
삭제
|
|
915
|
+
</MenuItem>
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
5. **적절한 메뉴 크기**: 너무 긴 메뉴는 스크롤을 적용하거나 서브메뉴로 나누세요.
|
|
919
|
+
|
|
920
|
+
```tsx
|
|
921
|
+
<Menu sx={{ maxHeight: 300, overflow: 'auto' }}>
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
6. **상태 피드백**: 선택된 아이템이나 현재 상태를 명확히 표시하세요.
|
|
925
|
+
|
|
926
|
+
7. **모바일 고려**: 터치 기기에서 사용하기 쉽도록 충분한 터치 영역을 제공하세요.
|
|
927
|
+
|
|
928
|
+
## Performance Considerations
|
|
929
|
+
|
|
930
|
+
1. **메뉴 지연 로딩**: 복잡한 메뉴는 필요할 때만 렌더링하세요.
|
|
931
|
+
|
|
932
|
+
2. **가상화**: 매우 긴 메뉴 목록에는 가상화를 고려하세요.
|
|
933
|
+
|
|
934
|
+
3. **메모이제이션**: 정적인 메뉴 아이템들은 메모이제이션을 활용하세요.
|
|
935
|
+
|
|
936
|
+
## Troubleshooting
|
|
937
|
+
|
|
938
|
+
### 흔한 문제들
|
|
939
|
+
|
|
940
|
+
1. **메뉴가 화면을 벗어남**
|
|
941
|
+
|
|
942
|
+
```tsx
|
|
943
|
+
<Menu placement="top-end"> {/* placement 조정 */}
|
|
944
|
+
```
|
|
945
|
+
|
|
946
|
+
2. **긴 메뉴 스크롤 문제**
|
|
947
|
+
|
|
948
|
+
```tsx
|
|
949
|
+
<Menu sx={{ maxHeight: 400, overflow: 'auto' }}>
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
3. **모바일에서 터치 영역 부족**
|
|
953
|
+
```tsx
|
|
954
|
+
<MenuItem sx={{ minHeight: 44 }}> {/* 최소 터치 영역 보장 */}
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
Menu와 MenuItem은 사용자 친화적이고 접근성이 뛰어난 메뉴 시스템을 구축하는 핵심 컴포넌트입니다. 적절히 활용하면 직관적이고 효율적인 사용자 인터페이스를 만들 수 있습니다.
|