UNPKG

@atlaskit/modal-dialog

Version:

A modal dialog displays content that requires user interaction, in a layer above the page.

130 lines (126 loc) 6.87 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _react = require("react"); var _react2 = require("@emotion/react"); var _reactFocusLock = _interopRequireDefault(require("react-focus-lock")); var _reactScrolllock = _interopRequireWildcard(require("react-scrolllock")); var _analyticsNext = require("@atlaskit/analytics-next"); var _blanket = _interopRequireDefault(require("@atlaskit/blanket")); var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop")); var _useCloseOnEscapePress = _interopRequireDefault(require("@atlaskit/ds-lib/use-close-on-escape-press")); var _fadeIn = _interopRequireDefault(require("@atlaskit/motion/fade-in")); var _portal = _interopRequireDefault(require("@atlaskit/portal")); var _constants = require("@atlaskit/theme/constants"); var _modalDialog = _interopRequireDefault(require("./internal/components/modal-dialog")); var _useModalStack = _interopRequireDefault(require("./internal/hooks/use-modal-stack")); var _usePreventProgrammaticScroll = _interopRequireDefault(require("./internal/hooks/use-prevent-programmatic-scroll")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(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; } /** @jsx jsx */ var fillScreenStyles = (0, _react2.css)({ width: '100vw', height: '100vh', position: 'fixed', // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing top: 0, // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing left: 0, overflowY: 'auto', WebkitOverflowScrolling: 'touch' }); var whiteListElements = function whiteListElements(element) { // allows focus to reach elements outside the modal if they contain the data-atlas-extension attribute return !element.hasAttribute('data-atlas-extension'); }; /** * __Modal wrapper__ * * A modal wrapper displays content that requires user interaction, in a layer above the page. * This component is primary container for other modal components. * * - [Examples](https://atlassian.design/components/modal-dialog/examples) * - [Code](https://atlassian.design/components/modal-dialog/code) * - [Usage](https://atlassian.design/components/modal-dialog/usage) */ var ModalWrapper = function ModalWrapper(props) { var _props$autoFocus = props.autoFocus, autoFocus = _props$autoFocus === void 0 ? true : _props$autoFocus, _props$shouldCloseOnE = props.shouldCloseOnEscapePress, shouldCloseOnEscapePress = _props$shouldCloseOnE === void 0 ? true : _props$shouldCloseOnE, _props$shouldCloseOnO = props.shouldCloseOnOverlayClick, shouldCloseOnOverlayClick = _props$shouldCloseOnO === void 0 ? true : _props$shouldCloseOnO, _props$shouldScrollIn = props.shouldScrollInViewport, shouldScrollInViewport = _props$shouldScrollIn === void 0 ? false : _props$shouldScrollIn, stackIndexOverride = props.stackIndex, _props$onClose = props.onClose, onClose = _props$onClose === void 0 ? _noop.default : _props$onClose, _props$onStackChange = props.onStackChange, onStackChange = _props$onStackChange === void 0 ? _noop.default : _props$onStackChange, isBlanketHidden = props.isBlanketHidden, children = props.children, height = props.height, width = props.width, onCloseComplete = props.onCloseComplete, onOpenComplete = props.onOpenComplete, testId = props.testId; var calculatedStackIndex = (0, _useModalStack.default)({ onStackChange: onStackChange }); var stackIndex = stackIndexOverride || calculatedStackIndex; var isForeground = stackIndex === 0; // When a user supplies a ref to focus we skip auto focus via react-focus-lock var autoFocusLock = typeof autoFocus === 'boolean' ? autoFocus : false; var onCloseHandler = (0, _analyticsNext.usePlatformLeafEventHandler)({ fn: onClose, action: 'closed', componentName: 'modalDialog', packageName: "@atlaskit/modal-dialog", packageVersion: "12.4.12" }); var onBlanketClicked = (0, _react.useCallback)(function (e) { if (shouldCloseOnOverlayClick) { onCloseHandler(e); } }, [shouldCloseOnOverlayClick, onCloseHandler]); (0, _usePreventProgrammaticScroll.default)(); (0, _useCloseOnEscapePress.default)({ onClose: onCloseHandler, isDisabled: !shouldCloseOnEscapePress || !isForeground }); var modalDialogWithBlanket = (0, _react2.jsx)(_blanket.default, { isTinted: !isBlanketHidden, onBlanketClicked: onBlanketClicked, testId: testId && "".concat(testId, "--blanket") }, (0, _react2.jsx)(_modalDialog.default, { testId: testId, autoFocus: autoFocus, stackIndex: stackIndex, onClose: onCloseHandler, shouldScrollInViewport: shouldScrollInViewport, height: height, width: width, onCloseComplete: onCloseComplete, onOpenComplete: onOpenComplete }, children)); return (0, _react2.jsx)(_portal.default, { zIndex: _constants.layers.modal() }, (0, _react2.jsx)(_fadeIn.default, null, function (fadeInProps) { return (0, _react2.jsx)("div", (0, _extends2.default)({}, fadeInProps, { css: fillScreenStyles, "aria-hidden": !isForeground }), (0, _react2.jsx)(_reactFocusLock.default, { autoFocus: autoFocusLock, disabled: !isForeground, returnFocus: true, whiteList: whiteListElements }, (0, _react2.jsx)(_reactScrolllock.default, null), shouldScrollInViewport ? (0, _react2.jsx)(_reactScrolllock.TouchScrollable, null, modalDialogWithBlanket) : modalDialogWithBlanket)); })); }; var _default = ModalWrapper; exports.default = _default;