motion 12.11.4 → 12.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/dist/cjs/index.js +72 -3
  2. package/dist/cjs/react-client.js +109 -109
  3. package/dist/cjs/react-m.js +108 -108
  4. package/dist/es/framer-motion/dist/es/animation/animate/single-value.mjs +1 -1
  5. package/dist/es/framer-motion/dist/es/animation/animate/subject.mjs +1 -1
  6. package/dist/es/framer-motion/dist/es/animation/sequence/create.mjs +1 -1
  7. package/dist/es/framer-motion/dist/es/components/Reorder/Item.mjs +1 -1
  8. package/dist/es/framer-motion/dist/es/render/VisualElement.mjs +1 -1
  9. package/dist/es/framer-motion/dist/es/render/dom/DOMVisualElement.mjs +1 -1
  10. package/dist/es/framer-motion/dist/es/render/dom/use-render.mjs +2 -2
  11. package/dist/es/framer-motion/dist/es/render/html/use-props.mjs +1 -1
  12. package/dist/es/framer-motion/dist/es/render/html/utils/scrape-motion-values.mjs +1 -1
  13. package/dist/es/framer-motion/dist/es/render/svg/utils/scrape-motion-values.mjs +1 -1
  14. package/dist/es/framer-motion/dist/es/render/utils/motion-values.mjs +1 -1
  15. package/dist/es/framer-motion/dist/es/value/use-motion-template.mjs +1 -1
  16. package/dist/es/framer-motion/dist/es/value/use-spring.mjs +13 -53
  17. package/dist/es/framer-motion/dist/es/value/use-will-change/is.mjs +1 -1
  18. package/dist/es/framer-motion/dist/es/value/utils/resolve-motion-value.mjs +1 -1
  19. package/dist/es/motion/lib/index.mjs +2 -0
  20. package/dist/es/motion/lib/react.mjs +2 -1
  21. package/dist/es/motion-dom/dist/es/utils/interpolate.mjs +1 -1
  22. package/dist/es/motion-dom/dist/es/value/spring-value.mjs +72 -0
  23. package/dist/motion.dev.js +72 -3
  24. package/dist/motion.js +1 -1
  25. package/package.json +3 -3
  26. /package/dist/es/{framer-motion → motion-dom}/dist/es/value/utils/is-motion-value.mjs +0 -0
