framer-motion 6.2.3 → 6.2.7
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 +79 -52
- 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/components/LayoutGroup/index.mjs +10 -3
- package/dist/es/projection/node/create-projection-node.mjs +11 -3
- package/dist/es/render/index.mjs +1 -0
- package/dist/es/utils/use-force-update.mjs +4 -5
- package/dist/es/utils/use-id.mjs +15 -0
- package/dist/es/utils/use-is-mounted.mjs +15 -0
- package/dist/framer-motion.dev.js +77 -51
- package/dist/framer-motion.js +1 -1
- package/dist/projection.dev.js +12 -3
- package/dist/size-rollup-dom-animation.js +1 -1
- package/dist/size-rollup-dom-max.js +1 -1
- package/dist/size-webpack-dom-animation.js +1 -1
- package/dist/size-webpack-dom-max.js +1 -1
- package/package.json +10 -6
- package/types/components/LayoutGroup/index.d.ts +6 -0
- 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/utils/use-id.d.ts +6 -0
- package/types/utils/use-is-mounted.d.ts +2 -0
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
|
};
|
|
@@ -4341,6 +4349,18 @@ var gestureAnimations = {
|
|
|
4341
4349
|
hover: makeRenderlessComponent(useHoverGesture),
|
|
4342
4350
|
};
|
|
4343
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
|
+
|
|
4344
4364
|
/**
|
|
4345
4365
|
* When a component is the child of `AnimatePresence`, it can use `usePresence`
|
|
4346
4366
|
* to access information about whether it's still present in the React tree.
|
|
@@ -4371,8 +4391,8 @@ function usePresence() {
|
|
|
4371
4391
|
var isPresent = context.isPresent, onExitComplete = context.onExitComplete, register = context.register;
|
|
4372
4392
|
// It's safe to call the following hooks conditionally (after an early return) because the context will always
|
|
4373
4393
|
// either be null or non-null for the lifespan of the component.
|
|
4374
|
-
// Replace with
|
|
4375
|
-
var id =
|
|
4394
|
+
// Replace with useId when released in React
|
|
4395
|
+
var id = useId();
|
|
4376
4396
|
React.useEffect(function () { return register(id); }, []);
|
|
4377
4397
|
var safeToRemove = function () { return onExitComplete === null || onExitComplete === void 0 ? void 0 : onExitComplete(id); };
|
|
4378
4398
|
return !isPresent && onExitComplete ? [false, safeToRemove] : [true];
|
|
@@ -4403,9 +4423,6 @@ function useIsPresent() {
|
|
|
4403
4423
|
function isPresent(context) {
|
|
4404
4424
|
return context === null ? true : context.isPresent;
|
|
4405
4425
|
}
|
|
4406
|
-
var counter = 0;
|
|
4407
|
-
var incrementId = function () { return counter++; };
|
|
4408
|
-
var useUniqueId = function () { return useConstant(incrementId); };
|
|
4409
4426
|
|
|
4410
4427
|
function shallowCompare(next, prev) {
|
|
4411
4428
|
if (!Array.isArray(prev))
|
|
@@ -6110,6 +6127,7 @@ var visualElement = function (_a) {
|
|
|
6110
6127
|
if (isVariantNode && parent && !isControllingVariants) {
|
|
6111
6128
|
removeFromVariantTree = parent === null || parent === void 0 ? void 0 : parent.addVariantChild(element);
|
|
6112
6129
|
}
|
|
6130
|
+
values.forEach(function (value, key) { return bindToMotionValue(key, value); });
|
|
6113
6131
|
parent === null || parent === void 0 ? void 0 : parent.children.add(element);
|
|
6114
6132
|
element.setProps(props);
|
|
6115
6133
|
},
|
|
@@ -7090,12 +7108,22 @@ function createDomMotionComponent(key) {
|
|
|
7090
7108
|
*/
|
|
7091
7109
|
var m = createMotionProxy(createDomMotionConfig);
|
|
7092
7110
|
|
|
7111
|
+
function useIsMounted() {
|
|
7112
|
+
var isMounted = React.useRef(false);
|
|
7113
|
+
useIsomorphicLayoutEffect(function () {
|
|
7114
|
+
isMounted.current = true;
|
|
7115
|
+
return function () {
|
|
7116
|
+
isMounted.current = false;
|
|
7117
|
+
};
|
|
7118
|
+
}, []);
|
|
7119
|
+
return isMounted;
|
|
7120
|
+
}
|
|
7121
|
+
|
|
7093
7122
|
function useForceUpdate() {
|
|
7094
|
-
var
|
|
7123
|
+
var isMounted = useIsMounted();
|
|
7095
7124
|
var _a = tslib.__read(React.useState(0), 2), forcedRenderCount = _a[0], setForcedRenderCount = _a[1];
|
|
7096
|
-
useUnmountEffect(function () { return (isUnmountingRef.current = true); });
|
|
7097
7125
|
var forceRender = React.useCallback(function () {
|
|
7098
|
-
|
|
7126
|
+
isMounted.current && setForcedRenderCount(forcedRenderCount + 1);
|
|
7099
7127
|
}, [forcedRenderCount]);
|
|
7100
7128
|
/**
|
|
7101
7129
|
* Defer this to the end of the next animation frame in case there are multiple
|
|
@@ -7105,16 +7133,10 @@ function useForceUpdate() {
|
|
|
7105
7133
|
return [deferredForceRender, forcedRenderCount];
|
|
7106
7134
|
}
|
|
7107
7135
|
|
|
7108
|
-
var presenceId = 0;
|
|
7109
|
-
function getPresenceId() {
|
|
7110
|
-
var id = presenceId;
|
|
7111
|
-
presenceId++;
|
|
7112
|
-
return id;
|
|
7113
|
-
}
|
|
7114
7136
|
var PresenceChild = function (_a) {
|
|
7115
7137
|
var children = _a.children, initial = _a.initial, isPresent = _a.isPresent, onExitComplete = _a.onExitComplete, custom = _a.custom, presenceAffectsLayout = _a.presenceAffectsLayout;
|
|
7116
7138
|
var presenceChildren = useConstant(newChildrenMap);
|
|
7117
|
-
var id =
|
|
7139
|
+
var id = useId();
|
|
7118
7140
|
var context = React.useMemo(function () { return ({
|
|
7119
7141
|
id: id,
|
|
7120
7142
|
initial: initial,
|
|
@@ -7166,17 +7188,14 @@ function newChildrenMap() {
|
|
|
7166
7188
|
return new Map();
|
|
7167
7189
|
}
|
|
7168
7190
|
|
|
7169
|
-
function
|
|
7170
|
-
|
|
7171
|
-
}
|
|
7191
|
+
var getChildKey = function (child) { return child.key || ""; };
|
|
7192
|
+
var isDev = process.env.NODE_ENV !== "production";
|
|
7172
7193
|
function updateChildLookup(children, allChildren) {
|
|
7173
|
-
var seenChildren =
|
|
7194
|
+
var seenChildren = isDev ? new Set() : null;
|
|
7174
7195
|
children.forEach(function (child) {
|
|
7175
7196
|
var key = getChildKey(child);
|
|
7176
|
-
if (
|
|
7177
|
-
|
|
7178
|
-
console.warn("Children of AnimatePresence require unique keys. \"".concat(key, "\" is a duplicate."));
|
|
7179
|
-
}
|
|
7197
|
+
if (isDev && seenChildren && seenChildren.has(key)) {
|
|
7198
|
+
console.warn("Children of AnimatePresence require unique keys. \"".concat(key, "\" is a duplicate."));
|
|
7180
7199
|
seenChildren.add(key);
|
|
7181
7200
|
}
|
|
7182
7201
|
allChildren.set(key, child);
|
|
@@ -7232,29 +7251,34 @@ var AnimatePresence = function (_a) {
|
|
|
7232
7251
|
var forceRenderLayoutGroup = React.useContext(LayoutGroupContext).forceRender;
|
|
7233
7252
|
if (forceRenderLayoutGroup)
|
|
7234
7253
|
forceRender = forceRenderLayoutGroup;
|
|
7235
|
-
var
|
|
7236
|
-
var isMounted = React.useRef(true);
|
|
7237
|
-
React.useEffect(function () { return function () {
|
|
7238
|
-
isMounted.current = false;
|
|
7239
|
-
}; }, []);
|
|
7254
|
+
var isMounted = useIsMounted();
|
|
7240
7255
|
// Filter out any children that aren't ReactElements. We can only track ReactElements with a props.key
|
|
7241
7256
|
var filteredChildren = onlyElements(children);
|
|
7257
|
+
var childrenToRender = filteredChildren;
|
|
7258
|
+
var exiting = new Set();
|
|
7242
7259
|
// Keep a living record of the children we're actually rendering so we
|
|
7243
7260
|
// can diff to figure out which are entering and exiting
|
|
7244
|
-
var presentChildren = React.useRef(
|
|
7261
|
+
var presentChildren = React.useRef(childrenToRender);
|
|
7245
7262
|
// A lookup table to quickly reference components by key
|
|
7246
7263
|
var allChildren = React.useRef(new Map()).current;
|
|
7247
|
-
// A living record of all currently exiting components.
|
|
7248
|
-
var exiting = React.useRef(new Set()).current;
|
|
7249
|
-
updateChildLookup(filteredChildren, allChildren);
|
|
7250
7264
|
// If this is the initial component render, just deal with logic surrounding whether
|
|
7251
7265
|
// we play onMount animations or not.
|
|
7252
|
-
|
|
7266
|
+
var isInitialRender = React.useRef(true);
|
|
7267
|
+
useIsomorphicLayoutEffect(function () {
|
|
7253
7268
|
isInitialRender.current = false;
|
|
7254
|
-
|
|
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)); })));
|
|
7255
7279
|
}
|
|
7256
7280
|
// If this is a subsequent render, deal with entering and exiting children
|
|
7257
|
-
|
|
7281
|
+
childrenToRender = tslib.__spreadArray([], tslib.__read(childrenToRender), false);
|
|
7258
7282
|
// Diff the keys of the currently-present and target children to update our
|
|
7259
7283
|
// exiting list.
|
|
7260
7284
|
var presentKeys = presentChildren.current.map(getChildKey);
|
|
@@ -7266,10 +7290,6 @@ var AnimatePresence = function (_a) {
|
|
|
7266
7290
|
if (targetKeys.indexOf(key) === -1) {
|
|
7267
7291
|
exiting.add(key);
|
|
7268
7292
|
}
|
|
7269
|
-
else {
|
|
7270
|
-
// In case this key has re-entered, remove from the exiting list
|
|
7271
|
-
exiting.delete(key);
|
|
7272
|
-
}
|
|
7273
7293
|
}
|
|
7274
7294
|
// If we currently have exiting children, and we're deferring rendering incoming children
|
|
7275
7295
|
// until after all current children have exiting, empty the childrenToRender array
|
|
@@ -7295,9 +7315,8 @@ var AnimatePresence = function (_a) {
|
|
|
7295
7315
|
// Defer re-rendering until all exiting children have indeed left
|
|
7296
7316
|
if (!exiting.size) {
|
|
7297
7317
|
presentChildren.current = filteredChildren;
|
|
7298
|
-
if (isMounted.current === false)
|
|
7318
|
+
if (isMounted.current === false)
|
|
7299
7319
|
return;
|
|
7300
|
-
}
|
|
7301
7320
|
forceRender();
|
|
7302
7321
|
onExitComplete && onExitComplete();
|
|
7303
7322
|
}
|
|
@@ -7310,7 +7329,6 @@ var AnimatePresence = function (_a) {
|
|
|
7310
7329
|
var key = child.key;
|
|
7311
7330
|
return exiting.has(key) ? (child) : (React__namespace.createElement(PresenceChild, { key: getChildKey(child), isPresent: true, presenceAffectsLayout: presenceAffectsLayout }, child));
|
|
7312
7331
|
});
|
|
7313
|
-
presentChildren.current = childrenToRender;
|
|
7314
7332
|
if (process.env.NODE_ENV !== "production" &&
|
|
7315
7333
|
exitBeforeEnter &&
|
|
7316
7334
|
childrenToRender.length > 1) {
|
|
@@ -7350,21 +7368,28 @@ function nodeGroup() {
|
|
|
7350
7368
|
};
|
|
7351
7369
|
}
|
|
7352
7370
|
|
|
7371
|
+
var shouldInheritGroup = function (inherit) { return inherit === true; };
|
|
7372
|
+
var shouldInheritId = function (inherit) {
|
|
7373
|
+
return shouldInheritGroup(inherit === true) || inherit === "id";
|
|
7374
|
+
};
|
|
7353
7375
|
var LayoutGroup = function (_a) {
|
|
7354
7376
|
var _b, _c;
|
|
7355
|
-
var children = _a.children, id = _a.id,
|
|
7377
|
+
var children = _a.children, id = _a.id, inheritId = _a.inheritId, _d = _a.inherit, inherit = _d === void 0 ? true : _d;
|
|
7378
|
+
// Maintain backwards-compatibility with inheritId until 7.0
|
|
7379
|
+
if (inheritId !== undefined)
|
|
7380
|
+
inherit = inheritId;
|
|
7356
7381
|
var layoutGroupContext = React.useContext(LayoutGroupContext);
|
|
7357
7382
|
var deprecatedLayoutGroupContext = React.useContext(DeprecatedLayoutGroupContext);
|
|
7358
7383
|
var _e = tslib.__read(useForceUpdate(), 2), forceRender = _e[0], key = _e[1];
|
|
7359
7384
|
var context = React.useRef(null);
|
|
7360
7385
|
var upstreamId = (_b = layoutGroupContext.id) !== null && _b !== void 0 ? _b : deprecatedLayoutGroupContext;
|
|
7361
7386
|
if (context.current === null) {
|
|
7362
|
-
if (
|
|
7387
|
+
if (shouldInheritId(inherit) && upstreamId) {
|
|
7363
7388
|
id = id ? upstreamId + "-" + id : upstreamId;
|
|
7364
7389
|
}
|
|
7365
7390
|
context.current = {
|
|
7366
7391
|
id: id,
|
|
7367
|
-
group:
|
|
7392
|
+
group: shouldInheritGroup(inherit)
|
|
7368
7393
|
? (_c = layoutGroupContext === null || layoutGroupContext === void 0 ? void 0 : layoutGroupContext.group) !== null && _c !== void 0 ? _c : nodeGroup()
|
|
7369
7394
|
: nodeGroup(),
|
|
7370
7395
|
};
|
|
@@ -8281,13 +8306,15 @@ function useAnimatedState(initialState) {
|
|
|
8281
8306
|
});
|
|
8282
8307
|
React.useEffect(function () {
|
|
8283
8308
|
element.mount({});
|
|
8284
|
-
return element.unmount
|
|
8285
|
-
}, []);
|
|
8309
|
+
return element.unmount;
|
|
8310
|
+
}, [element]);
|
|
8286
8311
|
React.useEffect(function () {
|
|
8287
8312
|
element.setProps({
|
|
8288
|
-
onUpdate: function (v) {
|
|
8313
|
+
onUpdate: function (v) {
|
|
8314
|
+
setAnimationState(tslib.__assign({}, v));
|
|
8315
|
+
},
|
|
8289
8316
|
});
|
|
8290
|
-
});
|
|
8317
|
+
}, [setAnimationState, element]);
|
|
8291
8318
|
var startAnimation = useConstant(function () { return function (animationDefinition) {
|
|
8292
8319
|
return animateVisualElement(element, animationDefinition);
|
|
8293
8320
|
}; });
|
|
@@ -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 };
|
|
@@ -6,21 +6,28 @@ import { DeprecatedLayoutGroupContext } from '../../context/DeprecatedLayoutGrou
|
|
|
6
6
|
import { useForceUpdate } from '../../utils/use-force-update.mjs';
|
|
7
7
|
import { nodeGroup } from '../../projection/node/group.mjs';
|
|
8
8
|
|
|
9
|
+
var shouldInheritGroup = function (inherit) { return inherit === true; };
|
|
10
|
+
var shouldInheritId = function (inherit) {
|
|
11
|
+
return shouldInheritGroup(inherit === true) || inherit === "id";
|
|
12
|
+
};
|
|
9
13
|
var LayoutGroup = function (_a) {
|
|
10
14
|
var _b, _c;
|
|
11
|
-
var children = _a.children, id = _a.id,
|
|
15
|
+
var children = _a.children, id = _a.id, inheritId = _a.inheritId, _d = _a.inherit, inherit = _d === void 0 ? true : _d;
|
|
16
|
+
// Maintain backwards-compatibility with inheritId until 7.0
|
|
17
|
+
if (inheritId !== undefined)
|
|
18
|
+
inherit = inheritId;
|
|
12
19
|
var layoutGroupContext = useContext(LayoutGroupContext);
|
|
13
20
|
var deprecatedLayoutGroupContext = useContext(DeprecatedLayoutGroupContext);
|
|
14
21
|
var _e = __read(useForceUpdate(), 2), forceRender = _e[0], key = _e[1];
|
|
15
22
|
var context = useRef(null);
|
|
16
23
|
var upstreamId = (_b = layoutGroupContext.id) !== null && _b !== void 0 ? _b : deprecatedLayoutGroupContext;
|
|
17
24
|
if (context.current === null) {
|
|
18
|
-
if (
|
|
25
|
+
if (shouldInheritId(inherit) && upstreamId) {
|
|
19
26
|
id = id ? upstreamId + "-" + id : upstreamId;
|
|
20
27
|
}
|
|
21
28
|
context.current = {
|
|
22
29
|
id: id,
|
|
23
|
-
group:
|
|
30
|
+
group: shouldInheritGroup(inherit)
|
|
24
31
|
? (_c = layoutGroupContext === null || layoutGroupContext === void 0 ? void 0 : layoutGroupContext.group) !== null && _c !== void 0 ? _c : nodeGroup()
|
|
25
32
|
: nodeGroup(),
|
|
26
33
|
};
|
|
@@ -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
|
};
|
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
|
},
|
|
@@ -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,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,15 @@
|
|
|
1
|
+
import { useRef } from 'react';
|
|
2
|
+
import { useIsomorphicLayoutEffect } from './use-isomorphic-effect.mjs';
|
|
3
|
+
|
|
4
|
+
function useIsMounted() {
|
|
5
|
+
var isMounted = useRef(false);
|
|
6
|
+
useIsomorphicLayoutEffect(function () {
|
|
7
|
+
isMounted.current = true;
|
|
8
|
+
return function () {
|
|
9
|
+
isMounted.current = false;
|
|
10
|
+
};
|
|
11
|
+
}, []);
|
|
12
|
+
return isMounted;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { useIsMounted };
|