framer-motion 12.35.2 → 12.36.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 (38) hide show
  1. package/dist/cjs/client.js +1 -1
  2. package/dist/cjs/{feature-bundle-DqHxNjy5.js → feature-bundle-BakEQtGR.js} +40 -3
  3. package/dist/cjs/feature-bundle-BakEQtGR.js.map +1 -0
  4. package/dist/cjs/index.js +3 -2
  5. package/dist/cjs/index.js.map +1 -1
  6. package/dist/cjs/m.js +7 -1
  7. package/dist/cjs/m.js.map +1 -1
  8. package/dist/dom.js +1 -1
  9. package/dist/es/components/AnimatePresence/PopChild.mjs +1 -0
  10. package/dist/es/components/AnimatePresence/PopChild.mjs.map +1 -1
  11. package/dist/es/components/AnimatePresence/index.mjs +1 -1
  12. package/dist/es/components/AnimatePresence/index.mjs.map +1 -1
  13. package/dist/es/gestures/drag/VisualElementDragControls.mjs +2 -1
  14. package/dist/es/gestures/drag/VisualElementDragControls.mjs.map +1 -1
  15. package/dist/es/gestures/pan/PanSession.mjs.map +1 -1
  16. package/dist/es/motion/features/animation/exit.mjs +31 -1
  17. package/dist/es/motion/features/animation/exit.mjs.map +1 -1
  18. package/dist/es/render/dom/utils/filter-props.mjs +8 -1
  19. package/dist/es/render/dom/utils/filter-props.mjs.map +1 -1
  20. package/dist/es/value/use-spring.mjs.map +1 -1
  21. package/dist/framer-motion.dev.js +93 -14
  22. package/dist/framer-motion.js +1 -1
  23. package/dist/size-rollup-animate.js +1 -1
  24. package/dist/size-rollup-animate.js.map +1 -1
  25. package/dist/size-rollup-dom-animation-assets.js +1 -1
  26. package/dist/size-rollup-dom-animation-m.js +1 -1
  27. package/dist/size-rollup-dom-animation.js +1 -1
  28. package/dist/size-rollup-dom-max-assets.js +1 -1
  29. package/dist/size-rollup-dom-max.js +1 -1
  30. package/dist/size-rollup-m.js +1 -1
  31. package/dist/size-rollup-m.js.map +1 -1
  32. package/dist/size-rollup-motion.js +1 -1
  33. package/dist/size-rollup-motion.js.map +1 -1
  34. package/dist/size-rollup-scroll.js +1 -1
  35. package/dist/size-rollup-scroll.js.map +1 -1
  36. package/dist/types/index.d.ts +5 -4
  37. package/package.json +4 -4
  38. package/dist/cjs/feature-bundle-DqHxNjy5.js.map +0 -1
@@ -324,7 +324,11 @@
324
324
  const backIn = /*@__PURE__*/ reverseEasing(backOut);
325
325
  const backInOut = /*@__PURE__*/ mirrorEasing(backIn);
326
326
 
327
- const anticipate = (p) => (p *= 2) < 1 ? 0.5 * backIn(p) : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
327
+ const anticipate = (p) => p >= 1
328
+ ? 1
329
+ : (p *= 2) < 1
330
+ ? 0.5 * backIn(p)
331
+ : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
328
332
 
329
333
  const circIn = (p) => 1 - Math.sin(Math.acos(p));
330
334
  const circOut = reverseEasing(circIn);
@@ -443,8 +447,7 @@
443
447
  const queue = addToCurrentFrame ? thisFrame : nextFrame;
444
448
  if (keepAlive)
445
449
  toKeepAlive.add(callback);
446
- if (!queue.has(callback))
447
- queue.add(callback);
450
+ queue.add(callback);
448
451
  return callback;
449
452
  },
