/**
 * Copyright Aquera Inc 2023
 *
 * This source code is licensed under the BSD-3-Clause license found in the
 * LICENSE file in the root directory of this source tree.
 */
import { __decorate } from "tslib";
import { html, } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { styles } from './nile-checkbox.css';
import { classMap } from 'lit/directives/class-map.js';
import { query, state } from 'lit/decorators.js';
import { defaultValue } from '../internal/default-value';
import { ifDefined } from 'lit/directives/if-defined.js';
import { live } from 'lit/directives/live.js';
import { watch } from '../internal/watch';
import NileElement from '../internal/nile-element';
/**
 * @summary Checkboxes allow the user to toggle an option on or off.
 *
 * @dependency nile-icon
 *
 * @slot - The checkbox's label.
 *
 * @event nile-blur - Emitted when the checkbox loses focus.
 * @event nile-change - Emitted when the checked state changes.
 * @event nile-focus - Emitted when the checkbox gains focus.
 * @event nile-input - Emitted when the checkbox receives input.
 * @event nile-invalid - Emitted when the form control has been checked for validity and its constraints aren't satisfied.
 *
 * @csspart base - The component's base wrapper.
 * @csspart control - The square container that wraps the checkbox's checked state.
 * @csspart control--checked - Matches the control part when the checkbox is checked.
 * @csspart control--indeterminate - Matches the control part when the checkbox is indeterminate.
 * @csspart checked-icon - The checked icon, an `<nile-icon>` element.
 * @csspart indeterminate-icon - The indeterminate icon, an `<nile-icon>` element.
 * @csspart label - The container that wraps the checkbox's label.
 */
/**
 * Nile icon component.
 *
 * @tag nile-checkbox
 *
 */
