motion 12.11.4 → 12.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/cjs/index.js +110 -16
  2. package/dist/cjs/react-client.js +141 -120
  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/animation/utils/create-visual-element.mjs +3 -2
  8. package/dist/es/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs +4 -1
  9. package/dist/es/framer-motion/dist/es/components/Reorder/Item.mjs +1 -1
  10. package/dist/es/framer-motion/dist/es/projection/node/create-projection-node.mjs +3 -2
  11. package/dist/es/framer-motion/dist/es/render/VisualElement.mjs +1 -1
  12. package/dist/es/framer-motion/dist/es/render/dom/DOMVisualElement.mjs +1 -1
  13. package/dist/es/framer-motion/dist/es/render/dom/resize/handle-element.mjs +2 -1
  14. package/dist/es/framer-motion/dist/es/render/dom/scroll/offsets/inset.mjs +3 -1
  15. package/dist/es/framer-motion/dist/es/render/dom/use-render.mjs +2 -2
  16. package/dist/es/framer-motion/dist/es/render/html/use-props.mjs +1 -1
  17. package/dist/es/framer-motion/dist/es/render/html/utils/scrape-motion-values.mjs +1 -1
  18. package/dist/es/framer-motion/dist/es/render/svg/utils/scrape-motion-values.mjs +1 -1
  19. package/dist/es/framer-motion/dist/es/render/utils/motion-values.mjs +1 -1
  20. package/dist/es/framer-motion/dist/es/value/use-motion-template.mjs +1 -1
  21. package/dist/es/framer-motion/dist/es/value/use-spring.mjs +13 -53
  22. package/dist/es/framer-motion/dist/es/value/use-will-change/is.mjs +1 -1
  23. package/dist/es/framer-motion/dist/es/value/utils/resolve-motion-value.mjs +1 -1
  24. package/dist/es/motion/lib/index.mjs +6 -0
  25. package/dist/es/motion/lib/react.mjs +6 -1
  26. package/dist/es/motion-dom/dist/es/animation/waapi/supports/waapi.mjs +3 -5
  27. package/dist/es/motion-dom/dist/es/gestures/press/index.mjs +2 -1
  28. package/dist/es/motion-dom/dist/es/utils/interpolate.mjs +1 -1
  29. package/dist/es/motion-dom/dist/es/utils/is-html-element.mjs +11 -0
  30. package/dist/es/motion-dom/dist/es/utils/is-svg-element.mjs +11 -0
  31. package/dist/es/motion-dom/dist/es/utils/is-svg-svg-element.mjs +11 -0
  32. package/dist/es/motion-dom/dist/es/value/spring-value.mjs +72 -0
  33. package/dist/es/motion-utils/dist/es/is-object.mjs +5 -0
  34. package/dist/motion.dev.js +110 -16
  35. package/dist/motion.js +1 -1
  36. package/package.json +3 -3
  37. package/dist/es/framer-motion/dist/es/render/dom/utils/is-svg-element.mjs +0 -5
  38. /package/dist/es/{framer-motion → motion-dom}/dist/es/value/utils/is-motion-value.mjs +0 -0
@@ -1,3 +1,4 @@
1
+ import { isHTMLElement } from '../../../utils/is-html-element.mjs';
1
2
  import { memo } from '../../../../../../motion-utils/dist/es/memo.mjs';
2
3
 
3
4
  /**
@@ -8,16 +9,13 @@ const acceleratedValues = new Set([
8
9
  "clipPath",
9
10
  "filter",
10
11
  "transform",
11
- // TODO: Can be accelerated but currently disabled until https://issues.chromium.org/issues/41491098 is resolved
12
- // or until we implement support for linear() easing.
12
+ // TODO: Could be re-enabled now we have support for linear() easing
13
13
  // "background-color"
14
14
  ]);
15
15
  const supportsWaapi = /*@__PURE__*/ memo(() => Object.hasOwnProperty.call(Element.prototype, "animate"));
