import * as i0 from '@angular/core';
import { Injectable, InjectionToken, inject, input, output, computed, signal, effect, afterRenderEffect, untracked, Component, Directive, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { createMotion, resolveDuration } from '@primeuix/motion';
import { nextFrame } from '@primeuix/utils';
import { BaseComponent, PARENT_INSTANCE } from 'primeng/basecomponent';
import * as i1 from 'primeng/bind';
import { Bind, BindModule } from 'primeng/bind';
import { BaseStyle } from 'primeng/base';

const originalStyles = new WeakMap();
function applyHiddenStyles(element, strategy) {
    if (!element)
        return;
    if (!originalStyles.has(element)) {
        originalStyles.set(element, {
            display: element.style.display,
            visibility: element.style.visibility,
            maxHeight: element.style.maxHeight
        });
    }
    switch (strategy) {
        case 'display':
            element.style.display = 'none';
            break;
        case 'visibility':
            element.style.visibility = 'hidden';
            element.style.maxHeight = '0';
            break;
    }
}
function resetStyles(element, strategy) {
    if (!element)
        return;
    const original = originalStyles.get(element) ?? element.style;
    switch (strategy) {
        case 'display':
            element.style.display = original?.display || '';
            break;
        case 'visibility':
            element.style.visibility = original?.visibility || '';
            element.style.maxHeight = original?.maxHeight || '';
            break;
    }
    originalStyles.delete(element);
}

const style = /*css*/ `
    .p-motion {
        display: block;
    }
`;
const classes = {
    root: 'p-motion'
};
class MotionStyle extends BaseStyle {
    name = 'motion';
    style = style;
    classes = classes;
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MotionStyle, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MotionStyle });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MotionStyle, decorators: [{
            type: Injectable
        }] });
/**
 *
 * Motion and MotionDirective provide an easy way to add motion effects to Angular applications.
 *
 * [Live Demo](https://www.primeng.org/motion)
 *
 * @module motionstyle
 *
 */
var MotionClasses;
(function (MotionClasses) {
    /**
     * Class name of the root element
     */
    MotionClasses["root"] = "p-motion";
})(MotionClasses || (MotionClasses = {}));

const MOTION_INSTANCE = new InjectionToken('MOTION_INSTANCE');
/**
 * Motion component is a container to apply motion effects to its content.
 * @group Components
 */