let NileCheckbox = class NileCheckbox extends NileElement {
    constructor() {
        super();
        this.hasFocus = false;
        this.title = ''; // make reactive to pass through
        /** The name of the checkbox, submitted as a name/value pair with form data. */
        this.name = '';
        /** The checkbox's size. */
        this.size = 'medium';
        /** Disables the checkbox. */
        this.disabled = false;
        /** Draws the checkbox in a checked state. */
        this.checked = false;
        /** Label, declared this property for backward compatibility of old component  */
        this.label = '';
        /**
         * Draws the checkbox in an indeterminate state. This is usually applied to checkboxes that represents a "select
         * all/none" behavior when associated checkboxes have a mix of checked and unchecked states.
         */
        this.indeterminate = false;
        /** The default value of the form control. Primarily used for resetting the form control. */
        this.defaultChecked = false;
        this.helpText = '';
        this.errorMessage = '';
        this.showHelpText = false;
        /**
         * By default, form controls are associated with the nearest containing `<form>` element. This attribute allows you
         * to place the form control outside of a form and associate it with the form that has this `id`. The form must be in
         * the same document or shadow root for this to work.
         */
        this.form = '';
        /** Associates this checkbox with a nile-checkbox-group via a shared group name. */
        this.group = '';
        /** Makes the checkbox a required field. */
        this.required = false;
    }
    toggleHelpText() {
        this.showHelpText = !this.showHelpText;
    }
    handleClick() {
        this.checked = !this.checked;
        this.indeterminate = false;
        this.emit('nile-change', { checked: this.checked });
        this.emit('valueChange', { checked: this.checked });
    }
    handleBlur() {
        this.hasFocus = false;
        this.emit('blur');
    }
    handleInput() {
        this.emit('input');
    }
    handleFocus() {
        this.hasFocus = true;
        this.emit('focus');
    }
    handleStateChange() {
        this.input.checked = this.checked; // force a sync update
        this.input.indeterminate = this.indeterminate; // force a sync update
    }
    /** 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();
    }
    connectedCallback() {
        super.connectedCallback();
        this.updateHostClass();
        this.emit('nile-init');
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        this.emit('nile-destroy');
    }
    updated(changedProperties) {
        super.updated(changedProperties);
        if (changedProperties.has('helpText')) {
            this.updateHostClass();
        }
    }
    updateHostClass() {
        if (this.helpText) {
            this.classList.add('full-width');
        }
        else {
            this.classList.remove('full-width');
        }
    }
    render() {
        const hasHelpText = this.helpText ? true : false;
        const hasErrorMessage = this.errorMessage ? true : false;
        return html `
      <label
        part="base"
        class=${classMap({
            checkbox: true,
            'checkbox--checked': this.checked,
            'checkbox--disabled': this.disabled,
            'checkbox--focused': this.hasFocus,
            'checkbox--indeterminate': this.indeterminate,
            'checkbox--medium': this.size === 'medium',
        })}
      >
        <input
          class="checkbox__input"
          type="checkbox"
          title=${this
            .title /* An empty title prevents browser validation tooltips from appearing on hover */}
          name=${this.name}
          value=${ifDefined(this.value)}
          .indeterminate=${live(this.indeterminate)}
          .checked=${live(this.checked)}
          .disabled=${this.disabled}
          .required=${this.required}
          aria-checked=${this.checked ? 'true' : 'false'}
          @click=${this.handleClick}
          @input=${this.handleInput}
          @blur=${this.handleBlur}
          @focus=${this.handleFocus}
        />

        <span
          part="control${this.checked ? ' control--checked' : ''}${this
            .indeterminate
            ? ' control--indeterminate'
            : ''}"
          class="checkbox__control"
        >
        ${this.checked && this.disabled
            ? html `
      <nile-icon
        part="checked-icon"
        class="checkbox__checked-icon"
        color="var(--nile-colors-white-base, var(--ng-colors-fg-disabled-subtle))"
        opacity="0.6"
        library="system"
        name="var(--nile-icon-tick, var(--ng-icon-check))"
        size="12"
        method="var(--nile-svg-method-fill, var(--ng-svg-method-stroke))"
      ></nile-icon>
    `
            : this.checked
                ? html `
      <nile-icon
        part="checked-icon"
        class="checkbox__checked-icon"
        color="var(--nile-colors-white-base, var(--ng-colors-fg-white))"
        library="system"
        name="var(--nile-icon-tick, var(--ng-icon-check))"
        size="12"
        method="var(--nile-svg-method-fill, var(--ng-svg-method-stroke))"
      ></nile-icon>
    `
                : ''}
        ${!this.checked && this.indeterminate && this.disabled
            ? html `
      <nile-icon
        part="indeterminate-icon"
        class="checkbox__indeterminate-icon"
        library="system"
        color="var(--nile-colors-white-base, var(--ng-colors-fg-disabled-subtle))"
        name="var(--nile-icon-minus, var(--ng-icon-minus))"
        size="12"
        method="var(--nile-svg-method-fill, var(--ng-svg-method-stroke))"
      ></nile-icon>
    `
            : !this.checked && this.indeterminate
                ? html `
      <nile-icon
        part="indeterminate-icon"
        class="checkbox__indeterminate-icon"
        library="system"
        color="var(--nile-colors-white-base, var(--ng-colors-fg-white))"
        name="var(--nile-icon-minus, var(--ng-icon-minus))"
        size="12"
        method="var(--nile-svg-method-fill, var(--ng-svg-method-stroke))"
      ></nile-icon>
    `
                : ''}

        </span>

        <div part="label" class="checkbox__label">
          ${typeof this.label === 'boolean' ? '' : this.label}
          <slot></slot>
        </div>
      </label>

      ${hasHelpText
            ? html ` <nile-form-help-text>${this.helpText}</nile-form-help-text> `
            : ``}
        
      ${hasErrorMessage
            ? html `
            <nile-form-error-message
              >${this.errorMessage}</nile-form-error-message
            >
          `
            : ``}
    `;
    }
};
NileCheckbox.styles = styles;
__decorate([
    query('input[type="checkbox"]')
], NileCheckbox.prototype, "input", void 0);
__decorate([
    state()
], NileCheckbox.prototype, "hasFocus", void 0);
__decorate([
    property()
], NileCheckbox.prototype, "title", void 0);
__decorate([
    property()
], NileCheckbox.prototype, "name", void 0);
__decorate([
    property()
], NileCheckbox.prototype, "value", void 0);
__decorate([
    property({ reflect: true })
], NileCheckbox.prototype, "size", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], NileCheckbox.prototype, "disabled", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], NileCheckbox.prototype, "checked", void 0);
__decorate([
    property({ type: String, reflect: true })
], NileCheckbox.prototype, "label", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], NileCheckbox.prototype, "indeterminate", void 0);
__decorate([
    defaultValue('checked')
], NileCheckbox.prototype, "defaultChecked", void 0);
__decorate([
    property({ attribute: 'help-text', reflect: true })
], NileCheckbox.prototype, "helpText", void 0);
__decorate([
    property({ attribute: 'error-message', reflect: true })
], NileCheckbox.prototype, "errorMessage", void 0);
__decorate([
    property({ type: Boolean })
], NileCheckbox.prototype, "showHelpText", void 0);
__decorate([
    property({ reflect: true })
], NileCheckbox.prototype, "form", void 0);
__decorate([
    property({ reflect: true })
], NileCheckbox.prototype, "group", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], NileCheckbox.prototype, "required", void 0);
__decorate([
    watch(['checked', 'indeterminate'], { waitUntilFirstUpdate: true })
], NileCheckbox.prototype, "handleStateChange", null);
NileCheckbox = __decorate([
    customElement('nile-checkbox')
], NileCheckbox);
export { NileCheckbox };
export default NileCheckbox;
//# sourceMappingURL=nile-checkbox.js.map