import { MXInteractiveComponent, MXLookComponent, convertToPlacement, AXComponent, AXClosableComponent, AXCommonModule } from '@acorex/cdk/common';
import * as i0 from '@angular/core';
import { EventEmitter, Injectable, input, inject, HostBinding, HostListener, Output, ViewChild, Component, effect, Input, ViewEncapsulation, ChangeDetectionStrategy, NgModule } from '@angular/core';
import { AXPopoverComponent, AXPopoverModule } from '@acorex/components/popover';
import { AXPlatform, isBrowser } from '@acorex/core/platform';
import { classes } from 'polytype';
import { startWith } from 'rxjs';
import { AXDecoratorModule } from '@acorex/components/decorators';
import { A11yModule } from '@angular/cdk/a11y';
import { OverlayModule } from '@angular/cdk/overlay';
import { CommonModule } from '@angular/common';

/**
 * Base behavior for components that manage a dropdown/popup via an internal `AXDropdownBoxComponent`.
 *
 * Extends MXInteractiveComponent to inherit interactive features (focus, blur, disabled, tabIndex)
 * and exposes a consistent API to open/close/toggle the dropdown as well as events for open/close lifecycle.
 */
class MXDropdownBoxBaseComponent extends MXInteractiveComponent {
    constructor() {
        super(...arguments);
        /**
         * Emitted when the dropdown/popup is opened.
         *
         * @event
         */
        this.onOpened = new EventEmitter();
        /**
         * Emitted when the dropdown/popup is closed.
         *
         * @event
         */
        this.onClosed = new EventEmitter();
    }
    /**
     * Emits the `onOpened` event with component context.
     * @ignore
     */
    emitOnOpenedEvent() {
        this.onOpened.emit({
            component: this,
            htmlElement: this.getHostElement(),
        });
    }
    /**
     * Emits the `onClosed` event with component context.
     * @ignore
     */
    emitOnClosedEvent() {
        this.onClosed.emit({
            component: this,
            htmlElement: this.getHostElement(),
        });
    }
    /**
     * Toggles the dropdown if the component is not disabled.
     *
     * @returns void - No return value. Switches between open and closed states.
     */
    toggle() {
        if (this.disabled !== true) {
            this.dropdown.toggle();
        }
    }
    /**
     * Closes the dropdown if it is open and the component is not disabled, then focuses the host.
     *
     * @returns void - No return value. Dropdown is closed and focus returns to the host.
     */
    close() {
        if (!this.isOpen || this.disabled) {
            return;
        }
        this.dropdown.close();
        this.focus();
    }
    /**
     * Opens the dropdown if it is not already open and the component is not disabled, then focuses the dropdown.
     *
     * @returns void - No return value. Dropdown becomes open and receives focus.
     */
    open() {
        if (this.isOpen || this.disabled) {
            return;
        }
        this.dropdown.open();
        this.dropdown.focus();
    }
    /**
     * Indicates whether the dropdown is currently open.
     *
     * @returns boolean - True if open; otherwise false.
     */
    get isOpen() {
        return this.dropdown?.isOpen;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: MXDropdownBoxBaseComponent, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: MXDropdownBoxBaseComponent }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: MXDropdownBoxBaseComponent, decorators: [{
            type: Injectable
        }] });

