import { h, } from "@stencil/core";
import { createRandomString } from "../../util/random-string";
import { CheckboxTemplate } from "./checkbox.template";
/**
 * The Checkbox component is a classic and essential element in UI design that allows
 * users to make multiple selections from a predefined list of options. The Checkbox component is commonly used in forms and settings interfaces to enable users to
 * select one or more items from a list of choices.
 *
 * ## States of a Checkbox
 * When a user clicks or taps on the box, it toggles between two states:
 * Checked and Unchecked.
 *
 * However, a Checkbox can visualize a third state called the "Indeterminate" state.
 * In this state, the checkbox appears as a filled box with a horizontal line or dash inside it.
 *
 * The Indeterminate state is typically used when dealing with checkbox groups
 * that have hierarchical relationships or when the group contains sub-items.
 * This state is used to indicate that that some, but not all, of the items in a group are selected.
 *
 * :::important
 * Checkboxes are sometimes used interchangeably with switches in user interfaces.
 * But there is an important difference between the two! Please read our guidelines about
 * [Switch vs. Checkbox](#/DesignGuidelines/switch-vs-checkbox.md/).
 *
 * @exampleComponent limel-example-checkbox
 * @exampleComponent limel-example-checkbox-helper-text
 * @exampleComponent limel-example-checkbox-readonly
 */
export class Checkbox {
    constructor() {
        /**
         * Disables the checkbox when `true`. Works exactly the same as `readonly`.
         * If either property is `true`, the checkbox will be disabled.
         */
        this.disabled = false;
        /**
         * Disables the checkbox when `true`. This visualizes the checkbox slightly differently.
         * But shows no visual sign indicating that the checkbox is disabled
         * or can ever become interactable.
         */
        this.readonly = false;
        /**
         * The value of the checkbox. Set to `true` to make the checkbox checked.
         */
        this.checked = false;
        /**
         * Enables indeterminate state. Set to `true` to signal indeterminate check.
         */
        this.indeterminate = false;
        /**
         * Set to `true` to indicate that the checkbox must be checked.
         */
        this.required = false;
        /**
         * The labels to use to clarify what kind of data is being visualized,
         * when the component is `readonly`.
         */
        this.readonlyLabels = [];
        this.modified = false;
        this.shouldReinitialize = false;
        this.id = createRandomString();
        this.helperTextId = createRandomString();
        this.destroyMDCInstances = () => {
            const input = this.getCheckboxElement();
            if (input) {
                delete input.dataset['indeterminate'];
                input.indeterminate = false;
            }
        };
        this.isInvalid = () => {
            if (this.invalid) {
                return true;
            }
            if (this.required && this.modified && !this.checked) {
                return true;
            }
        };
        this.initialize = () => {
            const input = this.getCheckboxElement();
            if (!input) {
                return;
            }
            input.indeterminate = this.indeterminate;
            input.checked = this.checked || this.indeterminate;
        };
        this.getCheckboxElement = () => {
            var _a, _b;
            return (((_b = (_a = this.limelCheckbox) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('input[type="checkbox"]')) || null);
        };
        this.onChange = (event) => {
            var _a;
            event.stopPropagation();
            const input = event.currentTarget;
            const isChecked = (_a = input === null || input === void 0 ? void 0 : input.checked) !== null && _a !== void 0 ? _a : this.checked;
            this.change.emit(isChecked);
            this.modified = true;
        };
    }
    handleCheckedChange(newValue) {
        const input = this.getCheckboxElement();
        if (!input) {
            return;
        }
        input.checked = newValue || this.indeterminate;
    }
    handleIndeterminateChange(newValue) {
        const input = this.getCheckboxElement();
        if (!input) {
            return;
        }
        input.checked = this.checked || newValue;
        input.indeterminate = newValue;
    }
    handleReadonlyChange() {
        this.destroyMDCInstances();
        this.shouldReinitialize = true;
    }
    componentDidRender() {
        if (this.shouldReinitialize) {
            this.initialize();
            this.shouldReinitialize = false;
        }
    }
    connectedCallback() {
        this.initialize();
    }
    componentDidLoad() {
        this.initialize();
    }
    disconnectedCallback() {
        this.destroyMDCInstances();
    }
    render() {
        return (h(CheckboxTemplate, { key: '42d3d0c8905e8d0426482ac079fa1da76d713698', disabled: this.disabled || this.readonly, label: this.label, readonlyLabels: this.readonlyLabels, helperText: this.helperText, helperTextId: this.helperTextId, checked: this.checked || this.indeterminate, indeterminate: this.indeterminate, required: this.required, readonly: this.readonly, invalid: this.isInvalid(), onChange: this.onChange, id: this.id }));
    }
    static get is() { return "limel-checkbox"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["checkbox.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["checkbox.css"]
        };
    }
    static get properties() {
        return {
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Disables the checkbox when `true`. Works exactly the same as `readonly`.\nIf either property is `true`, the checkbox will be disabled."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "disabled",
                "defaultValue": "false"
            },
            "readonly": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Disables the checkbox when `true`. This visualizes the checkbox slightly differently.\nBut shows no visual sign indicating that the checkbox is disabled\nor can ever become interactable."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "readonly",
                "defaultValue": "false"
            },
            "invalid": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set to `true` to indicate that the current value is invalid."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "invalid"
            },
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The checkbox label."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "label"
            },
            "helperText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Optional helper text to display below the checkbox"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "helper-text"
            },
            "checked": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The value of the checkbox. Set to `true` to make the checkbox checked."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "checked",
                "defaultValue": "false"
            },
            "indeterminate": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Enables indeterminate state. Set to `true` to signal indeterminate check."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "indeterminate",
                "defaultValue": "false"
            },
            "required": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set to `true` to indicate that the checkbox must be checked."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "required",
                "defaultValue": "false"
            },
            "readonlyLabels": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Array<Label<boolean>>",
                    "resolved": "Label<boolean>[]",
                    "references": {
                        "Array": {
                            "location": "global",
                            "id": "global::Array"
                        },
                        "Label": {
                            "location": "import",
                            "path": "../dynamic-label/label.types",
                            "id": "src/components/dynamic-label/label.types.ts::Label",
                            "referenceLocation": "Label"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The labels to use to clarify what kind of data is being visualized,\nwhen the component is `readonly`."
                },
                "getter": false,
                "setter": false,
                "defaultValue": "[]"
            }
        };
    }
    static get states() {
        return {
            "modified": {}
        };
    }
    static get events() {
        return [{
                "method": "change",
                "name": "change",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the input value is changed."
                },
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                }
            }];
    }
    static get elementRef() { return "limelCheckbox"; }
    static get watchers() {
        return [{
                "propName": "checked",
                "methodName": "handleCheckedChange"
            }, {
                "propName": "indeterminate",
                "methodName": "handleIndeterminateChange"
            }, {
                "propName": "readonly",
                "methodName": "handleReadonlyChange"
            }];
    }
}
