import { __decorate } from 'tslib';
import { property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { literal, html } from 'lit/static-html.js';
import ButtonElement from '../../base/button-element.js';
import { HasSlotController } from '../../utils/slot.js';
import { FormSubmitController } from '../../utils/formSubmitController.js';
import css_248z from '../../styles/anchor.js';
import css_248z$1 from './button.js';

/**
 * @summary Custom button styles for actions in forms, dialogs, and more with support for multiple sizes, states, and more.
 *
 * @slot default - The button's label.
 * @slot leftIcon - The slot for icon to the left of the button text
 * @slot rightIcon - The slot for icon to the right of the button text
 *
 * @event sgds-blur - Emitted when the button is blurred.
 * @event sgds-focus - Emitted when the button is focused.
 *
 *
 */
class SgdsButton extends ButtonElement {
    constructor() {
        super(...arguments);
        /** @internal */
        this.formSubmitController = new FormSubmitController(this, {
            form: (input) => {
                // Buttons support a form attribute that points to an arbitrary form, so if this attribute it set we need to query
                // the form from the same root using its id
                if (input.hasAttribute("form")) {
                    const doc = input.getRootNode();
                    const formId = input.getAttribute("form");
                    return doc.getElementById(formId);
                }
                // Fall back to the closest containing form
                return input.closest("form");
            }
        });
        /** The behavior of the button with default as `type='button', `reset` resets all the controls to their initial values and `submit` submits the form data to the server */
        this.type = "button";
        /** When set, the button will be in full width. */
        this.fullWidth = false;
        /** Used only for SSR to indicate the presence of the `leftIcon` slot. */
        this.hasLeftIconSlot = false;
        /** Used only for SSR to indicate the presence of the `rightIcon` slot. */
        this.hasRightIconSlot = false;
        this.hasSlotController = new HasSlotController(this, "leftIcon", "rightIcon");
        this._clickHandler = () => {
            if (this.type === "submit") {
                this.formSubmitController.submit(this);
            }
            if (this.type === "reset") {
                this.formSubmitController.reset(this);
            }
        };
    }
    updated() {
        if (!this.hasLeftIconSlot)
            this.hasLeftIconSlot = this.hasSlotController.test("leftIcon");
        if (!this.hasRightIconSlot)
            this.hasRightIconSlot = this.hasSlotController.test("rightIcon");
    }
    _handleClick(event) {
        if (this.disabled || this.loading) {
            event.preventDefault();
            event.stopPropagation();
            return;
        }
        this.removeEventListener("click", this._clickHandler);
        this.addEventListener("click", this._clickHandler);
    }
    render() {
        const isLink = this.href;
        const tag = isLink ? literal `a` : literal `button`;
        const noIcon = !this.hasLeftIconSlot && !this.hasRightIconSlot;
        return html `
      <${tag}
        class="btn ${classMap({
            disabled: this.disabled,
            active: this.active,
            "has-left-icon": this.hasLeftIconSlot,
            "has-right-icon": this.hasRightIconSlot,
            "no-icon": noIcon,
            loading: this.loading
        })}"
        ?disabled=${ifDefined(isLink ? undefined : this.disabled)}
        type=${ifDefined(isLink ? undefined : this.type)}
        href=${ifDefined(isLink ? this.href : undefined)}
        target=${ifDefined(isLink ? this.target : undefined)}
        download=${ifDefined(isLink ? this.download : undefined)}
        rel=${ifDefined(isLink && this.target === "_blank" ? "noreferrer noopener" : undefined)}
        role=${ifDefined(isLink ? "button" : undefined)}
        aria-disabled=${this.disabled || this.loading ? "true" : "false"}
        tabindex=${this.disabled ? "-1" : "0"}
        @click=${this._handleClick}
        @keydown=${this._handleKeydown}
        @focus=${this._handleFocus}
        @blur=${this._handleBlur}
        aria-label=${ifDefined(this.loading ? "Loading" : this.ariaLabel)}
      >
       ${this.loading
            ? html `<sgds-spinner
               size=${ifDefined(this._assignSpinnerSize(this.size))}
               tone=${ifDefined(this._assignSpinnerTone(this.tone, this.variant))}
             ></sgds-spinner>`
            : html `<slot name="leftIcon"></slot>
               <span><slot></slot></span>
               <slot name="rightIcon"></slot>`}
      
      </${tag}>
    `;
    }
}
SgdsButton.styles = [...ButtonElement.styles, css_248z, css_248z$1];
__decorate([
    property({ type: String, reflect: true })
], SgdsButton.prototype, "type", void 0);
__decorate([
    property({ type: String, reflect: true })
], SgdsButton.prototype, "form", void 0);
__decorate([
    property({ type: String, reflect: true, attribute: "formaction" })
], SgdsButton.prototype, "formAction", void 0);
__decorate([
    property({ type: String, reflect: true, attribute: "formmethod" })
], SgdsButton.prototype, "formMethod", void 0);
__decorate([
    property({ attribute: "formnovalidate", type: Boolean, reflect: true })
], SgdsButton.prototype, "formNoValidate", void 0);
__decorate([
    property({ type: String, reflect: true, attribute: "formtarget" })
], SgdsButton.prototype, "formTarget", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], SgdsButton.prototype, "fullWidth", void 0);
__decorate([
    property({ type: Boolean })
], SgdsButton.prototype, "hasLeftIconSlot", void 0);
__decorate([
    property({ type: Boolean })
], SgdsButton.prototype, "hasRightIconSlot", void 0);

export { SgdsButton, SgdsButton as default };
//# sourceMappingURL=sgds-button.js.map
