import { trigger, state, style, transition, group, query, animate } from '@angular/animations';
import { TemplatePortal, DomPortalOutlet } from '@angular/cdk/portal';
import * as i1$1 from '@angular/common';
import { DOCUMENT, NgClass } from '@angular/common';
import * as i0 from '@angular/core';
import { inject, Directive, InjectionToken, booleanAttribute, Component, ChangeDetectionStrategy, ViewEncapsulation, Inject, Optional, ViewChild, ContentChild, Input, HostListener, EventEmitter, QueryList, TemplateRef, ContentChildren, Output, numberAttribute, Self, NgModule } from '@angular/core';
import { Subject, Subscription, merge, of, asapScheduler } from 'rxjs';
import * as i1 from '@angular/cdk/a11y';
import { KbqComponentColors, KBQ_TITLE_TEXT_REF, KBQ_WINDOW, defaultOffsetY } from '@koobiq/components/core';
import * as i2 from '@koobiq/components/icon';
import { KbqIcon, KbqIconModule } from '@koobiq/components/icon';
import * as i4 from '@angular/cdk/bidi';
import * as i1$2 from '@angular/cdk/overlay';
import { Overlay, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
import { normalizePassiveListenerOptions, Platform } from '@angular/cdk/platform';
import { RIGHT_ARROW, LEFT_ARROW, ESCAPE, ENTER, SPACE, DOWN_ARROW as DOWN_ARROW$1 } from '@koobiq/cdk/keycodes';
import { startWith, switchMap, take, filter, takeUntil, delay } from 'rxjs/operators';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { UP_ARROW, DOWN_ARROW } from '@angular/cdk/keycodes';
import { FocusKeyManager } from '@koobiq/cdk/a11y';

/**
 * Animations used by the kbq-dropdown component.
 * @docs-private
 */
const kbqDropdownAnimations = {
    /**
     * This animation controls the dropdown panel's entry and exit from the page.
     *
     * When the dropdown panel is added to the DOM, it scales in and fades in its border.
     *
     * When the dropdown panel is removed from the DOM, it simply fades out after a brief
     * delay to display the ripple.
     */
    transformDropdown: trigger('transformDropdown', [
        state('void', style({
            opacity: 0,
            transform: 'scale(0.8)'
        })),
        transition('void => enter', group([
            query('.kbq-dropdown__content', animate('0ms linear', style({ opacity: 1 }))),
            animate('0ms cubic-bezier(0, 0, 0.2, 1)', style({ transform: 'scale(1)' }))
        ])),
        transition('* => void', animate('50ms 25ms linear', style({ opacity: 0 })))
    ]),
    /**
     * This animation fades in the background color and content of the dropdown panel
     * after its containing element is scaled in.
     */
    fadeInItems: trigger('fadeInItems', [
        // now. Remove next time we do breaking changes.
        state('showing', style({ opacity: 1 })),
        transition('void => *', [
            style({ opacity: 0 }),
            animate('0ms 0ms cubic-bezier(0.55, 0, 0.55, 0.2)')
        ])
    ])
};
const fadeInItems = kbqDropdownAnimations.fadeInItems;
const transformDropdown = kbqDropdownAnimations.transformDropdown;

/**
 * Dropdown content that will be rendered lazily once the dropdown is opened.
 */
class KbqDropdownContent {
    constructor(template, componentFactoryResolver, appRef, injector, viewContainerRef) {
        this.template = template;
        this.componentFactoryResolver = componentFactoryResolver;
        this.appRef = appRef;
        this.injector = injector;
        this.viewContainerRef = viewContainerRef;
        this.document = inject(DOCUMENT);
        /** Emits when the dropdown content has been attached. */
        this.attached = new Subject();
    }
    /**
     * Attaches the content with a particular context.
     * @docs-private
     */
    attach(context = {}) {
        if (!this.portal) {
            this.portal = new TemplatePortal(this.template, this.viewContainerRef);
        }
        this.detach();
        if (!this.outlet) {
            this.outlet = new DomPortalOutlet(this.document.createElement('div'), this.componentFactoryResolver, this.appRef, this.injector);
        }
        const element = this.template.elementRef.nativeElement;
        // Because we support opening the same dropdown from different triggers (which in turn have their
        // own `OverlayRef` panel), we have to re-insert the host element every time, otherwise we
        // risk it staying attached to a pane that's no longer in the DOM.
        element.parentNode.insertBefore(this.outlet.outletElement, element);
        this.portal.attach(this.outlet, context);
        this.attached.next();
    }
    /**
     * Detaches the content.
     * @docs-private
     */
    detach() {
        if (this.portal?.isAttached) {
            this.portal.detach();
        }
    }
    ngOnDestroy() {
        this.outlet?.dispose();
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqDropdownContent, deps: [{ token: i0.TemplateRef }, { token: i0.ComponentFactoryResolver }, { token: i0.ApplicationRef }, { token: i0.Injector }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); }
    /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: KbqDropdownContent, selector: "ng-template[kbqDropdownContent]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqDropdownContent, decorators: [{
            type: Directive,
            args: [{
                    selector: 'ng-template[kbqDropdownContent]'
                }]
        }], ctorParameters: () => [{ type: i0.TemplateRef }, { type: i0.ComponentFactoryResolver }, { type: i0.ApplicationRef }, { type: i0.Injector }, { type: i0.ViewContainerRef }] });

/**
 * Throws an exception for the case when dropdown trigger doesn't have a valid kbq-dropdown instance
 * @docs-private
 */
function throwKbqDropdownMissingError() {
    throw Error(`kbqDropdownTriggerFor: must pass in an kbq-dropdown instance.
    Example:
      <kbq-dropdown #dropdown="kbqDropdown"></kbq-dropdown>
      <button [kbqDropdownTriggerFor]="dropdown"></button>`);
}
/**
 * Throws an exception for the case when dropdown's x-position value isn't valid.
 * In other words, it doesn't match 'before' or 'after'.
 * @docs-private
 */
function throwKbqDropdownInvalidPositionX() {
    throw Error(`xPosition value must be either 'before' or after'.
      Example: <kbq-dropdown [xPosition]="'before'" #dropdown="kbqDropdown"></kbq-dropdown>`);
}
/**
 * Throws an exception for the case when dropdown's y-position value isn't valid.
 * In other words, it doesn't match 'above' or 'below'.
 * @docs-private
 */
function throwKbqDropdownInvalidPositionY() {
    throw Error(`yPosition value must be either 'above' or below'.
      Example: <kbq-dropdown [yPosition]="'above'" #dropdown="kbqDropdown"></kbq-dropdown>`);
}

/**
 * Injection token used to provide the parent dropdown to dropdown-specific components.
 * @docs-private
 */
const KBQ_DROPDOWN_PANEL = new InjectionToken('KBQ_DROPDOWN_PANEL');
/** Injection token to be used to override the default options for `kbq-dropdown`. */
const KBQ_DROPDOWN_DEFAULT_OPTIONS = new InjectionToken('kbq-dropdown-default-options', {
    providedIn: 'root',
    factory: KBQ_DROPDOWN_DEFAULT_OPTIONS_FACTORY
});
/** @docs-private */
function KBQ_DROPDOWN_DEFAULT_OPTIONS_FACTORY() {
    return {
        overlapTriggerX: true,
        overlapTriggerY: false,
        xPosition: 'after',
        yPosition: 'below',
        backdropClass: 'cdk-overlay-transparent-backdrop',
        hasBackdrop: false
    };
}

/**
 * This directive is intended to be used inside an kbq-dropdown tag.
 * It exists mostly to set the role attribute.
 */
