@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
428 lines (427 loc) • 16.8 kB
JavaScript
;
"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 _react = _interopRequireDefault(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _Suffix = require("../../shared/helpers/Suffix");
var _Context = _interopRequireDefault(require("../../shared/Context"));
var _componentHelper = require("../../shared/component-helper");
var _SpacingHelper = require("../space/SpacingHelper");
var _HelpButtonInstance = _interopRequireDefault(require("../help-button/HelpButtonInstance"));
var _helpers = require("./helpers");
var _ModalInner = _interopRequireDefault(require("./parts/ModalInner"));
var _ModalHeader = _interopRequireDefault(require("./parts/ModalHeader"));
var _ModalHeaderBar = _interopRequireDefault(require("./parts/ModalHeaderBar"));
var _CloseButton = _interopRequireDefault(require("./parts/CloseButton"));
var _ModalRoot = _interopRequireDefault(require("./ModalRoot"));
var _withCamelCaseProps = require("../../shared/helpers/withCamelCaseProps");
const _excluded = ["root_id", "content_id", "disabled", "labelled_by", "focus_selector", "header_content", "bar_content", "bypass_invalidation_selectors", "vertical_alignment", "id", "open_delay", "omit_trigger_button", "trigger", "trigger_attributes"];
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); }
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) {
var _this;
super(props);
_this = this;
_defineProperty(this, "state", {
hide: false,
modalActive: false,
preventAutoFocus: true,
animation_duration: ANIMATION_DURATION,
no_animation: false
});
_defineProperty(this, "toggleOpenClose", function () {
let event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
let showModal = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 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) {
_this._onUnmount.push(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) {
this._onUnmount.push(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 ? 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", function (event) {
var _this$modalContentClo, _this$modalContentClo2;
let {
ifIsLatest,
triggeredBy = 'handler'
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
ifIsLatest: true
};
(_this$modalContentClo = (_this$modalContentClo2 = _this.modalContentCloseRef).current) === null || _this$modalContentClo === void 0 ? 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 (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
} = props,
rest = _objectWithoutProperties(props, _excluded);
const {
hide,
modalActive
} = this.state;
const modal_content = Modal.getContent(typeof this.props.children === 'function' ? Object.freeze(_objectSpread(_objectSpread({}, this.props), {}, {
close: this.close
})) : this.props);
const render = suffixProps => {
const triggerAttributes = _objectSpread({
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 TriggerButton = trigger ? trigger : _HelpButtonInstance.default;
const title = !triggerAttributes.text ? rest.title || 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)(props), triggerAttributes.className, triggerAttributes.class)
})), modalActive && modal_content && _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: rest.title || fallbackTitle,
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