motion 11.17.0 → 11.17.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.
@@ -142,7 +142,9 @@ function isRefObject(ref) {
142
142
  */
143
143
  function useMotionRef(visualState, visualElement, externalRef) {
144
144
  return react.useCallback((instance) => {
145
- instance && visualState.mount && visualState.mount(instance);
145
+ if (instance) {
146
+ visualState.onMount && visualState.onMount(instance);
147
+ }
146
148
  if (visualElement) {
147
149
  if (instance) {
148
150
  visualElement.mount(instance);
@@ -604,117 +606,7 @@ function isSVGComponent(Component) {
604
606
  return false;
605
607
  }
606
608
 
607
- function renderHTML(element, { style, vars }, styleProp, projection) {
608
- Object.assign(element.style, style, projection && projection.getProjectionStyles(styleProp));
609
- // Loop over any CSS variables and assign those.
610
- for (const key in vars) {
611
- element.style.setProperty(key, vars[key]);
612
- }
613
- }
614
-
615
- /**
616
- * A set of attribute names that are always read/written as camel case.
617
- */
618
- const camelCaseAttributes = new Set([
619
- "baseFrequency",
620
- "diffuseConstant",
621
- "kernelMatrix",
622
- "kernelUnitLength",
623
- "keySplines",
624
- "keyTimes",
625
- "limitingConeAngle",
626
- "markerHeight",
627
- "markerWidth",
628
- "numOctaves",
629
- "targetX",
630
- "targetY",
631
- "surfaceScale",
632
- "specularConstant",
633
- "specularExponent",
634
- "stdDeviation",
635
- "tableValues",
636
- "viewBox",
637
- "gradientTransform",
638
- "pathLength",
639
- "startOffset",
640
- "textLength",
641
- "lengthAdjust",
642
- ]);
643
-
644
- function renderSVG(element, renderState, _styleProp, projection) {
645
- renderHTML(element, renderState, undefined, projection);
646
- for (const key in renderState.attrs) {
647
- element.setAttribute(!camelCaseAttributes.has(key) ? camelToDash(key) : key, renderState.attrs[key]);
648
- }
649
- }
650
-
651
- const isMotionValue = (value) => Boolean(value && value.getVelocity);
652
-
653
- /**
654
- * Generate a list of every possible transform key.
655
- */
656
- const transformPropOrder = [
657
- "transformPerspective",
658
- "x",
659
- "y",
660
- "z",
661
- "translateX",
662
- "translateY",
663
- "translateZ",
664
- "scale",
665
- "scaleX",
666
- "scaleY",
667
- "rotate",
668
- "rotateX",
669
- "rotateY",
670
- "rotateZ",
671
- "skew",
672
- "skewX",
673
- "skewY",
674
- ];
675
- /**
676
- * A quick lookup for transform props.
677
- */
678
- const transformProps = new Set(transformPropOrder);
679
-
680
- const scaleCorrectors = {};
681
-
682
- function isForcedMotionValue(key, { layout, layoutId }) {
683
- return (transformProps.has(key) ||
684
- key.startsWith("origin") ||
685
- ((layout || layoutId !== undefined) &&
686
- (!!scaleCorrectors[key] || key === "opacity")));
687
- }
688
-
689
- function scrapeMotionValuesFromProps$1(props, prevProps, visualElement) {
690
- var _a;
691
- const { style } = props;
692
- const newValues = {};
693
- for (const key in style) {
694
- if (isMotionValue(style[key]) ||
695
- (prevProps.style &&
696
- isMotionValue(prevProps.style[key])) ||
697
- isForcedMotionValue(key, props) ||
698
- ((_a = visualElement === null || visualElement === void 0 ? void 0 : visualElement.getValue(key)) === null || _a === void 0 ? void 0 : _a.liveStyle) !== undefined) {
699
- newValues[key] = style[key];
700
- }
701
- }
702
- return newValues;
703
- }
704
-
705
- function scrapeMotionValuesFromProps(props, prevProps, visualElement) {
706
- const newValues = scrapeMotionValuesFromProps$1(props, prevProps, visualElement);
707
- for (const key in props) {
708
- if (isMotionValue(props[key]) ||
709
- isMotionValue(prevProps[key])) {
710
- const targetKey = transformPropOrder.indexOf(key) !== -1
711
- ? "attr" + key.charAt(0).toUpperCase() + key.substring(1)
712
- : key;
713
- newValues[targetKey] = props[key];
714
- }
715
- }
716
- return newValues;
717
- }
609
+ const { schedule: frame, cancel: cancelFrame, state: frameData, steps: frameSteps, } = createRenderBatcher(typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : noop, true);
718
610
 
719
611
  function getValueState(visualElement) {
720
612
  const state = [{}, {}];
@@ -770,6 +662,8 @@ const isCustomValue = (v) => {
770
662
  return Boolean(v && typeof v === "object" && v.mix && v.toValue);
771
663
  };
772
664
 
665
+ const isMotionValue = (value) => Boolean(value && value.getVelocity);
666
+
773
667
  /**
774
668
  * If the provided value is a MotionValue, this returns the actual value, otherwise just the value itself
775
669
  *
@@ -782,13 +676,19 @@ function resolveMotionValue(value) {
782
676
  : unwrappedValue;
783
677
  }
784
678
 
785
- function makeState({ scrapeMotionValuesFromProps, createRenderState, onMount, }, props, context, presenceContext) {
679
+ function makeState({ scrapeMotionValuesFromProps, createRenderState, onUpdate, }, props, context, presenceContext) {
786
680
  const state = {
787
681
  latestValues: makeLatestValues(props, context, presenceContext, scrapeMotionValuesFromProps),
788
682
  renderState: createRenderState(),
789
683
  };
790
- if (onMount) {
791
- state.mount = (instance) => onMount(props, instance, state);
684
+ if (onUpdate) {
685
+ /**
686
+ * onMount works without the VisualElement because it could be
687
+ * called before the VisualElement payload has been hydrated.
688
+ * (e.g. if someone is using m components <m.circle />)
689
+ */
690
+ state.onMount = (instance) => onUpdate({ props, current: instance, ...state });
691
+ state.onUpdate = (visualElement) => onUpdate(visualElement);
792
692
  }
793
693
  return state;
794
694
  }
@@ -854,17 +754,32 @@ function makeLatestValues(props, context, presenceContext, scrapeMotionValues) {
854
754
  return values;
855
755
  }
856
756
 
857
- const createHtmlRenderState = () => ({
858
- style: {},
859
- transform: {},
860
- transformOrigin: {},
861
- vars: {},
862
- });
863
-
864
- const createSvgRenderState = () => ({
865
- ...createHtmlRenderState(),
866
- attrs: {},
867
- });
757
+ /**
758
+ * Generate a list of every possible transform key.
759
+ */
760
+ const transformPropOrder = [
761
+ "transformPerspective",
762
+ "x",
763
+ "y",
764
+ "z",
765
+ "translateX",
766
+ "translateY",
767
+ "translateZ",
768
+ "scale",
769
+ "scaleX",
770
+ "scaleY",
771
+ "rotate",
772
+ "rotateX",
773
+ "rotateY",
774
+ "rotateZ",
775
+ "skew",
776
+ "skewX",
777
+ "skewY",
778
+ ];
779
+ /**
780
+ * A quick lookup for transform props.
781
+ */
782
+ const transformProps = new Set(transformPropOrder);
868
783
 
869
784
  const checkStringStartsWith = (token) => (key) => typeof key === "string" && key.startsWith(token);
870
785
  const isCSSVariableName =
@@ -1202,36 +1117,159 @@ function buildSVGAttrs(state, { attrX, attrY, attrScale, originX, originY, pathL
1202
1117
  }
1203
1118
  }
1204
1119
 
1120
+ const createHtmlRenderState = () => ({
1121
+ style: {},
1122
+ transform: {},
1123
+ transformOrigin: {},
1124
+ vars: {},
1125
+ });
1126
+
1127
+ const createSvgRenderState = () => ({
1128
+ ...createHtmlRenderState(),
1129
+ attrs: {},
1130
+ });
1131
+
1205
1132
  const isSVGTag = (tag) => typeof tag === "string" && tag.toLowerCase() === "svg";
1206
1133
 
1207
- const { schedule: frame, cancel: cancelFrame, state: frameData, steps: frameSteps, } = createRenderBatcher(typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : noop, true);
1134
+ function renderHTML(element, { style, vars }, styleProp, projection) {
1135
+ Object.assign(element.style, style, projection && projection.getProjectionStyles(styleProp));
1136
+ // Loop over any CSS variables and assign those.
1137
+ for (const key in vars) {
1138
+ element.style.setProperty(key, vars[key]);
1139
+ }
1140
+ }
1141
+
1142
+ /**
1143
+ * A set of attribute names that are always read/written as camel case.
1144
+ */
1145
+ const camelCaseAttributes = new Set([
1146
+ "baseFrequency",
1147
+ "diffuseConstant",
1148
+ "kernelMatrix",
1149
+ "kernelUnitLength",
1150
+ "keySplines",
1151
+ "keyTimes",
1152
+ "limitingConeAngle",
1153
+ "markerHeight",
1154
+ "markerWidth",
1155
+ "numOctaves",
1156
+ "targetX",
1157
+ "targetY",
1158
+ "surfaceScale",
1159
+ "specularConstant",
1160
+ "specularExponent",
1161
+ "stdDeviation",
1162
+ "tableValues",
1163
+ "viewBox",
1164
+ "gradientTransform",
1165
+ "pathLength",
1166
+ "startOffset",
1167
+ "textLength",
1168
+ "lengthAdjust",
1169
+ ]);
1208
1170
 
1171
+ function renderSVG(element, renderState, _styleProp, projection) {
1172
+ renderHTML(element, renderState, undefined, projection);
1173
+ for (const key in renderState.attrs) {
1174
+ element.setAttribute(!camelCaseAttributes.has(key) ? camelToDash(key) : key, renderState.attrs[key]);
1175
+ }
1176
+ }
1177
+
1178
+ const scaleCorrectors = {};
1179
+
1180
+ function isForcedMotionValue(key, { layout, layoutId }) {
1181
+ return (transformProps.has(key) ||
1182
+ key.startsWith("origin") ||
1183
+ ((layout || layoutId !== undefined) &&
1184
+ (!!scaleCorrectors[key] || key === "opacity")));
1185
+ }
1186
+
1187
+ function scrapeMotionValuesFromProps$1(props, prevProps, visualElement) {
1188
+ var _a;
1189
+ const { style } = props;
1190
+ const newValues = {};
1191
+ for (const key in style) {
1192
+ if (isMotionValue(style[key]) ||
1193
+ (prevProps.style &&
1194
+ isMotionValue(prevProps.style[key])) ||
1195
+ isForcedMotionValue(key, props) ||
1196
+ ((_a = visualElement === null || visualElement === void 0 ? void 0 : visualElement.getValue(key)) === null || _a === void 0 ? void 0 : _a.liveStyle) !== undefined) {
1197
+ newValues[key] = style[key];
1198
+ }
1199
+ }
1200
+ return newValues;
1201
+ }
1202
+
1203
+ function scrapeMotionValuesFromProps(props, prevProps, visualElement) {
1204
+ const newValues = scrapeMotionValuesFromProps$1(props, prevProps, visualElement);
1205
+ for (const key in props) {
1206
+ if (isMotionValue(props[key]) ||
1207
+ isMotionValue(prevProps[key])) {
1208
+ const targetKey = transformPropOrder.indexOf(key) !== -1
1209
+ ? "attr" + key.charAt(0).toUpperCase() + key.substring(1)
1210
+ : key;
1211
+ newValues[targetKey] = props[key];
1212
+ }
1213
+ }
1214
+ return newValues;
1215
+ }
1216
+
1217
+ function updateSVGDimensions(instance, renderState) {
1218
+ try {
1219
+ renderState.dimensions =
1220
+ typeof instance.getBBox === "function"
1221
+ ? instance.getBBox()
1222
+ : instance.getBoundingClientRect();
1223
+ }
1224
+ catch (e) {
1225
+ // Most likely trying to measure an unrendered element under Firefox
1226
+ renderState.dimensions = {
1227
+ x: 0,
1228
+ y: 0,
1229
+ width: 0,
1230
+ height: 0,
1231
+ };
1232
+ }
1233
+ }
1234
+ const layoutProps = ["x", "y", "width", "height", "cx", "cy", "r"];
1209
1235
  const svgMotionConfig = {
1210
1236
  useVisualState: makeUseVisualState({
1211
1237
  scrapeMotionValuesFromProps: scrapeMotionValuesFromProps,
1212
1238
  createRenderState: createSvgRenderState,
1213
- onMount: (props, instance, { renderState, latestValues }) => {
1214
- frame.read(() => {
1215
- try {
1216
- renderState.dimensions =
1217
- typeof instance.getBBox ===
1218
- "function"
1219
- ? instance.getBBox()
1220
- : instance.getBoundingClientRect();
1239
+ onUpdate: ({ props, prevProps, current, renderState, latestValues, }) => {
1240
+ if (!current)
1241
+ return;
1242
+ let hasTransform = !!props.drag;
1243
+ if (!hasTransform) {
1244
+ for (const key in latestValues) {
1245
+ if (transformProps.has(key)) {
1246
+ hasTransform = true;
1247
+ break;
1248
+ }
1221
1249
  }
1222
- catch (e) {
1223
- // Most likely trying to measure an unrendered element under Firefox
1224
- renderState.dimensions = {
1225
- x: 0,
1226
- y: 0,
1227
- width: 0,
1228
- height: 0,
1229
- };
1250
+ }
1251
+ if (!hasTransform)
1252
+ return;
1253
+ let needsMeasure = !prevProps;
1254
+ if (prevProps) {
1255
+ /**
1256
+ * Check the layout props for changes, if any are found we need to
1257
+ * measure the element again.
1258
+ */
1259
+ for (let i = 0; i < layoutProps.length; i++) {
1260
+ const key = layoutProps[i];
1261
+ if (props[key] !==
1262
+ prevProps[key]) {
1263
+ needsMeasure = true;
1264
+ }
1230
1265
  }
1231
- });
1266
+ }
1267
+ if (!needsMeasure)
1268
+ return;
1269
+ frame.read(() => updateSVGDimensions(current, renderState));
1232
1270
  frame.render(() => {
1233
- buildSVGAttrs(renderState, latestValues, isSVGTag(instance.tagName), props.transformTemplate);
1234
- renderSVG(instance, renderState);
1271
+ buildSVGAttrs(renderState, latestValues, isSVGTag(current.tagName), props.transformTemplate);
1272
+ renderSVG(current, renderState);
1235
1273
  });
1236
1274
  },
1237
1275
  }),
@@ -7,7 +7,9 @@ import { isRefObject } from '../../utils/is-ref-object.mjs';
7
7
  */
8
8
  function useMotionRef(visualState, visualElement, externalRef) {
9
9
  return useCallback((instance) => {
10
- instance && visualState.mount && visualState.mount(instance);
10
+ if (instance) {
11
+ visualState.onMount && visualState.onMount(instance);
12
+ }
11
13
  if (visualElement) {
12
14
  if (instance) {
13
15
  visualElement.mount(instance);
@@ -1,19 +1,25 @@
1
1
  import { useContext } from 'react';
2
2
  import { isAnimationControls } from '../../animation/utils/is-animation-controls.mjs';
3
+ import { MotionContext } from '../../context/MotionContext/index.mjs';
3
4
  import { PresenceContext } from '../../context/PresenceContext.mjs';
5
+ import { isControllingVariants, isVariantNode } from '../../render/utils/is-controlling-variants.mjs';
4
6
  import { resolveVariantFromProps } from '../../render/utils/resolve-variants.mjs';
5
7
  import { useConstant } from '../../utils/use-constant.mjs';
6
8
  import { resolveMotionValue } from '../../value/utils/resolve-motion-value.mjs';
7
- import { MotionContext } from '../../context/MotionContext/index.mjs';
8
- import { isControllingVariants, isVariantNode } from '../../render/utils/is-controlling-variants.mjs';
9
9
 
10
- function makeState({ scrapeMotionValuesFromProps, createRenderState, onMount, }, props, context, presenceContext) {
10
+ function makeState({ scrapeMotionValuesFromProps, createRenderState, onUpdate, }, props, context, presenceContext) {
11
11
  const state = {
12
12
  latestValues: makeLatestValues(props, context, presenceContext, scrapeMotionValuesFromProps),
13
13
  renderState: createRenderState(),
14
14
  };
15
- if (onMount) {
16
- state.mount = (instance) => onMount(props, instance, state);
15
+ if (onUpdate) {
16
+ /**
17
+ * onMount works without the VisualElement because it could be
18
+ * called before the VisualElement payload has been hydrated.
19
+ * (e.g. if someone is using m components <m.circle />)
20
+ */
21
+ state.onMount = (instance) => onUpdate({ props, current: instance, ...state });
22
+ state.onUpdate = (visualElement) => onUpdate(visualElement);
17
23
  }
18
24
  return state;
19
25
  }
@@ -114,7 +114,8 @@ class VisualElement {
114
114
  frame.render(this.render, false, true);
115
115
  }
116
116
  };
117
- const { latestValues, renderState } = visualState;
117
+ const { latestValues, renderState, onUpdate } = visualState;
118
+ this.onUpdate = onUpdate;
118
119
  this.latestValues = latestValues;
119
120
  this.baseTarget = { ...latestValues };
120
121
  this.initialValues = props.initial ? { ...latestValues } : {};
@@ -314,6 +315,7 @@ class VisualElement {
314
315
  if (this.handleChildMotionValue) {
315
316
  this.handleChildMotionValue();
316
317
  }
318
+ this.onUpdate && this.onUpdate(this);
317
319
  }
318
320
  getProps() {
319
321
  return this.props;
@@ -1,37 +1,68 @@
1
- import { renderSVG } from './utils/render.mjs';
2
- import { scrapeMotionValuesFromProps } from './utils/scrape-motion-values.mjs';
1
+ import { frame } from '../../frameloop/frame.mjs';
3
2
  import { makeUseVisualState } from '../../motion/utils/use-visual-state.mjs';
4
- import { createSvgRenderState } from './utils/create-render-state.mjs';
3
+ import { transformProps } from '../html/utils/keys-transform.mjs';
5
4
  import { buildSVGAttrs } from './utils/build-attrs.mjs';
5
+ import { createSvgRenderState } from './utils/create-render-state.mjs';
6
6
  import { isSVGTag } from './utils/is-svg-tag.mjs';
7
- import { frame } from '../../frameloop/frame.mjs';
7
+ import { renderSVG } from './utils/render.mjs';
8
+ import { scrapeMotionValuesFromProps } from './utils/scrape-motion-values.mjs';
8
9
 
10
+ function updateSVGDimensions(instance, renderState) {
11
+ try {
12
+ renderState.dimensions =
13
+ typeof instance.getBBox === "function"
14
+ ? instance.getBBox()
15
+ : instance.getBoundingClientRect();
16
+ }
17
+ catch (e) {
18
+ // Most likely trying to measure an unrendered element under Firefox
19
+ renderState.dimensions = {
20
+ x: 0,
21
+ y: 0,
22
+ width: 0,
23
+ height: 0,
24
+ };
25
+ }
26
+ }
27
+ const layoutProps = ["x", "y", "width", "height", "cx", "cy", "r"];
9
28
  const svgMotionConfig = {
10
29
  useVisualState: makeUseVisualState({
11
30
  scrapeMotionValuesFromProps: scrapeMotionValuesFromProps,
12
31
  createRenderState: createSvgRenderState,
13
- onMount: (props, instance, { renderState, latestValues }) => {
14
- frame.read(() => {
15
- try {
16
- renderState.dimensions =
17
- typeof instance.getBBox ===
18
- "function"
19
- ? instance.getBBox()
20
- : instance.getBoundingClientRect();
32
+ onUpdate: ({ props, prevProps, current, renderState, latestValues, }) => {
33
+ if (!current)
34
+ return;
35
+ let hasTransform = !!props.drag;
36
+ if (!hasTransform) {
37
+ for (const key in latestValues) {
38
+ if (transformProps.has(key)) {
39
+ hasTransform = true;
40
+ break;
41
+ }
21
42
  }
22
- catch (e) {
23
- // Most likely trying to measure an unrendered element under Firefox
24
- renderState.dimensions = {
25
- x: 0,
26
- y: 0,
27
- width: 0,
28
- height: 0,
29
- };
43
+ }
44
+ if (!hasTransform)
45
+ return;
46
+ let needsMeasure = !prevProps;
47
+ if (prevProps) {
48
+ /**
49
+ * Check the layout props for changes, if any are found we need to
50
+ * measure the element again.
51
+ */
52
+ for (let i = 0; i < layoutProps.length; i++) {
53
+ const key = layoutProps[i];
54
+ if (props[key] !==
55
+ prevProps[key]) {
56
+ needsMeasure = true;
57
+ }
30
58
  }
31
- });
59
+ }
60
+ if (!needsMeasure)
61
+ return;
62
+ frame.read(() => updateSVGDimensions(current, renderState));
32
63
  frame.render(() => {
33
- buildSVGAttrs(renderState, latestValues, isSVGTag(instance.tagName), props.transformTemplate);
34
- renderSVG(instance, renderState);
64
+ buildSVGAttrs(renderState, latestValues, isSVGTag(current.tagName), props.transformTemplate);
65
+ renderSVG(current, renderState);
35
66
  });
36
67
  },
37
68
  }),
@@ -17,7 +17,7 @@ function updateMotionValuesFromProps(element, next, prev) {
17
17
  * and warn against mismatches.
18
18
  */
19
19
  if (process.env.NODE_ENV === "development") {
20
- warnOnce(nextValue.version === "11.17.0", `Attempting to mix Motion versions ${nextValue.version} with 11.17.0 may not work as expected.`);
20
+ warnOnce(nextValue.version === "11.17.1", `Attempting to mix Motion versions ${nextValue.version} with 11.17.1 may not work as expected.`);
21
21
  }
22
22
  }
23
23
  else if (isMotionValue(prevValue)) {
@@ -34,7 +34,7 @@ class MotionValue {
34
34
  * This will be replaced by the build step with the latest version number.
35
35
  * When MotionValues are provided to motion components, warn if versions are mixed.
36
36
  */
37
- this.version = "11.17.0";
37
+ this.version = "11.17.1";
38
38
  /**
39
39
  * Tracks whether this value can output a velocity. Currently this is only true
40
40
  * if the value is numerical, but we might be able to widen the scope here and support
@@ -1369,7 +1369,7 @@
1369
1369
  * This will be replaced by the build step with the latest version number.
1370
1370
  * When MotionValues are provided to motion components, warn if versions are mixed.
1371
1371
  */
1372
- this.version = "11.17.0";
1372
+ this.version = "11.17.1";
1373
1373
  /**
1374
1374
  * Tracks whether this value can output a velocity. Currently this is only true
1375
1375
  * if the value is numerical, but we might be able to widen the scope here and support
@@ -4299,7 +4299,7 @@
4299
4299
  * and warn against mismatches.
4300
4300
  */
4301
4301
  {
4302
- warnOnce(nextValue.version === "11.17.0", `Attempting to mix Motion versions ${nextValue.version} with 11.17.0 may not work as expected.`);
4302
+ warnOnce(nextValue.version === "11.17.1", `Attempting to mix Motion versions ${nextValue.version} with 11.17.1 may not work as expected.`);
4303
4303
  }
4304
4304
  }
4305
4305
  else if (isMotionValue(prevValue)) {
@@ -4432,7 +4432,8 @@
4432
4432
  frame.render(this.render, false, true);
4433
4433
  }
4434
4434
  };
4435
- const { latestValues, renderState } = visualState;
4435
+ const { latestValues, renderState, onUpdate } = visualState;
4436
+ this.onUpdate = onUpdate;
4436
4437
  this.latestValues = latestValues;
4437
4438
  this.baseTarget = { ...latestValues };
4438
4439
  this.initialValues = props.initial ? { ...latestValues } : {};
@@ -4632,6 +4633,7 @@
4632
4633
  if (this.handleChildMotionValue) {
4633
4634
  this.handleChildMotionValue();
4634
4635
  }
4636
+ this.onUpdate && this.onUpdate(this);
4635
4637
  }
4636
4638
  getProps() {
4637
4639
  return this.props;