import { __esDecorate, __runInitializers } from "tslib";
import { html, LitElement } from 'lit';
import { queryAssignedElements } from 'lit/decorators.js';
import Chip from './Chip.js';
let ChipSet = (() => {
    let _classSuper = LitElement;
    let _childElements_decorators;
    let _childElements_initializers = [];
    let _childElements_extraInitializers = [];
    return class ChipSet extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _childElements_decorators = [queryAssignedElements()];
            __esDecorate(this, null, _childElements_decorators, { kind: "accessor", name: "childElements", static: false, private: false, access: { has: obj => "childElements" in obj, get: obj => obj.childElements, set: (obj, value) => { obj.childElements = value; } }, metadata: _metadata }, _childElements_initializers, _childElements_extraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        get chips() {
            return this.childElements.filter((child) => child instanceof Chip);
        }
        #childElements_accessor_storage = __runInitializers(this, _childElements_initializers, void 0);
        get childElements() { return this.#childElements_accessor_storage; }
        set childElements(value) { this.#childElements_accessor_storage = value; }
        internals = (__runInitializers(this, _childElements_extraInitializers), this.attachInternals());
        constructor() {
            super();
            this.addEventListener('focusin', this.updateTabIndices.bind(this));
            this.addEventListener('update-focus', this.updateTabIndices.bind(this));
            this.addEventListener('keydown', this.handleKeyDown.bind(this));
            this.internals.role = 'toolbar';
        }
        connectedCallback() {
            super.connectedCallback();
            if (!this.hasAttribute('role')) {
                this.setAttribute('role', 'toolbar');
            }
        }
        render() {
            return html `<slot @slotchange=${this.updateTabIndices}></slot>`;
        }
        handleKeyDown(event) {
            const isLeft = event.key === 'ArrowLeft';
            const isRight = event.key === 'ArrowRight';
            const isHome = event.key === 'Home';
            const isEnd = event.key === 'End';
            // Ignore non-navigation keys
            if (!isLeft && !isRight && !isHome && !isEnd) {
                return;
            }
            const { chips } = this;
            // Don't try to select another chip if there aren't any.
            if (chips.length < 2) {
                return;
            }
            // Prevent default interactions, such as scrolling.
            event.preventDefault();
            if (isHome || isEnd) {
                const index = isHome ? 0 : chips.length - 1;
                chips[index].focus({ trailing: isEnd });
                this.updateTabIndices();
                return;
            }
            // Check if moving forwards or backwards
            const isRtl = getComputedStyle(this).direction === 'rtl';
            const forwards = isRtl ? isLeft : isRight;
            const focusedChip = chips.find((chip) => chip.matches(':focus-within'));
            if (!focusedChip) {
                // If there is not already a chip focused, select the first or last chip
                // based on the direction we're traveling.
                const nextChip = forwards ? chips[0] : chips[chips.length - 1];
                nextChip.focus({ trailing: !forwards });
                this.updateTabIndices();
                return;
            }
            const currentIndex = chips.indexOf(focusedChip);
            let nextIndex = forwards ? currentIndex + 1 : currentIndex - 1;
            // Search for the next sibling that is not disabled to select.
            // If we return to the host index, there is nothing to select.
            while (nextIndex !== currentIndex) {
                if (nextIndex >= chips.length) {
                    // Return to start if moving past the last item.
                    nextIndex = 0;
                }
                else if (nextIndex < 0) {
                    // Go to end if moving before the first item.
                    nextIndex = chips.length - 1;
                }
                // Check if the next sibling is disabled. If so,
                // move the index and continue searching.
                //
                // Some toolbar items may be focusable when disabled for increased
                // visibility.
                const nextChip = chips[nextIndex];
                if (nextChip.disabled) {
                    if (forwards) {
                        nextIndex++;
                    }
                    else {
                        nextIndex--;
                    }
                    continue;
                }
                nextChip.focus({ trailing: !forwards });
                this.updateTabIndices();
                break;
            }
        }
        updateTabIndices() {
            // The chip that should be focusable is either the chip that currently has
            // focus or the first chip that can be focused.
            const { chips } = this;
            let chipToFocus;
            for (const chip of chips) {
                const isChipFocusable = !chip.disabled;
                const chipIsFocused = chip.matches(':focus-within');
                if (chipIsFocused && isChipFocusable) {
                    // Found the first chip that is actively focused. This overrides the
                    // first focusable chip found.
                    chipToFocus = chip;
                    continue;
                }
                if (isChipFocusable && !chipToFocus) {
                    chipToFocus = chip;
                }
                // Disable non-focused chips. If we disable all of them, we'll grant focus
                // to the first focusable child that was found.
                chip.tabIndex = -1;
            }
            if (chipToFocus) {
                chipToFocus.tabIndex = 0;
            }
        }
    };
})();
/**
 * A chip set component.
 */
export default ChipSet;
//# sourceMappingURL=ChipSet.js.map