@universal-material/web
Version:
Material web components
216 lines • 6.93 kB
JavaScript
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" =${this.#handleScrimClick}></div>
<div class="container" part="container">
<u-elevation></u-elevation>
<div class="icon" part="icon">
<slot
name="icon"
=${this.#handleIconSlotChange}>
</slot>
</div>
<div class="headline" part="headline">
<slot
name="headline"
=${this.#handleHeadlineSlotChange}>
</slot>
</div>
<div
class="content"
part="content"
=${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