framer-motion 12.23.28 → 12.24.1

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/dom.js +15 -0
  3. package/dist/cjs/dom.js.map +1 -1
  4. package/dist/cjs/{feature-bundle-Dt2VtvSZ.js → feature-bundle-DRMwxyzS.js} +45 -13
  5. package/dist/cjs/feature-bundle-DRMwxyzS.js.map +1 -0
  6. package/dist/cjs/index.js +1 -1
  7. package/dist/cjs/index.js.map +1 -1
  8. package/dist/cjs/m.js +29 -11
  9. package/dist/cjs/m.js.map +1 -1
  10. package/dist/dom-mini.js +1 -1
  11. package/dist/dom.js +1 -1
  12. package/dist/es/components/Reorder/Group.mjs.map +1 -1
  13. package/dist/es/components/Reorder/Item.mjs.map +1 -1
  14. package/dist/es/gestures/drag/index.mjs +10 -0
  15. package/dist/es/gestures/drag/index.mjs.map +1 -1
  16. package/dist/es/motion/index.mjs +10 -6
  17. package/dist/es/motion/index.mjs.map +1 -1
  18. package/dist/es/motion/utils/use-visual-element.mjs +2 -1
  19. package/dist/es/motion/utils/use-visual-element.mjs.map +1 -1
  20. package/dist/es/render/dom/create-visual-element.mjs +5 -1
  21. package/dist/es/render/dom/create-visual-element.mjs.map +1 -1
  22. package/dist/es/render/dom/use-render.mjs +2 -4
  23. package/dist/es/render/dom/use-render.mjs.map +1 -1
  24. package/dist/es/render/svg/utils/build-attrs.mjs +15 -0
  25. package/dist/es/render/svg/utils/build-attrs.mjs.map +1 -1
  26. package/dist/framer-motion.dev.js +82 -34
  27. package/dist/framer-motion.js +1 -1
  28. package/dist/m.d.ts +8 -0
  29. package/dist/mini.js +1 -1
  30. package/dist/size-rollup-animate.js +1 -1
  31. package/dist/size-rollup-animate.js.map +1 -1
  32. package/dist/size-rollup-dom-animation-assets.js +1 -1
  33. package/dist/size-rollup-dom-animation-m.js +1 -1
  34. package/dist/size-rollup-dom-animation.js +1 -1
  35. package/dist/size-rollup-dom-max-assets.js +1 -1
  36. package/dist/size-rollup-dom-max.js +1 -1
  37. package/dist/size-rollup-m.js +1 -1
  38. package/dist/size-rollup-m.js.map +1 -1
  39. package/dist/size-rollup-motion.js +1 -1
  40. package/dist/size-rollup-motion.js.map +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-C8SDx5n-.d.ts → types.d-a9pt5qxk.d.ts} +5 -0
  47. package/package.json +3 -3
  48. 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;;"}
@@ -1,6 +1,15 @@
1
1
  import { buildHTMLStyles } from '../../html/utils/build-styles.mjs';
2
2
  import { buildSVGPath } from './path.mjs';
3
3
 
4
+ /**
5
+ * CSS Motion Path properties that should remain as CSS styles on SVG elements.
6
+ */
7
+ const cssMotionPathProperties = [
8
+ "offsetDistance",
9
+ "offsetPath",
10
+ "offsetRotate",
11
+ "offsetAnchor",
12
+ ];
4
13
  /**
5
14
  * Build SVG visual attributes, like cx and style.transform
6
15
  */
