import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
import { _ as __decorate, a as __metadata } from './tslib.es6.js';
import { a as ariaBooleanToString } from './aria.js';
import { a as areArraysEqual } from './array.js';
import { i as inheritAttributes } from './attributes.js';
import { B as BEM } from './bem.js';
import { d as defaultBalAriaForm } from './form.js';
import { s as stopEventBubbling } from './form-input.js';
import { i as isDescendant, o as hasTagName } from './helpers.js';
import { L as Logger } from './log.js';
import { d as defineCustomElement$5 } from './bal-check2.js';
import { d as defineCustomElement$4 } from './bal-checkbox2.js';
import { d as defineCustomElement$3 } from './bal-icon2.js';
import { d as defineCustomElement$2 } from './bal-switch2.js';
import { L as ListenToFocus } from './focus.decorator.js';
import { L as ListenToMutation } from './mutation.decorator.js';

const balCheckboxGroupCss = ".bal-checkbox-group{display:inline-block;position:relative;width:100%}.bal-checkbox-group__inner{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-pack:start;justify-content:flex-start;-ms-flex-align:stretch;align-items:stretch;-ms-flex-wrap:wrap;flex-wrap:wrap;gap:var(--bal-space-normal)}.bal-checkbox-group__inner--button{-ms-flex-direction:column;flex-direction:column;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex:1;flex:1;gap:var(--bal-space-x-small)}@media screen and (min-width: 769px),print{.bal-checkbox-group__inner--button{-ms-flex-direction:row;flex-direction:row}}.bal-checkbox-group__inner--expanded{-ms-flex-align:stretch;align-items:stretch}.bal-checkbox-group__inner--expanded .bal-checkbox{-ms-flex:1;flex:1}@media screen and (max-width: 768px){.bal-checkbox-group__inner--expanded .bal-checkbox{width:100%}}.bal-checkbox-group__inner--button.bal-checkbox-group__inner--vertical{gap:var(--bal-space-x-small)}.bal-checkbox-group__inner--vertical{-ms-flex-direction:column;flex-direction:column;border-radius:var(--bal-radius-normal);gap:0}@media screen and (min-width: 769px),print{.bal-checkbox-group__inner--vertical{-ms-flex-align:start;align-items:flex-start}}@media screen and (max-width: 768px){.bal-checkbox-group__inner--vertical-mobile{-ms-flex-direction:column;flex-direction:column;border-radius:var(--bal-radius-normal);gap:0}}";

