framer-motion 5.0.0-rc.3 → 5.0.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.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  <p align="center">
2
- <img src="https://misc.framerstatic.com/motion/motion-readme-4.gif" width="400" height="250" alt="Framer Motion" />
2
+ <img src="https://user-images.githubusercontent.com/22095598/123793419-f5528800-d8e1-11eb-8c5f-e2dad45a9c81.png" width="108" height="108" alt="Framer Motion" />
3
3
  </p>
4
-
4
+ <h1 align="center">Framer Motion</h1>
5
5
  <h3 align="center">
6
6
  An open source and production-ready motion<br>library for React on the web.
7
7
  </h3>
@@ -35,21 +35,22 @@ It looks like this:
35
35
 
36
36
  It does all this:
37
37
 
38
- - Spring animations
39
- - Simple keyframes syntax
38
+ - Springs
39
+ - Keyframes
40
+ - Layout animations
41
+ - Shared layout animations
40
42
  - Gestures (drag/tap/hover)
41
- - Layout and shared layout animations
42
43
  - SVG paths
43
44
  - Exit animations
44
45
  - Server-side rendering
45
- - Variants for orchestrating animations across components
46
+ - Orchestrate animations across components
46
47
  - CSS variables
47
48
 
48
49
  ...and a whole lot more.
49
50
 
50
51
  ## Get started
51
52
 
52
- ### Quick start
53
+ ### 🐇 Quick start
53
54
 
54
55
  ```
55
56
  npm install framer-motion
@@ -63,17 +64,17 @@ export const MyComponent = ({ isVisible }) => (
63
64
  )
64
65
  ```
65
66
 
66
- ### Docs
67
+ ### 📚 Docs
67
68
 
