import { __esDecorate, __runInitializers } from "tslib";
import { html, nothing } from 'lit';
import { property, queryAsync, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { UiElement } from '../../UiElement.js';
import { isDisabled, setDisabled } from '../../../lib/disabled.js';
import '../../ripple/ui-ripple.js';
import '@material/web/focus/md-focus-ring.js';
let UiButton = (() => {
    let _classSuper = UiElement;
    let _instanceExtraInitializers = [];
    let _hasIcon_decorators;
    let _hasIcon_initializers = [];
    let _hasIcon_extraInitializers = [];
    let _name_decorators;
    let _name_initializers = [];
    let _name_extraInitializers = [];
    let _set_value_decorators;
    let _trailingIcon_decorators;
    let _trailingIcon_initializers = [];
    let _trailingIcon_extraInitializers = [];
    let _ripple_decorators;
    let _ripple_initializers = [];
    let _ripple_extraInitializers = [];
    let _type_decorators;
    let _type_initializers = [];
    let _type_extraInitializers = [];
    let _set_disabled_decorators;
    return class UiButton extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _hasIcon_decorators = [state()];
            _name_decorators = [property({ type: String })];
            _set_value_decorators = [property({ type: String })];
            _trailingIcon_decorators = [property({ type: Boolean, attribute: 'trailingicon', reflect: true })];
            _ripple_decorators = [queryAsync('ui-ripple')];
            _type_decorators = [property({ type: String, reflect: true })];
            _set_disabled_decorators = [property({ reflect: true, type: Boolean })];
            __esDecorate(this, null, _hasIcon_decorators, { kind: "accessor", name: "hasIcon", static: false, private: false, access: { has: obj => "hasIcon" in obj, get: obj => obj.hasIcon, set: (obj, value) => { obj.hasIcon = value; } }, metadata: _metadata }, _hasIcon_initializers, _hasIcon_extraInitializers);
            __esDecorate(this, null, _name_decorators, { kind: "accessor", name: "name", static: false, private: false, access: { has: obj => "name" in obj, get: obj => obj.name, set: (obj, value) => { obj.name = value; } }, metadata: _metadata }, _name_initializers, _name_extraInitializers);
            __esDecorate(this, null, _set_value_decorators, { kind: "setter", name: "value", static: false, private: false, access: { has: obj => "value" in obj, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _trailingIcon_decorators, { kind: "accessor", name: "trailingIcon", static: false, private: false, access: { has: obj => "trailingIcon" in obj, get: obj => obj.trailingIcon, set: (obj, value) => { obj.trailingIcon = value; } }, metadata: _metadata }, _trailingIcon_initializers, _trailingIcon_extraInitializers);
            __esDecorate(this, null, _ripple_decorators, { kind: "accessor", name: "ripple", static: false, private: false, access: { has: obj => "ripple" in obj, get: obj => obj.ripple, set: (obj, value) => { obj.ripple = value; } }, metadata: _metadata }, _ripple_initializers, _ripple_extraInitializers);
            __esDecorate(this, null, _type_decorators, { kind: "accessor", name: "type", static: false, private: false, access: { has: obj => "type" in obj, get: obj => obj.type, set: (obj, value) => { obj.type = value; } }, metadata: _metadata }, _type_initializers, _type_extraInitializers);
            __esDecorate(this, null, _set_disabled_decorators, { kind: "setter", name: "disabled", static: false, private: false, access: { has: obj => "disabled" in obj, set: (obj, value) => { obj.disabled = value; } }, metadata: _metadata }, null, _instanceExtraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        static formAssociated = true;
        #internals = (__runInitializers(this, _instanceExtraInitializers), this.attachInternals());
        /**
         * The form associated with this element
         * @attribute {string} form - The form associated with this element when the element is outside the form.
         *                   It should be the id of the form element within the same document.
         */
        get form() {
            return this.#internals.form;
        }
        get validity() {
            return this.#internals.validity;
        }
        get validationMessage() {
            return this.#internals.validationMessage;
        }
        get willValidate() {
            return this.#internals.willValidate;
        }
        #hasIcon_accessor_storage = __runInitializers(this, _hasIcon_initializers, void 0);
        /**
         * Determines when the element has an icon in the "icon" slot.
         */
        get hasIcon() { return this.#hasIcon_accessor_storage; }
        set hasIcon(value) { this.#hasIcon_accessor_storage = value; }
        #name_accessor_storage = (__runInitializers(this, _hasIcon_extraInitializers), __runInitializers(this, _name_initializers, void 0));
        /**
         * The name of the button, submitted as a pair with the button's value as part of the form data,
         * when that button is used to submit the form.
         * @attribute
         */
        get name() { return this.#name_accessor_storage; }
        set name(value) { this.#name_accessor_storage = value; }
        #value = __runInitializers(this, _name_extraInitializers);
        get value() {
            return this.#value;
        }
        /**
         * Defines the value associated with the button's name when it's submitted with the form data.
         * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#value}
         * @attribute
         */
        set value(value) {
            if (this.#value === value) {
                return;
            }
            this.#value = value;
            this.#internals?.setFormValue(value || null);
        }
        #trailingIcon_accessor_storage = __runInitializers(this, _trailingIcon_initializers, false);
        /**
         * Whether to render the icon at the inline end of the label rather than the
         * inline start.
         * @attribute
         */
        get trailingIcon() { return this.#trailingIcon_accessor_storage; }
        set trailingIcon(value) { this.#trailingIcon_accessor_storage = value; }
        #ripple_accessor_storage = (__runInitializers(this, _trailingIcon_extraInitializers), __runInitializers(this, _ripple_initializers, void 0));
        get ripple() { return this.#ripple_accessor_storage; }
        set ripple(value) { this.#ripple_accessor_storage = value; }
        #type_accessor_storage = (__runInitializers(this, _ripple_extraInitializers), __runInitializers(this, _type_initializers, 'button'));
        /**
         * The default behavior of the button.
         * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#type}
         * @attribute
         */
        get type() { return this.#type_accessor_storage; }
        set type(value) { this.#type_accessor_storage = value; }
        get disabled() {
            return isDisabled(this);
        }
        /**
         * When set, the button is a disabled state.
         * @attribute
         */
        set disabled(value) {
            const old = isDisabled(this);
            setDisabled(this, value);
            this.requestUpdate('disabled', old);
        }
        constructor() {
            super();
            __runInitializers(this, _type_extraInitializers);
            this.hasIcon = false;
            this.actionController.cancelKeyboardEvents = true;
            this.addEventListener('keydown', this.handleKeyDown.bind(this));
            this.addEventListener('keyup', this.handleKeyUp.bind(this));
            this.addEventListener('click', this.handleClick.bind(this));
            this.addEventListener('pointerdown', this.handlePointerDown.bind(this));
            this.addEventListener('pointerup', this.handlePointerUp.bind(this));
            this.addEventListener('pointercancel', this.handlePointerCancel.bind(this));
            this.addEventListener('pointerleave', this.handlePointerLeave.bind(this));
            this.addEventListener('contextmenu', this.handleContextMenu.bind(this));
        }
        connectedCallback() {
            super.connectedCallback();
            if (!this.hasAttribute('role')) {
                this.setAttribute('role', 'button');
            }
            if (!this.hasAttribute('tabindex') && !this.disabled) {
                this.setAttribute('tabindex', '0');
            }
        }
        checkValidity() {
            return this.#internals.checkValidity();
        }
        reportValidity() {
            return this.#internals.reportValidity();
        }
        firstUpdated() {
            this.#internals?.setFormValue(this.value || null);
        }
        async pressRipple() {
            const element = await this.ripple;
            if (element && !element.isPressed) {
                element.beginPress();
            }
        }
        async endRipple() {
            const element = await this.ripple;
            element?.endPress();
        }
        beginPress(options) {
            super.beginPress(options);
            this.pressRipple();
        }
        endPress(config) {
            super.endPress(config);
            this.endRipple();
            const { cancelled, reason } = config;
            if (cancelled) {
                return;
            }
            const allowedReasons = reason === 'enter' || reason === 'space';
            if (this.type === 'submit' && (!reason || allowedReasons)) {
                this.handleSubmit();
            }
            else if (allowedReasons) {
                this.click();
            }
        }
        handleSubmit() {
            const { name, value, type, disabled, form } = this;
            if (!form || !type || disabled) {
                return;
            }
            let button;
            if (name || value) {
                button = document.createElement('button');
                if (name) {
                    button.name = name;
                }
                if (value) {
                    button.value = value;
                }
                button.type = type;
                button.hidden = true;
                form.append(button);
            }
            try {
                form.requestSubmit(button);
            }
            catch {
                // ...
            }
            if (button) {
                form.removeChild(button);
            }
        }
        /**
         * Sets the `_hasIcon` state property when the "icon" slot change event is dispatched.
         */
        handleSlotChange(e) {
            const slot = e.target;
            this.hasIcon = !!slot.assignedNodes().length;
        }
        render() {
            const { pressed = false, trailingIcon = false } = this;
            const containerClasses = classMap({
                surface: true,
                withIcon: this.hasIcon,
                pressed,
            });
            const icon = this.renderIcon();
            return html `
      <md-focus-ring part="focus-ring" .control="${this}"></md-focus-ring>
      <ui-ripple class="ripple" ?disabled="${this.disabled}"></ui-ripple>
      <div class="${containerClasses}" id="container">
        <div class="container"></div>
        <div class="state"></div>
        <div class="content">
          ${trailingIcon ? nothing : icon}
          <slot></slot>
          ${trailingIcon ? icon : nothing}
        </div>
      </div>
    `;
        }
        renderIcon() {
            return html `<slot name="icon" @slotchange="${this.handleSlotChange}"></slot>`;
        }
    };
})();
/**
 * A material design button.
 *
 * Note, this control is form associated.
 *
 * @slot icon - A slot for the icon element
 * @slot - The default slot for the label
 * @attribute {string} form - The form associated with this element when the element is outside the form.
 *                   It should be the id of the form element within the same document.
 */
export default UiButton;
//# sourceMappingURL=button.js.map