var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var IgcDialogComponent_1;
import { LitElement, html, nothing } from 'lit';
import { property, queryAssignedElements, state } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { createRef, ref } from 'lit/directives/ref.js';
import { addAnimationController } from '../../animations/player.js';
import { fadeIn, fadeOut } from '../../animations/presets/fade/index.js';
import { themes } from '../../theming/theming-decorator.js';
import IgcButtonComponent from '../button/button.js';
import { blazorAdditionalDependencies } from '../common/decorators/blazorAdditionalDependencies.js';
import { watch } from '../common/decorators/watch.js';
import { registerComponent } from '../common/definitions/register.js';
import { EventEmitterMixin } from '../common/mixins/event-emitter.js';
import { createCounter, isEmpty, numberInRangeInclusive, partNameMap, } from '../common/util.js';
import { styles } from './themes/dialog.base.css.js';
import { styles as shared } from './themes/shared/dialog.common.css.js';
import { all } from './themes/themes.js';
let IgcDialogComponent = IgcDialogComponent_1 = class IgcDialogComponent extends EventEmitterMixin(LitElement) {
    constructor() {
        super(...arguments);
        this.titleId = `title-${IgcDialogComponent_1.increment()}`;
        this.dialogRef = createRef();
        this.animationPlayer = addAnimationController(this, this.dialogRef);
        this.animating = false;
        this.keepOpenOnEscape = false;
        this.closeOnOutsideClick = false;
        this.hideDefaultAction = false;
        this.open = false;
        this.formSubmitHandler = (e) => {
            if (e.submitter) {
                this.returnValue = e.submitter?.value ?? '';
            }
            if (!e.defaultPrevented) {
                this._hide(true);
            }
        };
    }
    static register() {
        registerComponent(IgcDialogComponent_1, IgcButtonComponent);
    }
    get dialog() {
        return this.dialogRef.value;
    }
    handleOpenState() {
        this.open ? this.dialog.showModal() : this.dialog.close();
    }
    createRenderRoot() {
        const root = super.createRenderRoot();
        root.addEventListener('slotchange', () => this.requestUpdate());
        return root;
    }
    firstUpdated() {
        if (this.open) {
            this.dialog.showModal();
        }
    }
    async toggleAnimation(dir) {
        const animation = dir === 'open' ? fadeIn : fadeOut;
        const [_, event] = await Promise.all([
            this.animationPlayer.stopAll(),
            this.animationPlayer.play(animation()),
        ]);
        return event.type === 'finish';
    }
    async _hide(emitEvent = false) {
        if (!this.open || (emitEvent && !this.emitClosing())) {
            return false;
        }
        this.animating = true;
        await this.toggleAnimation('close');
        this.open = false;
        this.animating = false;
        if (emitEvent) {
            await this.updateComplete;
            this.emitEvent('igcClosed');
        }
        return true;
    }
    async show() {
        if (this.open) {
            return false;
        }
        this.open = true;
        await this.toggleAnimation('open');
        return true;
    }
    async hide() {
        return this._hide();
    }
    async toggle() {
        return this.open ? this.hide() : this.show();
    }
    handleCancel(event) {
        event.preventDefault();
        if (!this.keepOpenOnEscape) {
            this._hide(true);
        }
    }
    handleClick({ clientX, clientY, target }) {
        if (this.closeOnOutsideClick && this.dialog === target) {
            const rect = this.dialog.getBoundingClientRect();
            const inX = numberInRangeInclusive(clientX, rect.left, rect.right);
            const inY = numberInRangeInclusive(clientY, rect.top, rect.bottom);
            if (!(inX && inY)) {
                this._hide(true);
            }
        }
    }
    emitClosing() {
        return this.emitEvent('igcClosing', { cancelable: true });
    }
    handleContentChange() {
        const forms = this.querySelectorAll('form[method="dialog"]');
        for (const form of forms) {
            form.removeEventListener('submit', this.formSubmitHandler);
            form.addEventListener('submit', this.formSubmitHandler);
        }
    }
    render() {
        const label = this.ariaLabel ? this.ariaLabel : undefined;
        const labelledby = label ? undefined : this.titleId;
        const backdropParts = partNameMap({
            backdrop: true,
            animating: this.animating,
        });
        const baseParts = partNameMap({
            base: true,
            titled: this.titleElements.length > 0 || this.title,
            footed: this.footerElements.length > 0 || !this.hideDefaultAction,
        });
        return html `
      <div part=${backdropParts} aria-hidden=${!this.open}></div>
      <dialog
        ${ref(this.dialogRef)}
        part=${baseParts}
        role="dialog"
        @click=${this.handleClick}
        @cancel=${this.handleCancel}
        aria-label=${ifDefined(label)}
        aria-labelledby=${ifDefined(labelledby)}
      >
        <header part="title" id=${this.titleId}>
          <slot name="title"><span>${this.title}</span></slot>
        </header>
        <section part="content">
          <slot name="message" .hidden=${isEmpty(this.messageElements)}></slot>
          <slot @slotchange=${this.handleContentChange}></slot>
        </section>
        <footer part="footer">
          <slot name="footer">
            ${this.hideDefaultAction
            ? nothing
            : html `<igc-button variant="flat" @click=${() => this._hide(true)}
                  >OK</igc-button
                >`}
          </slot>
        </footer>
      </dialog>
    `;
    }
};
IgcDialogComponent.tagName = 'igc-dialog';
IgcDialogComponent.styles = [styles, shared];
IgcDialogComponent.increment = createCounter();
__decorate([
    state()
], IgcDialogComponent.prototype, "animating", void 0);
__decorate([
    queryAssignedElements({ slot: 'title' })
], IgcDialogComponent.prototype, "titleElements", void 0);
__decorate([
    queryAssignedElements({ slot: 'message' })
], IgcDialogComponent.prototype, "messageElements", void 0);
__decorate([
    queryAssignedElements({ slot: 'footer' })
], IgcDialogComponent.prototype, "footerElements", void 0);
__decorate([
    property({ type: Boolean, attribute: 'keep-open-on-escape' })
], IgcDialogComponent.prototype, "keepOpenOnEscape", void 0);
__decorate([
    property({ type: Boolean, attribute: 'close-on-outside-click' })
], IgcDialogComponent.prototype, "closeOnOutsideClick", void 0);
__decorate([
    property({ type: Boolean, attribute: 'hide-default-action' })
], IgcDialogComponent.prototype, "hideDefaultAction", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], IgcDialogComponent.prototype, "open", void 0);
__decorate([
    property()
], IgcDialogComponent.prototype, "title", void 0);
__decorate([
    property({ attribute: false })
], IgcDialogComponent.prototype, "returnValue", void 0);
__decorate([
    watch('open', { waitUntilFirstUpdate: true })
], IgcDialogComponent.prototype, "handleOpenState", null);
IgcDialogComponent = IgcDialogComponent_1 = __decorate([
    themes(all),
    blazorAdditionalDependencies('IgcButtonComponent')
], IgcDialogComponent);
export default IgcDialogComponent;
//# sourceMappingURL=dialog.js.map