@atlaskit/modal-dialog
Version:
A modal dialog displays content that requires user interaction, in a layer above the page.
120 lines (118 loc) • 5.96 kB
JavaScript
;
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 _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = _interopRequireWildcard(require("react"));
var _react2 = require("@emotion/react");
var _bindEventListener = require("bind-event-listener");
var _rafSchd = _interopRequireDefault(require("raf-schd"));
var _mergeRefs = _interopRequireDefault(require("@atlaskit/ds-lib/merge-refs"));
var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
var _useLazyCallback = _interopRequireDefault(require("@atlaskit/ds-lib/use-lazy-callback"));
var _useStateRef3 = _interopRequireDefault(require("@atlaskit/ds-lib/use-state-ref"));
var _focusRing = _interopRequireDefault(require("@atlaskit/focus-ring"));
var _constants = require("../constants");
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 baseStyles = (0, _react2.css)({
display: 'inherit',
margin: "var(--ds-space-0, 0px)",
flex: 'inherit',
flexDirection: 'inherit',
flexGrow: 1,
overflowX: 'hidden',
overflowY: 'auto',
'@media (min-width: 480px)': {
height: 'unset',
overflowY: 'auto'
}
});
var topKeylineStyles = (0, _react2.css)({
borderTop: "".concat(_constants.keylineHeight, "px solid ").concat(_constants.keylineColor)
});
var bottomKeylineStyles = (0, _react2.css)({
borderBottom: "".concat(_constants.keylineHeight, "px solid ").concat(_constants.keylineColor)
});
/**
* A container that shows top and bottom keylines when the
* content overflows into the scrollable element.
*/
var ScrollContainer = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
var testId = props.testId,
children = props.children;
var _useStateRef = (0, _useStateRef3.default)({
previous: false,
next: false
}),
_useStateRef2 = (0, _slicedToArray2.default)(_useStateRef, 2),
hasSiblings = _useStateRef2[0],
setSiblings = _useStateRef2[1];
var _useState = (0, _react.useState)(false),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
showContentFocus = _useState2[0],
setContentFocus = _useState2[1];
var _useState3 = (0, _react.useState)(false),
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
showTopKeyline = _useState4[0],
setTopKeyline = _useState4[1];
var _useState5 = (0, _react.useState)(false),
_useState6 = (0, _slicedToArray2.default)(_useState5, 2),
showBottomKeyline = _useState6[0],
setBottomKeyline = _useState6[1];
var scrollableRef = (0, _react.useRef)(null);
var setLazySiblings = (0, _useLazyCallback.default)(setSiblings);
var setLazyContentFocus = (0, _useLazyCallback.default)((0, _rafSchd.default)(function () {
var target = scrollableRef.current;
target && setContentFocus(target.scrollHeight > target.clientHeight);
}));
var setLazyKeylines = (0, _useLazyCallback.default)((0, _rafSchd.default)(function () {
var target = scrollableRef.current;
if (target) {
var scrollableDistance = target.scrollHeight - target.clientHeight;
if (hasSiblings.current.previous) {
setTopKeyline(target.scrollTop > _constants.keylineHeight);
}
if (hasSiblings.current.next) {
setBottomKeyline(target.scrollTop <= scrollableDistance - _constants.keylineHeight);
}
}
}));
(0, _react.useEffect)(function () {
var target = scrollableRef.current;
var unbindWindowEvent = (0, _bindEventListener.bind)(window, {
type: 'resize',
listener: setLazyKeylines
});
var unbindTargetEvent = target ? (0, _bindEventListener.bind)(target, {
type: 'scroll',
listener: setLazyKeylines
}) : _noop.default;
setLazyContentFocus();
setLazyKeylines();
setLazySiblings({
previous: Boolean(target === null || target === void 0 ? void 0 : target.previousElementSibling),
next: Boolean(target === null || target === void 0 ? void 0 : target.nextElementSibling)
});
return function () {
unbindWindowEvent();
unbindTargetEvent();
};
}, [setLazyContentFocus, setLazyKeylines, setLazySiblings]);
return (0, _react2.jsx)(_focusRing.default, {
isInset: true
}, (0, _react2.jsx)("div", {
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
tabIndex: showContentFocus ? 0 : undefined,
"data-testid": testId && "".concat(testId, "--scrollable"),
ref: (0, _mergeRefs.default)([ref, scrollableRef]),
css: [baseStyles, showTopKeyline && topKeylineStyles, showBottomKeyline && bottomKeylineStyles]
}, children));
});
ScrollContainer.displayName = 'ScrollContainer';
var _default = ScrollContainer;
exports.default = _default;