@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
432 lines (431 loc) • 15.4 kB
JavaScript
"use strict";
"use client";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ANIMATION_DURATION = void 0;
Object.defineProperty(exports, "CloseButton", {
enumerable: true,
get: function () {
return _CloseButton.default;
}
});
exports.default = exports.OriginalComponent = void 0;
var _push = _interopRequireDefault(require("core-js-pure/stable/instance/push.js"));
var _react = _interopRequireDefault(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _Suffix = require("../../shared/helpers/Suffix.js");
var _Context = _interopRequireDefault(require("../../shared/Context.js"));
var _componentHelper = require("../../shared/component-helper.js");
var _SpacingHelper = require("../space/SpacingHelper.js");
var _HelpButtonInstance = _interopRequireDefault(require("../help-button/HelpButtonInstance.js"));
var _helpers = require("./helpers.js");
var _ModalInner = _interopRequireDefault(require("./parts/ModalInner.js"));
var _ModalHeader = _interopRequireDefault(require("./parts/ModalHeader.js"));
var _ModalHeaderBar = _interopRequireDefault(require("./parts/ModalHeaderBar.js"));
var _CloseButton = _interopRequireDefault(require("./parts/CloseButton.js"));
var _ModalRoot = _interopRequireDefault(require("./ModalRoot.js"));
var _P = require("../../elements/typography/P.js");
var _withCamelCaseProps = require("../../shared/helpers/withCamelCaseProps.js");
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 _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); }
const ANIMATION_DURATION = exports.ANIMATION_DURATION = 300;
class Modal extends _react.default.PureComponent {
static getContent(props) {
if (typeof props.modal_content === 'string') {
return props.modal_content;
} else if (typeof props.modal_content === 'function') {
return props.modal_content(props);
}
return (0, _componentHelper.processChildren)(props);
}
static getDerivedStateFromProps(props, state) {
if (typeof window !== 'undefined' && window['IS_TEST']) {
state.animation_duration = 0;
state.no_animation = true;
} else {
state.animation_duration = props.animation_duration;
state.no_animation = props.no_animation;
}
if (props.open_state !== state._open_state) {
switch (props.open_state) {
case 'opened':
case true:
state.hide = false;
if ((0, _componentHelper.isTrue)(state.no_animation)) {
state.modalActive = true;
}
break;
case 'closed':
case false:
state.hide = true;
if ((0, _componentHelper.isTrue)(state.no_animation)) {
state.modalActive = false;
}
break;
}
}
state._open_state = props.open_state;
return state;
}
constructor(props) {
super(props);
_defineProperty(this, "state", {
hide: false,
modalActive: false,
preventAutoFocus: true,
animation_duration: ANIMATION_DURATION,
no_animation: false
});
_defineProperty(this, "toggleOpenClose", (event = null, showModal = null) => {
if (event && event.preventDefault) {
event.preventDefault();
}
const toggleNow = () => {
const {
animation_duration = ANIMATION_DURATION,
no_animation = false
} = this.state;
const timeoutDuration = typeof animation_duration === 'string' ? parseFloat(animation_duration) : animation_duration;
const modalActive = typeof showModal === 'boolean' ? showModal : !this.state.modalActive;
this.isInTransition = true;
const doItNow = () => {
this.setState({
hide: false,
modalActive
}, () => {
this.isInTransition = false;
this.handleSideEffects();
});
};
if (modalActive === false && !(0, _componentHelper.isTrue)(no_animation)) {
this.setState({
hide: true
});
this._closeTimeout = setTimeout(doItNow, timeoutDuration);
} else {
doItNow();
}
};
const waitBeforeOpen = () => {
const {
open_delay
} = this.props;
const {
no_animation
} = this.state;
const delay = typeof open_delay === 'string' ? parseFloat(open_delay) : open_delay;
if (delay > 0 && !(0, _componentHelper.isTrue)(no_animation)) {
this._openTimeout = setTimeout(toggleNow, delay);
} else {
toggleNow();
}
};
clearTimeout(this._closeTimeout);
clearTimeout(this._openTimeout);
const {
open_modal
} = this.props;
if (typeof open_modal === 'function') {
const fn = open_modal(waitBeforeOpen, this);
if (fn) {
var _context;
(0, _push.default)(_context = this._onUnmount).call(_context, fn);
}
} else {
waitBeforeOpen();
}
});
_defineProperty(this, "handleSideEffects", () => {
const {
modalActive,
preventAutoFocus,
animation_duration
} = this.state;
const {
close_modal,
open_state
} = this.props;
if (modalActive) {
if (typeof close_modal === 'function') {
const fn = close_modal(() => {
this.toggleOpenClose(null, false);
}, this);
if (fn) {
var _context2;
(0, _push.default)(_context2 = this._onUnmount).call(_context2, fn);
}
}
this.setActiveState(this._id);
} else if (modalActive === false && !preventAutoFocus) {
var _this$_triggerRef;
const focus = elem => {
elem.setAttribute('data-autofocus', 'true');
elem.focus({
preventScroll: true
});
return new Promise(resolve => {
setTimeout(() => {
elem === null || elem === void 0 || elem.removeAttribute('data-autofocus');
resolve();
}, parseFloat(String(animation_duration)) / 3);
});
};
if ((_this$_triggerRef = this._triggerRef) !== null && _this$_triggerRef !== void 0 && _this$_triggerRef.current) {
focus(this._triggerRef.current);
}
if ((open_state === 'opened' || open_state === true) && this.activeElement instanceof HTMLElement) {
try {
focus(this.activeElement).then(() => {
this.activeElement = null;
});
} catch (e) {}
}
this.removeActiveState();
}
if (preventAutoFocus) {
this.setState({
preventAutoFocus: false
});
}
});
_defineProperty(this, "open", e => {
this.toggleOpenClose(e, true);
});
_defineProperty(this, "close", (event, {
ifIsLatest,
triggeredBy = 'handler'
} = {
ifIsLatest: true
}) => {
var _this$modalContentClo, _this$modalContentClo2;
(_this$modalContentClo = (_this$modalContentClo2 = this.modalContentCloseRef).current) === null || _this$modalContentClo === void 0 || _this$modalContentClo.call(_this$modalContentClo2, event, {
triggeredBy
});
const {
prevent_close = false
} = this.props;
if ((0, _componentHelper.isTrue)(prevent_close)) {
const id = this._id;
(0, _componentHelper.dispatchCustomElementEvent)(this, 'on_close_prevent', {
id,
event,
triggeredBy,
close: e => {
this.toggleOpenClose(e, false);
}
});
} else {
if (ifIsLatest) {
const list = (0, _helpers.getListOfModalRoots)();
if (list.length > 1) {
const last = (0, _helpers.getModalRoot)(-1);
if (last !== this) {
return;
}
}
}
this.toggleOpenClose(event, false);
}
});
this._id = props.id || (0, _componentHelper.makeUniqueId)('modal-');
this._triggerRef = _react.default.createRef();
this.modalContentCloseRef = _react.default.createRef();
this._onUnmount = [];
}
componentDidMount() {
this.openBasedOnStateUpdate();
}
componentWillUnmount() {
clearTimeout(this._openTimeout);
clearTimeout(this._closeTimeout);
this.removeActiveState();
this._onUnmount.forEach(fn => {
if (typeof fn === 'function') {
fn();
}
});
}
componentDidUpdate(prevProps) {
if (this.isInTransition) {
return;
}
if (prevProps !== this.props) {
this.openBasedOnStateUpdate();
}
}
openBasedOnStateUpdate() {
const {
hide
} = this.state;
const {
open_state
} = this.props;
if (!this.activeElement && typeof document !== 'undefined') {
this.activeElement = document.activeElement;
}
if (!hide && (open_state === 'opened' || open_state === true)) {
this.toggleOpenClose(null, true);
} else if (hide && (open_state === 'closed' || open_state === false)) {
this.toggleOpenClose(null, false);
}
}
removeActiveState() {
const last = (0, _helpers.getModalRoot)(-1);
if (last !== null && last !== void 0 && last._id && last._id !== this._id) {
return this.setActiveState(last._id);
}
try {
document.documentElement.removeAttribute('data-dnb-modal-active');
} catch (e) {
(0, _componentHelper.warn)('Modal: Error on remove "data-dnb-modal-active"', e);
}
}
setActiveState(modalId) {
if (!modalId) {
(0, _componentHelper.warn)('Modal: A valid modalId is required');
}
if (typeof document !== 'undefined') {
try {
document.documentElement.setAttribute('data-dnb-modal-active', modalId);
} catch (e) {
(0, _componentHelper.warn)('Modal: Error on set "data-dnb-modal-active"', e);
}
}
}
render() {
const visualTestsPropsOverride = typeof window !== 'undefined' && window['IS_TEST'] ? {
animation_duration: 0,
no_animation: true
} : {};
const props = (0, _componentHelper.extendPropsWithContextInClassComponent)(this.props, Modal.defaultProps, this.context.getTranslation(this.props).Modal, this.context.Modal, visualTestsPropsOverride);
const {
root_id = 'root',
content_id = null,
disabled = null,
labelled_by = null,
focus_selector = null,
header_content = null,
bar_content = null,
bypass_invalidation_selectors = null,
vertical_alignment = 'center',
id,
open_delay,
omit_trigger_button = false,
trigger = null,
trigger_attributes = null,
...rest
} = props;
const {
hide,
modalActive
} = this.state;
const modal_content = Modal.getContent(typeof this.props.children === 'function' ? Object.freeze({
...this.props,
close: this.close
}) : this.props);
const render = suffixProps => {
const triggerAttributes = {
hidden: false,
variant: 'secondary',
icon_position: 'left',
...trigger_attributes
};
if ((0, _componentHelper.isTrue)(disabled)) {
triggerAttributes.disabled = true;
}
if (triggerAttributes.id) {
this._id = triggerAttributes.id;
}
let fallbackTitle;
if (triggerAttributes.title) {
fallbackTitle = triggerAttributes.title;
} else if (suffixProps) {
fallbackTitle = this.context.translation.HelpButton.title;
}
const headerTitle = rest.title || fallbackTitle;
const TriggerButton = trigger ? trigger : _HelpButtonInstance.default;
const title = !triggerAttributes.text && headerTitle ? headerTitle || fallbackTitle : null;
return _react.default.createElement(_react.default.Fragment, null, TriggerButton && !(0, _componentHelper.isTrue)(omit_trigger_button) && _react.default.createElement(TriggerButton, _extends({}, triggerAttributes, {
id: this._id,
title: title,
onClick: this.toggleOpenClose,
innerRef: this._triggerRef,
className: (0, _classnames.default)('dnb-modal__trigger', (0, _SpacingHelper.createSpacingClasses)(rest), triggerAttributes.className, triggerAttributes.class)
})), modalActive && modal_content && _react.default.createElement(_P.ParagraphContext.Provider, {
value: {
isNested: false
}
}, _react.default.createElement(_ModalRoot.default, _extends({}, rest, {
id: this._id,
root_id: root_id,
content_id: content_id || `dnb-modal-${this._id}`,
labelled_by: labelled_by,
focus_selector: focus_selector,
modal_content: modal_content,
header_content: header_content,
vertical_alignment: vertical_alignment,
bar_content: bar_content,
bypass_invalidation_selectors: bypass_invalidation_selectors,
close: this.close,
hide: hide,
title: headerTitle,
modalContentCloseRef: this.modalContentCloseRef
}))));
};
return _react.default.createElement(_Suffix.SuffixContext.Consumer, null, render);
}
}
exports.OriginalComponent = Modal;
_defineProperty(Modal, "contextType", _Context.default);
_defineProperty(Modal, "Bar", _ModalHeaderBar.default);
_defineProperty(Modal, "Header", _ModalHeader.default);
_defineProperty(Modal, "Content", _ModalInner.default);
_defineProperty(Modal, "defaultProps", {
id: null,
focus_selector: null,
labelled_by: null,
title: null,
disabled: null,
spacing: true,
open_delay: null,
content_id: null,
dialog_title: 'Vindu',
close_title: 'Lukk',
hide_close_button: false,
close_button_attributes: null,
prevent_close: false,
prevent_core_style: false,
animation_duration: ANIMATION_DURATION,
no_animation: false,
no_animation_on_mobile: false,
fullscreen: 'auto',
min_width: null,
max_width: null,
align_content: 'left',
container_placement: null,
vertical_alignment: null,
open_state: null,
direct_dom_return: false,
root_id: 'root',
omit_trigger_button: false,
className: null,
children: null,
on_open: null,
on_close: null,
on_close_prevent: null,
open_modal: null,
close_modal: null,
trigger: null,
trigger_attributes: null,
overlay_class: null,
content_class: null,
modal_content: null,
header_content: null,
bar_content: null
});
var _default = exports.default = (0, _withCamelCaseProps.classWithCamelCaseProps)(Modal);
//# sourceMappingURL=Modal.js.map