class KbqDropdownItem {
    get disabled() {
        return this._disabled;
    }
    set disabled(value) {
        if (value !== this.disabled) {
            this._disabled = value;
        }
    }
    constructor(elementRef, focusMonitor, parentDropdownPanel) {
        this.elementRef = elementRef;
        this.focusMonitor = focusMonitor;
        this.parentDropdownPanel = parentDropdownPanel;
        this._disabled = false;
        /** Stream that emits when the dropdown item is hovered. */
        this.hovered = new Subject();
        /** Stream that emits when the menu item is focused. */
        this.focused = new Subject();
        /** Whether the dropdown item is highlighted. */
        this.highlighted = false;
        /** Whether the dropdown item acts as a trigger for a nested dropdown. */
        this.isNested = false;
        /** @docs-private */
        this.componentColors = KbqComponentColors;
    }
    ngAfterViewInit() {
        if (this.focusMonitor) {
            // Start monitoring the element so it gets the appropriate focused classes. We want
            // to show the focus style for menu items only when the focus was not caused by a
            // mouse or touch interaction.
            this.focusMonitor.monitor(this.elementRef, false);
        }
    }
    ngOnDestroy() {
        if (this.focusMonitor) {
            this.focusMonitor.stopMonitoring(this.elementRef);
        }
        this.hovered.complete();
        this.focused.complete();
    }
    resetStyles() {
        this.getHostElement().classList.remove('cdk-keyboard-focused');
    }
    /** Focuses the dropdown item. */
    focus(origin, options) {
        if (this.focusMonitor && origin) {
            this.focusMonitor.focusVia(this.getHostElement(), origin, options);
        }
        else {
            this.getHostElement().focus(options);
        }
        this.focused.next(this);
    }
    /** Returns the host DOM element. */
    getHostElement() {
        return this.elementRef.nativeElement;
    }
    /** Used to set the `tabindex`. */
    getTabIndex() {
        return this.disabled ? '-1' : '0';
    }
    /** Prevents the default element actions if it is disabled. */
    // We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
    // In Ivy the `host` bindings will be merged when this class is extended, whereas in
    // ViewEngine they're overwritten.
    // TODO(crisbeto): we move this back into `host` once Ivy is turned on by default.
    checkDisabled(event) {
        if (this.disabled) {
            event.preventDefault();
            event.stopPropagation();
        }
    }
    /** Emits to the hover stream. */
    // We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
    // In Ivy the `host` bindings will be merged when this class is extended, whereas in
    // ViewEngine they're overwritten.
    // TODO(crisbeto): we move this back into `host` once Ivy is turned on by default.
    handleMouseEnter() {
        this.hovered.next(this);
    }
    /** Gets the label to be used when determining whether the option should be focused. */
    getLabel() {
        const clone = this.getHostElement().cloneNode(true);
        const icons = clone.querySelectorAll('[kbq-icon], .kbq-icon');
        // Strip away icons so they don't show up in the text.
        for (let i = 0; i < icons.length; i++) {
            const icon = icons[i];
            icon.parentNode?.removeChild(icon);
        }
        return clone.textContent?.trim() || '';
    }
    haltDisabledEvents(event) {
        if (this.disabled) {
            event.preventDefault();
            event.stopImmediatePropagation();
            event.stopPropagation();
        }
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqDropdownItem, deps: [{ token: i0.ElementRef }, { token: i1.FocusMonitor }, { token: KBQ_DROPDOWN_PANEL, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
    /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: KbqDropdownItem, selector: "kbq-dropdown-item, [kbq-dropdown-item]", inputs: { disabled: ["disabled", "disabled", booleanAttribute] }, host: { listeners: { "click": "checkDisabled($event)", "mouseenter": "handleMouseEnter()" }, properties: { "class.kbq-dropdown-item_with-icon": "icon", "class.kbq-dropdown-item_highlighted": "highlighted", "class.kbq-disabled": "disabled", "attr.disabled": "disabled || null", "attr.tabindex": "getTabIndex()" }, classAttribute: "kbq-dropdown-item" }, providers: [
            { provide: KBQ_TITLE_TEXT_REF, useExisting: KbqDropdownItem }
        ], queries: [{ propertyName: "icon", first: true, predicate: KbqIcon, descendants: true }], viewQueries: [{ propertyName: "textElement", first: true, predicate: ["kbqTitleText"], descendants: true, static: true }], exportAs: ["kbqDropdownItem"], ngImport: i0, template: "<ng-content select=\"[kbq-icon]\" />\n\n<div #kbqTitleText class=\"kbq-dropdown-item__text\">\n    <ng-content />\n</div>\n\n@if (isNested) {\n    <i kbq-icon=\"kbq-chevron-right-s_16\" class=\"kbq-dropdown-trigger__icon\" [color]=\"componentColors.ContrastFade\"></i>\n}\n\n<div class=\"kbq-dropdown-item-overlay\" (click)=\"haltDisabledEvents($event)\"></div>\n", styles: [".kbq-truncate-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kbq-no-select{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.kbq-dropdown-item{width:100%;border-radius:var(--kbq-dropdown-item-border-radius);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:flex;flex-direction:row;align-items:center;box-sizing:border-box;outline:none;-webkit-tap-highlight-color:transparent;min-height:32px;gap:var(--kbq-size-s);border:var(--kbq-size-3xs) solid transparent;padding:var(--kbq-size-xxs) calc(var(--kbq-size-m) - var(--kbq-size-3xs));text-align:left;align-items:flex-start;text-decoration:none}.kbq-dropdown-item .kbq-list-text{display:flex;flex-direction:column;width:100%;box-sizing:content-box;display:inline-block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kbq-dropdown-item .kbq-list-text>*{margin:0;padding:0;font-weight:400;font-size:inherit}.kbq-dropdown-item .kbq-list-text:empty{display:none}.kbq-dropdown-item .kbq-list-option-caption{padding-top:var(--kbq-size-3xs)}.kbq-dropdown-item:not(.kbq-disabled){cursor:pointer}.kbq-dropdown-item>.kbq-icon:first-child:before{align-self:center;display:flex;height:var(--kbq-size-xl);width:16px;align-items:center}.kbq-dropdown-item .kbq-dropdown-item__caption{padding-top:var(--kbq-size-3xs)}.kbq-dropdown-item__text{display:flex;flex-direction:column;width:100%;box-sizing:content-box;display:inline-block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kbq-dropdown-item__text>*{margin:0;padding:0;font-weight:400;font-size:inherit}.kbq-dropdown-item__text:empty{display:none}.kbq-dropdown-item-overlay{position:absolute;inset:-1px;border-radius:inherit}.kbq-dropdown__group-header{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-direction:row;align-items:center;box-sizing:border-box;min-height:32px;border-left:var(--kbq-size-3xs) solid transparent;border-right:var(--kbq-size-3xs) solid transparent;padding-top:var(--kbq-size-xs);padding-left:calc(var(--kbq-size-m) - var(--kbq-size-3xs));padding-right:calc(var(--kbq-size-m) - var(--kbq-size-3xs));padding-bottom:var(--kbq-size-3xs)}.kbq-dropdown__group-header .kbq-list-text{display:flex;flex-direction:column;width:100%;box-sizing:content-box;display:inline-block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kbq-dropdown__group-header .kbq-list-text>*{margin:0;padding:0;font-weight:400;font-size:inherit}.kbq-dropdown__group-header .kbq-list-text:empty{display:none}.kbq-dropdown__group-header.kbq-dropdown__group-header_small{display:flex;flex-direction:row;align-items:center;box-sizing:border-box;min-height:32px;border-left:var(--kbq-size-3xs) solid transparent;border-right:var(--kbq-size-3xs) solid transparent;padding-top:var(--kbq-size-m);padding-left:calc(var(--kbq-size-m) - var(--kbq-size-3xs));padding-right:calc(var(--kbq-size-m) - var(--kbq-size-3xs));padding-bottom:var(--kbq-size-xxs)}.kbq-dropdown__group-header.kbq-dropdown__group-header_small .kbq-list-text{display:flex;flex-direction:column;width:100%;box-sizing:content-box;display:inline-block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kbq-dropdown__group-header.kbq-dropdown__group-header_small .kbq-list-text>*{margin:0;padding:0;font-weight:400;font-size:inherit}.kbq-dropdown__group-header.kbq-dropdown__group-header_small .kbq-list-text:empty{display:none}\n"], dependencies: [{ kind: "component", type: i2.KbqIcon, selector: "[kbq-icon]", inputs: ["small", "autoColor", "kbq-icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqDropdownItem, decorators: [{
            type: Component,
            args: [{ selector: 'kbq-dropdown-item, [kbq-dropdown-item]', exportAs: 'kbqDropdownItem', host: {
                        class: 'kbq-dropdown-item',
                        '[class.kbq-dropdown-item_with-icon]': 'icon',
                        '[class.kbq-dropdown-item_highlighted]': 'highlighted',
                        '[class.kbq-disabled]': 'disabled',
                        '[attr.disabled]': 'disabled || null',
                        '[attr.tabindex]': 'getTabIndex()'
                    }, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
                        { provide: KBQ_TITLE_TEXT_REF, useExisting: KbqDropdownItem }
                    ], template: "<ng-content select=\"[kbq-icon]\" />\n\n<div #kbqTitleText class=\"kbq-dropdown-item__text\">\n    <ng-content />\n</div>\n\n@if (isNested) {\n    <i kbq-icon=\"kbq-chevron-right-s_16\" class=\"kbq-dropdown-trigger__icon\" [color]=\"componentColors.ContrastFade\"></i>\n}\n\n<div class=\"kbq-dropdown-item-overlay\" (click)=\"haltDisabledEvents($event)\"></div>\n", styles: [".kbq-truncate-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kbq-no-select{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.kbq-dropdown-item{width:100%;border-radius:var(--kbq-dropdown-item-border-radius);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:flex;flex-direction:row;align-items:center;box-sizing:border-box;outline:none;-webkit-tap-highlight-color:transparent;min-height:32px;gap:var(--kbq-size-s);border:var(--kbq-size-3xs) solid transparent;padding:var(--kbq-size-xxs) calc(var(--kbq-size-m) - var(--kbq-size-3xs));text-align:left;align-items:flex-start;text-decoration:none}.kbq-dropdown-item .kbq-list-text{display:flex;flex-direction:column;width:100%;box-sizing:content-box;display:inline-block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kbq-dropdown-item .kbq-list-text>*{margin:0;padding:0;font-weight:400;font-size:inherit}.kbq-dropdown-item .kbq-list-text:empty{display:none}.kbq-dropdown-item .kbq-list-option-caption{padding-top:var(--kbq-size-3xs)}.kbq-dropdown-item:not(.kbq-disabled){cursor:pointer}.kbq-dropdown-item>.kbq-icon:first-child:before{align-self:center;display:flex;height:var(--kbq-size-xl);width:16px;align-items:center}.kbq-dropdown-item .kbq-dropdown-item__caption{padding-top:var(--kbq-size-3xs)}.kbq-dropdown-item__text{display:flex;flex-direction:column;width:100%;box-sizing:content-box;display:inline-block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kbq-dropdown-item__text>*{margin:0;padding:0;font-weight:400;font-size:inherit}.kbq-dropdown-item__text:empty{display:none}.kbq-dropdown-item-overlay{position:absolute;inset:-1px;border-radius:inherit}.kbq-dropdown__group-header{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-direction:row;align-items:center;box-sizing:border-box;min-height:32px;border-left:var(--kbq-size-3xs) solid transparent;border-right:var(--kbq-size-3xs) solid transparent;padding-top:var(--kbq-size-xs);padding-left:calc(var(--kbq-size-m) - var(--kbq-size-3xs));padding-right:calc(var(--kbq-size-m) - var(--kbq-size-3xs));padding-bottom:var(--kbq-size-3xs)}.kbq-dropdown__group-header .kbq-list-text{display:flex;flex-direction:column;width:100%;box-sizing:content-box;display:inline-block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kbq-dropdown__group-header .kbq-list-text>*{margin:0;padding:0;font-weight:400;font-size:inherit}.kbq-dropdown__group-header .kbq-list-text:empty{display:none}.kbq-dropdown__group-header.kbq-dropdown__group-header_small{display:flex;flex-direction:row;align-items:center;box-sizing:border-box;min-height:32px;border-left:var(--kbq-size-3xs) solid transparent;border-right:var(--kbq-size-3xs) solid transparent;padding-top:var(--kbq-size-m);padding-left:calc(var(--kbq-size-m) - var(--kbq-size-3xs));padding-right:calc(var(--kbq-size-m) - var(--kbq-size-3xs));padding-bottom:var(--kbq-size-xxs)}.kbq-dropdown__group-header.kbq-dropdown__group-header_small .kbq-list-text{display:flex;flex-direction:column;width:100%;box-sizing:content-box;display:inline-block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kbq-dropdown__group-header.kbq-dropdown__group-header_small .kbq-list-text>*{margin:0;padding:0;font-weight:400;font-size:inherit}.kbq-dropdown__group-header.kbq-dropdown__group-header_small .kbq-list-text:empty{display:none}\n"] }]
        }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.FocusMonitor }, { type: undefined, decorators: [{
                    type: Inject,
                    args: [KBQ_DROPDOWN_PANEL]
                }, {
                    type: Optional
                }] }], propDecorators: { textElement: [{
                type: ViewChild,
                args: ['kbqTitleText', { static: true }]
            }], icon: [{
                type: ContentChild,
                args: [KbqIcon]
            }], disabled: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], checkDisabled: [{
                type: HostListener,
                args: ['click', ['$event']]
            }], handleMouseEnter: [{
                type: HostListener,
                args: ['mouseenter']
            }] } });