450
453
  /**
@@ -469,7 +472,10 @@
469
472
  return;
470
473
  }
471
474
  isProcessing = true;
472
- [thisFrame, nextFrame] = [nextFrame, thisFrame];
475
+ // Swap this frame and the next to avoid GC
476
+ const prevFrame = thisFrame;
477
+ thisFrame = nextFrame;
478
+ nextFrame = prevFrame;
473
479
  // Execute this frame
474
480
  thisFrame.forEach(triggerCallback);
475
481
  /**
@@ -508,11 +514,12 @@
508
514
  }, {});
509
515
  const { setup, read, resolveKeyframes, preUpdate, update, preRender, render, postRender, } = steps;
510
516
  const processBatch = () => {
511
- const timestamp = MotionGlobalConfig.useManualTiming
517
+ const useManualTiming = MotionGlobalConfig.useManualTiming;
518
+ const timestamp = useManualTiming
512
519
  ? state.timestamp
513
520
  : performance.now();
514
521
  runNextFrame = false;
515
- if (!MotionGlobalConfig.useManualTiming) {
522
+ if (!useManualTiming) {
516
523
  state.delta = useDefaultElapsed
517
524
  ? 1000 / 60
518
525
  : Math.max(Math.min(timestamp - state.timestamp, maxElapsed$1), 1);
@@ -2244,8 +2251,18 @@
2244
2251
  }
2245
2252
  const positionalValues = {
2246
2253
  // Dimensions
2247
- width: ({ x }, { paddingLeft = "0", paddingRight = "0" }) => x.max - x.min - parseFloat(paddingLeft) - parseFloat(paddingRight),
2248
- height: ({ y }, { paddingTop = "0", paddingBottom = "0" }) => y.max - y.min - parseFloat(paddingTop) - parseFloat(paddingBottom),
2254
+ width: ({ x }, { paddingLeft = "0", paddingRight = "0", boxSizing }) => {
2255
+ const width = x.max - x.min;
2256
+ return boxSizing === "border-box"
2257
+ ? width
2258
+ : width - parseFloat(paddingLeft) - parseFloat(paddingRight);
2259
+ },
2260
+ height: ({ y }, { paddingTop = "0", paddingBottom = "0", boxSizing }) => {
2261
+ const height = y.max - y.min;
2262
+ return boxSizing === "border-box"
2263
+ ? height
2264
+ : height - parseFloat(paddingTop) - parseFloat(paddingBottom);
2265
+ },
2249
2266
  top: (_bbox, { top }) => parseFloat(top),
2250
2267
  left: (_bbox, { left }) => parseFloat(left),
2251
2268
  bottom: ({ y }, { top }) => parseFloat(top) + (y.max - y.min),
@@ -2937,7 +2954,9 @@
2937
2954
  * If we can't animate this value with the resolved keyframes
2938
2955
  * then we should complete it immediately.
2939
2956
  */
