framer-motion 6.2.1 → 6.2.6

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/dist/cjs/index.js CHANGED
@@ -1897,9 +1897,6 @@ function createProjectionNode(_a) {
1897
1897
  };
1898
1898
  this.hasProjected = false;
1899
1899
  this.isVisible = true;
1900
- /**
1901
- * Animation
1902
- */
1903
1900
  this.animationProgress = 0;
1904
1901
  /**
1905
1902
  * Shared layout
@@ -2024,6 +2021,15 @@ function createProjectionNode(_a) {
2024
2021
  _this.startAnimation(animationOptions);
2025
2022
  }
2026
2023
  else {
2024
+ /**
2025
+ * If the layout hasn't changed and we have an animation that hasn't started yet,
2026
+ * finish it immediately. Otherwise it will be animating from a location
2027
+ * that was probably never commited to screen and look like a jumpy box.
2028
+ */
2029
+ if (!hasLayoutChanged &&
2030
+ _this.animationProgress === 0) {
2031
+ _this.finishAnimation();
2032
+ }
2027
2033
  _this.isLead() && ((_f = (_e = _this.options).onExitComplete) === null || _f === void 0 ? void 0 : _f.call(_e));
2028
2034
  }
2029
2035
  _this.targetLayout = newLayout;
@@ -2513,6 +2519,7 @@ function createProjectionNode(_a) {
2513
2519
  !isOnlyMember &&
2514
2520
  this.options.crossfade === true &&
2515
2521
  !this.path.some(hasOpacityCrossfade));
2522
+ this.animationProgress = 0;
2516
2523
  this.mixTargetDelta = function (latest) {
2517
2524
  var _a;
2518
2525
  var progress = latest / 1000;
@@ -2532,6 +2539,7 @@ function createProjectionNode(_a) {
2532
2539
  }
2533
2540
  _this.root.scheduleUpdateProjection();
2534
2541
  _this.scheduleRender();
2542
+ _this.animationProgress = progress;
2535
2543
  };
2536
2544
  this.mixTargetDelta(0);
2537
2545
  };
@@ -2897,6 +2905,10 @@ function clearMeasurements(node) {
2897
2905
  node.clearMeasurements();
2898
2906
  }
2899
2907
  function resetTransformStyle(node) {
2908
+ var visualElement = node.options.visualElement;
2909
+ if (visualElement === null || visualElement === void 0 ? void 0 : visualElement.getProps().onBeforeLayoutMeasure) {
2910
+ visualElement.notifyBeforeLayoutMeasure();
2911
+ }
2900
2912
  node.resetTransform();
2901
2913
  }