class KbqDropdownStaticContent {
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqDropdownStaticContent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: KbqDropdownStaticContent, isStandalone: true, selector: "[kbqDropdownStaticContent]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqDropdownStaticContent, decorators: [{
            type: Directive,
            args: [{
                    standalone: true,
                    selector: '[kbqDropdownStaticContent]'
                }]
        }] });
class KbqDropdown {
    /** Position of the dropdown in the X axis. */
    get xPosition() {
        return this._xPosition;
    }
    set xPosition(value) {
        if (value !== 'before' && value !== 'after') {
            throwKbqDropdownInvalidPositionX();
        }
        this._xPosition = value;
        this.setPositionClasses();
    }
    /** Position of the dropdown in the Y axis. */
    get yPosition() {
        return this._yPosition;
    }
    set yPosition(value) {
        if (value !== 'above' && value !== 'below') {
            throwKbqDropdownInvalidPositionY();
        }
        this._yPosition = value;
        this.setPositionClasses();
    }
    /** Whether the dropdown should overlap its trigger vertically. */
    get overlapTriggerY() {
        return this._overlapTriggerY;
    }
    set overlapTriggerY(value) {
        this._overlapTriggerY = coerceBooleanProperty(value);
    }
    /** Whether the dropdown should overlap its trigger horizontally. */
    get overlapTriggerX() {
        return this._overlapTriggerX;
    }
    set overlapTriggerX(value) {
        this._overlapTriggerX = coerceBooleanProperty(value);
    }
    /** Whether the dropdown has a backdrop. */
    get hasBackdrop() {
        return this._hasBackdrop;
    }
    set hasBackdrop(value) {
        this._hasBackdrop = coerceBooleanProperty(value);
    }
    /**
     * This method takes classes set on the host kbq-dropdown element and applies them on the
     * dropdown template that displays in the overlay container.  Otherwise, it's difficult
     * to style the containing dropdown from outside the component.
     * @param classes list of class names
     */
    set panelClass(classes) {
        const previousPanelClass = this.previousPanelClass;
        if (previousPanelClass && previousPanelClass.length) {
            previousPanelClass.split(' ').forEach((className) => (this.classList[className] = false));
        }
        this.previousPanelClass = classes;
        if (classes?.length) {
            classes.split(' ').forEach((className) => (this.classList[className] = true));
            this.elementRef.nativeElement.className = '';
        }
    }
    constructor(elementRef, ngZone, defaultOptions) {
        this.elementRef = elementRef;
        this.ngZone = ngZone;
        this.defaultOptions = defaultOptions;
        this.navigationWithWrap = false;
        this._xPosition = this.defaultOptions.xPosition;
        this._yPosition = this.defaultOptions.yPosition;
        this._overlapTriggerX = this.defaultOptions.overlapTriggerX;
        this._overlapTriggerY = this.defaultOptions.overlapTriggerY;
        this._hasBackdrop = this.defaultOptions.hasBackdrop;
        /** Config object to be passed into the dropdown's ngClass */
        this.classList = {};
        /** Current state of the panel animation. */
        this.panelAnimationState = 'void';
        /** Emits whenever an animation on the dropdown completes. */
        this.animationDone = new Subject();
        /** Class to be added to the backdrop element. */
        this.backdropClass = this.defaultOptions.backdropClass;
        /** Event emitted when the dropdown is closed. */
        this.closed = new EventEmitter();
        /** Only the direct descendant menu items. */
        this.directDescendantItems = new QueryList();
        /** Subscription to tab events on the dropdown panel */
        this.tabSubscription = Subscription.EMPTY;
    }
    ngOnInit() {
        this.setPositionClasses();
    }
    ngAfterContentInit() {
        this.updateDirectDescendants();
        this.keyManager = new FocusKeyManager(this.directDescendantItems).withTypeAhead();
        if (this.navigationWithWrap) {
            this.keyManager.withWrap();
        }
        this.tabSubscription = this.keyManager.tabOut.subscribe(() => this.closed.emit('tab'));
        // If a user manually (programmatically) focuses a menu item, we need to reflect that focus
        // change back to the key manager. Note that we don't need to unsubscribe here because focused
        // is internal and we know that it gets completed on destroy.
        this.directDescendantItems.changes
            .pipe(startWith(this.directDescendantItems), switchMap((items) => merge(...items.map((item) => item.focused))))
            .subscribe((focusedItem) => this.keyManager.updateActiveItem(focusedItem));
    }
    ngOnDestroy() {
        this.directDescendantItems.destroy();
        this.tabSubscription.unsubscribe();
        this.closed.complete();
    }
    /** Stream that emits whenever the hovered dropdown item changes. */
    hovered() {
        const itemChanges = this.directDescendantItems.changes;
        return itemChanges.pipe(startWith(this.directDescendantItems), switchMap((items) => merge(...items.map((item) => item.hovered))));
    }
    /** Handle a keyboard event from the dropdown, delegating to the appropriate action. */
    handleKeydown(event) {
        const keyCode = event.keyCode;
        switch (keyCode) {
            case ESCAPE:
                this.closed.emit('keydown');
                break;
            case LEFT_ARROW:
                if (this.parent && this.direction === 'ltr') {
                    this.closed.emit('keydown');
                }
                break;
            case RIGHT_ARROW:
                if (this.parent && this.direction === 'rtl') {
                    this.closed.emit('keydown');
                }
                break;
            default:
                if (keyCode === UP_ARROW || keyCode === DOWN_ARROW) {
                    this.keyManager.setFocusOrigin('keyboard');
                }
                this.keyManager.onKeydown(event);
                return;
        }
        // Don't allow the event to propagate if we've already handled it, or it may
        // end up reaching other overlays that were opened earlier.
        event.stopPropagation();
    }
    /**
     * Focus the first item in the dropdown.
     * @param origin Action from which the focus originated. Used to set the correct styling.
     */
    focusFirstItem(origin = 'program') {
        // When the content is rendered lazily, it takes a bit before the items are inside the DOM.
        if (this.lazyContent) {
            this.ngZone.onStable
                .pipe(take(1))
                .subscribe(() => this.keyManager.setFocusOrigin(origin).setFirstItemActive());
        }
        else {
            this.keyManager.setFocusOrigin(origin).setFirstItemActive();
        }
    }
    /**
     * Resets the active item in the dropdown. This is used when the dropdown is opened, allowing
     * the user to start from the first option when pressing the down arrow.
     */
    resetActiveItem() {
        this.keyManager.activeItem?.resetStyles();
        this.keyManager.setActiveItem(-1);
    }
    /**
     * Adds classes to the dropdown panel based on its position. Can be used by
     * consumers to add specific styling based on the position.
     * @param posX Position of the dropdown along the x axis.
     * @param posY Position of the dropdown along the y axis.
     * @docs-private
     */
    setPositionClasses(posX = this.xPosition, posY = this.yPosition) {
        const classes = this.classList;
        classes['kbq-dropdown-before'] = posX === 'before';
        classes['kbq-dropdown-after'] = posX === 'after';
        classes['kbq-dropdown-above'] = posY === 'above';
        classes['kbq-dropdown-below'] = posY === 'below';
    }
    /** Starts the enter animation. */
    startAnimation() {
        this.panelAnimationState = 'enter';
    }
    /** Resets the panel animation to its initial state. */
    resetAnimation() {
        this.panelAnimationState = 'void';
    }
    /** Callback that is invoked when the panel animation completes. */
    onAnimationDone(event) {
        this.animationDone.next(event);
        this.isAnimating = false;
    }
    onAnimationStart(event) {
        this.isAnimating = true;
        // Scroll the content element to the top as soon as the animation starts. This is necessary,
        // because we move focus to the first item while it's still being animated, which can throw
        // the browser off when it determines the scroll position. Alternatively we can move focus
        // when the animation is done, however moving focus asynchronously will interrupt screen
        // readers which are in the process of reading out the dropdown already. We take the `element`
        // from the `event` since we can't use a `ViewChild` to access the pane.
        if (event.toState === 'enter' && this.keyManager.activeItemIndex === 0) {
            event.element.scrollTop = 0;
        }
    }
    close() {
        const focusOrigin = this.keyManager.getFocusOrigin() === 'keyboard' ? 'keydown' : 'click';
        this.closed.emit(focusOrigin);
    }
    /**
     * Sets up a stream that will keep track of any newly-added menu items and will update the list
     * of direct descendants. We collect the descendants this way, because `items` can include
     * items that are part of child menus, and using a custom way of registering items is unreliable
     * when it comes to maintaining the item order.
     */
    updateDirectDescendants() {
        this.items.changes.pipe(startWith(this.items)).subscribe((items) => {
            this.directDescendantItems.reset(items.filter((item) => item.parentDropdownPanel === this));
            this.directDescendantItems.notifyOnChanges();
        });
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqDropdown, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: KBQ_DROPDOWN_DEFAULT_OPTIONS }], target: i0.ɵɵFactoryTarget.Component }); }
    /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: KbqDropdown, selector: "kbq-dropdown", inputs: { navigationWithWrap: "navigationWithWrap", xPosition: "xPosition", yPosition: "yPosition", overlapTriggerY: "overlapTriggerY", overlapTriggerX: "overlapTriggerX", hasBackdrop: "hasBackdrop", panelClass: ["class", "panelClass"], backdropClass: "backdropClass" }, outputs: { closed: "closed" }, providers: [
            { provide: KBQ_DROPDOWN_PANEL, useExisting: KbqDropdown }
        ], queries: [{ propertyName: "lazyContent", first: true, predicate: KbqDropdownContent, descendants: true }, { propertyName: "items", predicate: KbqDropdownItem, descendants: true }], viewQueries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true }], exportAs: ["kbqDropdown"], ngImport: i0, template: "<ng-template>\n    <div\n        tabindex=\"-1\"\n        class=\"kbq-dropdown__panel\"\n        [class.kbq-dropdown__panel_nested]=\"parent\"\n        [ngClass]=\"classList\"\n        [style.min-width]=\"triggerWidth\"\n        [@transformDropdown]=\"panelAnimationState\"\n        (@transformDropdown.done)=\"onAnimationDone($event)\"\n        (@transformDropdown.start)=\"onAnimationStart($event)\"\n        (click)=\"close()\"\n        (keydown)=\"handleKeydown($event)\"\n    >\n        <div class=\"kbq-dropdown__content\">\n            <ng-content />\n        </div>\n    </div>\n</ng-template>\n\n<ng-content select=\"[kbqDropdownStaticContent]\" />\n", styles: [".kbq-dropdown-trigger.kbq-button{padding-left:calc(10px - var(--kbq-size-border-width));padding-right:calc(10px - var(--kbq-size-border-width))}.kbq-dropdown-trigger.kbq-button .kbq-icon_left{margin-right:var(--kbq-size-xs)}.kbq-dropdown-trigger.kbq-button .kbq-icon_right{margin-left:var(--kbq-size-3xs)}.kbq-dropdown-trigger.kbq-button-icon.kbq-button-icon_right.kbq-button-icon_left .kbq-icon_left{margin-right:0}.kbq-dropdown-trigger.kbq-button-icon.kbq-button-icon_right.kbq-button-icon_left .kbq-icon_right{margin-left:0}.kbq-dropdown-trigger__icon{margin-left:auto;align-self:center}.kbq-dropdown__panel{min-width:var(--kbq-dropdown-size-container-width-min);max-width:var(--kbq-dropdown-size-container-width-max);border-radius:var(--kbq-dropdown-size-container-border-radius);box-sizing:border-box;padding:var(--kbq-size-xxs)}.kbq-dropdown__panel.ng-animating{pointer-events:none}.kbq-dropdown__panel .kbq-dropdown-item{position:relative}.kbq-dropdown__panel .kbq-dropdown-item:before,.kbq-dropdown__panel .kbq-dropdown-item:after{position:absolute;content:\"\";width:var(--kbq-size-xxs);height:calc(100% + var(--kbq-size-3xs) * 2)}.kbq-dropdown__panel .kbq-dropdown-item:before{right:calc(100% + var(--kbq-size-3xs))}.kbq-dropdown__panel .kbq-dropdown-item:after{left:calc(100% + var(--kbq-size-3xs))}.kbq-dropdown__panel .kbq-dropdown-item:before,.kbq-dropdown__panel .kbq-dropdown-item:after{top:calc(-1 * var(--kbq-size-3xs));bottom:calc(-1 * var(--kbq-size-3xs))}.kbq-dropdown__panel .kbq-divider{margin-left:calc(var(--kbq-size-xxs) * -1);margin-right:calc(var(--kbq-size-xxs) * -1)}.kbq-dropdown__content{display:flex;flex-direction:column}.kbq-dropdown__panel{box-shadow:var(--kbq-dropdown-container-shadow);background:var(--kbq-dropdown-container-background)}.kbq-dropdown-item{background:var(--kbq-list-default-container-background);color:var(--kbq-list-default-text-color)}.kbq-dropdown-item .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item){color:var(--kbq-list-default-text-color)}.kbq-dropdown-item .kbq-dropdown-item__caption{color:var(--kbq-dropdown-item-caption-color)}.kbq-dropdown-item.kbq-dropdown-item_highlighted,.kbq-dropdown-item:hover:not(.kbq-disabled){background:var(--kbq-list-states-hover-container-background);color:var(--kbq-list-states-hover-text-color)}.kbq-dropdown-item.kbq-dropdown-item_highlighted .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item),.kbq-dropdown-item:hover:not(.kbq-disabled) .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item){color:var(--kbq-list-states-hover-text-color)}.kbq-dropdown-item.cdk-keyboard-focused{border-color:var(--kbq-list-states-focused-focus-outline-color)}.kbq-dropdown-item.kbq-selected{background:var(--kbq-list-states-selected-container-background);color:var(--kbq-list-states-selected-text-color)}.kbq-dropdown-item.kbq-selected .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item){color:var(--kbq-list-states-selected-text-color)}.kbq-dropdown-item.kbq-selected:hover:not(.kbq-disabled){background:var(--kbq-list-states-selected-hover-container-background);color:var(--kbq-list-states-selected-hover-text-color)}.kbq-dropdown-item.kbq-selected:hover:not(.kbq-disabled) .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item){color:var(--kbq-list-states-selected-hover-text-color)}.kbq-dropdown-item.kbq-disabled{background:var(--kbq-list-states-disabled-container-background);color:var(--kbq-list-states-disabled-text-color)}.kbq-dropdown-item.kbq-disabled .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item){color:var(--kbq-list-states-disabled-text-color)}.kbq-dropdown-item:is(.kbq-selected,.cdk-keyboard-focused):has(+:is(.kbq-selected,.cdk-keyboard-focused)){border-bottom-left-radius:0;border-bottom-right-radius:0}.kbq-dropdown-item:is(.kbq-selected,.cdk-keyboard-focused)+:is(.kbq-selected,.cdk-keyboard-focused){border-top-left-radius:0;border-top-right-radius:0}.kbq-dropdown__group-header.kbq-dropdown__group-header_small{color:var(--kbq-foreground-contrast-secondary)}.kbq-dropdown-item-overlay{background:transparent}.kbq-dropdown-item,.kbq-dropdown__content{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}.kbq-dropdown-item .kbq-dropdown-item__caption,.kbq-dropdown__content .kbq-dropdown-item__caption{font-size:var(--kbq-typography-text-compact-font-size);font-style:var(--kbq-typography-text-compact-font-style);font-weight:var(--kbq-typography-text-compact-font-weight);line-height:var(--kbq-typography-text-compact-line-height);font-family:var(--kbq-typography-text-compact-font-family);text-transform:var(--kbq-typography-text-compact-text-transform);font-feature-settings:var(--kbq-typography-text-compact-font-feature-settings);letter-spacing:var(--kbq-typography-text-compact-letter-spacing)}.kbq-dropdown__group-header{font-size:var(--kbq-typography-big-strong-font-size);font-style:var(--kbq-typography-big-strong-font-style);font-weight:var(--kbq-typography-big-strong-font-weight);line-height:var(--kbq-typography-big-strong-line-height);font-family:var(--kbq-typography-big-strong-font-family);text-transform:var(--kbq-typography-big-strong-text-transform);font-feature-settings:var(--kbq-typography-big-strong-font-feature-settings);letter-spacing:var(--kbq-typography-big-strong-letter-spacing)}.kbq-dropdown__group-header.kbq-dropdown__group-header_small{font-size:var(--kbq-typography-caps-compact-strong-font-size);font-style:var(--kbq-typography-caps-compact-strong-font-style);font-weight:var(--kbq-typography-caps-compact-strong-font-weight);line-height:var(--kbq-typography-caps-compact-strong-line-height);font-family:var(--kbq-typography-caps-compact-strong-font-family);text-transform:var(--kbq-typography-caps-compact-strong-text-transform);font-feature-settings:var(--kbq-typography-caps-compact-strong-font-feature-settings);letter-spacing:var(--kbq-typography-caps-compact-strong-letter-spacing)}\n", ".kbq-list,.kbq-list-selection{--kbq-list-size-container-padding-left: var(--kbq-size-m);--kbq-list-size-container-padding-right: var(--kbq-size-m);--kbq-list-size-container-padding-vertical: var(--kbq-size-xs);--kbq-list-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-list-size-container-content-gap-vertical: var(--kbq-size-3xs);--kbq-list-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-list-size-header-padding-top: var(--kbq-size-s);--kbq-list-size-header-padding-bottom: var(--kbq-size-xxs);--kbq-list-size-header-padding-horizontal: var(--kbq-size-m);--kbq-list-size-subheading-padding-top: var(--kbq-size-m);--kbq-list-size-subheading-padding-bottom: var(--kbq-size-xxs);--kbq-list-size-subheading-padding-horizontal: var(--kbq-size-m);--kbq-list-default-container-background: transparent;--kbq-list-default-text-color: var(--kbq-foreground-contrast);--kbq-list-default-icon-color: var(--kbq-icon-contrast);--kbq-list-default-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-list-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-list-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-list-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-list-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-list-states-hover-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-states-selected-container-background: var(--kbq-background-theme-less);--kbq-list-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-list-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-list-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-list-states-selected-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-list-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-list-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-list-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-list-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-list-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-list-states-selected-hover-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-list-states-disabled-container-background: transparent;--kbq-list-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-list-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-list-states-disabled-icon-button-color: var(--kbq-states-icon-disabled);--kbq-list-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}.kbq-dropdown__panel{--kbq-dropdown-size-container-width-min: var(--kbq-size-7xl);--kbq-dropdown-size-container-width-max: 640px;--kbq-dropdown-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-dropdown-size-container-border-radius: var(--kbq-size-s);--kbq-dropdown-container-background: var(--kbq-background-card);--kbq-dropdown-container-shadow: var(--kbq-shadow-popup);--kbq-dropdown-item-border-radius: var(--kbq-size-xs);--kbq-dropdown-item-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-list-default-container-background: transparent;--kbq-list-default-text-color: var(--kbq-foreground-contrast);--kbq-list-default-icon-color: var(--kbq-icon-contrast);--kbq-list-default-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-list-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-list-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-list-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-list-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-list-states-hover-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-states-selected-container-background: var(--kbq-background-theme-less);--kbq-list-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-list-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-list-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-list-states-selected-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-list-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-list-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-list-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-list-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-list-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-list-states-selected-hover-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-list-states-disabled-container-background: transparent;--kbq-list-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-list-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-list-states-disabled-icon-button-color: var(--kbq-states-icon-disabled);--kbq-list-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], animations: [
            kbqDropdownAnimations.transformDropdown,
            kbqDropdownAnimations.fadeInItems
        ], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqDropdown, decorators: [{
            type: Component,
            args: [{ selector: 'kbq-dropdown', exportAs: 'kbqDropdown', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, animations: [
                        kbqDropdownAnimations.transformDropdown,
                        kbqDropdownAnimations.fadeInItems
                    ], providers: [
                        { provide: KBQ_DROPDOWN_PANEL, useExisting: KbqDropdown }
                    ], template: "<ng-template>\n    <div\n        tabindex=\"-1\"\n        class=\"kbq-dropdown__panel\"\n        [class.kbq-dropdown__panel_nested]=\"parent\"\n        [ngClass]=\"classList\"\n        [style.min-width]=\"triggerWidth\"\n        [@transformDropdown]=\"panelAnimationState\"\n        (@transformDropdown.done)=\"onAnimationDone($event)\"\n        (@transformDropdown.start)=\"onAnimationStart($event)\"\n        (click)=\"close()\"\n        (keydown)=\"handleKeydown($event)\"\n    >\n        <div class=\"kbq-dropdown__content\">\n            <ng-content />\n        </div>\n    </div>\n</ng-template>\n\n<ng-content select=\"[kbqDropdownStaticContent]\" />\n", styles: [".kbq-dropdown-trigger.kbq-button{padding-left:calc(10px - var(--kbq-size-border-width));padding-right:calc(10px - var(--kbq-size-border-width))}.kbq-dropdown-trigger.kbq-button .kbq-icon_left{margin-right:var(--kbq-size-xs)}.kbq-dropdown-trigger.kbq-button .kbq-icon_right{margin-left:var(--kbq-size-3xs)}.kbq-dropdown-trigger.kbq-button-icon.kbq-button-icon_right.kbq-button-icon_left .kbq-icon_left{margin-right:0}.kbq-dropdown-trigger.kbq-button-icon.kbq-button-icon_right.kbq-button-icon_left .kbq-icon_right{margin-left:0}.kbq-dropdown-trigger__icon{margin-left:auto;align-self:center}.kbq-dropdown__panel{min-width:var(--kbq-dropdown-size-container-width-min);max-width:var(--kbq-dropdown-size-container-width-max);border-radius:var(--kbq-dropdown-size-container-border-radius);box-sizing:border-box;padding:var(--kbq-size-xxs)}.kbq-dropdown__panel.ng-animating{pointer-events:none}.kbq-dropdown__panel .kbq-dropdown-item{position:relative}.kbq-dropdown__panel .kbq-dropdown-item:before,.kbq-dropdown__panel .kbq-dropdown-item:after{position:absolute;content:\"\";width:var(--kbq-size-xxs);height:calc(100% + var(--kbq-size-3xs) * 2)}.kbq-dropdown__panel .kbq-dropdown-item:before{right:calc(100% + var(--kbq-size-3xs))}.kbq-dropdown__panel .kbq-dropdown-item:after{left:calc(100% + var(--kbq-size-3xs))}.kbq-dropdown__panel .kbq-dropdown-item:before,.kbq-dropdown__panel .kbq-dropdown-item:after{top:calc(-1 * var(--kbq-size-3xs));bottom:calc(-1 * var(--kbq-size-3xs))}.kbq-dropdown__panel .kbq-divider{margin-left:calc(var(--kbq-size-xxs) * -1);margin-right:calc(var(--kbq-size-xxs) * -1)}.kbq-dropdown__content{display:flex;flex-direction:column}.kbq-dropdown__panel{box-shadow:var(--kbq-dropdown-container-shadow);background:var(--kbq-dropdown-container-background)}.kbq-dropdown-item{background:var(--kbq-list-default-container-background);color:var(--kbq-list-default-text-color)}.kbq-dropdown-item .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item){color:var(--kbq-list-default-text-color)}.kbq-dropdown-item .kbq-dropdown-item__caption{color:var(--kbq-dropdown-item-caption-color)}.kbq-dropdown-item.kbq-dropdown-item_highlighted,.kbq-dropdown-item:hover:not(.kbq-disabled){background:var(--kbq-list-states-hover-container-background);color:var(--kbq-list-states-hover-text-color)}.kbq-dropdown-item.kbq-dropdown-item_highlighted .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item),.kbq-dropdown-item:hover:not(.kbq-disabled) .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item){color:var(--kbq-list-states-hover-text-color)}.kbq-dropdown-item.cdk-keyboard-focused{border-color:var(--kbq-list-states-focused-focus-outline-color)}.kbq-dropdown-item.kbq-selected{background:var(--kbq-list-states-selected-container-background);color:var(--kbq-list-states-selected-text-color)}.kbq-dropdown-item.kbq-selected .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item){color:var(--kbq-list-states-selected-text-color)}.kbq-dropdown-item.kbq-selected:hover:not(.kbq-disabled){background:var(--kbq-list-states-selected-hover-container-background);color:var(--kbq-list-states-selected-hover-text-color)}.kbq-dropdown-item.kbq-selected:hover:not(.kbq-disabled) .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item){color:var(--kbq-list-states-selected-hover-text-color)}.kbq-dropdown-item.kbq-disabled{background:var(--kbq-list-states-disabled-container-background);color:var(--kbq-list-states-disabled-text-color)}.kbq-dropdown-item.kbq-disabled .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item){color:var(--kbq-list-states-disabled-text-color)}.kbq-dropdown-item:is(.kbq-selected,.cdk-keyboard-focused):has(+:is(.kbq-selected,.cdk-keyboard-focused)){border-bottom-left-radius:0;border-bottom-right-radius:0}.kbq-dropdown-item:is(.kbq-selected,.cdk-keyboard-focused)+:is(.kbq-selected,.cdk-keyboard-focused){border-top-left-radius:0;border-top-right-radius:0}.kbq-dropdown__group-header.kbq-dropdown__group-header_small{color:var(--kbq-foreground-contrast-secondary)}.kbq-dropdown-item-overlay{background:transparent}.kbq-dropdown-item,.kbq-dropdown__content{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}.kbq-dropdown-item .kbq-dropdown-item__caption,.kbq-dropdown__content .kbq-dropdown-item__caption{font-size:var(--kbq-typography-text-compact-font-size);font-style:var(--kbq-typography-text-compact-font-style);font-weight:var(--kbq-typography-text-compact-font-weight);line-height:var(--kbq-typography-text-compact-line-height);font-family:var(--kbq-typography-text-compact-font-family);text-transform:var(--kbq-typography-text-compact-text-transform);font-feature-settings:var(--kbq-typography-text-compact-font-feature-settings);letter-spacing:var(--kbq-typography-text-compact-letter-spacing)}.kbq-dropdown__group-header{font-size:var(--kbq-typography-big-strong-font-size);font-style:var(--kbq-typography-big-strong-font-style);font-weight:var(--kbq-typography-big-strong-font-weight);line-height:var(--kbq-typography-big-strong-line-height);font-family:var(--kbq-typography-big-strong-font-family);text-transform:var(--kbq-typography-big-strong-text-transform);font-feature-settings:var(--kbq-typography-big-strong-font-feature-settings);letter-spacing:var(--kbq-typography-big-strong-letter-spacing)}.kbq-dropdown__group-header.kbq-dropdown__group-header_small{font-size:var(--kbq-typography-caps-compact-strong-font-size);font-style:var(--kbq-typography-caps-compact-strong-font-style);font-weight:var(--kbq-typography-caps-compact-strong-font-weight);line-height:var(--kbq-typography-caps-compact-strong-line-height);font-family:var(--kbq-typography-caps-compact-strong-font-family);text-transform:var(--kbq-typography-caps-compact-strong-text-transform);font-feature-settings:var(--kbq-typography-caps-compact-strong-font-feature-settings);letter-spacing:var(--kbq-typography-caps-compact-strong-letter-spacing)}\n", ".kbq-list,.kbq-list-selection{--kbq-list-size-container-padding-left: var(--kbq-size-m);--kbq-list-size-container-padding-right: var(--kbq-size-m);--kbq-list-size-container-padding-vertical: var(--kbq-size-xs);--kbq-list-size-container-content-gap-horizontal: var(--kbq-size-s);--kbq-list-size-container-content-gap-vertical: var(--kbq-size-3xs);--kbq-list-size-container-focus-outline-width: var(--kbq-size-3xs);--kbq-list-size-header-padding-top: var(--kbq-size-s);--kbq-list-size-header-padding-bottom: var(--kbq-size-xxs);--kbq-list-size-header-padding-horizontal: var(--kbq-size-m);--kbq-list-size-subheading-padding-top: var(--kbq-size-m);--kbq-list-size-subheading-padding-bottom: var(--kbq-size-xxs);--kbq-list-size-subheading-padding-horizontal: var(--kbq-size-m);--kbq-list-default-container-background: transparent;--kbq-list-default-text-color: var(--kbq-foreground-contrast);--kbq-list-default-icon-color: var(--kbq-icon-contrast);--kbq-list-default-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-list-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-list-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-list-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-list-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-list-states-hover-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-states-selected-container-background: var(--kbq-background-theme-less);--kbq-list-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-list-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-list-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-list-states-selected-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-list-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-list-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-list-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-list-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-list-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-list-states-selected-hover-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-list-states-disabled-container-background: transparent;--kbq-list-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-list-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-list-states-disabled-icon-button-color: var(--kbq-states-icon-disabled);--kbq-list-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}.kbq-dropdown__panel{--kbq-dropdown-size-container-width-min: var(--kbq-size-7xl);--kbq-dropdown-size-container-width-max: 640px;--kbq-dropdown-size-container-padding-vertical: var(--kbq-size-xxs);--kbq-dropdown-size-container-border-radius: var(--kbq-size-s);--kbq-dropdown-container-background: var(--kbq-background-card);--kbq-dropdown-container-shadow: var(--kbq-shadow-popup);--kbq-dropdown-item-border-radius: var(--kbq-size-xs);--kbq-dropdown-item-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-list-default-container-background: transparent;--kbq-list-default-text-color: var(--kbq-foreground-contrast);--kbq-list-default-icon-color: var(--kbq-icon-contrast);--kbq-list-default-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-default-caption-color: var(--kbq-foreground-contrast-secondary);--kbq-list-states-hover-container-background: var(--kbq-states-background-transparent-hover);--kbq-list-states-active-container-background: var(--kbq-states-background-transparent-active);--kbq-list-states-hover-text-color: var(--kbq-foreground-contrast);--kbq-list-states-hover-icon-color: var(--kbq-icon-contrast);--kbq-list-states-hover-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-states-selected-container-background: var(--kbq-background-theme-less);--kbq-list-multiple-states-selected-container-background: var(--kbq-background-contrast-less);--kbq-list-states-selected-text-color: var(--kbq-foreground-contrast);--kbq-list-states-selected-icon-color: var(--kbq-icon-contrast);--kbq-list-states-selected-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-states-selected-hover-container-background: var(--kbq-states-background-theme-less-hover);--kbq-list-multiple-states-selected-hover-container-background: var(--kbq-states-background-contrast-less-hover);--kbq-list-states-selected-active-container-background: var(--kbq-states-background-theme-less-active);--kbq-list-multiple-states-selected-active-container-background: var(--kbq-states-background-contrast-less-active);--kbq-list-states-selected-hover-text-color: var(--kbq-foreground-contrast);--kbq-list-states-selected-hover-icon-color: var(--kbq-icon-contrast);--kbq-list-states-selected-hover-icon-button-color: var(--kbq-icon-contrast-fade);--kbq-list-states-focused-focus-outline-color: var(--kbq-states-line-focus-theme);--kbq-list-states-disabled-container-background: transparent;--kbq-list-states-disabled-text-color: var(--kbq-states-foreground-disabled);--kbq-list-states-disabled-icon-color: var(--kbq-states-icon-disabled);--kbq-list-states-disabled-icon-button-color: var(--kbq-states-icon-disabled);--kbq-list-states-disabled-caption-color: var(--kbq-states-foreground-disabled)}\n"] }]
        }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: undefined, decorators: [{
                    type: Inject,
                    args: [KBQ_DROPDOWN_DEFAULT_OPTIONS]
                }] }], propDecorators: { navigationWithWrap: [{
                type: Input
            }], xPosition: [{
                type: Input
            }], yPosition: [{
                type: Input
            }], overlapTriggerY: [{
                type: Input
            }], overlapTriggerX: [{
                type: Input
            }], hasBackdrop: [{
                type: Input
            }], panelClass: [{
                type: Input,
                args: ['class']
            }], backdropClass: [{
                type: Input
            }], templateRef: [{
                type: ViewChild,
                args: [TemplateRef, { static: false }]
            }], items: [{
                type: ContentChildren,
                args: [KbqDropdownItem, { descendants: true }]
            }], lazyContent: [{
                type: ContentChild,
                args: [KbqDropdownContent, { static: false }]
            }], closed: [{
                type: Output
            }] } });

