@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
JavaScript
"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;