@@ -41,6 +50,12 @@ function buildSVGAttrs(state, { attrX, attrY, attrScale, pathLength, pathSpacing
41
50
  style.transformBox = styleProp?.transformBox ?? "fill-box";
42
51
  delete attrs.transformBox;
43
52
  }
53
+ for (const key of cssMotionPathProperties) {
54
+ if (attrs[key] !== undefined) {
55
+ style[key] = attrs[key];
56
+ delete attrs[key];
57
+ }
58
+ }
44
59
  // Render attrX/attrY/attrScale as attributes
45
60
  if (attrX !== undefined)
46
61
  attrs.x = attrX;
@@ -1 +1 @@
1
- {"version":3,"file":"build-attrs.mjs","sources":["../../../../../src/render/svg/utils/build-attrs.ts"],"sourcesContent":["import { MotionProps } from \"../../../motion/types\"\nimport { buildHTMLStyles } from \"../../html/utils/build-styles\"\nimport { ResolvedValues } from \"../../types\"\nimport { SVGRenderState } from \"../types\"\nimport { buildSVGPath } from \"./path\"\n\n/**\n * Build SVG visual attributes, like cx and style.transform\n */\nexport function buildSVGAttrs(\n state: SVGRenderState,\n {\n attrX,\n attrY,\n attrScale,\n pathLength,\n pathSpacing = 1,\n pathOffset = 0,\n // This is object creation, which we try to avoid per-frame.\n ...latest\n }: ResolvedValues,\n isSVGTag: boolean,\n transformTemplate?: MotionProps[\"transformTemplate\"],\n styleProp?: MotionProps[\"style\"]\n) {\n buildHTMLStyles(state, latest, transformTemplate)\n\n /**\n * For svg tags we just want to make sure viewBox is animatable and treat all the styles\n * as normal HTML tags.\n */\n if (isSVGTag) {\n if (state.style.viewBox) {\n state.attrs.viewBox = state.style.viewBox\n }\n return\n }\n\n state.attrs = state.style\n state.style = {}\n const { attrs, style } = state\n\n /**\n * However, we apply transforms as CSS transforms.\n * So if we detect a transform, transformOrigin we take it from attrs and copy it into style.\n */\n if (attrs.transform) {\n style.transform = attrs.transform\n delete attrs.transform\n }\n if (style.transform || attrs.transformOrigin) {\n style.transformOrigin = attrs.transformOrigin ?? \"50% 50%\"\n delete attrs.transformOrigin\n }\n\n if (style.transform) {\n /**\n * SVG's element transform-origin uses its own median as a reference.\n * Therefore, transformBox becomes a fill-box\n */\n style.transformBox = (styleProp?.transformBox as string) ?? \"fill-box\"\n delete attrs.transformBox\n }\n\n // Render attrX/attrY/attrScale as attributes\n if (attrX !== undefined) attrs.x = attrX\n if (attrY !== undefined) attrs.y = attrY\n if (attrScale !== undefined) attrs.scale = attrScale\n\n // Build SVG path if one has been defined\n if (pathLength !== undefined) {\n buildSVGPath(\n attrs,\n pathLength as number,\n pathSpacing as number,\n pathOffset as number,\n false\n )\n }\n}\n"],"names":[],"mappings":";;;AAMA;;AAEG;AACG,SAAU,aAAa,CACzB,KAAqB,EACrB,EACI,KAAK,EACL,KAAK,EACL,SAAS,EACT,UAAU,EACV,WAAW,GAAG,CAAC,EACf,UAAU,GAAG,CAAC;AACd;AACA,GAAG,MAAM,EACI,EACjB,QAAiB,EACjB,iBAAoD,EACpD,SAAgC,EAAA;AAEhC,IAAA,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAA;AAEjD;;;AAGG;IACH,IAAI,QAAQ,EAAE;AACV,QAAA,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE;YACrB,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAA;SAC5C;QACD,OAAM;KACT;AAED,IAAA,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAA;AACzB,IAAA,KAAK,CAAC,KAAK,GAAG,EAAE,CAAA;AAChB,IAAA,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CAAA;AAE9B;;;AAGG;AACH,IAAA,IAAI,KAAK,CAAC,SAAS,EAAE;AACjB,QAAA,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAA;QACjC,OAAO,KAAK,CAAC,SAAS,CAAA;KACzB;IACD,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,eAAe,EAAE;QAC1C,KAAK,CAAC,eAAe,GAAG,KAAK,CAAC,eAAe,IAAI,SAAS,CAAA;QAC1D,OAAO,KAAK,CAAC,eAAe,CAAA;KAC/B;AAED,IAAA,IAAI,KAAK,CAAC,SAAS,EAAE;AACjB;;;AAGG;QACH,KAAK,CAAC,YAAY,GAAI,SAAS,EAAE,YAAuB,IAAI,UAAU,CAAA;QACtE,OAAO,KAAK,CAAC,YAAY,CAAA;KAC5B;;IAGD,IAAI,KAAK,KAAK,SAAS;AAAE,QAAA,KAAK,CAAC,CAAC,GAAG,KAAK,CAAA;IACxC,IAAI,KAAK,KAAK,SAAS;AAAE,QAAA,KAAK,CAAC,CAAC,GAAG,KAAK,CAAA;IACxC,IAAI,SAAS,KAAK,SAAS;AAAE,QAAA,KAAK,CAAC,KAAK,GAAG,SAAS,CAAA;;AAGpD,IAAA,IAAI,UAAU,KAAK,SAAS,EAAE;QAC1B,YAAY,CACR,KAAK,EACL,UAAoB,EACpB,WAAqB,EACrB,UAAoB,EACpB,KAAK,CACR,CAAA;KACJ;AACL;;;;"}
1
+ {"version":3,"file":"build-attrs.mjs","sources":["../../../../../src/render/svg/utils/build-attrs.ts"],"sourcesContent":["import { MotionProps } from \"../../../motion/types\"\nimport { buildHTMLStyles } from \"../../html/utils/build-styles\"\nimport { ResolvedValues } from \"../../types\"\nimport { SVGRenderState } from \"../types\"\nimport { buildSVGPath } from \"./path\"\n\n/**\n * CSS Motion Path properties that should remain as CSS styles on SVG elements.\n */\nconst cssMotionPathProperties = [\n \"offsetDistance\",\n \"offsetPath\",\n \"offsetRotate\",\n \"offsetAnchor\",\n]\n\n/**\n * Build SVG visual attributes, like cx and style.transform\n */\nexport function buildSVGAttrs(\n state: SVGRenderState,\n {\n attrX,\n attrY,\n attrScale,\n pathLength,\n pathSpacing = 1,\n pathOffset = 0,\n // This is object creation, which we try to avoid per-frame.\n ...latest\n }: ResolvedValues,\n isSVGTag: boolean,\n transformTemplate?: MotionProps[\"transformTemplate\"],\n styleProp?: MotionProps[\"style\"]\n) {\n buildHTMLStyles(state, latest, transformTemplate)\n\n /**\n * For svg tags we just want to make sure viewBox is animatable and treat all the styles\n * as normal HTML tags.\n */\n if (isSVGTag) {\n if (state.style.viewBox) {\n state.attrs.viewBox = state.style.viewBox\n }\n return\n }\n\n state.attrs = state.style\n state.style = {}\n const { attrs, style } = state\n\n /**\n * However, we apply transforms as CSS transforms.\n * So if we detect a transform, transformOrigin we take it from attrs and copy it into style.\n */\n if (attrs.transform) {\n style.transform = attrs.transform\n delete attrs.transform\n }\n if (style.transform || attrs.transformOrigin) {\n style.transformOrigin = attrs.transformOrigin ?? \"50% 50%\"\n delete attrs.transformOrigin\n }\n\n if (style.transform) {\n /**\n * SVG's element transform-origin uses its own median as a reference.\n * Therefore, transformBox becomes a fill-box\n */\n style.transformBox = (styleProp?.transformBox as string) ?? \"fill-box\"\n delete attrs.transformBox\n }\n\n for (const key of cssMotionPathProperties) {\n if (attrs[key] !== undefined) {\n style[key] = attrs[key]\n delete attrs[key]\n }\n }\n\n // Render attrX/attrY/attrScale as attributes\n if (attrX !== undefined) attrs.x = attrX\n if (attrY !== undefined) attrs.y = attrY\n if (attrScale !== undefined) attrs.scale = attrScale\n\n // Build SVG path if one has been defined\n if (pathLength !== undefined) {\n buildSVGPath(\n attrs,\n pathLength as number,\n pathSpacing as number,\n pathOffset as number,\n false\n )\n }\n}\n"],"names":[],"mappings":";;;AAMA;;AAEG;AACH,MAAM,uBAAuB,GAAG;IAC5B,gBAAgB;IAChB,YAAY;IACZ,cAAc;IACd,cAAc;CACjB,CAAA;AAED;;AAEG;AACG,SAAU,aAAa,CACzB,KAAqB,EACrB,EACI,KAAK,EACL,KAAK,EACL,SAAS,EACT,UAAU,EACV,WAAW,GAAG,CAAC,EACf,UAAU,GAAG,CAAC;AACd;AACA,GAAG,MAAM,EACI,EACjB,QAAiB,EACjB,iBAAoD,EACpD,SAAgC,EAAA;AAEhC,IAAA,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAA;AAEjD;;;AAGG;IACH,IAAI,QAAQ,EAAE;AACV,QAAA,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE;YACrB,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAA;SAC5C;QACD,OAAM;KACT;AAED,IAAA,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAA;AACzB,IAAA,KAAK,CAAC,KAAK,GAAG,EAAE,CAAA;AAChB,IAAA,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CAAA;AAE9B;;;AAGG;AACH,IAAA,IAAI,KAAK,CAAC,SAAS,EAAE;AACjB,QAAA,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAA;QACjC,OAAO,KAAK,CAAC,SAAS,CAAA;KACzB;IACD,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,eAAe,EAAE;QAC1C,KAAK,CAAC,eAAe,GAAG,KAAK,CAAC,eAAe,IAAI,SAAS,CAAA;QAC1D,OAAO,KAAK,CAAC,eAAe,CAAA;KAC/B;AAED,IAAA,IAAI,KAAK,CAAC,SAAS,EAAE;AACjB;;;AAGG;QACH,KAAK,CAAC,YAAY,GAAI,SAAS,EAAE,YAAuB,IAAI,UAAU,CAAA;QACtE,OAAO,KAAK,CAAC,YAAY,CAAA;KAC5B;AAED,IAAA,KAAK,MAAM,GAAG,IAAI,uBAAuB,EAAE;AACvC,QAAA,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE;YAC1B,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;AACvB,YAAA,OAAO,KAAK,CAAC,GAAG,CAAC,CAAA;SACpB;KACJ;;IAGD,IAAI,KAAK,KAAK,SAAS;AAAE,QAAA,KAAK,CAAC,CAAC,GAAG,KAAK,CAAA;IACxC,IAAI,KAAK,KAAK,SAAS;AAAE,QAAA,KAAK,CAAC,CAAC,GAAG,KAAK,CAAA;IACxC,IAAI,SAAS,KAAK,SAAS;AAAE,QAAA,KAAK,CAAC,KAAK,GAAG,SAAS,CAAA;;AAGpD,IAAA,IAAI,UAAU,KAAK,SAAS,EAAE;QAC1B,YAAY,CACR,KAAK,EACL,UAAoB,EACpB,WAAqB,EACrB,UAAoB,EACpB,KAAK,CACR,CAAA;KACJ;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",
@@ -9248,6 +9265,15 @@
9248
9265
  attrs[keys.array] = `${pathLength} ${pathSpacing}`;
9249
9266
  }
9250
9267
 
9268
+ /**
9269
+ * CSS Motion Path properties that should remain as CSS styles on SVG elements.
9270
+ */
9271
+ const cssMotionPathProperties = [
9272
+ "offsetDistance",
9273
+ "offsetPath",
9274
+ "offsetRotate",
9275
+ "offsetAnchor",
9276
+ ];
9251
9277
  /**
9252
9278
  * Build SVG visual attributes, like cx and style.transform
9253
9279
  */
@@ -9288,6 +9314,12 @@
9288
9314
  style.transformBox = styleProp?.transformBox ?? "fill-box";
9289
9315
  delete attrs.transformBox;
9290
9316
  }
