'use client';
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var tslib = require('tslib');
var lit = require('lit');
var decorators_js = require('lit/decorators.js');
var classMap_js = require('lit/directives/class-map.js');
var ifDefined_js = require('lit/directives/if-defined.js');
var live_js = require('lit/directives/live.js');
var sgdsIcon = require('../Icon/sgds-icon.cjs.js');
var formControlElement = require('../../base/form-control-element.cjs.js');
var defaultvalue = require('../../utils/defaultvalue.cjs.js');
var validatorMixin = require('../../utils/validatorMixin.cjs.js');
var watch = require('../../utils/watch.cjs.js');
var checkbox = require('./checkbox.cjs.js');
var formCheck = require('../../styles/form-check.cjs.js');

/**
 * @summary Checkbox component is used when you require users to select multiple items from a list.
 *
 * @slot default - The label of checkbox.
 *
 * @event sgds-change - Emitted when the checked state changes.
 * @event sgds-blur - Emitted when input is not in focus.
 * @event sgds-focus - Emitted when input is in focus.
 * @event sgds-check - Emitted when checkbox is checked
 * @event sgds-uncheck - Emitted when checkbox is unchecked
 */
class SgdsCheckbox extends validatorMixin.SgdsFormValidatorMixin(formControlElement["default"]) {
    constructor() {
        super(...arguments);
        /** Draws the checkbox in a checked state. */
        this.checked = false;
        /** Gets or sets the default value used to reset this element. The initial value corresponds to the one originally specified in the HTML that created this element. */
        this.defaultChecked = false;
        /** Marks the checkbox input as indeterminate , with indeterminate logo  */
        this.indeterminate = false;
        /** Makes the checkbox a required field. */
        this.required = false;
        /**Feedback text for error state when validated */
        this.invalidFeedback = "";
        this._isTouched = false;
        // Delegates host-targeted clicks to the internal input so that clicking anywhere
        // on the sgds-checkbox element (e.g. expanded padding inside sgds-dropdown-item) toggles
        // the checkbox. Clicks already originating from inside the shadow DOM are left alone.
        this._handleHostClick = (e) => {
            if (e.composedPath()[0] === this) {
                e.stopPropagation();
                this.input.click();
            }
        };
    }
    /** Simulates a click on the checkbox. */
    click() {
        this.input.click();
    }
    /** Sets focus on the checkbox. */
    focus(options) {
        this.input.focus(options);
    }
    /** Removes focus from the checkbox. */
    blur() {
        this.input.blur();
    }
    _handleChange(e) {
        if (this.indeterminate) {
            this.indeterminate = !this.indeterminate;
        }
        this.checked = !this.checked;
        super._mixinHandleChange(e);
        this.emit("sgds-change", { detail: { checked: this.checked, value: this.value } });
        this.checked
            ? this.emit("sgds-check", { detail: { value: this.value } })
            : this.emit("sgds-uncheck", { detail: { value: this.value } });
    }
    _handleKeyDown(event) {
        const hasModifier = event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
        if (event.key === "Enter" && !hasModifier) {
            this.click();
        }
    }
    _handleBlur() {
        this._isTouched = true;
        this.emit("sgds-blur");
    }
    _handleFocus() {
        this.emit("sgds-focus");
    }
    _handleInvalid(e) {
        e.preventDefault();
        this.invalid = true;
    }
    /** @internal */
    _handleDisabledChange() {
        // Disabled form controls are always valid, so we need to recheck validity when the state changes
        this.setInvalid(false);
    }
    _handleIsTouched() {
        if (this._isTouched) {
            this.invalid = !this.input.checkValidity();
        }
    }
    _mixinResetFormControl() {
        this._isTouched = false;
        this.checked = this.input.checked = this.defaultChecked;
        this.input.dispatchEvent(new InputEvent("reset"));
        this._mixinResetValidity(this.input);
    }
    /**
     * Checks for validity. Under the hood, HTMLFormElement's reportValidity method calls this method to check for component's validity state
     * Note that the native error popup is prevented for SGDS form components by default. Instead the validation message shows up in the feedback container of SgdsInput
     */
    reportValidity() {
        return this._mixinReportValidity();
    }
    /**
     * Checks for validity without any native error popup message
     */
    checkValidity() {
        return this._mixinCheckValidity();
    }
    /**
     * Returns the ValidityState object
     */
    get validity() {
        return this._mixinGetValidity();
    }
    /**
     * Returns the validation message based on the ValidityState
     */
    get validationMessage() {
        return this._mixinGetValidationMessage();
    }
    firstUpdated(_changedProperties) {
        super.firstUpdated(_changedProperties);
        this.checked && this.emit("sgds-check", { detail: { value: this.value } });
    }
    connectedCallback() {
        super.connectedCallback();
        this.addEventListener("click", this._handleHostClick);
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        this.removeEventListener("click", this._handleHostClick);
    }
    render() {
        const displayFeedbackStyle = this.hasFeedback === "both" || this.hasFeedback === "style";
        const displayFeedbackText = this.hasFeedback === "both" || this.hasFeedback === "text";
        return lit.html `
      <div class="form-check">
        <input
          class=${classMap_js.classMap({
            "form-check-input": true,
            "is-invalid": displayFeedbackStyle && this.invalid
        })}
          type="checkbox"
          id=${this._controlId}
          aria-invalid=${this.invalid ? "true" : "false"}
          name=${ifDefined_js.ifDefined(this.name)}
          ?indeterminate=${this.indeterminate}
          ?required=${this.required}
          aria-disabled=${this.disabled ? "true" : "false"}
          aria-checked=${this.checked ? "true" : "false"}
          @change=${(e) => this._handleChange(e)}
          @keydown=${this._handleKeyDown}
          @invalid=${(e) => this._handleInvalid(e)}
          ?checked=${live_js.live(this.checked)}
          .disabled=${this.disabled}
          .required=${this.required}
          @blur=${this._handleBlur}
          @focus=${this._handleFocus}
        />
        <label for="${this._controlId}" class="form-check-label" id="${this._labelId}"><slot></slot></label>
      </div>
      ${displayFeedbackText && this.invalid
            ? lit.html `
            <div class="invalid-feedback-container">
              <slot name="invalidIcon">
                <sgds-icon name="exclamation-circle-fill" size="md"></sgds-icon>
              </slot>
              <div id="checkbox-feedback" tabindex="0" class="invalid-feedback">
                ${this.invalidFeedback ? this.invalidFeedback : this.input.validationMessage}
              </div>
            </div>
          `
            : lit.nothing}
    `;
    }
}
SgdsCheckbox.styles = [...formControlElement["default"].styles, formCheck["default"], checkbox["default"]];
/**@internal */
SgdsCheckbox.dependencies = {
    "sgds-icon": sgdsIcon.SgdsIcon
};
tslib.__decorate([
    decorators_js.property({ type: String, reflect: true })
], SgdsCheckbox.prototype, "value", void 0);
tslib.__decorate([
    decorators_js.property({ type: Boolean, reflect: true })
], SgdsCheckbox.prototype, "checked", void 0);
tslib.__decorate([
    decorators_js.property({ type: String, reflect: true })
], SgdsCheckbox.prototype, "hasFeedback", void 0);
tslib.__decorate([
    defaultvalue.defaultValue("checked")
], SgdsCheckbox.prototype, "defaultChecked", void 0);
tslib.__decorate([
    decorators_js.property({ type: Boolean, reflect: true })
], SgdsCheckbox.prototype, "indeterminate", void 0);
tslib.__decorate([
    decorators_js.property({ type: Boolean, reflect: true })
], SgdsCheckbox.prototype, "required", void 0);
tslib.__decorate([
    decorators_js.property({ type: String, reflect: true })
], SgdsCheckbox.prototype, "invalidFeedback", void 0);
tslib.__decorate([
    decorators_js.state()
], SgdsCheckbox.prototype, "_isTouched", void 0);
tslib.__decorate([
    watch.watch("disabled", { waitUntilFirstUpdate: true })
], SgdsCheckbox.prototype, "_handleDisabledChange", null);
tslib.__decorate([
    watch.watch("_isTouched", { waitUntilFirstUpdate: true })
], SgdsCheckbox.prototype, "_handleIsTouched", null);

exports.SgdsCheckbox = SgdsCheckbox;
exports["default"] = SgdsCheckbox;
//# sourceMappingURL=sgds-checkbox.cjs.js.map
