UNPKG

wj-elements

Version:

WebJET Elements is a modern set of user interface tools harnessing the power of web components designed to simplify web application development.

265 lines (264 loc) 14 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); import WJElement from "./wje-element.js"; import { event } from "./event.js"; const styles = "/*\n[ WJ Dialog ]\n*/\n\n:host {\n --wje-dialog-header-actions-gap: 0.5rem;\n\n .close {\n margin-left: auto;\n }\n\n .header-actions {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: var(--wje-dialog-header-actions-gap);\n }\n\n .modal-content {\n border-radius: 3px;\n box-shadow: none;\n }\n\n .dialog-header {\n position: relative;\n border-bottom: 0;\n padding-inline: var(--wje-dialog-padding);\n padding-top: var(--wje-dialog-padding);\n padding-bottom: var(--wje-dialog-padding);\n display: flex;\n align-items: center;\n span {\n font-family: var(--wje-font-family-secondary);\n font-size: var(--wje-dialog-headline-font-size);\n text-transform: var(--wje-dialog-headline-text-transform);\n display: inline-block;\n letter-spacing: var(--wje-dialog-headline-letter-spacing);\n font-weight: var(--wje-dialog-headline-font-weight);\n margin: 0;\n padding: 0;\n line-height: normal;\n overflow: hidden;\n text-overflow: ellipsis;\n filter: alpha(opacity=40);\n }\n }\n\n .dialog-content {\n box-shadow: none;\n padding-inline: var(--wje-dialog-padding);\n white-space: normal;\n z-index: 1;\n }\n\n .dialog-footer {\n display: flex;\n justify-content: end;\n border-top: none;\n box-shadow: none;\n margin-top: 0;\n padding-inline: var(--wje-dialog-padding-inline);\n padding-top: var(--wje-dialog-padding-top);\n padding-bottom: var(--wje-dialog-padding-bottom);\n }\n}\n\n/*Blocking element styles*/\n.blocking-element {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: var(--wje-color-contrast-0);\n opacity: 0.75;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n\n wje-icon {\n animation: loader 1s linear infinite;\n }\n}\n\n@keyframes loader {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\ndialog::backdrop {\n opacity: var(--wje-backdrop-opacity);\n background-color: var(--wje-backdrop);\n}\n\ndialog:focus-visible {\n outline: none;\n}\n\n:host(.separator) .dialog-header:after {\n content: '';\n height: 1px;\n background: rgba(0, 0, 0, 0.08);\n left: var(--wje-dialog-padding);\n right: var(--wje-dialog-padding);\n position: absolute;\n bottom: 0;\n}\n\n:host {\n dialog {\n box-sizing: border-box;\n transition: all 0.2s !important;\n width: var(--wje-dialog-width);\n height: var(--wje-dialog-height);\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n\n border-radius: var(--wje-dialog-border-radius);\n border-width: var(--wje-dialog-border-width);\n border-style: var(--wje-dialog-border-style);\n border-color: var(--wje-dialog-border-color);\n\n margin-top: var(--wje-dialog-margin-top);\n\n margin-bottom: var(--wje-dialog-margin-bottom);\n margin-inline: var(--wje-dialog-margin-start) var(--wje-dialog-margin-end);\n\n padding: 0;\n }\n}\n\n/*Top*/\n:host(.stick-up) {\n --wje-dialog-width: 300px !important;\n --wje-dialog-height: fit-content;\n --wje-dialog-border-radius: 0 0 8px 8px;\n --wje-dialog-border-width: 0 1px 1px 1px;\n --wje-dialog-margin-top: 0;\n --wje-dialog-translate-from: translateY(-110%);\n --wje-dialog-template-to: translateX(0);\n}\n\n/*Cenetered*/\n:host(.slide-up) {\n --wje-dialog-width: 300px !important;\n --wje-dialog-height: fit-content;\n --wje-dialog-border-radius: 8px;\n --wje-dialog-border-width: 1px;\n --wje-dialog-opacity-from: 0;\n --wje-dialog-translate-from: scale(0.9);\n --wje-dialog-translate-to: scale(1);\n}\n\n/*Fullscreen*/\n:host(.fill-in) {\n --wje-dialog-width: 100%;\n --wje-dialog-height: 100%;\n --wje-dialog-border-radius: 0 0 0 0 !important;\n --wje-dialog-border-width: 0;\n --wje-dialog-margin-top: 0;\n --wje-dialog-margin-start: 0;\n --wje-dialog-margin-end: 0;\n --wje-dialog-margin-bottom: 0;\n --wje-dialog-translate-from: scale(0.95);\n --wje-dialog-translate-to: scale(1);\n dialog {\n min-width: var(--wje-dialog-width);\n min-height: var(--wje-dialog-height);\n }\n}\n\n/*Slide Left*/\n:host(.slide-left) {\n --wje-dialog-width: 300px !important;\n --wje-dialog-height: 100% !important;\n --wje-dialog-border-radius: 0;\n --wje-dialog-border-width: 0 1px 0 0;\n --wje-dialog-margin-top: 0;\n --wje-dialog-margin-start: 0;\n --wje-dialog-margin-end: auto;\n --wje-dialog-margin-bottom: 0;\n dialog {\n min-height: var(--wje-dialog-height);\n --wje-dialog-translate-from: translateX(-110%);\n --wje-dialog-template-to: translateX(0);\n }\n}\n\n/*Slide Right*/\n:host(.slide-right) {\n --wje-dialog-width: 300px !important;\n --wje-dialog-height: 100% !important;\n --wje-dialog-border-radius: 0;\n --wje-dialog-border-width: 0 0 0 1px;\n --wje-dialog-margin-top: 0;\n --wje-dialog-margin-start: auto;\n --wje-dialog-margin-end: 0;\n --wje-dialog-margin-bottom: 0;\n dialog {\n min-height: var(--wje-dialog-height);\n --wje-dialog-translate-from: translateX(110%);\n --wje-dialog-template-to: translateX(0);\n }\n}\n\n:host(.small) {\n --wje-dialog-width: 300px !important;\n}\n\n:host(.medium) {\n --wje-dialog-width: 500px !important;\n}\n\n:host(.large) {\n --wje-dialog-width: 600px !important;\n}\n\n:host(.ex-large) {\n --wje-dialog-width: 900px !important;\n}\n\ndialog[open] {\n animation: show 0.5s ease normal;\n}\n\n@keyframes show {\n from {\n opacity: var(--wje-dialog-opacity-from, 1);\n transform: var(--wje-dialog-translate-from);\n }\n to {\n opacity: 1;\n transform: var(--wje-dialog-translate-to);\n }\n}\n"; class Dialog extends WJElement { /** * @class */ constructor() { super(); /** * Sets the headline of the dialog. * @type {string} */ __publicField(this, "className", "Dialog"); /** * Opens the dialog. * @param e */ __publicField(this, "onOpen", (e) => { if (this.dialog) { this.dialog.innerHTML = ""; } Promise.resolve(this.beforeOpen(this, e)).then((res) => { this.htmlDialogBody(this.dialog); this.dialog.showModal(); if (this.dialog.open) { Promise.resolve(this.afterOpen(this, e)); } }); }); /** * Closes the dialog. * @param {object} e */ __publicField(this, "onClose", (e) => { Promise.resolve(this.beforeClose(this, e)).then((res) => { this.dialog.close(); if (!this.dialog.open) { Promise.resolve(this.afterClose(this, e)); } }); }); } /** * Sets the value of the 'headline' attribute. * @param {string} value The new value for the 'headline' attribute. */ set headline(value) { this.setAttribute("headline", value); } /** * Retrieves the value of the "headline" attribute from the element. * If the "headline" attribute is not present, returns an empty string. * @returns {string} The headline attribute value or an empty string if not set. */ get headline() { return this.getAttribute("headline") || ""; } /** * Sets the headline of the dialog. * @param value */ set placement(value) { this.setAttribute("placement", value); } /** * Gets the headline of the dialog. * @returns {string|string} */ get placement() { return this.getAttribute("placement") || "slide-up"; } /** * Sets the headline of the dialog. * @param value */ set async(value) { this.setAttribute("async", ""); } /** * Gets the headline of the dialog. * @returns {boolean} */ get async() { return this.hasAttribute("async"); } /** * Sets the headline of the dialog. * @param value */ set closeHidden(value) { if (value) this.setAttribute("close-hidden", ""); } /** * Gets the headline of the dialog. * @returns {boolean} */ get closeHidden() { return !!this.hasAttribute("close-hidden"); } /** * Returns the CSS styles for the component. * @returns {*} */ static get cssStyleSheet() { return styles; } /** * Returns the list of attributes to observe for changes. * @returns {*[]} */ static get observedAttributes() { return []; } /** * Sets up the attributes for the component. */ setupAttributes() { this.isShadowRoot = "open"; } /** * Draws the component. * @param {object} context The context for drawing. * @param {object} store The store for drawing. * @param {object} params The parameters for drawing. * @returns {DocumentFragment} */ draw(context, store, params) { let fragment = document.createDocumentFragment(); this.classList.add("fade", this.placement, params.size); let dialog = document.createElement("dialog"); dialog.classList.add("modal-dialog"); fragment.appendChild(dialog); this.dialog = dialog; return fragment; } /** * Creates the dialog body. * @param dialog */ htmlDialogBody(dialog) { let icon = document.createElement("wje-icon"); icon.setAttribute("name", "x"); icon.setAttribute("slot", "icon-only"); let close = document.createElement("wje-button"); close.setAttribute("fill", "link"); close.setAttribute("size", "small"); close.setAttribute("part", "close"); close.addEventListener("click", (e) => { this.close(e); }); close.appendChild(icon); let header = document.createElement("div"); header.setAttribute("part", "header"); header.classList.add("dialog-header"); if (this.hasAttribute("headline")) header.innerHTML = `<span part="headline">${this.headline}</span>`; let slotHeader = document.createElement("slot"); slotHeader.setAttribute("name", "header"); const headerActions = document.createElement("div"); headerActions.classList.add("header-actions"); headerActions.setAttribute("part", "header-actions"); headerActions.appendChild(slotHeader); header.appendChild(headerActions); if (!this.closeHidden) header.appendChild(close); let contentSlot = document.createElement("slot"); let body = document.createElement("div"); body.setAttribute("part", "body"); body.classList.add("dialog-content"); body.appendChild(contentSlot); let footer = document.createElement("div"); footer.setAttribute("part", "footer"); footer.classList.add("dialog-footer"); footer.innerHTML = ""; let slotFooter = document.createElement("slot"); slotFooter.setAttribute("name", "footer"); footer.appendChild(slotFooter); dialog.appendChild(header); dialog.appendChild(body); dialog.appendChild(footer); } /** * Closes the dialog. * @param e */ close(e) { this.onClose(e); } /** * Draws the component after it has been drawn. * @param {object} context The context for drawing. * @param {object} store The store for drawing. * @param {object} params The parameters for drawing. */ afterDraw(context, store, params) { if (params.trigger) { event.addListener(document, params.trigger, null, this.onOpen); } } /** * Before the component is disconnected. */ beforeDisconnect() { var _a, _b; if ((_a = this.params) == null ? void 0 : _a.trigger) { event.removeListener(document, (_b = this.params) == null ? void 0 : _b.trigger, null, this.onOpen); } } /** * Before the dialog opens. */ beforeOpen(dialog, trigger) { } /** * After the dialog opens. */ afterOpen(dialog, trigger) { } /** * Before the dialog closes. */ beforeClose(dialog, trigger) { } /** * After the dialog closes. */ afterClose(dialog, trigger) { } /** * Registers an event listener on the provided button that triggers a blocking UI element * and executes a given promise when the button is clicked. * @param {HTMLElement} button The button element to attach the event listener to. * @param {Function} promise A function that returns a promise to be executed when the button is clicked. */ registerBlockingEvent(button, promise) { button.addEventListener("wje-button:click", async (e) => { let blockingElement = document.createElement("div"); blockingElement.classList.add("blocking-element"); let icon = document.createElement("wje-icon"); icon.setAttribute("name", "loader-2"); icon.setAttribute("size", "2x-large"); blockingElement.appendChild(icon); let scrollOffset = this.dialog.scrollTop; blockingElement.style.top = `${scrollOffset}px`; blockingElement.style.bottom = `-${scrollOffset}px`; this.dialog.appendChild(blockingElement); await promise().then((res) => { this.close(); blockingElement.remove(); }).catch((err) => { console.error(err); blockingElement.remove(); }); }); } } Dialog.define("wje-dialog", Dialog); export { Dialog as default }; //# sourceMappingURL=wje-dialog.js.map