UNPKG

@atlaskit/modal-dialog

Version:

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

141 lines (138 loc) 5.55 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _react = require("react"); var _react2 = require("@emotion/react"); var _reactUid = require("react-uid"); var _mergeRefs = _interopRequireDefault(require("@atlaskit/ds-lib/merge-refs")); var _useAutoFocus = _interopRequireDefault(require("@atlaskit/ds-lib/use-auto-focus")); var _focusRing = _interopRequireDefault(require("@atlaskit/focus-ring")); var _fadeIn = _interopRequireDefault(require("@atlaskit/motion/fade-in")); var _colors = require("@atlaskit/theme/colors"); var _constants = require("../constants"); var _context = require("../context"); var _useOnMotionFinish3 = _interopRequireDefault(require("../hooks/use-on-motion-finish")); var _utils = require("../utils"); var _positioner = _interopRequireDefault(require("./positioner")); /** @jsx jsx */ var dialogStyles = (0, _react2.css)({ display: 'flex', width: '100%', maxWidth: '100vw', height: '100%', minHeight: 0, maxHeight: '100vh', // Flex-grow set to 0 to prevent this element from filling its parent flexbox container flex: '0 1 auto', flexDirection: 'column', backgroundColor: "var(--ds-surface-overlay, ".concat(_colors.N0, ")"), color: _constants.textColor, pointerEvents: 'auto', '@media (min-width: 480px)': { width: 'var(--modal-dialog-width)', maxWidth: 'inherit', // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing marginRight: 'inherit', // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing marginLeft: 'inherit', borderRadius: _constants.borderRadius, boxShadow: "var(--ds-shadow-overlay, ".concat("0 0 0 1px ".concat(_colors.N30A, ", 0 2px 1px ").concat(_colors.N30A, ", 0 0 20px -6px ").concat(_colors.N60A), ")") }, /** * This is to support scrolling if the modal's children are wrapped in * a form. */ // eslint-disable-next-line @repo/internal/styles/no-nested-styles '& > form:only-child': { display: 'inherit', maxHeight: 'inherit', flexDirection: 'inherit' } }); var viewportScrollStyles = (0, _react2.css)({ /** * This ensures that the element fills the viewport on mobile * while also allowing it to overflow if its height is larger than * the viewport. */ minHeight: '100vh', maxHeight: 'none', '@media (min-width: 480px)': { minHeight: 'var(--modal-dialog-height)' } }); var bodyScrollStyles = (0, _react2.css)({ '@media (min-width: 480px)': { height: 'var(--modal-dialog-height)', maxHeight: 'inherit' } }); var ModalDialog = function ModalDialog(props) { var _props$width = props.width, width = _props$width === void 0 ? 'medium' : _props$width, _props$shouldScrollIn = props.shouldScrollInViewport, shouldScrollInViewport = _props$shouldScrollIn === void 0 ? false : _props$shouldScrollIn, autoFocus = props.autoFocus, stackIndex = props.stackIndex, onClose = props.onClose, onCloseComplete = props.onCloseComplete, onOpenComplete = props.onOpenComplete, height = props.height, children = props.children, testId = props.testId; var id = (0, _reactUid.useUID)(); var titleId = "modal-dialog-title-".concat(id); (0, _useAutoFocus.default)((0, _typeof2.default)(autoFocus) === 'object' ? autoFocus : undefined, // When a user supplies a ref to focus we enable this hook (0, _typeof2.default)(autoFocus) === 'object'); var _useOnMotionFinish = (0, _useOnMotionFinish3.default)({ onOpenComplete: onOpenComplete, onCloseComplete: onCloseComplete }), _useOnMotionFinish2 = (0, _slicedToArray2.default)(_useOnMotionFinish, 2), motionRef = _useOnMotionFinish2[0], onMotionFinish = _useOnMotionFinish2[1]; var modalDialogContext = (0, _react.useMemo)(function () { return { testId: testId, titleId: titleId, onClose: onClose }; }, [testId, titleId, onClose]); return (0, _react2.jsx)(_positioner.default, { stackIndex: stackIndex, shouldScrollInViewport: shouldScrollInViewport, testId: testId }, (0, _react2.jsx)(_context.ModalContext.Provider, { value: modalDialogContext }, (0, _react2.jsx)(_context.ScrollContext.Provider, { value: shouldScrollInViewport }, (0, _react2.jsx)(_fadeIn.default, { entranceDirection: "bottom", onFinish: onMotionFinish }, function (bottomFadeInProps) { return (0, _react2.jsx)(_focusRing.default, null, (0, _react2.jsx)("section", (0, _extends2.default)({}, bottomFadeInProps, { ref: (0, _mergeRefs.default)([bottomFadeInProps.ref, motionRef]), style: { '--modal-dialog-width': (0, _utils.dialogWidth)(width), '--modal-dialog-height': (0, _utils.dialogHeight)(height) }, css: [dialogStyles, shouldScrollInViewport ? viewportScrollStyles : bodyScrollStyles], role: "dialog", "aria-labelledby": titleId, "data-testid": testId, "data-modal-stack": stackIndex, tabIndex: -1, "aria-modal": true }), children)); })))); }; // eslint-disable-next-line @repo/internal/react/require-jsdoc var _default = ModalDialog; exports.default = _default;