68
- Check out [our documentation](https://framer.com/api/motion) for guides and a full API reference.
69
+ Check out [our documentation](https://www.framer.com/docs/) for guides and a full API reference.
69
70
 
70
- Or checkout [our examples](https://framer.com/motion) for inspiration.
71
+ Or checkout [our examples](https://www.framer.com/docs/examples/) for inspiration.
71
72
 
72
- ### Contribute
73
+ ### 🛠 Contribute
73
74
 
74
75
  Want to contribute to Framer Motion? Our [contributing guide](https://github.com/framer/motion/blob/master/CONTRIBUTING.md) has you covered.
75
76
 
76
- ### License
77
+ ### 👩🏻‍⚖️ License
77
78
 
78
79
  Framer Motion is MIT licensed.
79
80
 
@@ -75,9 +75,9 @@ function convertTransitionToAnimationOptions(_a) {
75
75
  * Get the delay for a value by checking Transition with decreasing specificity.
76
76
  */
77
77
  function getDelayFromTransition(transition, key) {
78
- var _a;
78
+ var _a, _b;
79
79
  var valueTransition = getValueTransition(transition, key) || {};
80
- return (_a = valueTransition.delay) !== null && _a !== void 0 ? _a : 0;
80
+ return (_b = (_a = valueTransition.delay) !== null && _a !== void 0 ? _a : transition.delay) !== null && _b !== void 0 ? _b : 0;
81
81
  }
82
82
  function hydrateKeyframes(options) {
83
83
  if (Array.isArray(options.to) && options.to[0] === null) {
@@ -1,6 +1,6 @@
1
1
  import { __read, __spreadArray } from 'tslib';
2
2
  import * as React from 'react';
3
- import { useContext, useRef, cloneElement, Children, isValidElement } from 'react';
3
+ import { useContext, useRef, useEffect, cloneElement, Children, isValidElement } from 'react';
4
4
  import { useForceUpdate } from '../../utils/use-force-update.mjs';
5
5
  import { PresenceChild } from './PresenceChild.mjs';
6
6
  import { LayoutGroupContext } from '../../context/LayoutGroupContext.mjs';
@@ -72,6 +72,10 @@ var AnimatePresence = function (_a) {
72
72
  if (forceRenderLayoutGroup)
73
73
  forceRender = forceRenderLayoutGroup;
74
74
  var isInitialRender = useRef(true);
75
+ var isMounted = useRef(true);
76
+ useEffect(function () { return function () {
77
+ isMounted.current = false;
78
+ }; }, []);
75
79
  // Filter out any children that aren't ReactElements. We can only track ReactElements with a props.key
76
80
  var filteredChildren = onlyElements(children);
77
81
  // Keep a living record of the children we're actually rendering so we
@@ -130,6 +134,9 @@ var AnimatePresence = function (_a) {
130
134
  // Defer re-rendering until all exiting children have indeed left
131
135
  if (!exiting.size) {
132
136
  presentChildren.current = filteredChildren;
137
+ if (isMounted.current === false) {
138
+ return;
139
+ }
133
140
  forceRender();
134
141
  onExitComplete && onExitComplete();
135
142
  }
@@ -2,18 +2,9 @@ import { useMemo, useContext } from 'react';
2
2
  import { MotionContext } from './index.mjs';
3
3
  import { getCurrentTreeVariants } from './utils.mjs';
4
4
 
5
- function useCreateMotionContext(props, isStatic) {
5
+ function useCreateMotionContext(props) {
6
6
  var _a = getCurrentTreeVariants(props, useContext(MotionContext)), initial = _a.initial, animate = _a.animate;
7
- return useMemo(function () { return ({ initial: initial, animate: animate }); },
8
- /**
9
- * Only break memoisation in static mode
10
- */
11
- isStatic
12
- ? [
13
- variantLabelsAsDependency(initial),
14
- variantLabelsAsDependency(animate),
15
- ]
16
- : []);
7
+ return useMemo(function () { return ({ initial: initial, animate: animate }); }, [variantLabelsAsDependency(initial), variantLabelsAsDependency(animate)]);
17
8
  }
18
9
  function variantLabelsAsDependency(prop) {
19
10
  return Array.isArray(prop) ? prop.join(" ") : prop;
@@ -1,4 +1,5 @@
1
1
  import { __extends, __assign, __read } from 'tslib';
2
+ import sync from 'framesync';
2
3
  import React__default, { useContext } from 'react';
3
4
  import { usePresence } from '../../../components/AnimatePresence/use-presence.mjs';
4
5
  import { LayoutGroupContext } from '../../../context/LayoutGroupContext.mjs';
@@ -38,6 +39,7 @@ var MeasureLayoutWithContext = /** @class */ (function (_super) {
38
39
  globalProjectionState.hasEverUpdated = true;
39
40
  };
40
41
  MeasureLayoutWithContext.prototype.getSnapshotBeforeUpdate = function (prevProps) {
42
+ var _this = this;
41
43
  var _a = this.props, layoutDependency = _a.layoutDependency, visualElement = _a.visualElement, drag = _a.drag, isPresent = _a.isPresent;
42
44
  var projection = visualElement.projection;
43
45
  if (!projection)
@@ -55,12 +57,25 @@ var MeasureLayoutWithContext = /** @class */ (function (_super) {
55
57
  layoutDependency === undefined) {
56
58
  projection.willUpdate();
57
59
  }
60
+ else {
61
+ this.safeToRemove();
62
+ }
58
63
  if (prevProps.isPresent !== isPresent) {
59
64
  if (isPresent) {
60
65
  projection.promote();
61
66
  }
62
- else {
63
- projection.relegate();
67
+ else if (!projection.relegate()) {
68
+ /**
69
+ * If there's another stack member taking over from this one,
70
+ * it's in charge of the exit animation and therefore should
71
+ * be in charge of the safe to remove. Otherwise we call it here.
72
+ */
73
+ sync.postRender(function () {
74
+ var _a;
75
+ if (!((_a = projection.getStack()) === null || _a === void 0 ? void 0 : _a.members.length)) {
76
+ _this.safeToRemove();
77
+ }
78
+ });
64
79
  }
65
80
  }
66
81
  return null;
@@ -39,11 +39,7 @@ function createMotionComponent(_a) {
39
39
  */
40
40
  var config = useContext(MotionConfigContext);
41
41
  var features = null;
42
- /**
43
- * Create the tree context. This is memoized and will only trigger renders
44
- * when the current tree variant changes in static mode.
45
- */
46
- var context = useCreateMotionContext(props, config.isStatic);
42
+ var context = useCreateMotionContext(props);
47
43
  /**
48
44
  * Create a unique projection ID for this component. If a new component is added
49
45
  * during a layout animation we'll use this to query the DOM and hydrate its ref early, allowing
@@ -29,10 +29,6 @@ function useVisualElement(Component, visualState, props, createVisualElement) {
29
29
  });
30
30
  useEffect(function () {
31
31
  var _a;
32
- /**
33
- * In a future refactor we can replace the features-as-components and
34
- * have this loop through them all firing "effect" listeners
35
- */
36
32
  (_a = visualElement === null || visualElement === void 0 ? void 0 : visualElement.animationState) === null || _a === void 0 ? void 0 : _a.animateChanges();
37
33
  });
38
34
  useIsomorphicLayoutEffect(function () { return function () { return visualElement === null || visualElement === void 0 ? void 0 : visualElement.notifyUnmount(); }; }, []);
@@ -287,8 +287,12 @@ function createProjectionNode(_a) {
287
287
  (_a = this.nodes) === null || _a === void 0 ? void 0 : _a.forEach(resetRotation);
288
288
  };
289
289
  ProjectionNode.prototype.willUpdate = function (shouldNotifyListeners) {
290
- var _a;
290
+ var _a, _b, _c;
291
291
  if (shouldNotifyListeners === void 0) { shouldNotifyListeners = true; }
292
+ if (this.root.isUpdateBlocked()) {
293
+ (_b = (_a = this.options).onExitComplete) === null || _b === void 0 ? void 0 : _b.call(_a);
294
+ return;
295
+ }
292
296
  !this.root.isUpdating && this.root.startUpdate();
293
297
  if (this.isLayoutDirty)
294
298
  return;
@@ -302,10 +306,10 @@ function createProjectionNode(_a) {
302
306
  */
303
307
  node.updateScroll();
304
308
  }
305
- var _b = this.options, layoutId = _b.layoutId, layout = _b.layout;
309
+ var _d = this.options, layoutId = _d.layoutId, layout = _d.layout;
306
310
  if (!layoutId && !layout)
307
311
  return;
308
- var transformTemplate = (_a = this.options.visualElement) === null || _a === void 0 ? void 0 : _a.getProps().transformTemplate;
312
+ var transformTemplate = (_c = this.options.visualElement) === null || _c === void 0 ? void 0 : _c.getProps().transformTemplate;
309
313
  this.prevTransformTemplateValue = transformTemplate === null || transformTemplate === void 0 ? void 0 : transformTemplate(this.latestValues, "");
310
314
  this.updateSnapshot();
311
315
  shouldNotifyListeners && this.notifyListeners("willUpdate");
@@ -1030,13 +1034,13 @@ function updateLayout(node) {
1030
1034
  node.updateLayout();
1031
1035
  }
1032
1036
  function notifyLayoutUpdate(node) {
1033
- var _a, _b;
1037
+ var _a, _b, _c, _d;
1034
1038
  var snapshot = (_b = (_a = node.resumeFrom) === null || _a === void 0 ? void 0 : _a.snapshot) !== null && _b !== void 0 ? _b : node.snapshot;
1035
1039
  if (node.isLead() &&
1036
1040
  node.layout &&
1037
1041
  snapshot &&
1038
1042
  node.hasListeners("didUpdate")) {
1039
- var _c = node.layout, layout_1 = _c.actual, measuredLayout = _c.measured;
1043
+ var _e = node.layout, layout_1 = _e.actual, measuredLayout = _e.measured;
1040
1044
  // TODO Maybe we want to also resize the layout snapshot so we don't trigger
1041
1045
  // animations for instance if layout="size" and an element has only changed position
1042
1046
  if (node.options.animationType === "size") {
@@ -1076,7 +1080,7 @@ function notifyLayoutUpdate(node) {
1076
1080
  * the relative snapshot is not relavent
1077
1081
  */
1078
1082
  if (node.relativeParent && !node.relativeParent.resumeFrom) {
1079
- var _d = node.relativeParent, parentSnapshot = _d.snapshot, parentLayout = _d.layout;
1083
+ var _f = node.relativeParent, parentSnapshot = _f.snapshot, parentLayout = _f.layout;
1080
1084
  if (parentSnapshot && parentLayout) {
1081
1085
  var relativeSnapshot = createBox();
1082
1086
  calcRelativePosition(relativeSnapshot, snapshot.layout, parentSnapshot.layout);
@@ -1097,6 +1101,9 @@ function notifyLayoutUpdate(node) {
1097
1101
  hasRelativeTargetChanged: hasRelativeTargetChanged,
1098
1102
  });
1099
1103
  }
1104
+ else if (node.isLead()) {
1105
+ (_d = (_c = node.options).onExitComplete) === null || _d === void 0 ? void 0 : _d.call(_c);
1106
+ }
1100
1107
  /**
1101
1108
  * Clearing transition
1102
1109
  * TODO: Investigate why this transition is being passed in as {type: false } from Framer
@@ -40,24 +40,26 @@ var BoundingBoxDimension;
40
40
  var getPosFromMatrix = function (matrix, pos) {
41
41
  return parseFloat(matrix.split(", ")[pos]);
42
42
  };
43
- var getTranslateFromMatrix = function (pos2, pos3) { return function (_bbox, _a) {
44
- var transform = _a.transform;
45
- if (transform === "none" || !transform)
46
- return 0;
47
- var matrix3d = transform.match(/^matrix3d\((.+)\)$/);
48
- if (matrix3d) {
49
- return getPosFromMatrix(matrix3d[1], pos3);
50
- }
51
- else {
52
- var matrix = transform.match(/^matrix\((.+)\)$/);
53
- if (matrix) {
54
- return getPosFromMatrix(matrix[1], pos2);
43
+ var getTranslateFromMatrix = function (pos2, pos3) {
44
+ return function (_bbox, _a) {
45
+ var transform = _a.transform;
46
+ if (transform === "none" || !transform)
47
+ return 0;
48
+ var matrix3d = transform.match(/^matrix3d\((.+)\)$/);
49
+ if (matrix3d) {
50
+ return getPosFromMatrix(matrix3d[1], pos3);
55
51
  }
56
52
  else {
57
- return 0;
53
+ var matrix = transform.match(/^matrix\((.+)\)$/);
54
+ if (matrix) {
55
+ return getPosFromMatrix(matrix[1], pos2);
56
+ }
57
+ else {
58
+ return 0;
59
+ }
58
60
  }
59
- }
60
- }; };
61
+ };
62
+ };
61
63
  var transformKeys = new Set(["x", "y", "z"]);
62
64
  var nonTranslationalTransformKeys = transformProps.filter(function (key) { return !transformKeys.has(key); });
63
65
  function removeNonTranslationalTransform(visualElement) {
@@ -145,8 +147,8 @@ var checkAndConvertChangedValueTypes = function (visualElement, target, origin,
145
147
  if (!visualElement.hasValue(key))
146
148
  return;
147
149
  var from = origin[key];
148
- var to = target[key];
149
150
  var fromType = findDimensionValueType(from);
151
+ var to = target[key];
150
152
  var toType;
151
153
  // TODO: The current implementation of this basically throws an error
152
154
  // if you try and do value conversion via keyframes. There's probably
@@ -154,7 +156,10 @@ var checkAndConvertChangedValueTypes = function (visualElement, target, origin,
154
156
  // as it'd be doing multiple resize-remeasure operations.
155
157
  if (isKeyframesTarget(to)) {
156
158
  var numKeyframes = to.length;
157
- for (var i = to[0] === null ? 1 : 0; i < numKeyframes; i++) {
159
+ var fromIndex = to[0] === null ? 1 : 0;
160
+ from = to[fromIndex];
161
+ fromType = findDimensionValueType(from);
162
+ for (var i = fromIndex; i < numKeyframes; i++) {
158
163
  if (!toType) {
159
164
  toType = findDimensionValueType(to[i]);
160
165
  invariant(toType === fromType ||
@@ -199,7 +204,8 @@ var checkAndConvertChangedValueTypes = function (visualElement, target, origin,
199
204
  // If we're going to do value conversion via DOM measurements, we first
200
205
  // need to remove non-positional transform values that could affect the bbox measurements.
201
206
  if (!hasAttemptedToRemoveTransformValues) {
202
- removedTransformValues = removeNonTranslationalTransform(visualElement);
207
+ removedTransformValues =
208
+ removeNonTranslationalTransform(visualElement);
203
209
  hasAttemptedToRemoveTransformValues = true;
204
210
  }
205
211
  changedValueTypeKeys.push(key);
@@ -8,7 +8,7 @@ import { resolveVariant } from './variants.mjs';
8
8
  */
9
9
  function animateVisualElement(visualElement, definition, options) {
10
10
  if (options === void 0) { options = {}; }
11
- visualElement.notifyAnimationStart();
11
+ visualElement.notifyAnimationStart(definition);
12
12
  var animation;
13
13
  if (Array.isArray(definition)) {
14
14
  var animations = definition.map(function (variant) {
@@ -157,10 +157,6 @@ function useVisualElement(Component, visualState, props, createVisualElement) {
157
157
  });
158
158
  React.useEffect(function () {
159
159
  var _a;
160
- /**
161
- * In a future refactor we can replace the features-as-components and
162
- * have this loop through them all firing "effect" listeners
163
- */
164
160
  (_a = visualElement === null || visualElement === void 0 ? void 0 : visualElement.animationState) === null || _a === void 0 ? void 0 : _a.animateChanges();
165
161
  });
166
162
  useIsomorphicLayoutEffect(function () { return function () { return visualElement === null || visualElement === void 0 ? void 0 : visualElement.notifyUnmount(); }; }, []);
@@ -273,18 +269,9 @@ function getCurrentTreeVariants(props, context) {
273
269
  return props.inherit !== false ? context : {};
274
270
  }
275
271
 
276
- function useCreateMotionContext(props, isStatic) {
272
+ function useCreateMotionContext(props) {
277
273
  var _a = getCurrentTreeVariants(props, React.useContext(MotionContext)), initial = _a.initial, animate = _a.animate;
278
- return React.useMemo(function () { return ({ initial: initial, animate: animate }); },
279
- /**
280
- * Only break memoisation in static mode
281
- */
282
- isStatic
283
- ? [
284
- variantLabelsAsDependency(initial),
285
- variantLabelsAsDependency(animate),
286
- ]
287
- : []);
274
+ return React.useMemo(function () { return ({ initial: initial, animate: animate }); }, [variantLabelsAsDependency(initial), variantLabelsAsDependency(animate)]);
288
275
  }
289
276
  function variantLabelsAsDependency(prop) {
290
277
  return Array.isArray(prop) ? prop.join(" ") : prop;
@@ -955,9 +942,9 @@ function convertTransitionToAnimationOptions(_a) {
955
942
  * Get the delay for a value by checking Transition with decreasing specificity.
956
943
  */
957
944
  function getDelayFromTransition(transition, key) {
958
- var _a;
945
+ var _a, _b;
959
946
  var valueTransition = getValueTransition(transition, key) || {};
960
- return (_a = valueTransition.delay) !== null && _a !== void 0 ? _a : 0;
947
+ return (_b = (_a = valueTransition.delay) !== null && _a !== void 0 ? _a : transition.delay) !== null && _b !== void 0 ? _b : 0;
961
948
  }
962
949
  function hydrateKeyframes(options) {
963
950
  if (Array.isArray(options.to) && options.to[0] === null) {
@@ -1965,8 +1952,12 @@ function createProjectionNode(_a) {
1965
1952
  (_a = this.nodes) === null || _a === void 0 ? void 0 : _a.forEach(resetRotation);
1966
1953
  };
1967
1954
  ProjectionNode.prototype.willUpdate = function (shouldNotifyListeners) {
1968
- var _a;
1955
+ var _a, _b, _c;
1969
1956
  if (shouldNotifyListeners === void 0) { shouldNotifyListeners = true; }
1957
+ if (this.root.isUpdateBlocked()) {
1958
+ (_b = (_a = this.options).onExitComplete) === null || _b === void 0 ? void 0 : _b.call(_a);
1959
+ return;
1960
+ }
1970
1961
  !this.root.isUpdating && this.root.startUpdate();
1971
1962
  if (this.isLayoutDirty)
1972
1963
  return;
@@ -1980,10 +1971,10 @@ function createProjectionNode(_a) {
1980
1971
  */
1981
1972
  node.updateScroll();
1982
1973
  }
1983
- var _b = this.options, layoutId = _b.layoutId, layout = _b.layout;
1974
+ var _d = this.options, layoutId = _d.layoutId, layout = _d.layout;
1984
1975
  if (!layoutId && !layout)
1985
1976
  return;
1986
- var transformTemplate = (_a = this.options.visualElement) === null || _a === void 0 ? void 0 : _a.getProps().transformTemplate;
1977
+ var transformTemplate = (_c = this.options.visualElement) === null || _c === void 0 ? void 0 : _c.getProps().transformTemplate;
1987
1978
  this.prevTransformTemplateValue = transformTemplate === null || transformTemplate === void 0 ? void 0 : transformTemplate(this.latestValues, "");
1988
1979
  this.updateSnapshot();
1989
1980
  shouldNotifyListeners && this.notifyListeners("willUpdate");
@@ -2708,13 +2699,13 @@ function updateLayout(node) {
2708
2699
  node.updateLayout();
2709
2700
  }
2710
2701
  function notifyLayoutUpdate(node) {
2711
- var _a, _b;
2702
+ var _a, _b, _c, _d;
2712
2703
  var snapshot = (_b = (_a = node.resumeFrom) === null || _a === void 0 ? void 0 : _a.snapshot) !== null && _b !== void 0 ? _b : node.snapshot;
2713
2704
  if (node.isLead() &&
2714
2705
  node.layout &&
2715
2706
  snapshot &&
2716
2707
  node.hasListeners("didUpdate")) {
2717
- var _c = node.layout, layout_1 = _c.actual, measuredLayout = _c.measured;
2708
+ var _e = node.layout, layout_1 = _e.actual, measuredLayout = _e.measured;
2718
2709
  // TODO Maybe we want to also resize the layout snapshot so we don't trigger
2719
2710
  // animations for instance if layout="size" and an element has only changed position
2720
2711
  if (node.options.animationType === "size") {
@@ -2754,7 +2745,7 @@ function notifyLayoutUpdate(node) {
2754
2745
  * the relative snapshot is not relavent
2755
2746
  */
2756
2747
  if (node.relativeParent && !node.relativeParent.resumeFrom) {
2757
- var _d = node.relativeParent, parentSnapshot = _d.snapshot, parentLayout = _d.layout;
2748
+ var _f = node.relativeParent, parentSnapshot = _f.snapshot, parentLayout = _f.layout;
2758
2749
  if (parentSnapshot && parentLayout) {
2759
2750
  var relativeSnapshot = createBox();
2760
2751
  calcRelativePosition(relativeSnapshot, snapshot.layout, parentSnapshot.layout);
@@ -2775,6 +2766,9 @@ function notifyLayoutUpdate(node) {
2775
2766
  hasRelativeTargetChanged: hasRelativeTargetChanged,
2776
2767
  });
2777
2768
  }
2769
+ else if (node.isLead()) {
2770
+ (_d = (_c = node.options).onExitComplete) === null || _d === void 0 ? void 0 : _d.call(_c);
2771
+ }
2778
2772
  /**
2779
2773
  * Clearing transition
2780
2774
  * TODO: Investigate why this transition is being passed in as {type: false } from Framer
@@ -2951,11 +2945,7 @@ function createMotionComponent(_a) {
2951
2945
  */
2952
2946
  var config = React.useContext(MotionConfigContext);
2953
2947
  var features = null;
2954
- /**
2955
- * Create the tree context. This is memoized and will only trigger renders
2956
- * when the current tree variant changes in static mode.
2957
- */
2958
- var context = useCreateMotionContext(props, config.isStatic);
2948
+ var context = useCreateMotionContext(props);
2959
2949
  /**
2960
2950
  * Create a unique projection ID for this component. If a new component is added
2961
2951
  * during a layout animation we'll use this to query the DOM and hydrate its ref early, allowing
@@ -4275,7 +4265,7 @@ function getOrigin(target, transition, visualElement) {
4275
4265
  */
4276
4266
  function animateVisualElement(visualElement, definition, options) {
4277
4267
  if (options === void 0) { options = {}; }
4278
- visualElement.notifyAnimationStart();
4268
+ visualElement.notifyAnimationStart(definition);
4279
4269
  var animation;
4280
4270
  if (Array.isArray(definition)) {
4281
4271
  var animations = definition.map(function (variant) {
@@ -6145,24 +6135,26 @@ var BoundingBoxDimension;
6145
6135
  var getPosFromMatrix = function (matrix, pos) {
6146
6136
  return parseFloat(matrix.split(", ")[pos]);
6147
6137
  };
6148
- var getTranslateFromMatrix = function (pos2, pos3) { return function (_bbox, _a) {
6149
- var transform = _a.transform;
6150
- if (transform === "none" || !transform)
6151
- return 0;
6152
- var matrix3d = transform.match(/^matrix3d\((.+)\)$/);
6153
- if (matrix3d) {
6154
- return getPosFromMatrix(matrix3d[1], pos3);
6155
- }
6156
- else {
6157
- var matrix = transform.match(/^matrix\((.+)\)$/);
6158
- if (matrix) {
6159
- return getPosFromMatrix(matrix[1], pos2);
6138
+ var getTranslateFromMatrix = function (pos2, pos3) {
6139
+ return function (_bbox, _a) {
6140
+ var transform = _a.transform;
6141
+ if (transform === "none" || !transform)
6142
+ return 0;
6143
+ var matrix3d = transform.match(/^matrix3d\((.+)\)$/);
6144
+ if (matrix3d) {
6145
+ return getPosFromMatrix(matrix3d[1], pos3);
6160
6146
  }
6161
6147
  else {
6162
- return 0;
6148
+ var matrix = transform.match(/^matrix\((.+)\)$/);
6149
+ if (matrix) {
6150
+ return getPosFromMatrix(matrix[1], pos2);
6151
+ }
6152
+ else {
6153
+ return 0;
6154
+ }
6163
6155
  }
6164
- }
6165
- }; };
6156
+ };
6157
+ };
6166
6158
  var transformKeys = new Set(["x", "y", "z"]);
6167
6159
  var nonTranslationalTransformKeys = transformProps.filter(function (key) { return !transformKeys.has(key); });
6168
6160
  function removeNonTranslationalTransform(visualElement) {
@@ -6250,8 +6242,8 @@ var checkAndConvertChangedValueTypes = function (visualElement, target, origin,
6250
6242
  if (!visualElement.hasValue(key))
6251
6243
  return;
6252
6244
  var from = origin[key];
6253
- var to = target[key];
6254
6245
  var fromType = findDimensionValueType(from);
6246
+ var to = target[key];
6255
6247
  var toType;
6256
6248
  // TODO: The current implementation of this basically throws an error
6257
6249
  // if you try and do value conversion via keyframes. There's probably
@@ -6259,7 +6251,10 @@ var checkAndConvertChangedValueTypes = function (visualElement, target, origin,
6259
6251
  // as it'd be doing multiple resize-remeasure operations.
6260
6252
  if (isKeyframesTarget(to)) {
6261
6253
  var numKeyframes = to.length;
6262
- for (var i = to[0] === null ? 1 : 0; i < numKeyframes; i++) {
6254
+ var fromIndex = to[0] === null ? 1 : 0;
6255
+ from = to[fromIndex];
6256
+ fromType = findDimensionValueType(from);
6257
+ for (var i = fromIndex; i < numKeyframes; i++) {
6263
6258
  if (!toType) {
6264
6259
  toType = findDimensionValueType(to[i]);
6265
6260
  heyListen.invariant(toType === fromType ||
@@ -6304,7 +6299,8 @@ var checkAndConvertChangedValueTypes = function (visualElement, target, origin,
6304
6299
  // If we're going to do value conversion via DOM measurements, we first
6305
6300
  // need to remove non-positional transform values that could affect the bbox measurements.
6306
6301
  if (!hasAttemptedToRemoveTransformValues) {
6307
- removedTransformValues = removeNonTranslationalTransform(visualElement);
6302
+ removedTransformValues =
6303
+ removeNonTranslationalTransform(visualElement);
6308
6304
  hasAttemptedToRemoveTransformValues = true;
6309
6305
  }
6310
6306
  changedValueTypeKeys.push(key);
@@ -6594,6 +6590,7 @@ var MeasureLayoutWithContext = /** @class */ (function (_super) {
6594
6590
  globalProjectionState.hasEverUpdated = true;
6595
6591
  };
6596
6592
  MeasureLayoutWithContext.prototype.getSnapshotBeforeUpdate = function (prevProps) {
6593
+ var _this = this;
6597
6594
  var _a = this.props, layoutDependency = _a.layoutDependency, visualElement = _a.visualElement, drag = _a.drag, isPresent = _a.isPresent;
6598
6595
  var projection = visualElement.projection;
6599
6596
  if (!projection)
@@ -6611,12 +6608,25 @@ var MeasureLayoutWithContext = /** @class */ (function (_super) {
6611
6608
  layoutDependency === undefined) {
6612
6609
  projection.willUpdate();
6613
6610
  }
6611
+ else {
6612
+ this.safeToRemove();
6613
+ }
6614
6614
  if (prevProps.isPresent !== isPresent) {
6615
6615
  if (isPresent) {
6616
6616
  projection.promote();
6617
6617
  }
6618
- else {
6619
- projection.relegate();
6618
+ else if (!projection.relegate()) {
6619
+ /**
6620
+ * If there's another stack member taking over from this one,
6621
+ * it's in charge of the exit animation and therefore should
6622
+ * be in charge of the safe to remove. Otherwise we call it here.
6623
+ */
6624
+ sync__default['default'].postRender(function () {
6625
+ var _a;
6626
+ if (!((_a = projection.getStack()) === null || _a === void 0 ? void 0 : _a.members.length)) {
6627
+ _this.safeToRemove();
6628
+ }
6629
+ });
6620
6630
  }
6621
6631
  }
6622
6632
  return null;
@@ -6880,6 +6890,10 @@ var AnimatePresence = function (_a) {
6880
6890
  if (forceRenderLayoutGroup)
6881
6891
  forceRender = forceRenderLayoutGroup;
6882
6892
  var isInitialRender = React.useRef(true);
6893
+ var isMounted = React.useRef(true);
6894
+ React.useEffect(function () { return function () {
6895
+ isMounted.current = false;
6896
+ }; }, []);
6883
6897
  // Filter out any children that aren't ReactElements. We can only track ReactElements with a props.key
6884
6898
  var filteredChildren = onlyElements(children);
6885
6899
  // Keep a living record of the children we're actually rendering so we
@@ -6938,6 +6952,9 @@ var AnimatePresence = function (_a) {
6938
6952
  // Defer re-rendering until all exiting children have indeed left
6939
6953
  if (!exiting.size) {
6940
6954
  presentChildren.current = filteredChildren;
6955
+ if (isMounted.current === false) {
6956
+ return;
6957
+ }
6941
6958
  forceRender();
6942
6959
  onExitComplete && onExitComplete();
6943
6960
  }