import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
import { e as deepReady, b as waitAfterFramePaint } from './helpers.js';
import { d as defaultBalAriaForm } from './form.js';
import { L as ListenToMutation } from './mutation.decorator.js';

const balFieldCss = ":root{--bal-field-label-horizontal-width:33.3333%;--bal-field-label-column-gap:.5rem}.bal-field,.bal-field-label,.bal-field-control,.bal-field-message,.bal-field-hint{display:block;position:relative;font-family:var(--bal-font-family-text)}.bal-field-label{display:inline}.bal-field-label~.bal-field-control{margin-top:.25rem}.bal-field-hint{display:inline-block;margin-left:.25rem;height:1rem;width:1rem}.bal-field-hint__hint{position:absolute;top:2px;left:0}.bal-field-message{line-height:var(--bal-line-height-normal)}.bal-field-hidden{display:none !important;visibility:hidden !important}.bal-field-control{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-direction:row;flex-direction:row;gap:.5rem}.bal-field-control .bal-input{-ms-flex:1;flex:1}@media screen and (max-width: 768px){.bal-field-control--expanded-on-mobile{-ms-flex-direction:column;flex-direction:column}.bal-field-control--expanded-on-mobile .bal-button,.bal-field-control--expanded-on-mobile .bal-button .button{width:100%}}.bal-field-control{padding-bottom:1.375rem}.bal-field-control+.bal-field-message{margin-top:-1.5rem !important}.bal-field--horizontal{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-column-gap:var(--bal-field-label-column-gap);-moz-column-gap:var(--bal-field-label-column-gap);column-gap:var(--bal-field-label-column-gap);-ms-flex-align:center;align-items:center}.bal-field--horizontal .bal-field-label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-width:var(--bal-field-label-horizontal-width);max-width:var(--bal-field-label-horizontal-width);-ms-flex-pack:end;justify-content:flex-end;text-align:right;margin-bottom:0}.bal-field--horizontal .bal-field-control{-ms-flex:1;flex:1;padding-bottom:0;-ms-flex-item-align:end;align-self:flex-end}.bal-field--horizontal .bal-field-message{-ms-flex-preferred-size:100%;flex-basis:100%;margin-top:0 !important;margin-left:calc(var(--bal-field-label-horizontal-width) + var(--bal-field-label-column-gap))}.bal-field--horizontal .bal-field-hint{margin-left:0}.bal-field--horizontal .bal-field-hint .bal-hint{top:0}.bal-field--horizontal .bal-field-hint~.bal-field-message{margin-left:calc(var(--bal-field-label-horizontal-width) + var(--bal-field-label-column-gap)*2 + 1.125rem)}.bal-field--horizontal .bal-field-label~.bal-field-control{margin-top:0}";
const BalFieldStyle0 = balFieldCss;

