import { __esDecorate, __runInitializers } from "tslib";
import { html, LitElement, nothing } from 'lit';
import { cancelEvent } from '@api-client/core/lib/events/Utils.js';
import { property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import '../../button/ui-button.js';
import '../../icon-button/ui-icon-button.js';
import '../../icons/ui-icon.js';
/**
 * Snackbars provide brief messages about app processes at the bottom of the screen.
 *
 * Snackbars inform users of a process that an app has performed or will perform.
 * They appear temporarily, towards the bottom of the screen.
 * They shouldn’t interrupt the user experience, and they don’t require user input to disappear.
 *
 * Only one snackbar may be displayed at a time.
 *
 * A snackbar can contain a single action. "Dismiss" or "cancel" actions are optional.
 *
 * Snackbars communicate messages that are minimally interruptive and don’t require user action.
 *
 * **Caution**, Do not use this element directly.
 *
 * A snackbar is the UI to render in the application. It does not care whether another
 * message is already rendered. Use `SnackNotifications` to manage notification system.
 * The `SnackNotifications` will position toasts directly under the `body` which will make
 * it easier to manage especially when relative / absolute positioning is used.
 *
 * @fires open - When the open state changes. Note, this event is not dispatched when it was programmatically closed.
 * @fires dismiss - When the message was closed via the API.
 * @fires action - When the action button was activated.
 */
let Snackbar = (() => {
    let _classSuper = LitElement;
    let _persistent_decorators;
    let _persistent_initializers = [];
    let _persistent_extraInitializers = [];
    let _cancellable_decorators;
    let _cancellable_initializers = [];
    let _cancellable_extraInitializers = [];
    let _timeout_decorators;
    let _timeout_initializers = [];
    let _timeout_extraInitializers = [];
    let _action_decorators;
    let _action_initializers = [];
    let _action_extraInitializers = [];
    let _close_decorators;
    let _close_initializers = [];
    let _close_extraInitializers = [];
    let _open_decorators;
    let _open_initializers = [];
    let _open_extraInitializers = [];
    return class Snackbar extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _persistent_decorators = [property({ type: Boolean })];
            _cancellable_decorators = [property({ type: Boolean })];
            _timeout_decorators = [property({ type: Number })];
            _action_decorators = [property({ type: String })];
            _close_decorators = [property({ type: Boolean })];
            _open_decorators = [property({ type: Boolean, reflect: true })];
            __esDecorate(this, null, _persistent_decorators, { kind: "accessor", name: "persistent", static: false, private: false, access: { has: obj => "persistent" in obj, get: obj => obj.persistent, set: (obj, value) => { obj.persistent = value; } }, metadata: _metadata }, _persistent_initializers, _persistent_extraInitializers);
            __esDecorate(this, null, _cancellable_decorators, { kind: "accessor", name: "cancellable", static: false, private: false, access: { has: obj => "cancellable" in obj, get: obj => obj.cancellable, set: (obj, value) => { obj.cancellable = value; } }, metadata: _metadata }, _cancellable_initializers, _cancellable_extraInitializers);
            __esDecorate(this, null, _timeout_decorators, { kind: "accessor", name: "timeout", static: false, private: false, access: { has: obj => "timeout" in obj, get: obj => obj.timeout, set: (obj, value) => { obj.timeout = value; } }, metadata: _metadata }, _timeout_initializers, _timeout_extraInitializers);
            __esDecorate(this, null, _action_decorators, { kind: "accessor", name: "action", static: false, private: false, access: { has: obj => "action" in obj, get: obj => obj.action, set: (obj, value) => { obj.action = value; } }, metadata: _metadata }, _action_initializers, _action_extraInitializers);
            __esDecorate(this, null, _close_decorators, { kind: "accessor", name: "close", static: false, private: false, access: { has: obj => "close" in obj, get: obj => obj.close, set: (obj, value) => { obj.close = value; } }, metadata: _metadata }, _close_initializers, _close_extraInitializers);
            __esDecorate(this, null, _open_decorators, { kind: "accessor", name: "open", static: false, private: false, access: { has: obj => "open" in obj, get: obj => obj.open, set: (obj, value) => { obj.open = value; } }, metadata: _metadata }, _open_initializers, _open_extraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        #persistent_accessor_storage = __runInitializers(this, _persistent_initializers, false
        /**
         * Whether the snackbar can be cancelled via user interaction.
         *
         * @default true
         * @attribute
         */
        );
        /**
         * When set the snackbar does not timeout.
         * It has to be cancelled by user interaction or programmatically.
         *
         * When the `cancellable` is set to false the user won't be able to dismiss the
         * snackbar and the application must remove the snackbar after the process
         * finish. Otherwise another snackbar won't appear.
         *
         * @default false
         * @attribute
         */
        get persistent() { return this.#persistent_accessor_storage; }
        set persistent(value) { this.#persistent_accessor_storage = value; }
        #cancellable_accessor_storage = (__runInitializers(this, _persistent_extraInitializers), __runInitializers(this, _cancellable_initializers, true
        /**
         * The time in milliseconds after which the message is removed.
         * Has not effect when `persistent` flag is set.
         *
         * @default 5000
         * @attribute
         */
        ));
        /**
         * Whether the snackbar can be cancelled via user interaction.
         *
         * @default true
         * @attribute
         */
        get cancellable() { return this.#cancellable_accessor_storage; }
        set cancellable(value) { this.#cancellable_accessor_storage = value; }
        #timeout_accessor_storage = (__runInitializers(this, _cancellable_extraInitializers), __runInitializers(this, _timeout_initializers, 5000
        /**
         * The action to render next to the message.
         * There can be only one action.
         * It is only rendered when `actionCallback` is set.
         *
         * @attribute
         */
        ));
        /**
         * The time in milliseconds after which the message is removed.
         * Has not effect when `persistent` flag is set.
         *
         * @default 5000
         * @attribute
         */
        get timeout() { return this.#timeout_accessor_storage; }
        set timeout(value) { this.#timeout_accessor_storage = value; }
        #action_accessor_storage = (__runInitializers(this, _timeout_extraInitializers), __runInitializers(this, _action_initializers, void 0));
        /**
         * The action to render next to the message.
         * There can be only one action.
         * It is only rendered when `actionCallback` is set.
         *
         * @attribute
         */
        get action() { return this.#action_accessor_storage; }
        set action(value) { this.#action_accessor_storage = value; }
        #close_accessor_storage = (__runInitializers(this, _action_extraInitializers), __runInitializers(this, _close_initializers, void 0));
        /**
         * Whether to render affordable "close" icon.
         *
         * @attribute
         */
        get close() { return this.#close_accessor_storage; }
        set close(value) { this.#close_accessor_storage = value; }
        #open_accessor_storage = (__runInitializers(this, _close_extraInitializers), __runInitializers(this, _open_initializers, void 0));
        /**
         * Whether the message is being rendered.
         *
         * @attribute
         */
        get open() { return this.#open_accessor_storage; }
        set open(value) { this.#open_accessor_storage = value; }
        dismissed = __runInitializers(this, _open_extraInitializers);
        timer;
        touchXStart;
        touchYStart;
        constructor() {
            super();
            this.addEventListener('touchstart', this.touchstartHandler.bind(this), { passive: true });
            this.addEventListener('touchend', this.touchendHandler.bind(this), { passive: true });
            this.addEventListener('transitionend', this.transitionendHandler.bind(this), { passive: true });
        }
        updated(cp) {
            if (cp.has('open')) {
                if (this.open) {
                    this.setupTimeout();
                }
                else {
                    this.clearTimer();
                }
            }
        }
        /**
         * Dismisses the snackbar
         */
        dismiss() {
            this.dismissed = true;
            this.open = false;
        }
        setupTimeout() {
            const { timeout = 5000, persistent } = this;
            this.clearTimer();
            if (persistent) {
                return;
            }
            this.timer = setTimeout(() => {
                this.timeoutHandler();
            }, timeout);
        }
        clearTimer() {
            if (this.timer) {
                clearTimeout(this.timer);
                this.timer = undefined;
            }
        }
        timeoutHandler() {
            this.open = false;
        }
        touchstartHandler(e) {
            if (this.cancellable === false) {
                return;
            }
            this.touchXStart = e.changedTouches[0].screenX;
            this.touchYStart = e.changedTouches[0].screenY;
        }
        touchendHandler(e) {
            if (this.cancellable === false) {
                return;
            }
            const { touchXStart, touchYStart } = this;
            if (typeof touchXStart !== 'number' || typeof touchYStart !== 'number') {
                return;
            }
            this.touchXStart = undefined;
            this.touchYStart = undefined;
            const endX = e.changedTouches[0].screenX;
            const endY = e.changedTouches[0].screenY;
            const xDelta = Math.abs(endX - touchXStart);
            const yDelta = Math.abs(endY - touchYStart);
            const threshold = 20;
            if (xDelta > threshold || yDelta > threshold) {
                this.open = false;
            }
        }
        actionHandler() {
            this.dispatchEvent(new Event('action'));
            this.dismiss();
        }
        transitionendHandler() {
            if (!this.dismissed) {
                this.dispatchEvent(new Event('open'));
            }
            else {
                this.dismissed = false;
                this.dispatchEvent(new Event('dismiss'));
            }
        }
        closeHandler() {
            this.open = false;
        }
        render() {
            const classes = {
                body: true,
                withAction: !!this.action,
                withClose: !!this.close,
            };
            return html `
      <div class="${classMap(classes)}">
        <slot></slot>
      </div>
      ${this.renderAction()} ${this.renderIcon()}
    `;
        }
        renderAction() {
            const { action } = this;
            if (!action) {
                return nothing;
            }
            return html `
      <ui-button color="text" class="action" @click="${this.actionHandler}" @action="${cancelEvent}"
        >${action}</ui-button
      >
    `;
        }
        renderIcon() {
            const { close } = this;
            if (!close) {
                return nothing;
            }
            return html `
      <ui-icon-button @click="${this.closeHandler}" class="icon" @action="${cancelEvent}">
        <ui-icon icon="close"></ui-icon>
      </ui-icon-button>
    `;
        }
    };
})();
export { Snackbar };
//# sourceMappingURL=Snackbar.js.map