// #region Imports
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { on } from '@breadstone/mosaik-elements';
import { DomServiceLocator } from '../../../../Dom/Dom';
import { Animatable } from '../../../Behaviors/Animatable';
import { Appearanceable } from '../../../Behaviors/Appearanceable';
import { Attachable } from '../../../Behaviors/Attachable';
import { Disableable } from '../../../Behaviors/Disableable';
import { Elevatable } from '../../../Behaviors/Elevatable';
import { Slottable } from '../../../Behaviors/Slottable';
import { Themeable } from '../../../Behaviors/Themeable';
import { Variantable } from '../../../Behaviors/Variantable';
import { ClickOutsideController } from '../../../Controllers/ClickOutsideController';
import { addFocusTrapController } from '../../../Controllers/FocusTrapController';
import { Attribute } from '../../../Decorators/AttributeDecorator';
import { Component } from '../../../Decorators/ComponentDecorator';
import { Watch } from '../../../Decorators/WatchDecorator';
import { Placement } from '../../../Types/Placement';
import { Trigger } from '../../../Types/Trigger';
import { OverlayElement } from '../../Overlays/Abstracts/OverlayElement';
import { BackdropElement } from '../Backdrop/BackdropElement';
import { ElevationElement } from '../Elevation/ElevationElement';
import { FloatingElement } from '../Floating/FloatingElement';
import { PortalElement } from '../Portal/PortalElement';
import { ProjectionController } from '../Portal/ProjectionController';
import { IPopupElementProps } from './IPopupElementProps';
import { popupElementTemplate } from './PopupElementTemplate';
import { popupElementCosmopolitanStyle } from './Themes/PopupElement.Cosmopolitan';
import { popupElementJoyStyle } from './Themes/PopupElement.Joy';
import { popupElementMemphisStyle } from './Themes/PopupElement.Memphis';
// #endregion
/**
 * Popup - A versatile floating container that appears relative to an anchor element.
 *
 * @description
 * The Popup component provides a flexible way to display content in a floating container
 * that can be positioned relative to any anchor element. Unlike Tooltip which is text-focused,
 * Popup supports rich interactive content with features like modal backdrop, focus trapping,
 * multiple trigger modes, and extensive positioning options.
 *
 * @name Popup
 * @element mosaik-popup
 * @category Primitives
 *
 * @slot - Default slot for the trigger/anchor element.
 * @slot content - The popup content to display.
 * @slot header - Optional header content for the popup.
 * @slot footer - Optional footer content for the popup.
 *
 * @csspart portal - The portal container.
 * @csspart popup - The floating popup container.
 * @csspart body - The main body of the popup.
 * @csspart header - The header section.
 * @csspart content - The content projection area.
 * @csspart footer - The footer section.
 * @csspart backdrop - The modal backdrop (when has-backdrop=true).
 *
 * @fires opened {OpenedEvent} - Fired when the popup is opened.
 * @fires closed {ClosedEvent} - Fired when the popup is closed.
 *
 * @example
 * ```html
 * <!-- Basic popup with click trigger -->
 * <mosaik-popup trigger="click">
 *   <mosaik-button>Open Popup</mosaik-button>
 *   <div slot="content">
 *     <p>Popup content here</p>
 *   </div>
 * </mosaik-popup>
 *
 * <!-- Modal popup with backdrop -->
 * <mosaik-popup has-backdrop trap-focus press-escape-to-close>
 *   <mosaik-button>Open Modal</mosaik-button>
 *   <div slot="content">
 *     <h3 slot="header">Dialog Title</h3>
 *     <p>Modal content</p>
 *     <div slot="footer">
 *       <mosaik-button>Close</mosaik-button>
 *     </div>
 *   </div>
 * </mosaik-popup>
 *
 * <!-- Hover popup with delay -->
 * <mosaik-popup trigger="hover" show-delay="200" hide-delay="100" placement="top">
 *   <mosaik-button>Hover me</mosaik-button>
 *   <div slot="content">
 *     <p>This appears on hover</p>
 *   </div>
 * </mosaik-popup>
 * ```
 *
 * @public
 */
