0
# Layout & Positioning
1
2
Components for popups, modals, overlays, and DOM portal management with advanced positioning using Floating UI and comprehensive accessibility features.
3
4
## Capabilities
5
6
### Modal Component
7
8
Modal dialog component with backdrop, focus management, and accessibility features.
9
10
```typescript { .api }
11
/**
12
* Modal dialog component with backdrop and focus management
13
* @param props - Modal properties including open state and event handlers
14
* @returns Modal element with proper accessibility and focus trapping
15
*/
16
function Modal(props: ModalProps): JSX.Element;
17
18
interface ModalProps {
19
/** Single child element to render in modal */
20
children: React.ReactElement;
21
/** Whether to wait for transition before closing */
22
closeAfterTransition?: boolean;
23
/** Container element or function returning container */
24
container?: HTMLElement | (() => HTMLElement | null) | null;
25
/** Whether to disable auto focus on open */
26
disableAutoFocus?: boolean;
27
/** Whether to disable focus enforcement */
28
disableEnforceFocus?: boolean;
29
/** Whether to disable escape key handling */
30
disableEscapeKeyDown?: boolean;
31
/** Whether to disable portal rendering */
32
disablePortal?: boolean;
33
/** Whether to disable focus restoration on close */
34
disableRestoreFocus?: boolean;
35
/** Whether to disable scroll lock */
36
disableScrollLock?: boolean;
37
/** Whether to hide backdrop */
38
hideBackdrop?: boolean;
39
/** Whether to keep mounted when closed */
40
keepMounted?: boolean;
41
/** Close event handler */
42
onClose?: (event: {}, reason: ModalCloseReason) => void;
43
/** Transition enter handler */
44
onTransitionEnter?: () => void;
45
/** Transition exited handler */
46
onTransitionExited?: () => void;
47
/** Whether modal is open */
48
open: boolean;
49
}
50
51
type ModalCloseReason = 'escapeKeyDown' | 'backdropClick';
52
53
// Modal manager for handling multiple modals
54
declare class ModalManager {
55
add(modal: any, container: HTMLElement): number;
56
remove(modal: any): number;
57
isTopModal(modal: any): boolean;
58
}
59
```
60
61
**Usage Examples:**
62
63
```typescript
64
import { Modal } from "@mui/base/Modal";
65
66
// Basic modal
67
<Modal
68
open={isOpen}
69
onClose={() => setIsOpen(false)}
70
>
71
<div className="modal-content">
72
<h2>Modal Title</h2>
73
<p>Modal content goes here.</p>
74
<button onClick={() => setIsOpen(false)}>Close</button>
75
</div>
76
</Modal>
77
78
// Modal with custom backdrop behavior
79
<Modal
80
open={isOpen}
81
onClose={(event, reason) => {
82
if (reason === 'backdropClick') {
83
console.log('Closed by backdrop click');
84
}
85
setIsOpen(false);
86
}}
87
disableEscapeKeyDown
88
>
89
<div className="modal-content">
90
<p>This modal can only be closed by clicking backdrop</p>
91
</div>
92
</Modal>
93
```
94
95
### Popup Component (Unstable)
96
97
Floating popup component using Floating UI for advanced positioning.
98
99
```typescript { .api }
100
/**
101
* Floating popup component using Floating UI for positioning
102
* @param props - Popup properties including anchor and placement
103
* @returns Popup element with advanced positioning capabilities
104
*/
105
function Unstable_Popup(props: PopupProps): JSX.Element;
106
107
interface PopupProps {
108
/** Anchor element for positioning */
109
anchor?: VirtualElement | (() => VirtualElement) | null;
110
/** Popup content */
111
children?: React.ReactNode | ((props: PopupChildrenProps) => React.ReactNode);
112
/** Container element for portal */
113
container?: HTMLElement | null | (() => HTMLElement | null);
114
/** Whether to disable portal rendering */
115
disablePortal?: boolean;
116
/** Whether to keep mounted when closed */
117
keepMounted?: boolean;
118
/** Floating UI middleware array */
119
middleware?: Array<Middleware | null | undefined | false>;
120
/** Offset from anchor element */
121
offset?: number | Options;
122
/** Whether popup is visible */
123
open?: boolean;
124
/** Popup placement relative to anchor */
125
placement?: Placement;
126
/** Positioning strategy */
127
strategy?: 'absolute' | 'fixed';
128
}
129
130
interface PopupChildrenProps {
131
placement: Placement;
132
arrowRef: React.RefCallback<Element>;
133
arrowProps: React.HTMLProps<HTMLElement>;
134
}
135
136
// Popup context for accessing popup state
137
const PopupContext: React.Context<PopupContextValue | null>;
138
139
interface PopupContextValue {
140
open: boolean;
141
setOpen: (open: boolean) => void;
142
placement: Placement;
143
anchor: VirtualElement | null;
144
setAnchor: (anchor: VirtualElement | null) => void;
145
}
146
```
147
148
### Popper Component
149
150
Legacy popup component using Popper.js for positioning (consider using Unstable_Popup for new projects).
151
152
```typescript { .api }
153
/**
154
* Legacy popup component using Popper.js for positioning
155
* @param props - Popper properties including anchor element and placement
156
* @returns Popper element with Popper.js positioning
157
*/
158
function Popper(props: PopperProps): JSX.Element;
159
160
interface PopperProps {
161
/** Anchor element for positioning */
162
anchorEl?: null | VirtualElement | (() => VirtualElement);
163
/** Popper content */
164
children?: React.ReactNode | ((props: PopperChildrenProps) => React.ReactNode);
165
/** Container element for portal */
166
container?: HTMLElement | (() => HTMLElement | null) | null;
167
/** Text direction for placement calculations */
168
direction?: 'ltr' | 'rtl';
169
/** Whether to disable portal rendering */
170
disablePortal?: boolean;
171
/** Whether to keep mounted when closed */
172
keepMounted?: boolean;
173
/** Popper.js modifiers */
174
modifiers?: ReadonlyArray<Modifier<any, any>>;
175
/** Whether popper is visible */
176
open: boolean;
177
/** Popper placement */
178
placement?: PopperPlacementType;
179
/** Popper.js options */
180
popperOptions?: Partial<Options>;
181
/** Ref to Popper.js instance */
182
popperRef?: React.Ref<Instance>;
183
/** Whether to use transition */
184
transition?: boolean;
185
}
186
187
interface PopperChildrenProps {
188
placement: PopperPlacementType;
189
TransitionProps?: {
190
in: boolean;
191
onEnter: () => void;
192
onExited: () => void;
193
};
194
}
195
196
type PopperPlacementType =
197
| 'auto-end'
198
| 'auto-start'
199
| 'auto'
200
| 'bottom-end'
201
| 'bottom-start'
202
| 'bottom'
203
| 'left-end'
204
| 'left-start'
205
| 'left'
206
| 'right-end'
207
| 'right-start'
208
| 'right'
209
| 'top-end'
210
| 'top-start'
211
| 'top';
212
```
213
214
### Portal Component
215
216
Renders children into a different part of the DOM tree.
217
218
```typescript { .api }
219
/**
220
* Renders children into different part of DOM tree
221
* @param props - Portal properties including container and children
222
* @returns Portal that renders children in specified container
223
*/
224
function Portal(props: PortalProps): React.ReactPortal | null;
225
226
interface PortalProps {
227
/** Content to render in portal */
228
children?: React.ReactNode;
229
/** DOM element to render children into */
230
container?: Element | (() => Element | null) | null;
231
/** Whether to disable portal (render in normal location) */
232
disablePortal?: boolean;
233
}
234
```
235
236
**Usage Examples:**
237
238
```typescript
239
import { Portal } from "@mui/base/Portal";
240
241
// Basic portal
242
<Portal>
243
<div>This will render at document.body</div>
244
</Portal>
245
246
// Portal with custom container
247
<Portal container={() => document.getElementById('modal-root')}>
248
<div>This will render in #modal-root</div>
249
</Portal>
250
251
// Conditional portal
252
<Portal disablePortal={!usePortal}>
253
<div>This may or may not use portal based on usePortal state</div>
254
</Portal>
255
```
256
257
### FocusTrap Component
258
259
Manages focus within a container element for accessibility.
260
261
```typescript { .api }
262
/**
263
* Traps focus within container element for accessibility
264
* @param props - Focus trap properties including open state and options
265
* @returns Focus trap wrapper around single child element
266
*/
267
function FocusTrap(props: FocusTrapProps): JSX.Element;
268
269
interface FocusTrapProps {
270
/** Single child element to wrap with focus trap */
271
children: React.ReactElement;
272
/** Whether to disable auto focus on mount */
273
disableAutoFocus?: boolean;
274
/** Whether to disable focus enforcement */
275
disableEnforceFocus?: boolean;
276
/** Whether to disable focus restoration on unmount */
277
disableRestoreFocus?: boolean;
278
/** Function to get tabbable elements */
279
getTabbable?: () => HTMLElement[];
280
/** Function determining if focus trap is enabled */
281
isEnabled?: () => boolean;
282
/** Whether focus trap is active */
283
open: boolean;
284
}
285
```
286
287
### Snackbar Component
288
289
Toast notification component with auto-hide functionality.
290
291
```typescript { .api }
292
/**
293
* Toast notification component with auto-hide functionality
294
* @param props - Snackbar properties including open state and duration
295
* @returns Snackbar element with notification display
296
*/
297
function Snackbar<RootComponentType extends React.ElementType = "div">(
298
props: SnackbarProps<RootComponentType>
299
): JSX.Element;
300
301
interface SnackbarProps<RootComponentType extends React.ElementType = "div">
302
extends PolymorphicProps<SnackbarTypeMap, RootComponentType> {
303
/** Time in milliseconds to auto-hide (default: null) */
304
autoHideDuration?: number | null;
305
/** Snackbar content */
306
children?: React.ReactNode;
307
/** Whether snackbar is fully exited from view */
308
exited?: boolean;
309
/** Close event handler */
310
onClose?: (event: Event | React.SyntheticEvent<any> | null, reason: SnackbarCloseReason) => void;
311
/** Whether snackbar is visible */
312
open?: boolean;
313
/** Time left before auto-hide when resuming */
314
resumeHideDuration?: number;
315
}
316
317
type SnackbarCloseReason = 'timeout' | 'clickaway' | 'escapeKeyDown';
318
```
319
320
**Usage Examples:**
321
322
```typescript
323
import { Snackbar } from "@mui/base/Snackbar";
324
325
// Basic snackbar
326
<Snackbar
327
open={showNotification}
328
autoHideDuration={4000}
329
onClose={() => setShowNotification(false)}
330
>
331
<div className="snackbar-content">
332
Operation completed successfully!
333
</div>
334
</Snackbar>
335
336
// Snackbar with close reason handling
337
<Snackbar
338
open={showError}
339
onClose={(event, reason) => {
340
if (reason === 'timeout') {
341
console.log('Auto-closed after timeout');
342
}
343
setShowError(false);
344
}}
345
>
346
<div className="error-snackbar">
347
<span>Error occurred!</span>
348
<button onClick={() => setShowError(false)}>×</button>
349
</div>
350
</Snackbar>
351
```
352
353
### Transitions
354
355
CSS transition and animation wrapper components.
356
357
```typescript { .api }
358
/**
359
* CSS transition wrapper component
360
* @param props - CSS transition properties including class names
361
* @returns Element with CSS transition support
362
*/
363
function CssTransition(props: CssTransitionProps): JSX.Element;
364
365
interface CssTransitionProps {
366
/** Content to animate */
367
children?: React.ReactNode;
368
/** Base CSS class name */
369
className?: string;
370
/** CSS class applied when entering */
371
enterClassName?: string;
372
/** CSS class applied when exiting */
373
exitClassName?: string;
374
/** Property name to determine transition end */
375
lastTransitionedPropertyOnExit?: string;
376
}
377
378
/**
379
* CSS animation wrapper component
380
* @param props - CSS animation properties including animation names
381
* @returns Element with CSS animation support
382
*/
383
function CssAnimation(props: CssAnimationProps): JSX.Element;
384
385
interface CssAnimationProps {
386
/** Content to animate */
387
children?: React.ReactNode;
388
/** Base CSS class name */
389
className?: string;
390
/** CSS animation name for enter */
391
enterAnimationName?: string;
392
/** CSS class applied when entering */
393
enterClassName?: string;
394
/** CSS animation name for exit */
395
exitAnimationName?: string;
396
/** CSS class applied when exiting */
397
exitClassName?: string;
398
}
399
```
400
401
### ClickAwayListener
402
403
Utility component for detecting clicks outside wrapped element.
404
405
```typescript { .api }
406
/**
407
* Detects clicks outside wrapped element
408
* @param props - Click away listener properties including callback
409
* @returns Wrapper that detects outside clicks
410
*/
411
function ClickAwayListener(props: ClickAwayListenerProps): JSX.Element;
412
413
interface ClickAwayListenerProps {
414
/** Single child element to monitor for outside clicks */
415
children: React.ReactElement;
416
/** Whether to ignore React tree for click detection */
417
disableReactTree?: boolean;
418
/** Mouse event type to listen for */
419
mouseEvent?: 'onClick' | 'onMouseDown' | 'onMouseUp' | false;
420
/** Callback fired when click occurs outside */
421
onClickAway: (event: MouseEvent | TouchEvent) => void;
422
/** Touch event type to listen for */
423
touchEvent?: 'onTouchStart' | 'onTouchEnd' | false;
424
}
425
```
426
427
### NoSsr Component
428
429
Prevents server-side rendering of children components.
430
431
```typescript { .api }
432
/**
433
* Prevents server-side rendering of children
434
* @param props - NoSsr properties including fallback content
435
* @returns Wrapper that conditionally renders children on client
436
*/
437
function NoSsr(props: NoSsrProps): JSX.Element;
438
439
interface NoSsrProps {
440
/** Content to render on client side only */
441
children?: React.ReactNode;
442
/** Whether to defer rendering until after first client render */
443
defer?: boolean;
444
/** Placeholder content during SSR */
445
fallback?: React.ReactNode;
446
}
447
```
448
449
### TextareaAutosize Component
450
451
Textarea that automatically adjusts height based on content.
452
453
```typescript { .api }
454
/**
455
* Textarea that automatically adjusts height based on content
456
* @param props - Textarea autosize properties including min/max rows
457
* @returns Textarea element with auto-sizing behavior
458
*/
459
const TextareaAutosize: React.ForwardRefExoticComponent<
460
TextareaAutosizeProps & React.RefAttributes<HTMLTextAreaElement>
461
>;
462
463
interface TextareaAutosizeProps
464
extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'rows'> {
465
/** Maximum number of rows */
466
maxRows?: number;
467
/** Minimum number of rows (default: 1) */
468
minRows?: number;
469
}
470
```
471
472
## Related Hooks
473
474
```typescript { .api }
475
// Modal behavior hook
476
function unstable_useModal(props: UseModalParameters): UseModalReturnValue;
477
478
// Snackbar behavior hook
479
function useSnackbar(props: UseSnackbarParameters): UseSnackbarReturnValue;
480
481
// Transition hooks (used internally by transition components)
482
function useTransition(props: UseTransitionParameters): UseTransitionReturnValue;
483
```