UNPKG

@mui/material

Version:

Quickly build beautiful React apps. MUI is a simple and customizable component library to build faster, beautiful, and more accessible React applications. Follow your own design system, or start with Material Design.

492 lines (421 loc) 15.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _clsx = _interopRequireDefault(require("clsx")); var _base = require("@mui/base"); var _ClickAwayListener = _interopRequireDefault(require("@mui/base/ClickAwayListener")); var _styled = _interopRequireDefault(require("../styles/styled")); var _useTheme = _interopRequireDefault(require("../styles/useTheme")); var _useThemeProps = _interopRequireDefault(require("../styles/useThemeProps")); var _createTransitions = require("../styles/createTransitions"); var _useEventCallback = _interopRequireDefault(require("../utils/useEventCallback")); var _capitalize = _interopRequireDefault(require("../utils/capitalize")); var _Grow = _interopRequireDefault(require("../Grow")); var _SnackbarContent = _interopRequireDefault(require("../SnackbarContent")); var _snackbarClasses = require("./snackbarClasses"); var _jsxRuntime = require("react/jsx-runtime"); const _excluded = ["onEnter", "onExited"], _excluded2 = ["action", "anchorOrigin", "autoHideDuration", "children", "className", "ClickAwayListenerProps", "ContentProps", "disableWindowBlurListener", "message", "onBlur", "onClose", "onFocus", "onMouseEnter", "onMouseLeave", "open", "resumeHideDuration", "TransitionComponent", "transitionDuration", "TransitionProps"]; function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } const useUtilityClasses = ownerState => { const { classes, anchorOrigin } = ownerState; const slots = { root: ['root', `anchorOrigin${(0, _capitalize.default)(anchorOrigin.vertical)}${(0, _capitalize.default)(anchorOrigin.horizontal)}`] }; return (0, _base.unstable_composeClasses)(slots, _snackbarClasses.getSnackbarUtilityClass, classes); }; const SnackbarRoot = (0, _styled.default)('div', { name: 'MuiSnackbar', slot: 'Root', overridesResolver: (props, styles) => { const { ownerState } = props; return [styles.root, styles[`anchorOrigin${(0, _capitalize.default)(ownerState.anchorOrigin.vertical)}${(0, _capitalize.default)(ownerState.anchorOrigin.horizontal)}`]]; } })(({ theme, ownerState }) => { const center = (0, _extends2.default)({}, !ownerState.isRtl && { left: '50%', right: 'auto', transform: 'translateX(-50%)' }, ownerState.isRtl && { right: '50%', left: 'auto', transform: 'translateX(50%)' }); return (0, _extends2.default)({ zIndex: theme.zIndex.snackbar, position: 'fixed', display: 'flex', left: 8, right: 8, justifyContent: 'center', alignItems: 'center' }, ownerState.anchorOrigin.vertical === 'top' ? { top: 8 } : { bottom: 8 }, ownerState.anchorOrigin.horizontal === 'left' && { justifyContent: 'flex-start' }, ownerState.anchorOrigin.horizontal === 'right' && { justifyContent: 'flex-end' }, { [theme.breakpoints.up('sm')]: (0, _extends2.default)({}, ownerState.anchorOrigin.vertical === 'top' ? { top: 24 } : { bottom: 24 }, ownerState.anchorOrigin.horizontal === 'center' && center, ownerState.anchorOrigin.horizontal === 'left' && (0, _extends2.default)({}, !ownerState.isRtl && { left: 24, right: 'auto' }, ownerState.isRtl && { right: 24, left: 'auto' }), ownerState.anchorOrigin.horizontal === 'right' && (0, _extends2.default)({}, !ownerState.isRtl && { right: 24, left: 'auto' }, ownerState.isRtl && { left: 24, right: 'auto' })) }); }); const Snackbar = /*#__PURE__*/React.forwardRef(function Snackbar(inProps, ref) { const props = (0, _useThemeProps.default)({ props: inProps, name: 'MuiSnackbar' }); const { action, anchorOrigin: { vertical, horizontal } = { vertical: 'bottom', horizontal: 'left' }, autoHideDuration = null, children, className, ClickAwayListenerProps, ContentProps, disableWindowBlurListener = false, message, onBlur, onClose, onFocus, onMouseEnter, onMouseLeave, open, resumeHideDuration, TransitionComponent = _Grow.default, transitionDuration = { enter: _createTransitions.duration.enteringScreen, exit: _createTransitions.duration.leavingScreen }, TransitionProps: { onEnter, onExited } = {} } = props, TransitionProps = (0, _objectWithoutPropertiesLoose2.default)(props.TransitionProps, _excluded), other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded2); const theme = (0, _useTheme.default)(); const isRtl = theme.direction === 'rtl'; const ownerState = (0, _extends2.default)({}, props, { anchorOrigin: { vertical, horizontal }, isRtl }); const classes = useUtilityClasses(ownerState); const timerAutoHide = React.useRef(); const [exited, setExited] = React.useState(true); const handleClose = (0, _useEventCallback.default)((...args) => { if (onClose) { onClose(...args); } }); const setAutoHideTimer = (0, _useEventCallback.default)(autoHideDurationParam => { if (!onClose || autoHideDurationParam == null) { return; } clearTimeout(timerAutoHide.current); timerAutoHide.current = setTimeout(() => { handleClose(null, 'timeout'); }, autoHideDurationParam); }); React.useEffect(() => { if (open) { setAutoHideTimer(autoHideDuration); } return () => { clearTimeout(timerAutoHide.current); }; }, [open, autoHideDuration, setAutoHideTimer]); // Pause the timer when the user is interacting with the Snackbar // or when the user hide the window. const handlePause = () => { clearTimeout(timerAutoHide.current); }; // Restart the timer when the user is no longer interacting with the Snackbar // or when the window is shown back. const handleResume = React.useCallback(() => { if (autoHideDuration != null) { setAutoHideTimer(resumeHideDuration != null ? resumeHideDuration : autoHideDuration * 0.5); } }, [autoHideDuration, resumeHideDuration, setAutoHideTimer]); const handleFocus = event => { if (onFocus) { onFocus(event); } handlePause(); }; const handleMouseEnter = event => { if (onMouseEnter) { onMouseEnter(event); } handlePause(); }; const handleBlur = event => { if (onBlur) { onBlur(event); } handleResume(); }; const handleMouseLeave = event => { if (onMouseLeave) { onMouseLeave(event); } handleResume(); }; const handleClickAway = event => { if (onClose) { onClose(event, 'clickaway'); } }; const handleExited = node => { setExited(true); if (onExited) { onExited(node); } }; const handleEnter = (node, isAppearing) => { setExited(false); if (onEnter) { onEnter(node, isAppearing); } }; React.useEffect(() => { // TODO: window global should be refactored here if (!disableWindowBlurListener && open) { window.addEventListener('focus', handleResume); window.addEventListener('blur', handlePause); return () => { window.removeEventListener('focus', handleResume); window.removeEventListener('blur', handlePause); }; } return undefined; }, [disableWindowBlurListener, handleResume, open]); React.useEffect(() => { if (!open) { return undefined; } /** * @param {KeyboardEvent} nativeEvent */ function handleKeyDown(nativeEvent) { if (!nativeEvent.defaultPrevented) { // IE11, Edge (prior to using Bink?) use 'Esc' if (nativeEvent.key === 'Escape' || nativeEvent.key === 'Esc') { // not calling `preventDefault` since we don't know if people may ignore this event e.g. a permanently open snackbar if (onClose) { onClose(nativeEvent, 'escapeKeyDown'); } } } } document.addEventListener('keydown', handleKeyDown); return () => { document.removeEventListener('keydown', handleKeyDown); }; }, [exited, open, onClose]); // So we only render active snackbars. if (!open && exited) { return null; } return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ClickAwayListener.default, (0, _extends2.default)({ onClickAway: handleClickAway }, ClickAwayListenerProps, { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(SnackbarRoot, (0, _extends2.default)({ className: (0, _clsx.default)(classes.root, className), onBlur: handleBlur, onFocus: handleFocus, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, ownerState: ownerState, ref: ref }, other, { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(TransitionComponent, (0, _extends2.default)({ appear: true, in: open, timeout: transitionDuration, direction: vertical === 'top' ? 'down' : 'up', onEnter: handleEnter, onExited: handleExited }, TransitionProps, { children: children || /*#__PURE__*/(0, _jsxRuntime.jsx)(_SnackbarContent.default, (0, _extends2.default)({ message: message, action: action }, ContentProps)) })) })) })); }); process.env.NODE_ENV !== "production" ? Snackbar.propTypes /* remove-proptypes */ = { // ----------------------------- Warning -------------------------------- // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the d.ts file and run "yarn proptypes" | // ---------------------------------------------------------------------- /** * The action to display. It renders after the message, at the end of the snackbar. */ action: _propTypes.default.node, /** * The anchor of the `Snackbar`. * On smaller screens, the component grows to occupy all the available width, * the horizontal alignment is ignored. * @default { vertical: 'bottom', horizontal: 'left' } */ anchorOrigin: _propTypes.default.shape({ horizontal: _propTypes.default.oneOf(['center', 'left', 'right']).isRequired, vertical: _propTypes.default.oneOf(['bottom', 'top']).isRequired }), /** * The number of milliseconds to wait before automatically calling the * `onClose` function. `onClose` should then set the state of the `open` * prop to hide the Snackbar. This behavior is disabled by default with * the `null` value. * @default null */ autoHideDuration: _propTypes.default.number, /** * Replace the `SnackbarContent` component. */ children: _propTypes.default.element, /** * Override or extend the styles applied to the component. */ classes: _propTypes.default.object, /** * @ignore */ className: _propTypes.default.string, /** * Props applied to the `ClickAwayListener` element. */ ClickAwayListenerProps: _propTypes.default.object, /** * Props applied to the [`SnackbarContent`](/api/snackbar-content/) element. */ ContentProps: _propTypes.default.object, /** * If `true`, the `autoHideDuration` timer will expire even if the window is not focused. * @default false */ disableWindowBlurListener: _propTypes.default.bool, /** * When displaying multiple consecutive Snackbars from a parent rendering a single * <Snackbar/>, add the key prop to ensure independent treatment of each message. * e.g. <Snackbar key={message} />, otherwise, the message may update-in-place and * features such as autoHideDuration may be canceled. */ key: () => null, /** * The message to display. */ message: _propTypes.default.node, /** * @ignore */ onBlur: _propTypes.default.func, /** * Callback fired when the component requests to be closed. * Typically `onClose` is used to set state in the parent component, * which is used to control the `Snackbar` `open` prop. * The `reason` parameter can optionally be used to control the response to `onClose`, * for example ignoring `clickaway`. * * @param {React.SyntheticEvent<any> | Event} event The event source of the callback. * @param {string} reason Can be: `"timeout"` (`autoHideDuration` expired), `"clickaway"`, or `"escapeKeyDown"`. */ onClose: _propTypes.default.func, /** * @ignore */ onFocus: _propTypes.default.func, /** * @ignore */ onMouseEnter: _propTypes.default.func, /** * @ignore */ onMouseLeave: _propTypes.default.func, /** * If `true`, the component is shown. */ open: _propTypes.default.bool, /** * The number of milliseconds to wait before dismissing after user interaction. * If `autoHideDuration` prop isn't specified, it does nothing. * If `autoHideDuration` prop is specified but `resumeHideDuration` isn't, * we default to `autoHideDuration / 2` ms. */ resumeHideDuration: _propTypes.default.number, /** * The system prop that allows defining system overrides as well as additional CSS styles. */ sx: _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object, _propTypes.default.bool])), _propTypes.default.func, _propTypes.default.object]), /** * The component used for the transition. * [Follow this guide](/components/transitions/#transitioncomponent-prop) to learn more about the requirements for this component. * @default Grow */ TransitionComponent: _propTypes.default.elementType, /** * The duration for the transition, in milliseconds. * You may specify a single timeout for all transitions, or individually with an object. * @default { * enter: duration.enteringScreen, * exit: duration.leavingScreen, * } */ transitionDuration: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.shape({ appear: _propTypes.default.number, enter: _propTypes.default.number, exit: _propTypes.default.number })]), /** * Props applied to the transition element. * By default, the element is based on this [`Transition`](http://reactcommunity.org/react-transition-group/transition/) component. * @default {} */ TransitionProps: _propTypes.default.object } : void 0; var _default = Snackbar; exports.default = _default;