2902
2914
  function finishAnimation(node) {
@@ -4337,6 +4349,18 @@ var gestureAnimations = {
4337
4349
  hover: makeRenderlessComponent(useHoverGesture),
4338
4350
  };
4339
4351
 
4352
+ var counter = 0;
4353
+ var incrementId = function () { return counter++; };
4354
+ var useId = function () { return useConstant(incrementId); };
4355
+ /**
4356
+ * Ideally we'd use the following code to support React 18 optionally.
4357
+ * But this fairly fails in Webpack (otherwise treeshaking wouldn't work at all).
4358
+ * Need to come up with a different way of figuring this out.
4359
+ */
4360
+ // export const useId = (React as any).useId
4361
+ // ? (React as any).useId
4362
+ // : () => useConstant(incrementId)
4363
+
4340
4364
  /**
4341
4365
  * When a component is the child of `AnimatePresence`, it can use `usePresence`
4342
4366
  * to access information about whether it's still present in the React tree.
@@ -4367,8 +4391,8 @@ function usePresence() {
4367
4391
  var isPresent = context.isPresent, onExitComplete = context.onExitComplete, register = context.register;
4368
4392
  // It's safe to call the following hooks conditionally (after an early return) because the context will always
4369
4393
  // either be null or non-null for the lifespan of the component.
4370
- // Replace with useOpaqueId when released in React
4371
- var id = useUniqueId();
4394
+ // Replace with useId when released in React
4395
+ var id = useId();
4372
4396
  React.useEffect(function () { return register(id); }, []);
4373
4397
  var safeToRemove = function () { return onExitComplete === null || onExitComplete === void 0 ? void 0 : onExitComplete(id); };
4374
4398
  return !isPresent && onExitComplete ? [false, safeToRemove] : [true];
@@ -4399,9 +4423,6 @@ function useIsPresent() {
4399
4423
  function isPresent(context) {
4400
4424
  return context === null ? true : context.isPresent;
4401
4425
  }
4402
- var counter = 0;
4403
- var incrementId = function () { return counter++; };
4404
- var useUniqueId = function () { return useConstant(incrementId); };
4405
4426
 
4406
4427
  function shallowCompare(next, prev) {
4407
4428
  if (!Array.isArray(prev))
@@ -5903,7 +5924,7 @@ function createLifecycles() {
5903
5924
  for (var _i = 0; _i < arguments.length; _i++) {
5904
5925
  args[_i] = arguments[_i];
5905
5926
  }
5906
- manager.notify.apply(manager, tslib.__spreadArray([], tslib.__read(args), false));
5927
+ return manager.notify.apply(manager, tslib.__spreadArray([], tslib.__read(args), false));
5907
5928
  };
5908
5929
  });
5909
5930
  return lifecycles;
@@ -6106,6 +6127,7 @@ var visualElement = function (_a) {
6106
6127
  if (isVariantNode && parent && !isControllingVariants) {
6107
6128
  removeFromVariantTree = parent === null || parent === void 0 ? void 0 : parent.addVariantChild(element);
6108
6129
  }
6130
+ values.forEach(function (value, key) { return bindToMotionValue(key, value); });
6109
6131
  parent === null || parent === void 0 ? void 0 : parent.children.add(element);
6110
6132
  element.setProps(props);
6111
6133
  },
@@ -7086,12 +7108,22 @@ function createDomMotionComponent(key) {
7086
7108
  */
7087
7109
  var m = createMotionProxy(createDomMotionConfig);
7088
7110
 
7111
+ function useIsMounted() {
7112
+ var isMounted = React.useRef(false);
7113
+ React.useLayoutEffect(function () {
7114
+ isMounted.current = true;
7115
+ return function () {
7116
+ isMounted.current = false;
7117
+ };
7118
+ }, []);
7119
+ return isMounted;
7120
+ }
7121
+
7089
7122
  function useForceUpdate() {
7090
- var isUnmountingRef = React.useRef(false);
7123
+ var isMounted = useIsMounted();
7091
7124
  var _a = tslib.__read(React.useState(0), 2), forcedRenderCount = _a[0], setForcedRenderCount = _a[1];
7092
- useUnmountEffect(function () { return (isUnmountingRef.current = true); });
7093
7125
  var forceRender = React.useCallback(function () {
7094
- !isUnmountingRef.current && setForcedRenderCount(forcedRenderCount + 1);
7126
+ isMounted.current && setForcedRenderCount(forcedRenderCount + 1);
7095
7127
  }, [forcedRenderCount]);
7096
7128
  /**
7097
7129
  * Defer this to the end of the next animation frame in case there are multiple
@@ -7101,16 +7133,10 @@ function useForceUpdate() {
7101
7133
  return [deferredForceRender, forcedRenderCount];
7102
7134
  }
7103
7135
 
7104
- var presenceId = 0;
7105
- function getPresenceId() {
7106
- var id = presenceId;
7107
- presenceId++;
7108
- return id;
7109
- }
7110
7136
  var PresenceChild = function (_a) {
7111
7137
  var children = _a.children, initial = _a.initial, isPresent = _a.isPresent, onExitComplete = _a.onExitComplete, custom = _a.custom, presenceAffectsLayout = _a.presenceAffectsLayout;
7112
7138
  var presenceChildren = useConstant(newChildrenMap);
7113
- var id = useConstant(getPresenceId);
7139
+ var id = useId();
7114
7140
  var context = React.useMemo(function () { return ({
7115
7141
  id: id,
7116
7142
  initial: initial,
@@ -7162,17 +7188,14 @@ function newChildrenMap() {
7162
7188
  return new Map();
7163
7189
  }
7164
7190
 
7165
- function getChildKey(child) {
7166
- return child.key || "";
7167
- }
7191
+ var getChildKey = function (child) { return child.key || ""; };
7192
+ var isDev = process.env.NODE_ENV !== "production";
7168
7193
  function updateChildLookup(children, allChildren) {
7169
- var seenChildren = process.env.NODE_ENV !== "production" ? new Set() : null;
7194
+ var seenChildren = isDev ? new Set() : null;
7170
7195
  children.forEach(function (child) {
7171
7196
  var key = getChildKey(child);
7172
- if (process.env.NODE_ENV !== "production" && seenChildren) {
7173
- if (seenChildren.has(key)) {
7174
- console.warn("Children of AnimatePresence require unique keys. \"".concat(key, "\" is a duplicate."));
7175
- }
7197
+ if (isDev && seenChildren && seenChildren.has(key)) {
7198
+ console.warn("Children of AnimatePresence require unique keys. \"".concat(key, "\" is a duplicate."));
7176
7199
  seenChildren.add(key);
7177
7200
  }
7178
7201
  allChildren.set(key, child);
@@ -7228,29 +7251,34 @@ var AnimatePresence = function (_a) {
7228
7251
  var forceRenderLayoutGroup = React.useContext(LayoutGroupContext).forceRender;
7229
7252
  if (forceRenderLayoutGroup)
7230
7253
  forceRender = forceRenderLayoutGroup;
7231
- var isInitialRender = React.useRef(true);
7232
- var isMounted = React.useRef(true);
7233
- React.useEffect(function () { return function () {
7234
- isMounted.current = false;
7235
- }; }, []);
7254
+ var isMounted = useIsMounted();
7236
7255
  // Filter out any children that aren't ReactElements. We can only track ReactElements with a props.key
7237
7256
  var filteredChildren = onlyElements(children);
7257
+ var childrenToRender = filteredChildren;
7258
+ var exiting = new Set();
7238
7259
  // Keep a living record of the children we're actually rendering so we
7239
7260
  // can diff to figure out which are entering and exiting
7240
- var presentChildren = React.useRef(filteredChildren);
7261
+ var presentChildren = React.useRef(childrenToRender);
7241
7262
  // A lookup table to quickly reference components by key
7242
7263
  var allChildren = React.useRef(new Map()).current;
7243
- // A living record of all currently exiting components.
7244
- var exiting = React.useRef(new Set()).current;
7245
- updateChildLookup(filteredChildren, allChildren);
7246
7264
  // If this is the initial component render, just deal with logic surrounding whether
7247
7265
  // we play onMount animations or not.
7248
- if (isInitialRender.current) {
7266
+ var isInitialRender = React.useRef(true);
7267
+ useIsomorphicLayoutEffect(function () {
7249
7268
  isInitialRender.current = false;
7250
- return (React__namespace.createElement(React__namespace.Fragment, null, filteredChildren.map(function (child) { return (React__namespace.createElement(PresenceChild, { key: getChildKey(child), isPresent: true, initial: initial ? undefined : false, presenceAffectsLayout: presenceAffectsLayout }, child)); })));
7269
+ updateChildLookup(filteredChildren, allChildren);
7270
+ presentChildren.current = childrenToRender;
7271
+ });
7272
+ useUnmountEffect(function () {
7273
+ isInitialRender.current = true;
7274
+ allChildren.clear();
7275
+ exiting.clear();
7276
+ });
7277
+ if (isInitialRender.current) {
7278
+ return (React__namespace.createElement(React__namespace.Fragment, null, childrenToRender.map(function (child) { return (React__namespace.createElement(PresenceChild, { key: getChildKey(child), isPresent: true, initial: initial ? undefined : false, presenceAffectsLayout: presenceAffectsLayout }, child)); })));
7251
7279
  }
7252
7280
  // If this is a subsequent render, deal with entering and exiting children
7253
- var childrenToRender = tslib.__spreadArray([], tslib.__read(filteredChildren), false);
7281
+ childrenToRender = tslib.__spreadArray([], tslib.__read(childrenToRender), false);
7254
7282
  // Diff the keys of the currently-present and target children to update our
7255
7283
  // exiting list.
7256
7284
  var presentKeys = presentChildren.current.map(getChildKey);
@@ -7262,10 +7290,6 @@ var AnimatePresence = function (_a) {
7262
7290
  if (targetKeys.indexOf(key) === -1) {
7263
7291
  exiting.add(key);
7264
7292
  }
7265
- else {
7266
- // In case this key has re-entered, remove from the exiting list
7267
- exiting.delete(key);
7268
- }
7269
7293
  }
7270
7294
  // If we currently have exiting children, and we're deferring rendering incoming children
7271
7295
  // until after all current children have exiting, empty the childrenToRender array
@@ -7291,9 +7315,8 @@ var AnimatePresence = function (_a) {
7291
7315
  // Defer re-rendering until all exiting children have indeed left
7292
7316
  if (!exiting.size) {
7293
7317
  presentChildren.current = filteredChildren;
7294
- if (isMounted.current === false) {
7318
+ if (isMounted.current === false)
7295
7319
  return;
7296
- }
7297
7320
  forceRender();
7298
7321
  onExitComplete && onExitComplete();
7299
7322
  }
@@ -7306,7 +7329,6 @@ var AnimatePresence = function (_a) {
7306
7329
  var key = child.key;
7307
7330
  return exiting.has(key) ? (child) : (React__namespace.createElement(PresenceChild, { key: getChildKey(child), isPresent: true, presenceAffectsLayout: presenceAffectsLayout }, child));
7308
7331
  });
7309
- presentChildren.current = childrenToRender;
7310
7332
  if (process.env.NODE_ENV !== "production" &&
7311
7333
  exitBeforeEnter &&
7312
7334
  childrenToRender.length > 1) {
@@ -8277,13 +8299,15 @@ function useAnimatedState(initialState) {
8277
8299
  });
8278
8300
  React.useEffect(function () {
8279
8301
  element.mount({});
8280
- return element.unmount();
8281
- }, []);
8302
+ return element.unmount;
8303
+ }, [element]);
8282
8304
  React.useEffect(function () {
8283
8305
  element.setProps({
8284
- onUpdate: function (v) { return setAnimationState(tslib.__assign({}, v)); },
8306
+ onUpdate: function (v) {
8307
+ setAnimationState(tslib.__assign({}, v));
8308
+ },
8285
8309
  });
8286
- });
8310
+ }, [setAnimationState, element]);
8287
8311
  var startAnimation = useConstant(function () { return function (animationDefinition) {
8288
8312
  return animateVisualElement(element, animationDefinition);
8289
8313
  }; });
@@ -8394,6 +8418,7 @@ exports.useMotionTemplate = useMotionTemplate;
8394
8418
  exports.useMotionValue = useMotionValue;
8395
8419
  exports.usePresence = usePresence;
8396
8420
  exports.useReducedMotion = useReducedMotion;
8421
+ exports.useReducedMotionConfig = useReducedMotionConfig;
8397
8422
  exports.useResetProjection = useResetProjection;
8398
8423
  exports.useSpring = useSpring;
8399
8424
  exports.useTime = useTime;
@@ -43,13 +43,15 @@ function useAnimatedState(initialState) {
43
43
  });
44
44
  useEffect(function () {
45
45
  element.mount({});
46
- return element.unmount();
47
- }, []);
46
+ return element.unmount;
47
+ }, [element]);
48
48
  useEffect(function () {
49
49
  element.setProps({
50
- onUpdate: function (v) { return setAnimationState(__assign({}, v)); },
50
+ onUpdate: function (v) {
51
+ setAnimationState(__assign({}, v));
52
+ },
51
53
  });
52
- });
54
+ }, [setAnimationState, element]);
53
55
  var startAnimation = useConstant(function () { return function (animationDefinition) {
54
56
  return animateVisualElement(element, animationDefinition);
55
57
  }; });
@@ -3,17 +3,12 @@ import * as React from 'react';
3
3
  import { useMemo } from 'react';
4
4
  import { PresenceContext } from '../../context/PresenceContext.mjs';
5
5
  import { useConstant } from '../../utils/use-constant.mjs';
6
+ import { useId } from '../../utils/use-id.mjs';
6
7
 
7
- var presenceId = 0;
8
- function getPresenceId() {
9
- var id = presenceId;
10
- presenceId++;
11
- return id;
12
- }
13
8
  var PresenceChild = function (_a) {
14
9
  var children = _a.children, initial = _a.initial, isPresent = _a.isPresent, onExitComplete = _a.onExitComplete, custom = _a.custom, presenceAffectsLayout = _a.presenceAffectsLayout;
15
10
  var presenceChildren = useConstant(newChildrenMap);
16
- var id = useConstant(getPresenceId);
11
+ var id = useId();
17
12
  var context = useMemo(function () { return ({
18
13
  id: id,
19
14
  initial: initial,
@@ -1,21 +1,21 @@
1
1
  import { __read, __spreadArray } from 'tslib';
2
2
  import * as React from 'react';
3
- import { useContext, useRef, useEffect, cloneElement, Children, isValidElement } from 'react';
3
+ import { useContext, useRef, cloneElement, Children, isValidElement } from 'react';
4
4
  import { useForceUpdate } from '../../utils/use-force-update.mjs';
5
+ import { useIsMounted } from '../../utils/use-is-mounted.mjs';
5
6
  import { PresenceChild } from './PresenceChild.mjs';
6
7
  import { LayoutGroupContext } from '../../context/LayoutGroupContext.mjs';
8
+ import { useIsomorphicLayoutEffect } from '../../utils/use-isomorphic-effect.mjs';
9
+ import { useUnmountEffect } from '../../utils/use-unmount-effect.mjs';
7
10
 
8
- function getChildKey(child) {
9
- return child.key || "";
10
- }
11
+ var getChildKey = function (child) { return child.key || ""; };
12
+ var isDev = process.env.NODE_ENV !== "production";
11
13
  function updateChildLookup(children, allChildren) {
12
- var seenChildren = process.env.NODE_ENV !== "production" ? new Set() : null;
14
+ var seenChildren = isDev ? new Set() : null;
13
15
  children.forEach(function (child) {
14
16
  var key = getChildKey(child);
15
- if (process.env.NODE_ENV !== "production" && seenChildren) {
16
- if (seenChildren.has(key)) {
17
- console.warn("Children of AnimatePresence require unique keys. \"".concat(key, "\" is a duplicate."));
18
- }
17
+ if (isDev && seenChildren && seenChildren.has(key)) {
18
+ console.warn("Children of AnimatePresence require unique keys. \"".concat(key, "\" is a duplicate."));
19
19
  seenChildren.add(key);
20
20
  }
21
21
  allChildren.set(key, child);
@@ -71,29 +71,34 @@ var AnimatePresence = function (_a) {
71
71
  var forceRenderLayoutGroup = useContext(LayoutGroupContext).forceRender;
72
72
  if (forceRenderLayoutGroup)
73
73
  forceRender = forceRenderLayoutGroup;
74
- var isInitialRender = useRef(true);
75
- var isMounted = useRef(true);
76
- useEffect(function () { return function () {
77
- isMounted.current = false;
78
- }; }, []);
74
+ var isMounted = useIsMounted();
79
75
  // Filter out any children that aren't ReactElements. We can only track ReactElements with a props.key
80
76
  var filteredChildren = onlyElements(children);
77
+ var childrenToRender = filteredChildren;
78
+ var exiting = new Set();
81
79
  // Keep a living record of the children we're actually rendering so we
82
80
  // can diff to figure out which are entering and exiting
83
- var presentChildren = useRef(filteredChildren);
81
+ var presentChildren = useRef(childrenToRender);
84
82
  // A lookup table to quickly reference components by key
85
83
  var allChildren = useRef(new Map()).current;
86
- // A living record of all currently exiting components.
87
- var exiting = useRef(new Set()).current;
88
- updateChildLookup(filteredChildren, allChildren);
89
84
  // If this is the initial component render, just deal with logic surrounding whether
90
85
  // we play onMount animations or not.
91
- if (isInitialRender.current) {
86
+ var isInitialRender = useRef(true);
87
+ useIsomorphicLayoutEffect(function () {
92
88
  isInitialRender.current = false;
93
- return (React.createElement(React.Fragment, null, filteredChildren.map(function (child) { return (React.createElement(PresenceChild, { key: getChildKey(child), isPresent: true, initial: initial ? undefined : false, presenceAffectsLayout: presenceAffectsLayout }, child)); })));
89
+ updateChildLookup(filteredChildren, allChildren);
90
+ presentChildren.current = childrenToRender;
91
+ });
92
+ useUnmountEffect(function () {
93
+ isInitialRender.current = true;
94
+ allChildren.clear();
95
+ exiting.clear();
96
+ });
97
+ if (isInitialRender.current) {
98
+ return (React.createElement(React.Fragment, null, childrenToRender.map(function (child) { return (React.createElement(PresenceChild, { key: getChildKey(child), isPresent: true, initial: initial ? undefined : false, presenceAffectsLayout: presenceAffectsLayout }, child)); })));
94
99
  }
95
100
  // If this is a subsequent render, deal with entering and exiting children
96
- var childrenToRender = __spreadArray([], __read(filteredChildren), false);
101
+ childrenToRender = __spreadArray([], __read(childrenToRender), false);
97
102
  // Diff the keys of the currently-present and target children to update our
98
103
  // exiting list.
99
104
  var presentKeys = presentChildren.current.map(getChildKey);
@@ -105,10 +110,6 @@ var AnimatePresence = function (_a) {
105
110
  if (targetKeys.indexOf(key) === -1) {
106
111
  exiting.add(key);
107
112
  }
108
- else {
109
- // In case this key has re-entered, remove from the exiting list
110
- exiting.delete(key);
111
- }
112
113
  }
113
114
  // If we currently have exiting children, and we're deferring rendering incoming children
114
115
  // until after all current children have exiting, empty the childrenToRender array
@@ -134,9 +135,8 @@ var AnimatePresence = function (_a) {
134
135
  // Defer re-rendering until all exiting children have indeed left
135
136
  if (!exiting.size) {
136
137
  presentChildren.current = filteredChildren;
137
- if (isMounted.current === false) {
138
+ if (isMounted.current === false)
138
139
  return;
139
- }
140
140
  forceRender();
141
141
  onExitComplete && onExitComplete();
142
142
  }
@@ -149,7 +149,6 @@ var AnimatePresence = function (_a) {
149
149
  var key = child.key;
150
150
  return exiting.has(key) ? (child) : (React.createElement(PresenceChild, { key: getChildKey(child), isPresent: true, presenceAffectsLayout: presenceAffectsLayout }, child));
151
151
  });
152
- presentChildren.current = childrenToRender;
153
152
  if (process.env.NODE_ENV !== "production" &&
154
153
  exitBeforeEnter &&
155
154
  childrenToRender.length > 1) {
@@ -1,6 +1,6 @@
1
1
  import { useContext, useEffect } from 'react';
2
2
  import { PresenceContext } from '../../context/PresenceContext.mjs';
3
- import { useConstant } from '../../utils/use-constant.mjs';
3
+ import { useId } from '../../utils/use-id.mjs';
4
4
 
5
5
  /**
6
6
  * When a component is the child of `AnimatePresence`, it can use `usePresence`
@@ -32,8 +32,8 @@ function usePresence() {
32
32
  var isPresent = context.isPresent, onExitComplete = context.onExitComplete, register = context.register;
33
33
  // It's safe to call the following hooks conditionally (after an early return) because the context will always
34
34
  // either be null or non-null for the lifespan of the component.
35
- // Replace with useOpaqueId when released in React
36
- var id = useUniqueId();
35
+ // Replace with useId when released in React
36
+ var id = useId();
37
37
  useEffect(function () { return register(id); }, []);
38
38
  var safeToRemove = function () { return onExitComplete === null || onExitComplete === void 0 ? void 0 : onExitComplete(id); };
39
39
  return !isPresent && onExitComplete ? [false, safeToRemove] : [true];
@@ -64,8 +64,5 @@ function useIsPresent() {
64
64
  function isPresent(context) {
65
65
  return context === null ? true : context.isPresent;
66
66
  }
67
- var counter = 0;
68
- var incrementId = function () { return counter++; };
69
- var useUniqueId = function () { return useConstant(incrementId); };
70
67
 
71
68
  export { isPresent, useIsPresent, usePresence };
package/dist/es/index.mjs CHANGED
@@ -18,7 +18,7 @@ export { useVelocity } from './value/use-velocity.mjs';
18
18
  export { useElementScroll } from './value/scroll/use-element-scroll.mjs';
19
19
  export { useViewportScroll } from './value/scroll/use-viewport-scroll.mjs';
20
20
  export { useTime } from './value/use-time.mjs';
21
- export { useReducedMotion } from './utils/use-reduced-motion.mjs';
21
+ export { useReducedMotion, useReducedMotionConfig } from './utils/use-reduced-motion.mjs';
22
22
  export { animationControls } from './animation/animation-controls.mjs';
23
23
  export { useAnimation } from './animation/use-animation.mjs';
24
24
  export { useAnimationFrame } from './utils/use-animation-frame.mjs';
@@ -125,9 +125,6 @@ function createProjectionNode(_a) {
125
125
  };
126
126
  this.hasProjected = false;
127
127
  this.isVisible = true;
128
- /**
129
- * Animation
130
- */
131
128
  this.animationProgress = 0;
132
129
  /**
133
130
  * Shared layout
@@ -252,6 +249,15 @@ function createProjectionNode(_a) {
252
249
  _this.startAnimation(animationOptions);
253
250
  }
254
251
  else {
252
+ /**
253
+ * If the layout hasn't changed and we have an animation that hasn't started yet,
254
+ * finish it immediately. Otherwise it will be animating from a location
255
+ * that was probably never commited to screen and look like a jumpy box.
256
+ */
257
+ if (!hasLayoutChanged &&
258
+ _this.animationProgress === 0) {
259
+ _this.finishAnimation();
260
+ }
255
261
  _this.isLead() && ((_f = (_e = _this.options).onExitComplete) === null || _f === void 0 ? void 0 : _f.call(_e));
256
262
  }
257
263
  _this.targetLayout = newLayout;
@@ -741,6 +747,7 @@ function createProjectionNode(_a) {
741
747
  !isOnlyMember &&
742
748
  this.options.crossfade === true &&
743
749
  !this.path.some(hasOpacityCrossfade));
750
+ this.animationProgress = 0;
744
751
  this.mixTargetDelta = function (latest) {
745
752
  var _a;
746
753
  var progress = latest / 1000;
@@ -760,6 +767,7 @@ function createProjectionNode(_a) {
760
767
  }
761
768
  _this.root.scheduleUpdateProjection();
762
769
  _this.scheduleRender();
770
+ _this.animationProgress = progress;
763
771
  };
764
772
  this.mixTargetDelta(0);
765
773
  };
