framer-motion 12.23.27 → 12.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/cjs/client.js +1 -1
  2. package/dist/cjs/{feature-bundle-kvRbMDEA.js → feature-bundle-DhbxBqkJ.js} +32 -15
  3. package/dist/cjs/feature-bundle-DhbxBqkJ.js.map +1 -0
  4. package/dist/cjs/index.js +1 -1
  5. package/dist/cjs/index.js.map +1 -1
  6. package/dist/cjs/m.js +14 -11
  7. package/dist/cjs/m.js.map +1 -1
  8. package/dist/dom-mini.js +1 -1
  9. package/dist/dom.js +1 -1
  10. package/dist/es/components/Reorder/Group.mjs.map +1 -1
  11. package/dist/es/gestures/drag/index.mjs +10 -0
  12. package/dist/es/gestures/drag/index.mjs.map +1 -1
  13. package/dist/es/motion/index.mjs +10 -6
  14. package/dist/es/motion/index.mjs.map +1 -1
  15. package/dist/es/motion/utils/use-visual-element.mjs +2 -1
  16. package/dist/es/motion/utils/use-visual-element.mjs.map +1 -1
  17. package/dist/es/projection/geometry/delta-apply.mjs +1 -1
  18. package/dist/es/projection/geometry/delta-apply.mjs.map +1 -1
  19. package/dist/es/projection/node/create-projection-node.mjs +1 -1
  20. package/dist/es/projection/node/create-projection-node.mjs.map +1 -1
  21. package/dist/es/render/dom/create-visual-element.mjs +5 -1
  22. package/dist/es/render/dom/create-visual-element.mjs.map +1 -1
  23. package/dist/es/render/dom/use-render.mjs +2 -4
  24. package/dist/es/render/dom/use-render.mjs.map +1 -1
  25. package/dist/framer-motion.dev.js +73 -17
  26. package/dist/framer-motion.js +1 -1
  27. package/dist/m.d.ts +9 -1
  28. package/dist/mini.js +1 -1
  29. package/dist/size-rollup-animate.js +1 -1
  30. package/dist/size-rollup-animate.js.map +1 -1
  31. package/dist/size-rollup-dom-animation-assets.js +1 -1
  32. package/dist/size-rollup-dom-animation-m.js +1 -1
  33. package/dist/size-rollup-dom-animation.js +1 -1
  34. package/dist/size-rollup-dom-max-assets.js +1 -1
  35. package/dist/size-rollup-dom-max.js +1 -1
  36. package/dist/size-rollup-m.js +1 -1
  37. package/dist/size-rollup-m.js.map +1 -1
  38. package/dist/size-rollup-motion.js +1 -1
  39. package/dist/size-rollup-motion.js.map +1 -1
  40. package/dist/size-rollup-scroll.js +1 -1
  41. package/dist/size-rollup-scroll.js.map +1 -1
  42. package/dist/size-rollup-waapi-animate.js +1 -1
  43. package/dist/size-rollup-waapi-animate.js.map +1 -1
  44. package/dist/types/client.d.ts +1 -1
  45. package/dist/types/index.d.ts +13 -5
  46. package/dist/{types.d-DagZKalS.d.ts → types.d-a9pt5qxk.d.ts} +6 -1
  47. package/package.json +4 -4
  48. package/dist/cjs/feature-bundle-kvRbMDEA.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../src/motion/index.tsx"],"sourcesContent":["\"use client\"\n\nimport { invariant, warning } from \"motion-utils\"\nimport * as React from \"react\"\nimport { forwardRef, useContext } from \"react\"\nimport { LayoutGroupContext } from \"../context/LayoutGroupContext\"\nimport { LazyContext } from \"../context/LazyContext\"\nimport { MotionConfigContext } from \"../context/MotionConfigContext\"\nimport { MotionContext } from \"../context/MotionContext\"\nimport { useCreateMotionContext } from \"../context/MotionContext/create\"\nimport { DOMMotionComponents } from \"../render/dom/types\"\nimport { useRender } from \"../render/dom/use-render\"\nimport { isSVGComponent } from \"../render/dom/utils/is-svg-component\"\nimport { HTMLRenderState } from \"../render/html/types\"\nimport { useHTMLVisualState } from \"../render/html/use-html-visual-state\"\nimport { SVGRenderState } from \"../render/svg/types\"\nimport { useSVGVisualState } from \"../render/svg/use-svg-visual-state\"\nimport { CreateVisualElement } from \"../render/types\"\nimport { isBrowser } from \"../utils/is-browser\"\nimport { featureDefinitions } from \"./features/definitions\"\nimport { loadFeatures } from \"./features/load-features\"\nimport { FeatureBundle, FeaturePackages } from \"./features/types\"\nimport { MotionProps } from \"./types\"\nimport { motionComponentSymbol } from \"./utils/symbol\"\nimport { useMotionRef } from \"./utils/use-motion-ref\"\nimport { useVisualElement } from \"./utils/use-visual-element\"\n\nexport interface MotionComponentConfig<\n TagName extends keyof DOMMotionComponents | string = \"div\"\n> {\n preloadedFeatures?: FeatureBundle\n createVisualElement?: CreateVisualElement\n Component: TagName | React.ComponentType<React.PropsWithChildren<unknown>>\n forwardMotionProps?: boolean\n}\n\nexport type MotionComponentProps<Props> = {\n [K in Exclude<keyof Props, keyof MotionProps>]?: Props[K]\n} & MotionProps\n\nexport type MotionComponent<T, P> = T extends keyof DOMMotionComponents\n ? DOMMotionComponents[T]\n : React.ComponentType<\n Omit<MotionComponentProps<P>, \"children\"> & {\n children?: \"children\" extends keyof P\n ? P[\"children\"] | MotionComponentProps<P>[\"children\"]\n : MotionComponentProps<P>[\"children\"]\n }\n >\n\nexport interface MotionComponentOptions {\n forwardMotionProps?: boolean\n}\n\n/**\n * Create a `motion` component.\n *\n * This function accepts a Component argument, which can be either a string (ie \"div\"\n * for `motion.div`), or an actual React component.\n *\n * Alongside this is a config option which provides a way of rendering the provided\n * component \"offline\", or outside the React render cycle.\n */\nexport function createMotionComponent<\n Props,\n TagName extends keyof DOMMotionComponents | string = \"div\"\n>(\n Component: TagName | string | React.ComponentType<Props>,\n { forwardMotionProps = false }: MotionComponentOptions = {},\n preloadedFeatures?: FeaturePackages,\n createVisualElement?: CreateVisualElement<Props, TagName>\n) {\n preloadedFeatures && loadFeatures(preloadedFeatures)\n\n const useVisualState = isSVGComponent(Component)\n ? useSVGVisualState\n : useHTMLVisualState\n\n function MotionDOMComponent(\n props: MotionComponentProps<Props>,\n externalRef?: React.Ref<HTMLElement | SVGElement>\n ) {\n /**\n * If we need to measure the element we load this functionality in a\n * separate class component in order to gain access to getSnapshotBeforeUpdate.\n */\n let MeasureLayout: undefined | React.ComponentType<MotionProps>\n\n const configAndProps = {\n ...useContext(MotionConfigContext),\n ...props,\n layoutId: useLayoutId(props),\n }\n\n const { isStatic } = configAndProps\n\n const context = useCreateMotionContext<HTMLElement | SVGElement>(props)\n\n const visualState = useVisualState(props, isStatic)\n\n if (!isStatic && isBrowser) {\n useStrictMode(configAndProps, preloadedFeatures)\n\n const layoutProjection = getProjectionFunctionality(configAndProps)\n MeasureLayout = layoutProjection.MeasureLayout\n\n /**\n * Create a VisualElement for this component. A VisualElement provides a common\n * interface to renderer-specific APIs (ie DOM/Three.js etc) as well as\n * providing a way of rendering to these APIs outside of the React render loop\n * for more performant animations and interactions\n */\n context.visualElement = useVisualElement(\n Component,\n visualState,\n configAndProps,\n createVisualElement,\n layoutProjection.ProjectionNode\n )\n }\n\n /**\n * The mount order and hierarchy is specific to ensure our element ref\n * is hydrated by the time features fire their effects.\n */\n return (\n <MotionContext.Provider value={context}>\n {MeasureLayout && context.visualElement ? (\n <MeasureLayout\n visualElement={context.visualElement}\n {...configAndProps}\n />\n ) : null}\n {useRender<Props, TagName>(\n Component,\n props,\n useMotionRef<\n HTMLElement | SVGElement,\n HTMLRenderState | SVGRenderState\n >(visualState, context.visualElement, externalRef),\n visualState,\n isStatic,\n forwardMotionProps\n )}\n </MotionContext.Provider>\n )\n }\n\n MotionDOMComponent.displayName = `motion.${\n typeof Component === \"string\"\n ? Component\n : `create(${Component.displayName ?? Component.name ?? \"\"})`\n }`\n\n const ForwardRefMotionComponent = forwardRef(MotionDOMComponent as any)\n ;(ForwardRefMotionComponent as any)[motionComponentSymbol] = Component\n\n return ForwardRefMotionComponent as MotionComponent<TagName, Props>\n}\n\nfunction useLayoutId({ layoutId }: MotionProps) {\n const layoutGroupId = useContext(LayoutGroupContext).id\n return layoutGroupId && layoutId !== undefined\n ? layoutGroupId + \"-\" + layoutId\n : layoutId\n}\n\nfunction useStrictMode(\n configAndProps: MotionProps,\n preloadedFeatures?: FeaturePackages\n) {\n const isStrict = useContext(LazyContext).strict\n\n /**\n * If we're in development mode, check to make sure we're not rendering a motion component\n * as a child of LazyMotion, as this will break the file-size benefits of using it.\n */\n if (\n process.env.NODE_ENV !== \"production\" &&\n preloadedFeatures &&\n isStrict\n ) {\n const strictMessage =\n \"You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.\"\n configAndProps.ignoreStrict\n ? warning(false, strictMessage, \"lazy-strict-mode\")\n : invariant(false, strictMessage, \"lazy-strict-mode\")\n }\n}\n\nfunction getProjectionFunctionality(props: MotionProps) {\n const { drag, layout } = featureDefinitions\n\n if (!drag && !layout) return {}\n\n const combined = { ...drag, ...layout }\n\n return {\n MeasureLayout:\n drag?.isEnabled(props) || layout?.isEnabled(props)\n ? combined.MeasureLayout\n : undefined,\n ProjectionNode: combined.ProjectionNode,\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAsDA;;;;;;;;AAQG;AACa;AASZ;AAEA;AACI;;AAGJ;AAII;;;AAGG;AACH;AAEA;;AAEI;AACA;;AAGJ;AAEA;;AAIA;AACI;AAEA;AACA;AAEA;;;;;AAKG;AACH;;AASJ;;;AAGG;AACH;;AAuBJ;AAEQ;AACA;AAGR;AACE;AAEF;AACJ;AAEA;;AAEI;AACI;;AAER;AAEA;;AAMI;;;AAGG;AACH;;AAGI;;AAIA;;;;AAIR;AAEA;AACI;AAEA;AAAsB;;;AAKlB;;AAGQ;;;AAGhB;;"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../src/motion/index.tsx"],"sourcesContent":["\"use client\"\n\nimport { invariant, warning } from \"motion-utils\"\nimport * as React from \"react\"\nimport { forwardRef, useContext } from \"react\"\nimport { LayoutGroupContext } from \"../context/LayoutGroupContext\"\nimport { LazyContext } from \"../context/LazyContext\"\nimport { MotionConfigContext } from \"../context/MotionConfigContext\"\nimport { MotionContext } from \"../context/MotionContext\"\nimport { useCreateMotionContext } from \"../context/MotionContext/create\"\nimport { DOMMotionComponents } from \"../render/dom/types\"\nimport { useRender } from \"../render/dom/use-render\"\nimport { isSVGComponent } from \"../render/dom/utils/is-svg-component\"\nimport { HTMLRenderState } from \"../render/html/types\"\nimport { useHTMLVisualState } from \"../render/html/use-html-visual-state\"\nimport { SVGRenderState } from \"../render/svg/types\"\nimport { useSVGVisualState } from \"../render/svg/use-svg-visual-state\"\nimport { CreateVisualElement } from \"../render/types\"\nimport { isBrowser } from \"../utils/is-browser\"\nimport { featureDefinitions } from \"./features/definitions\"\nimport { loadFeatures } from \"./features/load-features\"\nimport { FeatureBundle, FeaturePackages } from \"./features/types\"\nimport { MotionProps } from \"./types\"\nimport { motionComponentSymbol } from \"./utils/symbol\"\nimport { useMotionRef } from \"./utils/use-motion-ref\"\nimport { useVisualElement } from \"./utils/use-visual-element\"\n\nexport interface MotionComponentConfig<\n TagName extends keyof DOMMotionComponents | string = \"div\"\n> {\n preloadedFeatures?: FeatureBundle\n createVisualElement?: CreateVisualElement\n Component: TagName | React.ComponentType<React.PropsWithChildren<unknown>>\n forwardMotionProps?: boolean\n}\n\nexport type MotionComponentProps<Props> = {\n [K in Exclude<keyof Props, keyof MotionProps>]?: Props[K]\n} & MotionProps\n\nexport type MotionComponent<T, P> = T extends keyof DOMMotionComponents\n ? DOMMotionComponents[T]\n : React.ComponentType<\n Omit<MotionComponentProps<P>, \"children\"> & {\n children?: \"children\" extends keyof P\n ? P[\"children\"] | MotionComponentProps<P>[\"children\"]\n : MotionComponentProps<P>[\"children\"]\n }\n >\n\nexport interface MotionComponentOptions {\n forwardMotionProps?: boolean\n /**\n * Specify whether the component renders an HTML or SVG element.\n * This is useful when wrapping custom SVG components that need\n * SVG-specific attribute handling (like viewBox animation).\n * By default, Motion auto-detects based on the component name,\n * but custom React components are always treated as HTML.\n */\n type?: \"html\" | \"svg\"\n}\n\n/**\n * Create a `motion` component.\n *\n * This function accepts a Component argument, which can be either a string (ie \"div\"\n * for `motion.div`), or an actual React component.\n *\n * Alongside this is a config option which provides a way of rendering the provided\n * component \"offline\", or outside the React render cycle.\n */\nexport function createMotionComponent<\n Props,\n TagName extends keyof DOMMotionComponents | string = \"div\"\n>(\n Component: TagName | string | React.ComponentType<Props>,\n { forwardMotionProps = false, type }: MotionComponentOptions = {},\n preloadedFeatures?: FeaturePackages,\n createVisualElement?: CreateVisualElement<Props, TagName>\n) {\n preloadedFeatures && loadFeatures(preloadedFeatures)\n\n /**\n * Determine whether to use SVG or HTML rendering based on:\n * 1. Explicit `type` option (highest priority)\n * 2. Auto-detection via `isSVGComponent`\n */\n const isSVG = type ? type === \"svg\" : isSVGComponent(Component)\n const useVisualState = isSVG ? useSVGVisualState : useHTMLVisualState\n\n function MotionDOMComponent(\n props: MotionComponentProps<Props>,\n externalRef?: React.Ref<HTMLElement | SVGElement>\n ) {\n /**\n * If we need to measure the element we load this functionality in a\n * separate class component in order to gain access to getSnapshotBeforeUpdate.\n */\n let MeasureLayout: undefined | React.ComponentType<MotionProps>\n\n const configAndProps = {\n ...useContext(MotionConfigContext),\n ...props,\n layoutId: useLayoutId(props),\n }\n\n const { isStatic } = configAndProps\n\n const context = useCreateMotionContext<HTMLElement | SVGElement>(props)\n\n const visualState = useVisualState(props, isStatic)\n\n if (!isStatic && isBrowser) {\n useStrictMode(configAndProps, preloadedFeatures)\n\n const layoutProjection = getProjectionFunctionality(configAndProps)\n MeasureLayout = layoutProjection.MeasureLayout\n\n /**\n * Create a VisualElement for this component. A VisualElement provides a common\n * interface to renderer-specific APIs (ie DOM/Three.js etc) as well as\n * providing a way of rendering to these APIs outside of the React render loop\n * for more performant animations and interactions\n */\n context.visualElement = useVisualElement(\n Component,\n visualState,\n configAndProps,\n createVisualElement,\n layoutProjection.ProjectionNode,\n isSVG\n )\n }\n\n /**\n * The mount order and hierarchy is specific to ensure our element ref\n * is hydrated by the time features fire their effects.\n */\n return (\n <MotionContext.Provider value={context}>\n {MeasureLayout && context.visualElement ? (\n <MeasureLayout\n visualElement={context.visualElement}\n {...configAndProps}\n />\n ) : null}\n {useRender<Props, TagName>(\n Component,\n props,\n useMotionRef<\n HTMLElement | SVGElement,\n HTMLRenderState | SVGRenderState\n >(visualState, context.visualElement, externalRef),\n visualState,\n isStatic,\n forwardMotionProps,\n isSVG\n )}\n </MotionContext.Provider>\n )\n }\n\n MotionDOMComponent.displayName = `motion.${\n typeof Component === \"string\"\n ? Component\n : `create(${Component.displayName ?? Component.name ?? \"\"})`\n }`\n\n const ForwardRefMotionComponent = forwardRef(MotionDOMComponent as any)\n ;(ForwardRefMotionComponent as any)[motionComponentSymbol] = Component\n\n return ForwardRefMotionComponent as MotionComponent<TagName, Props>\n}\n\nfunction useLayoutId({ layoutId }: MotionProps) {\n const layoutGroupId = useContext(LayoutGroupContext).id\n return layoutGroupId && layoutId !== undefined\n ? layoutGroupId + \"-\" + layoutId\n : layoutId\n}\n\nfunction useStrictMode(\n configAndProps: MotionProps,\n preloadedFeatures?: FeaturePackages\n) {\n const isStrict = useContext(LazyContext).strict\n\n /**\n * If we're in development mode, check to make sure we're not rendering a motion component\n * as a child of LazyMotion, as this will break the file-size benefits of using it.\n */\n if (\n process.env.NODE_ENV !== \"production\" &&\n preloadedFeatures &&\n isStrict\n ) {\n const strictMessage =\n \"You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.\"\n configAndProps.ignoreStrict\n ? warning(false, strictMessage, \"lazy-strict-mode\")\n : invariant(false, strictMessage, \"lazy-strict-mode\")\n }\n}\n\nfunction getProjectionFunctionality(props: MotionProps) {\n const { drag, layout } = featureDefinitions\n\n if (!drag && !layout) return {}\n\n const combined = { ...drag, ...layout }\n\n return {\n MeasureLayout:\n drag?.isEnabled(props) || layout?.isEnabled(props)\n ? combined.MeasureLayout\n : undefined,\n ProjectionNode: combined.ProjectionNode,\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AA8DA;;;;;;;;AAQG;;AAUC;AAEA;;;;AAIG;AACH;;AAGA;AAII;;;AAGG;AACH;AAEA;;AAEI;AACA;;AAGJ;AAEA;;AAIA;AACI;AAEA;AACA;AAEA;;;;;AAKG;AACH;;AAUJ;;;AAGG;AACH;;AAwBJ;AAEQ;AACA;AAGR;AACE;AAEF;AACJ;AAEA;;AAEI;AACI;;AAER;AAEA;;AAMI;;;AAGG;AACH;;AAGI;;AAIA;;;;AAIR;AAEA;AACI;AAEA;AAAsB;;;AAKlB;;AAGQ;;;AAGhB;;"}
