/**
 * @license
 * Copyright Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
import { __decorate } from "tslib";
import { attachShadowTemplate, coerceBoolean, CustomElement, FoundationProperty, isDefined, isString } from '@tylertech/forge-core';
import { getFormState, getFormValue, getValidationMessage, inputType, internals, setDefaultAria, setValidity } from '../constants';
import { BaseComponent } from '../core';
import { WithFocusable } from '../core/mixins/focus/with-focusable';
import { WithFormAssociation } from '../core/mixins/form/with-form-associated';
import { WithDefaultAria } from '../core/mixins/internals/with-default-aria';
import { WithElementInternals } from '../core/mixins/internals/with-element-internals';
import { WithLabelAwareness } from '../core/mixins/label/with-label-aware';
import { FocusIndicatorComponent } from '../focus-indicator/focus-indicator';
import { StateLayerComponent } from '../state-layer/state-layer';
import { CheckboxAdapter } from './checkbox-adapter';
import { CHECKBOX_CONSTANTS } from './checkbox-constants';
import { CheckboxFoundation } from './checkbox-foundation';
const template = '<template><div class=\"forge-checkbox\" part=\"root\"><div id=\"container\" class=\"container\"><div class=\"background\" part=\"background\"><svg class=\"icon icon--checked\" aria-hidden=\"true\" viewBox=\"0 0 24 24\" part=\"checkmark\"><path d=\"M1.73,12.91 8.1,19.28 22.79,4.59\"></path></svg> <svg class=\"icon icon--indeterminate\" aria-hidden=\"true\" viewBox=\"0 0 24 24\" part=\"mixedmark\"><line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"></line></svg><forge-focus-indicator target=\":host\" part=\"focus-indicator\"></forge-focus-indicator></div><forge-state-layer target=\":host\" exportparts=\"surface:state-layer\"></forge-state-layer></div><div id=\"label\" class=\"label\" part=\"label\"><slot></slot></div></div></template>';
const styles = ':host{display:inline-block;outline:0;-webkit-tap-highlight-color:transparent}:host([hidden]){display:none}.forge-checkbox{--_checkbox-primary-color:var(--forge-checkbox-primary-color, var(--forge-theme-tertiary, #3d5afe));--_checkbox-size:var(--forge-checkbox-size, 16px);--_checkbox-border-width:var(--forge-checkbox-border-width, var(--forge-border-medium, 2px));--_checkbox-icon-color:var(--forge-checkbox-icon-color, var(--forge-theme-on-tertiary, #ffffff));--_checkbox-state-layer-size:var(--forge-checkbox-state-layer-size, 40px);--_checkbox-state-layer-dense-size:var(--forge-checkbox-state-layer-dense-size, 24px);--_checkbox-background:var(--forge-checkbox-background, var(--forge-theme-surface, #ffffff));--_checkbox-width:var(--forge-checkbox-width, var(--_checkbox-size));--_checkbox-height:var(--forge-checkbox-height, var(--_checkbox-size));--_checkbox-unchecked-border-width:var(--forge-checkbox-unchecked-border-width, var(--_checkbox-border-width));--_checkbox-unchecked-border-color:var(--forge-checkbox-unchecked-border-color, var(--forge-theme-surface-container-high, #9e9e9e));--_checkbox-shape:var(--forge-checkbox-shape, var(--forge-shape-small, 2px));--_checkbox-elevation:var(--forge-checkbox-elevation, 0px 0px 0px 0px rgba(0, 0, 0, 0.2), 0px 0px 0px 0px rgba(0, 0, 0, 0.14), 0px 0px 0px 0px rgba(0, 0, 0, 0.12));--_checkbox-checked-background:var(--forge-checkbox-checked-background, var(--_checkbox-primary-color));--_checkbox-checked-border-width:var(--forge-checkbox-checked-border-width, var(--_checkbox-border-width));--_checkbox-checked-border-color:var(--forge-checkbox-checked-border-color, var(--_checkbox-checked-background));--_checkbox-icon-checked-color:var(--forge-checkbox-icon-checked-color, var(--_checkbox-icon-color));--_checkbox-icon-indeterminate-color:var(--forge-checkbox-icon-indeterminate-color, var(--_checkbox-icon-color));--_checkbox-icon-stroke-width:var(--forge-checkbox-icon-stroke-width, 4px);--_checkbox-gap:var(--forge-checkbox-gap, 0);--_checkbox-justify:var(--forge-checkbox-justify, start);--_checkbox-direction:var(--forge-checkbox-direction, initial);--_checkbox-state-layer-width:var(--forge-checkbox-state-layer-width, var(--_checkbox-state-layer-size));--_checkbox-state-layer-height:var(--forge-checkbox-state-layer-height, var(--_checkbox-state-layer-size));--_checkbox-state-layer-checked-color:var(--forge-checkbox-state-layer-checked-color, var(--_checkbox-primary-color));--_checkbox-state-layer-unchecked-color:var(--forge-checkbox-state-layer-unchecked-color, var(--_checkbox-color));--_checkbox-state-layer-shape:var(--forge-checkbox-state-layer-shape, var(--forge-shape-full, 9999px));--_checkbox-dense-gap:var(--forge-checkbox-dense-gap, 8px);--_checkbox-state-layer-dense-width:var(--forge-checkbox-state-layer-dense-width, var(--_checkbox-state-layer-dense-size));--_checkbox-state-layer-dense-height:var(--forge-checkbox-state-layer-dense-height, var(--_checkbox-state-layer-dense-size));--_checkbox-disabled-opacity:var(--forge-checkbox-disabled-opacity, 0.38);--_checkbox-animation-duration:var(--forge-checkbox-animation-duration, var(--forge-animation-duration-short2, 100ms));--_checkbox-background-animation-timing:var(--forge-checkbox-background-animation-timing, var(--forge-animation-easing-standard, cubic-bezier(0.2, 0, 0, 1)));--_checkbox-icon-animation-timing:var(--forge-checkbox-icon-animation-timing, var(--forge-animation-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15)))}.forge-checkbox{position:relative;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:var(--_checkbox-direction);flex-shrink:0;-webkit-box-align:center;align-items:center;-webkit-box-pack:var(--_checkbox-justify);justify-content:var(--_checkbox-justify);gap:var(--_checkbox-gap);display:-webkit-box;display:flex}.forge-checkbox .container{position:relative;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center;display:-webkit-box;display:flex;border-radius:var(--_checkbox-state-layer-shape);inline-size:var(--_checkbox-state-layer-width);block-size:var(--_checkbox-state-layer-height);cursor:pointer}.forge-checkbox .background{position:relative;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center;display:-webkit-box;display:flex;-webkit-transition-property:background,border-width,border-color;transition-property:background,border-width,border-color;-webkit-transition-duration:var(--_checkbox-animation-duration);transition-duration:var(--_checkbox-animation-duration);-webkit-transition-timing-function:var(--_checkbox-background-animation-timing);transition-timing-function:var(--_checkbox-background-animation-timing);-webkit-box-shadow:var(--_checkbox-elevation);box-shadow:var(--_checkbox-elevation);border-style:solid;border-width:var(--_checkbox-unchecked-border-width);border-color:var(--_checkbox-unchecked-border-color);border-radius:var(--_checkbox-shape);-webkit-box-sizing:border-box;box-sizing:border-box;block-size:var(--_checkbox-height);inline-size:var(--_checkbox-width);background:var(--_checkbox-background)}.forge-checkbox .icon{position:absolute;-webkit-transition-property:stroke-dashoffset;transition-property:stroke-dashoffset;-webkit-transition-duration:var(--_checkbox-animation-duration);transition-duration:var(--_checkbox-animation-duration);-webkit-transition-timing-function:var(--_checkbox-icon-animation-timing);transition-timing-function:var(--_checkbox-icon-animation-timing);fill:none;stroke-width:var(--_checkbox-icon-stroke-width)}.forge-checkbox .icon--checked{stroke:var(--_checkbox-icon-checked-color);stroke-dasharray:30;-webkit-transition-delay:0s;transition-delay:0s;stroke-dashoffset:30}.forge-checkbox .icon--indeterminate{stroke:var(--_checkbox-icon-indeterminate-color);stroke-dasharray:20;-webkit-transition-delay:0s;transition-delay:0s;stroke-dashoffset:20}.forge-checkbox .label{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--forge-typography-label1-font-family, var(--forge-typography-font-family, \"Roboto\", sans-serif));font-size:var(--forge-typography-label1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-font-size-scale, .75)));font-weight:var(--forge-typography-label1-font-weight,400);line-height:var(--forge-typography-label1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-line-height-scale, 1.25)));letter-spacing:var(--forge-typography-label1-letter-spacing, .0357142857em);text-transform:var(--forge-typography-label1-text-transform,inherit);-webkit-text-decoration:var(--forge-typography-label1-text-decoration,inherit);text-decoration:var(--forge-typography-label1-text-decoration,inherit);cursor:default}:host([checked]) .background{border-style:solid;border-width:var(--_checkbox-checked-border-width);border-color:var(--_checkbox-checked-border-color);background:var(--_checkbox-checked-background)}:host([checked]) .icon--checked{-webkit-transition-delay:var(--_checkbox-animation-duration);transition-delay:var(--_checkbox-animation-duration);stroke-dashoffset:0}:host([checked]) .icon--checked:dir(rtl){stroke-dashoffset:60}:host([checked]) .icon--indeterminate{-webkit-transition-delay:0s;transition-delay:0s;stroke-dashoffset:20}:host([checked]) forge-state-layer{--forge-state-layer-color:var(--_checkbox-state-layer-checked-color)}:host([indeterminate]) .background{border-style:solid;border-width:var(--_checkbox-checked-border-width);border-color:var(--_checkbox-checked-border-color);background:var(--_checkbox-checked-background)}:host([indeterminate]) .icon--checked{-webkit-transition-delay:0s;transition-delay:0s;stroke-dashoffset:30}:host([indeterminate]) .icon--indeterminate{-webkit-transition-delay:var(--_checkbox-animation-duration);transition-delay:var(--_checkbox-animation-duration);stroke-dashoffset:0}:host([indeterminate]) .icon--indeterminate:dir(rtl){stroke-dashoffset:40}:host([indeterminate]) forge-state-layer{--forge-state-layer-color:var(--_checkbox-state-layer-checked-color)}:host([dense]) .forge-checkbox{--_checkbox-gap:var(--_checkbox-dense-gap)}:host([dense]) .forge-checkbox .container{inline-size:var(--_checkbox-state-layer-dense-width);block-size:var(--_checkbox-state-layer-dense-height)}:host([disabled]) .forge-checkbox{opacity:var(--_checkbox-disabled-opacity)}:host([disabled]) .forge-checkbox .container{cursor:not-allowed}:host([readonly]) .forge-checkbox .container{cursor:not-allowed}@media (prefers-reduced-motion){.forge-checkbox{--_checkbox-animation-duration:var(--forge-checkbox-animation-duration, 0s)}}forge-state-layer{--forge-state-layer-color:var(--_checkbox-state-layer-unchecked-color)}forge-focus-indicator{--forge-focus-indicator-shape:0px;--forge-focus-indicator-outward-offset:8px}';
/**
 * @tag forge-checkbox
 *
 * @summary Checkboxes select single values for submission in a form.
 *
 * @description
 * Use checkboxes to:
 * - Select one or multiple items from a list.
 * - Present a list containing sub-selections.
 * - Turn an option on or off in desktop environment.
 *
 * @property {boolean} checked - Whether the checkbox is checked.
 * @property {boolean} defaultChecked - Whether the checkbox is checked by default.
 * @property {boolean} indeterminate - Toggles the indeterminate state. This does not affect whether the checkbox is checked or its form submission.
 * @property {string} value - The value of the checkbox when checked.
 * @property {boolean} disabled - Controls if the checkbix is disabled.
 * @property {boolean} required = Controls if the checkbox is required.
 * @property {boolean} readonly = Controls if the checkbox is readonly.
 * @property {boolean} dense - The density state.
 * @property {SwitchLabelPosition} labelPosition - Whether the label appears before or after the checkbox.
 *
 * @attribute {string} checked - Controls whether the checkbox is checked.
 * @attribute {string} defaultChecked - Controls whether the checkbox is checked by default.
 * @attribute {string} indeterminate - Controls the indeterminate state.
 * @attribute {string} value - The value of the checkbox when checked.
 * @attribute {string} disabled - Controls if the switch is disabled.
 * @attribute {string} required - Controls if the switch is required.
 * @attribute {string} readonly - Controls if the switch is readonly.
 * @attribute {string} dense - Sets the density state.
 * @attribute {string} label-position - Sets whether the label appears before or after the switch.
 *
 * @method {(force?: boolean) => void} toggle - Toggles whether the checkbox is is checked or forces a checked state.
 *
 * @event {Event} change - Dispatches when the checkbox is checked or unchecked.
 *
 * @cssproperty --forge-theme-tertiary - The primary color of the checkbox.
 * @cssproperty --forge-theme-on-tertiary - The color of the checkmark and indeterminate mark.
 * @cssproperty --forge-checkbox-primary-color - The primary color of the checkbox.
 * @cssproperty --forge-checkbox-size - The inline and block size of the checkbox.
 * @cssproperty --forge-checkbox-border-width - The width of the checkbox border.
 * @cssproperty --forge-checkbox-state-layer-size - The inline and block size of the state layer.
 * @cssproperty --forge-checkbox-state-layer-dense-size - The inline and block size of the state layer when dense.
 * @cssproperty --forge-checkbox-background - The color of the checkbox background when unchecked and not indeterminate.
 * @cssproperty --forge-checkbox-width - The inline size of the checkbox.
 * @cssproperty --forge-checkbox-height - The block size of the checkbox.
 * @cssproperty --forge-checkbox-unchecked-border-width - The width of the checkbox border when unchecked and not indeterminate.
 * @cssproperty --forge-checkbox-unchecked-border-color - The color of the checkbox border when unchecked and not indeterminate.
 * @cssproperty --forge-checkbox-shape - The shape of the checkbox.
 * @cssproperty --forge-checkbox-elevation - The shadow of the checkbox.
 * @cssproperty --forge-checkbox-gap - The space between the checkbox and label.
 * @cssproperty --forge-checkbox-justify - How the checkbox and label are distributed along their main axis.
 * @cssproperty --forge-checkbox-direction - Whether the checkbox and label are arranged along the inline or block axis.
 * @cssproperty --forge-checkbox-checked-background - The color of the checkbox background when checked or indeterminate.
 * @cssproperty --forge-checkbox-checked-border-width - The width of the checkbox border when checked or indeterminate.
 * @cssproperty --forge-checkbox-checked-border-color - The color of the checkbox border when checked or indeterminate.
 * @cssproperty --forge-checkbox-icon-color - The color of the checkmark and indeterminate mark.
 * @cssproperty --forge-checkbox-icon-checked-color - The color of the checkmark mark.
 * @cssproperty --forge-checkbox-icon-indeterminate-color - The color of the indeterminate mark.
 * @cssproperty --forge-checkbox-icon-stroke-width - The stroke width of the checkmark and indeterminate marks.
 * @cssproperty --forge-checkbox-state-layer-width - The inline size of the state layer.
 * @cssproperty --forge-checkbox-state-layer-width - The inline size of the state layer.
 * @cssproperty --forge-checkbox-state-layer-height - The block size of the state layer.
 * @cssproperty --forge-checkbox-state-layer-checked-color - The color of the state layer when checked.
 * @cssproperty --forge-checkbox-state-layer-unchecked-color - The color of the state layer when unchecked.
 * @cssproperty --forge-checkbox-state-layer-shape - The shape of the state layer.
 * @cssproperty --forge-checkbox-state-layer-dense-width - The inline size of the state layer when dense.
 * @cssproperty --forge-checkbox-state-layer-dense-height - The block size of the state layer when dense.
 * @cssproperty --forge-checkbox-disabled-opacity - The opacity when disabled.
 * @cssproperty --forge-checkbox-animation-duration - The duration of animations.
 * @cssproperty --forge-checkbox-background-animation-timing - The timing function of the background animations.
 * @cssproperty --forge-checkbox-icon-animation-timing - The timing function of the checked and indeterminate icons animations.
 *
 * @csspart root - Styles the root element.
 * @csspart background - Styles the checkbox background element.
 * @csspart checkmark - Styles the checkmark element.
 * @csspart mixedmark - Styles the indeterminate mark element.
 * @csspart label - Styles the label element.
 * @csspart state-layer - Styles the state layer element.
 * @csspart focus-indicator - Styles the focus indicator element.
 */
