UNPKG

@larva.io/webcomponents

Version:

Fentrica SmartUnits WebComponents package

804 lines (803 loc) 31.9 kB
/*! * (C) Fentrica http://fentrica.com - Seee LICENSE.md */ import { Host, h } from "@stencil/core"; import { createColorClasses } from "../../../utils/theme"; import { enterAnimationBottom, enterAnimationRight } from "../modal/animations/enter"; import { config } from "../../../global/config"; import { leaveAnimationBottom, leaveAnimationRight } from "../modal/animations/leave"; import { attachComponent } from "../../../utils/helpers"; export class Modal { constructor() { // Reference to the user's provided modal content this.presented = false; this.config = config; this.components = []; /** * Modal appearing animation if animations enabled * Default options are: `"bottom"`, `"right"` */ this.animation = 'right'; /** * Modal header size */ this.headerSize = 'default'; /** * If `true`, a backdrop will be displayed behind the modal. */ this.showBackdrop = true; /** * If `true`, the modal will be dismissed when the backdrop is clicked. */ this.backdropDismiss = true; } swipeHandlerChanged() { if (this.gesture) { this.gesture.enable(!!this.swipeGesture); } } async componentWillLoad() { // swipe not set and enabled by config. if (this.swipeGesture === undefined) { this.swipeGesture = this.config.getBoolean('swipeBack', true); } if (this.component) { this.components.push({ component: this.component, componentProps: Object.assign(Object.assign({}, this.componentProps), { modal: this.el }) }); } } /** * Get modal components */ async getComponents() { return this.components; } /** * Get modal component. If index not provided default returned */ async getComponent(index) { if (index) { return this.components[index] || null; } else if (this.component && this.components[0]) { return this.components[0]; } return null; } onBackdropTap() { if (this.backdropDismiss) { this.dismiss(); } } /** * Attach additional component to modal */ async attachComponent(component, componentProps) { this.components.push({ component, componentProps }); } /** * Present the modal overlay after it has been created. */ async present() { if (this.presented) { return; } // Wait for component to render before querying shadow DOM await new Promise(resolve => requestAnimationFrame(resolve)); const el = this.el.shadowRoot || this.el; const container = el.querySelector(`.lar-modal-components-slot`); if (!container) { throw new Error('container is undefined'); } this.willPresent.emit(); this.presented = true; for (const comp of this.components) { comp.element = await attachComponent(container, comp.component, comp.componentProps); } const animationBuilder = this.animation === 'bottom' ? enterAnimationBottom : enterAnimationRight; const animation = await import('../../../utils/animation').then(mod => mod.create(animationBuilder, el)); // add 'display' to :host element before we start animating. // first time animation controller element creation to DOM takes time and default values may show you flickering because of beforeStyles functions // do awoid flickering with 'beforeStyles' params we display host after controller is created. if (!this.config.getBoolean('animated', true)) { animation.duration(0); } await animation.playAsync(); animation.destroy(); // OSX safari scroll fix: https://stackoverflow.com/questions/28288710/cant-scroll-inside-a-div-after-applying-webkit-transform-in-safari const scrollContent = el.querySelector('#lar-modal-scroll'); if (scrollContent) { scrollContent.style.overflowY = 'hidden'; setTimeout(() => { scrollContent.style.overflowY = 'auto'; }); } this.didPresent.emit(); } async componentDidLoad() { const el = this.el.shadowRoot || this.el; const animationBuilder = this.animation === 'bottom' ? leaveAnimationBottom : leaveAnimationRight; const dismissAnimation = await import('../../../utils/animation').then(mod => mod.create(animationBuilder, el)); const swipe = this.animation === 'bottom' ? await import('../../../utils/gesture/swipe-down') : await import('../../../utils/gesture/swipe-back'); let shouldHide = false; dismissAnimation.onFinish(() => { if (shouldHide) { this.willDismiss.emit(); this.didDismiss.emit(); } }); this.gesture = swipe.createSwipeBackGesture(this.el, () => !!this.swipeGesture, () => { return dismissAnimation && dismissAnimation.progressStart(); }, step => { return dismissAnimation && dismissAnimation.progressStep(step); }, async (shouldComplete, step, dur) => { if (dismissAnimation) { dismissAnimation.progressEnd(shouldComplete, step, dur); } shouldHide = shouldComplete; }); this.swipeHandlerChanged(); } /** * Present the modal overlay after it has been created. */ async dismiss() { if (this.presented) { this.willDismiss.emit(); const el = this.el.shadowRoot || this.el; const animationBuilder = this.animation === 'bottom' ? leaveAnimationBottom : leaveAnimationRight; const animation = await import('../../../utils/animation').then(mod => mod.create(animationBuilder, el)); if (!this.config.getBoolean('animated', true)) { animation.duration(0); } await animation.playAsync(); animation.destroy(); this.didDismiss.emit(); } } render() { // if it comes using DOM prop, objects not supporteed, so node.tsx coverts it to JSON string const valueTranslationValues = !!this.valueTranslationValues && typeof this.valueTranslationValues === 'string' ? JSON.parse(this.valueTranslationValues) : this.valueTranslationValues; let iconSmall; let body; let value; if (this.iconSmall) { iconSmall = h("lar-icon", { key: '9fecdfd3ad1741285ab70e6347b046ff5b54a444', size: "large", color: this.colorIconSmall || this.colorHeaderInputs || this.color, icon: this.iconSmall }); } if (this.value && this.value !== '') { value = h("lar-translate", { key: 'a0e7ef7a0641046380fdba91ec6cc795dfacd2b2', t: this.value, values: valueTranslationValues }); } body = [ h("div", { key: '338e3e5f6a0b1dd0add5ccd4d447e0dcaaf7b0de', class: "lar-modal-header" }, h("div", { key: 'b1c3241dbbfe487325c84b4b10c98e67403120d3', class: "lar-toolbar" }, h("div", { key: '89b267d6e2300770251f62ef6261925631ed6b41', class: "lar-toolbar-background" }), h("div", { key: 'ccbdcf15fb157deaff7d32ba5c364a2d3f4e4e3b', class: "lar-toolbar-container" }, h("div", { key: 'c8c0d514b8163cd993fe32f49f54d259860dc83f', class: "lar-start" }, h("a", { key: 'd7ae9c3e34d3db2312446899da5299df6bba2382', href: "#", onClick: (e) => { e.preventDefault(); e.stopPropagation(); this.dismiss(); } }, h("lar-icon", { key: 'c56b0d17673e12c16d413cc9ab043cd2d3a16f4d', size: "medium", icon: this.animation === 'bottom' ? 'down' : 'back', color: this.colorHeaderInputs || 'medium' }))), h("div", { key: '0216e42dabef2ec1a9e66bbad12546d0f8a02edc', class: "lar-mid" }, h("div", { key: '85fa18b756d75494c0dd7c34c1570b00907e1c8a', class: 'lar-modal-icon ' + this.headerSize }, this.icon ? h("lar-icon", { icon: this.icon }) : '')), h("div", { key: 'c35df90bc07cc198ff0a4c36af80c351c25b35f2', class: "lar-end" }, iconSmall)))), h("div", { key: '5269152383f291f6e6dd78aef3fbc6fd4911419a', class: "lar-modal-content" }, h("div", { key: 'c9b872ba1594de02779990d50cd1511567a29d98', id: "lar-modal-scroll", class: 'lar-modal-scroll ' + this.headerSize }, h("div", { key: '69b8d9f669ea37a8d0186c40d85536ad9cdaa295', class: "lar-modal-body" }, h("h3", { key: 'd6a3615a0b2aa834fa99da3e4f86c26f3ada52e6' }, h("lar-translate", { key: '3d13792f0ea36f87ef369d42bda965103637c82f', t: this.supTitle })), h("h2", { key: '8ef27993ceb18bba2ea64dfb76ac39649355c2ff' }, h("lar-translate", { key: 'b30eaa8658945b75934ddde3802d4ff7f7667466', t: this.mainTitle })), h("h3", { key: '1c487b8ed0c91e2b3332a44a9f994adfc311bdd8' }, h("lar-translate", { key: 'c7573d310fea8e0ddd708f9a6dc77e4d4297cdb1', t: this.subTitle })), h("div", { key: '0b22711dfe43b6e6e807b425b3133c9ab98f55f8', class: "lar-value" }, value), h("slot", { key: '5bd99cf39e93361ecaa3d9999bd9e59505aa07ef', name: "lar-modal-components-slot" }, h("div", { key: '617e8f466cd647fbf2c2b95128f8076064d21e53', class: "lar-modal-components-slot" }))))) ]; return (h(Host, { key: '6e1f75205bc62c94b10b74f2bf58eefbf8a8ae6f', class: Object.assign(Object.assign({}, createColorClasses(this.color)), { 'lar-modal': true }), style: { 'zIndex': String(200 + (this.overlayIndex || 0)), } }, h("lar-backdrop", { key: 'd0bb529773c077b30486db2b10ead612ee1a9dcb', visible: this.showBackdrop, tappable: this.backdropDismiss }), h("div", { key: '0199095b01e7f66af7d3d3e0e63d1cced1172e35', role: "dialog", class: "lar-modal-wrapper" }, body))); } static get is() { return "lar-modal"; } static get encapsulation() { return "shadow"; } static get originalStyleUrls() { return { "$": ["modal.scss"] }; } static get styleUrls() { return { "$": ["modal.css"] }; } static get properties() { return { "color": { "type": "string", "mutable": false, "complexType": { "original": "Color", "resolved": "string", "references": { "Color": { "location": "import", "path": "../../../interface", "id": "src/interface.d.ts::Color" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "The icon color to use from your application's color palette.\nDefault options are: `\"primary\"`, `\"secondary\"`, `\"tertiary\"`, `\"success\"`, `\"warning\"`, `\"danger\"`, `\"light\"`, `\"medium\"`, and `\"dark\"`." }, "getter": false, "setter": false, "reflect": false, "attribute": "color" }, "colorIconSmall": { "type": "string", "mutable": false, "complexType": { "original": "Color", "resolved": "string", "references": { "Color": { "location": "import", "path": "../../../interface", "id": "src/interface.d.ts::Color" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "The small icon color to use from your application's color palette." }, "getter": false, "setter": false, "reflect": false, "attribute": "color-icon-small" }, "colorHeaderInputs": { "type": "string", "mutable": false, "complexType": { "original": "Color", "resolved": "string", "references": { "Color": { "location": "import", "path": "../../../interface", "id": "src/interface.d.ts::Color" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "The icon color to use from your application's color palette." }, "getter": false, "setter": false, "reflect": false, "attribute": "color-header-inputs" }, "colorValue": { "type": "string", "mutable": false, "complexType": { "original": "Color", "resolved": "string", "references": { "Color": { "location": "import", "path": "../../../interface", "id": "src/interface.d.ts::Color" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "The color to use from your application's color palette for value" }, "getter": false, "setter": false, "reflect": false, "attribute": "color-value" }, "animation": { "type": "string", "mutable": false, "complexType": { "original": "('bottom' | 'right')", "resolved": "\"bottom\" | \"right\"", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Modal appearing animation if animations enabled\nDefault options are: `\"bottom\"`, `\"right\"`" }, "getter": false, "setter": false, "reflect": false, "attribute": "animation", "defaultValue": "'right'" }, "icon": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Modal title big icon" }, "getter": false, "setter": false, "reflect": false, "attribute": "icon" }, "headerSize": { "type": "string", "mutable": false, "complexType": { "original": "('small' | 'default')", "resolved": "\"default\" | \"small\"", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Modal header size" }, "getter": false, "setter": false, "reflect": false, "attribute": "header-size", "defaultValue": "'default'" }, "iconSmall": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Modal corner small icon" }, "getter": false, "setter": false, "reflect": false, "attribute": "icon-small" }, "subTitle": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Modal subscript title" }, "getter": false, "setter": false, "reflect": false, "attribute": "sub-title" }, "supTitle": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Modal superscript title" }, "getter": false, "setter": false, "reflect": false, "attribute": "sup-title" }, "mainTitle": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Moda main title" }, "getter": false, "setter": false, "reflect": false, "attribute": "main-title" }, "value": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Node corner value" }, "getter": false, "setter": false, "reflect": false, "attribute": "value" }, "valueTranslationValues": { "type": "any", "mutable": false, "complexType": { "original": "any", "resolved": "any", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Value translation valriables" }, "getter": false, "setter": false, "reflect": false, "attribute": "value-translation-values" }, "overlayIndex": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Modal z-index" }, "getter": false, "setter": false, "reflect": false, "attribute": "overlay-index" }, "showBackdrop": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "If `true`, a backdrop will be displayed behind the modal." }, "getter": false, "setter": false, "reflect": false, "attribute": "show-backdrop", "defaultValue": "true" }, "backdropDismiss": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "If `true`, the modal will be dismissed when the backdrop is clicked." }, "getter": false, "setter": false, "reflect": false, "attribute": "backdrop-dismiss", "defaultValue": "true" }, "swipeGesture": { "type": "boolean", "mutable": true, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "If `true`, the modal will be dismissed when swiped back." }, "getter": false, "setter": false, "reflect": false, "attribute": "swipe-gesture" }, "component": { "type": "string", "mutable": false, "complexType": { "original": "ComponentRef", "resolved": "Element | HTMLElement | string", "references": { "ComponentRef": { "location": "import", "path": "../../../interface", "id": "src/interface.d.ts::ComponentRef" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "The component to display inside of the modal." }, "getter": false, "setter": false, "reflect": false, "attribute": "component" }, "componentProps": { "type": "unknown", "mutable": false, "complexType": { "original": "ComponentProps", "resolved": "{ [key: string]: any; }", "references": { "ComponentProps": { "location": "import", "path": "../../../interface", "id": "src/interface.d.ts::ComponentProps" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "The data to pass to the modal component." }, "getter": false, "setter": false } }; } static get events() { return [{ "method": "willPresent", "name": "larmodalwillpresent", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emitted before the modal has presented." }, "complexType": { "original": "any", "resolved": "any", "references": {} } }, { "method": "didPresent", "name": "larmodaldidpresent", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emitted after the modal has presented." }, "complexType": { "original": "any", "resolved": "any", "references": {} } }, { "method": "willDismiss", "name": "larmodalwilldismiss", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emitted before the modal has dismissed." }, "complexType": { "original": "any", "resolved": "any", "references": {} } }, { "method": "didDismiss", "name": "larmodaldiddismiss", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emitted after the modal has dismissed." }, "complexType": { "original": "any", "resolved": "any", "references": {} } }]; } static get methods() { return { "getComponents": { "complexType": { "signature": "() => Promise<ModalComponent[]>", "parameters": [], "references": { "Promise": { "location": "global", "id": "global::Promise" }, "ModalComponent": { "location": "import", "path": "./modal-interface", "id": "src/components/internal/modal/modal-interface.tsx::ModalComponent" } }, "return": "Promise<ModalComponent[]>" }, "docs": { "text": "Get modal components", "tags": [] } }, "getComponent": { "complexType": { "signature": "(index?: number) => Promise<ModalComponent | null>", "parameters": [{ "name": "index", "type": "number", "docs": "" }], "references": { "Promise": { "location": "global", "id": "global::Promise" }, "ModalComponent": { "location": "import", "path": "./modal-interface", "id": "src/components/internal/modal/modal-interface.tsx::ModalComponent" } }, "return": "Promise<ModalComponent>" }, "docs": { "text": "Get modal component. If index not provided default returned", "tags": [] } }, "attachComponent": { "complexType": { "signature": "(component: ComponentRef, componentProps?: ComponentProps) => Promise<void>", "parameters": [{ "name": "component", "type": "string | HTMLElement | Element", "docs": "" }, { "name": "componentProps", "type": "{ [key: string]: any; }", "docs": "" }], "references": { "Promise": { "location": "global", "id": "global::Promise" }, "ComponentRef": { "location": "import", "path": "../../../interface", "id": "src/interface.d.ts::ComponentRef" }, "ComponentProps": { "location": "import", "path": "../../../interface", "id": "src/interface.d.ts::ComponentProps" } }, "return": "Promise<void>" }, "docs": { "text": "Attach additional component to modal", "tags": [] } }, "present": { "complexType": { "signature": "() => Promise<void>", "parameters": [], "references": { "Promise": { "location": "global", "id": "global::Promise" } }, "return": "Promise<void>" }, "docs": { "text": "Present the modal overlay after it has been created.", "tags": [] } }, "dismiss": { "complexType": { "signature": "() => Promise<void>", "parameters": [], "references": { "Promise": { "location": "global", "id": "global::Promise" } }, "return": "Promise<void>" }, "docs": { "text": "Present the modal overlay after it has been created.", "tags": [] } } }; } static get elementRef() { return "el"; } static get watchers() { return [{ "propName": "swipeGesture", "methodName": "swipeHandlerChanged" }]; } static get listeners() { return [{ "name": "larbackdroptap", "method": "onBackdropTap", "target": undefined, "capture": false, "passive": false }]; } } //# sourceMappingURL=modal.js.map