framer-motion 1.9.1 → 1.10.3
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/CHANGELOG.md +25 -0
- package/dist/framer-motion.api.json +2 -2
- package/dist/framer-motion.cjs.js +115 -101
- package/dist/framer-motion.d.ts +28 -31
- package/dist/framer-motion.dev.js +115 -101
- package/dist/framer-motion.es.js +116 -102
- package/dist/framer-motion.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
Framer Motion adheres to [Semantic Versioning](http://semver.org/).
|
|
4
4
|
|
|
5
|
+
## [1.10.3] 2020-03-23
|
|
6
|
+
|
|
7
|
+
### Fix
|
|
8
|
+
|
|
9
|
+
- Replacing the functionality of `DragControls` `e.preventDefault()` with CSS and HTML attributes. ([@inventingwithmonster](https://github.com/inventingwithmonster) in [#495](https://github.com/framer/motion/pull/495))
|
|
10
|
+
|
|
11
|
+
## [1.10.2] 2020-03-23
|
|
12
|
+
|
|
13
|
+
### Fix
|
|
14
|
+
|
|
15
|
+
- Fixing `PresenceChild` losing correct count of exiting children if it re-renders. ([@inventingwithmonster](https://github.com/inventingwithmonster) in [#490](https://github.com/framer/motion/pull/490))
|
|
16
|
+
|
|
17
|
+
## [1.10.1] 2020-03-23
|
|
18
|
+
|
|
19
|
+
### Fix
|
|
20
|
+
|
|
21
|
+
- Fixing `AnimatePresence` children not re-rendering when their exiting siblings have been removed from the tree (which broke siblings `positionTransition` and `layoutTransition`). ([@inventingwithmonster](https://github.com/inventingwithmonster) in [#489](https://github.com/framer/motion/pull/489))
|
|
22
|
+
- Adding `null` check for `getTranslateFromMatrix` ([@JoyalJoyMadeckal](https://github.com/JoyalJoyMadeckal) in [#482](https://github.com/framer/motion/pull/482))
|
|
23
|
+
|
|
24
|
+
## [1.10.0] 2020-03-19
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- `AnimatePresence` now supports multiple `usePresence` children within a given sub-tree.
|
|
29
|
+
|
|
5
30
|
## [1.9.1] 2020-03-06
|
|
6
31
|
|
|
7
32
|
### Fixed
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"members": [
|
|
16
16
|
{
|
|
17
17
|
"kind": "Variable",
|
|
18
|
-
"docComment": "/**\n *
|
|
18
|
+
"docComment": "/**\n * `AnimatePresence` enables the animation of components that have been removed from the tree.\n *\n * When adding/removing more than a single child, every child **must** be given a unique `key` prop.\n *\n * @library\n *\n * Any `Frame` components that have an `exit` property defined will animate out when removed from the tree.\n * ```jsx\n * import { Frame, AnimatePresence } from 'framer'\n *\n * // As items are added and removed from `items`\n * export function Items({ items }) {\n * return (\n * <AnimatePresence>\n * {items.map(item => (\n * <Frame\n * key={item.id}\n * initial={{ opacity: 0 }}\n * animate={{ opacity: 1 }}\n * exit={{ opacity: 0 }}\n * />\n * ))}\n * </AnimatePresence>\n * )\n * }\n * ```\n *\n * You can sequence exit animations throughout a tree using variants.\n *\n * @motion\n *\n * Any `motion` components that have an `exit` property defined will animate out when removed from the tree.\n * ```jsx\n * import { motion, AnimatePresence } from 'framer-motion'\n *\n * export const Items = ({ items }) => (\n * <AnimatePresence>\n * {items.map(item => (\n * <motion.div\n * key={item.id}\n * initial={{ opacity: 0 }}\n * animate={{ opacity: 1 }}\n * exit={{ opacity: 0 }}\n * />\n * ))}\n * </AnimatePresence>\n * )\n * ```\n *\n * You can sequence exit animations throughout a tree using variants.\n *\n * If a child contains multiple `motion` components with `exit` props, it will only unmount the child once all `motion` components have finished animating out. Likewise, any components using `usePresence` all need to call `safeToRemove`.\n *\n * @public\n */\n",
|
|
19
19
|
"excerptTokens": [
|
|
20
20
|
{
|
|
21
21
|
"kind": "Reference",
|
|
@@ -13330,7 +13330,7 @@
|
|
|
13330
13330
|
},
|
|
13331
13331
|
{
|
|
13332
13332
|
"kind": "Function",
|
|
13333
|
-
"docComment": "/**\n * When a component is the child of
|
|
13333
|
+
"docComment": "/**\n * When a component is the child of `AnimatePresence`, it can use `usePresence` to access information about whether it's still present in the React tree.\n * ```jsx\n * import { usePresence } from \"framer-motion\"\n *\n * export const Component = () => {\n * const [isPresent, safeToRemove] = usePresence()\n *\n * useEffect(() => {\n * !isPresent setTimeout(safeToRemove, 1000)\n * }, [isPresent])\n *\n * return <div />\n * }\n * ```\n *\n * If `isPresent` is `false`, it means that a component has been removed the tree, but `AnimatePresence` won't really remove it until `safeToRemove` has been called.\n *\n * @public\n */\n",
|
|
13334
13334
|
"excerptTokens": [
|
|
13335
13335
|
{
|
|
13336
13336
|
"kind": "Content",
|
|
@@ -1605,6 +1605,8 @@ var AnimationControls = /** @class */ (function () {
|
|
|
1605
1605
|
*/
|
|
1606
1606
|
var animationControls = function () { return new AnimationControls(); };
|
|
1607
1607
|
|
|
1608
|
+
var PresenceContext = React.createContext(null);
|
|
1609
|
+
|
|
1608
1610
|
/**
|
|
1609
1611
|
* @internal
|
|
1610
1612
|
*/
|
|
@@ -1625,10 +1627,11 @@ var isAnimationControls = function (v) {
|
|
|
1625
1627
|
var useMotionContext = function (parentContext, controls, values, isStatic, _a) {
|
|
1626
1628
|
if (isStatic === void 0) { isStatic = false; }
|
|
1627
1629
|
var initial = _a.initial, animate = _a.animate, variants = _a.variants, whileTap = _a.whileTap, whileHover = _a.whileHover;
|
|
1630
|
+
var _b;
|
|
1631
|
+
var presenceContext = React.useContext(PresenceContext);
|
|
1628
1632
|
// Override initial with that from a parent context, if defined
|
|
1629
|
-
if (
|
|
1630
|
-
|
|
1631
|
-
initial = parentContext.exitProps.initial;
|
|
1633
|
+
if (((_b = presenceContext) === null || _b === void 0 ? void 0 : _b.initial) !== undefined) {
|
|
1634
|
+
initial = presenceContext.initial;
|
|
1632
1635
|
}
|
|
1633
1636
|
var initialState;
|
|
1634
1637
|
if (initial === false && !isAnimationControls(animate)) {
|
|
@@ -1708,14 +1711,13 @@ var useMotionContext = function (parentContext, controls, values, isStatic, _a)
|
|
|
1708
1711
|
*
|
|
1709
1712
|
* @internal
|
|
1710
1713
|
*/
|
|
1711
|
-
function useValueAnimationControls(config, props, subscribeToParentControls
|
|
1714
|
+
function useValueAnimationControls(config, props, subscribeToParentControls) {
|
|
1712
1715
|
var variants = props.variants, transition = props.transition;
|
|
1713
1716
|
var parentControls = React.useContext(MotionContext).controls;
|
|
1717
|
+
var presenceContext = React.useContext(PresenceContext);
|
|
1714
1718
|
var controls = useConstant(function () { return new ValueAnimationControls(config); });
|
|
1715
1719
|
// Reset and resubscribe children every render to ensure stagger order is correct
|
|
1716
|
-
if (!
|
|
1717
|
-
!parentContext.exitProps ||
|
|
1718
|
-
!parentContext.exitProps.isExiting) {
|
|
1720
|
+
if (!presenceContext || presenceContext.isPresent) {
|
|
1719
1721
|
controls.resetChildren();
|
|
1720
1722
|
controls.setProps(props);
|
|
1721
1723
|
controls.setVariants(variants);
|
|
@@ -1790,7 +1792,7 @@ var createMotionComponent = function (_a) {
|
|
|
1790
1792
|
var controlsConfig = useConstant(function () {
|
|
1791
1793
|
return getValueControlsConfig(ref, values);
|
|
1792
1794
|
});
|
|
1793
|
-
var controls = useValueAnimationControls(controlsConfig, props, shouldInheritVariant
|
|
1795
|
+
var controls = useValueAnimationControls(controlsConfig, props, shouldInheritVariant);
|
|
1794
1796
|
var context = useMotionContext(parentContext, controls, values, isStatic, props);
|
|
1795
1797
|
var functionality = isStatic
|
|
1796
1798
|
? null
|
|
@@ -2587,10 +2589,6 @@ var isRefObject = function (ref) {
|
|
|
2587
2589
|
};
|
|
2588
2590
|
|
|
2589
2591
|
var noop = function (v) { return v; };
|
|
2590
|
-
/**
|
|
2591
|
-
* Don't block the default pointerdown behaviour of these elements.
|
|
2592
|
-
*/
|
|
2593
|
-
var allowDefaultPointerDown = new Set(["INPUT", "TEXTAREA", "SELECT"]);
|
|
2594
2592
|
var ComponentDragControls = /** @class */ (function () {
|
|
2595
2593
|
function ComponentDragControls(_a) {
|
|
2596
2594
|
var ref = _a.ref, values = _a.values, controls = _a.controls;
|
|
@@ -2670,20 +2668,7 @@ var ComponentDragControls = /** @class */ (function () {
|
|
|
2670
2668
|
var _this = this;
|
|
2671
2669
|
var _b = (_a === void 0 ? {} : _a).snapToCursor, snapToCursor = _b === void 0 ? false : _b;
|
|
2672
2670
|
snapToCursor && this.snapToCursor(originEvent);
|
|
2673
|
-
var onSessionStart = function (
|
|
2674
|
-
// Prevent browser-specific behaviours like text selection or Chrome's image dragging.
|
|
2675
|
-
if (event.target &&
|
|
2676
|
-
!allowDefaultPointerDown.has(event.target.tagName)) {
|
|
2677
|
-
// On iOS it's important to not `preventDefault` the `touchstart`
|
|
2678
|
-
// event, as otherwise clicks won't fire inside the draggable element.
|
|
2679
|
-
if (!supportsTouchEvents()) {
|
|
2680
|
-
event.preventDefault();
|
|
2681
|
-
// Make sure input elements loose focus when we prevent the default.
|
|
2682
|
-
if (document.activeElement instanceof HTMLElement) {
|
|
2683
|
-
document.activeElement.blur();
|
|
2684
|
-
}
|
|
2685
|
-
}
|
|
2686
|
-
}
|
|
2671
|
+
var onSessionStart = function () {
|
|
2687
2672
|
// Initiate viewport scroll blocking on touch start. This is a very aggressive approach
|
|
2688
2673
|
// which has come out of the difficulty in us being able to do this once a scroll gesture
|
|
2689
2674
|
// has initiated in mobile browsers. This means if there's a horizontally-scrolling carousel
|
|
@@ -3228,7 +3213,12 @@ var getTranslateFromMatrix = function (pos2, pos3) { return function (_bbox, _a)
|
|
|
3228
3213
|
}
|
|
3229
3214
|
else {
|
|
3230
3215
|
var matrix = transform.match(/^matrix\((.+)\)$/);
|
|
3231
|
-
|
|
3216
|
+
if (matrix) {
|
|
3217
|
+
return getPosFromMatrix(matrix[1], pos2);
|
|
3218
|
+
}
|
|
3219
|
+
else {
|
|
3220
|
+
return 0;
|
|
3221
|
+
}
|
|
3232
3222
|
}
|
|
3233
3223
|
}; };
|
|
3234
3224
|
var transformKeys = new Set(["x", "y", "z"]);
|
|
@@ -4007,28 +3997,54 @@ var getAnimationComponent = function (props) {
|
|
|
4007
3997
|
return animatePropType ? AnimatePropComponents[animatePropType] : undefined;
|
|
4008
3998
|
};
|
|
4009
3999
|
|
|
4000
|
+
/**
|
|
4001
|
+
* When a component is the child of `AnimatePresence`, it can use `usePresence`
|
|
4002
|
+
* to access information about whether it's still present in the React tree.
|
|
4003
|
+
*
|
|
4004
|
+
* ```jsx
|
|
4005
|
+
* import { usePresence } from "framer-motion"
|
|
4006
|
+
*
|
|
4007
|
+
* export const Component = () => {
|
|
4008
|
+
* const [isPresent, safeToRemove] = usePresence()
|
|
4009
|
+
*
|
|
4010
|
+
* useEffect(() => {
|
|
4011
|
+
* !isPresent setTimeout(safeToRemove, 1000)
|
|
4012
|
+
* }, [isPresent])
|
|
4013
|
+
*
|
|
4014
|
+
* return <div />
|
|
4015
|
+
* }
|
|
4016
|
+
* ```
|
|
4017
|
+
*
|
|
4018
|
+
* If `isPresent` is `false`, it means that a component has been removed the tree, but
|
|
4019
|
+
* `AnimatePresence` won't really remove it until `safeToRemove` has been called.
|
|
4020
|
+
*
|
|
4021
|
+
* @public
|
|
4022
|
+
*/
|
|
4023
|
+
function usePresence() {
|
|
4024
|
+
var context = React.useContext(PresenceContext);
|
|
4025
|
+
if (context === null)
|
|
4026
|
+
return [true];
|
|
4027
|
+
var isPresent = context.isPresent, onExitComplete = context.onExitComplete, register = context.register;
|
|
4028
|
+
React.useEffect(register, []);
|
|
4029
|
+
return !isPresent && onExitComplete ? [false, onExitComplete] : [true];
|
|
4030
|
+
}
|
|
4031
|
+
|
|
4010
4032
|
var Exit = {
|
|
4011
4033
|
key: "exit",
|
|
4012
|
-
shouldRender: function (
|
|
4013
|
-
var exit = _a.exit;
|
|
4014
|
-
var exitProps = _b.exitProps;
|
|
4015
|
-
var hasExitProps = !!exitProps;
|
|
4016
|
-
var hasExitAnimation = !!exit;
|
|
4017
|
-
heyListen.invariant(!hasExitProps || (hasExitProps && hasExitAnimation), "No exit prop defined on a child of AnimatePresence.");
|
|
4018
|
-
return hasExitProps && hasExitAnimation;
|
|
4019
|
-
},
|
|
4034
|
+
shouldRender: function (props) { return !!props.exit && !checkShouldInheritVariant(props); },
|
|
4020
4035
|
Component: makeRenderlessComponent(function (props) {
|
|
4021
|
-
var
|
|
4022
|
-
var
|
|
4036
|
+
var _a;
|
|
4037
|
+
var animate = props.animate, controls = props.controls, exit = props.exit;
|
|
4038
|
+
var _b = usePresence(), isPresent = _b[0], onExitComplete = _b[1];
|
|
4039
|
+
var presenceContext = React.useContext(PresenceContext);
|
|
4023
4040
|
var isPlayingExitAnimation = React.useRef(false);
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
var isExiting = exitProps.isExiting, custom = exitProps.custom, onExitComplete = exitProps.onExitComplete;
|
|
4041
|
+
var custom = ((_a = presenceContext) === null || _a === void 0 ? void 0 : _a.custom) !== undefined
|
|
4042
|
+
? presenceContext.custom
|
|
4043
|
+
: props.custom;
|
|
4028
4044
|
React.useEffect(function () {
|
|
4029
|
-
if (
|
|
4045
|
+
if (!isPresent) {
|
|
4030
4046
|
if (!isPlayingExitAnimation.current && exit) {
|
|
4031
|
-
controls.setProps(tslib.__assign(tslib.__assign({}, props), { custom: custom
|
|
4047
|
+
controls.setProps(tslib.__assign(tslib.__assign({}, props), { custom: custom }));
|
|
4032
4048
|
controls.start(exit).then(onExitComplete);
|
|
4033
4049
|
}
|
|
4034
4050
|
isPlayingExitAnimation.current = true;
|
|
@@ -4038,10 +4054,10 @@ var Exit = {
|
|
|
4038
4054
|
!(animate instanceof AnimationControls)) {
|
|
4039
4055
|
controls.start(animate);
|
|
4040
4056
|
}
|
|
4041
|
-
if (
|
|
4057
|
+
if (isPresent) {
|
|
4042
4058
|
isPlayingExitAnimation.current = false;
|
|
4043
4059
|
}
|
|
4044
|
-
}, [
|
|
4060
|
+
}, [isPresent]);
|
|
4045
4061
|
}),
|
|
4046
4062
|
};
|
|
4047
4063
|
|
|
@@ -4083,6 +4099,19 @@ function filterValidProps(props) {
|
|
|
4083
4099
|
}
|
|
4084
4100
|
return domProps;
|
|
4085
4101
|
}
|
|
4102
|
+
var buildHTMLProps = function (values, style, isStatic, isDrag) {
|
|
4103
|
+
// The `any` isn't ideal but it is the type of createElement props argument
|
|
4104
|
+
var props = {
|
|
4105
|
+
style: buildStyleAttr(values, style, isStatic),
|
|
4106
|
+
};
|
|
4107
|
+
if (isDrag) {
|
|
4108
|
+
// Disable text selection
|
|
4109
|
+
props.style.userSelect = "none";
|
|
4110
|
+
// Disable the ghost element when a user drags
|
|
4111
|
+
props.draggable = false;
|
|
4112
|
+
}
|
|
4113
|
+
return props;
|
|
4114
|
+
};
|
|
4086
4115
|
var buildSVGProps = function (values, style) {
|
|
4087
4116
|
var motionValueStyles = resolveCurrent(values);
|
|
4088
4117
|
var props = styler.buildSVGAttrs(motionValueStyles, undefined, undefined, undefined, undefined, false);
|
|
@@ -4104,7 +4133,7 @@ function createDomMotionConfig(Component) {
|
|
|
4104
4133
|
var forwardedProps = isDOM ? filterValidProps(props) : props;
|
|
4105
4134
|
var staticVisualStyles = isSVG
|
|
4106
4135
|
? buildSVGProps(values, style)
|
|
4107
|
-
:
|
|
4136
|
+
: buildHTMLProps(values, style, isStatic, !!props.drag);
|
|
4108
4137
|
return React.createElement(Component, tslib.__assign(tslib.__assign(tslib.__assign({}, forwardedProps), { ref: ref }), staticVisualStyles));
|
|
4109
4138
|
},
|
|
4110
4139
|
/**
|
|
@@ -4778,13 +4807,29 @@ function useDragControls() {
|
|
|
4778
4807
|
}
|
|
4779
4808
|
|
|
4780
4809
|
var PresenceChild = function (_a) {
|
|
4781
|
-
var children = _a.children,
|
|
4782
|
-
var
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4810
|
+
var children = _a.children, initial = _a.initial, isPresent = _a.isPresent, onExitComplete = _a.onExitComplete, custom = _a.custom;
|
|
4811
|
+
var numPresenceChildren = React.useRef(0);
|
|
4812
|
+
var numExitComplete = React.useRef(0);
|
|
4813
|
+
var context = {
|
|
4814
|
+
initial: initial,
|
|
4815
|
+
isPresent: isPresent,
|
|
4816
|
+
custom: custom,
|
|
4817
|
+
onExitComplete: function () {
|
|
4818
|
+
numExitComplete.current++;
|
|
4819
|
+
var allComplete = numExitComplete.current >= numPresenceChildren.current;
|
|
4820
|
+
onExitComplete && allComplete && onExitComplete();
|
|
4821
|
+
},
|
|
4822
|
+
};
|
|
4823
|
+
var register = React.useMemo(function () {
|
|
4824
|
+
numExitComplete.current = 0;
|
|
4825
|
+
return function () {
|
|
4826
|
+
numPresenceChildren.current++;
|
|
4827
|
+
return function () { return numPresenceChildren.current--; };
|
|
4828
|
+
};
|
|
4829
|
+
}, [isPresent]);
|
|
4830
|
+
return (React.createElement(PresenceContext.Provider, { value: tslib.__assign(tslib.__assign({}, context), { register: register }) }, children));
|
|
4831
|
+
};
|
|
4832
|
+
|
|
4788
4833
|
function getChildKey(child) {
|
|
4789
4834
|
return child.key || "";
|
|
4790
4835
|
}
|
|
@@ -4811,18 +4856,14 @@ function onlyElements(children) {
|
|
|
4811
4856
|
return filtered;
|
|
4812
4857
|
}
|
|
4813
4858
|
/**
|
|
4814
|
-
*
|
|
4815
|
-
* when they're removed from the component tree.
|
|
4816
|
-
*
|
|
4817
|
-
* When adding/removing more than a single child component, every component
|
|
4818
|
-
* **must** be given a unique `key` prop.
|
|
4859
|
+
* `AnimatePresence` enables the animation of components that have been removed from the tree.
|
|
4819
4860
|
*
|
|
4820
|
-
*
|
|
4861
|
+
* When adding/removing more than a single child, every child **must** be given a unique `key` prop.
|
|
4821
4862
|
*
|
|
4822
4863
|
* @library
|
|
4823
4864
|
*
|
|
4824
|
-
*
|
|
4825
|
-
*
|
|
4865
|
+
* Any `Frame` components that have an `exit` property defined will animate out when removed from
|
|
4866
|
+
* the tree.
|
|
4826
4867
|
*
|
|
4827
4868
|
* ```jsx
|
|
4828
4869
|
* import { Frame, AnimatePresence } from 'framer'
|
|
@@ -4844,10 +4885,12 @@ function onlyElements(children) {
|
|
|
4844
4885
|
* }
|
|
4845
4886
|
* ```
|
|
4846
4887
|
*
|
|
4888
|
+
* You can sequence exit animations throughout a tree using variants.
|
|
4889
|
+
*
|
|
4847
4890
|
* @motion
|
|
4848
4891
|
*
|
|
4849
|
-
*
|
|
4850
|
-
*
|
|
4892
|
+
* Any `motion` components that have an `exit` property defined will animate out when removed from
|
|
4893
|
+
* the tree.
|
|
4851
4894
|
*
|
|
4852
4895
|
* ```jsx
|
|
4853
4896
|
* import { motion, AnimatePresence } from 'framer-motion'
|
|
@@ -4866,6 +4909,12 @@ function onlyElements(children) {
|
|
|
4866
4909
|
* )
|
|
4867
4910
|
* ```
|
|
4868
4911
|
*
|
|
4912
|
+
* You can sequence exit animations throughout a tree using variants.
|
|
4913
|
+
*
|
|
4914
|
+
* If a child contains multiple `motion` components with `exit` props, it will only unmount the child
|
|
4915
|
+
* once all `motion` components have finished animating out. Likewise, any components using
|
|
4916
|
+
* `usePresence` all need to call `safeToRemove`.
|
|
4917
|
+
*
|
|
4869
4918
|
* @public
|
|
4870
4919
|
*/
|
|
4871
4920
|
var AnimatePresence = function (_a) {
|
|
@@ -4891,7 +4940,7 @@ var AnimatePresence = function (_a) {
|
|
|
4891
4940
|
// we play onMount animations or not.
|
|
4892
4941
|
if (isInitialRender.current) {
|
|
4893
4942
|
isInitialRender.current = false;
|
|
4894
|
-
return (React.createElement(React.Fragment, null, filteredChildren.map(function (child) { return (React.createElement(PresenceChild, { key: getChildKey(child),
|
|
4943
|
+
return (React.createElement(React.Fragment, null, filteredChildren.map(function (child) { return (React.createElement(PresenceChild, { key: getChildKey(child), isPresent: true, initial: initial ? undefined : false }, child)); })));
|
|
4895
4944
|
}
|
|
4896
4945
|
// If this is a subsequent render, deal with entering and exiting children
|
|
4897
4946
|
var childrenToRender = tslib.__spreadArrays(filteredChildren);
|
|
@@ -4938,18 +4987,13 @@ var AnimatePresence = function (_a) {
|
|
|
4938
4987
|
onExitComplete && onExitComplete();
|
|
4939
4988
|
}
|
|
4940
4989
|
};
|
|
4941
|
-
|
|
4942
|
-
custom: custom,
|
|
4943
|
-
isExiting: true,
|
|
4944
|
-
onExitComplete: onExit,
|
|
4945
|
-
};
|
|
4946
|
-
childrenToRender.splice(insertionIndex, 0, React.createElement(PresenceChild, { key: getChildKey(child), exitProps: exitProps }, child));
|
|
4990
|
+
childrenToRender.splice(insertionIndex, 0, React.createElement(PresenceChild, { key: getChildKey(child), isPresent: false, onExitComplete: onExit, custom: custom }, child));
|
|
4947
4991
|
});
|
|
4948
4992
|
// Add `MotionContext` even to children that don't need it to ensure we're rendering
|
|
4949
4993
|
// the same tree between renders
|
|
4950
4994
|
childrenToRender = childrenToRender.map(function (child) {
|
|
4951
4995
|
var key = child.key;
|
|
4952
|
-
return exiting.has(key) ? (child) : (React.createElement(PresenceChild, { key: getChildKey(child) }, child));
|
|
4996
|
+
return exiting.has(key) ? (child) : (React.createElement(PresenceChild, { key: getChildKey(child), isPresent: true }, child));
|
|
4953
4997
|
});
|
|
4954
4998
|
presentChildren.current = childrenToRender;
|
|
4955
4999
|
if (process.env.NODE_ENV !== "production" &&
|
|
@@ -4962,36 +5006,6 @@ var AnimatePresence = function (_a) {
|
|
|
4962
5006
|
: childrenToRender.map(function (child) { return React.cloneElement(child); })));
|
|
4963
5007
|
};
|
|
4964
5008
|
|
|
4965
|
-
/**
|
|
4966
|
-
* When a component is the child of an `AnimatePresence` component, it has access to
|
|
4967
|
-
* information about whether it's still present the React tree. `usePresence` can be
|
|
4968
|
-
* used to access that data and perform operations before the component can be considered
|
|
4969
|
-
* safe to remove.
|
|
4970
|
-
*
|
|
4971
|
-
* It returns two values. `isPresent` is a boolean that is `true` when the component
|
|
4972
|
-
* is present within the React tree. It is `false` when it's been removed, but still visible.
|
|
4973
|
-
*
|
|
4974
|
-
* When `isPresent` is `false`, the `safeToRemove` callback can be used to tell `AnimatePresence`
|
|
4975
|
-
* that it's safe to remove the component from the DOM, for instance after a animation has completed.
|
|
4976
|
-
*
|
|
4977
|
-
* ```jsx
|
|
4978
|
-
* const [isPresent, safeToRemove] = usePresence()
|
|
4979
|
-
*
|
|
4980
|
-
* useEffect(() => {
|
|
4981
|
-
* !isPresent setTimeout(safeToRemove, 1000)
|
|
4982
|
-
* }, [isPresent])
|
|
4983
|
-
* ```
|
|
4984
|
-
*
|
|
4985
|
-
* @public
|
|
4986
|
-
*/
|
|
4987
|
-
function usePresence() {
|
|
4988
|
-
var exitProps = React.useContext(MotionContext).exitProps;
|
|
4989
|
-
if (!exitProps)
|
|
4990
|
-
return [true];
|
|
4991
|
-
var isExiting = exitProps.isExiting, onExitComplete = exitProps.onExitComplete;
|
|
4992
|
-
return isExiting && onExitComplete ? [false, onExitComplete] : [true];
|
|
4993
|
-
}
|
|
4994
|
-
|
|
4995
5009
|
// Does this device prefer reduced motion? Returns `null` server-side.
|
|
4996
5010
|
var prefersReducedMotion = motionValue(null);
|
|
4997
5011
|
if (typeof window !== "undefined") {
|
package/dist/framer-motion.d.ts
CHANGED
|
@@ -17,18 +17,14 @@ import { SpringProps } from 'popmotion';
|
|
|
17
17
|
import { SVGAttributes } from 'react';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
21
|
-
* when they're removed from the component tree.
|
|
20
|
+
* `AnimatePresence` enables the animation of components that have been removed from the tree.
|
|
22
21
|
*
|
|
23
|
-
* When adding/removing more than a single child
|
|
24
|
-
* **must** be given a unique `key` prop.
|
|
25
|
-
*
|
|
26
|
-
* You can propagate exit animations throughout a tree by using variants.
|
|
22
|
+
* When adding/removing more than a single child, every child **must** be given a unique `key` prop.
|
|
27
23
|
*
|
|
28
24
|
* @library
|
|
29
25
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
26
|
+
* Any `Frame` components that have an `exit` property defined will animate out when removed from
|
|
27
|
+
* the tree.
|
|
32
28
|
*
|
|
33
29
|
* ```jsx
|
|
34
30
|
* import { Frame, AnimatePresence } from 'framer'
|
|
@@ -50,10 +46,12 @@ import { SVGAttributes } from 'react';
|
|
|
50
46
|
* }
|
|
51
47
|
* ```
|
|
52
48
|
*
|
|
49
|
+
* You can sequence exit animations throughout a tree using variants.
|
|
50
|
+
*
|
|
53
51
|
* @motion
|
|
54
52
|
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
53
|
+
* Any `motion` components that have an `exit` property defined will animate out when removed from
|
|
54
|
+
* the tree.
|
|
57
55
|
*
|
|
58
56
|
* ```jsx
|
|
59
57
|
* import { motion, AnimatePresence } from 'framer-motion'
|
|
@@ -72,6 +70,12 @@ import { SVGAttributes } from 'react';
|
|
|
72
70
|
* )
|
|
73
71
|
* ```
|
|
74
72
|
*
|
|
73
|
+
* You can sequence exit animations throughout a tree using variants.
|
|
74
|
+
*
|
|
75
|
+
* If a child contains multiple `motion` components with `exit` props, it will only unmount the child
|
|
76
|
+
* once all `motion` components have finished animating out. Likewise, any components using
|
|
77
|
+
* `usePresence` all need to call `safeToRemove`.
|
|
78
|
+
*
|
|
75
79
|
* @public
|
|
76
80
|
*/
|
|
77
81
|
export declare const AnimatePresence: FunctionComponent<AnimatePresenceProps>;
|
|
@@ -1406,13 +1410,6 @@ export declare interface EventInfo {
|
|
|
1406
1410
|
point: Point;
|
|
1407
1411
|
}
|
|
1408
1412
|
|
|
1409
|
-
declare interface ExitProps {
|
|
1410
|
-
initial?: false | VariantLabels;
|
|
1411
|
-
isExiting?: boolean;
|
|
1412
|
-
onExitComplete?: () => void;
|
|
1413
|
-
custom?: any;
|
|
1414
|
-
}
|
|
1415
|
-
|
|
1416
1413
|
/**
|
|
1417
1414
|
* @public
|
|
1418
1415
|
*/
|
|
@@ -2417,7 +2414,6 @@ declare interface MotionContextProps {
|
|
|
2417
2414
|
animate?: VariantLabels;
|
|
2418
2415
|
static?: boolean;
|
|
2419
2416
|
hasMounted?: RefObject<boolean>;
|
|
2420
|
-
exitProps?: ExitProps;
|
|
2421
2417
|
isReducedMotion?: boolean | undefined;
|
|
2422
2418
|
}
|
|
2423
2419
|
|
|
@@ -4944,25 +4940,26 @@ export declare function useMotionValue<T>(initial: T): MotionValue<T>;
|
|
|
4944
4940
|
export declare function usePanGesture({ onPan, onPanStart, onPanEnd, onPanSessionStart }: PanHandlers, ref: RefObject<Element>): void;
|
|
4945
4941
|
|
|
4946
4942
|
/**
|
|
4947
|
-
* When a component is the child of
|
|
4948
|
-
* information about whether it's still present the React tree.
|
|
4949
|
-
* used to access that data and perform operations before the component can be considered
|
|
4950
|
-
* safe to remove.
|
|
4943
|
+
* When a component is the child of `AnimatePresence`, it can use `usePresence`
|
|
4944
|
+
* to access information about whether it's still present in the React tree.
|
|
4951
4945
|
*
|
|
4952
|
-
*
|
|
4953
|
-
*
|
|
4946
|
+
* ```jsx
|
|
4947
|
+
* import { usePresence } from "framer-motion"
|
|
4954
4948
|
*
|
|
4955
|
-
*
|
|
4956
|
-
*
|
|
4949
|
+
* export const Component = () => {
|
|
4950
|
+
* const [isPresent, safeToRemove] = usePresence()
|
|
4957
4951
|
*
|
|
4958
|
-
*
|
|
4959
|
-
*
|
|
4952
|
+
* useEffect(() => {
|
|
4953
|
+
* !isPresent setTimeout(safeToRemove, 1000)
|
|
4954
|
+
* }, [isPresent])
|
|
4960
4955
|
*
|
|
4961
|
-
*
|
|
4962
|
-
*
|
|
4963
|
-
* }, [isPresent])
|
|
4956
|
+
* return <div />
|
|
4957
|
+
* }
|
|
4964
4958
|
* ```
|
|
4965
4959
|
*
|
|
4960
|
+
* If `isPresent` is `false`, it means that a component has been removed the tree, but
|
|
4961
|
+
* `AnimatePresence` won't really remove it until `safeToRemove` has been called.
|
|
4962
|
+
*
|
|
4966
4963
|
* @public
|
|
4967
4964
|
*/
|
|
4968
4965
|
export declare function usePresence(): Present | NotPresent;
|