UNPKG

jiro-ui

Version:

A Mithril.js UI library based from construct-ui

252 lines (251 loc) 10.5 kB
import { __assign, __extends } from "tslib"; import m from 'mithril'; import classnames from 'classnames'; import PopperJS from 'popper.js'; import { Classes, safeCall, getClosest, elementIsOrContains } from '../../_shared'; import { AbstractComponent } from '../abstract-component'; import { Overlay } from '../overlay'; var Popover = /** @class */ (function (_super) { __extends(Popover, _super); function Popover() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.handleOpened = function (contentEl) { if (!_this.popper && contentEl) { var popoverEl = contentEl.querySelector("." + Classes.POPOVER); _this.createPopper(popoverEl); safeCall(_this.attrs.onOpened, contentEl); } }; _this.handleClosed = function () { _this.destroyPopper(); safeCall(_this.attrs.onClosed); }; _this.handleOverlayClose = function (e) { var target = e.target; var isTriggerClick = elementIsOrContains(_this.trigger.dom, target); if (!isTriggerClick || e instanceof KeyboardEvent) { _this.isControlled ? _this.handleInteraction(e) : _this.isOpen = false; } }; _this.handlePopoverClick = function (e) { var target = e.target; var hasDimiss = getClosest(target, "." + Classes.POPOVER_DISSMISS) != null; if (_this.attrs.closeOnContentClick || hasDimiss) { _this.isControlled ? _this.handleInteraction(e) : _this.isOpen = false; } else e.redraw = false; }; _this.handleTriggerMouseEnter = function (e) { var _a = _this.attrs, hoverOpenDelay = _a.hoverOpenDelay, interactionType = _a.interactionType; if (interactionType !== 'hover-trigger') { _this.clearTimeouts(); } if (!_this.isOpen && _this.isHoverInteraction()) { if (hoverOpenDelay > 0) { _this.setTimeout(function () { _this.isOpen = true; m.redraw(); }, hoverOpenDelay); } else { _this.isOpen = true; m.redraw(); } } e.redraw = false; }; _this.handleTriggerMouseLeave = function (e) { var hoverCloseDelay = _this.attrs.hoverCloseDelay; _this.clearTimeouts(); if (_this.isOpen && _this.isHoverInteraction()) { if (hoverCloseDelay > 0) { _this.setTimeout(function () { _this.isOpen = false; m.redraw(); }, hoverCloseDelay); } else { _this.isOpen = false; m.redraw(); } } e.redraw = false; }; _this.getContentOffset = function (data, containerEl) { if (!_this.attrs.hasArrow) { return data; } var placement = data.placement; var isHorizontal = placement.includes('left') || placement.includes('right'); var position = isHorizontal ? 'left' : 'top'; var arrowSize = containerEl.children[0].clientHeight + 1; var offset = placement.includes('top') || placement.includes('left') ? -arrowSize : arrowSize; data.offsets.popper[position] += offset; return data; }; return _this; } Popover.prototype.getDefaultAttrs = function () { return { boundariesEl: 'window', restoreFocus: false, hasBackdrop: false, hoverCloseDelay: 100, hoverOpenDelay: 0, interactionType: 'click', position: 'bottom', hasArrow: true }; }; Popover.prototype.oninit = function (vnode) { _super.prototype.oninit.call(this, vnode); var _a = this.attrs, isOpen = _a.isOpen, defaultIsOpen = _a.defaultIsOpen; this.isOpen = isOpen != null ? isOpen : defaultIsOpen != null ? defaultIsOpen : false; }; Popover.prototype.onbeforeupdate = function (vnode, old) { _super.prototype.onbeforeupdate.call(this, vnode, old); var isOpen = vnode.attrs.isOpen; var wasOpen = old.attrs.isOpen; if (isOpen && !wasOpen) { this.isOpen = true; } else if (!isOpen && wasOpen) { this.isOpen = false; } }; Popover.prototype.onupdate = function () { if (this.popper) { this.popper.options.placement = this.attrs.position; this.popper.scheduleUpdate(); } }; Popover.prototype.onremove = function () { this.destroyPopper(); }; Popover.prototype.view = function () { var _a = this.attrs, className = _a.class, style = _a.style, content = _a.content, hasArrow = _a.hasArrow, trigger = _a.trigger, interactionType = _a.interactionType, inline = _a.inline, backdropClass = _a.backdropClass, overlayClass = _a.overlayClass, overlayStyle = _a.overlayStyle; this.trigger = trigger; this.setTriggerAttrs(); var innerContent = m('', { class: classnames(Classes.POPOVER, className), onclick: this.handlePopoverClick, onmouseenter: this.handleTriggerMouseEnter, onmouseleave: this.handleTriggerMouseLeave, style: style }, [ hasArrow && m("." + Classes.POPOVER_ARROW), m("." + Classes.POPOVER_CONTENT, content) ]); return m.fragment({}, [ this.trigger, m(Overlay, __assign(__assign({ restoreFocus: this.isClickInteraction() }, this.attrs), { backdropClass: classnames(Classes.POPOVER_BACKDROP, backdropClass), class: overlayClass, closeOnOutsideClick: interactionType !== 'click-trigger', content: innerContent, inline: inline, isOpen: this.isOpen, onClose: this.handleOverlayClose, onOpened: this.handleOpened, onClosed: this.handleClosed, style: overlayStyle })) ]); }; Popover.prototype.createPopper = function (el) { var _this = this; var _a = this.attrs, position = _a.position, hasArrow = _a.hasArrow, boundariesEl = _a.boundariesEl, modifiers = _a.modifiers; var options = { placement: position, modifiers: __assign({ arrow: { enabled: hasArrow, element: "." + Classes.POPOVER_ARROW }, offset: { enabled: hasArrow, fn: function (data) { return _this.getContentOffset(data, el); } }, preventOverflow: { enabled: true, boundariesElement: boundariesEl, padding: 0 } }, modifiers) }; this.popper = new PopperJS(this.trigger.dom, el, options); }; Popover.prototype.destroyPopper = function () { if (this.popper) { this.popper.destroy(); this.popper = undefined; } }; Popover.prototype.setTriggerAttrs = function () { var _this = this; var isControlled = this.isControlled; if (!this.trigger.attrs) { this.trigger.attrs = {}; } var triggerAttrs = this.trigger.attrs; if (this.isOpen) { triggerAttrs.class = classnames(triggerAttrs.className || triggerAttrs.class, Classes.ACTIVE, Classes.POPOVER_TRIGGER_ACTIVE); } else triggerAttrs.class = triggerAttrs.className || triggerAttrs.class || ''; var triggerEvents = { onmouseenter: triggerAttrs.onmouseenter, onmouseleave: triggerAttrs.onmouseleave, onfocus: triggerAttrs.onfocus, onblur: triggerAttrs.onblur, onclick: triggerAttrs.onclick }; if (this.isClickInteraction()) { triggerAttrs.onclick = function (e) { isControlled ? _this.handleInteraction(e) : _this.handleTriggerClick(); safeCall(triggerEvents.onclick); }; } else { triggerAttrs.onmouseenter = function (e) { isControlled ? _this.handleInteraction(e) : _this.handleTriggerMouseEnter(e); safeCall(triggerEvents.onmouseenter); }; triggerAttrs.onmouseleave = function (e) { isControlled ? _this.handleInteraction(e) : _this.handleTriggerMouseLeave(e); safeCall(triggerEvents.onmouseleave); }; triggerAttrs.onfocus = function (e) { isControlled ? _this.handleInteraction(e) : _this.handleTriggerFocus(e); safeCall(triggerEvents.onfocus); }; triggerAttrs.onblur = function (e) { isControlled ? _this.handleInteraction(e) : _this.handleTriggerBlur(e); safeCall(triggerEvents.onblur); }; } }; Popover.prototype.handleInteraction = function (e) { safeCall(this.attrs.onInteraction, !this.isOpen, e); }; Popover.prototype.handleTriggerClick = function () { this.isOpen = !this.isOpen; }; Popover.prototype.handleTriggerFocus = function (e) { if (this.attrs.openOnTriggerFocus) { this.handleTriggerMouseEnter(e); } else e.redraw = false; }; Popover.prototype.handleTriggerBlur = function (e) { if (this.attrs.openOnTriggerFocus) { this.handleTriggerMouseLeave(e); } else e.redraw = false; }; Popover.prototype.isHoverInteraction = function () { var interactionType = this.attrs.interactionType; return interactionType === 'hover' || interactionType === 'hover-trigger'; }; Popover.prototype.isClickInteraction = function () { var interactionType = this.attrs.interactionType; return interactionType === 'click' || interactionType === 'click-trigger'; }; Object.defineProperty(Popover.prototype, "isControlled", { get: function () { return this.attrs.isOpen != null; }, enumerable: false, configurable: true }); return Popover; }(AbstractComponent)); export { Popover };