const CheckboxGroup = /*@__PURE__*/ proxyCustomElement(class CheckboxGroup extends HTMLElement {
    constructor(registerHost) {
        super();
        if (registerHost !== false) {
            this.__registerHost();
        }
        this.balChange = createEvent(this, "balChange", 7);
        this.balFocus = createEvent(this, "balFocus", 7);
        this.balBlur = createEvent(this, "balBlur", 7);
        this.inputId = `bal-cg-${checkboxGroupIds++}`;
        this.inheritedAttributes = {};
        this.ariaForm = defaultBalAriaForm;
        /**
         * Defines the layout of the checkbox button
         */
        this.interface = undefined;
        /**
         * If `true` it acts as the main form control
         */
        this.control = false;
        /**
         * The name of the control, which is submitted with the form data.
         */
        this.name = this.inputId;
        /**
         * Displays the checkboxes vertically
         */
        this.vertical = false;
        /**
         * If `true`, the controls will be vertically on mobile devices.
         */
        this.verticalOnMobile = false;
        /**
         * Uses the whole width
         */
        this.expanded = false;
        /**
         * If `true`, the element is not mutable, focusable, or even submitted with the form. The user can neither edit nor focus on the control, nor its form control descendants.
         */
        this.invalid = undefined;
        /**
         * If `true`, the user cannot interact with the checkboxes.
         */
        this.disabled = undefined;
        /**
         * If `true`, the user cannot interact with the checkboxes.
         */
        this.readonly = undefined;
        /**
         * The value of the control.
         */
        this.value = [];
        /**
         * Defines the column size like the grid.
         */
        this.columns = 1;
        /**
         * Defines the column size for tablet and bigger like the grid.
         */
        this.columnsTablet = 1;
        /**
         * Defines the column size for mobile and bigger like the grid.
         */
        this.columnsMobile = 1;
        /**
         * If `true`, in Angular reactive forms the control will not be set invalid
         */
        this.autoInvalidOff = false;
        /**
         * LISTENERS
         * ------------------------------------------------------
         */
        this.hasFocus = false;
        this.mutationObserverActive = true;
        /**
         * EVENT BINDING
         * ------------------------------------------------------
         */
        this.onClick = (ev) => {
            if (!this.control) {
                return;
            }
            const element = ev.target;
            if (element.href) {
                return;
            }
            const selectedCheckbox = ev.target && ev.target.closest('bal-checkbox');
            if (selectedCheckbox) {
                if (selectedCheckbox.disabled || selectedCheckbox.readonly) {
                    return ev.stopPropagation();
                }
            }
            this.updateValues();
        };
        this.onOptionChange = async () => {
            this.sync();
        };
    }
    createLogger(log) {
        this.log = log;
    }
    async optionChanged() {
        if (this.control) {
            this.onOptionChange();
            this.mutationObserverActive = this.options === undefined;
        }
    }
    invalidChanged(value) {
        if (this.control) {
            if (value !== undefined) {
                this.getCheckboxes().forEach(child => {
                    child.invalid = value;
                });
            }
        }
    }
    disabledChanged(value) {
        if (this.control) {
            if (value !== undefined) {
                this.getCheckboxes().forEach(child => {
                    child.disabled = value;
                });
            }
        }
    }
    readonlyChanged(value) {
        if (this.control) {
            if (value !== undefined) {
                this.getCheckboxes().forEach(child => {
                    child.readonly = value;
                });
            }
        }
    }
    valueChanged(_value, oldValue) {
        if (this.control) {
            if (!areArraysEqual(this.value, oldValue)) {
                this.onOptionChange();
            }
        }
        else {
            this.onOptionChange();
        }
    }
    columnsChanged(value) {
        this.getCheckboxes().forEach(checkbox => (checkbox.colSize = value));
    }
    columnsTabletChanged(value) {
        this.getCheckboxes().forEach(checkbox => (checkbox.colSizeTablet = value));
    }
    columnsMobileChanged(value) {
        this.getCheckboxes().forEach(checkbox => (checkbox.colSizeMobile = value));
    }
    /**
     * LIFECYCLE
     * ------------------------------------------------------
     */
    connectedCallback() {
        if (this.control) {
            this.mutationObserverActive = this.options === undefined;
            this.valueChanged(this.value, []);
        }
    }
    componentWillLoad() {
        if (this.control) {
            this.inheritedAttributes = inheritAttributes(this.el, ['aria-label', 'tabindex', 'title']);
            this.disabledChanged(this.disabled);
            this.invalidChanged(this.invalid);
            this.readonlyChanged(this.readonly);
        }
        this.columnsChanged(this.columns);
        this.columnsTabletChanged(this.columnsTablet);
        this.columnsMobileChanged(this.columnsMobile);
        this.onOptionChange();
    }
    focusInListener(ev) {
        this.balFocus.emit(ev);
    }
    focusOutListener(ev) {
        this.balBlur.emit(ev);
    }
    mutationListener() {
        if (this.control) {
            this.disabledChanged(this.disabled);
            this.readonlyChanged(this.readonly);
        }
        this.columnsChanged(this.columns);
        this.columnsTabletChanged(this.columnsTablet);
        this.columnsMobileChanged(this.columnsMobile);
        this.onOptionChange();
    }
    listenOnCheckboxChange(ev) {
        if (this.control) {
            if (isDescendant(this.el, ev.target)) {
                stopEventBubbling(ev);
                this.updateValues();
            }
        }
    }
    resetHandler(ev) {
        const formElement = ev.target;
        if (formElement === null || formElement === void 0 ? void 0 : formElement.contains(this.el)) {
            if (this.control) {
                this.value = [];
            }
            this.onOptionChange();
        }
    }
    checkboxFocusListener(ev) {
        const { target } = ev;
        if (target && isDescendant(this.el, target) && hasTagName(target, 'bal-checkbox')) {
            stopEventBubbling(ev);
        }
    }
    checkboxBlurListener(ev) {
        const { target } = ev;
        if (target && isDescendant(this.el, target) && hasTagName(target, 'bal-checkbox')) {
            stopEventBubbling(ev);
        }
    }
    /**
     * PUBLIC METHODS
     * ------------------------------------------------------
     */
    /** @internal */
    async setValue(value) {
        if (this.control) {
            this.value = value;
        }
    }
    /**
     * Find the options properties by its value
     */
    async getOptionByValue(value) {
        const options = this.options;
        if (options) {
            return options.find(option => option.value === value);
        }
        return undefined;
    }
    /**
     * @internal
     */
    async setAriaForm(ariaForm) {
        this.ariaForm = Object.assign({}, ariaForm);
    }
    /**
     * PRIVATE METHODS
     * ------------------------------------------------------
     */
    sync() {
        if (this.control) {
            const isChecked = (checkbox) => {
                for (let index = 0; index < this.value.length; index++) {
                    const valueItem = this.value[index];
                    if (valueItem !== undefined && valueItem.toString() === checkbox.value.toString()) {
                        return true;
                    }
                }
                return false;
            };
            this.getCheckboxes().forEach((checkbox) => {
                checkbox.checked = isChecked(checkbox);
            });
        }
        this.getCheckboxes().forEach((checkbox) => {
            if (this.interface) {
                checkbox.interface = this.interface;
            }
        });
    }
    /**
     * GETTERS
     * ------------------------------------------------------
     */
    getCheckboxes() {
        return Array.from(this.el.querySelectorAll('bal-checkbox'));
    }
    updateValues() {
        // generate new value array out of the checked checkboxes
        const newValue = [];
        this.getCheckboxes().forEach(cb => {
            if (cb.checked) {
                newValue.push(cb.value);
            }
        });
        if (!areArraysEqual(this.value, newValue)) {
            this.value = [...newValue];
            this.balChange.emit(this.value);
        }
    }
    /**
     * RENDER
     * ------------------------------------------------------
     */
    render() {
        const block = BEM.block('checkbox-group');
        const innerEl = block.element('inner');
        const rawOptions = this.options || [];
        const options = rawOptions.map(option => {
            if (typeof option.html === 'function') {
                return Object.assign(Object.assign({}, option), { html: option.html() });
            }
            return option;
        });
        return (h(Host, Object.assign({ class: Object.assign({}, block.class()), role: "group", "aria-labelledby": this.ariaForm.labelId, "aria-describedby": this.ariaForm.messageId, "aria-disabled": ariaBooleanToString(this.disabled), "aria-invalid": ariaBooleanToString(this.invalid), onClick: this.onClick }, this.inheritedAttributes), h("div", { class: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, innerEl.class()), innerEl.modifier('vertical-mobile').class(this.verticalOnMobile)), innerEl.modifier('vertical').class(this.vertical)), innerEl.modifier('expanded').class(this.expanded)), innerEl.modifier('button').class(this.interface === 'button')) }, h("slot", null), options.map(option => (h("bal-checkbox", { key: option.value, name: option.name, value: option.value, labelHidden: option.labelHidden, flat: option.flat, interface: option.interface, disabled: option.disabled, readonly: option.readonly, required: option.required, nonSubmit: !!option.nonSubmit, invalid: option.invalid, innerHTML: option.html }))))));
    }
    get el() { return this; }
    static get watchers() { return {
        "options": ["optionChanged"],
        "invalid": ["invalidChanged"],
        "disabled": ["disabledChanged"],
        "readonly": ["readonlyChanged"],
        "value": ["valueChanged"],
        "columns": ["columnsChanged"],
        "columnsTablet": ["columnsTabletChanged"],
        "columnsMobile": ["columnsMobileChanged"]
    }; }
    static get style() { return balCheckboxGroupCss; }
}, [260, "bal-checkbox-group", {
        "options": [16],
        "interface": [1],
        "control": [4],
        "name": [1],
        "vertical": [4],
        "verticalOnMobile": [4, "vertical-on-mobile"],
        "expanded": [4],
        "invalid": [4],
        "disabled": [4],
        "readonly": [4],
        "value": [1040],
        "columns": [2],
        "columnsTablet": [2, "columns-tablet"],
        "columnsMobile": [2, "columns-mobile"],
        "autoInvalidOff": [516, "auto-invalid-off"],
        "ariaForm": [32],
        "setValue": [64],
        "getOptionByValue": [64],
        "setAriaForm": [64]
    }, [[6, "balChange", "listenOnCheckboxChange"], [6, "reset", "resetHandler"], [6, "balFocus", "checkboxFocusListener"], [6, "balBlur", "checkboxBlurListener"]], {
        "options": ["optionChanged"],
        "invalid": ["invalidChanged"],
        "disabled": ["disabledChanged"],
        "readonly": ["readonlyChanged"],
        "value": ["valueChanged"],
        "columns": ["columnsChanged"],
        "columnsTablet": ["columnsTabletChanged"],
        "columnsMobile": ["columnsMobileChanged"]
    }]);
