0
# Interactive Elements
1
2
Trigger and link components that handle user interactions with keyboard and pointer support.
3
4
## Capabilities
5
6
### NavigationMenuTrigger
7
8
Interactive button element that triggers the display of associated navigation content, with built-in keyboard and pointer event handling.
9
10
```typescript { .api }
11
/**
12
* Interactive trigger button for menu items with accessibility support
13
* Handles click, hover, and keyboard interactions to open/close menu content
14
* Automatically manages ARIA attributes and focus states
15
*/
16
const NavigationMenuTrigger: React.ForwardRefExoticComponent<
17
NavigationMenuTriggerProps & React.RefAttributes<HTMLButtonElement>
18
>;
19
20
interface NavigationMenuTriggerProps
21
extends React.ComponentPropsWithoutRef<"button"> {}
22
```
23
24
**Key Features:**
25
- Automatic ARIA attributes (`aria-expanded`, `aria-controls`)
26
- Keyboard navigation (Enter, Space, Arrow keys)
27
- Hover delay and skip delay behavior
28
- Focus management and visual states
29
- Pointer event handling (mouse, touch)
30
31
**Usage Examples:**
32
33
```typescript
34
import {
35
NavigationMenu,
36
NavigationMenuList,
37
NavigationMenuItem,
38
NavigationMenuTrigger,
39
NavigationMenuContent
40
} from "@radix-ui/react-navigation-menu";
41
42
function TriggerExample() {
43
return (
44
<NavigationMenu>
45
<NavigationMenuList>
46
<NavigationMenuItem>
47
<NavigationMenuTrigger className="nav-trigger">
48
Products
49
</NavigationMenuTrigger>
50
<NavigationMenuContent>
51
Product information here
52
</NavigationMenuContent>
53
</NavigationMenuItem>
54
55
<NavigationMenuItem>
56
<NavigationMenuTrigger
57
onPointerEnter={() => console.log("Hover started")}
58
onPointerLeave={() => console.log("Hover ended")}
59
onClick={() => console.log("Clicked")}
60
>
61
Services
62
</NavigationMenuTrigger>
63
<NavigationMenuContent>
64
Service information here
65
</NavigationMenuContent>
66
</NavigationMenuItem>
67
</NavigationMenuList>
68
</NavigationMenu>
69
);
70
}
71
72
// Custom trigger with disabled state
73
function DisabledTriggerExample() {
74
return (
75
<NavigationMenuItem>
76
<NavigationMenuTrigger disabled>
77
Coming Soon
78
</NavigationMenuTrigger>
79
</NavigationMenuItem>
80
);
81
}
82
```
83
84
### NavigationMenuLink
85
86
Navigation link component with active state support and custom selection event handling.
87
88
```typescript { .api }
89
/**
90
* Navigation link component with active state and selection events
91
* @param active - Whether this link represents the current page/section
92
* @param onSelect - Custom selection event handler (called before navigation)
93
*/
94
const NavigationMenuLink: React.ForwardRefExoticComponent<
95
NavigationMenuLinkProps & React.RefAttributes<HTMLAnchorElement>
96
>;
97
98
interface NavigationMenuLinkProps
99
extends Omit<React.ComponentPropsWithoutRef<"a">, "onSelect"> {
100
active?: boolean;
101
onSelect?: (event: Event) => void;
102
}
103
```
104
105
**Key Features:**
106
- Active state with `aria-current="page"` when active
107
- Custom selection event system
108
- Focus group integration for keyboard navigation
109
- Automatic menu dismissal on selection
110
- Support for both internal and external links
111
112
**Usage Examples:**
113
114
```typescript
115
import {
116
NavigationMenu,
117
NavigationMenuList,
118
NavigationMenuItem,
119
NavigationMenuLink,
120
NavigationMenuTrigger,
121
NavigationMenuContent
122
} from "@radix-ui/react-navigation-menu";
123
124
function LinkExample() {
125
const [currentPage, setCurrentPage] = React.useState("/home");
126
127
return (
128
<NavigationMenu>
129
<NavigationMenuList>
130
{/* Direct navigation link */}
131
<NavigationMenuItem>
132
<NavigationMenuLink
133
href="/home"
134
active={currentPage === "/home"}
135
onSelect={(event) => {
136
console.log("Navigating to home");
137
setCurrentPage("/home");
138
}}
139
>
140
Home
141
</NavigationMenuLink>
142
</NavigationMenuItem>
143
144
{/* Links within content */}
145
<NavigationMenuItem>
146
<NavigationMenuTrigger>Products</NavigationMenuTrigger>
147
<NavigationMenuContent>
148
<NavigationMenuLink
149
href="/products/web"
150
active={currentPage === "/products/web"}
151
>
152
Web Development
153
</NavigationMenuLink>
154
<NavigationMenuLink
155
href="/products/mobile"
156
active={currentPage === "/products/mobile"}
157
>
158
Mobile Apps
159
</NavigationMenuLink>
160
</NavigationMenuContent>
161
</NavigationMenuItem>
162
163
{/* External link */}
164
<NavigationMenuItem>
165
<NavigationMenuLink
166
href="https://example.com"
167
target="_blank"
168
rel="noopener noreferrer"
169
onSelect={(event) => {
170
console.log("Opening external link");
171
}}
172
>
173
External Resource
174
</NavigationMenuLink>
175
</NavigationMenuItem>
176
</NavigationMenuList>
177
</NavigationMenu>
178
);
179
}
180
181
// Link with custom selection handling
182
function CustomLinkExample() {
183
return (
184
<NavigationMenuItem>
185
<NavigationMenuLink
186
href="/custom"
187
onSelect={(event) => {
188
// Prevent default navigation
189
event.preventDefault();
190
191
// Custom handling (e.g., modal, confirmation)
192
if (confirm("Are you sure you want to navigate?")) {
193
window.location.href = "/custom";
194
}
195
}}
196
>
197
Custom Link
198
</NavigationMenuLink>
199
</NavigationMenuItem>
200
);
201
}
202
```
203
204
## Event Handling
205
206
Both trigger and link components support comprehensive event handling:
207
208
### Trigger Events
209
210
```typescript
211
// Pointer events
212
onPointerEnter?: (event: React.PointerEvent) => void;
213
onPointerMove?: (event: React.PointerEvent) => void;
214
onPointerLeave?: (event: React.PointerEvent) => void;
215
216
// Click and keyboard events
217
onClick?: (event: React.MouseEvent) => void;
218
onKeyDown?: (event: React.KeyboardEvent) => void;
219
220
// Focus events
221
onFocus?: (event: React.FocusEvent) => void;
222
onBlur?: (event: React.FocusEvent) => void;
223
```
224
225
### Link Events
226
227
```typescript
228
// Custom selection event
229
onSelect?: (event: Event) => void;
230
231
// Standard anchor events
232
onClick?: (event: React.MouseEvent) => void;
233
onKeyDown?: (event: React.KeyboardEvent) => void;
234
onFocus?: (event: React.FocusEvent) => void;
235
```
236
237
## Accessibility Features
238
239
- **ARIA Support**: Automatic ARIA attributes for screen readers
240
- **Keyboard Navigation**: Full keyboard support with arrow keys, Enter, Space, Tab
241
- **Focus Management**: Proper focus order and visual focus indicators
242
- **Active States**: Clear indication of current page/section
243
- **Selection Events**: Custom event system for enhanced interaction tracking
244
245
## Data Attributes
246
247
Interactive elements expose data attributes for styling:
248
249
### NavigationMenuTrigger Data Attributes
250
251
```css
252
[data-state="open"] { /* Trigger is active (content is open) */ }
253
[data-state="closed"] { /* Trigger is inactive */ }
254
[data-disabled] { /* Trigger is disabled */ }
255
```
256
257
**Usage Example:**
258
259
```css
260
.nav-trigger[data-state="open"] {
261
background-color: var(--accent-color);
262
color: white;
263
}
264
265
.nav-trigger[data-disabled] {
266
opacity: 0.5;
267
cursor: not-allowed;
268
}
269
```
270
271
### NavigationMenuLink Data Attributes
272
273
```css
274
[data-active] { /* Link represents the current page */ }
275
```
276
277
**Usage Example:**
278
279
```css
280
.nav-link[data-active] {
281
font-weight: bold;
282
color: var(--primary-color);
283
}
284
285
.nav-link[data-active]::after {
286
content: "";
287
position: absolute;
288
bottom: 0;
289
left: 0;
290
right: 0;
291
height: 2px;
292
background: var(--primary-color);
293
}
294
```