/** Injection token that determines the scroll handling while the dropdown is open. */
const KBQ_DROPDOWN_SCROLL_STRATEGY = new InjectionToken('kbq-dropdown-scroll-strategy');
/** @docs-private */
function KBQ_DROPDOWN_SCROLL_STRATEGY_FACTORY(overlay) {
    return () => overlay.scrollStrategies.reposition();
}
/** @docs-private */
const KBQ_DROPDOWN_SCROLL_STRATEGY_FACTORY_PROVIDER = {
    provide: KBQ_DROPDOWN_SCROLL_STRATEGY,
    deps: [Overlay],
    useFactory: KBQ_DROPDOWN_SCROLL_STRATEGY_FACTORY
};
/** Default top padding of the nested dropdown panel. */
const NESTED_PANEL_TOP_PADDING = 4;
const NESTED_PANEL_LEFT_PADDING = 8;
/** Options for binding a passive event listener. */
const passiveEventListenerOptions = normalizePassiveListenerOptions({ passive: true });
/**
 * This directive is intended to be used in conjunction with an kbq-dropdown tag.  It is
 * responsible for toggling the display of the provided dropdown instance.
 */
class KbqDropdownTrigger {
    /** References the dropdown instance that the trigger is associated with. */
    get dropdown() {
        return this._dropdown;
    }
    set dropdown(dropdown) {
        if (dropdown === this._dropdown) {
            return;
        }
        this._dropdown = dropdown;
        this.closeSubscription.unsubscribe();
        if (dropdown) {
            this.closeSubscription = dropdown.closed.asObservable().subscribe((reason) => {
                this.destroy(reason);
                // If a click closed the dropdown, we should close the entire chain of nested dropdowns.
                if (['click', 'tab'].includes(reason) && this.parent) {
                    this.parent.closed.emit(reason);
                }
            });
        }
    }
    /** The text direction of the containing app. */
    get dir() {
        return this._dir?.value === 'rtl' ? 'rtl' : 'ltr';
    }
    /** Whether the dropdown is open. */
    get opened() {
        return this._opened;
    }
    constructor(overlay, elementRef, viewContainerRef, scrollStrategy, parent, dropdownItemInstance, _dir, changeDetectorRef, focusMonitor) {
        this.overlay = overlay;
        this.elementRef = elementRef;
        this.viewContainerRef = viewContainerRef;
        this.scrollStrategy = scrollStrategy;
        this.parent = parent;
        this.dropdownItemInstance = dropdownItemInstance;
        this._dir = _dir;
        this.changeDetectorRef = changeDetectorRef;
        this.focusMonitor = focusMonitor;
        this.isBrowser = inject(Platform).isBrowser;
        this.window = inject(KBQ_WINDOW);
        this.openByArrowDown = true;
        /**
         * Whether focus should be restored when the menu is closed.
         * Note that disabling this option can have accessibility implications
         * and it's up to you to manage focus, if you decide to turn it off.
         */
        this.restoreFocus = true;
        /** Event emitted when the associated dropdown is opened. */
        this.dropdownOpened = new EventEmitter();
        /** Event emitted when the associated dropdown is closed. */
        this.dropdownClosed = new EventEmitter();
        this._opened = false;
        this.overlayRef = null;
        this.closeSubscription = Subscription.EMPTY;
        this.hoverSubscription = Subscription.EMPTY;
        /**
         * Handles touch start events on the trigger.
         * Needs to be an arrow function so we can easily use addEventListener and removeEventListener.
         */
        this.handleTouchStart = () => (this.openedBy = 'touch');
        elementRef.nativeElement.addEventListener('touchstart', this.handleTouchStart, passiveEventListenerOptions);
        if (dropdownItemInstance) {
            dropdownItemInstance.isNested = this.isNested();
        }
    }
    ngAfterContentInit() {
        this.check();
        this.handleHover();
    }
    ngOnDestroy() {
        if (this.overlayRef) {
            this.overlayRef.dispose();
            this.overlayRef = null;
        }
        this.elementRef.nativeElement.removeEventListener('touchstart', this.handleTouchStart, passiveEventListenerOptions);
        this.cleanUpSubscriptions();
    }
    /** Whether the dropdown triggers a nested dropdown or a top-level one. */
    isNested() {
        return !!(this.dropdownItemInstance && this.parent);
    }
    /** Toggles the dropdown between the open and closed states. */
    toggle() {
        return this._opened ? this.close() : this.open();
    }
    /** Opens the dropdown. */
    open() {
        if (this._opened) {
            return;
        }
        this.check();
        const overlayRef = this.createOverlay();
        const overlayConfig = overlayRef.getConfig();
        this.setPosition(overlayConfig.positionStrategy);
        overlayConfig.hasBackdrop = this.dropdown.hasBackdrop ? !this.isNested() : this.dropdown.hasBackdrop;
        overlayRef.attach(this.getPortal());
        if (this.dropdown.lazyContent) {
            this.dropdown.lazyContent.detach();
            this.dropdown.lazyContent.attach(this.data);
        }
        this.closeSubscription = this.closingActions().subscribe(() => this.close());
        this.init();
        if (this.dropdown instanceof KbqDropdown) {
            this.dropdown.startAnimation();
        }
    }
    /** Closes the dropdown. */
    close() {
        this.dropdown.closed.emit();
    }
    /**
     * Focuses the dropdown trigger.
     */
    focus(origin, options) {
        if (this.focusMonitor && origin) {
            this.focusMonitor.focusVia(this.elementRef.nativeElement, origin, options);
        }
        else {
            this.elementRef.nativeElement.focus();
        }
    }
    /** Handles mouse presses on the trigger. */
    handleMousedown(event) {
        // Since right or middle button clicks won't trigger the `click` event,
        // we shouldn't consider the dropdown as opened by mouse in those cases.
        this.openedBy = event.button === 0 ? 'mouse' : undefined;
        // Since clicking on the trigger won't close the dropdown if it opens a nested dropdown,
        // we should prevent focus from moving onto it via click to avoid the
        // highlight from lingering on the dropdown item.
        if (this.isNested()) {
            event.preventDefault();
        }
    }
    /** Handles key presses on the trigger. */
    handleKeydown(event) {
        const keyCode = event.keyCode;
        if (keyCode === ENTER || keyCode === SPACE) {
            this.openedBy = 'keyboard';
            event.preventDefault();
            if (this.isNested()) {
                // Stop event propagation to avoid closing the parent dropdown.
                event.stopPropagation();
                this.open();
            }
            else {
                this.toggle();
            }
        }
        if ((this.isNested() &&
            ((keyCode === RIGHT_ARROW && this.dir === 'ltr') || (keyCode === LEFT_ARROW && this.dir === 'rtl'))) ||
            (!this.isNested() && keyCode === DOWN_ARROW$1 && this.openByArrowDown)) {
            event.preventDefault();
            this.openedBy = 'keyboard';
            this.open();
        }
    }
    /** Handles click events on the trigger. */
    handleClick(event) {
        if (this.isNested()) {
            // Stop event propagation to avoid closing the parent dropdown.
            event.stopPropagation();
            this.open();
        }
        else {
            this.toggle();
        }
    }
    /** Closes the dropdown and does the necessary cleanup. */
    destroy(reason) {
        if (!this.overlayRef || !this.opened) {
            return;
        }
        this.lastDestroyReason = reason;
        this.dropdown.resetActiveItem();
        this.closeSubscription.unsubscribe();
        this.overlayRef.detach();
        if (this.restoreFocus && (reason === 'keydown' || !this.openedBy || !this.isNested())) {
            this.focus(this.openedBy);
        }
        this.openedBy = undefined;
        if (this.dropdown instanceof KbqDropdown) {
            this.dropdown.resetAnimation();
            const animationSubscription = this.dropdown.animationDone.pipe(filter((event) => event.toState === 'void'), take(1));
            if (this.dropdown.lazyContent) {
                // Wait for the exit animation to finish before detaching the content.
                animationSubscription
                    .pipe(
                // Interrupt if the content got re-attached.
                takeUntil(this.dropdown.lazyContent.attached))
                    .subscribe({
                    next: () => this.dropdown.lazyContent.detach(),
                    // No matter whether the content got re-attached, reset the this.dropdown.
                    complete: () => this.setIsOpened(false)
                });
            }
            else {
                animationSubscription.subscribe(() => this.setIsOpened(false));
            }
        }
        else {
            this.setIsOpened(false);
            if (this.dropdown.lazyContent) {
                this.dropdown.lazyContent.detach();
            }
        }
    }
    /**
     * This method sets the dropdown state to open and focuses the first item if
     * the dropdown was opened via the keyboard.
     */
    init() {
        this.dropdown.parent = this.isNested() ? this.parent : undefined;
        this.dropdown.direction = this.dir;
        // reset submenu items since they can be initialized as children of root menu
        if (this.parent && !this.dropdown.items.length) {
            this.dropdown.items.reset(Array.from(this.parent.items));
            this.dropdown.items.notifyOnChanges();
        }
        const isVerticalTrigger = this.dropdown.overlapTriggerY && !this.dropdown.overlapTriggerX;
        if (!this.dropdown.parent && !isVerticalTrigger) {
            this.dropdown.triggerWidth = this.dropdown.triggerWidth ?? this.getWidth();
        }
        this.dropdown.focusFirstItem(this.openedBy || 'program');
        this.setIsOpened(true);
    }
    // set state rather than toggle to support triggers sharing a dropdown
    setIsOpened(isOpen) {
        if (isOpen !== this._opened) {
            this.changeDetectorRef.markForCheck();
        }
        this._opened = isOpen;
        this._opened ? this.dropdownOpened.emit() : this.dropdownClosed.emit();
        if (this.isNested()) {
            this.dropdownItemInstance.highlighted = isOpen;
        }
    }
    /**
     * This method checks that a valid instance of KbqDropdown has been passed into
     * kbqDropdownTriggerFor. If not, an exception is thrown.
     */
    check() {
        if (!this.dropdown) {
            throwKbqDropdownMissingError();
        }
    }
    /**
     * This method creates the overlay from the provided dropdown's template and saves its
     * OverlayRef so that it can be attached to the DOM when open is called.
     */
    createOverlay() {
        if (!this.overlayRef) {
            const config = this.getOverlayConfig();
            this.subscribeToPositions(config.positionStrategy);
            this.overlayRef = this.overlay.create(config);
            // Consume the `keydownEvents` in order to prevent them from going to another overlay.
            // Ideally we'd also have our keyboard event logic in here, however doing so will
            // break anybody that may have implemented the `KbqDropdownPanel` themselves.
            this.overlayRef.keydownEvents().subscribe();
        }
        return this.overlayRef;
    }
    /**
     * This method builds the configuration object needed to create the overlay, the OverlayState.
     * @returns OverlayConfig
     */
    getOverlayConfig() {
        return new OverlayConfig({
            positionStrategy: this.overlay
                .position()
                .flexibleConnectedTo(this.elementRef)
                .withLockedPosition()
                .withTransformOriginOn('.kbq-dropdown__panel'),
            backdropClass: this.dropdown.backdropClass || 'cdk-overlay-transparent-backdrop',
            scrollStrategy: this.scrollStrategy(),
            direction: this.dir
        });
    }
    /**
     * Listens to changes in the position of the overlay and sets the correct classes
     * on the dropdown based on the new position. This ensures the animation origin is always
     * correct, even if a fallback position is used for the overlay.
     */
    subscribeToPositions(position) {
        if (this.dropdown.setPositionClasses) {
            position.positionChanges.subscribe((change) => {
                const posX = change.connectionPair.overlayX === 'start' ? 'after' : 'before';
                const posY = change.connectionPair.overlayY === 'top' ? 'below' : 'above';
                this.dropdown.setPositionClasses(posX, posY);
            });
        }
    }
    /**
     * Sets the appropriate positions on a position strategy
     * so the overlay connects with the trigger correctly.
     * @param positionStrategy Strategy whose position to update.
     */
    setPosition(positionStrategy) {
        let [originX, originFallbackX, overlayX, overlayFallbackX] = this.dropdown.xPosition === 'before' ? ['end', 'start', 'end', 'start'] : ['start', 'end', 'start', 'end'];
        // eslint-disable-next-line prefer-const
        let [overlayY, overlayFallbackY, originY, originFallbackY] = this.dropdown.yPosition === 'above'
            ? ['bottom', 'top', 'bottom', 'top']
            : ['top', 'bottom', 'top', 'bottom'];
        let offsetY = 0;
        let offsetX = 0;
        if (this.isNested()) {
            // When the dropdown is nested, it should always align itself
            // to the edges of the trigger, instead of overlapping it.
            overlayFallbackX = originX = this.dropdown.xPosition === 'before' ? 'start' : 'end';
            originFallbackX = overlayX = originX === 'end' ? 'start' : 'end';
            offsetY = overlayY === 'bottom' ? NESTED_PANEL_TOP_PADDING : -NESTED_PANEL_TOP_PADDING;
            offsetX = NESTED_PANEL_LEFT_PADDING;
        }
        else {
            if (!this.dropdown.overlapTriggerY) {
                offsetY = defaultOffsetY;
                originY = overlayY === 'top' ? 'bottom' : 'top';
                originFallbackY = overlayFallbackY === 'top' ? 'bottom' : 'top';
            }
            if (!this.dropdown.overlapTriggerX) {
                overlayFallbackX = originX = this.dropdown.xPosition === 'before' ? 'start' : 'end';
                originFallbackX = overlayX = originX === 'end' ? 'start' : 'end';
            }
        }
        positionStrategy.withPositions([
            {
                originX,
                originY,
                overlayX,
                overlayY,
                offsetY: this.offsetY ?? offsetY,
                offsetX: this.offsetX ?? -offsetX
            },
            {
                originX: originFallbackX,
                originY,
                overlayX: overlayFallbackX,
                overlayY,
                offsetY: this.offsetY ?? offsetY,
                offsetX: this.offsetX ?? offsetX
            },
            {
                originX,
                originY: originFallbackY,
                overlayX,
                overlayY: overlayFallbackY,
                offsetY: this.offsetY ?? -offsetY,
                offsetX: this.offsetX ?? -offsetX
            },
            {
                originX: originFallbackX,
                originY: originFallbackY,
                overlayX: overlayFallbackX,
                overlayY: overlayFallbackY,
                offsetY: this.offsetY ?? -offsetY,
                offsetX: this.offsetX ?? -offsetX
            }
        ]);
    }
    /** Cleans up the active subscriptions. */
    cleanUpSubscriptions() {
        this.closeSubscription.unsubscribe();
        this.hoverSubscription.unsubscribe();
    }
    /** Returns a stream that emits whenever an action that should close the dropdown occurs. */
    closingActions() {
        const backdrop = this.overlayRef.backdropClick();
        const outsidePointerEvents = this.overlayRef.outsidePointerEvents();
        const detachments = this.overlayRef.detachments();
        const parentClose = this.parent ? this.parent.closed : of();
        const hover = this.parent
            ? this.parent.hovered().pipe(filter((active) => active !== this.dropdownItemInstance), filter(() => this._opened))
            : of();
        return merge(backdrop, outsidePointerEvents, parentClose, hover, detachments);
    }
    /** Handles the cases where the user hovers over the trigger. */
    handleHover() {
        // Subscribe to changes in the hovered item in order to toggle the panel.
        if (!this.isNested()) {
            return;
        }
        this.hoverSubscription = this.parent
            .hovered()
            // Since we might have multiple competing triggers for the same dropdown (e.g. a nested dropdown
            // with different data and triggers), we have to delay it by a tick to ensure that
            // it won't be closed immediately after it is opened.
            .pipe(filter((active) => active === this.dropdownItemInstance && !active.disabled), delay(0, asapScheduler))
            .subscribe(() => {
            this.openedBy = 'mouse';
            // If the same dropdown is used between multiple triggers, it might still be animating
            // while the new trigger tries to re-open it. Wait for the animation to finish
            // before doing so. Also interrupt if the user moves to another item.
            if (this.dropdown instanceof KbqDropdown && this.dropdown.isAnimating) {
                // We need the `delay(0)` here in order to avoid
                // 'changed after checked' errors in some cases. See #12194.
                this.dropdown.animationDone
                    .pipe(take(1), delay(0, asapScheduler), takeUntil(this.parent.hovered()))
                    // eslint-disable-next-line rxjs/no-nested-subscribe
                    .subscribe(() => this.open());
            }
            else {
                this.open();
            }
        });
    }
    /** Gets the portal that should be attached to the overlay. */
    getPortal() {
        // Note that we can avoid this check by keeping the portal on the dropdown panel.
        // While it would be cleaner, we'd have to introduce another required method on
        // `KbqDropdownPanel`, making it harder to consume.
        if (!this.portal || this.portal.templateRef !== this.dropdown.templateRef) {
            this.portal = new TemplatePortal(this.dropdown.templateRef, this.viewContainerRef);
        }
        return this.portal;
    }
    getWidth() {
        if (!this.isBrowser)
            return '';
        const nativeElement = this.elementRef.nativeElement;
        const { width, borderRightWidth, borderLeftWidth } = this.window.getComputedStyle(nativeElement);
        return `${parseInt(width) - parseInt(borderRightWidth) - parseInt(borderLeftWidth)}px`;
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqDropdownTrigger, deps: [{ token: i1$2.Overlay }, { token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: KBQ_DROPDOWN_SCROLL_STRATEGY }, { token: KbqDropdown, optional: true }, { token: KbqDropdownItem, optional: true, self: true }, { token: i4.Directionality, optional: true }, { token: i0.ChangeDetectorRef }, { token: i1.FocusMonitor }], target: i0.ɵɵFactoryTarget.Directive }); }
    /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "18.2.14", type: KbqDropdownTrigger, selector: "[kbqDropdownTriggerFor]", inputs: { offsetX: ["offsetX", "offsetX", numberAttribute], offsetY: ["offsetY", "offsetY", numberAttribute], data: ["kbqDropdownTriggerData", "data"], openByArrowDown: "openByArrowDown", restoreFocus: ["kbqDropdownTriggerRestoreFocus", "restoreFocus"], dropdown: ["kbqDropdownTriggerFor", "dropdown"] }, outputs: { dropdownOpened: "dropdownOpened", dropdownClosed: "dropdownClosed" }, host: { listeners: { "mousedown": "handleMousedown($event)", "keydown": "handleKeydown($event)", "click": "handleClick($event)" }, properties: { "class.kbq-pressed": "opened" }, classAttribute: "kbq-dropdown-trigger" }, exportAs: ["kbqDropdownTrigger"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqDropdownTrigger, decorators: [{
            type: Directive,
            args: [{
                    selector: `[kbqDropdownTriggerFor]`,
                    exportAs: 'kbqDropdownTrigger',
                    host: {
                        class: 'kbq-dropdown-trigger',
                        '[class.kbq-pressed]': 'opened',
                        '(mousedown)': 'handleMousedown($event)',
                        '(keydown)': 'handleKeydown($event)',
                        '(click)': 'handleClick($event)'
                    }
                }]
        }], ctorParameters: () => [{ type: i1$2.Overlay }, { type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: undefined, decorators: [{
                    type: Inject,
                    args: [KBQ_DROPDOWN_SCROLL_STRATEGY]
                }] }, { type: KbqDropdown, decorators: [{
                    type: Optional
                }] }, { type: KbqDropdownItem, decorators: [{
                    type: Optional
                }, {
                    type: Self
                }] }, { type: i4.Directionality, decorators: [{
                    type: Optional
                }] }, { type: i0.ChangeDetectorRef }, { type: i1.FocusMonitor }], propDecorators: { offsetX: [{
                type: Input,
                args: [{ transform: numberAttribute }]
            }], offsetY: [{
                type: Input,
                args: [{ transform: numberAttribute }]
            }], data: [{
                type: Input,
                args: ['kbqDropdownTriggerData']
            }], openByArrowDown: [{
                type: Input
            }], restoreFocus: [{
                type: Input,
                args: ['kbqDropdownTriggerRestoreFocus']
            }], dropdown: [{
                type: Input,
                args: ['kbqDropdownTriggerFor']
            }], dropdownOpened: [{
                type: Output
            }], dropdownClosed: [{
                type: Output
            }] } });