__decorate([
    Logger('bal-checkbox-group'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Function]),
    __metadata("design:returntype", void 0)
], CheckboxGroup.prototype, "createLogger", null);
__decorate([
    ListenToFocus(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], CheckboxGroup.prototype, "focusInListener", null);
__decorate([
    ListenToFocus(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], CheckboxGroup.prototype, "focusOutListener", null);
__decorate([
    ListenToMutation({ tags: ['bal-checkbox-group', 'bal-checkbox'], attributes: false, characterData: false }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], CheckboxGroup.prototype, "mutationListener", null);
let checkboxGroupIds = 0;
function defineCustomElement$1() {
    if (typeof customElements === "undefined") {
        return;
    }
    const components = ["bal-checkbox-group", "bal-check", "bal-checkbox", "bal-icon", "bal-switch"];
    components.forEach(tagName => { switch (tagName) {
        case "bal-checkbox-group":
            if (!customElements.get(tagName)) {
                customElements.define(tagName, CheckboxGroup);
            }
            break;
        case "bal-check":
            if (!customElements.get(tagName)) {
                defineCustomElement$5();
            }
            break;
        case "bal-checkbox":
            if (!customElements.get(tagName)) {
                defineCustomElement$4();
            }
            break;
        case "bal-icon":
            if (!customElements.get(tagName)) {
                defineCustomElement$3();
            }
            break;
        case "bal-switch":
            if (!customElements.get(tagName)) {
                defineCustomElement$2();
            }
            break;
    } });
}

const BalCheckboxGroup = CheckboxGroup;
const defineCustomElement = defineCustomElement$1;

export { BalCheckboxGroup, defineCustomElement };