9317
+ for (const key of cssMotionPathProperties) {
9318
+ if (attrs[key] !== undefined) {
9319
+ style[key] = attrs[key];
9320
+ delete attrs[key];
9321
+ }
9322
+ }
9291
9323
  // Render attrX/attrY/attrScale as attributes
9292
9324
  if (attrX !== undefined)
9293
9325
  attrs.x = attrX;
@@ -9446,7 +9478,11 @@
9446
9478
  }
9447
9479
 
9448
9480
  const createDomVisualElement = (Component, options) => {
9449
- return isSVGComponent(Component)
9481
+ /**
9482
+ * Use explicit isSVG override if provided, otherwise auto-detect
9483
+ */
9484
+ const isSVG = options.isSVG ?? isSVGComponent(Component);
9485
+ return isSVG
9450
9486
  ? new SVGVisualElement(options)
9451
9487
  : new HTMLVisualElement(options, {
9452
9488
  allowProjection: Component !== React$1.Fragment,
@@ -9555,10 +9591,8 @@
9555
9591
  return visualProps;
9556
9592
  }
9557
9593
 
9558
- function useRender(Component, props, ref, { latestValues, }, isStatic, forwardMotionProps = false) {
9559
- const useVisualProps = isSVGComponent(Component)
9560
- ? useSVGProps
9561
- : useHTMLProps;
9594
+ function useRender(Component, props, ref, { latestValues, }, isStatic, forwardMotionProps = false, isSVG) {
9595
+ const useVisualProps = (isSVG ?? isSVGComponent(Component)) ? useSVGProps : useHTMLProps;
9562
9596
  const visualProps = useVisualProps(props, latestValues, isStatic, Component);
9563
9597
  const filteredProps = filterProps(props, typeof Component === "string", forwardMotionProps);
9564
9598
  const elementProps = Component !== React$1.Fragment ? { ...filteredProps, ...visualProps, ref } : {};
@@ -9700,7 +9734,7 @@
9700
9734
  */
9701
9735
  const SwitchLayoutGroupContext = React$1.createContext({});
9702
9736
 
9703
- function useVisualElement(Component, visualState, props, createVisualElement, ProjectionNodeConstructor) {
9737
+ function useVisualElement(Component, visualState, props, createVisualElement, ProjectionNodeConstructor, isSVG) {
9704
9738
  const { visualElement: parent } = React$1.useContext(MotionContext);
9705
9739
  const lazyContext = React$1.useContext(LazyContext);
9706
9740
  const presenceContext = React$1.useContext(PresenceContext);
@@ -9722,6 +9756,7 @@
9722
9756
  ? presenceContext.initial === false
9723
9757
  : false,
9724
9758
  reducedMotionConfig,
9759
+ isSVG,
9725
9760
  });
9726
9761
  }
9727
9762
  const visualElement = visualElementRef.current;
@@ -9837,11 +9872,15 @@
9837
9872
  * Alongside this is a config option which provides a way of rendering the provided
9838
9873
  * component "offline", or outside the React render cycle.
9839
9874
  */
9840
- function createMotionComponent(Component, { forwardMotionProps = false } = {}, preloadedFeatures, createVisualElement) {
9875
+ function createMotionComponent(Component, { forwardMotionProps = false, type } = {}, preloadedFeatures, createVisualElement) {
9841
9876
  preloadedFeatures && loadFeatures(preloadedFeatures);
9842
- const useVisualState = isSVGComponent(Component)
9843
- ? useSVGVisualState
9844
- : useHTMLVisualState;
9877
+ /**
9878
+ * Determine whether to use SVG or HTML rendering based on:
9879
+ * 1. Explicit `type` option (highest priority)
9880
+ * 2. Auto-detection via `isSVGComponent`
9881
+ */
9882
+ const isSVG = type ? type === "svg" : isSVGComponent(Component);
9883
+ const useVisualState = isSVG ? useSVGVisualState : useHTMLVisualState;
9845
9884
  function MotionDOMComponent(props, externalRef) {
9846
9885
  /**
9847
9886
  * If we need to measure the element we load this functionality in a
@@ -9866,13 +9905,13 @@
9866
9905
  * providing a way of rendering to these APIs outside of the React render loop
9867
9906
  * for more performant animations and interactions
9868
9907
  */
9869
- context.visualElement = useVisualElement(Component, visualState, configAndProps, createVisualElement, layoutProjection.ProjectionNode);
9908
+ context.visualElement = useVisualElement(Component, visualState, configAndProps, createVisualElement, layoutProjection.ProjectionNode, isSVG);
9870
9909
  }
9871
9910
  /**
9872
9911
  * The mount order and hierarchy is specific to ensure our element ref
9873
9912
  * is hydrated by the time features fire their effects.
9874
9913
  */
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)] }));
9914
+ 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
9915
  }