@@ -9,7 +9,7 @@ import { SwitchLayoutGroupContext } from '../../context/SwitchLayoutGroupContext
9
9
  import { isRefObject } from '../../utils/is-ref-object.mjs';
10
10
  import { useIsomorphicLayoutEffect } from '../../utils/use-isomorphic-effect.mjs';
11
11
 
12
- function useVisualElement(Component, visualState, props, createVisualElement, ProjectionNodeConstructor) {
12
+ function useVisualElement(Component, visualState, props, createVisualElement, ProjectionNodeConstructor, isSVG) {
13
13
  const { visualElement: parent } = useContext(MotionContext);
14
14
  const lazyContext = useContext(LazyContext);
15
15
  const presenceContext = useContext(PresenceContext);
@@ -31,6 +31,7 @@ function useVisualElement(Component, visualState, props, createVisualElement, Pr
31
31
  ? presenceContext.initial === false
32
32
  : false,
33
33
  reducedMotionConfig,
34
+ isSVG,
34
35
  });
35
36
  }
36
37
  const visualElement = visualElementRef.current;
@@ -1 +1 @@
1
- {"version":3,"file":"use-visual-element.mjs","sources":["../../../../src/motion/utils/use-visual-element.ts"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { useContext, useEffect, useInsertionEffect, useRef } from \"react\"\nimport { optimizedAppearDataAttribute } from \"../../animation/optimized-appear/data-id\"\nimport { LazyContext } from \"../../context/LazyContext\"\nimport { MotionConfigContext } from \"../../context/MotionConfigContext\"\nimport { MotionContext } from \"../../context/MotionContext\"\nimport { PresenceContext } from \"../../context/PresenceContext\"\nimport {\n InitialPromotionConfig,\n SwitchLayoutGroupContext,\n} from \"../../context/SwitchLayoutGroupContext\"\nimport { MotionProps } from \"../../motion/types\"\nimport { IProjectionNode } from \"../../projection/node/types\"\nimport { DOMMotionComponents } from \"../../render/dom/types\"\nimport { HTMLRenderState } from \"../../render/html/types\"\nimport { SVGRenderState } from \"../../render/svg/types\"\nimport { CreateVisualElement } from \"../../render/types\"\nimport type { VisualElement } from \"../../render/VisualElement\"\nimport { isRefObject } from \"../../utils/is-ref-object\"\nimport { useIsomorphicLayoutEffect } from \"../../utils/use-isomorphic-effect\"\nimport { VisualState } from \"./use-visual-state\"\n\nexport function useVisualElement<\n Props,\n TagName extends keyof DOMMotionComponents | string\n>(\n Component: TagName | string | React.ComponentType<Props>,\n visualState:\n | VisualState<SVGElement, SVGRenderState>\n | VisualState<HTMLElement, HTMLRenderState>,\n props: MotionProps & Partial<MotionConfigContext>,\n createVisualElement?: CreateVisualElement<Props, TagName>,\n ProjectionNodeConstructor?: any\n): VisualElement<HTMLElement | SVGElement> | undefined {\n const { visualElement: parent } = useContext(MotionContext)\n const lazyContext = useContext(LazyContext)\n const presenceContext = useContext(PresenceContext)\n const reducedMotionConfig = useContext(MotionConfigContext).reducedMotion\n\n const visualElementRef = useRef<VisualElement<\n HTMLElement | SVGElement\n > | null>(null)\n\n /**\n * If we haven't preloaded a renderer, check to see if we have one lazy-loaded\n */\n createVisualElement =\n createVisualElement ||\n (lazyContext.renderer as CreateVisualElement<Props, TagName>)\n\n if (!visualElementRef.current && createVisualElement) {\n visualElementRef.current = createVisualElement(Component, {\n visualState,\n parent,\n props,\n presenceContext,\n blockInitialAnimation: presenceContext\n ? presenceContext.initial === false\n : false,\n reducedMotionConfig,\n })\n }\n\n const visualElement = visualElementRef.current\n\n /**\n * Load Motion gesture and animation features. These are rendered as renderless\n * components so each feature can optionally make use of React lifecycle methods.\n */\n const initialLayoutGroupConfig = useContext(SwitchLayoutGroupContext)\n\n if (\n visualElement &&\n !visualElement.projection &&\n ProjectionNodeConstructor &&\n (visualElement.type === \"html\" || visualElement.type === \"svg\")\n ) {\n createProjectionNode(\n visualElementRef.current!,\n props,\n ProjectionNodeConstructor,\n initialLayoutGroupConfig\n )\n }\n\n const isMounted = useRef(false)\n useInsertionEffect(() => {\n /**\n * Check the component has already mounted before calling\n * `update` unnecessarily. This ensures we skip the initial update.\n */\n if (visualElement && isMounted.current) {\n visualElement.update(props, presenceContext)\n }\n })\n\n /**\n * Cache this value as we want to know whether HandoffAppearAnimations\n * was present on initial render - it will be deleted after this.\n */\n const optimisedAppearId =\n props[optimizedAppearDataAttribute as keyof typeof props]\n const wantsHandoff = useRef(\n Boolean(optimisedAppearId) &&\n !window.MotionHandoffIsComplete?.(optimisedAppearId) &&\n window.MotionHasOptimisedAnimation?.(optimisedAppearId)\n )\n\n useIsomorphicLayoutEffect(() => {\n if (!visualElement) return\n\n isMounted.current = true\n window.MotionIsMounted = true\n\n visualElement.updateFeatures()\n visualElement.scheduleRenderMicrotask()\n\n /**\n * Ideally this function would always run in a useEffect.\n *\n * However, if we have optimised appear animations to handoff from,\n * it needs to happen synchronously to ensure there's no flash of\n * incorrect styles in the event of a hydration error.\n *\n * So if we detect a situtation where optimised appear animations\n * are running, we use useLayoutEffect to trigger animations.\n */\n if (wantsHandoff.current && visualElement.animationState) {\n visualElement.animationState.animateChanges()\n }\n })\n\n useEffect(() => {\n if (!visualElement) return\n\n if (!wantsHandoff.current && visualElement.animationState) {\n visualElement.animationState.animateChanges()\n }\n\n if (wantsHandoff.current) {\n // This ensures all future calls to animateChanges() in this component will run in useEffect\n queueMicrotask(() => {\n window.MotionHandoffMarkAsComplete?.(optimisedAppearId)\n })\n\n wantsHandoff.current = false\n }\n\n /**\n * Now we've finished triggering animations for this element we\n * can wipe the enteringChildren set for the next render.\n */\n visualElement.enteringChildren = undefined\n })\n\n return visualElement!\n}\n\nfunction createProjectionNode(\n visualElement: VisualElement<any>,\n props: MotionProps,\n ProjectionNodeConstructor: any,\n initialPromotionConfig?: InitialPromotionConfig\n) {\n const {\n layoutId,\n layout,\n drag,\n dragConstraints,\n layoutScroll,\n layoutRoot,\n layoutCrossfade,\n } = props\n\n visualElement.projection = new ProjectionNodeConstructor(\n visualElement.latestValues,\n props[\"data-framer-portal-id\"]\n ? undefined\n : getClosestProjectingNode(visualElement.parent)\n ) as IProjectionNode\n\n visualElement.projection.setOptions({\n layoutId,\n layout,\n alwaysMeasureLayout:\n Boolean(drag) || (dragConstraints && isRefObject(dragConstraints)),\n visualElement,\n /**\n * TODO: Update options in an effect. This could be tricky as it'll be too late\n * to update by the time layout animations run.\n * We also need to fix this safeToRemove by linking it up to the one returned by usePresence,\n * ensuring it gets called if there's no potential layout animations.\n *\n */\n animationType: typeof layout === \"string\" ? layout : \"both\",\n initialPromotionConfig,\n crossfade: layoutCrossfade,\n layoutScroll,\n layoutRoot,\n })\n}\n\nfunction getClosestProjectingNode(\n visualElement?: VisualElement<\n unknown,\n unknown,\n { allowProjection?: boolean }\n >\n): IProjectionNode | undefined {\n if (!visualElement) return undefined\n\n return visualElement.options.allowProjection !== false\n ? visualElement.projection\n : getClosestProjectingNode(visualElement.parent)\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAwBM;;AAaF;AACA;;AAGA;AAIA;;AAEG;;;;AAKH;AACI;;;;;AAKI;AACI;AACA;;AAEP;;AAGL;AAEA;;;AAGG;AACH;AAEA;;;AAII;;;AAUJ;;AAEI;;;AAGG;AACH;AACI;;AAER;AAEA;;;AAGG;AACH;AAEA;AAEQ;AACA;;AAIJ;;AAEA;AACA;;;AAKA;;;;;;;;;AASG;;AAEC;;AAER;;AAGI;;;AAGI;;AAGJ;;;AAGQ;AACJ;AAEA;;AAGJ;;;AAGG;AACH;AACJ;AAEA;AACJ;AAEA;AAMI;AAUA;AAGQ;;AAIR;;;AAGI;;AAGA;;;;;;AAMG;AACH;;AAEA;;;AAGH;AACL;AAEA;AAOI;AAAoB;AAEpB;;AAEI;AACR;;"}
1
+ {"version":3,"file":"use-visual-element.mjs","sources":["../../../../src/motion/utils/use-visual-element.ts"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { useContext, useEffect, useInsertionEffect, useRef } from \"react\"\nimport { optimizedAppearDataAttribute } from \"../../animation/optimized-appear/data-id\"\nimport { LazyContext } from \"../../context/LazyContext\"\nimport { MotionConfigContext } from \"../../context/MotionConfigContext\"\nimport { MotionContext } from \"../../context/MotionContext\"\nimport { PresenceContext } from \"../../context/PresenceContext\"\nimport {\n InitialPromotionConfig,\n SwitchLayoutGroupContext,\n} from \"../../context/SwitchLayoutGroupContext\"\nimport { MotionProps } from \"../../motion/types\"\nimport { IProjectionNode } from \"../../projection/node/types\"\nimport { DOMMotionComponents } from \"../../render/dom/types\"\nimport { HTMLRenderState } from \"../../render/html/types\"\nimport { SVGRenderState } from \"../../render/svg/types\"\nimport { CreateVisualElement } from \"../../render/types\"\nimport type { VisualElement } from \"../../render/VisualElement\"\nimport { isRefObject } from \"../../utils/is-ref-object\"\nimport { useIsomorphicLayoutEffect } from \"../../utils/use-isomorphic-effect\"\nimport { VisualState } from \"./use-visual-state\"\n\nexport function useVisualElement<\n Props,\n TagName extends keyof DOMMotionComponents | string\n>(\n Component: TagName | string | React.ComponentType<Props>,\n visualState:\n | VisualState<SVGElement, SVGRenderState>\n | VisualState<HTMLElement, HTMLRenderState>,\n props: MotionProps & Partial<MotionConfigContext>,\n createVisualElement?: CreateVisualElement<Props, TagName>,\n ProjectionNodeConstructor?: any,\n isSVG?: boolean\n): VisualElement<HTMLElement | SVGElement> | undefined {\n const { visualElement: parent } = useContext(MotionContext)\n const lazyContext = useContext(LazyContext)\n const presenceContext = useContext(PresenceContext)\n const reducedMotionConfig = useContext(MotionConfigContext).reducedMotion\n\n const visualElementRef = useRef<VisualElement<\n HTMLElement | SVGElement\n > | null>(null)\n\n /**\n * If we haven't preloaded a renderer, check to see if we have one lazy-loaded\n */\n createVisualElement =\n createVisualElement ||\n (lazyContext.renderer as CreateVisualElement<Props, TagName>)\n\n if (!visualElementRef.current && createVisualElement) {\n visualElementRef.current = createVisualElement(Component, {\n visualState,\n parent,\n props,\n presenceContext,\n blockInitialAnimation: presenceContext\n ? presenceContext.initial === false\n : false,\n reducedMotionConfig,\n isSVG,\n })\n }\n\n const visualElement = visualElementRef.current\n\n /**\n * Load Motion gesture and animation features. These are rendered as renderless\n * components so each feature can optionally make use of React lifecycle methods.\n */\n const initialLayoutGroupConfig = useContext(SwitchLayoutGroupContext)\n\n if (\n visualElement &&\n !visualElement.projection &&\n ProjectionNodeConstructor &&\n (visualElement.type === \"html\" || visualElement.type === \"svg\")\n ) {\n createProjectionNode(\n visualElementRef.current!,\n props,\n ProjectionNodeConstructor,\n initialLayoutGroupConfig\n )\n }\n\n const isMounted = useRef(false)\n useInsertionEffect(() => {\n /**\n * Check the component has already mounted before calling\n * `update` unnecessarily. This ensures we skip the initial update.\n */\n if (visualElement && isMounted.current) {\n visualElement.update(props, presenceContext)\n }\n })\n\n /**\n * Cache this value as we want to know whether HandoffAppearAnimations\n * was present on initial render - it will be deleted after this.\n */\n const optimisedAppearId =\n props[optimizedAppearDataAttribute as keyof typeof props]\n const wantsHandoff = useRef(\n Boolean(optimisedAppearId) &&\n !window.MotionHandoffIsComplete?.(optimisedAppearId) &&\n window.MotionHasOptimisedAnimation?.(optimisedAppearId)\n )\n\n useIsomorphicLayoutEffect(() => {\n if (!visualElement) return\n\n isMounted.current = true\n window.MotionIsMounted = true\n\n visualElement.updateFeatures()\n visualElement.scheduleRenderMicrotask()\n\n /**\n * Ideally this function would always run in a useEffect.\n *\n * However, if we have optimised appear animations to handoff from,\n * it needs to happen synchronously to ensure there's no flash of\n * incorrect styles in the event of a hydration error.\n *\n * So if we detect a situtation where optimised appear animations\n * are running, we use useLayoutEffect to trigger animations.\n */\n if (wantsHandoff.current && visualElement.animationState) {\n visualElement.animationState.animateChanges()\n }\n })\n\n useEffect(() => {\n if (!visualElement) return\n\n if (!wantsHandoff.current && visualElement.animationState) {\n visualElement.animationState.animateChanges()\n }\n\n if (wantsHandoff.current) {\n // This ensures all future calls to animateChanges() in this component will run in useEffect\n queueMicrotask(() => {\n window.MotionHandoffMarkAsComplete?.(optimisedAppearId)\n })\n\n wantsHandoff.current = false\n }\n\n /**\n * Now we've finished triggering animations for this element we\n * can wipe the enteringChildren set for the next render.\n */\n visualElement.enteringChildren = undefined\n })\n\n return visualElement!\n}\n\nfunction createProjectionNode(\n visualElement: VisualElement<any>,\n props: MotionProps,\n ProjectionNodeConstructor: any,\n initialPromotionConfig?: InitialPromotionConfig\n) {\n const {\n layoutId,\n layout,\n drag,\n dragConstraints,\n layoutScroll,\n layoutRoot,\n layoutCrossfade,\n } = props\n\n visualElement.projection = new ProjectionNodeConstructor(\n visualElement.latestValues,\n props[\"data-framer-portal-id\"]\n ? undefined\n : getClosestProjectingNode(visualElement.parent)\n ) as IProjectionNode\n\n visualElement.projection.setOptions({\n layoutId,\n layout,\n alwaysMeasureLayout:\n Boolean(drag) || (dragConstraints && isRefObject(dragConstraints)),\n visualElement,\n /**\n * TODO: Update options in an effect. This could be tricky as it'll be too late\n * to update by the time layout animations run.\n * We also need to fix this safeToRemove by linking it up to the one returned by usePresence,\n * ensuring it gets called if there's no potential layout animations.\n *\n */\n animationType: typeof layout === \"string\" ? layout : \"both\",\n initialPromotionConfig,\n crossfade: layoutCrossfade,\n layoutScroll,\n layoutRoot,\n })\n}\n\nfunction getClosestProjectingNode(\n visualElement?: VisualElement<\n unknown,\n unknown,\n { allowProjection?: boolean }\n >\n): IProjectionNode | undefined {\n if (!visualElement) return undefined\n\n return visualElement.options.allowProjection !== false\n ? visualElement.projection\n : getClosestProjectingNode(visualElement.parent)\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAwBgB;;AAcZ;AACA;;AAGA;AAIA;;AAEG;;;;AAKH;AACI;;;;;AAKI;AACI;AACA;;;AAGP;;AAGL;AAEA;;;AAGG;AACH;AAEA;;;AAII;;;AAUJ;;AAEI;;;AAGG;AACH;AACI;;AAER;AAEA;;;AAGG;AACH;AAEA;AAEQ;AACA;;AAIJ;;AAEA;AACA;;;AAKA;;;;;;;;;AASG;;AAEC;;AAER;;AAGI;;;AAGI;;AAGJ;;;AAGQ;AACJ;AAEA;;AAGJ;;;AAGG;AACH;AACJ;AAEA;AACJ;AAEA;AAMI;AAUA;AAGQ;;AAIR;;;AAGI;;AAGA;;;;;;AAMG;AACH;;AAEA;;;AAGH;AACL;AAEA;AAOI;AAAoB;AAEpB;;AAEI;AACR;;"}
@@ -71,7 +71,7 @@ function applyTreeDeltas(box, treeScale, treePath, isSharedTransition = false) {
71
71
  });
72
72
  }
