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.
- package/dist/cjs/client.js +1 -1
- package/dist/cjs/{feature-bundle-Dt2VtvSZ.js → feature-bundle-DhbxBqkJ.js} +30 -13
- package/dist/cjs/feature-bundle-DhbxBqkJ.js.map +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/m.js +14 -11
- package/dist/cjs/m.js.map +1 -1
- package/dist/dom-mini.js +1 -1
- package/dist/dom.js +1 -1
- package/dist/es/components/Reorder/Group.mjs.map +1 -1
- package/dist/es/gestures/drag/index.mjs +10 -0
- package/dist/es/gestures/drag/index.mjs.map +1 -1
- package/dist/es/motion/index.mjs +10 -6
- package/dist/es/motion/index.mjs.map +1 -1
- package/dist/es/motion/utils/use-visual-element.mjs +2 -1
- package/dist/es/motion/utils/use-visual-element.mjs.map +1 -1
- package/dist/es/render/dom/create-visual-element.mjs +5 -1
- package/dist/es/render/dom/create-visual-element.mjs.map +1 -1
- package/dist/es/render/dom/use-render.mjs +2 -4
- package/dist/es/render/dom/use-render.mjs.map +1 -1
- package/dist/framer-motion.dev.js +67 -34
- package/dist/framer-motion.js +1 -1
- package/dist/m.d.ts +8 -0
- package/dist/mini.js +1 -1
- package/dist/size-rollup-animate.js +1 -1
- package/dist/size-rollup-animate.js.map +1 -1
- package/dist/size-rollup-dom-animation-assets.js +1 -1
- package/dist/size-rollup-dom-animation-m.js +1 -1
- package/dist/size-rollup-dom-animation.js +1 -1
- package/dist/size-rollup-dom-max-assets.js +1 -1
- package/dist/size-rollup-dom-max.js +1 -1
- package/dist/size-rollup-m.js +1 -1
- package/dist/size-rollup-m.js.map +1 -1
- package/dist/size-rollup-motion.js +1 -1
- package/dist/size-rollup-motion.js.map +1 -1
- package/dist/size-rollup-scroll.js.map +1 -1
- package/dist/size-rollup-waapi-animate.js +1 -1
- package/dist/size-rollup-waapi-animate.js.map +1 -1
- package/dist/types/client.d.ts +1 -1
- package/dist/types/index.d.ts +13 -5
- package/dist/{types.d-C8SDx5n-.d.ts → types.d-a9pt5qxk.d.ts} +5 -0
- package/package.json +3 -3
- package/dist/cjs/feature-bundle-Dt2VtvSZ.js.map +0 -1
package/dist/es/motion/index.mjs
CHANGED
|
@@ -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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
|
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":";;;;;;;;;;;
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
9843
|
-
|
|
9844
|
-
|
|
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;
|