import { MotionConfigContext, animate } from 'motion/react';
import { useRef, useImperativeHandle, use, useCallback, useEffect, createElement } from 'react';
import { useLatestFunction } from './useLatestFunction.mjs';
import { usePointCompareMemo, usePointCompareEffect } from './usePointCompare.mjs';

"use strict";
const basicProps = [
  "alpha",
  "angle",
  "rotation",
  "x",
  "y",
  "width",
  "height"
];
const nestedProps = ["scale", "pivot", "position", "skew"];
const supportedProps = [...basicProps, ...nestedProps];
const filterTransition = (transition) => {
  if (transition === void 0) return void 0;
  const withRemovedKeys = Object.fromEntries(
    Object.entries(transition).filter(([key]) => !(key in supportedProps))
  );
  if (Object.keys(withRemovedKeys).length === 0) return void 0;
  return withRemovedKeys;
};
function createMotionComponent(Component) {
  return function MotionComponent({
    initial,
    animate: animate$1,
    ref: userRef,
    transition,
    ...props
  }) {
    const ref = useRef(null);
    useImperativeHandle(userRef, () => ref.current);
    const firstRenderRef = useRef(true);
    const defaultTransition = use(MotionConfigContext).transition;
    const getTransitionDetails = useLatestFunction(
      (property) => {
        const scopedVague = animate$1?.transition;
        const scopedSpecific = animate$1?.transition?.[property];
        const transitionPropertyVague = transition;
        const transitionPropertySpecific = transition?.[property];
        const motionConfigVague = defaultTransition;
        const motionConfigSpecific = defaultTransition?.[property];
        return filterTransition(scopedSpecific) ?? filterTransition(scopedVague) ?? filterTransition(transitionPropertySpecific) ?? filterTransition(transitionPropertyVague) ?? filterTransition(motionConfigSpecific) ?? filterTransition(motionConfigVague);
      }
    );
    const useInstantState = (key) => {
      const instantValue = props[key];
      const initialValue = useRef(initial?.[key] ?? instantValue ?? animate$1?.[key]).current;
      return usePointCompareMemo(() => {
        if (firstRenderRef.current) return initialValue;
        return instantValue;
      }, instantValue);
    };
    const runningAnimations = useRef({});
    const saveAnimation = useCallback((key, value) => {
      var _a;
      (_a = runningAnimations.current)[key] ?? (_a[key] = []);
      runningAnimations.current[key].push(value);
    }, []);
    const clear = useCallback((key) => {
      runningAnimations.current[key]?.forEach((animation) => animation.stop());
      runningAnimations.current[key] = [];
    }, []);
    const to = useCallback(
      (key, value) => {
        if (value === void 0) return;
        if (!ref.current) return;
        const transition2 = getTransitionDetails(key);
        if (typeof value === "object") {
          const nestedValue = ref.current?.[key];
          const { x, y } = value;
          if (!nestedValue) return;
          if (x !== void 0) {
            saveAnimation(key, animate(nestedValue, {
              x: [
                nestedValue.x,
                x
              ]
            }, transition2));
          }
          if (y !== void 0) {
            saveAnimation(key, animate(nestedValue, {
              y: [
                nestedValue.y,
                y
              ]
            }, transition2));
          }
        } else {
          saveAnimation(key, animate(ref.current, { [key]: value }, transition2));
        }
      },
      [getTransitionDetails]
    );
    const propsToPass = useRef({});
    for (const key of supportedProps) {
      propsToPass.current[key] = useInstantState(key);
      usePointCompareEffect(() => () => clear(key), props[key]);
      usePointCompareEffect(() => to(key, animate$1?.[key]), animate$1?.[key]);
    }
    useEffect(() => {
      firstRenderRef.current = false;
    }, []);
    return createElement(Component, {
      ...props,
      ...propsToPass.current,
      ref
    });
  };
}

export { createMotionComponent };
//# sourceMappingURL=createMotionComponent.mjs.map