2957
+ let canAnimateValue = true;
2940
2958
  if (!canAnimate(keyframes, name, type, velocity)) {
2959
+ canAnimateValue = false;
2941
2960
  if (MotionGlobalConfig.instantAnimations || !delay) {
2942
2961
  onUpdate?.(getFinalKeyframe$1(keyframes, options, finalKeyframe));
2943
2962
  }
@@ -2974,8 +2993,13 @@
2974
2993
  * Animate via WAAPI if possible. If this is a handoff animation, the optimised animation will be running via
2975
2994
  * WAAPI. Therefore, this animation must be JS to ensure it runs "under" the
2976
2995
  * optimised animation.
2996
+ *
2997
+ * Also skip WAAPI when keyframes aren't animatable, as the resolved
2998
+ * values may not be valid CSS and would trigger browser warnings.
2977
2999
  */
2978
- const useWaapi = !isHandoff && supportsBrowserAnimation(resolvedOptions);
3000
+ const useWaapi = canAnimateValue &&
3001
+ !isHandoff &&
3002
+ supportsBrowserAnimation(resolvedOptions);
2979
3003
  const element = resolvedOptions.motionValue?.owner?.current;
2980
3004
  const animation = useWaapi
2981
3005
  ? new NativeAnimationExtended({
@@ -4583,7 +4607,9 @@
4583
4607
  * that works across iframes
4584
4608
  */
4585
4609
  function isHTMLElement(element) {
4586
- return isObject(element) && "offsetHeight" in element;
4610
+ return (isObject(element) &&
4611
+ "offsetHeight" in element &&
4612
+ !("ownerSVGElement" in element));
4587
4613
  }
4588
4614
 
4589
4615
  const translateAlias$1 = {
@@ -5363,7 +5389,16 @@
5363
5389
  frame.postRender(scheduleAnimation);
5364
5390
  }, stopAnimation);
5365
5391
  if (isMotionValue(source)) {
5366
- const removeSourceOnChange = source.on("change", (v) => value.set(parseValue(v, unit)));
5392
+ let skipNextAnimation = options.skipInitialAnimation === true;
5393
+ const removeSourceOnChange = source.on("change", (v) => {
5394
+ if (skipNextAnimation) {
5395
+ skipNextAnimation = false;
5396
+ value.jump(parseValue(v, unit), false);
5397
+ }
5398
+ else {
5399
+ value.set(parseValue(v, unit));
5400
+ }
5401
+ });
5367
5402
  const removeValueOnDestroy = value.on("destroy", removeSourceOnChange);
5368
5403
  return () => {
5369
5404
  removeSourceOnChange();
@@ -9477,6 +9512,12 @@
9477
9512
  axisSnapshot.max = axisSnapshot.min + length;
9478
9513
  });
9479
9514
  }
9515
+ else if (animationType === "x" || animationType === "y") {
9516
+ const snapAxis = animationType === "x" ? "y" : "x";
9517
+ copyAxisInto(isShared
9518
+ ? snapshot.measuredBox[snapAxis]
9519
+ : snapshot.layoutBox[snapAxis], layout[snapAxis]);
9520
+ }
9480
9521
  else if (shouldAnimatePositionOnly(animationType, snapshot.layoutBox, layout)) {
9481
9522
  eachAxis((axis) => {
9482
9523
  const axisSnapshot = isShared
@@ -10147,6 +10188,7 @@
10147
10188
  `);
10148
10189
  }
10149
10190
  return () => {
10191
+ ref.current?.removeAttribute("data-motion-pop-id");
10150
10192
  if (parent.contains(style)) {
10151
10193
  parent.removeChild(style);
10152
10194
  }
@@ -10425,8 +10467,8 @@
10425
10467
  if (exitingComponents.current.has(key)) {
10426
10468
  return;
10427
10469
  }
10428
- exitingComponents.current.add(key);
10429
10470
  if (exitComplete.has(key)) {
10471
+ exitingComponents.current.add(key);
10430
10472
  exitComplete.set(key, true);
10431
10473
  }
10432
10474
  else {
@@ -10706,8 +10748,12 @@
10706
10748
  * We attempt to import this package but require won't be defined in esm environments, in that case
10707
10749
  * isPropValid will have to be provided via `MotionContext`. In a 6.0.0 this should probably be removed
10708
10750
  * in favour of explicit injection.
10751
+ *
10752
+ * String concatenation prevents bundlers like webpack (e.g. Storybook)
10753
+ * from statically resolving this optional dependency at build time.
10709
10754
  */
10710
- loadExternalIsValidProp(require("@emotion/is-prop-valid").default);
10755
+ const emotionPkg = "@emotion/is-prop-" + "valid";
10756
+ loadExternalIsValidProp(require(emotionPkg).default);
10711
10757
  }
10712
10758
  catch {
10713
10759
  // We don't need to actually do anything here - the fallback is the existing `isPropValid`.
@@ -10724,6 +10770,8 @@
10724
10770
  */
10725
10771
  if (key === "values" && typeof props.values === "object")
10726
10772
  continue;
10773
+ if (isMotionValue(props[key]))
10774
+ continue;
10727
10775
  if (shouldForward(key) ||
10728
10776
  (forwardMotionProps === true && isValidMotionProp(key)) ||
10729
10777
  (!isDom && !isValidMotionProp(key)) ||
@@ -11436,6 +11484,7 @@
11436
11484
  constructor() {
11437
11485
  super(...arguments);
11438
11486
  this.id = id$1++;
11487
+ this.isExitComplete = false;
11439
11488
  }
11440
11489
  update() {
11441
11490
  if (!this.node.presenceContext)
@@ -11445,9 +11494,38 @@
11445
11494
  if (!this.node.animationState || isPresent === prevIsPresent) {
11446
11495
  return;
11447
11496
  }
11497
+ if (isPresent && prevIsPresent === false) {
11498
+ /**
11499
+ * When re-entering, if the exit animation already completed
11500
+ * (element is at rest), reset to initial values so the enter
11501
+ * animation replays from the correct position.
11502
+ */
11503
+ if (this.isExitComplete) {
11504
+ const { initial, custom } = this.node.getProps();
11505
+ if (typeof initial === "string") {
11506
+ const resolved = resolveVariant(this.node, initial, custom);
11507
+ if (resolved) {
11508
+ const { transition, transitionEnd, ...target } = resolved;
11509
+ for (const key in target) {
11510
+ this.node
11511
+ .getValue(key)
11512
+ ?.jump(target[key]);
11513
+ }
11514
+ }
11515
+ }
11516
+ this.node.animationState.reset();
11517
+ this.node.animationState.animateChanges();
11518
+ }
11519
+ else {
11520
+ this.node.animationState.setActive("exit", false);
11521
+ }
11522
+ this.isExitComplete = false;
11523
+ return;
11524
+ }
11448
11525
  const exitAnimation = this.node.animationState.setActive("exit", !isPresent);
11449
11526
  if (onExitComplete && !isPresent) {
11450
11527
  exitAnimation.then(() => {
11528
+ this.isExitComplete = true;
11451
11529
  onExitComplete(this.id);
11452
11530
  });
11453
11531
  }
@@ -12174,7 +12252,8 @@
12174
12252
  return;
12175
12253
  }
12176
12254
  let transition = (constraints && constraints[axis]) || {};
12177
- if (dragSnapToOrigin)
12255
+ if (dragSnapToOrigin === true ||
12256
+ dragSnapToOrigin === axis)
12178
12257
  transition = { min: 0, max: 0 };
12179
12258
  /**
12180
12259
  * Overdamp the boundary spring if `dragElastic` is disabled. There's still a frame