@larva.io/webcomponents
Version:
Fentrica SmartUnits WebComponents package
804 lines (803 loc) • 31.9 kB
JavaScript
/*!
* (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