import { __decorate } from "tslib";
import { DesignSystem, FoundationElement } from '@ni/fast-foundation';
import { observable, attr, volatile, Observable } from '@ni/fast-element';
import { styles } from './styles';
import { template } from './template';
import { ListOption } from '../list-option';
import { slotTextContent } from '../utilities/models/slot-text-content';
/**
 * A nimble-styled HTML listbox option group
 */
export class ListOptionGroup extends FoundationElement {
    constructor() {
        super(...arguments);
        /**
         * The hidden state of the element.
         *
         * @public
         * @defaultValue - false
         * @remarks
         * HTML Attribute: hidden
         */
        this.hidden = false;
        /**
         * @internal
         * This attribute is required to allow use-cases that offer dynamic filtering
         * (like the Select) to visually hide groups that are filtered out, but still
         * allow users to use the native 'hidden' attribute without it being affected
         * by the filtering process.
         */
        this.visuallyHidden = false;
        /**
         * @internal
         */
        this.topSeparatorVisible = false;
        /**
         * @internal
         */
        this.bottomSeparatorVisible = false;
        /** @internal */
        this.hasOverflow = false;
        this.hiddenOptions = new Set();
    }
    /** @internal */
    get labelContent() {
        if (this.label) {
            return this.label;
        }
        if (!this.$fastController.isConnected) {
            return '';
        }
        return slotTextContent(this.labelSlot);
    }
    /**
     * @internal
     */
    clickHandler(e) {
        e.preventDefault();
        e.stopImmediatePropagation();
    }
    /**
     * @internal
     */
    handleChange(source, propertyName) {
        if (source instanceof ListOption
            && (propertyName === 'hidden' || propertyName === 'visuallyHidden')) {
            if (source.hidden || source.visuallyHidden) {
                this.hiddenOptions.add(source);
            }
            else {
                this.hiddenOptions.delete(source);
            }
            this.visuallyHidden = this.hiddenOptions.size === this.listOptions.length;
        }
    }
    listOptionsChanged(prev, next) {
        this.hiddenOptions.clear();
        next.filter(o => o.hidden || o.visuallyHidden).forEach(o => this.hiddenOptions.add(o));
        prev?.forEach(o => {
            const notifier = Observable.getNotifier(o);
            notifier.unsubscribe(this, 'hidden');
            notifier.unsubscribe(this, 'visuallyHidden');
        });
        let allOptionsHidden = true;
        next?.forEach(o => {
            const notifier = Observable.getNotifier(o);
            notifier.subscribe(this, 'hidden');
            notifier.subscribe(this, 'visuallyHidden');
            allOptionsHidden = allOptionsHidden && (o.hidden || o.visuallyHidden);
        });
        this.visuallyHidden = next.length === 0 || allOptionsHidden;
    }
}
__decorate([
    attr
], ListOptionGroup.prototype, "label", void 0);
__decorate([
    attr({ mode: 'boolean' })
], ListOptionGroup.prototype, "hidden", void 0);
__decorate([
    attr({ attribute: 'visually-hidden', mode: 'boolean' })
], ListOptionGroup.prototype, "visuallyHidden", void 0);
__decorate([
    attr({ attribute: 'top-separator-visible', mode: 'boolean' })
], ListOptionGroup.prototype, "topSeparatorVisible", void 0);
__decorate([
    attr({ attribute: 'bottom-separator-visible', mode: 'boolean' })
], ListOptionGroup.prototype, "bottomSeparatorVisible", void 0);
__decorate([
    observable
], ListOptionGroup.prototype, "hasOverflow", void 0);
__decorate([
    observable
], ListOptionGroup.prototype, "listOptions", void 0);
__decorate([
    volatile
], ListOptionGroup.prototype, "labelContent", null);
const nimbleListOptionGroup = ListOptionGroup.compose({
    baseName: 'list-option-group',
    baseClass: FoundationElement,
    template,
    styles
});
DesignSystem.getOrCreate()
    .withPrefix('nimble')
    .register(nimbleListOptionGroup());
export const listOptionGroupTag = 'nimble-list-option-group';
//# sourceMappingURL=index.js.map