class AXDropdownBoxComponent extends classes(MXInteractiveComponent, MXLookComponent) {
    constructor() {
        super(...arguments);
        this.hasInput = input(true, ...(ngDevMode ? [{ debugName: "hasInput" }] : []));
        this.popoverWidth = input('auto', ...(ngDevMode ? [{ debugName: "popoverWidth" }] : []));
        this._platform = inject(AXPlatform);
        /**
         *  @ignore
         */
        this._isMobile = false;
        /**
         *  @ignore
         */
        this._popoverWidth = '180px';
        /**
         *  @ignore
         */
        this._placement = convertToPlacement('bottom-start');
        /**
         * Emitted when the drawer is opened.
         *
         * @event
         */
        this.onOpened = new EventEmitter();
        /**
         * Emitted when the drawer is closed.
         *
         * @event
         */
        this.onClosed = new EventEmitter();
    }
    /**
     *  @ignore
     */
    ngOnInit() {
        super.ngOnInit();
        this._target = this.getHostElement();
        this._platform.resize.pipe(startWith()).subscribe(() => {
            this._isMobile = this._platform.is('SM');
            if (!this.isActionsheetStyle)
                this.close();
        });
    }
    /**
     *  @ignore
     */
    _handlePopupOnOpened(e) {
        this._popover?.focus();
        this.onOpened.emit({
            component: this,
            isUserInteraction: e.isUserInteraction,
        });
    }
    /**
     *  @ignore
     */
    _handlePopupOnClosed(e) {
        this.focus();
        this.onClosed.emit({
            component: this,
            isUserInteraction: e.isUserInteraction,
        });
    }
    /**
     *  @ignore
     */
    _handleKeydown(e) {
        if (e.ctrlKey && e.code === 'ArrowDown') {
            this.open();
            e.preventDefault();
        }
        if (e.code === 'Escape') {
            this.close();
            e.preventDefault();
        }
    }
    /**
     * Updates the position of the popover.
     * @ignore
     */
    updatePosition() {
        this._popover?.updatePosition();
    }
    /**
     * Toggles the popover open or closed, if not disabled.
     * @ignore
     */
    toggle() {
        if (this.disabled !== true) {
            this._popover.toggle();
        }
    }
    /**
     * Closes the popover if it's open and not disabled, then focuses the element.
     * @ignore
     */
    close() {
        if (!this.isOpen || this.disabled) {
            return;
        }
        this._popover.close();
        this.focus();
    }
    /**
     * Opens the popover if it's not already open and not disabled, then focuses the popover.
     * @ignore
     */
    open() {
        if (this.isOpen || this.disabled) {
            return;
        }
        this._popover.open();
        this._popover.focus();
    }
    /**
     * Indicates if the popover is currently open.
     * @ignore
     */
    get isOpen() {
        return this._popover?.isOpen;
    }
    /**
     * Indicates if the popover is styled as an actionsheet.
     */
    get isActionsheetStyle() {
        return this._popover?.isActionsheetStyle;
    }
    /**
     *  @ignore
     */
    get __hostClass() {
        return this.hasInput() ? `ax-editor-container ax-${this.look} ${this.disabled ? 'ax-state-disabled' : ''}` : '';
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXDropdownBoxComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.9", type: AXDropdownBoxComponent, isStandalone: true, selector: "ax-dropdown-box", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: false, isRequired: false, transformFunction: null }, hasInput: { classPropertyName: "hasInput", publicName: "hasInput", isSignal: true, isRequired: false, transformFunction: null }, popoverWidth: { classPropertyName: "popoverWidth", publicName: "popoverWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabledChange: "disabledChange", onBlur: "onBlur", onFocus: "onFocus", onClick: "onClick", onOpened: "onOpened", onClosed: "onClosed" }, host: { attributes: { "ngSkipHydration": "true" }, listeners: { "keydown": "_handleKeydown($event)" }, properties: { "class": "this.__hostClass" } }, providers: [{ provide: AXComponent, useExisting: AXDropdownBoxComponent }], viewQueries: [{ propertyName: "_popover", first: true, predicate: AXPopoverComponent, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<ng-content select=\"[input]\"> </ng-content>\n<ax-popover\n  [target]=\"_target\"\n  [placement]=\"_placement\"\n  [openOn]=\"'manual'\"\n  [closeOn]=\"'clickOut'\"\n  [adaptivityEnabled]=\"true\"\n  [width]=\"popoverWidth()\"\n  (onOpened)=\"_handlePopupOnOpened($event)\"\n  (onClosed)=\"_handlePopupOnClosed($event)\"\n  #popover\n>\n  <div\n    class=\"ax-overlay-pane\"\n    [class.ax-w-full]=\"_isMobile\"\n    aria-modal=\"true\"\n    (keydown)=\"_handleKeydown($event)\"\n    [class.ax-overlay-actionsheet]=\"popover.isActionsheetStyle\"\n  >\n    <ng-content select=\"[panel]\"> </ng-content>\n  </div>\n</ax-popover>\n", dependencies: [{ kind: "component", type: AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXDropdownBoxComponent, decorators: [{
            type: Component,
            args: [{ selector: 'ax-dropdown-box', inputs: ['disabled', 'look'], outputs: ['disabledChange', 'onBlur', 'onFocus', 'onClick'], host: { ngSkipHydration: 'true' }, imports: [AXPopoverComponent], providers: [{ provide: AXComponent, useExisting: AXDropdownBoxComponent }], template: "<ng-content select=\"[input]\"> </ng-content>\n<ax-popover\n  [target]=\"_target\"\n  [placement]=\"_placement\"\n  [openOn]=\"'manual'\"\n  [closeOn]=\"'clickOut'\"\n  [adaptivityEnabled]=\"true\"\n  [width]=\"popoverWidth()\"\n  (onOpened)=\"_handlePopupOnOpened($event)\"\n  (onClosed)=\"_handlePopupOnClosed($event)\"\n  #popover\n>\n  <div\n    class=\"ax-overlay-pane\"\n    [class.ax-w-full]=\"_isMobile\"\n    aria-modal=\"true\"\n    (keydown)=\"_handleKeydown($event)\"\n    [class.ax-overlay-actionsheet]=\"popover.isActionsheetStyle\"\n  >\n    <ng-content select=\"[panel]\"> </ng-content>\n  </div>\n</ax-popover>\n" }]
        }], propDecorators: { hasInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasInput", required: false }] }], popoverWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "popoverWidth", required: false }] }], _popover: [{
                type: ViewChild,
                args: [AXPopoverComponent, { static: true }]
            }], onOpened: [{
                type: Output
            }], onClosed: [{
                type: Output
            }], _handleKeydown: [{
                type: HostListener,
                args: ['keydown', ['$event']]
            }], __hostClass: [{
                type: HostBinding,
                args: ['class']
            }] } });

/**
 * A panel for displaying dropdown content with configurable width and positioning.
 *
 * @category Components
 */
class AXDropdownPanelComponent extends MXInteractiveComponent {
    #effect;
    /**
     * Gets the target HTML element for the dropdown panel.
     */
    get _target() {
        return this.__target;
    }
    /**
     * Sets the target HTML element for the dropdown panel.
     */
    set _target(v) {
        this.__target = v;
    }
    // what the hell ???
    // constructor() {
    //   super();
    //   afterNextRender(() => {
    //     this._target = this.getHostElement()?.parentElement as HTMLDivElement;
    //     this._platform.resize.pipe(startWith(null)).subscribe(() => {
    //       this._isMobile = this._platform.is('SM');
    //       this._popover?.close();
    //     });
    //     [this._target, this.getHostElement()].forEach((el) => {
    //       el.addEventListener('keydown', (e) => {
    //         if (e.code == 'Escape' && this.isOpen) {
    //           e.stopPropagation();
    //           this.close();
    //         }
    //       });
    //     });
    //   });
    // }
    /**
     *  @ignore
     */
    constructor() {
        super();
        this._platform = inject(AXPlatform);
        /**
         *  @ignore
         */
        this._isMobile = false;
        /**
         *  @ignore
         */
        this._placement = convertToPlacement('bottom-start');
        this.placement = input('bottom-start', ...(ngDevMode ? [{ debugName: "placement" }] : []));
        this.#effect = effect(() => {
            if (!this.placement())
                return;
            this._placement = convertToPlacement(this.placement());
        }, ...(ngDevMode ? [{ debugName: "#effect" }] : []));
        /**
         *  @ignore
         */
        this._subs = [];
        /**
         * Emitted when the dropdown panel is opened.
         *
         * @event
         */
        this.onOpened = new EventEmitter();
        /**
         * Emitted when the dropdown panel is closed.
         *
         * @event
         */
        this.onClosed = new EventEmitter();
        /**
         * Determines if adaptivity is enabled for the component.
         *
         * @defaultValue  false
         */
        this.adaptivityEnabled = false;
    }
    /**
     *  @ignore
     */
    ngOnInit() {
        if (isBrowser()) {
            super.ngOnInit();
            if (!this._target) {
                this._target = this.getHostElement()?.parentElement;
            }
            this._platform.resize.pipe(startWith(null)).subscribe(() => {
                this._isMobile = this._platform.is('SM');
                this._popover?.close();
            });
        }
    }
    /**
     *  @ignore
     */
    ngAfterViewInit() {
        [this._target, this.getHostElement()].forEach((el) => {
            el?.addEventListener('keydown', (e) => {
                if (e.code == 'Escape' && this.isOpen) {
                    e.stopPropagation();
                    this.close();
                }
            });
        });
    }
    /**
     *  @ignore
     */
    ngOnDestroy() {
        this._subs.forEach((s) => {
            s?.unsubscribe();
        });
    }
    /**
     *  @ignore
     */
    _handlePopupOnOpened(e) {
        this._popover?.focus();
        this.onOpened.emit({
            component: this,
            isUserInteraction: e.isUserInteraction,
        });
    }
    /**
     *  @ignore
     */
    _handlePopupOnClosed(e) {
        this._target.focus();
        this.onClosed.emit({
            component: this,
            isUserInteraction: e.isUserInteraction,
        });
    }
    /**
     * Toggles the popover open or closed, if not disabled.
     * @ignore
     */
    toggle() {
        if (this.disabled !== true) {
            this._popover.toggle();
        }
    }
    /**
     * Closes the popover if it is open and not disabled.
     * @ignore
     */
    close() {
        if (!this.isOpen || this.disabled) {
            return;
        }
        this._popover.close();
        this.focus();
    }
    /**
     * Opens the popover if it is not already open and not disabled.
     * @ignore
     */
    open() {
        if (this.isOpen || this.disabled) {
            return;
        }
        this._popover.open();
        this._popover.focus();
    }
    /**
     * Gets whether the popover is currently open.
     * @ignore
     */
    get isOpen() {
        return this._popover?.isOpen;
    }
    /**
     * Gets whether the popover is styled as an actionsheet.
     * @ignore
     */
    get isActionsheetStyle() {
        return this._popover?.isActionsheetStyle;
    }
    /**
     *  @ignore
     */
    get __hostClass() {
        return ['ax-dropdown-panel'];
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXDropdownPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.9", type: AXDropdownPanelComponent, isStandalone: true, selector: "ax-dropdown-panel", inputs: { isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: false, isRequired: false, transformFunction: null }, fitParent: { classPropertyName: "fitParent", publicName: "fitParent", isSignal: false, isRequired: false, transformFunction: null }, dropdownWidth: { classPropertyName: "dropdownWidth", publicName: "dropdownWidth", isSignal: false, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: false, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, _target: { classPropertyName: "_target", publicName: "_target", isSignal: false, isRequired: false, transformFunction: null }, adaptivityEnabled: { classPropertyName: "adaptivityEnabled", publicName: "adaptivityEnabled", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { onOpened: "onOpened", onClosed: "onClosed" }, host: { attributes: { "ngSkipHydration": "true" }, properties: { "class": "this.__hostClass" } }, providers: [
            {
                provide: AXClosableComponent,
                useExisting: AXDropdownPanelComponent,
            },
            { provide: AXComponent, useExisting: AXDropdownPanelComponent },
        ], viewQueries: [{ propertyName: "_popover", first: true, predicate: AXPopoverComponent, descendants: true }], usesInheritance: true, ngImport: i0, template: "<ax-popover\n  [target]=\"_target\"\n  [placement]=\"_placement\"\n  [openOn]=\"'toggle'\"\n  [closeOn]=\"'clickOut'\"\n  [adaptivityEnabled]=\"adaptivityEnabled\"\n  (onOpened)=\"_handlePopupOnOpened($event)\"\n  (onClosed)=\"_handlePopupOnClosed($event)\"\n>\n  <div class=\"ax-overlay-pane\">\n    <ng-content> </ng-content>\n  </div>\n</ax-popover>\n", styles: [".ax-actionsheet-base .ax-overlay-pane{width:100%}.ax-overlay-pane:has(ax-menu){border:none}.ax-overlay-pane:has(ax-menu) .ax-menu-container{opacity:1;visibility:visible}.ax-overlay-pane:has(ax-menu) .ax-menu-container .ax-action-item{border-radius:0!important;display:flex;align-items:center;justify-content:space-between;font-size:.875rem;line-height:1.25rem;height:2.25rem;width:100%;cursor:pointer;padding-inline:.875rem}.ax-overlay-pane:has(ax-menu) .ax-menu-container .ax-action-item:hover>.ax-action-item-prefix,.ax-overlay-pane:has(ax-menu) .ax-menu-container .ax-action-item:hover>.ax-action-item-suffix{opacity:1}\n"], dependencies: [{ kind: "component", type: AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXDropdownPanelComponent, decorators: [{
            type: Component,
            args: [{ selector: 'ax-dropdown-panel', inputs: ['isOpen', 'fitParent', 'dropdownWidth', 'position'], outputs: ['onOpened', 'onClosed'], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
                        {
                            provide: AXClosableComponent,
                            useExisting: AXDropdownPanelComponent,
                        },
                        { provide: AXComponent, useExisting: AXDropdownPanelComponent },
                    ], host: { ngSkipHydration: 'true' }, imports: [AXPopoverComponent], template: "<ax-popover\n  [target]=\"_target\"\n  [placement]=\"_placement\"\n  [openOn]=\"'toggle'\"\n  [closeOn]=\"'clickOut'\"\n  [adaptivityEnabled]=\"adaptivityEnabled\"\n  (onOpened)=\"_handlePopupOnOpened($event)\"\n  (onClosed)=\"_handlePopupOnClosed($event)\"\n>\n  <div class=\"ax-overlay-pane\">\n    <ng-content> </ng-content>\n  </div>\n</ax-popover>\n", styles: [".ax-actionsheet-base .ax-overlay-pane{width:100%}.ax-overlay-pane:has(ax-menu){border:none}.ax-overlay-pane:has(ax-menu) .ax-menu-container{opacity:1;visibility:visible}.ax-overlay-pane:has(ax-menu) .ax-menu-container .ax-action-item{border-radius:0!important;display:flex;align-items:center;justify-content:space-between;font-size:.875rem;line-height:1.25rem;height:2.25rem;width:100%;cursor:pointer;padding-inline:.875rem}.ax-overlay-pane:has(ax-menu) .ax-menu-container .ax-action-item:hover>.ax-action-item-prefix,.ax-overlay-pane:has(ax-menu) .ax-menu-container .ax-action-item:hover>.ax-action-item-suffix{opacity:1}\n"] }]
        }], ctorParameters: () => [], propDecorators: { placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], _target: [{
                type: Input
            }], _popover: [{
                type: ViewChild,
                args: [AXPopoverComponent]
            }], onOpened: [{
                type: Output
            }], onClosed: [{
                type: Output
            }], adaptivityEnabled: [{
                type: Input
            }], __hostClass: [{
                type: HostBinding,
                args: ['class']
            }] } });

class AXDropdownModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXDropdownModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.9", ngImport: i0, type: AXDropdownModule, imports: [CommonModule,
            AXCommonModule,
            A11yModule,
            OverlayModule,
            AXDecoratorModule,
            AXPopoverModule,
            AXDropdownPanelComponent,
            AXDropdownBoxComponent], exports: [AXDropdownPanelComponent, AXDropdownBoxComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXDropdownModule, imports: [CommonModule,
            AXCommonModule,
            A11yModule,
            OverlayModule,
            AXDecoratorModule,
            AXPopoverModule,
            AXDropdownPanelComponent,
            AXDropdownBoxComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXDropdownModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [
                        CommonModule,
                        AXCommonModule,
                        A11yModule,
                        OverlayModule,
                        AXDecoratorModule,
                        AXPopoverModule,
                        AXDropdownPanelComponent,
                        AXDropdownBoxComponent,
                    ],
                    exports: [AXDropdownPanelComponent, AXDropdownBoxComponent],
                    providers: [],
                }]
        }] });

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

export { AXDropdownBoxComponent, AXDropdownModule, AXDropdownPanelComponent, MXDropdownBoxBaseComponent };
//# sourceMappingURL=acorex-components-dropdown.mjs.map
