import { __decorate } from "tslib";
import { html } from "lit";
import { property, queryAsync, state } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js";
import { when } from 'lit/directives/when.js';
import { Button } from "./Button.js";
import { ripple } from '../effects/rippleDirective.js';
import '../../define/ui/ui-ripple.js';
/**
 * The type of the button rendered.
 */
export var ButtonType;
(function (ButtonType) {
    ButtonType["elevated"] = "elevated";
    ButtonType["filled"] = "filled";
    ButtonType["tonal"] = "tonal";
    ButtonType["outlined"] = "outlined";
    ButtonType["text"] = "text";
})(ButtonType || (ButtonType = {}));
/**
 * 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
 */
export default class UiButton extends Button {
    static get formAssociated() {
        return true;
    }
    #_internals;
    get form() {
        return this.#_internals && this.#_internals.form;
    }
    #_value;
    /**
     * Defines the value associated with the button's name when it's submitted with the form data.
     * This value is passed to the server in params when the form is submitted using this button.
     * @attribute
     */
    get value() {
        return this.#_value;
    }
    set value(value) {
        if (this.#_value === value) {
            return;
        }
        this.#_value = value;
        this.#_internals?.setFormValue(value || null);
    }
    constructor() {
        super();
        this.#_internals = this.attachInternals();
        /**
         * Whether to render the icon at the inline end of the label rather than the
         * inline start.
         * @attribute
         */
        this.trailingIcon = false;
        this.showRipple = false;
        this.getRipple = () => {
            this.showRipple = true;
            return this.ripple;
        };
        this.renderRipple = () => {
            const { disabled } = this;
            return html `<ui-ripple class="ripple" ?disabled="${disabled}"></ui-ripple>`;
        };
        this.type = ButtonType.filled;
        this._hasIcon = false;
    }
    async pressRipple() {
        const element = await this.getRipple();
        if (element && !element.isPressed) {
            element.beginPress();
        }
    }
    async endRipple() {
        const element = await this.getRipple();
        element?.endPress();
    }
    beginPress(options) {
        super.beginPress(options);
        this.pressRipple();
    }
    endPress(config) {
        super.endPress(config);
        this.endRipple();
        const { cancelled, reason } = config;
        if (cancelled) {
            return;
        }
        if (!reason || reason === 'enter' || reason === 'space') {
            this._submitHandler();
        }
        if (reason === 'enter' || reason === 'space') {
            this.click();
        }
    }
    _submitHandler() {
        const { form, name, value, submit, disabled } = this;
        if (!form || !submit || disabled) {
            return;
        }
        let button;
        if (name || value) {
            button = document.createElement('button');
            if (name) {
                button.name = name;
            }
            if (value) {
                button.value = value;
            }
            button.type = 'submit';
            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.
     */
    _iconSlotChange(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,
        });
        return html `
    <div class="${containerClasses}" ${ripple(this.getRipple)}>
      <div class="container"></div>
      <div class="state"></div>
      ${when(this.showRipple, this.renderRipple)}
      <div class="content">
        ${trailingIcon ? '' : this._iconTemplate()}
        <slot></slot>
        ${trailingIcon ? this._iconTemplate() : ''}
      </div>
    </div>
    `;
    }
    _iconTemplate() {
        return html `<slot name="icon" @slotchange="${this._iconSlotChange}"></slot>`;
    }
}
__decorate([
    property({ type: String, reflect: true, })
], UiButton.prototype, "type", void 0);
__decorate([
    state()
], UiButton.prototype, "_hasIcon", void 0);
__decorate([
    property({ type: String })
], UiButton.prototype, "name", void 0);
__decorate([
    property({ type: String })
], UiButton.prototype, "value", null);
__decorate([
    property({ type: Boolean, attribute: 'trailingicon', reflect: true })
], UiButton.prototype, "trailingIcon", void 0);
__decorate([
    queryAsync('ui-ripple')
], UiButton.prototype, "ripple", void 0);
__decorate([
    state()
], UiButton.prototype, "showRipple", void 0);
__decorate([
    property({ type: Boolean, reflect: true, })
], UiButton.prototype, "submit", void 0);
//# sourceMappingURL=UiButton.js.map