let CheckboxComponent = class CheckboxComponent extends WithFormAssociation(WithLabelAwareness(WithFocusable(WithDefaultAria(WithElementInternals(BaseComponent))))) {
    static get observedAttributes() {
        return Object.values(CHECKBOX_CONSTANTS.observedAttributes);
    }
    constructor() {
        super();
        attachShadowTemplate(this, template, styles);
        this[inputType] = 'checkbox';
        this._foundation = new CheckboxFoundation(new CheckboxAdapter(this));
    }
    connectedCallback() {
        super.connectedCallback();
        this[setDefaultAria]({
            role: 'checkbox',
            ariaChecked: this.checked ? 'true' : 'false',
            ariaDisabled: this.disabled ? 'true' : 'false',
            ariaRequired: this.required ? 'true' : 'false'
        });
        this._foundation.initialize();
    }
    attributeChangedCallback(name, oldValue, newValue) {
        switch (name) {
            case CHECKBOX_CONSTANTS.observedAttributes.CHECKED:
                this.checked = coerceBoolean(newValue);
                break;
            case CHECKBOX_CONSTANTS.observedAttributes.DEFAULT_CHECKED:
                this.defaultChecked = coerceBoolean(newValue);
                break;
            case CHECKBOX_CONSTANTS.observedAttributes.INDETERMINATE:
                this.indeterminate = coerceBoolean(newValue);
                break;
            case CHECKBOX_CONSTANTS.observedAttributes.VALUE:
                this.value = newValue;
                break;
            case CHECKBOX_CONSTANTS.observedAttributes.DENSE:
                this.dense = coerceBoolean(newValue);
                break;
            case CHECKBOX_CONSTANTS.observedAttributes.DISABLED:
                this.disabled = coerceBoolean(newValue);
                break;
            case CHECKBOX_CONSTANTS.observedAttributes.REQUIRED:
                this.required = coerceBoolean(newValue);
                break;
            case CHECKBOX_CONSTANTS.observedAttributes.READONLY:
                this.readonly = coerceBoolean(newValue);
                break;
            case CHECKBOX_CONSTANTS.observedAttributes.LABEL_POSITION:
                this.labelPosition = newValue;
                break;
        }
        super.attributeChangedCallback(name, oldValue, newValue);
    }
    [getFormValue]() {
        return this.checked ? this.value : null;
    }
    [getFormState]() {
        if (this.checked) {
            return this.indeterminate ? 'checked-indeterminate' : 'checked';
        }
        return this.indeterminate ? 'unchecked-indeterminate' : 'unchecked';
    }
    [setValidity]() {
        this[internals].setValidity({ valueMissing: this.required && !this.checked }, this[getValidationMessage]({
            checked: this.checked,
            required: this.required
        }));
    }
    formResetCallback() {
        this.checked = this.defaultChecked;
    }
    formStateRestoreCallback(state) {
        this.checked = state === 'checked' || state === 'checked-indeterminate';
        this.indeterminate = state === 'unchecked-indeterminate' || state === 'checked-indeterminate';
    }
    labelClickedCallback() {
        this.click();
        // TODO: use `{ focusVisble: false }` when supported.
        this.focus();
    }
    labelChangedCallback(value) {
        this[setDefaultAria]({ ariaLabel: value });
    }
    setFormValue(value, state) {
        this[internals].setFormValue(value, state);
        if (state) {
            const stateValue = isString(state) ? state : state[this.name];
            this.checked = stateValue === 'checked' || stateValue === 'checked-indeterminate';
            this.indeterminate = stateValue === 'unchecked-indeterminate' || stateValue === 'checked-indeterminate';
            return;
        }
        if (isString(value)) {
            this.checked = !!value;
        }
        else if (value === null || value === void 0 ? void 0 : value[this.name]) {
            this.checked = !!value[this.name];
        }
        else {
            this.checked = false;
        }
    }
    /**
     * Toggles the checkbox checked or unchecked.
     * @param force Whether to set the checkbox checked or unchecked.
     */
    toggle(force) {
        if (isDefined(force)) {
            this._foundation.checked = force;
        }
        else {
            this._foundation.checked = !this._foundation.checked;
        }
    }
};
__decorate([
    FoundationProperty()
], CheckboxComponent.prototype, "checked", void 0);
__decorate([
    FoundationProperty()
], CheckboxComponent.prototype, "defaultChecked", void 0);
__decorate([
    FoundationProperty()
], CheckboxComponent.prototype, "indeterminate", void 0);
__decorate([
    FoundationProperty()
], CheckboxComponent.prototype, "value", void 0);
__decorate([
    FoundationProperty()
], CheckboxComponent.prototype, "dense", void 0);
__decorate([
    FoundationProperty()
], CheckboxComponent.prototype, "disabled", void 0);
__decorate([
    FoundationProperty()
], CheckboxComponent.prototype, "required", void 0);
__decorate([
    FoundationProperty()
], CheckboxComponent.prototype, "readonly", void 0);
__decorate([
    FoundationProperty()
], CheckboxComponent.prototype, "labelPosition", void 0);
CheckboxComponent = __decorate([
    CustomElement({
        name: CHECKBOX_CONSTANTS.elementName,
        dependencies: [
            FocusIndicatorComponent,
            StateLayerComponent
        ]
    })
], CheckboxComponent);
export { CheckboxComponent };