@@ -1125,6 +1133,10 @@ function clearMeasurements(node) {
1125
1133
  node.clearMeasurements();
1126
1134
  }
1127
1135
  function resetTransformStyle(node) {
1136
+ var visualElement = node.options.visualElement;
1137
+ if (visualElement === null || visualElement === void 0 ? void 0 : visualElement.getProps().onBeforeLayoutMeasure) {
1138
+ visualElement.notifyBeforeLayoutMeasure();
1139
+ }
1128
1140
  node.resetTransform();
1129
1141
  }
1130
1142
  function finishAnimation(node) {
@@ -161,6 +161,7 @@ var visualElement = function (_a) {
161
161
  if (isVariantNode && parent && !isControllingVariants) {
162
162
  removeFromVariantTree = parent === null || parent === void 0 ? void 0 : parent.addVariantChild(element);
163
163
  }
164
+ values.forEach(function (value, key) { return bindToMotionValue(key, value); });
164
165
  parent === null || parent === void 0 ? void 0 : parent.children.add(element);
165
166
  element.setProps(props);
166
167
  },
@@ -40,7 +40,7 @@ function createLifecycles() {
40
40
  for (var _i = 0; _i < arguments.length; _i++) {
41
41
  args[_i] = arguments[_i];
42
42
  }
43
- manager.notify.apply(manager, __spreadArray([], __read(args), false));
43
+ return manager.notify.apply(manager, __spreadArray([], __read(args), false));
44
44
  };
45
45
  });
