@atlaskit/modal-dialog
Version:
A modal dialog displays content that requires user interaction, in a layer above the page.
176 lines (172 loc) • 9.6 kB
JavaScript
/* modal-wrapper.tsx generated by @compiled/babel-plugin v0.39.1 */
"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;
require("./modal-wrapper.compiled.css");
var _react = _interopRequireWildcard(require("react"));
var React = _react;
var _runtime = require("@compiled/react/runtime");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
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 _layering = require("@atlaskit/layering");
var _openLayerObserver = require("@atlaskit/layering/experimental/open-layer-observer");
var _motion = require("@atlaskit/motion");
var _fadeIn = _interopRequireDefault(require("@atlaskit/motion/fade-in"));
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
var _portal = _interopRequireDefault(require("@atlaskit/portal"));
var _constants = require("@atlaskit/theme/constants");
var _useModalStack = _interopRequireDefault(require("../hooks/use-modal-stack"));
var _usePreventProgrammaticScroll = _interopRequireDefault(require("../hooks/use-prevent-programmatic-scroll"));
var _modalDialog = _interopRequireDefault(require("./modal-dialog"));
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
var fillScreenStyles = null;
var allowlistElements = function allowlistElements(element, callback) {
// Allow focus to reach elements outside the modal:
// if AUI dialog is allowListed and visible
if (!!document.querySelector('.aui-blanket:not([hidden])')) {
return false;
}
// allows to pass a callback function to allow elements be ignored by focus lock
if (typeof callback === 'function') {
return callback(element);
}
return true;
};
/**
* __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 InternalModalWrapper = function InternalModalWrapper(props) {
var _props$autoFocus = props.autoFocus,
autoFocus = _props$autoFocus === void 0 ? true : _props$autoFocus,
focusLockAllowlist = props.focusLockAllowlist,
_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,
_props$shouldReturnFo = props.shouldReturnFocus,
shouldReturnFocus = _props$shouldReturnFo === void 0 ? true : _props$shouldReturnFo,
stackIndexOverride = props.stackIndex,
providedOnClose = 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,
label = props.label,
testId = props.testId,
isFullScreen = props.isFullScreen;
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
// When flag is true and a ref is not supplied, autofocus is true. See https://product-fabric.atlassian.net/browse/DSP-24307
// When we remove boolean `autoFocus`, we won't have to worry about this
var autoFocusLock = (0, _platformFeatureFlags.fg)('platform_dst_autofocus-never-false-2') ? typeof autoFocus === 'boolean' : typeof autoFocus === 'boolean' ? autoFocus : false;
var onCloseHandler = (0, _analyticsNext.usePlatformLeafEventHandler)({
fn: providedOnClose || _noop.default,
action: 'closed',
componentName: 'modalDialog',
packageName: "@atlaskit/modal-dialog",
packageVersion: "14.14.2"
});
var onBlanketClicked = (0, _react.useCallback)(function (e) {
if (shouldCloseOnOverlayClick) {
onCloseHandler(e);
}
}, [shouldCloseOnOverlayClick, onCloseHandler]);
// This ensures to prevent additional re-renders while nothing is passed to focusLockAllowlist explicitly.
var allowListCallback = (0, _react.useCallback)(function (element) {
return allowlistElements(element, focusLockAllowlist);
}, [focusLockAllowlist]);
(0, _usePreventProgrammaticScroll.default)();
(0, _openLayerObserver.useNotifyOpenLayerObserver)({
type: 'modal',
// Modal dialog is conditionally rendered when visible, so when this runs it is always open.
isOpen: true,
// Passing a no-op for now, as there isn't a real use case for closing the modal dialog programmatically
// by the OpenLayerObserver. The only current use case is closing layers when resizing the nav layout,
// which cannot happen while a modal dialog is open.
onClose: _noop.default
});
var modalDialogWithBlanket = /*#__PURE__*/React.createElement(_blanket.default, {
isTinted: !isBlanketHidden,
onBlanketClicked: onBlanketClicked,
testId: testId && "".concat(testId, "--blanket")
}, /*#__PURE__*/React.createElement(_modalDialog.default, {
testId: testId,
label: label,
autoFocus: autoFocus,
stackIndex: stackIndex,
onClose: onCloseHandler,
shouldCloseOnEscapePress: shouldCloseOnEscapePress && isForeground,
shouldScrollInViewport: shouldScrollInViewport,
height: height,
width: width,
onCloseComplete: onCloseComplete,
onOpenComplete: onOpenComplete,
hasProvidedOnClose: Boolean(providedOnClose),
isFullScreen: isFullScreen
}, children));
var returnFocus = true;
var onDeactivation = _noop.default;
if ('boolean' === typeof shouldReturnFocus) {
returnFocus = shouldReturnFocus;
} else {
onDeactivation = function onDeactivation() {
window.setTimeout(function () {
var _shouldReturnFocus$cu;
(_shouldReturnFocus$cu = shouldReturnFocus.current) === null || _shouldReturnFocus$cu === void 0 || _shouldReturnFocus$cu.focus();
}, 0);
};
}
return /*#__PURE__*/React.createElement(_layering.Layering, {
isDisabled: false
}, /*#__PURE__*/React.createElement(_portal.default, {
zIndex: _constants.layers.modal()
}, (0, _platformFeatureFlags.fg)('platform-dst-motion-uplift') ? /*#__PURE__*/React.createElement(_motion.Motion, {
enteringAnimation: "var(--ds-content-enter-medium, 200ms cubic-bezier(0.4, 0, 0, 1) FadeIn)",
exitingAnimation: "var(--ds-content-exit-long, 200ms cubic-bezier(0.4, 0, 0, 1) FadeOut)"
}, /*#__PURE__*/React.createElement("div", {
"aria-hidden": !isForeground,
className: (0, _runtime.ax)(["_1bsbauwl _4t3i1kxc _kqsw1n9t _152tze3t _1e02ze3t _18m91wug _8am5i4x0"])
}, /*#__PURE__*/React.createElement(_reactFocusLock.default, {
autoFocus: autoFocusLock,
returnFocus: returnFocus,
onDeactivation: onDeactivation,
whiteList: allowListCallback
}, /*#__PURE__*/React.createElement(_reactScrolllock.default, null), shouldScrollInViewport ? /*#__PURE__*/React.createElement(_reactScrolllock.TouchScrollable, null, modalDialogWithBlanket) : modalDialogWithBlanket))) : /*#__PURE__*/React.createElement(_fadeIn.default, null, function (fadeInProps) {
return /*#__PURE__*/React.createElement("div", (0, _extends2.default)({}, fadeInProps, {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
className: (0, _runtime.ax)(["_1bsbauwl _4t3i1kxc _kqsw1n9t _152tze3t _1e02ze3t _18m91wug _8am5i4x0", fadeInProps.className]),
"aria-hidden": !isForeground
}), /*#__PURE__*/React.createElement(_reactFocusLock.default, {
autoFocus: autoFocusLock,
returnFocus: returnFocus,
onDeactivation: onDeactivation,
whiteList: allowListCallback
}, /*#__PURE__*/React.createElement(_reactScrolllock.default, null), shouldScrollInViewport ? /*#__PURE__*/React.createElement(_reactScrolllock.TouchScrollable, null, modalDialogWithBlanket) : modalDialogWithBlanket));
})));
};
var _default = exports.default = InternalModalWrapper;