package/dist/cjs/index.js CHANGED
@@ -1423,7 +1423,7 @@ function createMixers(output, ease, customMixer) {
1423
1423
  * mixColor(0.5) // 'rgba(128, 128, 128, 1)'
1424
1424
  * ```
1425
1425
  *
1426
- * TODO Revist this approach once we've moved to data models for values,
1426
+ * TODO Revisit this approach once we've moved to data models for values,
1427
1427
  * probably not needed to pregenerate mixer functions.
1428
1428
  *
1429
1429
  * @public
@@ -4268,6 +4268,74 @@ function mapValue(inputValue, inputRange, outputRange, options) {
4268
4268
  return transformValue(() => map(inputValue.get()));
4269
4269
  }
4270
4270
 
4271
+ const isMotionValue = (value) => Boolean(value && value.getVelocity);
4272
+
4273
+ /**
4274
+ * Create a `MotionValue` that animates to its latest value using a spring.
4275
+ * Can either be a value or track another `MotionValue`.
4276
+ *
4277
+ * ```jsx
4278
+ * const x = motionValue(0)
4279
+ * const y = transformValue(() => x.get() * 2) // double x
4280
+ * ```
4281
+ *
4282
+ * @param transformer - A transform function. This function must be pure with no side-effects or conditional statements.
4283
+ * @returns `MotionValue`
4284
+ *
4285
+ * @public
4286
+ */
4287
+ function springValue(source, options) {
4288
+ const initialValue = isMotionValue(source) ? source.get() : source;
4289
+ const value = motionValue(initialValue);
4290
+ attachSpring(value, source, options);
4291
+ return value;
4292
+ }
4293
+ function attachSpring(value, source, options) {
4294
+ const initialValue = value.get();
4295
+ let activeAnimation = null;
4296
+ let latestValue = initialValue;
4297
+ let latestSetter;
4298
+ const unit = typeof initialValue === "string"
4299
+ ? initialValue.replace(/[\d.-]/g, "")
4300
+ : undefined;
4301
+ const stopAnimation = () => {
4302
+ if (activeAnimation) {
4303
+ activeAnimation.stop();
4304
+ activeAnimation = null;
4305
+ }
4306
+ };
4307
+ const startAnimation = () => {
4308
+ stopAnimation();
4309
+ activeAnimation = new JSAnimation({
4310
+ keyframes: [asNumber(value.get()), asNumber(latestValue)],
4311
+ velocity: value.getVelocity(),
4312
+ type: "spring",
4313
+ restDelta: 0.001,
4314
+ restSpeed: 0.01,
4315
+ ...options,
4316
+ onUpdate: latestSetter,
4317
+ });
4318
+ };
4319
+ value.attach((v, set) => {
4320
+ latestValue = v;
4321
+ latestSetter = (latest) => set(parseValue(latest, unit));
4322
+ frame.postRender(startAnimation);
4323
+ return value.get();
4324
+ }, stopAnimation);
4325
+ let unsubscribe = undefined;
4326
+ if (isMotionValue(source)) {
4327
+ unsubscribe = source.on("change", (v) => value.set(parseValue(v, unit)));
4328
+ value.on("destroy", unsubscribe);
4329
+ }
4330
+ return unsubscribe;
4331
+ }
4332
+ function parseValue(v, unit) {
4333
+ return unit ? v + unit : v;
4334
+ }
4335
+ function asNumber(v) {
4336
+ return typeof v === "number" ? v : parseFloat(v);
4337
+ }
4338
+
4271
4339
  /**
4272
4340
  * A list of all ValueTypes
4273
4341
  */
@@ -4604,8 +4672,6 @@ const cancelSync = stepsOrder.reduce((acc, key) => {
4604
4672
  return acc;
4605
4673
  }, {});
4606
4674
 
4607
- const isMotionValue = (value) => Boolean(value && value.getVelocity);
4608
-
4609
4675
  function isDOMKeyframes(keyframes) {
4610
4676
  return typeof keyframes === "object" && !Array.isArray(keyframes);
4611
4677
  }
@@ -7186,6 +7252,7 @@ exports.animateView = animateView;
7186
7252
  exports.animationMapKey = animationMapKey;
7187
7253
  exports.anticipate = anticipate;
7188
7254
  exports.applyPxDefaults = applyPxDefaults;
7255
+ exports.attachSpring = attachSpring;
7189
7256
  exports.backIn = backIn;
7190
7257
  exports.backInOut = backInOut;
7191
7258
  exports.backOut = backOut;
@@ -7253,6 +7320,7 @@ exports.isDragActive = isDragActive;
7253
7320
  exports.isDragging = isDragging;
7254
7321
  exports.isEasingArray = isEasingArray;
7255
7322
  exports.isGenerator = isGenerator;
7323
+ exports.isMotionValue = isMotionValue;
7256
7324
  exports.isNodeOrChild = isNodeOrChild;
7257
7325
  exports.isNumericalString = isNumericalString;
7258
7326
  exports.isPrimaryPointer = isPrimaryPointer;
@@ -7304,6 +7372,7 @@ exports.secondsToMilliseconds = secondsToMilliseconds;
7304
7372
  exports.setDragLock = setDragLock;
7305
7373
  exports.setStyle = setStyle;
7306
7374
  exports.spring = spring;
7375
+ exports.springValue = springValue;
7307
7376
  exports.stagger = stagger;
7308
7377
  exports.startWaapiAnimation = startWaapiAnimation;
7309
7378
  exports.statsBuffer = statsBuffer;
@@ -1432,7 +1432,7 @@ function createMixers(output, ease, customMixer) {
1432
1432
  * mixColor(0.5) // 'rgba(128, 128, 128, 1)'
1433
1433
  * ```
1434
1434
  *
1435
- * TODO Revist this approach once we've moved to data models for values,
1435
+ * TODO Revisit this approach once we've moved to data models for values,
1436
1436
  * probably not needed to pregenerate mixer functions.
1437
1437
  *
1438
1438
  * @public
@@ -3741,6 +3741,8 @@ function press(targetOrSelector, onPressStart, options = {}) {
3741
3741
  return cancelEvents;
3742
3742
  }
3743
3743
 
3744
+ const isMotionValue = (value) => Boolean(value && value.getVelocity);
3745
+
3744
3746
  /**
3745
3747
  * A list of all ValueTypes
3746
3748
  */
@@ -3780,8 +3782,6 @@ function setTarget(visualElement, definition) {
3780
3782
  }
3781
3783
  }