46
46
  return lifecycles;
@@ -1,14 +1,13 @@
1
1
  import { __read } from 'tslib';
2
2
  import sync from 'framesync';
3
- import { useRef, useState, useCallback } from 'react';
4
- import { useUnmountEffect } from './use-unmount-effect.mjs';
3
+ import { useState, useCallback } from 'react';
4
+ import { useIsMounted } from './use-is-mounted.mjs';
5
5
 
6
6
  function useForceUpdate() {
7
- var isUnmountingRef = useRef(false);
7
+ var isMounted = useIsMounted();
8
8
  var _a = __read(useState(0), 2), forcedRenderCount = _a[0], setForcedRenderCount = _a[1];
9
- useUnmountEffect(function () { return (isUnmountingRef.current = true); });
10
9
  var forceRender = useCallback(function () {
11
- !isUnmountingRef.current && setForcedRenderCount(forcedRenderCount + 1);
10
+ isMounted.current && setForcedRenderCount(forcedRenderCount + 1);
12
11
  }, [forcedRenderCount]);
13
12
  /**
14
13
  * Defer this to the end of the next animation frame in case there are multiple
@@ -0,0 +1,15 @@
1
+ import { useConstant } from './use-constant.mjs';
2
+
3
+ var counter = 0;
4
+ var incrementId = function () { return counter++; };
5
+ var useId = function () { return useConstant(incrementId); };
6
+ /**
7
+ * Ideally we'd use the following code to support React 18 optionally.
8
+ * But this fairly fails in Webpack (otherwise treeshaking wouldn't work at all).
9
+ * Need to come up with a different way of figuring this out.
10
+ */
11
+ // export const useId = (React as any).useId
12
+ // ? (React as any).useId
13
+ // : () => useConstant(incrementId)
14
+
15
+ export { useId };
@@ -0,0 +1,14 @@
1
+ import { useRef, useLayoutEffect } from 'react';
2
+
3
+ function useIsMounted() {
4
+ var isMounted = useRef(false);
5
+ useLayoutEffect(function () {
6
+ isMounted.current = true;
7
+ return function () {
8
+ isMounted.current = false;
9
+ };
10
+ }, []);
11
+ return isMounted;
12
+ }
13
+
14
+ export { useIsMounted };