UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

346 lines (345 loc) 16.6 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; require("core-js/modules/web.dom-collections.iterator.js"); var _react = _interopRequireDefault(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _bodyScrollLock = require("./bodyScrollLock"); var _componentHelper = require("../../shared/component-helper"); var _ModalContext = _interopRequireDefault(require("./ModalContext")); var _helpers = require("../../shared/helpers"); var _helpers2 = require("./helpers"); var _Theme = require("../../shared/Theme"); var _shared = require("../../shared"); const _excluded = ["triggeredBy"], _excluded2 = ["hide", "title", "labelled_by", "id", "close_title", "dialog_title", "hide_close_button", "close_button_attributes", "no_animation", "no_animation_on_mobile", "fullscreen", "container_placement", "vertical_alignment", "close", "content_class", "overlay_class", "content_id", "children", "dialog_role"]; function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; } function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } class ModalContent extends _react.default.PureComponent { constructor(props) { super(props); _defineProperty(this, "state", { color: null }); _defineProperty(this, "_mounted", 0); _defineProperty(this, "lockBody", () => { const modalRoots = (0, _helpers2.getListOfModalRoots)(); const firstLevel = modalRoots[0]; if (firstLevel === this) { var _this$props; this._ii = new _componentHelper.InteractionInvalidation(); this._ii.setBypassSelector(['.dnb-modal__content *', `#dnb-modal-${this.props.root_id || 'root'}`, `#dnb-modal-${this.props.root_id || 'root'} *`, ...(((_this$props = this.props) === null || _this$props === void 0 ? void 0 : _this$props.bypass_invalidation_selectors) || [])].filter(Boolean)); this._ii.activate(); } else { modalRoots.forEach(modal => { if (modal !== this && typeof modal._iiLocal === 'undefined' && typeof modal._scrollRef !== 'undefined') { modal._iiLocal = new _componentHelper.InteractionInvalidation(); modal._iiLocal.activate(modal._scrollRef.current); } }); } if (typeof document !== 'undefined') { document.addEventListener('keydown', this.onKeyDownHandler); } }); _defineProperty(this, "_androidFocusHelper", () => { const { animation_duration = null } = this.props; const timeoutDuration = typeof animation_duration === 'string' ? parseFloat(animation_duration) : animation_duration; clearTimeout(this._androidFocusTimeout); this._androidFocusTimeout = setTimeout(() => { try { var _document$activeEleme, _document$activeEleme2; if (((_document$activeEleme = document.activeElement) === null || _document$activeEleme === void 0 ? void 0 : _document$activeEleme.tagName) == 'INPUT' || ((_document$activeEleme2 = document.activeElement) === null || _document$activeEleme2 === void 0 ? void 0 : _document$activeEleme2.tagName) == 'TEXTAREA') { document.activeElement.scrollIntoView(); } } catch (e) {} }, timeoutDuration / 2); }); _defineProperty(this, "preventClick", event => { if (event) { event.stopPropagation(); } }); _defineProperty(this, "onCloseClickHandler", event => { this.closeModalContent(event, { triggeredBy: 'button' }); }); _defineProperty(this, "onContentMouseDownHandler", event => { this._overlayClickRef.current = event.target === event.currentTarget ? event.target : null; }); _defineProperty(this, "onContentClickHandler", event => { if (this._overlayClickRef.current !== event.target) { return; } this._overlayClickRef.current = null; const { prevent_overlay_close } = this.props; if (!(0, _componentHelper.isTrue)(prevent_overlay_close)) { this.closeModalContent(event, { triggeredBy: 'overlay', ifIsLatest: false }); } }); _defineProperty(this, "onKeyDownHandler", event => { switch ((0, _componentHelper.keycode)(event)) { case 'esc': { const mostCurrent = (0, _helpers2.getModalRoot)(-1); if (mostCurrent === this) { event.preventDefault(); this.closeModalContent(event, { triggeredBy: 'keyboard' }); } break; } } }); _defineProperty(this, "setModalContentState", (event, _ref) => { let { triggeredBy } = _ref; this._triggeredBy = triggeredBy; this._triggeredByEvent = event; }); _defineProperty(this, "setBackgroundColor", color => { this.setState({ color }); }); this._contentRef = this.props.content_ref || _react.default.createRef(); this._scrollRef = this.props.scroll_ref || _react.default.createRef(); this._overlayClickRef = _react.default.createRef(); if (this.props.modalContentCloseRef) { this.props.modalContentCloseRef.current = this.setModalContentState; } this._id = props.id; } componentDidMount() { const { id = null, no_animation = false, animation_duration = null } = this.props; const timeoutDuration = typeof animation_duration === 'string' ? parseFloat(animation_duration) : animation_duration; (0, _helpers2.addToIndex)(this); this.removeScrollPossibility(); this.setFocus(); this.setAndroidFocusHelper(); (0, _componentHelper.dispatchCustomElementEvent)(this, 'on_open', { id }); if ((0, _componentHelper.isTrue)(no_animation) || process.env.NODE_ENV === 'test') { this.lockBody(); } else { this._lockTimeout = setTimeout(this.lockBody, timeoutDuration * 1.2); } this._mounted = Date.now(); } componentWillUnmount() { clearTimeout(this._focusTimeout); clearTimeout(this._lockTimeout); this.removeLocks(); this._mounted = 0; } wasOpenedManually() { if (this._triggeredBy) { return true; } const { open_state } = this.props; if (typeof open_state === 'boolean' || typeof open_state === 'string') { if (process.env.NODE_ENV !== 'test') { const delay = Date.now() - this._mounted; return delay > 30; } return true; } return false; } removeLocks() { const modalRoots = (0, _helpers2.getListOfModalRoots)(); const firstLevel = modalRoots[0]; (0, _helpers2.removeFromIndex)(this); if (firstLevel === this) { var _this$_ii; (_this$_ii = this._ii) === null || _this$_ii === void 0 ? void 0 : _this$_ii.revert(); this.revertScrollPossibility(); } else { try { const modal = modalRoots[modalRoots.length - 2]; if (modal !== this && modal._iiLocal) { modal._iiLocal.revert(); delete modal._iiLocal; } } catch (e) { (0, _componentHelper.warn)(e); } } this.removeAndroidFocusHelper(); if (this.wasOpenedManually()) { const id = this.props.id; (0, _componentHelper.dispatchCustomElementEvent)(this, 'on_close', { id, event: this._triggeredByEvent, triggeredBy: this._triggeredBy || 'unmount' }); } if (typeof document !== 'undefined') { document.removeEventListener('keydown', this.onKeyDownHandler); } } setAndroidFocusHelper() { if (typeof window !== 'undefined' && (0, _helpers.isAndroid)()) { window.addEventListener('resize', this._androidFocusHelper); } } removeAndroidFocusHelper() { window.removeEventListener('resize', this._androidFocusHelper); clearTimeout(this._androidFocusTimeout); } setFocus() { const { focus_selector = null, no_animation = null, animation_duration = null } = this.props; const elem = this._contentRef.current; const timeoutDuration = typeof animation_duration === 'string' ? parseFloat(animation_duration) : animation_duration; if (elem) { clearTimeout(this._focusTimeout); this._focusTimeout = setTimeout(() => { try { var _focusElement, _focusElement$focus, _focusElement2, _focusElement2$select, _elem$parentElement, _elem$parentElement$q, _elem$parentElement2, _elem$parentElement2$; let focusElement = elem; if (typeof focus_selector === 'string') { focusElement = elem.querySelector(focus_selector); } (_focusElement = focusElement) === null || _focusElement === void 0 ? void 0 : (_focusElement$focus = _focusElement.focus) === null || _focusElement$focus === void 0 ? void 0 : _focusElement$focus.call(_focusElement); (_focusElement2 = focusElement) === null || _focusElement2 === void 0 ? void 0 : (_focusElement2$select = _focusElement2.select) === null || _focusElement2$select === void 0 ? void 0 : _focusElement2$select.call(_focusElement2); const noH1Elem = elem.querySelector('h1, h2, h3'); const noH1ElemInDrawerHeader = (_elem$parentElement = elem.parentElement) === null || _elem$parentElement === void 0 ? void 0 : (_elem$parentElement$q = _elem$parentElement.querySelector('.dnb-drawer__header')) === null || _elem$parentElement$q === void 0 ? void 0 : _elem$parentElement$q.querySelector('h1, h2, h3'); const noH1ElemInDialogHeader = (_elem$parentElement2 = elem.parentElement) === null || _elem$parentElement2 === void 0 ? void 0 : (_elem$parentElement2$ = _elem$parentElement2.querySelector('.dnb-dialog__header')) === null || _elem$parentElement2$ === void 0 ? void 0 : _elem$parentElement2$.querySelector('h1, h2, h3'); if ((noH1Elem === null || noH1Elem === void 0 ? void 0 : noH1Elem.tagName) !== 'H1' && (noH1ElemInDrawerHeader === null || noH1ElemInDrawerHeader === void 0 ? void 0 : noH1ElemInDrawerHeader.tagName) !== 'H1' && (noH1ElemInDialogHeader === null || noH1ElemInDialogHeader === void 0 ? void 0 : noH1ElemInDialogHeader.tagName) !== 'H1') { (0, _componentHelper.warn)('A Dialog or Drawer needs a h1 as its first element!'); } } catch (e) { (0, _componentHelper.warn)(e); } }, (0, _componentHelper.isTrue)(no_animation) ? 0 : timeoutDuration || 0); } } removeScrollPossibility() { if (this._scrollRef.current) { (0, _bodyScrollLock.disableBodyScroll)(this._scrollRef.current); } } revertScrollPossibility() { (0, _bodyScrollLock.enableBodyScroll)(this._scrollRef.current); (0, _bodyScrollLock.clearAllBodyScrollLocks)(); } closeModalContent(event, _ref2) { var _event$persist; let { triggeredBy } = _ref2, params = _objectWithoutProperties(_ref2, _excluded); event === null || event === void 0 ? void 0 : (_event$persist = event.persist) === null || _event$persist === void 0 ? void 0 : _event$persist.call(event); this.props.close(event, _objectSpread({ triggeredBy }, params)); } render() { var _this$context; const _this$props2 = this.props, { hide, title, labelled_by, id: _id, close_title = 'Lukk', dialog_title = 'Vindu', hide_close_button = false, close_button_attributes, no_animation = false, no_animation_on_mobile = false, fullscreen = 'auto', container_placement = 'right', vertical_alignment = 'center', close, content_class, overlay_class, content_id, children, dialog_role = null } = _this$props2, rest = _objectWithoutProperties(_this$props2, _excluded2); const { color } = this.state; const contentId = content_id || (0, _componentHelper.makeUniqueId)('modal-'); const useDialogRole = !(_helpers.IS_MAC || _helpers.IS_SAFARI || _helpers.IS_IOS); let role = dialog_role || 'dialog'; if (!useDialogRole && role === 'dialog') { role = 'region'; } const contentParams = { role, 'aria-modal': useDialogRole ? true : undefined, 'aria-labelledby': (0, _componentHelper.combineLabelledBy)(this.props, title ? contentId + '-title' : null, labelled_by), 'aria-describedby': (0, _componentHelper.combineDescribedBy)(this.props, contentId + '-content'), 'aria-label': !title && !labelled_by ? dialog_title : undefined, className: (0, _classnames.default)(`dnb-modal__content dnb-modal__vertical-alignment--${vertical_alignment}`, (0, _componentHelper.isTrue)(fullscreen) ? 'dnb-modal__content--fullscreen' : fullscreen === 'auto' && 'dnb-modal__content--auto-fullscreen', (0, _Theme.getThemeClasses)((_this$context = this.context) === null || _this$context === void 0 ? void 0 : _this$context.theme), content_class, container_placement && `dnb-modal__content--${container_placement || 'right'}`), onMouseDown: this.onContentMouseDownHandler, onClick: this.onContentClickHandler }; const content = typeof children === 'function' ? children(_objectSpread(_objectSpread({}, rest), {}, { close })) : children; return _react.default.createElement(_ModalContext.default.Provider, { value: { id: this.props.id, title, hide_close_button, close_button_attributes, close_title, hide, setBackgroundColor: this.setBackgroundColor, onCloseClickHandler: this.onCloseClickHandler, preventClick: this.preventClick, onKeyDownHandler: this.onKeyDownHandler, contentRef: this._contentRef, scrollRef: this._scrollRef, contentId, close } }, _react.default.createElement("div", _extends({ id: contentId, style: color ? { '--modal-background-color': `var(--color-${color})` } : null }, contentParams), content), _react.default.createElement("span", { className: (0, _classnames.default)('dnb-modal__overlay', overlay_class, hide && 'dnb-modal__overlay--hide', (0, _componentHelper.isTrue)(no_animation) && 'dnb-modal__overlay--no-animation', (0, _componentHelper.isTrue)(no_animation_on_mobile) && 'dnb-modal__overlay--no-animation-on-mobile'), "aria-hidden": true })); } } exports.default = ModalContent; _defineProperty(ModalContent, "contextType", _shared.Context); //# sourceMappingURL=ModalContent.js.map