let PopupElement = class PopupElement extends Themeable(Animatable(Attachable(Slottable(Elevatable(Variantable(Appearanceable(Disableable(OverlayElement)))))))) {
    // #region Fields
    _floatingElement;
    _projectionController;
    _clickOutsideController;
    _focusTrapController;
    _placement;
    _placements;
    _distance;
    _skidding;
    _trigger;
    _showDelay;
    _hideDelay;
    _staysOpen;
    _closeOnScroll;
    _interactive;
    _flip;
    _shift;
    _trapFocus;
    _hoverTimeout;
    _blurSubscription;
    _focusSubscription;
    _clickSubscription;
    _mouseoverSubscription;
    _mouseoutSubscription;
    _scrollSubscription;
    _slottedControl;
    _anchorReady;
    _previousActiveElement;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._placement = IPopupElementProps.DEFAULTS.placement;
        this._placements = IPopupElementProps.DEFAULTS.placements;
        this._distance = IPopupElementProps.DEFAULTS.distance;
        this._skidding = IPopupElementProps.DEFAULTS.skidding;
        this._trigger = IPopupElementProps.DEFAULTS.trigger;
        this._showDelay = IPopupElementProps.DEFAULTS.showDelay;
        this._hideDelay = IPopupElementProps.DEFAULTS.hideDelay;
        this._staysOpen = IPopupElementProps.DEFAULTS.staysOpen;
        this._closeOnScroll = IPopupElementProps.DEFAULTS.closeOnScroll;
        this._interactive = IPopupElementProps.DEFAULTS.interactive;
        this._flip = IPopupElementProps.DEFAULTS.flip;
        this._shift = IPopupElementProps.DEFAULTS.shift;
        this._trapFocus = IPopupElementProps.DEFAULTS.trapFocus;
        this._floatingElement = null;
        this._hoverTimeout = null;
        this._blurSubscription = null;
        this._focusSubscription = null;
        this._clickSubscription = null;
        this._mouseoverSubscription = null;
        this._mouseoutSubscription = null;
        this._scrollSubscription = null;
        this._slottedControl = null;
        this._anchorReady = false;
        this._previousActiveElement = null;
        Object.assign(this, { enter: IPopupElementProps.DEFAULTS.enter });
        Object.assign(this, { exit: IPopupElementProps.DEFAULTS.exit });
        Object.assign(this, { elevation: IPopupElementProps.DEFAULTS.elevation });
        this._projectionController = new ProjectionController(this, {
            slotName: 'content',
            targetSelector: '[part="projection"]'
        });
        this._clickOutsideController = new ClickOutsideController(this, {
            ignored: () => {
                const elements = [];
                // Ignore clicks on the anchor/trigger element
                if (this.anchorElement) {
                    elements.push(this.anchorElement);
                }
                // Ignore clicks on the floating popup itself
                if (this._floatingElement) {
                    elements.push(this._floatingElement);
                }
                return elements;
            },
            skipInitial: true,
            callback: () => {
                if (this.clickOutsideToClose && this.isOpen && !this._staysOpen) {
                    void this.close();
                }
            }
        });
        this._focusTrapController = addFocusTrapController(this);
    }
    // #endregion
    // #region Properties
    /**
     * Returns the `is` property.
     *
     * @public
     * @static
     * @readonly
     */
    static get is() {
        return 'mosaik-popup';
    }
    /**
     * Gets the anchor element for the popup.
     *
     * @public
     * @readonly
     */
    get anchorElement() {
        return this._slottedControl ?? this.control;
    }
    /**
     * Gets whether the floating element should be active.
     *
     * @public
     * @readonly
     */
    get isFloatingActive() {
        return this.isOpen && this._anchorReady && this.anchorElement !== null;
    }
    /**
     * Gets whether slotted content is projected into the popup.
     *
     * @public
     * @readonly
     */
    get hasSlottedContent() {
        return this._projectionController.elements.length > 0;
    }
    /**
     * Gets or sets the `placement` property.
     *
     * @public
     * @attr
     */
    get placement() {
        return this._placement;
    }
    set placement(value) {
        if (this._placement !== value) {
            this._placement = value;
            this.requestUpdate('placement');
        }
    }
    /**
     * Gets or sets the `placements` property (fallback placements).
     *
     * @public
     * @attr
     */
    get placements() {
        return this._placements;
    }
    set placements(value) {
        if (this._placements !== value) {
            this._placements = value;
            this.requestUpdate('placements');
        }
    }
    /**
     * Gets or sets the `distance` property (horizontal offset from anchor).
     *
     * @public
     * @attr
     */
    get distance() {
        return this._distance;
    }
    set distance(value) {
        if (this._distance !== value) {
            this._distance = value;
            this.requestUpdate('distance');
        }
    }
    /**
     * Gets or sets the `skidding` property (vertical offset along anchor).
     *
     * @public
     * @attr
     */
    get skidding() {
        return this._skidding;
    }
    set skidding(value) {
        if (this._skidding !== value) {
            this._skidding = value;
            this.requestUpdate('skidding');
        }
    }
    /**
     * Gets or sets the `trigger` property.
     *
     * @public
     * @attr
     */
    get trigger() {
        return this._trigger;
    }
    set trigger(value) {
        if (this._trigger !== value) {
            this._trigger = value;
            this.requestUpdate('trigger');
        }
    }
    /**
     * Gets or sets the `showDelay` property.
     *
     * @public
     * @attr
     */
    get showDelay() {
        return this._showDelay;
    }
    set showDelay(value) {
        if (this._showDelay !== value) {
            this._showDelay = value;
            this.requestUpdate('showDelay');
        }
    }
    /**
     * Gets or sets the `hideDelay` property.
     *
     * @public
     * @attr
     */
    get hideDelay() {
        return this._hideDelay;
    }
    set hideDelay(value) {
        if (this._hideDelay !== value) {
            this._hideDelay = value;
            this.requestUpdate('hideDelay');
        }
    }
    /**
     * Gets or sets the `staysOpen` property.
     *
     * @public
     * @attr
     */
    get staysOpen() {
        return this._staysOpen;
    }
    set staysOpen(value) {
        if (this._staysOpen !== value) {
            this._staysOpen = value;
            this.requestUpdate('staysOpen');
        }
    }
    /**
     * Gets or sets the `closeOnScroll` property.
     *
     * @public
     * @attr
     */
    get closeOnScroll() {
        return this._closeOnScroll;
    }
    set closeOnScroll(value) {
        if (this._closeOnScroll !== value) {
            this._closeOnScroll = value;
            this.requestUpdate('closeOnScroll');
        }
    }
    /**
     * Gets or sets the `interactive` property.
     *
     * @public
     * @attr
     */
    get interactive() {
        return this._interactive;
    }
    set interactive(value) {
        if (this._interactive !== value) {
            this._interactive = value;
            this.requestUpdate('interactive');
        }
    }
    /**
     * Gets or sets the `flip` property.
     *
     * @public
     * @attr
     */
    get flip() {
        return this._flip;
    }
    set flip(value) {
        if (this._flip !== value) {
            this._flip = value;
            this.requestUpdate('flip');
        }
    }
    /**
     * Gets or sets the `shift` property.
     *
     * @public
     * @attr
     */
    get shift() {
        return this._shift;
    }
    set shift(value) {
        if (this._shift !== value) {
            this._shift = value;
            this.requestUpdate('shift');
        }
    }
    /**
     * Gets or sets the `trapFocus` property.
     *
     * @public
     * @attr
     */
    get trapFocus() {
        return this._trapFocus;
    }
    set trapFocus(value) {
        if (this._trapFocus !== value) {
            this._trapFocus = value;
            this.requestUpdate('trapFocus');
        }
    }
    // #endregion
    // #region Methods
    /**
     * Opens the popup.
     *
     * @public
     * @override
     */
    async open() {
        if (this.isOpen || this.disabled) {
            return;
        }
        // Store the previously focused element for focus restoration
        this._previousActiveElement = document.activeElement;
        // Call base class open (handles isOpen, events, escape listener)
        await super.open();
        // Handle focus trap
        if (this._trapFocus) {
            await this.updateComplete;
            this._focusTrapController.activate();
        }
        // Handle scroll close
        if (this._closeOnScroll) {
            this._scrollSubscription = on(window, 'scroll', () => void this.close(), { passive: true, capture: true });
        }
    }
    /**
     * Closes the popup.
     *
     * @public
     * @override
     */
    async close() {
        if (!this.isOpen) {
            return false;
        }
        // Deactivate focus trap
        this._focusTrapController.deactivate();
        // Call base class close (handles isOpen, events, escape listener)
        const result = await super.close();
        // Clean up scroll listener
        this._scrollSubscription?.dispose();
        this._scrollSubscription = null;
        // Restore focus to previously focused element
        if (this._previousActiveElement && typeof this._previousActiveElement.focus === 'function') {
            this._previousActiveElement.focus();
        }
        this._previousActiveElement = null;
        return result;
    }
    /**
     * Toggles the popup open/closed state.
     *
     * @public
     */
    async toggle() {
        if (this.isOpen) {
            await this.close();
        }
        else {
            await this.open();
        }
    }
    /**
     * @public
     * @override
     */
    connectedCallback() {
        super.connectedCallback();
        // Defer event binding to allow sibling elements (for="..." targets) to mount first.
        // Only binds if not already bound by onDefaultSlotChange (slotted control case).
        void this.updateComplete.then(() => {
            requestAnimationFrame(() => {
                // Only bind if not already bound (e.g., by slotchange)
                if (!this._clickSubscription) {
                    this.bindControlEvents();
                    this.updateFloatingAnchor();
                }
            });
        });
    }
    /**
     * @public
     * @override
     */
    disconnectedCallback() {
        super.disconnectedCallback();
        this.unbindControlEvents();
        this._scrollSubscription?.dispose();
    }
    /**
     * @protected
     * @override
     */
    onApplyTemplate() {
        super.onApplyTemplate();
        // Listen for slot changes to detect the slotted control element
        const defaultSlot = this.shadowRoot?.querySelector('slot:not([name])');
        if (defaultSlot) {
            defaultSlot.addEventListener('slotchange', () => this.onDefaultSlotChange(defaultSlot));
            this.onDefaultSlotChange(defaultSlot);
        }
        const portalElement = this.getTemplatePart('portal');
        // Wait for portal to attach and project its content
        portalElement.addEventListener('portalAttached', () => {
            const projectionElement = portalElement.projection;
            if (projectionElement) {
                this._floatingElement = DomServiceLocator.current.findDescendant(projectionElement, '[part="popup"]', { strict: true });
                this.updateFloatingAnchor();
            }
        }, { once: true });
    }
    /**
     * @protected
     * @override
     */
    firstUpdated(changedProperties) {
        super.firstUpdated(changedProperties);
        if (this.isOpen && this._floatingElement && this._anchorReady) {
            this._floatingElement.reposition();
        }
    }
    /**
     * Checks if a trigger is active.
     *
     * @private
     */
    hasTrigger(trigger) {
        return this._trigger === trigger;
    }
    /**
     * Handles changes to the default slot.
     *
     * @private
     */
    onDefaultSlotChange(slot) {
        const assignedElements = slot.assignedElements({ flatten: true });
        const previousControl = this._slottedControl;
        // Get the first element as the control
        this._slottedControl = assignedElements.length > 0
            ? assignedElements[0]
            : null;
        // Mark anchor as ready only for slotted controls
        const wasReady = this._anchorReady;
        if (this._slottedControl !== null) {
            this._anchorReady = true;
        }
        // Rebind events if control changed
        if (previousControl !== this._slottedControl) {
            this.unbindControlEvents();
            this.bindControlEvents();
            this.updateFloatingAnchor();
        }
        // Trigger re-render if anchor readiness changed
        if (wasReady !== this._anchorReady) {
            this.requestUpdate('anchorElement');
        }
    }
    /**
     * Updates the floating element's anchor reference.
     *
     * @private
     */
    updateFloatingAnchor() {
        this._anchorReady = this.anchorElement !== null;
        this.requestUpdate('anchorElement');
    }
    /**
     * Binds event listeners to the control element.
     *
     * @private
     */
    bindControlEvents() {
        const control = this.anchorElement;
        if (!control) {
            return;
        }
        // Bind all events and check trigger in handlers (like Tooltip does)
        this._blurSubscription = on(control, 'blur', (e) => this.onControlBlur(e), true);
        this._focusSubscription = on(control, 'focus', (e) => this.onControlFocus(e), true);
        this._clickSubscription = on(control, 'click', (e) => this.onControlClick(e));
        this._mouseoverSubscription = on(control, 'mouseenter', (e) => this.onControlMouseEnter(e));
        this._mouseoutSubscription = on(control, 'mouseleave', (e) => this.onControlMouseLeave(e));
    }
    /**
     * Unbinds event listeners from the control element.
     *
     * @private
     */
    unbindControlEvents() {
        this._blurSubscription?.dispose();
        this._focusSubscription?.dispose();
        this._clickSubscription?.dispose();
        this._mouseoverSubscription?.dispose();
        this._mouseoutSubscription?.dispose();
        this._blurSubscription = null;
        this._focusSubscription = null;
        this._clickSubscription = null;
        this._mouseoverSubscription = null;
        this._mouseoutSubscription = null;
    }
    /**
     * Handles click on the control element.
     *
     * @private
     */
    onControlClick(_event) {
        if (!this.hasTrigger(Trigger.Click)) {
            return;
        }
        void this.toggle();
    }
    /**
     * Handles mouse enter on the control element.
     *
     * @private
     */
    onControlMouseEnter(_event) {
        if (!this.hasTrigger(Trigger.Hover)) {
            return;
        }
        if (this._hoverTimeout) {
            clearTimeout(this._hoverTimeout);
        }
        this._hoverTimeout = window.setTimeout(() => void this.open(), this._showDelay);
    }
    /**
     * Handles mouse leave on the control element.
     *
     * @private
     */
    onControlMouseLeave(_event) {
        if (!this.hasTrigger(Trigger.Hover)) {
            return;
        }
        if (this._hoverTimeout) {
            clearTimeout(this._hoverTimeout);
        }
        if (this._staysOpen || this._interactive) {
            // Give time for mouse to move to popup content
            this._hoverTimeout = window.setTimeout(() => {
                // Check if mouse is over popup content
                if (!this.isMouseOverPopup()) {
                    void this.close();
                }
            }, this._hideDelay || 100);
        }
        else {
            this._hoverTimeout = window.setTimeout(() => void this.close(), this._hideDelay);
        }
    }
    /**
     * Handles focus on the control element.
     *
     * @private
     */
    onControlFocus(_event) {
        if (!this.hasTrigger(Trigger.Focus)) {
            return;
        }
        void this.open();
    }
    /**
     * Handles blur on the control element.
     *
     * @private
     */
    onControlBlur(_event) {
        if (!this.hasTrigger(Trigger.Focus)) {
            return;
        }
        // Don't close if focus moved to popup content
        requestAnimationFrame(() => {
            if (!this.containsFocus()) {
                void this.close();
            }
        });
    }
    /**
     * Checks if the mouse is currently over the popup content.
     *
     * @private
     */
    isMouseOverPopup() {
        if (!this._floatingElement) {
            return false;
        }
        const rect = this._floatingElement.getBoundingClientRect();
        const mouseEvent = window.event;
        if (!mouseEvent) {
            return false;
        }
        return (mouseEvent.clientX >= rect.left &&
            mouseEvent.clientX <= rect.right &&
            mouseEvent.clientY >= rect.top &&
            mouseEvent.clientY <= rect.bottom);
    }
    /**
     * Checks if the popup or anchor contains focus.
     *
     * @private
     */
    containsFocus() {
        const activeElement = document.activeElement;
        return (this.contains(activeElement) ||
            this._floatingElement?.contains(activeElement) ||
            false);
    }
    /**
     * Handles hover events on the popup content (for staysOpen behavior).
     *
     * @private
     */
    onPopupMouseEnter() {
        if (this._hoverTimeout) {
            clearTimeout(this._hoverTimeout);
            this._hoverTimeout = null;
        }
    }
    /**
     * Handles mouse leave from the popup content.
     *
     * @private
     */
    onPopupMouseLeave() {
        if (this.hasTrigger(Trigger.Hover) && !this._staysOpen) {
            this._hoverTimeout = window.setTimeout(() => void this.close(), this._hideDelay);
        }
    }
    /**
     * @private
     * @template
     */
    onBackdrop() {
        void this.close();
    }
    /**
     * @protected
     */
    onIsOpenPropertyChange() {
        void this.updateComplete.then(() => {
            if (this.isOpen) {
                if (this.disabled) {
                    return;
                }
                this.opened.emit();
            }
            else {
                const args = { cancel: false };
                this.closed.emit(args);
            }
        });
    }
    /**
     * @protected
     */
    onForPropertyChange() {
        // When 'for' changes, we need to rebind to a different element
        void this.updateComplete.then(() => {
            requestAnimationFrame(() => {
                this.unbindControlEvents();
                this.bindControlEvents();
                this.updateFloatingAnchor();
            });
        });
    }
    /**
     * @protected
     */
    onTriggerPropertyChange() {
        // Trigger change doesn't require rebinding - handlers check trigger dynamically
        // No action needed
    }
    /**
     * @protected
     */
    onPlacementPropertyChange() {
        void this.updateComplete.then(() => {
            this._floatingElement?.reposition();
        });
    }
    /**
     * @protected
     */
    onDistancePropertyChange() {
        void this.updateComplete.then(() => {
            this._floatingElement?.reposition();
        });
    }
    /**
     * @protected
     */
    onSkiddingPropertyChange() {
        void this.updateComplete.then(() => {
            this._floatingElement?.reposition();
        });
    }
    /**
     * @protected
     */
    onDisabledPropertyChange() {
        if (this.disabled && this.isOpen) {
            void this.close();
        }
    }
};
__decorate([
    Attribute({ type: Placement }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], PopupElement.prototype, "placement", null);
__decorate([
    Attribute({ type: Array }),
    __metadata("design:type", Array),
    __metadata("design:paramtypes", [Array])
], PopupElement.prototype, "placements", null);
__decorate([
    Attribute({ type: Number }),
    __metadata("design:type", Number),
    __metadata("design:paramtypes", [Number])
], PopupElement.prototype, "distance", null);
__decorate([
    Attribute({ type: Number }),
    __metadata("design:type", Number),
    __metadata("design:paramtypes", [Number])
], PopupElement.prototype, "skidding", null);
__decorate([
    Attribute({ type: Trigger }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], PopupElement.prototype, "trigger", null);
__decorate([
    Attribute({ type: Number }),
    __metadata("design:type", Number),
    __metadata("design:paramtypes", [Number])
], PopupElement.prototype, "showDelay", null);
__decorate([
    Attribute({ type: Number }),
    __metadata("design:type", Number),
    __metadata("design:paramtypes", [Number])
], PopupElement.prototype, "hideDelay", null);
__decorate([
    Attribute({ type: Boolean, useDefault: true }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], PopupElement.prototype, "staysOpen", null);
__decorate([
    Attribute({ type: Boolean, useDefault: true }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], PopupElement.prototype, "closeOnScroll", null);
__decorate([
    Attribute({ type: Boolean, useDefault: true }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], PopupElement.prototype, "interactive", null);
__decorate([
    Attribute({ type: Boolean, useDefault: true }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], PopupElement.prototype, "flip", null);
__decorate([
    Attribute({ type: Boolean, useDefault: true }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], PopupElement.prototype, "shift", null);
__decorate([
    Attribute({ type: Boolean, useDefault: true }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], PopupElement.prototype, "trapFocus", null);
__decorate([
    Watch('isOpen', { waitUntilFirstUpdate: true }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], PopupElement.prototype, "onIsOpenPropertyChange", null);
__decorate([
    Watch('for'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], PopupElement.prototype, "onForPropertyChange", null);
__decorate([
    Watch('trigger'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], PopupElement.prototype, "onTriggerPropertyChange", null);
__decorate([
    Watch('placement'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], PopupElement.prototype, "onPlacementPropertyChange", null);
__decorate([
    Watch('distance'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], PopupElement.prototype, "onDistancePropertyChange", null);
__decorate([
    Watch('skidding'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], PopupElement.prototype, "onSkiddingPropertyChange", null);
__decorate([
    Watch('disabled'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], PopupElement.prototype, "onDisabledPropertyChange", null);
PopupElement = __decorate([
    Component({
        selector: 'mosaik-popup',
        template: popupElementTemplate,
        themes: {
            joy: popupElementJoyStyle,
            memphis: popupElementMemphisStyle,
            cosmopolitan: popupElementCosmopolitanStyle
        },
        host: {
            tabIndex: '0',
            role: 'dialog'
        },
        imports: [
            ElevationElement,
            PortalElement,
            FloatingElement,
            BackdropElement
        ]
    }),
    __metadata("design:paramtypes", [])
], PopupElement);
export { PopupElement };
//# sourceMappingURL=PopupElement.js.map