framer-motion 12.23.28 → 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 (43) hide show
  1. package/dist/cjs/client.js +1 -1
  2. package/dist/cjs/{feature-bundle-Dt2VtvSZ.js → feature-bundle-DhbxBqkJ.js} +30 -13
  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/render/dom/create-visual-element.mjs +5 -1
  18. package/dist/es/render/dom/create-visual-element.mjs.map +1 -1
  19. package/dist/es/render/dom/use-render.mjs +2 -4
  20. package/dist/es/render/dom/use-render.mjs.map +1 -1
  21. package/dist/framer-motion.dev.js +67 -34
  22. package/dist/framer-motion.js +1 -1
  23. package/dist/m.d.ts +8 -0
  24. package/dist/mini.js +1 -1
  25. package/dist/size-rollup-animate.js +1 -1
  26. package/dist/size-rollup-animate.js.map +1 -1
  27. package/dist/size-rollup-dom-animation-assets.js +1 -1
  28. package/dist/size-rollup-dom-animation-m.js +1 -1
  29. package/dist/size-rollup-dom-animation.js +1 -1
  30. package/dist/size-rollup-dom-max-assets.js +1 -1
  31. package/dist/size-rollup-dom-max.js +1 -1
  32. package/dist/size-rollup-m.js +1 -1
  33. package/dist/size-rollup-m.js.map +1 -1
  34. package/dist/size-rollup-motion.js +1 -1
  35. package/dist/size-rollup-motion.js.map +1 -1
  36. package/dist/size-rollup-scroll.js.map +1 -1
  37. package/dist/size-rollup-waapi-animate.js +1 -1
  38. package/dist/size-rollup-waapi-animate.js.map +1 -1
  39. package/dist/types/client.d.ts +1 -1
  40. package/dist/types/index.d.ts +13 -5
  41. package/dist/{types.d-C8SDx5n-.d.ts → types.d-a9pt5qxk.d.ts} +5 -0
  42. package/package.json +3 -3
  43. package/dist/cjs/feature-bundle-Dt2VtvSZ.js.map +0 -1
@@ -27,11 +27,15 @@ import { useVisualElement } from './utils/use-visual-element.mjs';
27
27
  * Alongside this is a config option which provides a way of rendering the provided
28
28
  * component "offline", or outside the React render cycle.
29
29
  */