9877
9916
  MotionDOMComponent.displayName = `motion.${typeof Component === "string"
9878
9917
  ? Component
@@ -11444,6 +11483,16 @@
11444
11483
  }
11445
11484
  this.removeListeners = this.controls.addListeners() || noop;
11446
11485
  }
11486
+ update() {
11487
+ const { dragControls } = this.node.getProps();
11488
+ const { dragControls: prevDragControls } = this.node.prevProps || {};
11489
+ if (dragControls !== prevDragControls) {
11490
+ this.removeGroupControls();
11491
+ if (dragControls) {
11492
+ this.removeGroupControls = dragControls.subscribe(this.controls);
11493
+ }
11494
+ }
11495
+ }
11447
11496
  unmount() {
11448
11497
  this.removeGroupControls();
11449
11498
  this.removeListeners();
@@ -14242,7 +14291,6 @@
14242
14291
  exports.collectMotionValues = collectMotionValues;
14243
14292
  exports.color = color;
14244
14293
  exports.complex = complex;
14245
- exports.containsCSSVariable = containsCSSVariable;
14246
14294
  exports.convertOffsetToTimes = convertOffsetToTimes;
14247
14295
  exports.createBox = createBox;
14248
14296
  exports.createGeneratorEasing = createGeneratorEasing;