framer-motion 11.2.0-alpha.0 → 11.2.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.
@@ -708,12 +708,21 @@ function scrapeMotionValuesFromProps(props, prevProps, visualElement) {
708
708
  return newValues;
709
709
  }
710
710
 
711
- function resolveVariantFromProps(props, definition, custom, currentValues = {}, currentVelocity = {}) {
711
+ function getValueState(visualElement) {
712
+ const state = [{}, {}];
713
+ visualElement === null || visualElement === void 0 ? void 0 : visualElement.values.forEach((value, key) => {
714
+ state[0][key] = value.get();
715
+ state[1][key] = value.getVelocity();
716
+ });
717
+ return state;
718
+ }
719
+ function resolveVariantFromProps(props, definition, custom, visualElement) {
712
720
  /**
713
721
  * If the variant definition is a function, resolve.
714
722
  */
715
723
  if (typeof definition === "function") {
716
- definition = definition(custom !== undefined ? custom : props.custom, currentValues, currentVelocity);
724
+ const [current, velocity] = getValueState(visualElement);
725
+ definition = definition(custom !== undefined ? custom : props.custom, current, velocity);
717
726
  }
718
727
  /**
719
728
  * If the variant definition is a variant label, or
@@ -728,7 +737,8 @@ function resolveVariantFromProps(props, definition, custom, currentValues = {},
728
737
  * If so, resolve. This can only have returned a valid target object.
729
738
  */
730
739
  if (typeof definition === "function") {
731
- definition = definition(custom !== undefined ? custom : props.custom, currentValues, currentVelocity);
740
+ const [current, velocity] = getValueState(visualElement);
741
+ definition = definition(custom !== undefined ? custom : props.custom, current, velocity);
732
742
  }
733
743
  return definition;
734
744
  }
@@ -759,25 +769,9 @@ const { schedule: frame, cancel: cancelFrame, state: frameData, steps, } = creat
759
769
  const combineFunctions = (a, b) => (v) => b(a(v));
760
770
  const pipe = (...transformers) => transformers.reduce(combineFunctions);
761
771
 
762
- /**
763
- * Creates an object containing the latest state of every MotionValue on a VisualElement
764
- */
765
- function getCurrent(visualElement) {
766
- const current = {};
767
- visualElement.values.forEach((value, key) => (current[key] = value.get()));
768
- return current;
769
- }
770
- /**
771
- * Creates an object containing the latest velocity of every MotionValue on a VisualElement
772
- */
773
- function getVelocity(visualElement) {
774
- const velocity = {};
775
- visualElement.values.forEach((value, key) => (velocity[key] = value.getVelocity()));
776
- return velocity;
777
- }
778
772
  function resolveVariant(visualElement, definition, custom) {
779
773
  const props = visualElement.getProps();
780
- return resolveVariantFromProps(props, definition, custom !== undefined ? custom : props.custom, getCurrent(visualElement), getVelocity(visualElement));
774
+ return resolveVariantFromProps(props, definition, custom !== undefined ? custom : props.custom, visualElement);
781
775
  }
782
776
 
783
777
  /**
@@ -1464,13 +1458,15 @@ function getAnimatableNone(key, value) {
1464
1458
  * the "none" keyframes. In this case "#fff" or "200px 200px" - then these get turned into
1465
1459
  * zero equivalents, i.e. "#fff0" or "0px 0px".
1466
1460
  */
1461
+ const invalidTemplates = new Set(["auto", "none", "0"]);
1467
1462
  function makeNoneKeyframesAnimatable(unresolvedKeyframes, noneKeyframeIndexes, name) {
1468
1463
  let i = 0;
1469
1464
  let animatableTemplate = undefined;
1470
1465
  while (i < unresolvedKeyframes.length && !animatableTemplate) {
1471
- if (typeof unresolvedKeyframes[i] === "string" &&
1472
- unresolvedKeyframes[i] !== "none" &&
1473
- unresolvedKeyframes[i] !== "0") {
1466
+ const keyframe = unresolvedKeyframes[i];
1467
+ if (typeof keyframe === "string" &&
1468
+ !invalidTemplates.has(keyframe) &&
1469
+ analyseComplexValue(keyframe).values.length) {
1474
1470
  animatableTemplate = unresolvedKeyframes[i];
1475
1471
  }
1476
1472
  i++;
@@ -1506,6 +1502,12 @@ class DOMKeyframesResolver extends KeyframeResolver {
1506
1502
  }
1507
1503
  }
1508
1504
  }
1505
+ /**
1506
+ * Resolve "none" values. We do this potentially twice - once before and once after measuring keyframes.
1507
+ * This could be seen as inefficient but it's a trade-off to avoid measurements in more situations, which
1508
+ * have a far bigger performance impact.
1509
+ */
1510
+ this.resolveNoneKeyframes();
1509
1511
  /**
1510
1512
  * Check to see if unit type has changed. If so schedule jobs that will
1511
1513
  * temporarily set styles to the destination keyframes.
@@ -1513,7 +1515,7 @@ class DOMKeyframesResolver extends KeyframeResolver {
1513
1515
  * TODO: We can throw if there are multiple keyframes and the value type changes.
1514
1516
  */
1515
1517
  if (!positionalKeys.has(name) || unresolvedKeyframes.length !== 2) {
1516
- return this.resolveNoneKeyframes();
1518
+ return;
1517
1519
  }
1518
1520
  const [origin, target] = unresolvedKeyframes;
1519
1521
  const originType = findDimensionValueType(origin);
@@ -1648,6 +1650,13 @@ function canAnimate(keyframes, name, type, velocity) {
1648
1650
  const originKeyframe = keyframes[0];
1649
1651
  if (originKeyframe === null)
1650
1652
  return false;
1653
+ /**
1654
+ * These aren't traditionally animatable but we do support them.
1655
+ * In future we could look into making this more generic or replacing
1656
+ * this function with mix() === mixImmediate
1657
+ */
1658
+ if (name === "display" || name === "visibility")
1659
+ return true;
1651
1660
  const targetKeyframe = keyframes[keyframes.length - 1];
1652
1661
  const isOriginAnimatable = isAnimatable(originKeyframe, name);
1653
1662
  const isTargetAnimatable = isAnimatable(targetKeyframe, name);
@@ -2264,6 +2273,21 @@ const mixColor = (from, to) => {
2264
2273
  };
2265
2274
  };
2266
2275
 
2276
+ const invisibleValues = new Set(["none", "hidden"]);
2277
+ /**
2278
+ * Returns a function that, when provided a progress value between 0 and 1,
2279
+ * will return the "none" or "hidden" string only when the progress is that of
2280
+ * the origin or target.
2281
+ */
2282
+ function mixVisibility(origin, target) {
2283
+ if (invisibleValues.has(origin)) {
2284
+ return (p) => (p <= 0 ? origin : target);
2285
+ }
2286
+ else {
2287
+ return (p) => (p >= 1 ? target : origin);
2288
+ }
2289
+ }
2290
+
2267
2291
  function mixImmediate(a, b) {
2268
2292
  return (p) => (p > 0 ? b : a);
2269
2293
  }
@@ -2336,6 +2360,12 @@ const mixComplex = (origin, target) => {
2336
2360
  originStats.indexes.color.length === targetStats.indexes.color.length &&
2337
2361
  originStats.indexes.number.length >= targetStats.indexes.number.length;
2338
2362
  if (canInterpolate) {
2363
+ if ((invisibleValues.has(origin) &&
2364
+ !targetStats.values.length) ||
2365
+ (invisibleValues.has(target) &&
2366
+ !originStats.values.length)) {
2367
+ return mixVisibility(origin, target);
2368
+ }
2339
2369
  return pipe(mixArray(matchOrder(originStats, targetStats), targetStats.values), template);
2340
2370
  }
2341
2371
  else {
@@ -3419,7 +3449,7 @@ class MotionValue {
3419
3449
  * This will be replaced by the build step with the latest version number.
3420
3450
  * When MotionValues are provided to motion components, warn if versions are mixed.
3421
3451
  */
3422
- this.version = "11.2.0-alpha.0";
3452
+ this.version = "11.2.1";
3423
3453
  /**
3424
3454
  * Tracks whether this value can output a velocity. Currently this is only true
3425
3455
  * if the value is numerical, but we might be able to widen the scope here and support
@@ -3713,7 +3743,7 @@ function setMotionValue(visualElement, key, value) {
3713
3743
  }
3714
3744
  function setTarget(visualElement, definition) {
3715
3745
  const resolved = resolveVariant(visualElement, definition);
3716
- let { transitionEnd = {}, transitionFrom, transition = {}, ...target } = resolved || {};
3746
+ let { transitionEnd = {}, transition = {}, ...target } = resolved || {};
3717
3747
  target = { ...target, ...transitionEnd };
3718
3748
  for (const key in target) {
3719
3749
  const value = resolveFinalValueInKeyframes(target[key]);
@@ -3734,7 +3764,7 @@ function shouldBlockAnimation({ protectedKeys, needsAnimating }, key) {
3734
3764
  }
3735
3765
  function animateTarget(visualElement, targetAndTransition, { delay = 0, transitionOverride, type } = {}) {
3736
3766
  var _a;
3737
- let { transition = visualElement.getDefaultTransition(), transitionFrom, transitionEnd, ...target } = targetAndTransition;
3767
+ let { transition = visualElement.getDefaultTransition(), transitionEnd, ...target } = targetAndTransition;
3738
3768
  const willChange = visualElement.getValue("willChange");
3739
3769
  if (transitionOverride)
3740
3770
  transition = transitionOverride;
@@ -3750,23 +3780,10 @@ function animateTarget(visualElement, targetAndTransition, { delay = 0, transiti
3750
3780
  shouldBlockAnimation(animationTypeState, key))) {
3751
3781
  continue;
3752
3782
  }
3753
- let transitionFromType;
3754
- if (transitionFrom) {
3755
- if (value.currentAnimationState) {
3756
- transitionFromType = transitionFrom[value.currentAnimationState];
3757
- }
3758
- else {
3759
- // This is the first time the value has been animated.
3760
- const initialType = visualElement.getProps().initial || type === "animate"
3761
- ? "initial"
3762
- : "animate";
3763
- transitionFromType = transitionFrom[initialType];
3764
- }
3765
- }
3766
3783
  const valueTransition = {
3767
3784
  delay,
3768
3785
  elapsed: 0,
3769
- ...getValueTransition$1(transitionFromType || transition || {}, key),
3786
+ ...getValueTransition$1(transition || {}, key),
3770
3787
  };
3771
3788
  /**
3772
3789
  * If this is the first time a value is being animated, check
@@ -3787,7 +3804,6 @@ function animateTarget(visualElement, targetAndTransition, { delay = 0, transiti
3787
3804
  value.start(animateMotionValue(key, value, valueTarget, visualElement.shouldReduceMotion && transformProps.has(key)
3788
3805
  ? { type: false }
3789
3806
  : valueTransition, visualElement, isHandoff));
3790
- value.currentAnimationState = type || "animate";
3791
3807
  const animation = value.animation;
3792
3808
  if (animation) {
3793
3809
  if (isWillChangeMotionValue(willChange)) {
@@ -4202,7 +4218,7 @@ function updateMotionValuesFromProps(element, next, prev) {
4202
4218
  * and warn against mismatches.
4203
4219
  */
4204
4220
  if (process.env.NODE_ENV === "development") {
4205
- warnOnce(nextValue.version === "11.2.0-alpha.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 11.2.0-alpha.0 may not work as expected.`);
4221
+ warnOnce(nextValue.version === "11.2.1", `Attempting to mix Framer Motion versions ${nextValue.version} with 11.2.1 may not work as expected.`);
4206
4222
  }
4207
4223
  }
4208
4224
  else if (isMotionValue(prevValue)) {
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var domEntry = require('./dom-entry-BNd0N1D8.js');
5
+ var domEntry = require('./dom-entry-Bn7tpd2Y.js');
6
6
 
7
7
 
8
8
 
package/dist/cjs/index.js CHANGED
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var React = require('react');
7
- var domEntry = require('./dom-entry-BNd0N1D8.js');
7
+ var domEntry = require('./dom-entry-Bn7tpd2Y.js');
8
8
 
9
9
  function _interopNamespaceDefault(e) {
10
10
  var n = Object.create(null);
@@ -636,7 +636,7 @@ function makeLatestValues(props, context, presenceContext, scrapeMotionValues) {
636
636
  const resolved = domEntry.resolveVariantFromProps(props, definition);
637
637
  if (!resolved)
638
638
  return;
639
- const { transitionEnd, transitionFrom, transition, ...target } = resolved;
639
+ const { transitionEnd, transition, ...target } = resolved;
640
640
  for (const key in target) {
641
641
  let valueTarget = target[key];
642
642
  if (Array.isArray(valueTarget)) {
@@ -820,8 +820,9 @@ function addHoverEvent(node, isActive) {
820
820
  node.animationState.setActive("whileHover", isActive);
821
821
  }
822
822
  const callback = props[callbackName];
823
- if (callback)
824
- callback(event, info);
823
+ if (callback) {
824
+ domEntry.frame.postRender(() => callback(event, info));
825
+ }
825
826
  };
826
827
  return addPointerEvent(node.current, eventName, handleEvent, {
827
828
  passive: !node.getProps()[callbackName],
@@ -914,10 +915,13 @@ class PressGesture extends Feature {
914
915
  * We only count this as a tap gesture if the event.target is the same
915
916
  * as, or a child of, this component's element
916
917
  */
917
- !globalTapTarget &&
918
+ const handler = !globalTapTarget &&
918
919
  !isNodeOrChild(this.node.current, endEvent.target)
919
- ? onTapCancel && onTapCancel(endEvent, endInfo)
920
- : onTap && onTap(endEvent, endInfo);
920
+ ? onTapCancel
921
+ : onTap;
922
+ if (handler) {
923
+ domEntry.frame.update(() => handler(endEvent, endInfo));
924
+ }
921
925
  };
922
926
  const removePointerUpListener = addPointerEvent(window, "pointerup", endPointerPress, {
923
927
  passive: !(props.onTap || props["onPointerUp"]),
@@ -938,8 +942,9 @@ class PressGesture extends Feature {
938
942
  return;
939
943
  fireSyntheticPointerEvent("up", (event, info) => {
940
944
  const { onTap } = this.node.getProps();
941
- if (onTap)
942
- onTap(event, info);
945
+ if (onTap) {
946
+ domEntry.frame.postRender(() => onTap(event, info));
947
+ }
943
948
  });
944
949
  };
945
950
  this.removeEndListeners();
@@ -968,7 +973,7 @@ class PressGesture extends Feature {
968
973
  this.node.animationState.setActive("whileTap", true);
969
974
  }
970
975
  if (onTapStart) {
971
- onTapStart(event, info);
976
+ domEntry.frame.postRender(() => onTapStart(event, info));
972
977
  }
973
978
  }
974
979
  checkPressEnd() {
@@ -984,8 +989,9 @@ class PressGesture extends Feature {
984
989
  if (!this.checkPressEnd())
985
990
  return;
986
991
  const { onTapCancel } = this.node.getProps();
987
- if (onTapCancel)
988
- onTapCancel(event, info);
992
+ if (onTapCancel) {
993
+ domEntry.frame.postRender(() => onTapCancel(event, info));
994
+ }
989
995
  }
990
996
  mount() {
991
997
  const props = this.node.getProps();
@@ -1251,7 +1257,7 @@ function createAnimationState(visualElement) {
1251
1257
  ? (_a = visualElement.presenceContext) === null || _a === void 0 ? void 0 : _a.custom
1252
1258
  : undefined);
1253
1259
  if (resolved) {
1254
- const { transition, transitionEnd, transitionFrom, ...target } = resolved;
1260
+ const { transition, transitionEnd, ...target } = resolved;
1255
1261
  acc = { ...acc, ...target, ...transitionEnd };
1256
1262
  }
1257
1263
  return acc;
@@ -1483,16 +1489,7 @@ function createAnimationState(visualElement) {
1483
1489
  // @ts-expect-error - @mattgperry to figure if we should do something here
1484
1490
  fallbackAnimation[key] = fallbackTarget !== null && fallbackTarget !== void 0 ? fallbackTarget : null;
1485
1491
  });
1486
- const { initial } = props;
1487
- if (initial && typeof initial !== "boolean") {
1488
- const { transition, transitionFrom } = domEntry.resolveVariant(visualElement, Array.isArray(initial) ? initial[0] : initial) || {};
1489
- fallbackAnimation.transition = transition;
1490
- fallbackAnimation.transitionFrom = transitionFrom;
1491
- }
1492
- animations.push({
1493
- animation: fallbackAnimation,
1494
- options: { type: "initial" },
1495
- });
1492
+ animations.push({ animation: fallbackAnimation });
1496
1493
  }
1497
1494
  let shouldAnimate = Boolean(animations.length);
1498
1495
  if (isInitialRender &&
@@ -2023,8 +2020,9 @@ class VisualElementDragControls {
2023
2020
  this.originPoint[axis] = current;
2024
2021
  });
2025
2022
  // Fire onDragStart event
2026
- if (onDragStart)
2027
- onDragStart(event, info);
2023
+ if (onDragStart) {
2024
+ domEntry.frame.postRender(() => onDragStart(event, info));
2025
+ }
2028
2026
  const { animationState } = this.visualElement;
2029
2027
  animationState && animationState.setActive("whileDrag", true);
2030
2028
  };
@@ -2087,8 +2085,9 @@ class VisualElementDragControls {
2087
2085
  const { velocity } = info;
2088
2086
  this.startAnimation(velocity);
2089
2087
  const { onDragEnd } = this.getProps();
2090
- if (onDragEnd)
2091
- onDragEnd(event, info);
2088
+ if (onDragEnd) {
2089
+ domEntry.frame.postRender(() => onDragEnd(event, info));
2090
+ }
2092
2091
  }
2093
2092
  cancel() {
2094
2093
  this.isDragging = false;
@@ -2429,7 +2428,7 @@ class DragGesture extends Feature {
2429
2428
 
2430
2429
  const asyncHandler = (handler) => (event, info) => {
2431
2430
  if (handler) {
2432
- handler(event, info);
2431
+ domEntry.frame.postRender(() => handler(event, info));
2433
2432
  }
2434
2433
  };
2435
2434
  class PanGesture extends Feature {
@@ -2451,8 +2450,9 @@ class PanGesture extends Feature {
2451
2450
  onMove: onPan,
2452
2451
  onEnd: (event, info) => {
2453
2452
  delete this.session;
2454
- if (onPanEnd)
2455
- onPanEnd(event, info);
2453
+ if (onPanEnd) {
2454
+ domEntry.frame.postRender(() => onPanEnd(event, info));
2455
+ }
2456
2456
  },
2457
2457
  };
2458
2458
  }
@@ -38,8 +38,6 @@ interface FrameData {
38
38
  isProcessing: boolean;
39
39
  }
40
40
 
41
- type AnimationType = "animate" | "whileHover" | "whileTap" | "whileDrag" | "whileFocus" | "whileInView" | "exit";
42
-
43
41
  /**
44
42
  * @public
45
43
  */
@@ -507,10 +505,6 @@ declare class MotionValue<V = any> {
507
505
  * A reference to the currently-controlling animation.
508
506
  */
509
507
  animation?: AnimationPlaybackControls;
510
- /**
511
- * The current animation type of the `MotionValue`.
512
- */
513
- currentAnimationState?: AnimationType | "initial";
514
508
  setCurrent(current: V): void;
515
509
  setPrevFrameValue(prevFrameValue?: V | undefined): void;
516
510
  /**