0
# Interactive Components
1
2
Specialized components for drawer interaction and accessibility. These components provide enhanced functionality for user interaction and ensure proper accessibility support.
3
4
## Capabilities
5
6
### Drawer.Handle
7
8
Draggable handle component that provides a visual and interactive element for users to drag the drawer. The handle enables gesture-based interaction and can prevent snap point cycling.
9
10
```typescript { .api }
11
/**
12
* Draggable handle component for drawer interaction
13
* @param props - Handle component props
14
* @param ref - Forwarded ref to the handle element
15
* @returns Handle component for drawer dragging
16
*/
17
interface Drawer.Handle extends React.ForwardRefExoticComponent<HandleProps> {}
18
19
interface HandleProps extends React.HTMLAttributes<HTMLDivElement> {
20
/** Prevent snap point cycling when dragging the handle */
21
preventCycle?: boolean;
22
}
23
```
24
25
**Usage Examples:**
26
27
```typescript
28
// Basic handle
29
<Drawer.Content>
30
<Drawer.Handle />
31
<div>Drawer content...</div>
32
</Drawer.Content>
33
34
// Handle with custom styling
35
<Drawer.Handle className="drawer-handle" />
36
37
// Handle that prevents cycling through snap points
38
<Drawer.Handle preventCycle />
39
40
// Handle with custom content
41
<Drawer.Handle>
42
<div className="handle-bar" />
43
</Drawer.Handle>
44
```
45
46
### Drawer.Close
47
48
Element that closes the drawer when activated. Can be applied to any interactive element to give it close functionality.
49
50
```typescript { .api }
51
/**
52
* Element that closes the drawer when activated
53
*/
54
interface Drawer.Close extends typeof DialogPrimitive.Close {}
55
```
56
57
**Usage Examples:**
58
59
```typescript
60
// Basic close button
61
<Drawer.Close>Close</Drawer.Close>
62
63
// Close button with custom styling
64
<Drawer.Close className="close-button">×</Drawer.Close>
65
66
// Close applied to custom element
67
<Drawer.Close asChild>
68
<button className="my-close-button">
69
<Icon name="x" />
70
</button>
71
</Drawer.Close>
72
73
// Multiple close triggers
74
<div>
75
<Drawer.Close>Cancel</Drawer.Close>
76
<Drawer.Close>Done</Drawer.Close>
77
</div>
78
```
79
80
### Drawer.Title
81
82
Accessible title element for the drawer. This component provides proper semantic markup and screen reader support for the drawer's title.
83
84
```typescript { .api }
85
/**
86
* Accessible title element for drawer
87
*/
88
interface Drawer.Title extends typeof DialogPrimitive.Title {}
89
```
90
91
**Usage Examples:**
92
93
```typescript
94
// Basic title
95
<Drawer.Title>Settings</Drawer.Title>
96
97
// Title with custom styling
98
<Drawer.Title className="drawer-title">
99
User Profile
100
</Drawer.Title>
101
102
// Title as different heading level
103
<Drawer.Title asChild>
104
<h1>Main Drawer</h1>
105
</Drawer.Title>
106
```
107
108
### Drawer.Description
109
110
Accessible description element for the drawer. This component provides additional context and screen reader support for describing the drawer's purpose or contents.
111
112
```typescript { .api }
113
/**
114
* Accessible description element for drawer
115
*/
116
interface Drawer.Description extends typeof DialogPrimitive.Description {}
117
```
118
119
**Usage Examples:**
120
121
```typescript
122
// Basic description
123
<Drawer.Description>
124
Configure your account settings and preferences.
125
</Drawer.Description>
126
127
// Description with custom styling
128
<Drawer.Description className="drawer-description">
129
This drawer contains important information about your account.
130
</Drawer.Description>
131
132
// Description as different element
133
<Drawer.Description asChild>
134
<p className="custom-description">
135
Complete the form below to continue.
136
</p>
137
</Drawer.Description>
138
```
139
140
### Drawer.NestedRoot
141
142
Special root component for nested drawers. This component enables creating drawers within drawers while maintaining proper state management and interaction.
143
144
```typescript { .api }
145
/**
146
* Root component for nested drawers
147
* @param props - Same as DialogProps but with nested-specific behavior
148
* @returns Nested root component
149
*/
150
interface Drawer.NestedRoot extends React.Component<DialogProps> {}
151
```
152
153
**Usage Examples:**
154
155
```typescript
156
// Nested drawer structure
157
<Drawer.Root>
158
<Drawer.Trigger>Open Main Drawer</Drawer.Trigger>
159
<Drawer.Portal>
160
<Drawer.Content>
161
<Drawer.Title>Main Drawer</Drawer.Title>
162
163
{/* Nested drawer */}
164
<Drawer.NestedRoot>
165
<Drawer.Trigger>Open Nested</Drawer.Trigger>
166
<Drawer.Portal>
167
<Drawer.Content>
168
<Drawer.Title>Nested Drawer</Drawer.Title>
169
<p>This is nested content</p>
170
<Drawer.Close>Close Nested</Drawer.Close>
171
</Drawer.Content>
172
</Drawer.Portal>
173
</Drawer.NestedRoot>
174
175
<Drawer.Close>Close Main</Drawer.Close>
176
</Drawer.Content>
177
</Drawer.Portal>
178
</Drawer.Root>
179
180
// Multiple nested levels
181
<Drawer.Root>
182
<Drawer.Trigger>Level 1</Drawer.Trigger>
183
<Drawer.Portal>
184
<Drawer.Content>
185
<Drawer.NestedRoot>
186
<Drawer.Trigger>Level 2</Drawer.Trigger>
187
<Drawer.Portal>
188
<Drawer.Content>
189
<Drawer.NestedRoot>
190
<Drawer.Trigger>Level 3</Drawer.Trigger>
191
<Drawer.Portal>
192
<Drawer.Content>
193
<p>Deeply nested content</p>
194
</Drawer.Content>
195
</Drawer.Portal>
196
</Drawer.NestedRoot>
197
</Drawer.Content>
198
</Drawer.Portal>
199
</Drawer.NestedRoot>
200
</Drawer.Content>
201
</Drawer.Portal>
202
</Drawer.Root>
203
```
204
205
## Common Usage Patterns
206
207
### Complete Drawer with All Interactive Components
208
209
```typescript
210
function CompleteDrawer() {
211
return (
212
<Drawer.Root>
213
<Drawer.Trigger>Open Settings</Drawer.Trigger>
214
<Drawer.Portal>
215
<Drawer.Overlay />
216
<Drawer.Content>
217
<Drawer.Handle />
218
219
<div className="drawer-header">
220
<Drawer.Title>Account Settings</Drawer.Title>
221
<Drawer.Description>
222
Manage your account preferences and settings
223
</Drawer.Description>
224
<Drawer.Close>×</Drawer.Close>
225
</div>
226
227
<div className="drawer-body">
228
{/* Settings content */}
229
<form>
230
{/* Form fields */}
231
</form>
232
</div>
233
234
<div className="drawer-footer">
235
<Drawer.Close>Cancel</Drawer.Close>
236
<Drawer.Close>Save Changes</Drawer.Close>
237
</div>
238
</Drawer.Content>
239
</Drawer.Portal>
240
</Drawer.Root>
241
);
242
}
243
```
244
245
### Accessibility Best Practices
246
247
```typescript
248
function AccessibleDrawer() {
249
return (
250
<Drawer.Root>
251
<Drawer.Trigger aria-label="Open navigation menu">
252
Menu
253
</Drawer.Trigger>
254
<Drawer.Portal>
255
<Drawer.Overlay />
256
<Drawer.Content aria-describedby="drawer-description">
257
<Drawer.Handle aria-label="Drag to resize drawer" />
258
259
{/* Always include title for screen readers */}
260
<Drawer.Title>Navigation Menu</Drawer.Title>
261
262
{/* Description provides context */}
263
<Drawer.Description id="drawer-description">
264
Main navigation options for the application
265
</Drawer.Description>
266
267
<nav>
268
{/* Navigation items */}
269
</nav>
270
271
<Drawer.Close aria-label="Close navigation menu">
272
Close
273
</Drawer.Close>
274
</Drawer.Content>
275
</Drawer.Portal>
276
</Drawer.Root>
277
);
278
}
279
```