3782
3784
 
3783
- const isMotionValue = (value) => Boolean(value && value.getVelocity);
3784
-
3785
3785
  function isWillChangeMotionValue(value) {
3786
3786
  return Boolean(isMotionValue(value) && value.add);
3787
3787
  }
@@ -8652,6 +8652,112 @@ function useHTMLProps(props, visualState) {
8652
8652
  return htmlProps;
8653
8653
  }
8654
8654
 
8655
+ const dashKeys = {
8656
+ offset: "stroke-dashoffset",
8657
+ array: "stroke-dasharray",
8658
+ };
8659
+ const camelKeys = {
8660
+ offset: "strokeDashoffset",
8661
+ array: "strokeDasharray",
8662
+ };
8663
+ /**
8664
+ * Build SVG path properties. Uses the path's measured length to convert
8665
+ * our custom pathLength, pathSpacing and pathOffset into stroke-dashoffset
8666
+ * and stroke-dasharray attributes.
8667
+ *
8668
+ * This function is mutative to reduce per-frame GC.
8669
+ */
8670
+ function buildSVGPath(attrs, length, spacing = 1, offset = 0, useDashCase = true) {
8671
+ // Normalise path length by setting SVG attribute pathLength to 1
8672
+ attrs.pathLength = 1;
8673
+ // We use dash case when setting attributes directly to the DOM node and camel case
8674
+ // when defining props on a React component.
8675
+ const keys = useDashCase ? dashKeys : camelKeys;
8676
+ // Build the dash offset
8677
+ attrs[keys.offset] = px.transform(-offset);
8678
+ // Build the dash array
8679
+ const pathLength = px.transform(length);
8680
+ const pathSpacing = px.transform(spacing);
8681
+ attrs[keys.array] = `${pathLength} ${pathSpacing}`;
8682
+ }
8683
+
8684
+ /**
8685
+ * Build SVG visual attrbutes, like cx and style.transform
8686
+ */
8687
+ function buildSVGAttrs(state, { attrX, attrY, attrScale, pathLength, pathSpacing = 1, pathOffset = 0,
8688
+ // This is object creation, which we try to avoid per-frame.
8689
+ ...latest }, isSVGTag, transformTemplate, styleProp) {
8690
+ buildHTMLStyles(state, latest, transformTemplate);
8691
+ /**
8692
+ * For svg tags we just want to make sure viewBox is animatable and treat all the styles
8693
+ * as normal HTML tags.
8694
+ */
8695
+ if (isSVGTag) {
8696
+ if (state.style.viewBox) {
8697
+ state.attrs.viewBox = state.style.viewBox;
8698
+ }
8699
+ return;
8700
+ }
8701
+ state.attrs = state.style;
8702
+ state.style = {};
8703
+ const { attrs, style } = state;
8704
+ /**
8705
+ * However, we apply transforms as CSS transforms.
8706
+ * So if we detect a transform, transformOrigin we take it from attrs and copy it into style.
8707
+ */
8708
+ if (attrs.transform) {
8709
+ style.transform = attrs.transform;
8710
+ delete attrs.transform;
8711
+ }
8712
+ if (style.transform || attrs.transformOrigin) {
8713
+ style.transformOrigin = attrs.transformOrigin ?? "50% 50%";
8714
+ delete attrs.transformOrigin;
8715
+ }
8716
+ if (style.transform) {
8717
+ /**
8718
+ * SVG's element transform-origin uses its own median as a reference.
8719
+ * Therefore, transformBox becomes a fill-box
8720
+ */
8721
+ style.transformBox = styleProp?.transformBox ?? "fill-box";
8722
+ delete attrs.transformBox;
8723
+ }
8724
+ // Render attrX/attrY/attrScale as attributes
8725
+ if (attrX !== undefined)
8726
+ attrs.x = attrX;
8727
+ if (attrY !== undefined)
8728
+ attrs.y = attrY;
8729
+ if (attrScale !== undefined)
8730
+ attrs.scale = attrScale;
8731
+ // Build SVG path if one has been defined
8732
+ if (pathLength !== undefined) {
8733
+ buildSVGPath(attrs, pathLength, pathSpacing, pathOffset, false);
8734
+ }
8735
+ }
8736
+
8737
+ const createSvgRenderState = () => ({
8738
+ ...createHtmlRenderState(),
8739
+ attrs: {},
8740
+ });
8741
+
8742
+ const isSVGTag = (tag) => typeof tag === "string" && tag.toLowerCase() === "svg";
8743
+
8744
+ function useSVGProps(props, visualState, _isStatic, Component) {
8745
+ const visualProps = react.useMemo(() => {
8746
+ const state = createSvgRenderState();
8747
+ buildSVGAttrs(state, visualState, isSVGTag(Component), props.transformTemplate, props.style);
8748
+ return {
8749
+ ...state.attrs,
8750
+ style: { ...state.style },
8751
+ };
8752
+ }, [visualState]);
8753
+ if (props.style) {
8754
+ const rawStyles = {};
8755
+ copyRawValuesOnly(rawStyles, props.style, props);
8756
+ visualProps.style = { ...rawStyles, ...visualProps.style };
8757
+ }
8758
+ return visualProps;
8759
+ }
8760
+
8655
8761
  /**
8656
8762
  * A list of all valid MotionProps.
8657
8763
  *
@@ -8823,112 +8929,6 @@ function isSVGComponent(Component) {
8823
8929
  return false;
8824
8930
  }
8825
8931
 
8826
- const dashKeys = {
8827
- offset: "stroke-dashoffset",
8828
- array: "stroke-dasharray",
8829
- };
8830
- const camelKeys = {
8831
- offset: "strokeDashoffset",
8832
- array: "strokeDasharray",
8833
- };
8834
- /**
8835
- * Build SVG path properties. Uses the path's measured length to convert
8836
- * our custom pathLength, pathSpacing and pathOffset into stroke-dashoffset
8837
- * and stroke-dasharray attributes.
8838
- *
8839
- * This function is mutative to reduce per-frame GC.
8840
- */
8841
- function buildSVGPath(attrs, length, spacing = 1, offset = 0, useDashCase = true) {
8842
- // Normalise path length by setting SVG attribute pathLength to 1
8843
- attrs.pathLength = 1;
8844
- // We use dash case when setting attributes directly to the DOM node and camel case
8845
- // when defining props on a React component.
8846
- const keys = useDashCase ? dashKeys : camelKeys;
8847
- // Build the dash offset
8848
- attrs[keys.offset] = px.transform(-offset);
8849
- // Build the dash array
8850
- const pathLength = px.transform(length);
8851
- const pathSpacing = px.transform(spacing);
8852
- attrs[keys.array] = `${pathLength} ${pathSpacing}`;
8853
- }
8854
-
8855
- /**
8856
- * Build SVG visual attrbutes, like cx and style.transform
8857
- */
8858
- function buildSVGAttrs(state, { attrX, attrY, attrScale, pathLength, pathSpacing = 1, pathOffset = 0,
8859
- // This is object creation, which we try to avoid per-frame.
8860
- ...latest }, isSVGTag, transformTemplate, styleProp) {
8861
- buildHTMLStyles(state, latest, transformTemplate);
8862
- /**
8863
- * For svg tags we just want to make sure viewBox is animatable and treat all the styles
8864
- * as normal HTML tags.
8865
- */
8866
- if (isSVGTag) {
8867
- if (state.style.viewBox) {
8868
- state.attrs.viewBox = state.style.viewBox;
8869
- }
8870
- return;
8871
- }
8872
- state.attrs = state.style;
8873
- state.style = {};
8874
- const { attrs, style } = state;
8875
- /**
8876
- * However, we apply transforms as CSS transforms.
8877
- * So if we detect a transform, transformOrigin we take it from attrs and copy it into style.
8878
- */
8879
- if (attrs.transform) {
8880
- style.transform = attrs.transform;
8881
- delete attrs.transform;
8882
- }
8883
- if (style.transform || attrs.transformOrigin) {
8884
- style.transformOrigin = attrs.transformOrigin ?? "50% 50%";
8885
- delete attrs.transformOrigin;
8886
- }
8887
- if (style.transform) {
8888
- /**
8889
- * SVG's element transform-origin uses its own median as a reference.
8890
- * Therefore, transformBox becomes a fill-box
8891
- */
8892
- style.transformBox = styleProp?.transformBox ?? "fill-box";
8893
- delete attrs.transformBox;
8894
- }
8895
- // Render attrX/attrY/attrScale as attributes
8896
- if (attrX !== undefined)
8897
- attrs.x = attrX;
8898
- if (attrY !== undefined)
8899
- attrs.y = attrY;
8900
- if (attrScale !== undefined)
8901
- attrs.scale = attrScale;
8902
- // Build SVG path if one has been defined
8903
- if (pathLength !== undefined) {
8904
- buildSVGPath(attrs, pathLength, pathSpacing, pathOffset, false);
8905
- }
8906
- }
8907
-
8908
- const createSvgRenderState = () => ({
8909
- ...createHtmlRenderState(),
8910
- attrs: {},
8911
- });
8912
-
8913
- const isSVGTag = (tag) => typeof tag === "string" && tag.toLowerCase() === "svg";
8914
-
8915
- function useSVGProps(props, visualState, _isStatic, Component) {
8916
- const visualProps = react.useMemo(() => {
8917
- const state = createSvgRenderState();
8918
- buildSVGAttrs(state, visualState, isSVGTag(Component), props.transformTemplate, props.style);
8919
- return {
8920
- ...state.attrs,
8921
- style: { ...state.style },
8922
- };
8923
- }, [visualState]);
8924
- if (props.style) {
8925
- const rawStyles = {};
8926
- copyRawValuesOnly(rawStyles, props.style, props);
8927
- visualProps.style = { ...rawStyles, ...visualProps.style };
8928
- }
8929
- return visualProps;
8930
- }
8931
-
8932
8932
  function createUseRender(forwardMotionProps = false) {
8933
8933
  const useRender = (Component, props, ref, { latestValues }, isStatic) => {
8934
8934
  const useVisualProps = isSVGComponent(Component)
@@ -497,6 +497,8 @@ const getValueAsType = (value, type) => {
497
497
  const { schedule: microtask, cancel: cancelMicrotask } =
498
498
  /* @__PURE__ */ createRenderBatcher(queueMicrotask, false);
499
499
 
500
+ const isMotionValue = (value) => Boolean(value && value.getVelocity);
501
+
500
502
  /**
501
503
  * Convert camelCase to dash-case properties.
502
504
  */
@@ -732,8 +734,6 @@ function isForcedMotionValue(key, { layout, layoutId }) {
732
734
  (!!scaleCorrectors[key] || key === "opacity")));
733
735
  }
734
736
 
735
- const isMotionValue = (value) => Boolean(value && value.getVelocity);
736
-
737
737
  const translateAlias = {
738
738
  x: "translateX",
739
739
  y: "translateY",
@@ -906,6 +906,112 @@ function useHTMLProps(props, visualState) {
906
906
  return htmlProps;
907
907
  }
908
908
 
909
+ const dashKeys = {
910
+ offset: "stroke-dashoffset",
911
+ array: "stroke-dasharray",
912
+ };
913
+ const camelKeys = {
914
+ offset: "strokeDashoffset",
915
+ array: "strokeDasharray",
916
+ };
917
+ /**
918
+ * Build SVG path properties. Uses the path's measured length to convert
919
+ * our custom pathLength, pathSpacing and pathOffset into stroke-dashoffset
920
+ * and stroke-dasharray attributes.
921
+ *
922
+ * This function is mutative to reduce per-frame GC.
923
+ */
924
+ function buildSVGPath(attrs, length, spacing = 1, offset = 0, useDashCase = true) {
925
+ // Normalise path length by setting SVG attribute pathLength to 1
926
+ attrs.pathLength = 1;
927
+ // We use dash case when setting attributes directly to the DOM node and camel case
928
+ // when defining props on a React component.
929
+ const keys = useDashCase ? dashKeys : camelKeys;
930
+ // Build the dash offset
931
+ attrs[keys.offset] = px.transform(-offset);
932
+ // Build the dash array
933
+ const pathLength = px.transform(length);
934
+ const pathSpacing = px.transform(spacing);
935
+ attrs[keys.array] = `${pathLength} ${pathSpacing}`;
936
+ }
937
+
938
+ /**
939
+ * Build SVG visual attrbutes, like cx and style.transform
940
+ */
941
+ function buildSVGAttrs(state, { attrX, attrY, attrScale, pathLength, pathSpacing = 1, pathOffset = 0,
942
+ // This is object creation, which we try to avoid per-frame.
943
+ ...latest }, isSVGTag, transformTemplate, styleProp) {
944
+ buildHTMLStyles(state, latest, transformTemplate);
945
+ /**
946
+ * For svg tags we just want to make sure viewBox is animatable and treat all the styles
947
+ * as normal HTML tags.
948
+ */
949
+ if (isSVGTag) {
950
+ if (state.style.viewBox) {
951
+ state.attrs.viewBox = state.style.viewBox;
952
+ }
953
+ return;
954
+ }
955
+ state.attrs = state.style;
956
+ state.style = {};
957
+ const { attrs, style } = state;
958
+ /**
959
+ * However, we apply transforms as CSS transforms.
960
+ * So if we detect a transform, transformOrigin we take it from attrs and copy it into style.
961
+ */
962
+ if (attrs.transform) {
963
+ style.transform = attrs.transform;
964
+ delete attrs.transform;
965
+ }
966
+ if (style.transform || attrs.transformOrigin) {
967
+ style.transformOrigin = attrs.transformOrigin ?? "50% 50%";
968
+ delete attrs.transformOrigin;
969
+ }
970
+ if (style.transform) {
971
+ /**
972
+ * SVG's element transform-origin uses its own median as a reference.
973
+ * Therefore, transformBox becomes a fill-box
974
+ */
975
+ style.transformBox = styleProp?.transformBox ?? "fill-box";
976
+ delete attrs.transformBox;
977
+ }
978
+ // Render attrX/attrY/attrScale as attributes
979
+ if (attrX !== undefined)
980
+ attrs.x = attrX;
981
+ if (attrY !== undefined)
982
+ attrs.y = attrY;
983
+ if (attrScale !== undefined)
984
+ attrs.scale = attrScale;
985
+ // Build SVG path if one has been defined
986
+ if (pathLength !== undefined) {
987
+ buildSVGPath(attrs, pathLength, pathSpacing, pathOffset, false);
988
+ }
989
+ }
990
+
991
+ const createSvgRenderState = () => ({
992
+ ...createHtmlRenderState(),
993
+ attrs: {},
994
+ });
995
+
996
+ const isSVGTag = (tag) => typeof tag === "string" && tag.toLowerCase() === "svg";
997
+
998
+ function useSVGProps(props, visualState, _isStatic, Component) {
999
+ const visualProps = react.useMemo(() => {
1000
+ const state = createSvgRenderState();
1001
+ buildSVGAttrs(state, visualState, isSVGTag(Component), props.transformTemplate, props.style);
1002
+ return {
1003
+ ...state.attrs,
1004
+ style: { ...state.style },
1005
+ };
1006
+ }, [visualState]);
1007
+ if (props.style) {
1008
+ const rawStyles = {};
1009
+ copyRawValuesOnly(rawStyles, props.style, props);
1010
+ visualProps.style = { ...rawStyles, ...visualProps.style };
1011
+ }
1012
+ return visualProps;
1013
+ }
1014
+
909
1015
  /**
910
1016
  * A list of all valid MotionProps.
911
1017
  *
@@ -1077,112 +1183,6 @@ function isSVGComponent(Component) {
1077
1183
  return false;
1078
1184
  }
1079
1185
 
1080
- const dashKeys = {
1081
- offset: "stroke-dashoffset",
1082
- array: "stroke-dasharray",
1083
- };
1084
- const camelKeys = {
1085
- offset: "strokeDashoffset",
1086
- array: "strokeDasharray",
1087
- };
1088
- /**
1089
- * Build SVG path properties. Uses the path's measured length to convert
1090
- * our custom pathLength, pathSpacing and pathOffset into stroke-dashoffset
1091
- * and stroke-dasharray attributes.
1092
- *
1093
- * This function is mutative to reduce per-frame GC.
1094
- */
1095
- function buildSVGPath(attrs, length, spacing = 1, offset = 0, useDashCase = true) {
1096
- // Normalise path length by setting SVG attribute pathLength to 1
1097
- attrs.pathLength = 1;
1098
- // We use dash case when setting attributes directly to the DOM node and camel case
1099
- // when defining props on a React component.
1100
- const keys = useDashCase ? dashKeys : camelKeys;
1101
- // Build the dash offset
1102
- attrs[keys.offset] = px.transform(-offset);
1103
- // Build the dash array
1104
- const pathLength = px.transform(length);
1105
- const pathSpacing = px.transform(spacing);
1106
- attrs[keys.array] = `${pathLength} ${pathSpacing}`;
1107
- }
1108
-
1109
- /**
1110
- * Build SVG visual attrbutes, like cx and style.transform
1111
- */
1112
- function buildSVGAttrs(state, { attrX, attrY, attrScale, pathLength, pathSpacing = 1, pathOffset = 0,
1113
- // This is object creation, which we try to avoid per-frame.
1114
- ...latest }, isSVGTag, transformTemplate, styleProp) {
1115
- buildHTMLStyles(state, latest, transformTemplate);
1116
- /**
1117
- * For svg tags we just want to make sure viewBox is animatable and treat all the styles
1118
- * as normal HTML tags.
1119
- */
1120
- if (isSVGTag) {
1121
- if (state.style.viewBox) {
1122
- state.attrs.viewBox = state.style.viewBox;
1123
- }
1124
- return;
1125
- }
1126
- state.attrs = state.style;
1127
- state.style = {};
1128
- const { attrs, style } = state;
1129
- /**
1130
- * However, we apply transforms as CSS transforms.
1131
- * So if we detect a transform, transformOrigin we take it from attrs and copy it into style.
1132
- */
1133
- if (attrs.transform) {
1134
- style.transform = attrs.transform;
1135
- delete attrs.transform;
1136
- }
1137
- if (style.transform || attrs.transformOrigin) {
1138
- style.transformOrigin = attrs.transformOrigin ?? "50% 50%";
1139
- delete attrs.transformOrigin;
1140
- }
1141
- if (style.transform) {
1142
- /**
1143
- * SVG's element transform-origin uses its own median as a reference.
1144
- * Therefore, transformBox becomes a fill-box
1145
- */
1146
- style.transformBox = styleProp?.transformBox ?? "fill-box";
1147
- delete attrs.transformBox;
1148
- }
1149
- // Render attrX/attrY/attrScale as attributes
1150
- if (attrX !== undefined)
1151
- attrs.x = attrX;
1152
- if (attrY !== undefined)
1153
- attrs.y = attrY;
1154
- if (attrScale !== undefined)
1155
- attrs.scale = attrScale;
1156
- // Build SVG path if one has been defined
1157
- if (pathLength !== undefined) {
1158
- buildSVGPath(attrs, pathLength, pathSpacing, pathOffset, false);
1159
- }
1160
- }
1161
-
1162
- const createSvgRenderState = () => ({
1163
- ...createHtmlRenderState(),
1164
- attrs: {},
1165
- });
1166
-
1167
- const isSVGTag = (tag) => typeof tag === "string" && tag.toLowerCase() === "svg";
1168
-
1169
- function useSVGProps(props, visualState, _isStatic, Component) {
1170
- const visualProps = react.useMemo(() => {
1171
- const state = createSvgRenderState();
1172
- buildSVGAttrs(state, visualState, isSVGTag(Component), props.transformTemplate, props.style);
1173
- return {
1174
- ...state.attrs,
1175
- style: { ...state.style },
1176
- };
1177
- }, [visualState]);
1178
- if (props.style) {
1179
- const rawStyles = {};
1180
- copyRawValuesOnly(rawStyles, props.style, props);
1181
- visualProps.style = { ...rawStyles, ...visualProps.style };
1182
- }
1183
- return visualProps;
1184
- }
1185
-
1186
1186
  function createUseRender(forwardMotionProps = false) {
1187
1187
  const useRender = (Component, props, ref, { latestValues }, isStatic) => {
1188
1188
  const useVisualProps = isSVGComponent(Component)
@@ -1,5 +1,5 @@
1
- import { isMotionValue } from '../../value/utils/is-motion-value.mjs';
2
1
  import { animateMotionValue } from '../interfaces/motion-value.mjs';
2
+ import { isMotionValue } from '../../../../../motion-dom/dist/es/value/utils/is-motion-value.mjs';
3
3
  import { motionValue } from '../../../../../motion-dom/dist/es/value/index.mjs';
4
4
 
5
5
  function animateSingleValue(value, keyframes, options) {
@@ -1,11 +1,11 @@
1
1
  import { visualElementStore } from '../../render/store.mjs';
2
- import { isMotionValue } from '../../value/utils/is-motion-value.mjs';
3
2
  import { animateTarget } from '../interfaces/visual-element-target.mjs';
4
3
  import { createDOMVisualElement, createObjectVisualElement } from '../utils/create-visual-element.mjs';
5
4
  import { isDOMKeyframes } from '../utils/is-dom-keyframes.mjs';
6
5
  import { resolveSubjects } from './resolve-subjects.mjs';
7
6
  import { animateSingleValue } from './single-value.mjs';
8
7
  import { invariant } from '../../../../../motion-utils/dist/es/errors.mjs';
8
+ import { isMotionValue } from '../../../../../motion-dom/dist/es/value/utils/is-motion-value.mjs';
9
9
 
10
10
  function isSingleValue(subject, keyframes) {
11
11
  return (isMotionValue(subject) ||
@@ -1,10 +1,10 @@
1
- import { isMotionValue } from '../../value/utils/is-motion-value.mjs';
2
1
  import { resolveSubjects } from '../animate/resolve-subjects.mjs';
3
2
  import { calculateRepeatDuration } from './utils/calc-repeat-duration.mjs';
4
3
  import { calcNextTime } from './utils/calc-time.mjs';
5
4
  import { addKeyframes } from './utils/edit.mjs';
6
5
  import { normalizeTimes } from './utils/normalize-times.mjs';
7
6
  import { compareByTime } from './utils/sort.mjs';
7
+ import { isMotionValue } from '../../../../../motion-dom/dist/es/value/utils/is-motion-value.mjs';
8
8
  import { defaultOffset } from '../../../../../motion-dom/dist/es/animation/keyframes/offsets/default.mjs';
9
9
  import { isGenerator } from '../../../../../motion-dom/dist/es/animation/generators/utils/is-generator.mjs';
10
10
  import { createGeneratorEasing } from '../../../../../motion-dom/dist/es/animation/generators/utils/create-generator-easing.mjs';
@@ -6,8 +6,8 @@ import { motion } from '../../render/components/motion/proxy.mjs';
6
6
  import { useConstant } from '../../utils/use-constant.mjs';
7
7
  import { useMotionValue } from '../../value/use-motion-value.mjs';
8
8
  import { useTransform } from '../../value/use-transform.mjs';
9
- import { isMotionValue } from '../../value/utils/is-motion-value.mjs';
10
9
  import { invariant } from '../../../../../motion-utils/dist/es/errors.mjs';
10
+ import { isMotionValue } from '../../../../../motion-dom/dist/es/value/utils/is-motion-value.mjs';
11
11
 
12
12
  function useDefaultMotionValue(value, defaultValue = 0) {
13
13
  return isMotionValue(value) ? value : useMotionValue(defaultValue);
@@ -2,7 +2,6 @@ import { featureDefinitions } from '../motion/features/definitions.mjs';
2
2
  import { createBox } from '../projection/geometry/models.mjs';
3
3
  import { initPrefersReducedMotion } from '../utils/reduced-motion/index.mjs';
4
4
  import { hasReducedMotionListener, prefersReducedMotion } from '../utils/reduced-motion/state.mjs';
5
- import { isMotionValue } from '../value/utils/is-motion-value.mjs';
6
5
  import { visualElementStore } from './store.mjs';
7
6
  import { isControllingVariants, isVariantNode } from './utils/is-controlling-variants.mjs';
8
7
  import { updateMotionValuesFromProps } from './utils/motion-values.mjs';
@@ -10,6 +9,7 @@ import { resolveVariantFromProps } from './utils/resolve-variants.mjs';
10
9
  import { KeyframeResolver } from '../../../../motion-dom/dist/es/animation/keyframes/KeyframesResolver.mjs';
11
10
  import { time } from '../../../../motion-dom/dist/es/frameloop/sync-time.mjs';
12
11
  import { frame, cancelFrame } from '../../../../motion-dom/dist/es/frameloop/frame.mjs';
12
+ import { isMotionValue } from '../../../../motion-dom/dist/es/value/utils/is-motion-value.mjs';
13
13
  import { warnOnce } from '../../../../motion-utils/dist/es/warn-once.mjs';
14
14
  import { transformProps } from '../../../../motion-dom/dist/es/render/utils/keys-transform.mjs';
15
15
  import { motionValue } from '../../../../motion-dom/dist/es/value/index.mjs';
@@ -1,6 +1,6 @@
1
- import { isMotionValue } from '../../value/utils/is-motion-value.mjs';
2
1
  import { VisualElement } from '../VisualElement.mjs';
3
2
  import { DOMKeyframesResolver } from '../../../../../motion-dom/dist/es/animation/keyframes/DOMKeyframesResolver.mjs';
3
+ import { isMotionValue } from '../../../../../motion-dom/dist/es/value/utils/is-motion-value.mjs';
4
4
 
5
5
  class DOMVisualElement extends VisualElement {
6
6
  constructor() {