73
73
  if (delta) {
74
- // Incoporate each ancestor's scale into a culmulative treeScale for this component
74
+ // Incoporate each ancestor's scale into a cumulative treeScale for this component
75
75
  treeScale.x *= delta.x.scale;
76
76
  treeScale.y *= delta.y.scale;
77
77
  // Apply each ancestor's calculated delta into this component's recorded layout box
@@ -1 +1 @@
1
- {"version":3,"file":"delta-apply.mjs","sources":["../../../../src/projection/geometry/delta-apply.ts"],"sourcesContent":["import { mixNumber } from \"motion-dom\"\nimport { Axis, Box, Delta, Point } from \"motion-utils\"\nimport { ResolvedValues } from \"../../render/types\"\nimport { IProjectionNode } from \"../node/types\"\nimport { hasTransform } from \"../utils/has-transform\"\n\n/**\n * Scales a point based on a factor and an originPoint\n */\nexport function scalePoint(point: number, scale: number, originPoint: number) {\n const distanceFromOrigin = point - originPoint\n const scaled = scale * distanceFromOrigin\n return originPoint + scaled\n}\n\n/**\n * Applies a translate/scale delta to a point\n */\nexport function applyPointDelta(\n point: number,\n translate: number,\n scale: number,\n originPoint: number,\n boxScale?: number\n): number {\n if (boxScale !== undefined) {\n point = scalePoint(point, boxScale, originPoint)\n }\n\n return scalePoint(point, scale, originPoint) + translate\n}\n\n/**\n * Applies a translate/scale delta to an axis\n */\nexport function applyAxisDelta(\n axis: Axis,\n translate: number = 0,\n scale: number = 1,\n originPoint: number,\n boxScale?: number\n): void {\n axis.min = applyPointDelta(\n axis.min,\n translate,\n scale,\n originPoint,\n boxScale\n )\n\n axis.max = applyPointDelta(\n axis.max,\n translate,\n scale,\n originPoint,\n boxScale\n )\n}\n\n/**\n * Applies a translate/scale delta to a box\n */\nexport function applyBoxDelta(box: Box, { x, y }: Delta): void {\n applyAxisDelta(box.x, x.translate, x.scale, x.originPoint)\n applyAxisDelta(box.y, y.translate, y.scale, y.originPoint)\n}\n\nconst TREE_SCALE_SNAP_MIN = 0.999999999999\nconst TREE_SCALE_SNAP_MAX = 1.0000000000001\n\n/**\n * Apply a tree of deltas to a box. We do this to calculate the effect of all the transforms\n * in a tree upon our box before then calculating how to project it into our desired viewport-relative box\n *\n * This is the final nested loop within updateLayoutDelta for future refactoring\n */\nexport function applyTreeDeltas(\n box: Box,\n treeScale: Point,\n treePath: IProjectionNode[],\n isSharedTransition: boolean = false\n) {\n const treeLength = treePath.length\n if (!treeLength) return\n\n // Reset the treeScale\n treeScale.x = treeScale.y = 1\n\n let node: IProjectionNode\n let delta: Delta | undefined\n\n for (let i = 0; i < treeLength; i++) {\n node = treePath[i]\n delta = node.projectionDelta\n\n /**\n * TODO: Prefer to remove this, but currently we have motion components with\n * display: contents in Framer.\n */\n const { visualElement } = node.options\n if (\n visualElement &&\n visualElement.props.style &&\n visualElement.props.style.display === \"contents\"\n ) {\n continue\n }\n\n if (\n isSharedTransition &&\n node.options.layoutScroll &&\n node.scroll &&\n node !== node.root\n ) {\n transformBox(box, {\n x: -node.scroll.offset.x,\n y: -node.scroll.offset.y,\n })\n }\n\n if (delta) {\n // Incoporate each ancestor's scale into a culmulative treeScale for this component\n treeScale.x *= delta.x.scale\n treeScale.y *= delta.y.scale\n\n // Apply each ancestor's calculated delta into this component's recorded layout box\n applyBoxDelta(box, delta)\n }\n\n if (isSharedTransition && hasTransform(node.latestValues)) {\n transformBox(box, node.latestValues)\n }\n }\n\n /**\n * Snap tree scale back to 1 if it's within a non-perceivable threshold.\n * This will help reduce useless scales getting rendered.\n */\n if (\n treeScale.x < TREE_SCALE_SNAP_MAX &&\n treeScale.x > TREE_SCALE_SNAP_MIN\n ) {\n treeScale.x = 1.0\n }\n if (\n treeScale.y < TREE_SCALE_SNAP_MAX &&\n treeScale.y > TREE_SCALE_SNAP_MIN\n ) {\n treeScale.y = 1.0\n }\n}\n\nexport function translateAxis(axis: Axis, distance: number) {\n axis.min = axis.min + distance\n axis.max = axis.max + distance\n}\n\n/**\n * Apply a transform to an axis from the latest resolved motion values.\n * This function basically acts as a bridge between a flat motion value map\n * and applyAxisDelta\n */\nexport function transformAxis(\n axis: Axis,\n axisTranslate?: number,\n axisScale?: number,\n boxScale?: number,\n axisOrigin: number = 0.5\n): void {\n const originPoint = mixNumber(axis.min, axis.max, axisOrigin)\n\n // Apply the axis delta to the final axis\n applyAxisDelta(axis, axisTranslate, axisScale, originPoint, boxScale)\n}\n\n/**\n * Apply a transform to a box from the latest resolved motion values.\n */\nexport function transformBox(box: Box, transform: ResolvedValues) {\n transformAxis(\n box.x,\n transform.x as number,\n transform.scaleX as number,\n transform.scale as number,\n transform.originX as number\n )\n transformAxis(\n box.y,\n transform.y as number,\n transform.scaleY as number,\n transform.scale as number,\n transform.originY as number\n )\n}\n"],"names":[],"mappings":";;;AAMA;;AAEG;SACa,UAAU,CAAC,KAAa,EAAE,KAAa,EAAE,WAAmB,EAAA;AACxE,IAAA,MAAM,kBAAkB,GAAG,KAAK,GAAG,WAAW,CAAA;AAC9C,IAAA,MAAM,MAAM,GAAG,KAAK,GAAG,kBAAkB,CAAA;IACzC,OAAO,WAAW,GAAG,MAAM,CAAA;AAC/B,CAAC;AAED;;AAEG;AACG,SAAU,eAAe,CAC3B,KAAa,EACb,SAAiB,EACjB,KAAa,EACb,WAAmB,EACnB,QAAiB,EAAA;AAEjB,IAAA,IAAI,QAAQ,KAAK,SAAS,EAAE;QACxB,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAA;KACnD;IAED,OAAO,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,SAAS,CAAA;AAC5D,CAAC;AAED;;AAEG;AACa,SAAA,cAAc,CAC1B,IAAU,EACV,SAAA,GAAoB,CAAC,EACrB,KAAgB,GAAA,CAAC,EACjB,WAAmB,EACnB,QAAiB,EAAA;AAEjB,IAAA,IAAI,CAAC,GAAG,GAAG,eAAe,CACtB,IAAI,CAAC,GAAG,EACR,SAAS,EACT,KAAK,EACL,WAAW,EACX,QAAQ,CACX,CAAA;AAED,IAAA,IAAI,CAAC,GAAG,GAAG,eAAe,CACtB,IAAI,CAAC,GAAG,EACR,SAAS,EACT,KAAK,EACL,WAAW,EACX,QAAQ,CACX,CAAA;AACL,CAAC;AAED;;AAEG;AACG,SAAU,aAAa,CAAC,GAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,EAAS,EAAA;AACnD,IAAA,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,CAAA;AAC1D,IAAA,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,CAAA;AAC9D,CAAC;AAED,MAAM,mBAAmB,GAAG,cAAc,CAAA;AAC1C,MAAM,mBAAmB,GAAG,eAAe,CAAA;AAE3C;;;;;AAKG;AACG,SAAU,eAAe,CAC3B,GAAQ,EACR,SAAgB,EAChB,QAA2B,EAC3B,kBAAA,GAA8B,KAAK,EAAA;AAEnC,IAAA,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAA;AAClC,IAAA,IAAI,CAAC,UAAU;QAAE,OAAM;;IAGvB,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAA;AAE7B,IAAA,IAAI,IAAqB,CAAA;AACzB,IAAA,IAAI,KAAwB,CAAA;AAE5B,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE;AACjC,QAAA,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;AAClB,QAAA,KAAK,GAAG,IAAI,CAAC,eAAe,CAAA;AAE5B;;;AAGG;AACH,QAAA,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;AACtC,QAAA,IACI,aAAa;YACb,aAAa,CAAC,KAAK,CAAC,KAAK;YACzB,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,KAAK,UAAU,EAClD;YACE,SAAQ;SACX;AAED,QAAA,IACI,kBAAkB;YAClB,IAAI,CAAC,OAAO,CAAC,YAAY;AACzB,YAAA,IAAI,CAAC,MAAM;AACX,YAAA,IAAI,KAAK,IAAI,CAAC,IAAI,EACpB;YACE,YAAY,CAAC,GAAG,EAAE;gBACd,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBACxB,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC3B,aAAA,CAAC,CAAA;SACL;QAED,IAAI,KAAK,EAAE;;YAEP,SAAS,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAA;YAC5B,SAAS,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAA;;AAG5B,YAAA,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;SAC5B;QAED,IAAI,kBAAkB,IAAI,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE;AACvD,YAAA,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;SACvC;KACJ;AAED;;;AAGG;AACH,IAAA,IACI,SAAS,CAAC,CAAC,GAAG,mBAAmB;AACjC,QAAA,SAAS,CAAC,CAAC,GAAG,mBAAmB,EACnC;AACE,QAAA,SAAS,CAAC,CAAC,GAAG,GAAG,CAAA;KACpB;AACD,IAAA,IACI,SAAS,CAAC,CAAC,GAAG,mBAAmB;AACjC,QAAA,SAAS,CAAC,CAAC,GAAG,mBAAmB,EACnC;AACE,QAAA,SAAS,CAAC,CAAC,GAAG,GAAG,CAAA;KACpB;AACL,CAAC;AAEe,SAAA,aAAa,CAAC,IAAU,EAAE,QAAgB,EAAA;IACtD,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAA;IAC9B,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAA;AAClC,CAAC;AAED;;;;AAIG;AACa,SAAA,aAAa,CACzB,IAAU,EACV,aAAsB,EACtB,SAAkB,EAClB,QAAiB,EACjB,UAAA,GAAqB,GAAG,EAAA;AAExB,IAAA,MAAM,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;;IAG7D,cAAc,CAAC,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAA;AACzE,CAAC;AAED;;AAEG;AACa,SAAA,YAAY,CAAC,GAAQ,EAAE,SAAyB,EAAA;IAC5D,aAAa,CACT,GAAG,CAAC,CAAC,EACL,SAAS,CAAC,CAAW,EACrB,SAAS,CAAC,MAAgB,EAC1B,SAAS,CAAC,KAAe,EACzB,SAAS,CAAC,OAAiB,CAC9B,CAAA;IACD,aAAa,CACT,GAAG,CAAC,CAAC,EACL,SAAS,CAAC,CAAW,EACrB,SAAS,CAAC,MAAgB,EAC1B,SAAS,CAAC,KAAe,EACzB,SAAS,CAAC,OAAiB,CAC9B,CAAA;AACL;;;;"}
1
+ {"version":3,"file":"delta-apply.mjs","sources":["../../../../src/projection/geometry/delta-apply.ts"],"sourcesContent":["import { mixNumber } from \"motion-dom\"\nimport { Axis, Box, Delta, Point } from \"motion-utils\"\nimport { ResolvedValues } from \"../../render/types\"\nimport { IProjectionNode } from \"../node/types\"\nimport { hasTransform } from \"../utils/has-transform\"\n\n/**\n * Scales a point based on a factor and an originPoint\n */\nexport function scalePoint(point: number, scale: number, originPoint: number) {\n const distanceFromOrigin = point - originPoint\n const scaled = scale * distanceFromOrigin\n return originPoint + scaled\n}\n\n/**\n * Applies a translate/scale delta to a point\n */\nexport function applyPointDelta(\n point: number,\n translate: number,\n scale: number,\n originPoint: number,\n boxScale?: number\n): number {\n if (boxScale !== undefined) {\n point = scalePoint(point, boxScale, originPoint)\n }\n\n return scalePoint(point, scale, originPoint) + translate\n}\n\n/**\n * Applies a translate/scale delta to an axis\n */\nexport function applyAxisDelta(\n axis: Axis,\n translate: number = 0,\n scale: number = 1,\n originPoint: number,\n boxScale?: number\n): void {\n axis.min = applyPointDelta(\n axis.min,\n translate,\n scale,\n originPoint,\n boxScale\n )\n\n axis.max = applyPointDelta(\n axis.max,\n translate,\n scale,\n originPoint,\n boxScale\n )\n}\n\n/**\n * Applies a translate/scale delta to a box\n */\nexport function applyBoxDelta(box: Box, { x, y }: Delta): void {\n applyAxisDelta(box.x, x.translate, x.scale, x.originPoint)\n applyAxisDelta(box.y, y.translate, y.scale, y.originPoint)\n}\n\nconst TREE_SCALE_SNAP_MIN = 0.999999999999\nconst TREE_SCALE_SNAP_MAX = 1.0000000000001\n\n/**\n * Apply a tree of deltas to a box. We do this to calculate the effect of all the transforms\n * in a tree upon our box before then calculating how to project it into our desired viewport-relative box\n *\n * This is the final nested loop within updateLayoutDelta for future refactoring\n */\nexport function applyTreeDeltas(\n box: Box,\n treeScale: Point,\n treePath: IProjectionNode[],\n isSharedTransition: boolean = false\n) {\n const treeLength = treePath.length\n if (!treeLength) return\n\n // Reset the treeScale\n treeScale.x = treeScale.y = 1\n\n let node: IProjectionNode\n let delta: Delta | undefined\n\n for (let i = 0; i < treeLength; i++) {\n node = treePath[i]\n delta = node.projectionDelta\n\n /**\n * TODO: Prefer to remove this, but currently we have motion components with\n * display: contents in Framer.\n */\n const { visualElement } = node.options\n if (\n visualElement &&\n visualElement.props.style &&\n visualElement.props.style.display === \"contents\"\n ) {\n continue\n }\n\n if (\n isSharedTransition &&\n node.options.layoutScroll &&\n node.scroll &&\n node !== node.root\n ) {\n transformBox(box, {\n x: -node.scroll.offset.x,\n y: -node.scroll.offset.y,\n })\n }\n\n if (delta) {\n // Incoporate each ancestor's scale into a cumulative treeScale for this component\n treeScale.x *= delta.x.scale\n treeScale.y *= delta.y.scale\n\n // Apply each ancestor's calculated delta into this component's recorded layout box\n applyBoxDelta(box, delta)\n }\n\n if (isSharedTransition && hasTransform(node.latestValues)) {\n transformBox(box, node.latestValues)\n }\n }\n\n /**\n * Snap tree scale back to 1 if it's within a non-perceivable threshold.\n * This will help reduce useless scales getting rendered.\n */\n if (\n treeScale.x < TREE_SCALE_SNAP_MAX &&\n treeScale.x > TREE_SCALE_SNAP_MIN\n ) {\n treeScale.x = 1.0\n }\n if (\n treeScale.y < TREE_SCALE_SNAP_MAX &&\n treeScale.y > TREE_SCALE_SNAP_MIN\n ) {\n treeScale.y = 1.0\n }\n}\n\nexport function translateAxis(axis: Axis, distance: number) {\n axis.min = axis.min + distance\n axis.max = axis.max + distance\n}\n\n/**\n * Apply a transform to an axis from the latest resolved motion values.\n * This function basically acts as a bridge between a flat motion value map\n * and applyAxisDelta\n */\nexport function transformAxis(\n axis: Axis,\n axisTranslate?: number,\n axisScale?: number,\n boxScale?: number,\n axisOrigin: number = 0.5\n): void {\n const originPoint = mixNumber(axis.min, axis.max, axisOrigin)\n\n // Apply the axis delta to the final axis\n applyAxisDelta(axis, axisTranslate, axisScale, originPoint, boxScale)\n}\n\n/**\n * Apply a transform to a box from the latest resolved motion values.\n */\nexport function transformBox(box: Box, transform: ResolvedValues) {\n transformAxis(\n box.x,\n transform.x as number,\n transform.scaleX as number,\n transform.scale as number,\n transform.originX as number\n )\n transformAxis(\n box.y,\n transform.y as number,\n transform.scaleY as number,\n transform.scale as number,\n transform.originY as number\n )\n}\n"],"names":[],"mappings":"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"}
@@ -334,7 +334,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
334
334
  /**
335
335
  * If the layout hasn't changed and we have an animation that hasn't started yet,
336
336
  * finish it immediately. Otherwise it will be animating from a location
337
- * that was probably never commited to screen and look like a jumpy box.
337
+ * that was probably never committed to screen and look like a jumpy box.
338
338
  */
339
339
  if (!hasLayoutChanged) {
340
340
  finishAnimation(this);