UNPKG

jiro-ui

Version:

A Mithril.js UI library based from construct-ui

230 lines (229 loc) 9.87 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Overlay = void 0; var tslib_1 = require("tslib"); var classnames_1 = tslib_1.__importDefault(require("classnames")); var mithril_1 = tslib_1.__importDefault(require("mithril")); var _shared_1 = require("../../_shared"); var abstract_component_1 = require("../abstract-component"); var portal_1 = require("../portal"); var utils_1 = require("../../utils"); var instanceCounter = 0; var Overlay = /** @class */ (function (_super) { tslib_1.__extends(Overlay, _super); function Overlay() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.id = instanceCounter++; _this.shouldRender = false; _this.onContainerCreate = function (_a) { var dom = _a.dom; if (_this.shouldRender) { _this.handleOpen(dom); } }; _this.onContainerUpdate = function (_a) { var dom = _a.dom; var isOpen = _this.attrs.isOpen; var wasOpen = _this.prevAttrs.isOpen; if (isOpen && !wasOpen) { _this.handleOpen(dom); } else if (!isOpen && wasOpen) { _this.handleClose(); } }; _this.handleBackdropMouseDown = function (e) { var _a = _this.attrs, closeOnOutsideClick = _a.closeOnOutsideClick, onClose = _a.onClose; if (closeOnOutsideClick) { _shared_1.safeCall(onClose, e); } else e.redraw = false; }; _this.handleDocumentMouseDown = function (e) { var _a = _this.attrs, isOpen = _a.isOpen, onClose = _a.onClose, closeOnOutsideClick = _a.closeOnOutsideClick; var contentEl = _this.contentEl; var isClickOnOverlay = contentEl && contentEl.contains(e.target); if (isOpen && closeOnOutsideClick && !isClickOnOverlay && _this.lastOpened) { _shared_1.safeCall(onClose, e); mithril_1.default.redraw(); } }; _this.handleKeyDown = function (e) { var _a = _this.attrs, closeOnEscapeKey = _a.closeOnEscapeKey, onClose = _a.onClose; if (e.which === _shared_1.Keys.ESCAPE && closeOnEscapeKey && _this.lastOpened) { _shared_1.safeCall(onClose, e); e.preventDefault(); mithril_1.default.redraw(); } }; return _this; } Overlay.prototype.getDefaultAttrs = function () { return { closeOnEscapeKey: true, closeOnOutsideClick: true, hasBackdrop: true, addToStack: true, transitionName: 'fade', transitionDuration: utils_1.TransitionManager.isEnabled ? 200 : 0 }; }; Overlay.prototype.oninit = function (vnode) { _super.prototype.oninit.call(this, vnode); this.shouldRender = !!vnode.attrs.isOpen; }; Overlay.prototype.onbeforeupdate = function (vnode, old) { var _this = this; _super.prototype.onbeforeupdate.call(this, vnode, old); var _a = vnode.attrs, isOpen = _a.isOpen, transitionDuration = _a.transitionDuration; var wasOpen = old.attrs.isOpen; if (isOpen && !wasOpen) { this.clearTimeouts(); this.shouldRender = true; } else if (!isOpen && wasOpen) { if (transitionDuration > 0) { this.handleClose(); this.setTimeout(function () { _this.shouldRender = false; mithril_1.default.redraw(); _this.handleClosed(); }, transitionDuration); } else { this.shouldRender = false; this.handleClose(); this.handleClosed(); } } }; Overlay.prototype.onremove = function () { if (this.shouldRender === true) { this.handleClose(); this.handleClosed(); this.shouldRender = false; } }; Overlay.prototype.view = function () { var _a = this.attrs, backdropClass = _a.backdropClass, hasBackdrop = _a.hasBackdrop, content = _a.content, inline = _a.inline, className = _a.class, style = _a.style, portalAttrs = _a.portalAttrs; if (!this.shouldRender) { return null; } var innerContent = [ hasBackdrop && mithril_1.default('', { class: classnames_1.default(_shared_1.Classes.OVERLAY_BACKDROP, backdropClass), onmousedown: this.handleBackdropMouseDown, tabindex: 0 }), content ]; var classes = classnames_1.default(_shared_1.Classes.OVERLAY, inline && _shared_1.Classes.OVERLAY_INLINE, className); var container = mithril_1.default('', { class: classes, style: style, oncreate: this.onContainerCreate, onupdate: this.onContainerUpdate }, innerContent); return inline ? container : mithril_1.default(portal_1.Portal, tslib_1.__assign({}, portalAttrs), container); }; Overlay.prototype.handleOpen = function (contentEl) { var _a = this.attrs, addToStack = _a.addToStack, closeOnOutsideClick = _a.closeOnOutsideClick, closeOnEscapeKey = _a.closeOnEscapeKey, hasBackdrop = _a.hasBackdrop, onOpened = _a.onOpened, inline = _a.inline; this.contentEl = contentEl; if (addToStack) { Overlay.openStack.push(this.id); } if (closeOnOutsideClick && !hasBackdrop) { document.addEventListener('mousedown', this.handleDocumentMouseDown); } if (closeOnEscapeKey) { document.addEventListener('keydown', this.handleKeyDown); } this.handleEnterTransition(); if (hasBackdrop && !inline) { document.body.classList.add(_shared_1.Classes.OVERLAY_OPEN); var bodyHasScrollbar = _shared_1.hasScrollbar(document.body); if (bodyHasScrollbar) { document.body.style.paddingRight = _shared_1.getScrollbarWidth() + "px"; } } _shared_1.safeCall(onOpened, contentEl); this.handleFocus(); }; Overlay.prototype.handleClose = function () { document.removeEventListener('mousedown', this.handleDocumentMouseDown); document.removeEventListener('keydown', this.handleKeyDown); this.handleExitTransition(); }; Overlay.prototype.handleClosed = function () { var _this = this; var _a = this.attrs, restoreFocus = _a.restoreFocus, onClosed = _a.onClosed, hasBackdrop = _a.hasBackdrop, inline = _a.inline; if (this.attrs.addToStack) { Overlay.openStack = Overlay.openStack.filter(function (id) { return id !== _this.id; }); } if (this.lastActiveElement && restoreFocus) { window.requestAnimationFrame(function () { return _this.lastActiveElement.focus(); }); } if (hasBackdrop && !inline) { document.body.classList.remove(_shared_1.Classes.OVERLAY_OPEN); document.body.style.paddingRight = ''; } _shared_1.safeCall(onClosed); }; Overlay.prototype.handleEnterTransition = function () { var _a = this.attrs, transitionName = _a.transitionName, transitionDuration = _a.transitionDuration; var el = this.contentEl; if (el == null || transitionDuration === 0) return; el.classList.remove(transitionName + "-exit"); el.classList.remove(transitionName + "-exit-active"); el.classList.add(transitionName + "-enter"); // tslint:disable-next-line:no-unused-expression el.scrollTop; el.classList.add(transitionName + "-enter-active"); }; Overlay.prototype.handleExitTransition = function () { var _a = this.attrs, transitionDuration = _a.transitionDuration, transitionName = _a.transitionName; var el = this.contentEl; if (el == null || transitionDuration === 0) return; el.classList.remove(transitionName + "-enter"); el.classList.remove(transitionName + "-enter-active"); el.classList.add(transitionName + "-exit"); // tslint:disable-next-line:no-unused-expression el.scrollTop; el.classList.add(transitionName + "-exit-active"); }; Overlay.prototype.handleFocus = function () { this.lastActiveElement = document.activeElement; var contentEl = this.contentEl; var _a = this.attrs, isOpen = _a.isOpen, autofocus = _a.autofocus; if (!contentEl || !document.activeElement || !isOpen || !autofocus) { return; } window.requestAnimationFrame(function () { var isFocusOutsideOverlay = !contentEl.contains(document.activeElement); if (isFocusOutsideOverlay) { var autofocusEl = contentEl.querySelector('[autofocus]'); var tabIndexEl = contentEl.querySelector('[tabindex]'); if (autofocusEl) { autofocusEl.focus(); } else if (tabIndexEl) { tabIndexEl.focus(); } } }); }; Object.defineProperty(Overlay.prototype, "lastOpened", { get: function () { return this.attrs.addToStack ? Overlay.getLastOpened() === this.id : true; }, enumerable: false, configurable: true }); Overlay.openStack = []; Overlay.getLastOpened = function () { return Overlay.openStack[Overlay.openStack.length - 1]; }; return Overlay; }(abstract_component_1.AbstractComponent)); exports.Overlay = Overlay;