framer-motion 6.2.0 → 6.2.5
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 +72 -51
- package/dist/es/animation/use-animated-state.mjs +6 -4
- package/dist/es/components/AnimatePresence/PresenceChild.mjs +2 -7
- package/dist/es/components/AnimatePresence/index.mjs +27 -28
- package/dist/es/components/AnimatePresence/use-presence.mjs +3 -6
- package/dist/es/index.mjs +1 -1
- package/dist/es/projection/node/create-projection-node.mjs +15 -3
- package/dist/es/render/index.mjs +1 -0
- package/dist/es/render/utils/lifecycles.mjs +1 -1
- package/dist/es/utils/use-force-update.mjs +4 -5
- package/dist/es/utils/use-id.mjs +10 -0
- package/dist/es/utils/use-is-mounted.mjs +14 -0
- package/dist/es/utils/use-reduced-motion.mjs +3 -1
- package/dist/framer-motion.dev.js +70 -50
- package/dist/framer-motion.js +1 -1
- package/dist/projection.dev.js +17 -4
- package/dist/size-rollup-dom-animation.js +1 -1
- package/dist/size-rollup-dom-max.js +1 -1
- package/dist/size-rollup-m.js +1 -1
- package/dist/size-webpack-dom-animation.js +1 -1
- package/dist/size-webpack-dom-max.js +1 -1
- package/dist/size-webpack-m.js +1 -1
- package/package.json +9 -5
- package/types/index.d.ts +1 -1
- package/types/projection/node/DocumentProjectionNode.d.ts +1 -1
- package/types/projection/node/HTMLProjectionNode.d.ts +1 -1
- package/types/projection/node/create-projection-node.d.ts +1 -1
- package/types/projection/node/types.d.ts +1 -1
- package/types/render/utils/lifecycles.d.ts +1 -1
- package/types/utils/use-id.d.ts +1 -0
- package/types/utils/use-is-mounted.d.ts +2 -0
package/dist/cjs/index.js
CHANGED
|
@@ -139,7 +139,9 @@ var useIsomorphicLayoutEffect = isBrowser ? React.useLayoutEffect : React.useEff
|
|
|
139
139
|
|
|
140
140
|
// Does this device prefer reduced motion? Returns `null` server-side.
|
|
141
141
|
var prefersReducedMotion = { current: null };
|
|
142
|
+
var hasDetected = false;
|
|
142
143
|
function initPrefersReducedMotion() {
|
|
144
|
+
hasDetected = true;
|
|
143
145
|
if (typeof window === "undefined")
|
|
144
146
|
return;
|
|
145
147
|
if (window.matchMedia) {
|
|
@@ -184,7 +186,7 @@ function useReducedMotion() {
|
|
|
184
186
|
/**
|
|
185
187
|
* Lazy initialisation of prefersReducedMotion
|
|
186
188
|
*/
|
|
187
|
-
!
|
|
189
|
+
!hasDetected && initPrefersReducedMotion();
|
|
188
190
|
var _a = tslib.__read(React.useState(prefersReducedMotion.current), 1), shouldReduceMotion = _a[0];
|
|
189
191
|
/**
|
|
190
192
|
* TODO See if people miss automatically updating shouldReduceMotion setting
|
|
@@ -1895,9 +1897,6 @@ function createProjectionNode(_a) {
|
|
|
1895
1897
|
};
|
|
1896
1898
|
this.hasProjected = false;
|
|
1897
1899
|
this.isVisible = true;
|
|
1898
|
-
/**
|
|
1899
|
-
* Animation
|
|
1900
|
-
*/
|
|
1901
1900
|
this.animationProgress = 0;
|
|
1902
1901
|
/**
|
|
1903
1902
|
* Shared layout
|
|
@@ -2022,6 +2021,15 @@ function createProjectionNode(_a) {
|
|
|
2022
2021
|
_this.startAnimation(animationOptions);
|
|
2023
2022
|
}
|
|
2024
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
|
+
}
|
|
2025
2033
|
_this.isLead() && ((_f = (_e = _this.options).onExitComplete) === null || _f === void 0 ? void 0 : _f.call(_e));
|
|
2026
2034
|
}
|
|
2027
2035
|
_this.targetLayout = newLayout;
|
|
@@ -2511,6 +2519,7 @@ function createProjectionNode(_a) {
|
|
|
2511
2519
|
!isOnlyMember &&
|
|
2512
2520
|
this.options.crossfade === true &&
|
|
2513
2521
|
!this.path.some(hasOpacityCrossfade));
|
|
2522
|
+
this.animationProgress = 0;
|
|
2514
2523
|
this.mixTargetDelta = function (latest) {
|
|
2515
2524
|
var _a;
|
|
2516
2525
|
var progress = latest / 1000;
|
|
@@ -2530,6 +2539,7 @@ function createProjectionNode(_a) {
|
|
|
2530
2539
|
}
|
|
2531
2540
|
_this.root.scheduleUpdateProjection();
|
|
2532
2541
|
_this.scheduleRender();
|
|
2542
|
+
_this.animationProgress = progress;
|
|
2533
2543
|
};
|
|
2534
2544
|
this.mixTargetDelta(0);
|
|
2535
2545
|
};
|
|
@@ -2895,6 +2905,10 @@ function clearMeasurements(node) {
|
|
|
2895
2905
|
node.clearMeasurements();
|
|
2896
2906
|
}
|
|
2897
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
|
+
}
|
|
2898
2912
|
node.resetTransform();
|
|
2899
2913
|
}
|
|
2900
2914
|
function finishAnimation(node) {
|
|
@@ -4335,6 +4349,12 @@ var gestureAnimations = {
|
|
|
4335
4349
|
hover: makeRenderlessComponent(useHoverGesture),
|
|
4336
4350
|
};
|
|
4337
4351
|
|
|
4352
|
+
var counter = 0;
|
|
4353
|
+
var incrementId = function () { return counter++; };
|
|
4354
|
+
var useId = React__namespace.useId
|
|
4355
|
+
? React__namespace.useId
|
|
4356
|
+
: function () { return useConstant(incrementId); };
|
|
4357
|
+
|
|
4338
4358
|
/**
|
|
4339
4359
|
* When a component is the child of `AnimatePresence`, it can use `usePresence`
|
|
4340
4360
|
* to access information about whether it's still present in the React tree.
|
|
@@ -4365,8 +4385,8 @@ function usePresence() {
|
|
|
4365
4385
|
var isPresent = context.isPresent, onExitComplete = context.onExitComplete, register = context.register;
|
|
4366
4386
|
// It's safe to call the following hooks conditionally (after an early return) because the context will always
|
|
4367
4387
|
// either be null or non-null for the lifespan of the component.
|
|
4368
|
-
// Replace with
|
|
4369
|
-
var id =
|
|
4388
|
+
// Replace with useId when released in React
|
|
4389
|
+
var id = useId();
|
|
4370
4390
|
React.useEffect(function () { return register(id); }, []);
|
|
4371
4391
|
var safeToRemove = function () { return onExitComplete === null || onExitComplete === void 0 ? void 0 : onExitComplete(id); };
|
|
4372
4392
|
return !isPresent && onExitComplete ? [false, safeToRemove] : [true];
|
|
@@ -4397,9 +4417,6 @@ function useIsPresent() {
|
|
|
4397
4417
|
function isPresent(context) {
|
|
4398
4418
|
return context === null ? true : context.isPresent;
|
|
4399
4419
|
}
|
|
4400
|
-
var counter = 0;
|
|
4401
|
-
var incrementId = function () { return counter++; };
|
|
4402
|
-
var useUniqueId = function () { return useConstant(incrementId); };
|
|
4403
4420
|
|
|
4404
4421
|
function shallowCompare(next, prev) {
|
|
4405
4422
|
if (!Array.isArray(prev))
|
|
@@ -5901,7 +5918,7 @@ function createLifecycles() {
|
|
|
5901
5918
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
5902
5919
|
args[_i] = arguments[_i];
|
|
5903
5920
|
}
|
|
5904
|
-
manager.notify.apply(manager, tslib.__spreadArray([], tslib.__read(args), false));
|
|
5921
|
+
return manager.notify.apply(manager, tslib.__spreadArray([], tslib.__read(args), false));
|
|
5905
5922
|
};
|
|
5906
5923
|
});
|
|
5907
5924
|
return lifecycles;
|
|
@@ -6104,6 +6121,7 @@ var visualElement = function (_a) {
|
|
|
6104
6121
|
if (isVariantNode && parent && !isControllingVariants) {
|
|
6105
6122
|
removeFromVariantTree = parent === null || parent === void 0 ? void 0 : parent.addVariantChild(element);
|
|
6106
6123
|
}
|
|
6124
|
+
values.forEach(function (value, key) { return bindToMotionValue(key, value); });
|
|
6107
6125
|
parent === null || parent === void 0 ? void 0 : parent.children.add(element);
|
|
6108
6126
|
element.setProps(props);
|
|
6109
6127
|
},
|
|
@@ -7084,12 +7102,22 @@ function createDomMotionComponent(key) {
|
|
|
7084
7102
|
*/
|
|
7085
7103
|
var m = createMotionProxy(createDomMotionConfig);
|
|
7086
7104
|
|
|
7105
|
+
function useIsMounted() {
|
|
7106
|
+
var isMounted = React.useRef(false);
|
|
7107
|
+
React.useLayoutEffect(function () {
|
|
7108
|
+
isMounted.current = true;
|
|
7109
|
+
return function () {
|
|
7110
|
+
isMounted.current = false;
|
|
7111
|
+
};
|
|
7112
|
+
}, []);
|
|
7113
|
+
return isMounted;
|
|
7114
|
+
}
|
|
7115
|
+
|
|
7087
7116
|
function useForceUpdate() {
|
|
7088
|
-
var
|
|
7117
|
+
var isMounted = useIsMounted();
|
|
7089
7118
|
var _a = tslib.__read(React.useState(0), 2), forcedRenderCount = _a[0], setForcedRenderCount = _a[1];
|
|
7090
|
-
useUnmountEffect(function () { return (isUnmountingRef.current = true); });
|
|
7091
7119
|
var forceRender = React.useCallback(function () {
|
|
7092
|
-
|
|
7120
|
+
isMounted.current && setForcedRenderCount(forcedRenderCount + 1);
|
|
7093
7121
|
}, [forcedRenderCount]);
|
|
7094
7122
|
/**
|
|
7095
7123
|
* Defer this to the end of the next animation frame in case there are multiple
|
|
@@ -7099,16 +7127,10 @@ function useForceUpdate() {
|
|
|
7099
7127
|
return [deferredForceRender, forcedRenderCount];
|
|
7100
7128
|
}
|
|
7101
7129
|
|
|
7102
|
-
var presenceId = 0;
|
|
7103
|
-
function getPresenceId() {
|
|
7104
|
-
var id = presenceId;
|
|
7105
|
-
presenceId++;
|
|
7106
|
-
return id;
|
|
7107
|
-
}
|
|
7108
7130
|
var PresenceChild = function (_a) {
|
|
7109
7131
|
var children = _a.children, initial = _a.initial, isPresent = _a.isPresent, onExitComplete = _a.onExitComplete, custom = _a.custom, presenceAffectsLayout = _a.presenceAffectsLayout;
|
|
7110
7132
|
var presenceChildren = useConstant(newChildrenMap);
|
|
7111
|
-
var id =
|
|
7133
|
+
var id = useId();
|
|
7112
7134
|
var context = React.useMemo(function () { return ({
|
|
7113
7135
|
id: id,
|
|
7114
7136
|
initial: initial,
|
|
@@ -7160,17 +7182,14 @@ function newChildrenMap() {
|
|
|
7160
7182
|
return new Map();
|
|
7161
7183
|
}
|
|
7162
7184
|
|
|
7163
|
-
function
|
|
7164
|
-
|
|
7165
|
-
}
|
|
7185
|
+
var getChildKey = function (child) { return child.key || ""; };
|
|
7186
|
+
var isDev = process.env.NODE_ENV !== "production";
|
|
7166
7187
|
function updateChildLookup(children, allChildren) {
|
|
7167
|
-
var seenChildren =
|
|
7188
|
+
var seenChildren = isDev ? new Set() : null;
|
|
7168
7189
|
children.forEach(function (child) {
|
|
7169
7190
|
var key = getChildKey(child);
|
|
7170
|
-
if (
|
|
7171
|
-
|
|
7172
|
-
console.warn("Children of AnimatePresence require unique keys. \"".concat(key, "\" is a duplicate."));
|
|
7173
|
-
}
|
|
7191
|
+
if (isDev && seenChildren && seenChildren.has(key)) {
|
|
7192
|
+
console.warn("Children of AnimatePresence require unique keys. \"".concat(key, "\" is a duplicate."));
|
|
7174
7193
|
seenChildren.add(key);
|
|
7175
7194
|
}
|
|
7176
7195
|
allChildren.set(key, child);
|
|
@@ -7226,29 +7245,34 @@ var AnimatePresence = function (_a) {
|
|
|
7226
7245
|
var forceRenderLayoutGroup = React.useContext(LayoutGroupContext).forceRender;
|
|
7227
7246
|
if (forceRenderLayoutGroup)
|
|
7228
7247
|
forceRender = forceRenderLayoutGroup;
|
|
7229
|
-
var
|
|
7230
|
-
var isMounted = React.useRef(true);
|
|
7231
|
-
React.useEffect(function () { return function () {
|
|
7232
|
-
isMounted.current = false;
|
|
7233
|
-
}; }, []);
|
|
7248
|
+
var isMounted = useIsMounted();
|
|
7234
7249
|
// Filter out any children that aren't ReactElements. We can only track ReactElements with a props.key
|
|
7235
7250
|
var filteredChildren = onlyElements(children);
|
|
7251
|
+
var childrenToRender = filteredChildren;
|
|
7252
|
+
var exiting = new Set();
|
|
7236
7253
|
// Keep a living record of the children we're actually rendering so we
|
|
7237
7254
|
// can diff to figure out which are entering and exiting
|
|
7238
|
-
var presentChildren = React.useRef(
|
|
7255
|
+
var presentChildren = React.useRef(childrenToRender);
|
|
7239
7256
|
// A lookup table to quickly reference components by key
|
|
7240
7257
|
var allChildren = React.useRef(new Map()).current;
|
|
7241
|
-
// A living record of all currently exiting components.
|
|
7242
|
-
var exiting = React.useRef(new Set()).current;
|
|
7243
|
-
updateChildLookup(filteredChildren, allChildren);
|
|
7244
7258
|
// If this is the initial component render, just deal with logic surrounding whether
|
|
7245
7259
|
// we play onMount animations or not.
|
|
7246
|
-
|
|
7260
|
+
var isInitialRender = React.useRef(true);
|
|
7261
|
+
useIsomorphicLayoutEffect(function () {
|
|
7247
7262
|
isInitialRender.current = false;
|
|
7248
|
-
|
|
7263
|
+
updateChildLookup(filteredChildren, allChildren);
|
|
7264
|
+
presentChildren.current = childrenToRender;
|
|
7265
|
+
});
|
|
7266
|
+
useUnmountEffect(function () {
|
|
7267
|
+
isInitialRender.current = true;
|
|
7268
|
+
allChildren.clear();
|
|
7269
|
+
exiting.clear();
|
|
7270
|
+
});
|
|
7271
|
+
if (isInitialRender.current) {
|
|
7272
|
+
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)); })));
|
|
7249
7273
|
}
|
|
7250
7274
|
// If this is a subsequent render, deal with entering and exiting children
|
|
7251
|
-
|
|
7275
|
+
childrenToRender = tslib.__spreadArray([], tslib.__read(childrenToRender), false);
|
|
7252
7276
|
// Diff the keys of the currently-present and target children to update our
|
|
7253
7277
|
// exiting list.
|
|
7254
7278
|
var presentKeys = presentChildren.current.map(getChildKey);
|
|
@@ -7260,10 +7284,6 @@ var AnimatePresence = function (_a) {
|
|
|
7260
7284
|
if (targetKeys.indexOf(key) === -1) {
|
|
7261
7285
|
exiting.add(key);
|
|
7262
7286
|
}
|
|
7263
|
-
else {
|
|
7264
|
-
// In case this key has re-entered, remove from the exiting list
|
|
7265
|
-
exiting.delete(key);
|
|
7266
|
-
}
|
|
7267
7287
|
}
|
|
7268
7288
|
// If we currently have exiting children, and we're deferring rendering incoming children
|
|
7269
7289
|
// until after all current children have exiting, empty the childrenToRender array
|
|
@@ -7289,9 +7309,8 @@ var AnimatePresence = function (_a) {
|
|
|
7289
7309
|
// Defer re-rendering until all exiting children have indeed left
|
|
7290
7310
|
if (!exiting.size) {
|
|
7291
7311
|
presentChildren.current = filteredChildren;
|
|
7292
|
-
if (isMounted.current === false)
|
|
7312
|
+
if (isMounted.current === false)
|
|
7293
7313
|
return;
|
|
7294
|
-
}
|
|
7295
7314
|
forceRender();
|
|
7296
7315
|
onExitComplete && onExitComplete();
|
|
7297
7316
|
}
|
|
@@ -7304,7 +7323,6 @@ var AnimatePresence = function (_a) {
|
|
|
7304
7323
|
var key = child.key;
|
|
7305
7324
|
return exiting.has(key) ? (child) : (React__namespace.createElement(PresenceChild, { key: getChildKey(child), isPresent: true, presenceAffectsLayout: presenceAffectsLayout }, child));
|
|
7306
7325
|
});
|
|
7307
|
-
presentChildren.current = childrenToRender;
|
|
7308
7326
|
if (process.env.NODE_ENV !== "production" &&
|
|
7309
7327
|
exitBeforeEnter &&
|
|
7310
7328
|
childrenToRender.length > 1) {
|
|
@@ -8275,13 +8293,15 @@ function useAnimatedState(initialState) {
|
|
|
8275
8293
|
});
|
|
8276
8294
|
React.useEffect(function () {
|
|
8277
8295
|
element.mount({});
|
|
8278
|
-
return element.unmount
|
|
8279
|
-
}, []);
|
|
8296
|
+
return element.unmount;
|
|
8297
|
+
}, [element]);
|
|
8280
8298
|
React.useEffect(function () {
|
|
8281
8299
|
element.setProps({
|
|
8282
|
-
onUpdate: function (v) {
|
|
8300
|
+
onUpdate: function (v) {
|
|
8301
|
+
setAnimationState(tslib.__assign({}, v));
|
|
8302
|
+
},
|
|
8283
8303
|
});
|
|
8284
|
-
});
|
|
8304
|
+
}, [setAnimationState, element]);
|
|
8285
8305
|
var startAnimation = useConstant(function () { return function (animationDefinition) {
|
|
8286
8306
|
return animateVisualElement(element, animationDefinition);
|
|
8287
8307
|
}; });
|
|
@@ -8392,6 +8412,7 @@ exports.useMotionTemplate = useMotionTemplate;
|
|
|
8392
8412
|
exports.useMotionValue = useMotionValue;
|
|
8393
8413
|
exports.usePresence = usePresence;
|
|
8394
8414
|
exports.useReducedMotion = useReducedMotion;
|
|
8415
|
+
exports.useReducedMotionConfig = useReducedMotionConfig;
|
|
8395
8416
|
exports.useResetProjection = useResetProjection;
|
|
8396
8417
|
exports.useSpring = useSpring;
|
|
8397
8418
|
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) {
|
|
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 =
|
|
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,
|
|
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
|
|
9
|
-
|
|
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 =
|
|
14
|
+
var seenChildren = isDev ? new Set() : null;
|
|
13
15
|
children.forEach(function (child) {
|
|
14
16
|
var key = getChildKey(child);
|
|
15
|
-
if (
|
|
16
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
86
|
+
var isInitialRender = useRef(true);
|
|
87
|
+
useIsomorphicLayoutEffect(function () {
|
|
92
88
|
isInitialRender.current = false;
|
|
93
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
|
36
|
-
var id =
|
|
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) {
|
package/dist/es/render/index.mjs
CHANGED
|
@@ -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 {
|
|
4
|
-
import {
|
|
3
|
+
import { useState, useCallback } from 'react';
|
|
4
|
+
import { useIsMounted } from './use-is-mounted.mjs';
|
|
5
5
|
|
|
6
6
|
function useForceUpdate() {
|
|
7
|
-
var
|
|
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
|
-
|
|
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,10 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useConstant } from './use-constant.mjs';
|
|
3
|
+
|
|
4
|
+
var counter = 0;
|
|
5
|
+
var incrementId = function () { return counter++; };
|
|
6
|
+
var useId = React.useId
|
|
7
|
+
? React.useId
|
|
8
|
+
: function () { return useConstant(incrementId); };
|
|
9
|
+
|
|
10
|
+
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 };
|
|
@@ -4,7 +4,9 @@ import { MotionConfigContext } from '../context/MotionConfigContext.mjs';
|
|
|
4
4
|
|
|
5
5
|
// Does this device prefer reduced motion? Returns `null` server-side.
|
|
6
6
|
var prefersReducedMotion = { current: null };
|
|
7
|
+
var hasDetected = false;
|
|
7
8
|
function initPrefersReducedMotion() {
|
|
9
|
+
hasDetected = true;
|
|
8
10
|
if (typeof window === "undefined")
|
|
9
11
|
return;
|
|
10
12
|
if (window.matchMedia) {
|
|
@@ -49,7 +51,7 @@ function useReducedMotion() {
|
|
|
49
51
|
/**
|
|
50
52
|
* Lazy initialisation of prefersReducedMotion
|
|
51
53
|
*/
|
|
52
|
-
!
|
|
54
|
+
!hasDetected && initPrefersReducedMotion();
|
|
53
55
|
var _a = __read(useState(prefersReducedMotion.current), 1), shouldReduceMotion = _a[0];
|
|
54
56
|
/**
|
|
55
57
|
* TODO See if people miss automatically updating shouldReduceMotion setting
|