or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-context.mdcontent-accessibility.mddialog-root.mdindex.mdportal-layout.mdtriggers-controls.md

advanced-context.mddocs/

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

```