var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
        r = Reflect.decorate(decorators, target, key, desc);
    else
        for (var i = decorators.length - 1; i >= 0; i--)
            if (d = decorators[i])
                r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const Field = proxyCustomElement(class Field extends HTMLElement {
    constructor() {
        super();
        this.__registerHost();
        this.balFormControlDidLoad = createEvent(this, "balFormControlDidLoad", 7);
        this.fieldId = `bal-field-${FieldIds++}`;
        this.formControlElement = ['bal-field-control'];
        this.inputElements = [
            'bal-input',
            'bal-number-input',
            'bal-textarea',
            'bal-select',
            'bal-datepicker',
            'bal-checkbox',
            'bal-radio',
            'bal-input-group',
            'bal-date',
            'bal-input-date',
            'bal-input-stepper',
            'bal-input-slider',
            'bal-file-upload',
        ];
        this.formElements = [...this.formControlElement, 'bal-field-label', 'bal-field-message'];
        this.isDirectChild = (el) => {
            if (!el) {
                return false;
            }
            const parent = el.parentElement;
            if (!parent) {
                return false;
            }
            if (parent.nodeName.toLowerCase() === 'bal-field' && parent !== this.el) {
                return false;
            }
            if (parent === this.el) {
                return true;
            }
            return this.isDirectChild(parent);
        };
        this.findDirectChild = (selectors) => {
            const element = this.el.querySelector(selectors);
            const isDirectChild = this.isDirectChild(element);
            if (isDirectChild) {
                return element;
            }
            return undefined;
        };
        this.findDirectChildren = (selectors) => {
            return selectors
                .map(selector => {
                return Array.from(this.el.querySelectorAll(selector)).filter(this.isDirectChild);
            })
                .flat();
        };
        this.mutationObserverActive = true;
        this.required = undefined;
        this.horizontal = false;
        this.invalid = undefined;
        this.valid = false;
        this.disabled = undefined;
        this.readonly = undefined;
        this.loading = undefined;
    }
    requiredHandler() {
        this.updateProps([...this.inputElements, 'bal-field-label'], 'required');
    }
    invalidHandler() {
        this.updateProps([...this.inputElements, ...this.formElements], 'invalid');
    }
    validHandler() {
        this.updateProps([...this.inputElements, ...this.formElements], 'valid');
    }
    disabledHandler() {
        this.updateProps([...this.inputElements, ...this.formElements], 'disabled');
    }
    readonlyHandler() {
        this.updateProps([...this.inputElements, ...this.formElements], 'readonly');
    }
    loadingHandler() {
        this.updateProps([...this.inputElements, ...this.formControlElement], 'loading');
    }
    connectedCallback() {
        this.triggerAllHandlers();
    }
    componentWillLoad() {
        this.triggerAllHandlers();
    }
    async componentDidLoad() {
        await this.syncAriaAttributes();
    }
    async syncAriaAttributes() {
        await deepReady(this.el);
        await waitAfterFramePaint();
        const label = this.findDirectChild('bal-field-label bal-label');
        const message = this.findDirectChild('bal-field-message');
        const controls = this.findDirectChildren([
            'bal-field-control bal-input',
            'bal-field-control bal-select',
            'bal-field-control bal-input-date',
            'bal-field-control bal-checkbox',
            'bal-field-control bal-radio',
            'bal-field-control bal-checkbox-group',
            'bal-field-control bal-radio-group',
            'bal-field-control bal-number-input',
            'bal-field-control bal-time-input',
            'bal-field-control bal-datepicker',
            'bal-field-control bal-input-slider',
            'bal-field-control bal-input-stepper',
            'bal-field-control bal-textarea',
            'bal-field-control bal-file-upload',
        ]);
        const ariaForm = defaultBalAriaForm;
        if (label) {
            ariaForm.labelId = `${this.fieldId}-lbl`;
        }
        if (message) {
            ariaForm.messageId = `${this.fieldId}-msg`;
        }
        for (let index = 0; index < controls.length; index++) {
            const control = controls[index];
            if (index === 0) {
                ariaForm.controlId = `${this.fieldId}-ctrl`;
                await (label === null || label === void 0 ? void 0 : label.setAriaForm(ariaForm));
                await (message === null || message === void 0 ? void 0 : message.setAriaForm(ariaForm));
                await (control === null || control === void 0 ? void 0 : control.setAriaForm(ariaForm));
            }
            else {
                ariaForm.controlId = `${this.fieldId}-ctrl-${index}`;
                await (control === null || control === void 0 ? void 0 : control.setAriaForm(ariaForm));
            }
        }
    }
    mutationListener() {
        this.triggerAllHandlers();
        this.syncAriaAttributes();
    }
    triggerAllHandlers() {
        this.requiredHandler();
        this.invalidHandler();
        this.validHandler();
        this.readonlyHandler();
        this.disabledHandler();
        this.loadingHandler();
    }
    updateProps(selectors, key) {
        const value = this[key];
        if (value !== undefined) {
            this.notifyComponents(selectors, input => (input[key] = value));
        }
    }
    notifyComponents(selectors, callback) {
        const components = this.el.querySelectorAll(selectors.join(', '));
        components.forEach(c => callback(c));
    }
    render() {
        return (h(Host, { id: this.fieldId, class: {
                'bal-field': true,
                'field': true,
                'bal-field--invalid': this.invalid === true,
                'bal-field--horizontal': this.horizontal === true,
            } }, h("slot", null), h("span", { class: "bal-field-hidden" })));
    }
    get el() { return this; }
    static get watchers() { return {
        "required": ["requiredHandler"],
        "invalid": ["invalidHandler"],
        "valid": ["validHandler"],
        "disabled": ["disabledHandler"],
        "readonly": ["readonlyHandler"],
        "loading": ["loadingHandler"]
    }; }
    static get style() { return BalFieldStyle0; }
}, [4, "bal-field", {
        "required": [4],
        "horizontal": [4],
        "invalid": [4],
        "valid": [4],
        "disabled": [4],
        "readonly": [4],
        "loading": [4]
    }, undefined, {
        "required": ["requiredHandler"],
        "invalid": ["invalidHandler"],
        "valid": ["validHandler"],
        "disabled": ["disabledHandler"],
        "readonly": ["readonlyHandler"],
        "loading": ["loadingHandler"]
    }]);
__decorate([
    ListenToMutation({ subtree: false, waitAfterFramePrint: true })
], Field.prototype, "mutationListener", null);
let FieldIds = 0;
function defineCustomElement$1() {
    if (typeof customElements === "undefined") {
        return;
    }
    const components = ["bal-field"];
    components.forEach(tagName => { switch (tagName) {
        case "bal-field":
            if (!customElements.get(tagName)) {
                customElements.define(tagName, Field);
            }
            break;
    } });
}

const BalField = Field;
const defineCustomElement = defineCustomElement$1;

export { BalField, defineCustomElement };
