import { __decorate, __metadata } from "tslib";
import { h, Host, } from "@stencil/core";
import { ariaBooleanToString } from "../../utils/aria";
import { BEM } from "../../utils/bem";
import { ListenToElementStates } from "../../utils/element-states";
import { BalElementStateListener } from "../../utils/element-states/element-states.listener";
import { stopEventBubbling } from "../../utils/form-input";
import { Logger } from "../../utils/log";
export class Option {
    constructor() {
        this.inputId = `bal-option-${balOptionIds++}`;
        this.checkbox = false;
        this.interactionState = BalElementStateListener.DefaultState;
        /**
         * PUBLIC PROPERTY API
         * ------------------------------------------------------
         */
        /**
         * Label will be shown in the input element when it got selected
         */
        this.label = '';
        /**
         * The value of the select option. This value will be returned by the parent `<bal-select>` element.
         */
        this.value = '';
        /**
         * If `true`, the user cannot interact with the option.
         */
        this.disabled = false;
        /**
         * If `true`, the option can present in more than one line.
         */
        this.multiline = false;
        /**
         * If `true`, the option is shown in red.
         */
        this.invalid = false;
        /**
         * If `true`, the option is selected.
         */
        this.selected = false;
        /**
         * If `true`, the option is focused.
         */
        this.focused = false;
        /**
         * If `true`, the option is hidden.
         */
        this.hidden = false;
        /**
         * EVENT BINDING
         * ------------------------------------------------------
         */
        this.onClick = (ev) => {
            const listEl = this.el.closest('bal-option-list');
            if (this.disabled || (listEl && listEl.disabled)) {
                stopEventBubbling(ev);
            }
            else {
                if (listEl && listEl.required && !listEl.multiple) {
                    if (!this.selected) {
                        this.select(true);
                    }
                }
                else {
                    this.select(!this.selected);
                }
            }
        };
    }
    createLogger(log) {
        this.log = log;
    }
    /**
     * LIFECYCLE
     * ------------------------------------------------------
     */
    componentWillRender() {
        if (this.el) {
            const optionListEl = this.el.closest('bal-option-list');
            if (optionListEl) {
                this.checkbox = !!optionListEl.multiple;
            }
        }
    }
    /**
     * LISTENERS
     * ------------------------------------------------------
     */
    listenToMouseEnter() {
        const { label, value, selected, disabled, hidden } = this;
        if (!hidden && !disabled) {
            this.balOptionFocus.emit({ label, value, selected });
        }
    }
    elementStateListener(info) {
        this.interactionChildElements.forEach(element => {
            element.hovered = info.hovered;
            element.pressed = info.pressed;
        });
    }
    /**
     * PUBLIC METHODS
     * ------------------------------------------------------
     */
    /**
     * Selects or deselects the option and informs other components
     */
    async select(selected = true) {
        this.selected = selected;
        const { label, value } = this;
        this.balOptionChange.emit({ label, value, selected });
    }
    /**
     * PRIVATE METHODS
     * ------------------------------------------------------
     */
    get interactionChildElements() {
        return Array.from(this.el.querySelectorAll('bal-check'));
    }
    /**
     * RENDER
     * ------------------------------------------------------
     */
    render() {
        const block = BEM.block('option');
        return (h(Host, { key: 'dca805aa021ad35c2ea4153008a8a5ba4f37931c', class: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, block.class()), block.modifier('checkbox').class(this.checkbox)), block.modifier('focused').class(this.focused)), block.modifier('invalid').class(this.invalid)), block.modifier('selected').class(this.selected)), block.modifier('disabled').class(this.disabled)), block.modifier('hidden').class(this.hidden)), role: "option", id: this.inputId, "data-value": this.value, "data-label": this.label, "aria-label": this.label, "aria-hidden": ariaBooleanToString(this.hidden), "aria-selected": ariaBooleanToString(this.selected), "aria-checked": ariaBooleanToString(this.selected), "aria-disabled": ariaBooleanToString(this.disabled), "aria-invalid": ariaBooleanToString(this.invalid), tabIndex: -1, onClick: this.onClick }, h("bal-stack", { key: 'cfcf978a82159a6e7ad2dcddccdb40dd6b9f74a4', py: "small", space: "x-small" }, this.checkbox ? (h("bal-check", { checked: this.selected, disabled: this.disabled, invalid: this.invalid, hovered: this.interactionState.hovered, pressed: this.interactionState.pressed, tabindex: -1 })) : (''), h("div", { key: 'e92a9c019432d29f6153371daca316c8136c75e9', class: Object.assign(Object.assign({}, block.element('inner').class()), block.element('inner').modifier('multiline').class(this.multiline)) }, h("slot", { key: '639a99194ed6e86787e9eb2b3adc993161d58a07' })), this.selected && !this.checkbox ? (h("bal-icon", { name: "check", size: "small", color: this.disabled ? 'grey' : this.invalid ? 'danger' : 'primary' })) : (''))));
    }
    static get is() { return "bal-option"; }
    static get originalStyleUrls() {
        return {
            "$": ["bal-option.sass"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["bal-option.css"]
        };
    }
    static get properties() {
        return {
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Label will be shown in the input element when it got selected"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "label",
                "defaultValue": "''"
            },
            "value": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The value of the select option. This value will be returned by the parent `<bal-select>` element."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "value",
                "defaultValue": "''"
            },
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the user cannot interact with the option."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "disabled",
                "defaultValue": "false"
            },
            "multiline": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the option can present in more than one line."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "multiline",
                "defaultValue": "false"
            },
            "invalid": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the option is shown in red."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "invalid",
                "defaultValue": "false"
            },
            "selected": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the option is selected."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "selected",
                "defaultValue": "false"
            },
            "focused": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the option is focused."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "focused",
                "defaultValue": "false"
            },
            "hidden": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the option is hidden."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "hidden",
                "defaultValue": "false"
            }
        };
    }
    static get states() {
        return {
            "checkbox": {},
            "interactionState": {}
        };
    }
    static get events() {
        return [{
                "method": "balOptionChange",
                "name": "balOptionChange",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the option gets selected or unselected"
                },
                "complexType": {
                    "original": "BalEvents.BalOptionChangeDetail",
                    "resolved": "BalOption",
                    "references": {
                        "BalEvents": {
                            "location": "global",
                            "id": "global::BalEvents"
                        }
                    }
                }
            }, {
                "method": "balOptionFocus",
                "name": "balOptionFocus",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": "Emitted when a option gets focused."
                        }],
                    "text": ""
                },
                "complexType": {
                    "original": "BalEvents.BalOptionFocusDetail",
                    "resolved": "BalOption",
                    "references": {
                        "BalEvents": {
                            "location": "global",
                            "id": "global::BalEvents"
                        }
                    }
                }
            }];
    }
    static get methods() {
        return {
            "select": {
                "complexType": {
                    "signature": "(selected?: boolean) => Promise<void>",
                    "parameters": [{
                            "name": "selected",
                            "type": "boolean",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Selects or deselects the option and informs other components",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "el"; }
    static get listeners() {
        return [{
                "name": "mouseenter",
                "method": "listenToMouseEnter",
                "target": undefined,
                "capture": false,
                "passive": true
            }];
    }
}
__decorate([
    Logger('bal-option'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Function]),
    __metadata("design:returntype", void 0)
], Option.prototype, "createLogger", null);
__decorate([
    ListenToElementStates(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], Option.prototype, "elementStateListener", null);
let balOptionIds = 0;