30
- function createMotionComponent(Component, { forwardMotionProps = false } = {}, preloadedFeatures, createVisualElement) {
30
+ function createMotionComponent(Component, { forwardMotionProps = false, type } = {}, preloadedFeatures, createVisualElement) {
31
31
  preloadedFeatures && loadFeatures(preloadedFeatures);
32
- const useVisualState = isSVGComponent(Component)
33
- ? useSVGVisualState
34
- : useHTMLVisualState;
32
+ /**
33
+ * Determine whether to use SVG or HTML rendering based on:
34
+ * 1. Explicit `type` option (highest priority)
35
+ * 2. Auto-detection via `isSVGComponent`
36
+ */
37
+ const isSVG = type ? type === "svg" : isSVGComponent(Component);
38
+ const useVisualState = isSVG ? useSVGVisualState : useHTMLVisualState;
35
39
  function MotionDOMComponent(props, externalRef) {
36
40
  /**
37
41
  * If we need to measure the element we load this functionality in a
@@ -56,13 +60,13 @@ function createMotionComponent(Component, { forwardMotionProps = false } = {}, p
56
60
  * providing a way of rendering to these APIs outside of the React render loop
57
61
  * for more performant animations and interactions
58
62
  */
59
- context.visualElement = useVisualElement(Component, visualState, configAndProps, createVisualElement, layoutProjection.ProjectionNode);
63
+ context.visualElement = useVisualElement(Component, visualState, configAndProps, createVisualElement, layoutProjection.ProjectionNode, isSVG);
60
64
  }
61
65
  /**
62
66
  * The mount order and hierarchy is specific to ensure our element ref
63
67
  * is hydrated by the time features fire their effects.
64
68
  */
65
- return (jsxs(MotionContext.Provider, { value: context, children: [MeasureLayout && context.visualElement ? (jsx(MeasureLayout, { visualElement: context.visualElement, ...configAndProps })) : null, useRender(Component, props, useMotionRef(visualState, context.visualElement, externalRef), visualState, isStatic, forwardMotionProps)] }));
69
+ return (jsxs(MotionContext.Provider, { value: context, children: [MeasureLayout && context.visualElement ? (jsx(MeasureLayout, { visualElement: context.visualElement, ...configAndProps })) : null, useRender(Component, props, useMotionRef(visualState, context.visualElement, externalRef), visualState, isStatic, forwardMotionProps, isSVG)] }));
66
70
  }
67
71
  MotionDOMComponent.displayName = `motion.${typeof Component === "string"
68
72
  ? Component
@@ -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;;"}
@@ -4,7 +4,11 @@ import { SVGVisualElement } from '../svg/SVGVisualElement.mjs';
4
4
  import { isSVGComponent } from './utils/is-svg-component.mjs';
5
5
 
6
6
  const createDomVisualElement = (Component, options) => {
7
- return isSVGComponent(Component)
7
+ /**
8
+ * Use explicit isSVG override if provided, otherwise auto-detect
9
+ */
10
+ const isSVG = options.isSVG ?? isSVGComponent(Component);
11
+ return isSVG
8
12
  ? new SVGVisualElement(options)
9
13
  : new HTMLVisualElement(options, {
10
14
  allowProjection: Component !== Fragment,
@@ -1 +1 @@
1
- {"version":3,"file":"create-visual-element.mjs","sources":["../../../../src/render/dom/create-visual-element.ts"],"sourcesContent":["import { ComponentType, Fragment } from \"react\"\nimport { HTMLVisualElement } from \"../html/HTMLVisualElement\"\nimport { SVGVisualElement } from \"../svg/SVGVisualElement\"\nimport { CreateVisualElement, VisualElementOptions } from \"../types\"\nimport { isSVGComponent } from \"./utils/is-svg-component\"\n\nexport const createDomVisualElement: CreateVisualElement = (\n Component: string | ComponentType<React.PropsWithChildren<unknown>>,\n options: VisualElementOptions<HTMLElement | SVGElement>\n) => {\n return isSVGComponent(Component)\n ? new SVGVisualElement(options)\n : new HTMLVisualElement(options, {\n allowProjection: Component !== Fragment,\n })\n}\n"],"names":[],"mappings":";;;;;MAMa,sBAAsB,GAAwB,CACvD,SAAmE,EACnE,OAAuD,KACvD;IACA,OAAO,cAAc,CAAC,SAAS,CAAC;AAC5B,UAAE,IAAI,gBAAgB,CAAC,OAAO,CAAC;AAC/B,UAAE,IAAI,iBAAiB,CAAC,OAAO,EAAE;YAC3B,eAAe,EAAE,SAAS,KAAK,QAAQ;AAC1C,SAAA,CAAC,CAAA;AACZ;;;;"}
1
+ {"version":3,"file":"create-visual-element.mjs","sources":["../../../../src/render/dom/create-visual-element.ts"],"sourcesContent":["import { ComponentType, Fragment } from \"react\"\nimport { HTMLVisualElement } from \"../html/HTMLVisualElement\"\nimport { SVGVisualElement } from \"../svg/SVGVisualElement\"\nimport { CreateVisualElement, VisualElementOptions } from \"../types\"\nimport { isSVGComponent } from \"./utils/is-svg-component\"\n\nexport const createDomVisualElement: CreateVisualElement = (\n Component: string | ComponentType<React.PropsWithChildren<unknown>>,\n options: VisualElementOptions<HTMLElement | SVGElement>\n) => {\n /**\n * Use explicit isSVG override if provided, otherwise auto-detect\n */\n const isSVG = options.isSVG ?? isSVGComponent(Component)\n\n return isSVG\n ? new SVGVisualElement(options)\n : new HTMLVisualElement(options, {\n allowProjection: Component !== Fragment,\n })\n}\n"],"names":[],"mappings":";;;;;MAMa,sBAAsB,GAAwB,CACvD,SAAmE,EACnE,OAAuD,KACvD;AACA;;AAEG;IACH,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,cAAc,CAAC,SAAS,CAAC,CAAA;AAExD,IAAA,OAAO,KAAK;AACR,UAAE,IAAI,gBAAgB,CAAC,OAAO,CAAC;AAC/B,UAAE,IAAI,iBAAiB,CAAC,OAAO,EAAE;YAC3B,eAAe,EAAE,SAAS,KAAK,QAAQ;AAC1C,SAAA,CAAC,CAAA;AACZ;;;;"}
@@ -6,10 +6,8 @@ import { useSVGProps } from '../svg/use-props.mjs';
6
6
  import { filterProps } from './utils/filter-props.mjs';
7
7
  import { isSVGComponent } from './utils/is-svg-component.mjs';
8
8
 
9
- function useRender(Component, props, ref, { latestValues, }, isStatic, forwardMotionProps = false) {
10
- const useVisualProps = isSVGComponent(Component)
11
- ? useSVGProps
12
- : useHTMLProps;
9
+ function useRender(Component, props, ref, { latestValues, }, isStatic, forwardMotionProps = false, isSVG) {
10
+ const useVisualProps = (isSVG ?? isSVGComponent(Component)) ? useSVGProps : useHTMLProps;
13
11
  const visualProps = useVisualProps(props, latestValues, isStatic, Component);
14
12
  const filteredProps = filterProps(props, typeof Component === "string", forwardMotionProps);
15
13
  const elementProps = Component !== Fragment ? { ...filteredProps, ...visualProps, ref } : {};
@@ -1 +1 @@
1
- {"version":3,"file":"use-render.mjs","sources":["../../../../src/render/dom/use-render.ts"],"sourcesContent":["\"use client\"\n\nimport { isMotionValue } from \"motion-dom\"\nimport { Fragment, createElement, useMemo } from \"react\"\nimport { MotionProps } from \"../../motion/types\"\nimport { VisualState } from \"../../motion/utils/use-visual-state\"\nimport { HTMLRenderState } from \"../html/types\"\nimport { useHTMLProps } from \"../html/use-props\"\nimport { SVGRenderState } from \"../svg/types\"\nimport { useSVGProps } from \"../svg/use-props\"\nimport { DOMMotionComponents } from \"./types\"\nimport { filterProps } from \"./utils/filter-props\"\nimport { isSVGComponent } from \"./utils/is-svg-component\"\n\nexport function useRender<\n Props = {},\n TagName extends keyof DOMMotionComponents | string = \"div\"\n>(\n Component: TagName | string | React.ComponentType<Props>,\n props: MotionProps,\n ref: React.Ref<HTMLElement | SVGElement>,\n {\n latestValues,\n }: VisualState<HTMLElement | SVGElement, HTMLRenderState | SVGRenderState>,\n isStatic: boolean,\n forwardMotionProps: boolean = false\n) {\n const useVisualProps = isSVGComponent(Component)\n ? useSVGProps\n : useHTMLProps\n\n const visualProps = useVisualProps(\n props as any,\n latestValues,\n isStatic,\n Component as any\n )\n const filteredProps = filterProps(\n props,\n typeof Component === \"string\",\n forwardMotionProps\n )\n const elementProps =\n Component !== Fragment ? { ...filteredProps, ...visualProps, ref } : {}\n\n /**\n * If component has been handed a motion value as its child,\n * memoise its initial value and render that. Subsequent updates\n * will be handled by the onChange handler\n */\n const { children } = props\n const renderedChildren = useMemo(\n () => (isMotionValue(children) ? children.get() : children),\n [children]\n )\n\n return createElement<any>(Component, {\n ...elementProps,\n children: renderedChildren,\n })\n}\n"],"names":[],"mappings":";;;;;;;;;AA2BI;AACI;;AAGJ;AAMA;;AAQA;;;;AAIG;AACH;AACA;;AAMI;AACA;AACH;AACL;;"}
1
+ {"version":3,"file":"use-render.mjs","sources":["../../../../src/render/dom/use-render.ts"],"sourcesContent":["\"use client\"\n\nimport { isMotionValue } from \"motion-dom\"\nimport { Fragment, createElement, useMemo } from \"react\"\nimport { MotionProps } from \"../../motion/types\"\nimport { VisualState } from \"../../motion/utils/use-visual-state\"\nimport { HTMLRenderState } from \"../html/types\"\nimport { useHTMLProps } from \"../html/use-props\"\nimport { SVGRenderState } from \"../svg/types\"\nimport { useSVGProps } from \"../svg/use-props\"\nimport { DOMMotionComponents } from \"./types\"\nimport { filterProps } from \"./utils/filter-props\"\nimport { isSVGComponent } from \"./utils/is-svg-component\"\n\nexport function useRender<\n Props = {},\n TagName extends keyof DOMMotionComponents | string = \"div\"\n>(\n Component: TagName | string | React.ComponentType<Props>,\n props: MotionProps,\n ref: React.Ref<HTMLElement | SVGElement>,\n {\n latestValues,\n }: VisualState<HTMLElement | SVGElement, HTMLRenderState | SVGRenderState>,\n isStatic: boolean,\n forwardMotionProps: boolean = false,\n isSVG?: boolean\n) {\n const useVisualProps =\n (isSVG ?? isSVGComponent(Component)) ? useSVGProps : useHTMLProps\n\n const visualProps = useVisualProps(\n props as any,\n latestValues,\n isStatic,\n Component as any\n )\n const filteredProps = filterProps(\n props,\n typeof Component === \"string\",\n forwardMotionProps\n )\n const elementProps =\n Component !== Fragment ? { ...filteredProps, ...visualProps, ref } : {}\n\n /**\n * If component has been handed a motion value as its child,\n * memoise its initial value and render that. Subsequent updates\n * will be handled by the onChange handler\n */\n const { children } = props\n const renderedChildren = useMemo(\n () => (isMotionValue(children) ? children.get() : children),\n [children]\n )\n\n return createElement<any>(Component, {\n ...elementProps,\n children: renderedChildren,\n })\n}\n"],"names":[],"mappings":";;;;;;;;;AA4BI;AAGA;AAMA;;AAQA;;;;AAIG;AACH;AACA;;AAMI;AACA;AACH;AACL;;"}
@@ -606,17 +606,6 @@
606
606
  return singleCssVariableRegex.test(value.split("/*")[0].trim());
607
607
  };
608
608
  const singleCssVariableRegex = /var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;
609
- /**
610
- * Check if a value contains a CSS variable anywhere (e.g. inside calc()).
611
- * Unlike isCSSVariableToken which checks if the value IS a var() token,
612
- * this checks if the value CONTAINS var() somewhere in the string.
613
- */
614
- function containsCSSVariable(value) {
615
- if (typeof value !== "string")
616
- return false;
617
- // Strip comments to avoid false positives
618
- return value.split("/*")[0].includes("var(--");
619
- }
620
609
 
621
610
  const number = {
622
611
  test: (v) => typeof v === "number",
@@ -3190,17 +3179,36 @@
3190
3179
  right: px,
3191
3180
  bottom: px,
3192
3181
  left: px,
3182
+ inset: px,
3183
+ insetBlock: px,
3184
+ insetBlockStart: px,
3185
+ insetBlockEnd: px,
3186
+ insetInline: px,
3187
+ insetInlineStart: px,
3188
+ insetInlineEnd: px,
3193
3189
  // Spacing props
3194
3190
  padding: px,
3195
3191
  paddingTop: px,
3196
3192
  paddingRight: px,
3197
3193
  paddingBottom: px,
3198
3194
  paddingLeft: px,
3195
+ paddingBlock: px,
3196
+ paddingBlockStart: px,
3197
+ paddingBlockEnd: px,
3198
+ paddingInline: px,
3199
+ paddingInlineStart: px,
3200
+ paddingInlineEnd: px,
3199
3201
  margin: px,
3200
3202
  marginTop: px,
3201
3203
  marginRight: px,
3202
3204
  marginBottom: px,
3203
3205
  marginLeft: px,
3206
+ marginBlock: px,
3207
+ marginBlockStart: px,
3208
+ marginBlockEnd: px,
3209
+ marginInline: px,
3210
+ marginInlineStart: px,
3211
+ marginInlineEnd: px,
3204
3212
  // Misc
3205
3213
  backgroundPositionX: px,
3206
3214
  backgroundPositionY: px,
@@ -3318,16 +3326,6 @@
3318
3326
  const [origin, target] = unresolvedKeyframes;
3319
3327
  const originType = findDimensionValueType(origin);
3320
3328
  const targetType = findDimensionValueType(target);
3321
- /**
3322
- * If one keyframe contains embedded CSS variables (e.g. in calc()) and the other
3323
- * doesn't, we need to measure to convert to pixels. This handles GitHub issue #3410.
3324
- */
3325
- const originHasVar = containsCSSVariable(origin);
3326
- const targetHasVar = containsCSSVariable(target);
3327
- if (originHasVar !== targetHasVar && positionalValues[name]) {
3328
- this.needsMeasurement = true;
3329
- return;
3330
- }
3331
3329
  /**
3332
3330
  * Either we don't recognise these value types or we can animate between them.
3333
3331
  */
@@ -3426,17 +3424,36 @@
3426
3424
  "right",
3427
3425
  "bottom",
3428
3426
  "left",
3427
+ "inset",
3428
+ "insetBlock",
3429
+ "insetBlockStart",
3430
+ "insetBlockEnd",
3431
+ "insetInline",
3432
+ "insetInlineStart",
3433
+ "insetInlineEnd",
3429
3434
  // Spacing props
3430
3435
  "padding",
3431
3436
  "paddingTop",
3432
3437
  "paddingRight",
3433
3438
  "paddingBottom",
3434
3439
  "paddingLeft",
3440
+ "paddingBlock",
3441
+ "paddingBlockStart",
3442
+ "paddingBlockEnd",
3443
+ "paddingInline",
3444
+ "paddingInlineStart",
3445
+ "paddingInlineEnd",
3435
3446
  "margin",
3436
3447
  "marginTop",
3437
3448
  "marginRight",
3438
3449
  "marginBottom",
3439
3450
  "marginLeft",
3451
+ "marginBlock",
3452
+ "marginBlockStart",
3453
+ "marginBlockEnd",
3454
+ "marginInline",
3455
+ "marginInlineStart",
3456
+ "marginInlineEnd",
3440
3457
  // Misc
3441
3458
  "backgroundPositionX",
3442
3459
  "backgroundPositionY",
@@ -9446,7 +9463,11 @@
9446
9463
  }
9447
9464
 
9448
9465
  const createDomVisualElement = (Component, options) => {
9449
- return isSVGComponent(Component)
9466
+ /**
9467
+ * Use explicit isSVG override if provided, otherwise auto-detect
9468
+ */
9469
+ const isSVG = options.isSVG ?? isSVGComponent(Component);
9470
+ return isSVG
9450
9471
  ? new SVGVisualElement(options)
9451
9472
  : new HTMLVisualElement(options, {
9452
9473
  allowProjection: Component !== React$1.Fragment,
@@ -9555,10 +9576,8 @@
9555
9576
  return visualProps;
9556
9577
  }
9557
9578
 
9558
- function useRender(Component, props, ref, { latestValues, }, isStatic, forwardMotionProps = false) {
9559
- const useVisualProps = isSVGComponent(Component)
9560
- ? useSVGProps
9561
- : useHTMLProps;
9579
+ function useRender(Component, props, ref, { latestValues, }, isStatic, forwardMotionProps = false, isSVG) {
9580
+ const useVisualProps = (isSVG ?? isSVGComponent(Component)) ? useSVGProps : useHTMLProps;
9562
9581
  const visualProps = useVisualProps(props, latestValues, isStatic, Component);
9563
9582
  const filteredProps = filterProps(props, typeof Component === "string", forwardMotionProps);
9564
9583
  const elementProps = Component !== React$1.Fragment ? { ...filteredProps, ...visualProps, ref } : {};
@@ -9700,7 +9719,7 @@
9700
9719
  */
9701
9720
  const SwitchLayoutGroupContext = React$1.createContext({});
9702
9721
 
9703
- function useVisualElement(Component, visualState, props, createVisualElement, ProjectionNodeConstructor) {
9722
+ function useVisualElement(Component, visualState, props, createVisualElement, ProjectionNodeConstructor, isSVG) {
9704
9723
  const { visualElement: parent } = React$1.useContext(MotionContext);
9705
9724
  const lazyContext = React$1.useContext(LazyContext);
9706
9725
  const presenceContext = React$1.useContext(PresenceContext);
@@ -9722,6 +9741,7 @@
9722
9741
  ? presenceContext.initial === false
9723
9742
  : false,
9724
9743
  reducedMotionConfig,
9744
+ isSVG,
9725
9745
  });
9726
9746
  }
9727
9747
  const visualElement = visualElementRef.current;
@@ -9837,11 +9857,15 @@
9837
9857
  * Alongside this is a config option which provides a way of rendering the provided
9838
9858
  * component "offline", or outside the React render cycle.
9839
9859
  */
9840
- function createMotionComponent(Component, { forwardMotionProps = false } = {}, preloadedFeatures, createVisualElement) {
9860
+ function createMotionComponent(Component, { forwardMotionProps = false, type } = {}, preloadedFeatures, createVisualElement) {
9841
9861
  preloadedFeatures && loadFeatures(preloadedFeatures);
9842
- const useVisualState = isSVGComponent(Component)
9843
- ? useSVGVisualState
9844
- : useHTMLVisualState;
9862
+ /**
9863
+ * Determine whether to use SVG or HTML rendering based on:
9864
+ * 1. Explicit `type` option (highest priority)
9865
+ * 2. Auto-detection via `isSVGComponent`
9866
+ */
9867
+ const isSVG = type ? type === "svg" : isSVGComponent(Component);
9868
+ const useVisualState = isSVG ? useSVGVisualState : useHTMLVisualState;
9845
9869
  function MotionDOMComponent(props, externalRef) {
9846
9870
  /**
9847
9871
  * If we need to measure the element we load this functionality in a
@@ -9866,13 +9890,13 @@
9866
9890
  * providing a way of rendering to these APIs outside of the React render loop
9867
9891
  * for more performant animations and interactions
9868
9892
  */
9869
- context.visualElement = useVisualElement(Component, visualState, configAndProps, createVisualElement, layoutProjection.ProjectionNode);
9893
+ context.visualElement = useVisualElement(Component, visualState, configAndProps, createVisualElement, layoutProjection.ProjectionNode, isSVG);
9870
9894
  }
9871
9895
  /**
9872
9896
  * The mount order and hierarchy is specific to ensure our element ref
9873
9897
  * is hydrated by the time features fire their effects.
9874
9898
  */
9875
- return (jsxs(MotionContext.Provider, { value: context, children: [MeasureLayout && context.visualElement ? (jsx(MeasureLayout, { visualElement: context.visualElement, ...configAndProps })) : null, useRender(Component, props, useMotionRef(visualState, context.visualElement, externalRef), visualState, isStatic, forwardMotionProps)] }));
9899
+ return (jsxs(MotionContext.Provider, { value: context, children: [MeasureLayout && context.visualElement ? (jsx(MeasureLayout, { visualElement: context.visualElement, ...configAndProps })) : null, useRender(Component, props, useMotionRef(visualState, context.visualElement, externalRef), visualState, isStatic, forwardMotionProps, isSVG)] }));
9876
9900
  }
9877
9901
  MotionDOMComponent.displayName = `motion.${typeof Component === "string"
9878
9902
  ? Component
@@ -11444,6 +11468,16 @@
11444
11468
  }
11445
11469
  this.removeListeners = this.controls.addListeners() || noop;
11446
11470
  }
11471
+ update() {
11472
+ const { dragControls } = this.node.getProps();
11473
+ const { dragControls: prevDragControls } = this.node.prevProps || {};
11474
+ if (dragControls !== prevDragControls) {
11475
+ this.removeGroupControls();
11476
+ if (dragControls) {
11477
+ this.removeGroupControls = dragControls.subscribe(this.controls);
11478
+ }
11479
+ }
11480
+ }
11447
11481
  unmount() {
11448
11482
  this.removeGroupControls();
11449
11483
  this.removeListeners();
@@ -14242,7 +14276,6 @@
14242
14276
  exports.collectMotionValues = collectMotionValues;
14243
14277
  exports.color = color;
14244
14278
  exports.complex = complex;
14245
- exports.containsCSSVariable = containsCSSVariable;
14246
14279
  exports.convertOffsetToTimes = convertOffsetToTimes;
14247
14280
  exports.createBox = createBox;
14248
14281
  exports.createGeneratorEasing = createGeneratorEasing;