16
16
  function supportsBrowserAnimation(options) {
17
17
  const { motionValue, name, repeatDelay, repeatType, damping, type } = options;
18
- if (!motionValue ||
19
- !motionValue.owner ||
20
- !(motionValue.owner.current instanceof HTMLElement)) {
18
+ if (!isHTMLElement(motionValue?.owner?.current)) {
21
19
  return false;
22
20
  }
23
21
  const { onUpdate, transformTemplate } = motionValue.owner.getProps();
@@ -1,3 +1,4 @@
1
+ import { isHTMLElement } from '../../utils/is-html-element.mjs';
1
2
  import { isDragActive } from '../drag/state/is-active.mjs';
2
3
  import { isNodeOrChild } from '../utils/is-node-or-child.mjs';
3
4
  import { isPrimaryPointer } from '../utils/is-primary-pointer.mjs';
@@ -68,7 +69,7 @@ function press(targetOrSelector, onPressStart, options = {}) {
68
69
  targets.forEach((target) => {
69
70
  const pointerDownTarget = options.useGlobalTarget ? window : target;
70
71
  pointerDownTarget.addEventListener("pointerdown", startPress, eventOptions);
71
- if (target instanceof HTMLElement) {
72
+ if (isHTMLElement(target)) {
72
73
  target.addEventListener("focus", (event) => enableKeyboardPress(event, eventOptions));
73
74
  if (!isElementKeyboardAccessible(target) &&
74
75
  !target.hasAttribute("tabindex")) {
@@ -34,7 +34,7 @@ function createMixers(output, ease, customMixer) {
34
34
  * mixColor(0.5) // 'rgba(128, 128, 128, 1)'
35
35
  * ```
36
36
  *
37
- * TODO Revist this approach once we've moved to data models for values,
37
+ * TODO Revisit this approach once we've moved to data models for values,
38
38
  * probably not needed to pregenerate mixer functions.
39
39
  *
40
40
  * @public
@@ -0,0 +1,11 @@
1
+ import { isObject } from '../../../../motion-utils/dist/es/is-object.mjs';
2
+
3
+ /**
4
+ * Checks if an element is an HTML element in a way
5
+ * that works across iframes
6
+ */
7
+ function isHTMLElement(element) {
8
+ return isObject(element) && "offsetHeight" in element;
9
+ }
10
+
11
+ export { isHTMLElement };
@@ -0,0 +1,11 @@
1
+ import { isObject } from '../../../../motion-utils/dist/es/is-object.mjs';
2
+
3
+ /**
4
+ * Checks if an element is an SVG element in a way
5
+ * that works across iframes
6
+ */
7
+ function isSVGElement(element) {
8
+ return isObject(element) && "ownerSVGElement" in element;
9
+ }
10
+
11
+ export { isSVGElement };
@@ -0,0 +1,11 @@
1
+ import { isSVGElement } from './is-svg-element.mjs';
2
+
3
+ /**
4
+ * Checks if an element is specifically an SVGSVGElement (the root SVG element)
5
+ * in a way that works across iframes
6
+ */
7
+ function isSVGSVGElement(element) {
8
+ return isSVGElement(element) && element.tagName === "svg";
9
+ }
10
+
11
+ export { isSVGSVGElement };
@@ -0,0 +1,72 @@
1
+ import { motionValue } from './index.mjs';
2
+ import { JSAnimation } from '../animation/JSAnimation.mjs';
3
+ import { isMotionValue } from './utils/is-motion-value.mjs';
4
+ import { frame } from '../frameloop/frame.mjs';
5
+
6
+ /**
7
+ * Create a `MotionValue` that animates to its latest value using a spring.
8
+ * Can either be a value or track another `MotionValue`.
9
+ *
10
+ * ```jsx
11
+ * const x = motionValue(0)
12
+ * const y = transformValue(() => x.get() * 2) // double x
13
+ * ```
14
+ *
15
+ * @param transformer - A transform function. This function must be pure with no side-effects or conditional statements.
16
+ * @returns `MotionValue`
17
+ *
18
+ * @public
19
+ */
20
+ function springValue(source, options) {
21
+ const initialValue = isMotionValue(source) ? source.get() : source;
22
+ const value = motionValue(initialValue);
23
+ attachSpring(value, source, options);
24
+ return value;
25
+ }
26
+ function attachSpring(value, source, options) {
27
+ const initialValue = value.get();
28
+ let activeAnimation = null;
29
+ let latestValue = initialValue;
30
+ let latestSetter;
31
+ const unit = typeof initialValue === "string"
32
+ ? initialValue.replace(/[\d.-]/g, "")
33
+ : undefined;
34
+ const stopAnimation = () => {
35
+ if (activeAnimation) {
36
+ activeAnimation.stop();
37
+ activeAnimation = null;
38
+ }
39
+ };
40
+ const startAnimation = () => {
41
+ stopAnimation();
42
+ activeAnimation = new JSAnimation({
43
+ keyframes: [asNumber(value.get()), asNumber(latestValue)],
44
+ velocity: value.getVelocity(),
45
+ type: "spring",
46
+ restDelta: 0.001,
47
+ restSpeed: 0.01,
48
+ ...options,
49
+ onUpdate: latestSetter,
50
+ });
51
+ };
52
+ value.attach((v, set) => {
53
+ latestValue = v;
54
+ latestSetter = (latest) => set(parseValue(latest, unit));
55
+ frame.postRender(startAnimation);
56
+ return value.get();
57
+ }, stopAnimation);
58
+ let unsubscribe = undefined;
59
+ if (isMotionValue(source)) {
60
+ unsubscribe = source.on("change", (v) => value.set(parseValue(v, unit)));
61
+ value.on("destroy", unsubscribe);
62
+ }
63
+ return unsubscribe;
64
+ }
65
+ function parseValue(v, unit) {
66
+ return unit ? v + unit : v;
67
+ }
68
+ function asNumber(v) {
69
+ return typeof v === "number" ? v : parseFloat(v);
70
+ }
71
+
72
+ export { attachSpring, springValue };
@@ -0,0 +1,5 @@
1
+ function isObject(value) {
2
+ return typeof value === "object" && value !== null;
3
+ }
4
+
5
+ export { isObject };
@@ -54,6 +54,10 @@
54
54
  */
55
55
  const isNumericalString = (v) => /^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(v);
56
56
 
57
+ function isObject(value) {
58
+ return typeof value === "object" && value !== null;
59
+ }
60
+
57
61
  /**
58
62
  * Check if the value is a zero value string like "0px" or "0%"
59
63
  */
@@ -1425,7 +1429,7 @@
1425
1429
  * mixColor(0.5) // 'rgba(128, 128, 128, 1)'
1426
1430
  * ```
1427
1431
  *
1428
- * TODO Revist this approach once we've moved to data models for values,
1432
+ * TODO Revisit this approach once we've moved to data models for values,
1429
1433
  * probably not needed to pregenerate mixer functions.
1430
1434
  *
1431
1435
  * @public
@@ -2597,6 +2601,14 @@
2597
2601
  ((type === "spring" || isGenerator(type)) && velocity));
2598
2602
  }
2599
2603
 
2604
+ /**
2605
+ * Checks if an element is an HTML element in a way
2606
+ * that works across iframes
2607
+ */
2608
+ function isHTMLElement(element) {
2609
+ return isObject(element) && "offsetHeight" in element;
2610
+ }
2611
+
2600
2612
  /**
2601
2613
  * A list of values that can be hardware-accelerated.
2602
2614
  */
@@ -2605,16 +2617,13 @@
2605
2617
  "clipPath",
2606
2618
  "filter",
2607
2619
  "transform",
2608
- // TODO: Can be accelerated but currently disabled until https://issues.chromium.org/issues/41491098 is resolved
2609
- // or until we implement support for linear() easing.
2620
+ // TODO: Could be re-enabled now we have support for linear() easing
2610
2621
  // "background-color"
2611
2622
  ]);
2612
2623
  const supportsWaapi = /*@__PURE__*/ memo(() => Object.hasOwnProperty.call(Element.prototype, "animate"));
2613
2624
  function supportsBrowserAnimation(options) {
2614
2625
  const { motionValue, name, repeatDelay, repeatType, damping, type } = options;
2615
- if (!motionValue ||
2616
- !motionValue.owner ||
2617
- !(motionValue.owner.current instanceof HTMLElement)) {
2626
+ if (!isHTMLElement(motionValue?.owner?.current)) {
2618
2627
  return false;
2619
2628
  }
2620
2629
  const { onUpdate, transformTemplate } = motionValue.owner.getProps();
@@ -4030,7 +4039,7 @@
4030
4039
  targets.forEach((target) => {
4031
4040
  const pointerDownTarget = options.useGlobalTarget ? window : target;
4032
4041
  pointerDownTarget.addEventListener("pointerdown", startPress, eventOptions);
4033
- if (target instanceof HTMLElement) {
4042
+ if (isHTMLElement(target)) {
4034
4043
  target.addEventListener("focus", (event) => enableKeyboardPress(event, eventOptions));
4035
4044
  if (!isElementKeyboardAccessible(target) &&
4036
4045
  !target.hasAttribute("tabindex")) {
@@ -4175,6 +4184,22 @@
4175
4184
  return reportStats;
4176
4185
  }
4177
4186
 
4187
+ /**
4188
+ * Checks if an element is an SVG element in a way
4189
+ * that works across iframes
4190
+ */
4191
+ function isSVGElement(element) {
4192
+ return isObject(element) && "ownerSVGElement" in element;
4193
+ }
4194
+
4195
+ /**
4196
+ * Checks if an element is specifically an SVGSVGElement (the root SVG element)
4197
+ * in a way that works across iframes
4198
+ */
4199
+ function isSVGSVGElement(element) {
4200
+ return isSVGElement(element) && element.tagName === "svg";
4201
+ }
4202
+
4178
4203
  function transform(...args) {
4179
4204
  const useImmediate = !Array.isArray(args[0]);
4180
4205
  const argOffset = useImmediate ? 0 : -1;
@@ -4269,6 +4294,74 @@
4269
4294
  return transformValue(() => map(inputValue.get()));
4270
4295
  }
4271
4296
 
4297
+ const isMotionValue = (value) => Boolean(value && value.getVelocity);
4298
+
4299
+ /**
4300
+ * Create a `MotionValue` that animates to its latest value using a spring.
4301
+ * Can either be a value or track another `MotionValue`.
4302
+ *
4303
+ * ```jsx
4304
+ * const x = motionValue(0)
4305
+ * const y = transformValue(() => x.get() * 2) // double x
4306
+ * ```
4307
+ *
4308
+ * @param transformer - A transform function. This function must be pure with no side-effects or conditional statements.
4309
+ * @returns `MotionValue`
4310
+ *
4311
+ * @public
4312
+ */
4313
+ function springValue(source, options) {
4314
+ const initialValue = isMotionValue(source) ? source.get() : source;
4315
+ const value = motionValue(initialValue);
4316
+ attachSpring(value, source, options);
4317
+ return value;
4318
+ }
4319
+ function attachSpring(value, source, options) {
4320
+ const initialValue = value.get();
4321
+ let activeAnimation = null;
4322
+ let latestValue = initialValue;
4323
+ let latestSetter;
4324
+ const unit = typeof initialValue === "string"
4325
+ ? initialValue.replace(/[\d.-]/g, "")
4326
+ : undefined;
4327
+ const stopAnimation = () => {
4328
+ if (activeAnimation) {
4329
+ activeAnimation.stop();
4330
+ activeAnimation = null;
4331
+ }
4332
+ };
4333
+ const startAnimation = () => {
4334
+ stopAnimation();
4335
+ activeAnimation = new JSAnimation({
4336
+ keyframes: [asNumber(value.get()), asNumber(latestValue)],
4337
+ velocity: value.getVelocity(),
4338
+ type: "spring",
4339
+ restDelta: 0.001,
4340
+ restSpeed: 0.01,
4341
+ ...options,
4342
+ onUpdate: latestSetter,
4343
+ });
4344
+ };
4345
+ value.attach((v, set) => {
4346
+ latestValue = v;
4347
+ latestSetter = (latest) => set(parseValue(latest, unit));
4348
+ frame.postRender(startAnimation);
4349
+ return value.get();
4350
+ }, stopAnimation);
4351
+ let unsubscribe = undefined;
4352
+ if (isMotionValue(source)) {
4353
+ unsubscribe = source.on("change", (v) => value.set(parseValue(v, unit)));
4354
+ value.on("destroy", unsubscribe);
4355
+ }
4356
+ return unsubscribe;
4357
+ }
4358
+ function parseValue(v, unit) {
4359
+ return unit ? v + unit : v;
4360
+ }
4361
+ function asNumber(v) {
4362
+ return typeof v === "number" ? v : parseFloat(v);
4363
+ }
4364
+
4272
4365
  /**
4273
4366
  * A list of all ValueTypes
4274
4367
  */
@@ -4605,8 +4698,6 @@
4605
4698
  return acc;
4606
4699
  }, {});
4607
4700
 
4608
- const isMotionValue = (value) => Boolean(value && value.getVelocity);
4609
-
4610
4701
  function isDOMKeyframes(keyframes) {
4611
4702
  return typeof keyframes === "object" && !Array.isArray(keyframes);
4612
4703
  }
@@ -5267,10 +5358,6 @@
5267
5358
  return animations;
5268
5359
  }
5269
5360
 
5270
- function isSVGElement(element) {
5271
- return element instanceof SVGElement && element.tagName !== "svg";
5272
- }
5273
-
5274
5361
  /**
5275
5362
  * Bounding boxes tend to be defined as top, left, right, bottom. For various operations
5276
5363
  * it's easier to consider each axis individually. This function returns a bounding box
@@ -6330,7 +6417,7 @@
6330
6417
  latestValues: {},
6331
6418
  },
6332
6419
  };
6333
- const node = isSVGElement(element)
6420
+ const node = isSVGElement(element) && !isSVGSVGElement(element)
6334
6421
  ? new SVGVisualElement(options)
6335
6422
  : new HTMLVisualElement(options);
6336
6423
  node.mount(element);
@@ -6554,7 +6641,7 @@
6554
6641
  const { inlineSize, blockSize } = borderBoxSize[0];
6555
6642
  return { width: inlineSize, height: blockSize };
6556
6643
  }
6557
- else if (target instanceof SVGElement && "getBBox" in target) {
6644
+ else if (isSVGElement(target) && "getBBox" in target) {
6558
6645
  return target.getBBox();
6559
6646
  }
6560
6647
  else {
@@ -6696,7 +6783,7 @@
6696
6783
  const inset = { x: 0, y: 0 };
6697
6784
  let current = element;
6698
6785
  while (current && current !== container) {
6699
- if (current instanceof HTMLElement) {
6786
+ if (isHTMLElement(current)) {
6700
6787
  inset.x += current.offsetLeft;
6701
6788
  inset.y += current.offsetTop;
6702
6789
  current = current.offsetParent;
@@ -7187,6 +7274,7 @@
7187
7274
  exports.animationMapKey = animationMapKey;
7188
7275
  exports.anticipate = anticipate;
7189
7276
  exports.applyPxDefaults = applyPxDefaults;
7277
+ exports.attachSpring = attachSpring;
7190
7278
  exports.backIn = backIn;
7191
7279
  exports.backInOut = backInOut;
7192
7280
  exports.backOut = backOut;
@@ -7254,9 +7342,14 @@
7254
7342
  exports.isDragging = isDragging;
7255
7343
  exports.isEasingArray = isEasingArray;
7256
7344
  exports.isGenerator = isGenerator;
7345
+ exports.isHTMLElement = isHTMLElement;
7346
+ exports.isMotionValue = isMotionValue;
7257
7347
  exports.isNodeOrChild = isNodeOrChild;
7258
7348
  exports.isNumericalString = isNumericalString;
7349
+ exports.isObject = isObject;
7259
7350
  exports.isPrimaryPointer = isPrimaryPointer;
7351
+ exports.isSVGElement = isSVGElement;
7352
+ exports.isSVGSVGElement = isSVGSVGElement;
7260
7353
  exports.isWaapiSupportedEasing = isWaapiSupportedEasing;
7261
7354
  exports.isZeroValueString = isZeroValueString;
7262
7355
  exports.keyframes = keyframes;
@@ -7305,6 +7398,7 @@
7305
7398
  exports.setDragLock = setDragLock;
7306
7399
  exports.setStyle = setStyle;
7307
7400
  exports.spring = spring;
7401
+ exports.springValue = springValue;
7308
7402
  exports.stagger = stagger;
7309
7403
  exports.startWaapiAnimation = startWaapiAnimation;
7310
7404
  exports.statsBuffer = statsBuffer;