0
# Submenus
1
2
Components for creating nested dropdown menus with submenu triggers and content areas. These components enable complex menu hierarchies with multiple levels of navigation.
3
4
## Capabilities
5
6
### DropdownMenuSub (Sub)
7
8
Container component that manages the state and behavior of a submenu.
9
10
```typescript { .api }
11
/**
12
* Container for submenu functionality
13
* @param children - Child components (typically SubTrigger and SubContent)
14
* @param open - Controlled open state of the submenu
15
* @param defaultOpen - Default open state (uncontrolled)
16
* @param onOpenChange - Callback when submenu open state changes
17
*/
18
interface DropdownMenuSubProps {
19
children?: React.ReactNode;
20
open?: boolean;
21
defaultOpen?: boolean;
22
onOpenChange?(open: boolean): void;
23
}
24
25
const DropdownMenuSub: React.FC<DropdownMenuSubProps>;
26
```
27
28
**Usage Examples:**
29
30
```typescript
31
// Uncontrolled submenu
32
<DropdownMenu.Sub>
33
<DropdownMenu.SubTrigger>More Options</DropdownMenu.SubTrigger>
34
<DropdownMenu.SubContent>
35
<DropdownMenu.Item>Nested Option 1</DropdownMenu.Item>
36
<DropdownMenu.Item>Nested Option 2</DropdownMenu.Item>
37
</DropdownMenu.SubContent>
38
</DropdownMenu.Sub>
39
40
// Controlled submenu
41
const [subOpen, setSubOpen] = React.useState(false);
42
<DropdownMenu.Sub open={subOpen} onOpenChange={setSubOpen}>
43
<DropdownMenu.SubTrigger>Controlled Submenu</DropdownMenu.SubTrigger>
44
<DropdownMenu.SubContent>
45
<DropdownMenu.Item>Nested Item</DropdownMenu.Item>
46
</DropdownMenu.SubContent>
47
</DropdownMenu.Sub>
48
```
49
50
### DropdownMenuSubTrigger (SubTrigger)
51
52
Trigger component that opens a submenu when hovered or activated with keyboard.
53
54
```typescript { .api }
55
/**
56
* Trigger for opening submenu
57
* @param disabled - Whether the trigger is disabled
58
* @param textValue - Text value for typeahead functionality
59
* @param asChild - Compose with child element
60
*/
61
interface DropdownMenuSubTriggerProps {
62
disabled?: boolean;
63
textValue?: string;
64
asChild?: boolean;
65
children?: React.ReactNode;
66
}
67
68
const DropdownMenuSubTrigger: React.ForwardRefExoticComponent<DropdownMenuSubTriggerProps>;
69
```
70
71
**Usage Examples:**
72
73
```typescript
74
// Basic submenu trigger
75
<DropdownMenu.SubTrigger>
76
Share
77
<ChevronRightIcon />
78
</DropdownMenu.SubTrigger>
79
80
// Disabled submenu trigger
81
<DropdownMenu.SubTrigger disabled>
82
Unavailable Options
83
</DropdownMenu.SubTrigger>
84
85
// Custom submenu trigger using asChild
86
<DropdownMenu.SubTrigger asChild>
87
<button className="custom-submenu-trigger">
88
<ShareIcon />
89
Share Options
90
<ArrowIcon />
91
</button>
92
</DropdownMenu.SubTrigger>
93
```
94
95
### DropdownMenuSubContent (SubContent)
96
97
Content container for submenu items that appears when the submenu is triggered.
98
99
```typescript { .api }
100
/**
101
* Content container for submenu items
102
* Similar to DropdownMenuContent but for nested menus
103
* @param loop - Whether focus should loop when navigating
104
* @param onEscapeKeyDown - Callback when Escape key is pressed
105
* @param onKeyDown - Callback for key events
106
* @param forceMount - Force mounting regardless of open state
107
* @param container - Container element for portaling
108
*/
109
interface DropdownMenuSubContentProps {
110
loop?: boolean;
111
onEscapeKeyDown?: (event: KeyboardEvent) => void;
112
onKeyDown?: (event: KeyboardEvent) => void;
113
forceMount?: boolean;
114
container?: HTMLElement;
115
children?: React.ReactNode;
116
}
117
118
const DropdownMenuSubContent: React.ForwardRefExoticComponent<DropdownMenuSubContentProps>;
119
```
120
121
**Usage Examples:**
122
123
```typescript
124
// Basic submenu content
125
<DropdownMenu.SubContent>
126
<DropdownMenu.Item>Copy Link</DropdownMenu.Item>
127
<DropdownMenu.Item>Email</DropdownMenu.Item>
128
<DropdownMenu.Item>Print</DropdownMenu.Item>
129
</DropdownMenu.SubContent>
130
131
// Submenu content with custom behavior
132
<DropdownMenu.SubContent
133
loop={false}
134
onEscapeKeyDown={(e) => console.log('Escaping submenu')}
135
>
136
<DropdownMenu.Item>Option A</DropdownMenu.Item>
137
<DropdownMenu.Item>Option B</DropdownMenu.Item>
138
</DropdownMenu.SubContent>
139
```
140
141
## Complete Submenu Example
142
143
```typescript
144
function MultiLevelDropdownMenu() {
145
return (
146
<DropdownMenu.Root>
147
<DropdownMenu.Trigger>File</DropdownMenu.Trigger>
148
149
<DropdownMenu.Portal>
150
<DropdownMenu.Content>
151
<DropdownMenu.Item>New File</DropdownMenu.Item>
152
<DropdownMenu.Item>Open</DropdownMenu.Item>
153
154
<DropdownMenu.Separator />
155
156
{/* First level submenu */}
157
<DropdownMenu.Sub>
158
<DropdownMenu.SubTrigger>
159
Recent Files
160
<ChevronRightIcon />
161
</DropdownMenu.SubTrigger>
162
<DropdownMenu.SubContent>
163
<DropdownMenu.Item>document1.txt</DropdownMenu.Item>
164
<DropdownMenu.Item>document2.txt</DropdownMenu.Item>
165
166
{/* Second level submenu */}
167
<DropdownMenu.Sub>
168
<DropdownMenu.SubTrigger>
169
More Recent
170
<ChevronRightIcon />
171
</DropdownMenu.SubTrigger>
172
<DropdownMenu.SubContent>
173
<DropdownMenu.Item>old-file1.txt</DropdownMenu.Item>
174
<DropdownMenu.Item>old-file2.txt</DropdownMenu.Item>
175
</DropdownMenu.SubContent>
176
</DropdownMenu.Sub>
177
</DropdownMenu.SubContent>
178
</DropdownMenu.Sub>
179
180
<DropdownMenu.Sub>
181
<DropdownMenu.SubTrigger>
182
Export
183
<ChevronRightIcon />
184
</DropdownMenu.SubTrigger>
185
<DropdownMenu.SubContent>
186
<DropdownMenu.Item>Export as PDF</DropdownMenu.Item>
187
<DropdownMenu.Item>Export as HTML</DropdownMenu.Item>
188
<DropdownMenu.Item>Export as Markdown</DropdownMenu.Item>
189
</DropdownMenu.SubContent>
190
</DropdownMenu.Sub>
191
192
<DropdownMenu.Separator />
193
194
<DropdownMenu.Item>Close</DropdownMenu.Item>
195
</DropdownMenu.Content>
196
</DropdownMenu.Portal>
197
</DropdownMenu.Root>
198
);
199
}
200
```
201
202
## Keyboard Navigation
203
204
Submenus support full keyboard navigation:
205
206
- **Arrow Keys**: Navigate between items and into/out of submenus
207
- **Enter/Space**: Activate items or open submenus
208
- **Escape**: Close current submenu level
209
- **Home/End**: Jump to first/last item in current level
210
- **Letter keys**: Type-ahead search within current level
211
212
## Accessibility Features
213
214
- Proper ARIA attributes for nested menu structure
215
- Screen reader announcements for submenu state changes
216
- Focus management across menu levels
217
- Keyboard navigation between parent and child menus
218
- Automatic focus return when closing submenus
219
220
## Component Aliases
221
222
```typescript { .api }
223
// Short aliases for composition patterns
224
const Sub = DropdownMenuSub;
225
const SubTrigger = DropdownMenuSubTrigger;
226
const SubContent = DropdownMenuSubContent;
227
```
228
229
These submenu components enable the creation of complex, multi-level dropdown menus while maintaining full accessibility and keyboard navigation support.