class KbqDropdownModule {
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqDropdownModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: KbqDropdownModule, declarations: [KbqDropdown,
            KbqDropdownItem,
            KbqDropdownTrigger,
            KbqDropdownContent], imports: [OverlayModule,
            KbqIconModule,
            NgClass,
            KbqDropdownStaticContent], exports: [KbqDropdown,
            KbqDropdownItem,
            KbqDropdownTrigger,
            KbqDropdownContent,
            KbqDropdownStaticContent] }); }
    /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqDropdownModule, providers: [KBQ_DROPDOWN_SCROLL_STRATEGY_FACTORY_PROVIDER], imports: [OverlayModule,
            KbqIconModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqDropdownModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [
                        OverlayModule,
                        KbqIconModule,
                        NgClass,
                        KbqDropdownStaticContent
                    ],
                    exports: [
                        KbqDropdown,
                        KbqDropdownItem,
                        KbqDropdownTrigger,
                        KbqDropdownContent,
                        KbqDropdownStaticContent
                    ],
                    declarations: [
                        KbqDropdown,
                        KbqDropdownItem,
                        KbqDropdownTrigger,
                        KbqDropdownContent
                    ],
                    providers: [KBQ_DROPDOWN_SCROLL_STRATEGY_FACTORY_PROVIDER]
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { KBQ_DROPDOWN_DEFAULT_OPTIONS, KBQ_DROPDOWN_DEFAULT_OPTIONS_FACTORY, KBQ_DROPDOWN_PANEL, KBQ_DROPDOWN_SCROLL_STRATEGY, KBQ_DROPDOWN_SCROLL_STRATEGY_FACTORY, KBQ_DROPDOWN_SCROLL_STRATEGY_FACTORY_PROVIDER, KbqDropdown, KbqDropdownContent, KbqDropdownItem, KbqDropdownModule, KbqDropdownStaticContent, KbqDropdownTrigger, NESTED_PANEL_LEFT_PADDING, NESTED_PANEL_TOP_PADDING, fadeInItems, kbqDropdownAnimations, throwKbqDropdownInvalidPositionX, throwKbqDropdownInvalidPositionY, throwKbqDropdownMissingError, transformDropdown };
//# sourceMappingURL=koobiq-components-dropdown.mjs.map
