UNPKG

11.6 kBJavaScriptView Raw
1import _extends from "@babel/runtime/helpers/esm/extends";
2import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3import * as React from 'react';
4import PropTypes from 'prop-types';
5import clsx from 'clsx';
6import withStyles from '../styles/withStyles';
7import capitalize from '../utils/capitalize';
8import Modal from '../Modal';
9import Backdrop from '../Backdrop';
10import Fade from '../Fade';
11import { duration } from '../styles/transitions';
12import Paper from '../Paper';
13export const styles = theme => ({
14 /* Styles applied to the root element. */
15 root: {
16 '@media print': {
17 // Use !important to override the Modal inline-style.
18 position: 'absolute !important'
19 }
20 },
21
22 /* Styles applied to the container element if `scroll="paper"`. */
23 scrollPaper: {
24 display: 'flex',
25 justifyContent: 'center',
26 alignItems: 'center'
27 },
28
29 /* Styles applied to the container element if `scroll="body"`. */
30 scrollBody: {
31 overflowY: 'auto',
32 overflowX: 'hidden',
33 textAlign: 'center',
34 '&:after': {
35 content: '""',
36 display: 'inline-block',
37 verticalAlign: 'middle',
38 height: '100%',
39 width: '0'
40 }
41 },
42
43 /* Styles applied to the container element. */
44 container: {
45 height: '100%',
46 '@media print': {
47 height: 'auto'
48 },
49 // We disable the focus ring for mouse, touch and keyboard users.
50 outline: 0
51 },
52
53 /* Styles applied to the `Paper` component. */
54 paper: {
55 margin: 32,
56 position: 'relative',
57 overflowY: 'auto',
58 // Fix IE 11 issue, to remove at some point.
59 '@media print': {
60 overflowY: 'visible',
61 boxShadow: 'none'
62 }
63 },
64
65 /* Styles applied to the `Paper` component if `scroll="paper"`. */
66 paperScrollPaper: {
67 display: 'flex',
68 flexDirection: 'column',
69 maxHeight: 'calc(100% - 64px)'
70 },
71
72 /* Styles applied to the `Paper` component if `scroll="body"`. */
73 paperScrollBody: {
74 display: 'inline-block',
75 verticalAlign: 'middle',
76 textAlign: 'left' // 'initial' doesn't work on IE 11
77
78 },
79
80 /* Styles applied to the `Paper` component if `maxWidth=false`. */
81 paperWidthFalse: {
82 maxWidth: 'calc(100% - 64px)'
83 },
84
85 /* Styles applied to the `Paper` component if `maxWidth="xs"`. */
86 paperWidthXs: {
87 maxWidth: Math.max(theme.breakpoints.values.xs, 444),
88 '&$paperScrollBody': {
89 [theme.breakpoints.down(Math.max(theme.breakpoints.values.xs, 444) + 32 * 2)]: {
90 maxWidth: 'calc(100% - 64px)'
91 }
92 }
93 },
94
95 /* Styles applied to the `Paper` component if `maxWidth="sm"`. */
96 paperWidthSm: {
97 maxWidth: theme.breakpoints.values.sm,
98 '&$paperScrollBody': {
99 [theme.breakpoints.down(theme.breakpoints.values.sm + 32 * 2)]: {
100 maxWidth: 'calc(100% - 64px)'
101 }
102 }
103 },
104
105 /* Styles applied to the `Paper` component if `maxWidth="md"`. */
106 paperWidthMd: {
107 maxWidth: theme.breakpoints.values.md,
108 '&$paperScrollBody': {
109 [theme.breakpoints.down(theme.breakpoints.values.md + 32 * 2)]: {
110 maxWidth: 'calc(100% - 64px)'
111 }
112 }
113 },
114
115 /* Styles applied to the `Paper` component if `maxWidth="lg"`. */
116 paperWidthLg: {
117 maxWidth: theme.breakpoints.values.lg,
118 '&$paperScrollBody': {
119 [theme.breakpoints.down(theme.breakpoints.values.lg + 32 * 2)]: {
120 maxWidth: 'calc(100% - 64px)'
121 }
122 }
123 },
124
125 /* Styles applied to the `Paper` component if `maxWidth="xl"`. */
126 paperWidthXl: {
127 maxWidth: theme.breakpoints.values.xl,
128 '&$paperScrollBody': {
129 [theme.breakpoints.down(theme.breakpoints.values.xl + 32 * 2)]: {
130 maxWidth: 'calc(100% - 64px)'
131 }
132 }
133 },
134
135 /* Styles applied to the `Paper` component if `fullWidth={true}`. */
136 paperFullWidth: {
137 width: 'calc(100% - 64px)'
138 },
139
140 /* Styles applied to the `Paper` component if `fullScreen={true}`. */
141 paperFullScreen: {
142 margin: 0,
143 width: '100%',
144 maxWidth: '100%',
145 height: '100%',
146 maxHeight: 'none',
147 borderRadius: 0,
148 '&$paperScrollBody': {
149 margin: 0,
150 maxWidth: '100%'
151 }
152 }
153});
154const defaultTransitionDuration = {
155 enter: duration.enteringScreen,
156 exit: duration.leavingScreen
157};
158/**
159 * Dialogs are overlaid modal paper based components with a backdrop.
160 */
161
162const Dialog = /*#__PURE__*/React.forwardRef(function Dialog(props, ref) {
163 const {
164 BackdropProps,
165 children,
166 classes,
167 className,
168 disableBackdropClick = false,
169 disableEscapeKeyDown = false,
170 fullScreen = false,
171 fullWidth = false,
172 maxWidth = 'sm',
173 onBackdropClick,
174 onClose,
175 onEnter,
176 onEntered,
177 onEntering,
178 onEscapeKeyDown,
179 onExit,
180 onExited,
181 onExiting,
182 open,
183 PaperComponent = Paper,
184 PaperProps = {},
185 scroll = 'paper',
186 TransitionComponent = Fade,
187 transitionDuration = defaultTransitionDuration,
188 TransitionProps,
189 'aria-describedby': ariaDescribedby,
190 'aria-labelledby': ariaLabelledby
191 } = props,
192 other = _objectWithoutPropertiesLoose(props, ["BackdropProps", "children", "classes", "className", "disableBackdropClick", "disableEscapeKeyDown", "fullScreen", "fullWidth", "maxWidth", "onBackdropClick", "onClose", "onEnter", "onEntered", "onEntering", "onEscapeKeyDown", "onExit", "onExited", "onExiting", "open", "PaperComponent", "PaperProps", "scroll", "TransitionComponent", "transitionDuration", "TransitionProps", "aria-describedby", "aria-labelledby"]);
193
194 const mouseDownTarget = React.useRef();
195
196 const handleMouseDown = event => {
197 mouseDownTarget.current = event.target;
198 };
199
200 const handleBackdropClick = event => {
201 // Ignore the events not coming from the "backdrop"
202 // We don't want to close the dialog when clicking the dialog content.
203 if (event.target !== event.currentTarget) {
204 return;
205 } // Make sure the event starts and ends on the same DOM element.
206
207
208 if (event.target !== mouseDownTarget.current) {
209 return;
210 }
211
212 mouseDownTarget.current = null;
213
214 if (onBackdropClick) {
215 onBackdropClick(event);
216 }
217
218 if (!disableBackdropClick && onClose) {
219 onClose(event, 'backdropClick');
220 }
221 };
222
223 return /*#__PURE__*/React.createElement(Modal, _extends({
224 className: clsx(classes.root, className),
225 BackdropComponent: Backdrop,
226 BackdropProps: _extends({
227 transitionDuration
228 }, BackdropProps),
229 closeAfterTransition: true,
230 disableBackdropClick: disableBackdropClick,
231 disableEscapeKeyDown: disableEscapeKeyDown,
232 onEscapeKeyDown: onEscapeKeyDown,
233 onClose: onClose,
234 open: open,
235 ref: ref
236 }, other), /*#__PURE__*/React.createElement(TransitionComponent, _extends({
237 appear: true,
238 in: open,
239 timeout: transitionDuration,
240 onEnter: onEnter,
241 onEntering: onEntering,
242 onEntered: onEntered,
243 onExit: onExit,
244 onExiting: onExiting,
245 onExited: onExited,
246 role: "none presentation"
247 }, TransitionProps), /*#__PURE__*/React.createElement("div", {
248 className: clsx(classes.container, classes[`scroll${capitalize(scroll)}`]),
249 onMouseUp: handleBackdropClick,
250 onMouseDown: handleMouseDown
251 }, /*#__PURE__*/React.createElement(PaperComponent, _extends({
252 elevation: 24,
253 role: "dialog",
254 "aria-describedby": ariaDescribedby,
255 "aria-labelledby": ariaLabelledby
256 }, PaperProps, {
257 className: clsx(classes.paper, classes[`paperScroll${capitalize(scroll)}`], classes[`paperWidth${capitalize(String(maxWidth))}`], PaperProps.className, fullScreen && classes.paperFullScreen, fullWidth && classes.paperFullWidth)
258 }), children))));
259});
260process.env.NODE_ENV !== "production" ? Dialog.propTypes = {
261 // ----------------------------- Warning --------------------------------
262 // | These PropTypes are generated from the TypeScript type definitions |
263 // | To update them edit the d.ts file and run "yarn proptypes" |
264 // ----------------------------------------------------------------------
265
266 /**
267 * The id(s) of the element(s) that describe the dialog.
268 */
269 'aria-describedby': PropTypes.string,
270
271 /**
272 * The id(s) of the element(s) that label the dialog.
273 */
274 'aria-labelledby': PropTypes.string,
275
276 /**
277 * @ignore
278 */
279 BackdropProps: PropTypes.object,
280
281 /**
282 * Dialog children, usually the included sub-components.
283 */
284 children: PropTypes.node,
285
286 /**
287 * Override or extend the styles applied to the component.
288 * See [CSS API](#css) below for more details.
289 */
290 classes: PropTypes.object,
291
292 /**
293 * @ignore
294 */
295 className: PropTypes.string,
296
297 /**
298 * If `true`, clicking the backdrop will not fire the `onClose` callback.
299 */
300 disableBackdropClick: PropTypes.bool,
301
302 /**
303 * If `true`, hitting escape will not fire the `onClose` callback.
304 */
305 disableEscapeKeyDown: PropTypes.bool,
306
307 /**
308 * If `true`, the dialog will be full-screen
309 */
310 fullScreen: PropTypes.bool,
311
312 /**
313 * If `true`, the dialog stretches to `maxWidth`.
314 *
315 * Notice that the dialog width grow is limited by the default margin.
316 */
317 fullWidth: PropTypes.bool,
318
319 /**
320 * Determine the max-width of the dialog.
321 * The dialog width grows with the size of the screen.
322 * Set to `false` to disable `maxWidth`.
323 */
324 maxWidth: PropTypes.oneOf(['lg', 'md', 'sm', 'xl', 'xs', false]),
325
326 /**
327 * Callback fired when the backdrop is clicked.
328 */
329 onBackdropClick: PropTypes.func,
330
331 /**
332 * Callback fired when the component requests to be closed.
333 *
334 * @param {object} event The event source of the callback.
335 * @param {string} reason Can be: `"escapeKeyDown"`, `"backdropClick"`.
336 */
337 onClose: PropTypes.func,
338
339 /**
340 * Callback fired before the dialog enters.
341 */
342 onEnter: PropTypes.func,
343
344 /**
345 * Callback fired when the dialog has entered.
346 */
347 onEntered: PropTypes.func,
348
349 /**
350 * Callback fired when the dialog is entering.
351 */
352 onEntering: PropTypes.func,
353
354 /**
355 * Callback fired when the escape key is pressed,
356 * `disableKeyboard` is false and the modal is in focus.
357 */
358 onEscapeKeyDown: PropTypes.func,
359
360 /**
361 * Callback fired before the dialog exits.
362 */
363 onExit: PropTypes.func,
364
365 /**
366 * Callback fired when the dialog has exited.
367 */
368 onExited: PropTypes.func,
369
370 /**
371 * Callback fired when the dialog is exiting.
372 */
373 onExiting: PropTypes.func,
374
375 /**
376 * If `true`, the Dialog is open.
377 */
378 open: PropTypes.bool.isRequired,
379
380 /**
381 * The component used to render the body of the dialog.
382 */
383 PaperComponent: PropTypes.elementType,
384
385 /**
386 * Props applied to the [`Paper`](/api/paper/) element.
387 */
388 PaperProps: PropTypes.object,
389
390 /**
391 * Determine the container for scrolling the dialog.
392 */
393 scroll: PropTypes.oneOf(['body', 'paper']),
394
395 /**
396 * The component used for the transition.
397 * [Follow this guide](/components/transitions/#transitioncomponent-prop) to learn more about the requirements for this component.
398 */
399 TransitionComponent: PropTypes.elementType,
400
401 /**
402 * The duration for the transition, in milliseconds.
403 * You may specify a single timeout for all transitions, or individually with an object.
404 */
405 transitionDuration: PropTypes.oneOfType([PropTypes.number, PropTypes.shape({
406 appear: PropTypes.number,
407 enter: PropTypes.number,
408 exit: PropTypes.number
409 })]),
410
411 /**
412 * Props applied to the [`Transition`](http://reactcommunity.org/react-transition-group/transition#Transition-props) element.
413 */
414 TransitionProps: PropTypes.object
415} : void 0;
416export default withStyles(styles, {
417 name: 'MuiDialog'
418})(Dialog);
\No newline at end of file