0
# Utility Components
1
2
Utility components provide foundational functionality for portal rendering, click detection, transitions, responsive behavior, and other common patterns.
3
4
## Capabilities
5
6
### Portal
7
8
Portal component for rendering content in a different part of the DOM tree.
9
10
```typescript { .api }
11
/**
12
* Portal component for rendering content in a different part of the DOM tree
13
* @param props - Portal props
14
* @returns Portal React component or null
15
*/
16
function Portal(props: PortalProps): React.ReactPortal | null;
17
18
interface PortalProps {
19
children?: React.ReactNode;
20
container?: Element | (() => Element | null) | null;
21
disablePortal?: boolean;
22
onRendered?: () => void;
23
}
24
```
25
26
**Usage Examples:**
27
28
```typescript
29
import { Portal } from '@material-ui/core';
30
31
// Render to document body
32
<Portal>
33
<div>This content is rendered in document.body</div>
34
</Portal>
35
36
// Render to specific container
37
<Portal container={() => document.getElementById('modal-root')}>
38
<div>This content is rendered in #modal-root</div>
39
</Portal>
40
41
// Conditionally disable portal
42
<Portal disablePortal={!usePortal}>
43
<div>Conditional portal rendering</div>
44
</Portal>
45
```
46
47
### Click Away Listener
48
49
Utility component for detecting clicks outside of a specified element.
50
51
```typescript { .api }
52
/**
53
* Utility component for detecting clicks outside of a specified element
54
* @param props - Click away listener props
55
* @returns Click away listener React component
56
*/
57
function ClickAwayListener(props: ClickAwayListenerProps): JSX.Element;
58
59
interface ClickAwayListenerProps {
60
children: React.ReactElement<any, any>;
61
mouseEvent?: 'onClick' | 'onMouseDown' | 'onMouseUp' | false;
62
onClickAway: (event: MouseEvent | TouchEvent) => void;
63
touchEvent?: 'onTouchStart' | 'onTouchEnd' | false;
64
}
65
```
66
67
**Usage Examples:**
68
69
```typescript
70
import { ClickAwayListener, Paper } from '@material-ui/core';
71
72
const [open, setOpen] = useState(false);
73
74
<ClickAwayListener onClickAway={() => setOpen(false)}>
75
<Paper>
76
<p>Click outside this paper to close</p>
77
</Paper>
78
</ClickAwayListener>
79
```
80
81
### Modal
82
83
Base modal component providing focus management and backdrop functionality.
84
85
```typescript { .api }
86
/**
87
* Base modal component providing focus management and backdrop functionality
88
* @param props - Modal props
89
* @returns Modal React component
90
*/
91
function Modal(props: ModalProps): JSX.Element;
92
93
interface ModalProps extends StandardProps<React.HTMLAttributes<HTMLDivElement>, ModalClassKey> {
94
BackdropComponent?: React.ComponentType<BackdropProps>;
95
BackdropProps?: Partial<BackdropProps>;
96
children: React.ReactElement<any, any>;
97
closeAfterTransition?: boolean;
98
container?: Element | (() => Element | null) | null;
99
disableAutoFocus?: boolean;
100
disableBackdropClick?: boolean;
101
disableEnforceFocus?: boolean;
102
disableEscapeKeyDown?: boolean;
103
disablePortal?: boolean;
104
disableRestoreFocus?: boolean;
105
disableScrollLock?: boolean;
106
hideBackdrop?: boolean;
107
keepMounted?: boolean;
108
manager?: ModalManager;
109
onBackdropClick?: React.ReactEventHandler<{}>;
110
onClose?: (event: {}, reason: 'backdropClick' | 'escapeKeyDown') => void;
111
onEscapeKeyDown?: React.ReactEventHandler<{}>;
112
onRendered?: () => void;
113
open: boolean;
114
}
115
116
type ModalClassKey = 'root' | 'hidden' | 'backdrop';
117
```
118
119
### Modal Manager
120
121
Utility class for managing multiple modals and their z-index stacking.
122
123
```typescript { .api }
124
/**
125
* Utility class for managing multiple modals and their z-index stacking
126
*/
127
class ModalManager {
128
constructor();
129
add(modal: any, container: HTMLElement): number;
130
mount(modal: any): void;
131
remove(modal: any): number;
132
isTopModal(modal: any): boolean;
133
}
134
```
135
136
### No SSR
137
138
Component for preventing server-side rendering of its children.
139
140
```typescript { .api }
141
/**
142
* Component for preventing server-side rendering of its children
143
* @param props - No SSR props
144
* @returns No SSR React component
145
*/
146
function NoSsr(props: NoSsrProps): JSX.Element;
147
148
interface NoSsrProps {
149
children?: React.ReactNode;
150
defer?: boolean;
151
fallback?: React.ReactNode;
152
}
153
```
154
155
**Usage Examples:**
156
157
```typescript
158
import { NoSsr } from '@material-ui/core';
159
160
// Prevent SSR for component that uses browser APIs
161
<NoSsr>
162
<ComponentThatUsesWindow />
163
</NoSsr>
164
165
// With fallback content
166
<NoSsr fallback={<div>Loading...</div>}>
167
<ClientOnlyComponent />
168
</NoSsr>
169
```
170
171
### Popover
172
173
Popover component for displaying content in an overlay positioned relative to a target element.
174
175
```typescript { .api }
176
/**
177
* Popover component for displaying content in an overlay positioned relative to a target element
178
* @param props - Popover props
179
* @returns Popover React component
180
*/
181
function Popover(props: PopoverProps): JSX.Element;
182
183
interface PopoverProps extends StandardProps<ModalProps, PopoverClassKey> {
184
action?: React.Ref<PopoverActions>;
185
anchorEl?: null | Element | ((element: Element) => Element);
186
anchorOrigin?: PopoverOrigin;
187
anchorPosition?: PopoverPosition;
188
anchorReference?: 'anchorEl' | 'anchorPosition' | 'none';
189
children?: React.ReactNode;
190
elevation?: number;
191
getContentAnchorEl?: null | ((element: Element) => Element);
192
marginThreshold?: number;
193
onEnter?: TransitionHandlersProps['onEnter'];
194
onEntered?: TransitionHandlersProps['onEntered'];
195
onEntering?: TransitionHandlersProps['onEntering'];
196
onExit?: TransitionHandlersProps['onExit'];
197
onExited?: TransitionHandlersProps['onExited'];
198
onExiting?: TransitionHandlersProps['onExiting'];
199
open: boolean;
200
PaperProps?: Partial<PaperProps>;
201
transformOrigin?: PopoverOrigin;
202
TransitionComponent?: React.ComponentType<TransitionProps>;
203
transitionDuration?: TransitionProps['timeout'] | 'auto';
204
TransitionProps?: TransitionProps;
205
}
206
207
interface PopoverOrigin {
208
horizontal: 'left' | 'center' | 'right' | number;
209
vertical: 'top' | 'center' | 'bottom' | number;
210
}
211
212
interface PopoverPosition {
213
top: number;
214
left: number;
215
}
216
217
interface PopoverActions {
218
updatePosition(): void;
219
}
220
221
type PopoverClassKey = 'root' | 'paper';
222
```
223
224
### Popper
225
226
Popper component for advanced positioning using Popper.js.
227
228
```typescript { .api }
229
/**
230
* Popper component for advanced positioning using Popper.js
231
* @param props - Popper props
232
* @returns Popper React component
233
*/
234
function Popper(props: PopperProps): JSX.Element;
235
236
interface PopperProps extends StandardProps<React.HTMLAttributes<HTMLDivElement>, PopperClassKey> {
237
anchorEl?: null | Element | ((element: Element) => Element);
238
children: React.ReactNode | ((props: { placement: PopperPlacementType }) => React.ReactNode);
239
container?: Element | (() => Element | null) | null;
240
disablePortal?: boolean;
241
keepMounted?: boolean;
242
modifiers?: object;
243
open: boolean;
244
placement?: PopperPlacementType;
245
popperOptions?: object;
246
popperRef?: React.Ref<Element>;
247
transition?: boolean;
248
}
249
250
type PopperPlacementType = 'bottom-end' | 'bottom-start' | 'bottom' | 'left-end' | 'left-start' | 'left' | 'right-end' | 'right-start' | 'right' | 'top-end' | 'top-start' | 'top';
251
type PopperClassKey = 'root';
252
```
253
254
### Transition Components
255
256
#### Collapse
257
258
Collapse transition component for height-based animations.
259
260
```typescript { .api }
261
/**
262
* Collapse transition component for height-based animations
263
* @param props - Collapse props
264
* @returns Collapse React component
265
*/
266
function Collapse(props: CollapseProps): JSX.Element;
267
268
interface CollapseProps extends StandardProps<TransitionProps, CollapseClassKey> {
269
children?: React.ReactNode;
270
collapsedHeight?: string | number;
271
component?: React.ElementType;
272
in?: boolean;
273
timeout?: TransitionProps['timeout'] | 'auto';
274
}
275
276
type CollapseClassKey = 'root' | 'entered' | 'hidden' | 'wrapper' | 'wrapperInner';
277
```
278
279
#### Fade
280
281
Fade transition component for opacity-based animations.
282
283
```typescript { .api }
284
/**
285
* Fade transition component for opacity-based animations
286
* @param props - Fade props
287
* @returns Fade React component
288
*/
289
function Fade(props: FadeProps): JSX.Element;
290
291
interface FadeProps extends StandardProps<TransitionProps, FadeClassKey> {
292
children?: React.ReactElement<any, any>;
293
in?: boolean;
294
timeout?: TransitionProps['timeout'];
295
}
296
297
type FadeClassKey = 'root';
298
```
299
300
#### Grow
301
302
Grow transition component for scale-based animations.
303
304
```typescript { .api }
305
/**
306
* Grow transition component for scale-based animations
307
* @param props - Grow props
308
* @returns Grow React component
309
*/
310
function Grow(props: GrowProps): JSX.Element;
311
312
interface GrowProps extends StandardProps<TransitionProps, GrowClassKey> {
313
children?: React.ReactElement<any, any>;
314
in?: boolean;
315
timeout?: TransitionProps['timeout'] | 'auto';
316
}
317
318
type GrowClassKey = 'root';
319
```
320
321
#### Slide
322
323
Slide transition component for directional slide animations.
324
325
```typescript { .api }
326
/**
327
* Slide transition component for directional slide animations
328
* @param props - Slide props
329
* @returns Slide React component
330
*/
331
function Slide(props: SlideProps): JSX.Element;
332
333
interface SlideProps extends StandardProps<TransitionProps, SlideClassKey> {
334
children?: React.ReactElement<any, any>;
335
direction?: 'left' | 'right' | 'up' | 'down';
336
in?: boolean;
337
timeout?: TransitionProps['timeout'];
338
}
339
340
type SlideClassKey = 'root';
341
```
342
343
#### Zoom
344
345
Zoom transition component for scale-based animations with different timing.
346
347
```typescript { .api }
348
/**
349
* Zoom transition component for scale-based animations with different timing
350
* @param props - Zoom props
351
* @returns Zoom React component
352
*/
353
function Zoom(props: ZoomProps): JSX.Element;
354
355
interface ZoomProps extends StandardProps<TransitionProps, ZoomClassKey> {
356
children?: React.ReactElement<any, any>;
357
in?: boolean;
358
timeout?: TransitionProps['timeout'];
359
}
360
361
type ZoomClassKey = 'root';
362
```
363
364
### Higher-Order Components
365
366
#### withMobileDialog
367
368
HOC that makes dialogs full-screen on mobile devices.
369
370
```typescript { .api }
371
/**
372
* HOC that makes dialogs full-screen on mobile devices
373
* @param options - Mobile dialog options
374
* @returns HOC function
375
*/
376
function withMobileDialog<P = {}>(options?: WithMobileDialogOptions): (Component: React.ComponentType<P>) => React.ComponentType<P & WithMobileDialogProps>;
377
378
interface WithMobileDialogOptions {
379
breakpoint?: Breakpoint;
380
}
381
382
interface WithMobileDialogProps {
383
fullScreen: boolean;
384
}
385
```
386
387
#### withWidth
388
389
HOC that provides the current breakpoint width to components.
390
391
```typescript { .api }
392
/**
393
* HOC that provides the current breakpoint width to components
394
* @param options - Width detection options
395
* @returns HOC function
396
*/
397
function withWidth<P extends WithWidthProps = WithWidthProps>(options?: WithWidthOptions): (Component: React.ComponentType<P>) => React.ComponentType<Omit<P, keyof WithWidthProps> & Partial<WithWidthProps>>;
398
399
interface WithWidthOptions {
400
withTheme?: boolean;
401
noSSR?: boolean;
402
initialWidth?: Breakpoint;
403
resizeInterval?: number;
404
}
405
406
interface WithWidthProps {
407
width: Breakpoint;
408
}
409
```
410
411
**Usage Examples:**
412
413
```typescript
414
import { withMobileDialog, withWidth } from '@material-ui/core';
415
416
// Mobile dialog HOC
417
const ResponsiveDialog = withMobileDialog({ breakpoint: 'xs' })(Dialog);
418
419
// Width detection HOC
420
const ResponsiveComponent = withWidth()(({ width, ...props }) => (
421
<div>
422
Current breakpoint: {width}
423
{width === 'xs' && <MobileLayout />}
424
{width !== 'xs' && <DesktopLayout />}
425
</div>
426
));
427
```
428
429
### Root Ref
430
431
Utility component for forwarding refs to the root element.
432
433
```typescript { .api }
434
/**
435
* Utility component for forwarding refs to the root element
436
* @param props - Root ref props
437
* @returns Root ref React component
438
*/
439
function RootRef(props: RootRefProps): JSX.Element;
440
441
interface RootRefProps {
442
rootRef: React.Ref<any>;
443
children: React.ReactElement<any, any>;
444
}
445
```
446
447
### CSS Baseline
448
449
Component for providing consistent CSS baseline across browsers.
450
451
```typescript { .api }
452
/**
453
* Component for providing consistent CSS baseline across browsers
454
* @param props - CSS Baseline props
455
* @returns CSS Baseline React component
456
*/
457
function CssBaseline(props: CssBaselineProps): JSX.Element;
458
459
interface CssBaselineProps {
460
children?: React.ReactNode;
461
}
462
```
463
464
**Usage Examples:**
465
466
```typescript
467
import { CssBaseline } from '@material-ui/core';
468
469
// Apply at app root
470
function App() {
471
return (
472
<>
473
<CssBaseline />
474
<AppContent />
475
</>
476
);
477
}
478
```
479
480
### Experimental/Unstable APIs
481
482
#### useMediaQuery
483
484
Experimental hook for media query matching.
485
486
```typescript { .api }
487
/**
488
* Experimental hook for media query matching
489
* @param query - Media query string
490
* @param options - Media query options
491
* @returns Boolean indicating if query matches
492
*/
493
function unstable_useMediaQuery(query: string, options?: UseMediaQueryOptions): boolean;
494
495
interface UseMediaQueryOptions {
496
defaultMatches?: boolean;
497
noSsr?: boolean;
498
ssrMatchMedia?: (query: string) => { matches: boolean };
499
}
500
```
501
502
**Usage Examples:**
503
504
```typescript
505
import { unstable_useMediaQuery as useMediaQuery } from '@material-ui/core/useMediaQuery';
506
507
function ResponsiveComponent() {
508
const isMobile = useMediaQuery('(max-width:600px)');
509
510
return (
511
<div>
512
{isMobile ? <MobileView /> : <DesktopView />}
513
</div>
514
);
515
}
516
```