class Motion extends BaseComponent {
    $pcMotion = inject(MOTION_INSTANCE, { optional: true, skipSelf: true }) ?? undefined;
    bindDirectiveInstance = inject(Bind, { self: true });
    onAfterViewChecked() {
        const options = this.options();
        const optionsAttrs = options?.root || {};
        this.bindDirectiveInstance.setAttrs({ ...this.ptms(['host', 'root']), ...optionsAttrs });
    }
    _componentStyle = inject(MotionStyle);
    /******************** Inputs ********************/
    /**
     * Whether the element is visible or not.
     * @group Props
     */
    visible = input(false, ...(ngDevMode ? [{ debugName: "visible" }] : []));
    /**
     * Whether to mount the element on enter.
     * @group Props
     */
    mountOnEnter = input(true, ...(ngDevMode ? [{ debugName: "mountOnEnter" }] : []));
    /**
     * Whether to unmount the element on leave.
     * @group Props
     */
    unmountOnLeave = input(true, ...(ngDevMode ? [{ debugName: "unmountOnLeave" }] : []));
    /**
     * The name of the motion. It can be a predefined motion name or a custom one.
     * phases:
     *     [name]-enter
     *     [name]-enter-active
     *     [name]-enter-to
     *     [name]-leave
     *     [name]-leave-active
     *     [name]-leave-to
     * @group Props
     */
    name = input(undefined, ...(ngDevMode ? [{ debugName: "name" }] : []));
    /**
     * The type of the motion, valid values 'transition' and 'animation'.
     * @group Props
     */
    type = input(undefined, ...(ngDevMode ? [{ debugName: "type" }] : []));
    /**
     * Whether the motion is safe.
     * @group Props
     */
    safe = input(undefined, ...(ngDevMode ? [{ debugName: "safe" }] : []));
    /**
     * Whether the motion is disabled.
     * @group Props
     */
    disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
    /**
     * Whether the motion should appear.
     * @group Props
     */
    appear = input(false, ...(ngDevMode ? [{ debugName: "appear" }] : []));
    /**
     * Whether the motion should enter.
     * @group Props
     */
    enter = input(true, ...(ngDevMode ? [{ debugName: "enter" }] : []));
    /**
     * Whether the motion should leave.
     * @group Props
     */
    leave = input(true, ...(ngDevMode ? [{ debugName: "leave" }] : []));
    /**
     * The duration of the motion.
     * @group Props
     */
    duration = input(undefined, ...(ngDevMode ? [{ debugName: "duration" }] : []));
    /**
     * The hide strategy of the motion, valid values 'display' and 'visibility'.
     * @group Props
     */
    hideStrategy = input('display', ...(ngDevMode ? [{ debugName: "hideStrategy" }] : []));
    /**
     * The enter from class of the motion.
     * @group Props
     */
    enterFromClass = input(undefined, ...(ngDevMode ? [{ debugName: "enterFromClass" }] : []));
    /**
     * The enter to class of the motion.
     * @group Props
     */
    enterToClass = input(undefined, ...(ngDevMode ? [{ debugName: "enterToClass" }] : []));
    /**
     * The enter active class of the motion.
     * @group Props
     */
    enterActiveClass = input(undefined, ...(ngDevMode ? [{ debugName: "enterActiveClass" }] : []));
    /**
     * The leave from class of the motion.
     * @group Props
     */
    leaveFromClass = input(undefined, ...(ngDevMode ? [{ debugName: "leaveFromClass" }] : []));
    /**
     * The leave to class of the motion.
     * @group Props
     */
    leaveToClass = input(undefined, ...(ngDevMode ? [{ debugName: "leaveToClass" }] : []));
    /**
     * The leave active class of the motion.
     * @group Props
     */
    leaveActiveClass = input(undefined, ...(ngDevMode ? [{ debugName: "leaveActiveClass" }] : []));
    /******************** All Inputs ********************/
    /**
     * The motion options.
     * @group Props
     */
    options = input({}, ...(ngDevMode ? [{ debugName: "options" }] : []));
    /******************** Outputs ********************/
    /**
     * Callback fired before the enter transition/animation starts.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onBeforeEnter = output();
    /**
     * Callback fired when the enter transition/animation starts.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onEnter = output();
    /**
     * Callback fired after the enter transition/animation ends.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onAfterEnter = output();
    /**
     * Callback fired when the enter transition/animation is cancelled.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onEnterCancelled = output();
    /**
     * Callback fired before the leave transition/animation starts.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onBeforeLeave = output();
    /**
     * Callback fired when the leave transition/animation starts.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onLeave = output();
    /**
     * Callback fired after the leave transition/animation ends.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onAfterLeave = output();
    /**
     * Callback fired when the leave transition/animation is cancelled.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onLeaveCancelled = output();
    /******************** Computed ********************/
    motionOptions = computed(() => {
        const options = this.options();
        return {
            name: options.name ?? this.name(),
            type: options.type ?? this.type(),
            safe: options.safe ?? this.safe(),
            disabled: options.disabled ?? this.disabled(),
            appear: false,
            enter: options.enter ?? this.enter(),
            leave: options.leave ?? this.leave(),
            duration: options.duration ?? this.duration(),
            enterClass: {
                from: options.enterClass?.from ?? (!options.name ? this.enterFromClass() : undefined),
                to: options.enterClass?.to ?? (!options.name ? this.enterToClass() : undefined),
                active: options.enterClass?.active ?? (!options.name ? this.enterActiveClass() : undefined)
            },
            leaveClass: {
                from: options.leaveClass?.from ?? (!options.name ? this.leaveFromClass() : undefined),
                to: options.leaveClass?.to ?? (!options.name ? this.leaveToClass() : undefined),
                active: options.leaveClass?.active ?? (!options.name ? this.leaveActiveClass() : undefined)
            },
            onBeforeEnter: options.onBeforeEnter ?? this.handleBeforeEnter,
            onEnter: options.onEnter ?? this.handleEnter,
            onAfterEnter: options.onAfterEnter ?? this.handleAfterEnter,
            onEnterCancelled: options.onEnterCancelled ?? this.handleEnterCancelled,
            onBeforeLeave: options.onBeforeLeave ?? this.handleBeforeLeave,
            onLeave: options.onLeave ?? this.handleLeave,
            onAfterLeave: options.onAfterLeave ?? this.handleAfterLeave,
            onLeaveCancelled: options.onLeaveCancelled ?? this.handleLeaveCancelled
        };
    }, ...(ngDevMode ? [{ debugName: "motionOptions" }] : []));
    motion;
    isInitialMount = true;
    cancelled = false;
    destroyed = false;
    rendered = signal(false, ...(ngDevMode ? [{ debugName: "rendered" }] : []));
    handleBeforeEnter = (event) => !this.destroyed && this.onBeforeEnter.emit(event);
    handleEnter = (event) => !this.destroyed && this.onEnter.emit(event);
    handleAfterEnter = (event) => !this.destroyed && this.onAfterEnter.emit(event);
    handleEnterCancelled = (event) => !this.destroyed && this.onEnterCancelled.emit(event);
    handleBeforeLeave = (event) => !this.destroyed && this.onBeforeLeave.emit(event);
    handleLeave = (event) => !this.destroyed && this.onLeave.emit(event);
    handleAfterLeave = (event) => !this.destroyed && this.onAfterLeave.emit(event);
    handleLeaveCancelled = (event) => !this.destroyed && this.onLeaveCancelled.emit(event);
    constructor() {
        super();
        effect(() => {
            const hideStrategy = this.hideStrategy();
            if (this.isInitialMount) {
                applyHiddenStyles(this.$el, hideStrategy);
                this.rendered.set((this.visible() && this.mountOnEnter()) || !this.mountOnEnter());
            }
            else if (this.visible() && !this.rendered()) {
                applyHiddenStyles(this.$el, hideStrategy);
                this.rendered.set(true);
            }
        });
        effect(() => {
            if (!this.motion) {
                this.motion = createMotion(this.$el, this.motionOptions());
            }
            else {
                // @todo: Update motion options method to update options dynamically
                //this.motion.update(this.$el, this.motionOptions());
            }
        });
        afterRenderEffect(async () => {
            if (!this.$el)
                return;
            const shouldAppear = this.isInitialMount && this.visible() && this.appear();
            const hideStrategy = this.hideStrategy();
            if (this.visible()) {
                await nextFrame();
                resetStyles(this.$el, hideStrategy);
                if (shouldAppear || !this.isInitialMount) {
                    this.applyMotionDuration('enter');
                    this.motion?.enter();
                }
            }
            else if (!this.isInitialMount) {
                await nextFrame();
                this.applyMotionDuration('leave');
                this.motion?.leave()?.then(async () => {
                    if (this.$el && !this.cancelled && !this.visible()) {
                        applyHiddenStyles(this.$el, hideStrategy);
                        if (this.unmountOnLeave()) {
                            await nextFrame();
                            if (!this.cancelled) {
                                this.rendered.set(false);
                            }
                        }
                    }
                });
            }
            this.isInitialMount = false;
        });
    }
    applyMotionDuration(phase) {
        const options = untracked(this.motionOptions);
        const ms = resolveDuration(options.duration, phase);
        if (ms == null || !this.$el)
            return;
        const el = this.$el;
        const durationValue = `${ms}ms`;
        if (options.type === 'transition') {
            el.style.transitionDuration = durationValue;
        }
        else {
            el.style.animationDuration = durationValue;
        }
    }
    onDestroy() {
        this.destroyed = true;
        this.cancelled = true;
        this.motion?.cancel();
        this.motion = undefined;
        resetStyles(this.$el, this.hideStrategy());
        this.$el?.remove();
        this.isInitialMount = true;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: Motion, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: Motion, isStandalone: true, selector: "p-motion", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, mountOnEnter: { classPropertyName: "mountOnEnter", publicName: "mountOnEnter", isSignal: true, isRequired: false, transformFunction: null }, unmountOnLeave: { classPropertyName: "unmountOnLeave", publicName: "unmountOnLeave", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, safe: { classPropertyName: "safe", publicName: "safe", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, appear: { classPropertyName: "appear", publicName: "appear", isSignal: true, isRequired: false, transformFunction: null }, enter: { classPropertyName: "enter", publicName: "enter", isSignal: true, isRequired: false, transformFunction: null }, leave: { classPropertyName: "leave", publicName: "leave", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, hideStrategy: { classPropertyName: "hideStrategy", publicName: "hideStrategy", isSignal: true, isRequired: false, transformFunction: null }, enterFromClass: { classPropertyName: "enterFromClass", publicName: "enterFromClass", isSignal: true, isRequired: false, transformFunction: null }, enterToClass: { classPropertyName: "enterToClass", publicName: "enterToClass", isSignal: true, isRequired: false, transformFunction: null }, enterActiveClass: { classPropertyName: "enterActiveClass", publicName: "enterActiveClass", isSignal: true, isRequired: false, transformFunction: null }, leaveFromClass: { classPropertyName: "leaveFromClass", publicName: "leaveFromClass", isSignal: true, isRequired: false, transformFunction: null }, leaveToClass: { classPropertyName: "leaveToClass", publicName: "leaveToClass", isSignal: true, isRequired: false, transformFunction: null }, leaveActiveClass: { classPropertyName: "leaveActiveClass", publicName: "leaveActiveClass", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onBeforeEnter: "onBeforeEnter", onEnter: "onEnter", onAfterEnter: "onAfterEnter", onEnterCancelled: "onEnterCancelled", onBeforeLeave: "onBeforeLeave", onLeave: "onLeave", onAfterLeave: "onAfterLeave", onLeaveCancelled: "onLeaveCancelled" }, host: { properties: { "class": "cx('root')" } }, providers: [MotionStyle, { provide: MOTION_INSTANCE, useExisting: Motion }, { provide: PARENT_INSTANCE, useExisting: Motion }], usesInheritance: true, hostDirectives: [{ directive: i1.Bind }], ngImport: i0, template: `
        @if (rendered()) {
            <ng-content />
        }
    `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: BindModule }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: Motion, decorators: [{
            type: Component,
            args: [{
                    selector: 'p-motion',
                    standalone: true,
                    imports: [CommonModule, BindModule],
                    template: `
        @if (rendered()) {
            <ng-content />
        }
    `,
                    providers: [MotionStyle, { provide: MOTION_INSTANCE, useExisting: Motion }, { provide: PARENT_INSTANCE, useExisting: Motion }],
                    host: {
                        '[class]': "cx('root')"
                    },
                    hostDirectives: [Bind]
                }]
        }], ctorParameters: () => [], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }], mountOnEnter: [{ type: i0.Input, args: [{ isSignal: true, alias: "mountOnEnter", required: false }] }], unmountOnLeave: [{ type: i0.Input, args: [{ isSignal: true, alias: "unmountOnLeave", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], safe: [{ type: i0.Input, args: [{ isSignal: true, alias: "safe", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], appear: [{ type: i0.Input, args: [{ isSignal: true, alias: "appear", required: false }] }], enter: [{ type: i0.Input, args: [{ isSignal: true, alias: "enter", required: false }] }], leave: [{ type: i0.Input, args: [{ isSignal: true, alias: "leave", required: false }] }], duration: [{ type: i0.Input, args: [{ isSignal: true, alias: "duration", required: false }] }], hideStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideStrategy", required: false }] }], enterFromClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "enterFromClass", required: false }] }], enterToClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "enterToClass", required: false }] }], enterActiveClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "enterActiveClass", required: false }] }], leaveFromClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "leaveFromClass", required: false }] }], leaveToClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "leaveToClass", required: false }] }], leaveActiveClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "leaveActiveClass", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], onBeforeEnter: [{ type: i0.Output, args: ["onBeforeEnter"] }], onEnter: [{ type: i0.Output, args: ["onEnter"] }], onAfterEnter: [{ type: i0.Output, args: ["onAfterEnter"] }], onEnterCancelled: [{ type: i0.Output, args: ["onEnterCancelled"] }], onBeforeLeave: [{ type: i0.Output, args: ["onBeforeLeave"] }], onLeave: [{ type: i0.Output, args: ["onLeave"] }], onAfterLeave: [{ type: i0.Output, args: ["onAfterLeave"] }], onLeaveCancelled: [{ type: i0.Output, args: ["onLeaveCancelled"] }] } });

const MOTION_DIRECTIVE_INSTANCE = new InjectionToken('MOTION_DIRECTIVE_INSTANCE');
/**
 * Motion Directive is directive to apply motion effects to elements.
 * @group Components
 */
class MotionDirective extends BaseComponent {
    $pcMotionDirective = inject(MOTION_DIRECTIVE_INSTANCE, { optional: true, skipSelf: true }) ?? undefined;
    /******************** Inputs ********************/
    /**
     * Whether the element is visible or not.
     * @group Props
     */
    visible = input(false, { ...(ngDevMode ? { debugName: "visible" } : {}), alias: 'pMotion' });
    /**
     * The name of the motion. It can be a predefined motion name or a custom one.
     * phases:
     *     [name]-enter
     *     [name]-enter-active
     *     [name]-enter-to
     *     [name]-leave
     *     [name]-leave-active
     *     [name]-leave-to
     * @group Props
     */
    name = input(undefined, { ...(ngDevMode ? { debugName: "name" } : {}), alias: 'pMotionName' });
    /**
     * The type of the motion, valid values 'transition' and 'animation'.
     * @group Props
     */
    type = input(undefined, { ...(ngDevMode ? { debugName: "type" } : {}), alias: 'pMotionType' });
    /**
     * Whether the motion is safe.
     * @group Props
     */
    safe = input(undefined, { ...(ngDevMode ? { debugName: "safe" } : {}), alias: 'pMotionSafe' });
    /**
     * Whether the motion is disabled.
     * @group Props
     */
    disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : {}), alias: 'pMotionDisabled' });
    /**
     * Whether the motion should appear.
     * @group Props
     */
    appear = input(false, { ...(ngDevMode ? { debugName: "appear" } : {}), alias: 'pMotionAppear' });
    /**
     * Whether the motion should enter.
     * @group Props
     */
    enter = input(true, { ...(ngDevMode ? { debugName: "enter" } : {}), alias: 'pMotionEnter' });
    /**
     * Whether the motion should leave.
     * @group Props
     */
    leave = input(true, { ...(ngDevMode ? { debugName: "leave" } : {}), alias: 'pMotionLeave' });
    /**
     * The duration of the motion.
     * @group Props
     */
    duration = input(undefined, { ...(ngDevMode ? { debugName: "duration" } : {}), alias: 'pMotionDuration' });
    /**
     * The hide strategy of the motion, valid values 'display' and 'visibility'.
     * @group Props
     */
    hideStrategy = input('display', { ...(ngDevMode ? { debugName: "hideStrategy" } : {}), alias: 'pMotionHideStrategy' });
    /**
     * The enter from class of the motion.
     * @group Props
     */
    enterFromClass = input(undefined, { ...(ngDevMode ? { debugName: "enterFromClass" } : {}), alias: 'pMotionEnterFromClass' });
    /**
     * The enter to class of the motion.
     * @group Props
     */
    enterToClass = input(undefined, { ...(ngDevMode ? { debugName: "enterToClass" } : {}), alias: 'pMotionEnterToClass' });
    /**
     * The enter active class of the motion.
     * @group Props
     */
    enterActiveClass = input(undefined, { ...(ngDevMode ? { debugName: "enterActiveClass" } : {}), alias: 'pMotionEnterActiveClass' });
    /**
     * The leave from class of the motion.
     * @group Props
     */
    leaveFromClass = input(undefined, { ...(ngDevMode ? { debugName: "leaveFromClass" } : {}), alias: 'pMotionLeaveFromClass' });
    /**
     * The leave to class of the motion.
     * @group Props
     */
    leaveToClass = input(undefined, { ...(ngDevMode ? { debugName: "leaveToClass" } : {}), alias: 'pMotionLeaveToClass' });
    /**
     * The leave active class of the motion.
     * @group Props
     */
    leaveActiveClass = input(undefined, { ...(ngDevMode ? { debugName: "leaveActiveClass" } : {}), alias: 'pMotionLeaveActiveClass' });
    /******************** All Inputs ********************/
    /**
     * The motion options.
     * @group Props
     */
    options = input({}, { ...(ngDevMode ? { debugName: "options" } : {}), alias: 'pMotionOptions' });
    /******************** Outputs ********************/
    /**
     * Callback fired before the enter transition/animation starts.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onBeforeEnter = output({ alias: 'pMotionOnBeforeEnter' });
    /**
     * Callback fired when the enter transition/animation starts.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onEnter = output({ alias: 'pMotionOnEnter' });
    /**
     * Callback fired after the enter transition/animation ends.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onAfterEnter = output({ alias: 'pMotionOnAfterEnter' });
    /**
     * Callback fired when the enter transition/animation is cancelled.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onEnterCancelled = output({ alias: 'pMotionOnEnterCancelled' });
    /**
     * Callback fired before the leave transition/animation starts.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onBeforeLeave = output({ alias: 'pMotionOnBeforeLeave' });
    /**
     * Callback fired when the leave transition/animation starts.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onLeave = output({ alias: 'pMotionOnLeave' });
    /**
     * Callback fired after the leave transition/animation ends.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onAfterLeave = output({ alias: 'pMotionOnAfterLeave' });
    /**
     * Callback fired when the leave transition/animation is cancelled.
     * @param {MotionEvent} [event] - The event object containing details about the motion.
     * @param {Element} event.element - The element being transitioned/animated.
     * @group Emits
     */
    onLeaveCancelled = output({ alias: 'pMotionOnLeaveCancelled' });
    /******************** Computed ********************/
    motionOptions = computed(() => {
        const options = this.options() ?? {};
        return {
            name: options.name ?? this.name(),
            type: options.type ?? this.type(),
            safe: options.safe ?? this.safe(),
            disabled: options.disabled ?? this.disabled(),
            appear: false,
            enter: options.enter ?? this.enter(),
            leave: options.leave ?? this.leave(),
            duration: options.duration ?? this.duration(),
            enterClass: {
                from: options.enterClass?.from ?? (!options.name ? this.enterFromClass() : undefined),
                to: options.enterClass?.to ?? (!options.name ? this.enterToClass() : undefined),
                active: options.enterClass?.active ?? (!options.name ? this.enterActiveClass() : undefined)
            },
            leaveClass: {
                from: options.leaveClass?.from ?? (!options.name ? this.leaveFromClass() : undefined),
                to: options.leaveClass?.to ?? (!options.name ? this.leaveToClass() : undefined),
                active: options.leaveClass?.active ?? (!options.name ? this.leaveActiveClass() : undefined)
            },
            onBeforeEnter: options.onBeforeEnter ?? this.handleBeforeEnter,
            onEnter: options.onEnter ?? this.handleEnter,
            onAfterEnter: options.onAfterEnter ?? this.handleAfterEnter,
            onEnterCancelled: options.onEnterCancelled ?? this.handleEnterCancelled,
            onBeforeLeave: options.onBeforeLeave ?? this.handleBeforeLeave,
            onLeave: options.onLeave ?? this.handleLeave,
            onAfterLeave: options.onAfterLeave ?? this.handleAfterLeave,
            onLeaveCancelled: options.onLeaveCancelled ?? this.handleLeaveCancelled
        };
    }, ...(ngDevMode ? [{ debugName: "motionOptions" }] : []));
    motion;
    isInitialMount = true;
    cancelled = false;
    destroyed = false;
    handleBeforeEnter = (event) => !this.destroyed && this.onBeforeEnter.emit(event);
    handleEnter = (event) => !this.destroyed && this.onEnter.emit(event);
    handleAfterEnter = (event) => !this.destroyed && this.onAfterEnter.emit(event);
    handleEnterCancelled = (event) => !this.destroyed && this.onEnterCancelled.emit(event);
    handleBeforeLeave = (event) => !this.destroyed && this.onBeforeLeave.emit(event);
    handleLeave = (event) => !this.destroyed && this.onLeave.emit(event);
    handleAfterLeave = (event) => !this.destroyed && this.onAfterLeave.emit(event);
    handleLeaveCancelled = (event) => !this.destroyed && this.onLeaveCancelled.emit(event);
    constructor() {
        super();
        effect(() => {
            if (!this.motion) {
                this.motion = createMotion(this.$el, this.motionOptions());
            }
            else {
                // @todo: Update motion options method to update options dynamically
                //this.motion.update(this.$el, this.motionOptions());
            }
        });
        afterRenderEffect(() => {
            if (!this.$el)
                return;
            const shouldAppear = this.isInitialMount && this.visible() && this.appear();
            const hideStrategy = this.hideStrategy();
            if (this.visible()) {
                resetStyles(this.$el, hideStrategy);
                if (shouldAppear || !this.isInitialMount) {
                    this.applyMotionDuration('enter');
                    this.motion?.enter();
                }
            }
            else if (!this.isInitialMount) {
                this.applyMotionDuration('leave');
                this.motion?.leave()?.then(() => {
                    if (this.$el && !this.cancelled && !this.visible()) {
                        applyHiddenStyles(this.$el, hideStrategy);
                    }
                });
            }
            else {
                applyHiddenStyles(this.$el, hideStrategy);
            }
            this.isInitialMount = false;
        });
    }
    applyMotionDuration(phase) {
        const options = untracked(this.motionOptions);
        const ms = resolveDuration(options.duration, phase);
        if (ms == null || !this.$el)
            return;
        const el = this.$el;
        const durationValue = `${ms}ms`;
        if (options.type === 'transition') {
            el.style.transitionDuration = durationValue;
        }
        else {
            el.style.animationDuration = durationValue;
        }
    }
    onDestroy() {
        this.destroyed = true;
        this.cancelled = true;
        this.motion?.cancel();
        this.motion = undefined;
        resetStyles(this.$el, this.hideStrategy());
        this.isInitialMount = true;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MotionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.0", type: MotionDirective, isStandalone: true, selector: "[pMotion]", inputs: { visible: { classPropertyName: "visible", publicName: "pMotion", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "pMotionName", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "pMotionType", isSignal: true, isRequired: false, transformFunction: null }, safe: { classPropertyName: "safe", publicName: "pMotionSafe", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "pMotionDisabled", isSignal: true, isRequired: false, transformFunction: null }, appear: { classPropertyName: "appear", publicName: "pMotionAppear", isSignal: true, isRequired: false, transformFunction: null }, enter: { classPropertyName: "enter", publicName: "pMotionEnter", isSignal: true, isRequired: false, transformFunction: null }, leave: { classPropertyName: "leave", publicName: "pMotionLeave", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "pMotionDuration", isSignal: true, isRequired: false, transformFunction: null }, hideStrategy: { classPropertyName: "hideStrategy", publicName: "pMotionHideStrategy", isSignal: true, isRequired: false, transformFunction: null }, enterFromClass: { classPropertyName: "enterFromClass", publicName: "pMotionEnterFromClass", isSignal: true, isRequired: false, transformFunction: null }, enterToClass: { classPropertyName: "enterToClass", publicName: "pMotionEnterToClass", isSignal: true, isRequired: false, transformFunction: null }, enterActiveClass: { classPropertyName: "enterActiveClass", publicName: "pMotionEnterActiveClass", isSignal: true, isRequired: false, transformFunction: null }, leaveFromClass: { classPropertyName: "leaveFromClass", publicName: "pMotionLeaveFromClass", isSignal: true, isRequired: false, transformFunction: null }, leaveToClass: { classPropertyName: "leaveToClass", publicName: "pMotionLeaveToClass", isSignal: true, isRequired: false, transformFunction: null }, leaveActiveClass: { classPropertyName: "leaveActiveClass", publicName: "pMotionLeaveActiveClass", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "pMotionOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onBeforeEnter: "pMotionOnBeforeEnter", onEnter: "pMotionOnEnter", onAfterEnter: "pMotionOnAfterEnter", onEnterCancelled: "pMotionOnEnterCancelled", onBeforeLeave: "pMotionOnBeforeLeave", onLeave: "pMotionOnLeave", onAfterLeave: "pMotionOnAfterLeave", onLeaveCancelled: "pMotionOnLeaveCancelled" }, providers: [MotionStyle, { provide: MOTION_DIRECTIVE_INSTANCE, useExisting: MotionDirective }, { provide: PARENT_INSTANCE, useExisting: MotionDirective }], usesInheritance: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MotionDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[pMotion]',
                    standalone: true,
                    providers: [MotionStyle, { provide: MOTION_DIRECTIVE_INSTANCE, useExisting: MotionDirective }, { provide: PARENT_INSTANCE, useExisting: MotionDirective }]
                }]
        }], ctorParameters: () => [], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotion", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionName", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionType", required: false }] }], safe: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionSafe", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionDisabled", required: false }] }], appear: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionAppear", required: false }] }], enter: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionEnter", required: false }] }], leave: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionLeave", required: false }] }], duration: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionDuration", required: false }] }], hideStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionHideStrategy", required: false }] }], enterFromClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionEnterFromClass", required: false }] }], enterToClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionEnterToClass", required: false }] }], enterActiveClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionEnterActiveClass", required: false }] }], leaveFromClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionLeaveFromClass", required: false }] }], leaveToClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionLeaveToClass", required: false }] }], leaveActiveClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionLeaveActiveClass", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "pMotionOptions", required: false }] }], onBeforeEnter: [{ type: i0.Output, args: ["pMotionOnBeforeEnter"] }], onEnter: [{ type: i0.Output, args: ["pMotionOnEnter"] }], onAfterEnter: [{ type: i0.Output, args: ["pMotionOnAfterEnter"] }], onEnterCancelled: [{ type: i0.Output, args: ["pMotionOnEnterCancelled"] }], onBeforeLeave: [{ type: i0.Output, args: ["pMotionOnBeforeLeave"] }], onLeave: [{ type: i0.Output, args: ["pMotionOnLeave"] }], onAfterLeave: [{ type: i0.Output, args: ["pMotionOnAfterLeave"] }], onLeaveCancelled: [{ type: i0.Output, args: ["pMotionOnLeaveCancelled"] }] } });

class MotionModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MotionModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: MotionModule, imports: [Motion, MotionDirective], exports: [Motion, MotionDirective] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MotionModule, imports: [Motion] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MotionModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [Motion, MotionDirective],
                    exports: [Motion, MotionDirective]
                }]
        }] });

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

export { Motion, MotionDirective, MotionModule };
//# sourceMappingURL=primeng-motion.mjs.map
