0
# Advanced Context Management
1
2
Utilities for advanced use cases like nested dialogs, custom context scoping, and development-time warnings.
3
4
## Capabilities
5
6
### createDialogScope
7
8
Creates a scoped context for dialog components, enabling advanced patterns like nested dialogs or multiple dialog instances.
9
10
```typescript { .api }
11
/**
12
* Creates a scoped context for dialog components
13
* Enables advanced patterns like nested dialogs and multiple instances
14
* @returns Tuple of context scope and provider functions
15
*/
16
const createDialogScope: () => {
17
/**
18
* Creates a scoped provider for dialog context
19
* @param scope - The scope identifier for this dialog context
20
* @param scopeProps - Props to pass through to child contexts
21
*/
22
Provider: React.Provider<any>;
23
24
/**
25
* Hook to consume the scoped dialog context
26
* @param scope - The scope identifier to consume from
27
*/
28
useScope: (scope?: any) => any;
29
};
30
```
31
32
**Usage Examples:**
33
34
```typescript
35
import { createDialogScope, Dialog, DialogTrigger, DialogContent } from "@radix-ui/react-dialog";
36
37
// Create a custom scope for nested dialogs
38
const [createNestedDialogScope, useNestedDialogScope] = createDialogScope();
39
40
function NestedDialogs() {
41
const nestedScope = createNestedDialogScope();
42
43
return (
44
<Dialog>
45
<DialogTrigger>Open Parent Dialog</DialogTrigger>
46
<DialogContent>
47
<h2>Parent Dialog</h2>
48
<Dialog __scopeDialog={nestedScope}>
49
<DialogTrigger>Open Child Dialog</DialogTrigger>
50
<DialogContent>
51
<h3>Child Dialog</h3>
52
<p>This dialog is nested within the parent</p>
53
</DialogContent>
54
</Dialog>
55
</DialogContent>
56
</Dialog>
57
);
58
}
59
60
// Multiple independent dialog systems
61
function MultipleDialogSystems() {
62
const systemAScope = createDialogScope();
63
const systemBScope = createDialogScope();
64
65
return (
66
<div>
67
{/* Dialog System A */}
68
<Dialog __scopeDialog={systemAScope}>
69
<DialogTrigger>Open System A</DialogTrigger>
70
<DialogContent>
71
<p>Dialog from System A</p>
72
</DialogContent>
73
</Dialog>
74
75
{/* Dialog System B */}
76
<Dialog __scopeDialog={systemBScope}>
77
<DialogTrigger>Open System B</DialogTrigger>
78
<DialogContent>
79
<p>Dialog from System B</p>
80
</DialogContent>
81
</Dialog>
82
</div>
83
);
84
}
85
```
86
87
### WarningProvider
88
89
Context provider for development-time accessibility warnings and validation.
90
91
```typescript { .api }
92
/**
93
* Context provider for development-time accessibility warnings
94
* Provides configuration for warning messages and validation
95
* Internal component typically not used directly
96
*/
97
interface WarningContextValue {
98
contentName: string;
99
titleName: string;
100
docsSlug: string;
101
}
102
103
const WarningProvider: React.Provider<WarningContextValue>;
104
```
105
106
**Usage Examples:**
107
108
```typescript
109
// Typically used internally, but can be customized for advanced cases
110
import { WarningProvider } from "@radix-ui/react-dialog";
111
112
function CustomWarningProvider({ children }: { children: React.ReactNode }) {
113
const warningConfig = {
114
contentName: "CustomDialog",
115
titleName: "CustomTitle",
116
docsSlug: "custom-dialog"
117
};
118
119
return (
120
<WarningProvider value={warningConfig}>
121
{children}
122
</WarningProvider>
123
);
124
}
125
```
126
127
## Advanced Patterns
128
129
### Nested Dialogs
130
131
Create dialogs that can open other dialogs without conflicts:
132
133
```typescript
134
import {
135
Dialog,
136
DialogTrigger,
137
DialogContent,
138
DialogTitle,
139
createDialogScope
140
} from "@radix-ui/react-dialog";
141
142
function NestedDialogExample() {
143
// Create separate scopes for each dialog level
144
const [createLevel2Scope, useLevel2Scope] = createDialogScope();
145
const [createLevel3Scope, useLevel3Scope] = createDialogScope();
146
147
return (
148
<Dialog>
149
<DialogTrigger>Open Level 1</DialogTrigger>
150
<DialogContent>
151
<DialogTitle>Level 1 Dialog</DialogTitle>
152
153
<Dialog __scopeDialog={createLevel2Scope()}>
154
<DialogTrigger>Open Level 2</DialogTrigger>
155
<DialogContent>
156
<DialogTitle>Level 2 Dialog</DialogTitle>
157
158
<Dialog __scopeDialog={createLevel3Scope()}>
159
<DialogTrigger>Open Level 3</DialogTrigger>
160
<DialogContent>
161
<DialogTitle>Level 3 Dialog</DialogTitle>
162
<p>Deeply nested dialog</p>
163
</DialogContent>
164
</Dialog>
165
</DialogContent>
166
</Dialog>
167
</DialogContent>
168
</Dialog>
169
);
170
}
171
```
172
173
### Multiple Dialog Systems
174
175
Create independent dialog systems that don't interfere with each other:
176
177
```typescript
178
function MultiSystemExample() {
179
const settingsScope = createDialogScope();
180
const confirmationScope = createDialogScope();
181
182
return (
183
<div>
184
{/* Settings Dialog System */}
185
<div className="settings-section">
186
<Dialog __scopeDialog={settingsScope}>
187
<DialogTrigger>Settings</DialogTrigger>
188
<DialogContent>
189
<DialogTitle>Application Settings</DialogTitle>
190
{/* Settings content */}
191
</DialogContent>
192
</Dialog>
193
</div>
194
195
{/* Confirmation Dialog System */}
196
<div className="actions-section">
197
<Dialog __scopeDialog={confirmationScope}>
198
<DialogTrigger>Delete All</DialogTrigger>
199
<DialogContent>
200
<DialogTitle>Confirm Deletion</DialogTitle>
201
{/* Confirmation content */}
202
</DialogContent>
203
</Dialog>
204
</div>
205
</div>
206
);
207
}
208
```
209
210
### Custom Context Integration
211
212
Integrate dialog scoping with your own context systems:
213
214
```typescript
215
interface AppContextValue {
216
dialogScope: any;
217
theme: string;
218
}
219
220
const AppContext = React.createContext<AppContextValue | null>(null);
221
222
function AppWithCustomContext({ children }: { children: React.ReactNode }) {
223
const dialogScope = createDialogScope();
224
225
const contextValue = {
226
dialogScope,
227
theme: 'dark'
228
};
229
230
return (
231
<AppContext.Provider value={contextValue}>
232
{children}
233
</AppContext.Provider>
234
);
235
}
236
237
function DialogWithAppContext() {
238
const appContext = React.useContext(AppContext);
239
240
return (
241
<Dialog __scopeDialog={appContext?.dialogScope}>
242
<DialogTrigger>Open Contextual Dialog</DialogTrigger>
243
<DialogContent>
244
<DialogTitle>App Context Dialog</DialogTitle>
245
<p>This dialog uses the app's dialog scope</p>
246
</DialogContent>
247
</Dialog>
248
);
249
}
250
```
251
252
## Scope Prop Usage
253
254
All dialog components accept a `__scopeDialog` prop for custom scoping:
255
256
```typescript
257
// Scope applied to all components in the dialog tree
258
<Dialog __scopeDialog={customScope}>
259
<DialogTrigger __scopeDialog={customScope}>Open</DialogTrigger>
260
<DialogPortal __scopeDialog={customScope}>
261
<DialogOverlay __scopeDialog={customScope} />
262
<DialogContent __scopeDialog={customScope}>
263
<DialogTitle __scopeDialog={customScope}>Title</DialogTitle>
264
<DialogDescription __scopeDialog={customScope}>Description</DialogDescription>
265
<DialogClose __scopeDialog={customScope}>Close</DialogClose>
266
</DialogContent>
267
</DialogPortal>
268
</Dialog>
269
```
270
271
## Development Warnings
272
273
### Accessibility Warnings
274
275
In development mode, the dialog system provides warnings for:
276
277
- Missing DialogTitle components
278
- Missing DialogDescription when aria-describedby is expected
279
- Improper nesting or context usage
280
281
### Warning Customization
282
283
You can customize warning messages by providing your own WarningProvider:
284
285
```typescript
286
const customWarningContext = {
287
contentName: "MyDialog",
288
titleName: "MyDialogTitle",
289
docsSlug: "my-dialog"
290
};
291
292
<WarningProvider value={customWarningContext}>
293
<Dialog>
294
{/* Dialog components */}
295
</Dialog>
296
</WarningProvider>
297
```
298
299
## Best Practices
300
301
### When to Use Scoping
302
303
- **Nested Dialogs**: Always use scoping for dialogs within dialogs
304
- **Multiple Systems**: Use scoping when you have different types of dialogs
305
- **Component Libraries**: Use scoping to avoid conflicts with consumer code
306
- **Complex Apps**: Use scoping to isolate dialog contexts in different app sections
307
308
### Scope Management
309
310
- Create scopes at the highest level needed
311
- Don't create unnecessary scopes for simple use cases
312
- Pass scopes down through props or context
313
- Document your scoping strategy for team members
314
315
### Performance Considerations
316
317
- Scopes are lightweight and don't significantly impact performance
318
- Avoid creating new scopes on every render
319
- Memoize scope creation when necessary:
320
321
```typescript
322
const dialogScope = React.useMemo(() => createDialogScope(), []);
323
```