UNPKG

@universal-material/web

Version:
216 lines 6.93 kB
import { __decorate } from "tslib"; import { html, LitElement } from 'lit'; import { customElement, property, query, queryAssignedElements } from 'lit/decorators.js'; import { styles as baseStyles } from '../shared/base.styles.js'; import { ConfirmDialogBuilder } from './confirm-dialog-builder.js'; import { styles } from './dialog.styles.js'; import { MessageDialogBuilder } from './message-dialog-builder.js'; import '../elevation/elevation.js'; const topDividerClass = 'top-divider'; const bottomDividerClass = 'bottom-divider'; let UmDialog = class UmDialog extends LitElement { constructor() { super(...arguments); this.#open = false; /** * Whether dialog has headline or not * * _Note:_ Readonly */ this.hasHeadline = false; /** * Whether dialog has icon * * _Note:_ Readonly */ this.hasIcon = false; this.#handleCancel = (e) => { e.preventDefault(); const cancelPrevented = !this.dispatchEvent(new Event('cancel', { cancelable: true })); if (cancelPrevented) { return; } this.close(); }; } static { this.styles = [baseStyles, styles]; } #open; #contentResizeObserver; get open() { return this.#open; } set open(open) { if (this.#open === open) { return; } if (!open) { this.close(); return; } this.show(); } get returnValue() { return this.dialog.returnValue; } static message(message) { return MessageDialogBuilder.create(message); } static confirm(message) { return ConfirmDialogBuilder.create(message); } render() { return html ` <dialog> <div class="scrim" @click=${this.#handleScrimClick}></div> <div class="container" part="container"> <u-elevation></u-elevation> <div class="icon" part="icon"> <slot name="icon" @slotchange=${this.#handleIconSlotChange}> </slot> </div> <div class="headline" part="headline"> <slot name="headline" @slotchange=${this.#handleHeadlineSlotChange}> </slot> </div> <div class="content" part="content" @scroll=${this.#handleScroll}> <slot></slot> </div> <div class="actions" part="actions"> <slot name="actions"></slot> </div> </div> </dialog>`; } firstUpdated(changedProperties) { super.firstUpdated(changedProperties); this.dialog.addEventListener('cancel', this.#handleCancel); } connectedCallback() { super.connectedCallback(); this.addEventListener('submit', this.#handleSubmit); setTimeout(() => { this.#contentResizeObserver = new ResizeObserver(() => this.#setScrollDividers()); this.#contentResizeObserver.observe(this.content); }); } disconnectedCallback() { super.disconnectedCallback(); this.removeEventListener('submit', this.#handleSubmit); this.#contentResizeObserver.disconnect(); this.#contentResizeObserver = null; } #handleSubmit(event) { const form = event.target; const { submitter } = event; if (form.method !== 'dialog' || !submitter) { return; } this.close(submitter.getAttribute('value') ?? this.returnValue); } #handleCancel; #handleIconSlotChange() { this.hasIcon = this.assignedIcons.length > 0; } #handleHeadlineSlotChange() { this.hasHeadline = this.assignedHeadlines.length > 0; } #handleScroll() { this.#setScrollDividers(); } #setScrollDividers() { this.#setTopScrollDivider(); this.#setBottomScrollDivider(); } #setBottomScrollDivider() { const scrollBottom = this.content.scrollTop + this.content.offsetHeight; if (scrollBottom >= this.content.scrollHeight) { this.content.classList.remove(bottomDividerClass); return; } this.content.classList.add(bottomDividerClass); } #setTopScrollDivider() { if (this.content.scrollTop) { this.content.classList.add(topDividerClass); return; } this.content.classList.remove(topDividerClass); } async show() { this.#open = true; this.setAttribute('open', ''); await this.updateComplete; this.dialog.showModal(); const autoFocusElement = this.querySelector('[autofocus]'); autoFocusElement?.focus(); this.content.scrollTop = 0; } async close(returnValue = this.returnValue) { this.#open = false; this.removeAttribute('open'); await this.updateComplete; if (!this.dialog.open || this.open) { return; } const preventClose = !this.dispatchEvent(new Event('close', { cancelable: true })); if (preventClose) { this.#open = true; return; } this.open = false; const closed = new Promise(resolve => this.container.addEventListener('animationend', () => { resolve(); this.classList.remove('closing'); this.dialog.close(returnValue); this.dispatchEvent(new Event('closed')); }, { capture: true, once: true })); this.classList.add('closing'); await closed; } #handleScrimClick() { const cancelPrevented = !this.dispatchEvent(new Event('cancel', { cancelable: true })); if (cancelPrevented) { return; } this.close(); } }; __decorate([ property({ type: Boolean }) ], UmDialog.prototype, "open", null); __decorate([ property({ type: Boolean, attribute: 'has-headline', reflect: true }) ], UmDialog.prototype, "hasHeadline", void 0); __decorate([ property({ type: Boolean, attribute: 'has-icon', reflect: true }) ], UmDialog.prototype, "hasIcon", void 0); __decorate([ query('dialog') ], UmDialog.prototype, "dialog", void 0); __decorate([ query('.scrim') ], UmDialog.prototype, "scrim", void 0); __decorate([ query('.content') ], UmDialog.prototype, "content", void 0); __decorate([ query('.container') ], UmDialog.prototype, "container", void 0); __decorate([ queryAssignedElements({ slot: 'headline', flatten: true }) ], UmDialog.prototype, "assignedHeadlines", void 0); __decorate([ queryAssignedElements({ slot: 'icon', flatten: true }) ], UmDialog.prototype, "assignedIcons", void 0); UmDialog = __decorate([ customElement('u-dialog') ], UmDialog); export { UmDialog }; //# sourceMappingURL=dialog.js.map