framer-motion 2.1.4 → 2.2.0

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.
@@ -3653,251 +3653,55 @@ function useVisualElementAnimation(visualElement, props, config) {
3653
3653
  }
3654
3654
 
3655
3655
  /**
3656
- * @internal
3656
+ * @public
3657
3657
  */
3658
- var MotionPluginContext = React.createContext({
3658
+ var MotionConfigContext = React.createContext({
3659
3659
  transformPagePoint: function (p) { return p; },
3660
3660
  features: [],
3661
3661
  });
3662
3662
  /**
3663
- * @remarks For now I think this should remain a private API for our own use
3664
- * until we can figure out a nicer way of allowing people to add these
3665
- *
3666
- * @internal
3667
- */
3668
- function MotionPlugins(_a) {
3669
- var children = _a.children, props = tslib.__rest(_a, ["children"]);
3670
- var pluginContext = React.useContext(MotionPluginContext);
3671
- var value = React.useRef(tslib.__assign({}, pluginContext)).current;
3672
- // Mutative to prevent triggering rerenders in all listening
3673
- // components every time this component renders
3674
- for (var key in props) {
3675
- value[key] = props[key];
3676
- }
3677
- return (React.createElement(MotionPluginContext.Provider, { value: value }, children));
3678
- }
3679
-
3680
- var AnimatePropType;
3681
- (function (AnimatePropType) {
3682
- AnimatePropType["Target"] = "Target";
3683
- AnimatePropType["VariantLabel"] = "VariantLabel";
3684
- AnimatePropType["AnimationSubscription"] = "AnimationSubscription";
3685
- })(AnimatePropType || (AnimatePropType = {}));
3686
-
3687
- var makeRenderlessComponent = function (hook) { return function (props) {
3688
- hook(props);
3689
- return null;
3690
- }; };
3691
-
3692
- function shallowCompare(next, prev) {
3693
- if (prev === null)
3694
- return false;
3695
- var prevLength = prev.length;
3696
- if (prevLength !== next.length)
3697
- return false;
3698
- for (var i = 0; i < prevLength; i++) {
3699
- if (prev[i] !== next[i])
3700
- return false;
3701
- }
3702
- return true;
3703
- }
3704
-
3705
- var hasUpdated = function (prev, next) {
3706
- return (next !== undefined &&
3707
- (Array.isArray(prev) && Array.isArray(next)
3708
- ? !shallowCompare(next, prev)
3709
- : prev !== next));
3710
- };
3711
- function targetWithoutTransition(_a, mergeTransitionEnd) {
3712
- if (mergeTransitionEnd === void 0) { mergeTransitionEnd = false; }
3713
- var transition = _a.transition, transitionEnd = _a.transitionEnd, target = tslib.__rest(_a, ["transition", "transitionEnd"]);
3714
- return mergeTransitionEnd
3715
- ? tslib.__assign(tslib.__assign({}, target), transitionEnd)
3716
- : target;
3717
- }
3718
- /**
3719
- * Handle the `animate` prop when its an object of values, ie:
3663
+ * MotionConfig can be used in combination with the `m` component to cut bundle size
3664
+ * and dynamically load only the features you use.
3720
3665
  *
3721
3666
  * ```jsx
3722
- * <motion.div animate={{ opacity: 1 }} />
3723
- * ```
3724
- *
3725
- * @internalremarks
3726
- * It might be worth consolidating this with `use-variants`
3667
+ * import {
3668
+ * m as motion,
3669
+ * AnimationFeature,
3670
+ * MotionConfig
3671
+ * } from "framer-motion"
3727
3672
  *
3728
- * ```jsx
3729
- * <motion.div animate="visible" />
3673
+ * export function App() {
3674
+ * return (
3675
+ * <MotionConfig features={[AnimationFeature]}>
3676
+ * <motion.div animate={{ x: 100 }} />
3677
+ * </MotionConfig>
3678
+ * )
3679
+ * }
3730
3680
  * ```
3731
3681
  *
3732
- * @param target
3733
- * @param controls
3734
- * @param values
3735
- * @param transition
3736
- *
3737
- * @internal
3738
- */
3739
- function useAnimateProp(targetAndTransition, controls, visualElement, defaultTransition) {
3740
- var isInitialRender = React.useRef(true);
3741
- var prevValues = React.useRef(null);
3742
- if (!prevValues.current) {
3743
- prevValues.current = targetWithoutTransition(targetAndTransition, true);
3744
- }
3745
- React.useEffect(function () {
3746
- var targetToAnimate = {};
3747
- // These are the values we're actually animating
3748
- var animatingTarget = targetWithoutTransition(targetAndTransition);
3749
- // This is the target as it'll be once transitionEnd values are applied
3750
- var finalTarget = targetWithoutTransition(targetAndTransition, true);
3751
- // Detect which values have changed between renders
3752
- for (var key in animatingTarget) {
3753
- // This value should animate on mount if this value doesn't already exist (wasn't
3754
- // defined in `style` or `initial`) or if it does exist and it's already changed.
3755
- var shouldAnimateOnMount = isInitialRender.current &&
3756
- (!visualElement.hasValue(key) ||
3757
- visualElement.getValue(key).get() !== finalTarget[key]);
3758
- // If this value has updated between renders or it's we're animating this value on mount,
3759
- // add it to the animate target.
3760
- var isValidValue = finalTarget[key] !== null;
3761
- var valueHasUpdated = hasUpdated(prevValues.current[key], finalTarget[key]);
3762
- if (isValidValue && (valueHasUpdated || shouldAnimateOnMount)) {
3763
- targetToAnimate[key] = animatingTarget[key];
3764
- }
3765
- }
3766
- isInitialRender.current = false;
3767
- prevValues.current = tslib.__assign(tslib.__assign({}, prevValues.current), finalTarget);
3768
- if (Object.keys(targetToAnimate).length) {
3769
- controls.start(tslib.__assign(tslib.__assign({}, targetToAnimate), { transition: targetAndTransition.transition || defaultTransition, transitionEnd: targetAndTransition.transitionEnd }));
3770
- }
3771
- }, [targetAndTransition]);
3772
- }
3773
-
3774
- var labelsToArray = function (label) {
3775
- if (!label) {
3776
- return [];
3777
- }
3778
- if (Array.isArray(label)) {
3779
- return label;
3780
- }
3781
- return [label];
3782
- };
3783
- var resolveVariantLabels = function (variant) {
3784
- var unresolvedVariant = variant instanceof MotionValue ? variant.get() : variant;
3785
- return Array.from(new Set(labelsToArray(unresolvedVariant)));
3786
- };
3787
- /**
3788
- * Hooks in React sometimes accept a dependency array as their final argument. (ie useEffect/useMemo)
3789
- * When values in this array change, React re-runs the dependency. However if the array
3790
- * contains a variable number of items, React throws an error.
3791
- */
3792
- var asDependencyList = function (list) { return [
3793
- list.join(","),
3794
- ]; };
3795
-
3796
- var hasVariantChanged = function (oldVariant, newVariant) {
3797
- return oldVariant.join(",") !== newVariant.join(",");
3798
- };
3799
- /**
3800
- * Handle variants and the `animate` prop when its set as variant labels.
3801
- *
3802
- * @param initial - Initial variant(s)
3803
- * @param animate - Variant(s) to animate to
3804
- * @param inherit - `true` is inheriting animations from parent
3805
- * @param controls - Animation controls
3806
- *
3807
- * @internal
3808
- */
3809
- function useVariants(initial, animate, inherit, controls) {
3810
- var targetVariants = resolveVariantLabels(animate);
3811
- var context = React.useContext(MotionContext);
3812
- var parentAlreadyMounted = context.hasMounted && context.hasMounted.current;
3813
- var hasMounted = React.useRef(false);
3814
- React.useEffect(function () {
3815
- var shouldAnimate = false;
3816
- if (inherit) {
3817
- // If we're inheriting variant changes and the parent has already
3818
- // mounted when this component loads, we need to manually trigger
3819
- // this animation.
3820
- shouldAnimate = !!parentAlreadyMounted;
3821
- targetVariants = resolveVariantLabels(context.animate);
3822
- }
3823
- else {
3824
- shouldAnimate =
3825
- hasMounted.current ||
3826
- hasVariantChanged(resolveVariantLabels(initial), targetVariants);
3827
- }
3828
- shouldAnimate && controls.start(targetVariants);
3829
- hasMounted.current = true;
3830
- }, asDependencyList(targetVariants));
3831
- }
3832
-
3833
- /**
3834
- * `useAnimationGroupSubscription` allows a component to subscribe to an
3835
- * externally-created `AnimationControls`, created by the `useAnimation` hook.
3836
- *
3837
- * @param animation
3838
- * @param controls
3839
- *
3840
- * @internal
3682
+ * @public
3841
3683
  */
3842
- function useAnimationGroupSubscription(animation, controls) {
3843
- var unsubscribe = React.useMemo(function () { return animation.subscribe(controls); }, [
3844
- animation,
3684
+ function MotionConfig(_a) {
3685
+ var children = _a.children, _b = _a.features, features = _b === void 0 ? [] : _b, props = tslib.__rest(_a, ["children", "features"]);
3686
+ var pluginContext = React.useContext(MotionConfigContext);
3687
+ var loadedFeatures = tslib.__spreadArrays(pluginContext.features, features);
3688
+ // We do want to rerender children when the number of loaded features changes
3689
+ var value = React.useMemo(function () { return ({ features: loadedFeatures }); }, [
3690
+ loadedFeatures.length,
3845
3691
  ]);
3846
- React.useEffect(function () { return function () {
3847
- unsubscribe && unsubscribe();
3848
- }; }, [unsubscribe]);
3849
- }
3850
-
3851
- var _a, _b;
3852
- var AnimatePropComponents = (_a = {},
3853
- _a[AnimatePropType.Target] = makeRenderlessComponent(function (_a) {
3854
- var animate = _a.animate, controls = _a.controls, visualElement = _a.visualElement, transition = _a.transition;
3855
- return useAnimateProp(animate, controls, visualElement, transition);
3856
- }),
3857
- _a[AnimatePropType.VariantLabel] = makeRenderlessComponent(function (_a) {
3858
- var animate = _a.animate, _b = _a.inherit, inherit = _b === void 0 ? true : _b, controls = _a.controls, initial = _a.initial;
3859
- return useVariants(initial, animate, inherit, controls);
3860
- }),
3861
- _a[AnimatePropType.AnimationSubscription] = makeRenderlessComponent(function (_a) {
3862
- var animate = _a.animate, controls = _a.controls;
3863
- return useAnimationGroupSubscription(animate, controls);
3864
- }),
3865
- _a);
3866
- var isVariantLabel$1 = function (prop) {
3867
- return Array.isArray(prop) || typeof prop === "string";
3868
- };
3869
- var isAnimationSubscription = function (_a) {
3870
- var animate = _a.animate;
3871
- return animate instanceof AnimationControls;
3872
- };
3873
- var animationProps = ["initial", "animate", "whileTap", "whileHover"];
3874
- var animatePropTypeTests = (_b = {},
3875
- _b[AnimatePropType.Target] = function (props) {
3876
- return (props.animate !== undefined &&
3877
- !isVariantLabel$1(props.animate) &&
3878
- !isAnimationSubscription(props));
3879
- },
3880
- _b[AnimatePropType.VariantLabel] = function (props) {
3881
- return (props.variants !== undefined ||
3882
- animationProps.some(function (key) { return typeof props[key] === "string"; }));
3883
- },
3884
- _b[AnimatePropType.AnimationSubscription] = isAnimationSubscription,
3885
- _b);
3886
- var getAnimationComponent = function (props) {
3887
- var animatePropType = undefined;
3888
- for (var key in AnimatePropType) {
3889
- if (animatePropTypeTests[key](props)) {
3890
- animatePropType = key;
3891
- }
3692
+ // Mutative to prevent triggering rerenders in all listening
3693
+ // components every time this component renders
3694
+ for (var key in props) {
3695
+ value[key] = props[key];
3892
3696
  }
3893
- return animatePropType ? AnimatePropComponents[animatePropType] : undefined;
3894
- };
3697
+ return (React.createElement(MotionConfigContext.Provider, { value: value }, children));
3698
+ }
3895
3699
 
3896
3700
  /**
3897
3701
  * Load features via renderless components based on the provided MotionProps
3898
3702
  */
3899
3703
  function useFeatures(defaultFeatures, isStatic, visualElement, controls, props, context, parentContext, shouldInheritVariant) {
3900
- var plugins = React.useContext(MotionPluginContext);
3704
+ var plugins = React.useContext(MotionConfigContext);
3901
3705
  // If this is a static component, or we're rendering on the server, we don't load
3902
3706
  // any feature components
3903
3707
  if (isStatic || typeof window === "undefined")
@@ -3905,16 +3709,13 @@ function useFeatures(defaultFeatures, isStatic, visualElement, controls, props,
3905
3709
  var allFeatures = tslib.__spreadArrays(defaultFeatures, plugins.features);
3906
3710
  var numFeatures = allFeatures.length;
3907
3711
  var features = [];
3908
- // TODO: Consolidate Animation feature loading strategy with other functionality components
3909
- var Animation = getAnimationComponent(props);
3910
- if (Animation) {
3911
- features.push(React.createElement(Animation, { key: "animation", initial: props.initial, animate: props.animate, variants: props.variants, transition: props.transition, controls: controls, inherit: shouldInheritVariant, visualElement: visualElement }));
3912
- }
3913
3712
  // Decide which features we should render and add them to the returned array
3914
3713
  for (var i = 0; i < numFeatures; i++) {
3915
- var _a = allFeatures[i], shouldRender = _a.shouldRender, key = _a.key, Component = _a.Component;
3714
+ var _a = allFeatures[i], shouldRender = _a.shouldRender, key = _a.key, getComponent = _a.getComponent;
3916
3715
  if (shouldRender(props, parentContext)) {
3917
- features.push(React.createElement(Component, tslib.__assign({ key: key }, props, { localContext: context, parentContext: parentContext, visualElement: visualElement, controls: controls })));
3716
+ var Component = getComponent(props);
3717
+ Component &&
3718
+ features.push(React.createElement(Component, tslib.__assign({ key: key }, props, { localContext: context, parentContext: parentContext, visualElement: visualElement, controls: controls, inherit: shouldInheritVariant })));
3918
3719
  }
3919
3720
  }
3920
3721
  return features;
@@ -4941,7 +4742,7 @@ function getCurrentDirection(offset, lockThreshold) {
4941
4742
  */
4942
4743
  function useDrag(props, visualElement) {
4943
4744
  var groupDragControls = props.dragControls;
4944
- var transformPagePoint = React.useContext(MotionPluginContext).transformPagePoint;
4745
+ var transformPagePoint = React.useContext(MotionConfigContext).transformPagePoint;
4945
4746
  var dragControls = useConstant(function () {
4946
4747
  return new VisualElementDragControls({
4947
4748
  visualElement: visualElement,
@@ -4955,13 +4756,22 @@ function useDrag(props, visualElement) {
4955
4756
  React.useEffect(function () { return dragControls.mount(visualElement); }, []);
4956
4757
  }
4957
4758
 
4759
+ var makeRenderlessComponent = function (hook) { return function (props) {
4760
+ hook(props);
4761
+ return null;
4762
+ }; };
4763
+
4764
+ var Component = makeRenderlessComponent(function (_a) {
4765
+ var visualElement = _a.visualElement, props = tslib.__rest(_a, ["visualElement"]);
4766
+ return useDrag(props, visualElement);
4767
+ });
4768
+ /**
4769
+ * @public
4770
+ */
4958
4771
  var Drag = {
4959
4772
  key: "drag",
4960
4773
  shouldRender: function (props) { return !!props.drag; },
4961
- Component: makeRenderlessComponent(function (_a) {
4962
- var visualElement = _a.visualElement, props = tslib.__rest(_a, ["visualElement"]);
4963
- return useDrag(props, visualElement);
4964
- }),
4774
+ getComponent: function () { return Component; },
4965
4775
  };
4966
4776
 
4967
4777
  /**
@@ -4980,7 +4790,7 @@ function usePanGesture(_a, ref) {
4980
4790
  var onPan = _a.onPan, onPanStart = _a.onPanStart, onPanEnd = _a.onPanEnd, onPanSessionStart = _a.onPanSessionStart;
4981
4791
  var hasPanEvents = onPan || onPanStart || onPanEnd || onPanSessionStart;
4982
4792
  var panSession = React.useRef(null);
4983
- var transformPagePoint = React.useContext(MotionPluginContext).transformPagePoint;
4793
+ var transformPagePoint = React.useContext(MotionConfigContext).transformPagePoint;
4984
4794
  var handlers = {
4985
4795
  onSessionStart: onPanSessionStart,
4986
4796
  onStart: onPanStart,
@@ -5145,47 +4955,274 @@ var gestureProps = [
5145
4955
  "onHoverStart",
5146
4956
  "onHoverEnd",
5147
4957
  ];
4958
+ var GestureComponent = makeRenderlessComponent(function (_a) {
4959
+ var visualElement = _a.visualElement, props = tslib.__rest(_a, ["visualElement"]);
4960
+ useGestures(props, visualElement);
4961
+ });
4962
+ /**
4963
+ * @public
4964
+ */
5148
4965
  var Gestures = {
5149
4966
  key: "gestures",
5150
4967
  shouldRender: function (props) {
5151
4968
  return gestureProps.some(function (key) { return props.hasOwnProperty(key); });
5152
4969
  },
5153
- Component: makeRenderlessComponent(function (_a) {
5154
- var visualElement = _a.visualElement, props = tslib.__rest(_a, ["visualElement"]);
5155
- useGestures(props, visualElement);
5156
- }),
4970
+ getComponent: function () { return GestureComponent; },
5157
4971
  };
5158
4972
 
4973
+ var ExitComponent = makeRenderlessComponent(function (props) {
4974
+ var animate = props.animate, controls = props.controls, exit = props.exit;
4975
+ var _a = usePresence(), isPresent = _a[0], onExitComplete = _a[1];
4976
+ var presenceContext = React.useContext(PresenceContext);
4977
+ var isPlayingExitAnimation = React.useRef(false);
4978
+ var custom = (presenceContext === null || presenceContext === void 0 ? void 0 : presenceContext.custom) !== undefined
4979
+ ? presenceContext.custom
4980
+ : props.custom;
4981
+ React.useEffect(function () {
4982
+ if (!isPresent) {
4983
+ if (!isPlayingExitAnimation.current && exit) {
4984
+ controls.setProps(tslib.__assign(tslib.__assign({}, props), { custom: custom }));
4985
+ controls.start(exit).then(onExitComplete);
4986
+ }
4987
+ isPlayingExitAnimation.current = true;
4988
+ }
4989
+ else if (isPlayingExitAnimation.current &&
4990
+ animate &&
4991
+ typeof animate !== "boolean" &&
4992
+ !(animate instanceof AnimationControls)) {
4993
+ controls.start(animate);
4994
+ }
4995
+ if (isPresent) {
4996
+ isPlayingExitAnimation.current = false;
4997
+ }
4998
+ }, [animate, controls, custom, exit, isPresent, onExitComplete, props]);
4999
+ });
5000
+ /**
5001
+ * @public
5002
+ */
5159
5003
  var Exit = {
5160
5004
  key: "exit",
5161
5005
  shouldRender: function (props) { return !!props.exit && !checkShouldInheritVariant(props); },
5162
- Component: makeRenderlessComponent(function (props) {
5163
- var animate = props.animate, controls = props.controls, exit = props.exit;
5164
- var _a = usePresence(), isPresent = _a[0], onExitComplete = _a[1];
5165
- var presenceContext = React.useContext(PresenceContext);
5166
- var isPlayingExitAnimation = React.useRef(false);
5167
- var custom = (presenceContext === null || presenceContext === void 0 ? void 0 : presenceContext.custom) !== undefined
5168
- ? presenceContext.custom
5169
- : props.custom;
5170
- React.useEffect(function () {
5171
- if (!isPresent) {
5172
- if (!isPlayingExitAnimation.current && exit) {
5173
- controls.setProps(tslib.__assign(tslib.__assign({}, props), { custom: custom }));
5174
- controls.start(exit).then(onExitComplete);
5175
- }
5176
- isPlayingExitAnimation.current = true;
5177
- }
5178
- else if (isPlayingExitAnimation.current &&
5179
- animate &&
5180
- typeof animate !== "boolean" &&
5181
- !(animate instanceof AnimationControls)) {
5182
- controls.start(animate);
5183
- }
5184
- if (isPresent) {
5185
- isPlayingExitAnimation.current = false;
5006
+ getComponent: function () { return ExitComponent; },
5007
+ };
5008
+
5009
+ var AnimatePropType;
5010
+ (function (AnimatePropType) {
5011
+ AnimatePropType["Target"] = "Target";
5012
+ AnimatePropType["VariantLabel"] = "VariantLabel";
5013
+ AnimatePropType["AnimationSubscription"] = "AnimationSubscription";
5014
+ })(AnimatePropType || (AnimatePropType = {}));
5015
+
5016
+ function shallowCompare(next, prev) {
5017
+ if (prev === null)
5018
+ return false;
5019
+ var prevLength = prev.length;
5020
+ if (prevLength !== next.length)
5021
+ return false;
5022
+ for (var i = 0; i < prevLength; i++) {
5023
+ if (prev[i] !== next[i])
5024
+ return false;
5025
+ }
5026
+ return true;
5027
+ }
5028
+
5029
+ var hasUpdated = function (prev, next) {
5030
+ return (next !== undefined &&
5031
+ (Array.isArray(prev) && Array.isArray(next)
5032
+ ? !shallowCompare(next, prev)
5033
+ : prev !== next));
5034
+ };
5035
+ function targetWithoutTransition(_a, mergeTransitionEnd) {
5036
+ if (mergeTransitionEnd === void 0) { mergeTransitionEnd = false; }
5037
+ var transition = _a.transition, transitionEnd = _a.transitionEnd, target = tslib.__rest(_a, ["transition", "transitionEnd"]);
5038
+ return mergeTransitionEnd
5039
+ ? tslib.__assign(tslib.__assign({}, target), transitionEnd)
5040
+ : target;
5041
+ }
5042
+ /**
5043
+ * Handle the `animate` prop when its an object of values, ie:
5044
+ *
5045
+ * ```jsx
5046
+ * <motion.div animate={{ opacity: 1 }} />
5047
+ * ```
5048
+ *
5049
+ * @internalremarks
5050
+ * It might be worth consolidating this with `use-variants`
5051
+ *
5052
+ * ```jsx
5053
+ * <motion.div animate="visible" />
5054
+ * ```
5055
+ *
5056
+ * @param target
5057
+ * @param controls
5058
+ * @param values
5059
+ * @param transition
5060
+ *
5061
+ * @internal
5062
+ */
5063
+ function useAnimateProp(targetAndTransition, controls, visualElement, defaultTransition) {
5064
+ var isInitialRender = React.useRef(true);
5065
+ var prevValues = React.useRef(null);
5066
+ if (!prevValues.current) {
5067
+ prevValues.current = targetWithoutTransition(targetAndTransition, true);
5068
+ }
5069
+ React.useEffect(function () {
5070
+ var targetToAnimate = {};
5071
+ // These are the values we're actually animating
5072
+ var animatingTarget = targetWithoutTransition(targetAndTransition);
5073
+ // This is the target as it'll be once transitionEnd values are applied
5074
+ var finalTarget = targetWithoutTransition(targetAndTransition, true);
5075
+ // Detect which values have changed between renders
5076
+ for (var key in animatingTarget) {
5077
+ // This value should animate on mount if this value doesn't already exist (wasn't
5078
+ // defined in `style` or `initial`) or if it does exist and it's already changed.
5079
+ var shouldAnimateOnMount = isInitialRender.current &&
5080
+ (!visualElement.hasValue(key) ||
5081
+ visualElement.getValue(key).get() !== finalTarget[key]);
5082
+ // If this value has updated between renders or it's we're animating this value on mount,
5083
+ // add it to the animate target.
5084
+ var isValidValue = finalTarget[key] !== null;
5085
+ var valueHasUpdated = hasUpdated(prevValues.current[key], finalTarget[key]);
5086
+ if (isValidValue && (valueHasUpdated || shouldAnimateOnMount)) {
5087
+ targetToAnimate[key] = animatingTarget[key];
5186
5088
  }
5187
- }, [animate, controls, custom, exit, isPresent, onExitComplete, props]);
5089
+ }
5090
+ isInitialRender.current = false;
5091
+ prevValues.current = tslib.__assign(tslib.__assign({}, prevValues.current), finalTarget);
5092
+ if (Object.keys(targetToAnimate).length) {
5093
+ controls.start(tslib.__assign(tslib.__assign({}, targetToAnimate), { transition: targetAndTransition.transition || defaultTransition, transitionEnd: targetAndTransition.transitionEnd }));
5094
+ }
5095
+ }, [targetAndTransition]);
5096
+ }
5097
+
5098
+ var labelsToArray = function (label) {
5099
+ if (!label) {
5100
+ return [];
5101
+ }
5102
+ if (Array.isArray(label)) {
5103
+ return label;
5104
+ }
5105
+ return [label];
5106
+ };
5107
+ var resolveVariantLabels = function (variant) {
5108
+ var unresolvedVariant = variant instanceof MotionValue ? variant.get() : variant;
5109
+ return Array.from(new Set(labelsToArray(unresolvedVariant)));
5110
+ };
5111
+ /**
5112
+ * Hooks in React sometimes accept a dependency array as their final argument. (ie useEffect/useMemo)
5113
+ * When values in this array change, React re-runs the dependency. However if the array
5114
+ * contains a variable number of items, React throws an error.
5115
+ */
5116
+ var asDependencyList = function (list) { return [
5117
+ list.join(","),
5118
+ ]; };
5119
+
5120
+ var hasVariantChanged = function (oldVariant, newVariant) {
5121
+ return oldVariant.join(",") !== newVariant.join(",");
5122
+ };
5123
+ /**
5124
+ * Handle variants and the `animate` prop when its set as variant labels.
5125
+ *
5126
+ * @param initial - Initial variant(s)
5127
+ * @param animate - Variant(s) to animate to
5128
+ * @param inherit - `true` is inheriting animations from parent
5129
+ * @param controls - Animation controls
5130
+ *
5131
+ * @internal
5132
+ */
5133
+ function useVariants(initial, animate, inherit, controls) {
5134
+ var targetVariants = resolveVariantLabels(animate);
5135
+ var context = React.useContext(MotionContext);
5136
+ var parentAlreadyMounted = context.hasMounted && context.hasMounted.current;
5137
+ var hasMounted = React.useRef(false);
5138
+ React.useEffect(function () {
5139
+ var shouldAnimate = false;
5140
+ if (inherit) {
5141
+ // If we're inheriting variant changes and the parent has already
5142
+ // mounted when this component loads, we need to manually trigger
5143
+ // this animation.
5144
+ shouldAnimate = !!parentAlreadyMounted;
5145
+ targetVariants = resolveVariantLabels(context.animate);
5146
+ }
5147
+ else {
5148
+ shouldAnimate =
5149
+ hasMounted.current ||
5150
+ hasVariantChanged(resolveVariantLabels(initial), targetVariants);
5151
+ }
5152
+ shouldAnimate && controls.start(targetVariants);
5153
+ hasMounted.current = true;
5154
+ }, asDependencyList(targetVariants));
5155
+ }
5156
+
5157
+ /**
5158
+ * `useAnimationGroupSubscription` allows a component to subscribe to an
5159
+ * externally-created `AnimationControls`, created by the `useAnimation` hook.
5160
+ *
5161
+ * @param animation
5162
+ * @param controls
5163
+ *
5164
+ * @internal
5165
+ */
5166
+ function useAnimationGroupSubscription(animation, controls) {
5167
+ var unsubscribe = React.useMemo(function () { return animation.subscribe(controls); }, [
5168
+ animation,
5169
+ ]);
5170
+ React.useEffect(function () { return function () {
5171
+ unsubscribe && unsubscribe();
5172
+ }; }, [unsubscribe]);
5173
+ }
5174
+
5175
+ var _a, _b;
5176
+ var AnimatePropComponents = (_a = {},
5177
+ _a[AnimatePropType.Target] = makeRenderlessComponent(function (_a) {
5178
+ var animate = _a.animate, controls = _a.controls, visualElement = _a.visualElement, transition = _a.transition;
5179
+ return useAnimateProp(animate, controls, visualElement, transition);
5180
+ }),
5181
+ _a[AnimatePropType.VariantLabel] = makeRenderlessComponent(function (_a) {
5182
+ var animate = _a.animate, _b = _a.inherit, inherit = _b === void 0 ? true : _b, controls = _a.controls, initial = _a.initial;
5183
+ return useVariants(initial, animate, inherit, controls);
5188
5184
  }),
5185
+ _a[AnimatePropType.AnimationSubscription] = makeRenderlessComponent(function (_a) {
5186
+ var animate = _a.animate, controls = _a.controls;
5187
+ return useAnimationGroupSubscription(animate, controls);
5188
+ }),
5189
+ _a);
5190
+ var isVariantLabel$1 = function (prop) {
5191
+ return Array.isArray(prop) || typeof prop === "string";
5192
+ };
5193
+ var isAnimationSubscription = function (_a) {
5194
+ var animate = _a.animate;
5195
+ return animate instanceof AnimationControls;
5196
+ };
5197
+ var animationProps = ["initial", "animate", "whileTap", "whileHover"];
5198
+ var animatePropTypeTests = (_b = {},
5199
+ _b[AnimatePropType.Target] = function (props) {
5200
+ return (props.animate !== undefined &&
5201
+ !isVariantLabel$1(props.animate) &&
5202
+ !isAnimationSubscription(props));
5203
+ },
5204
+ _b[AnimatePropType.VariantLabel] = function (props) {
5205
+ return (props.variants !== undefined ||
5206
+ animationProps.some(function (key) { return typeof props[key] === "string"; }));
5207
+ },
5208
+ _b[AnimatePropType.AnimationSubscription] = isAnimationSubscription,
5209
+ _b);
5210
+ var getAnimationComponent = function (props) {
5211
+ var animatePropType = undefined;
5212
+ for (var key in AnimatePropType) {
5213
+ if (animatePropTypeTests[key](props)) {
5214
+ animatePropType = key;
5215
+ }
5216
+ }
5217
+ return animatePropType ? AnimatePropComponents[animatePropType] : undefined;
5218
+ };
5219
+ /**
5220
+ * @public
5221
+ */
5222
+ var Animation = {
5223
+ key: "animation",
5224
+ shouldRender: function () { return true; },
5225
+ getComponent: getAnimationComponent,
5189
5226
  };
5190
5227
 
5191
5228
  function tweenAxis(target, prev, next, p) {
@@ -5342,14 +5379,10 @@ var Animate = /** @class */ (function (_super) {
5342
5379
  };
5343
5380
  return Animate;
5344
5381
  }(React.Component));
5345
- var AnimateLayout = {
5346
- key: "animate-layout",
5347
- shouldRender: function (props) { return !!props.layout || !!props.layoutId; },
5348
- Component: function (props) {
5349
- var _a = usePresence(), safeToRemove = _a[1];
5350
- return React.createElement(Animate, tslib.__assign({}, props, { safeToRemove: safeToRemove }));
5351
- },
5352
- };
5382
+ function AnimateLayoutContextProvider(props) {
5383
+ var _a = usePresence(), safeToRemove = _a[1];
5384
+ return React.createElement(Animate, tslib.__assign({}, props, { safeToRemove: safeToRemove }));
5385
+ }
5353
5386
  function hasMoved(a, b) {
5354
5387
  return hasAxisMoved(a.x, b.x) || hasAxisMoved(a.y, b.y);
5355
5388
  }
@@ -5372,6 +5405,14 @@ function compress(min, max, easing) {
5372
5405
  }
5373
5406
  var easeCrossfadeIn = compress(0, 0.5, popcorn.circOut);
5374
5407
  var easeCrossfadeOut = compress(0.5, 0.95, popcorn.linear);
5408
+ /**
5409
+ * @public
5410
+ */
5411
+ var AnimateLayout = {
5412
+ key: "animate-layout",
5413
+ shouldRender: function (props) { return !!props.layout || !!props.layoutId; },
5414
+ getComponent: function () { return AnimateLayoutContextProvider; },
5415
+ };
5375
5416
 
5376
5417
  /**
5377
5418
  * This component is responsible for scheduling the measuring of the motion component
@@ -5420,15 +5461,16 @@ var Measure = /** @class */ (function (_super) {
5420
5461
  };
5421
5462
  return Measure;
5422
5463
  }(React__default.Component));
5464
+ function MeasureContextProvider(props) {
5465
+ var syncLayout = React.useContext(SharedLayoutContext);
5466
+ return React__default.createElement(Measure, tslib.__assign({}, props, { syncLayout: syncLayout }));
5467
+ }
5423
5468
  var MeasureLayout = {
5424
5469
  key: "measure-layout",
5425
5470
  shouldRender: function (props) {
5426
5471
  return !!props.drag || !!props.layout || !!props.layoutId;
5427
5472
  },
5428
- Component: function (props) {
5429
- var syncLayout = React.useContext(SharedLayoutContext);
5430
- return React__default.createElement(Measure, tslib.__assign({}, props, { syncLayout: syncLayout }));
5431
- },
5473
+ getComponent: function () { return MeasureContextProvider; },
5432
5474
  };
5433
5475
 
5434
5476
  /**
@@ -5476,6 +5518,7 @@ function createMotionProxy(defaultFeatures) {
5476
5518
  */
5477
5519
  var motion = /*@__PURE__*/ createMotionProxy([
5478
5520
  MeasureLayout,
5521
+ Animation,
5479
5522
  Drag,
5480
5523
  Gestures,
5481
5524
  Exit,
@@ -5484,7 +5527,7 @@ var motion = /*@__PURE__*/ createMotionProxy([
5484
5527
  /**
5485
5528
  * @public
5486
5529
  */
5487
- var m = /*@__PURE__*/ createMotionProxy([]);
5530
+ var m = /*@__PURE__*/ createMotionProxy([MeasureLayout]);
5488
5531
 
5489
5532
  function useForceUpdate() {
5490
5533
  var _a = React.useState(0), forcedRenderCount = _a[0], setForcedRenderCount = _a[1];
@@ -6884,13 +6927,18 @@ function useAnimatedState(initialState) {
6884
6927
  return [animationState, startAnimation];
6885
6928
  }
6886
6929
 
6930
+ exports.AnimateLayoutFeature = AnimateLayout;
6887
6931
  exports.AnimatePresence = AnimatePresence;
6888
6932
  exports.AnimateSharedLayout = AnimateSharedLayout;
6889
6933
  exports.AnimationControls = AnimationControls;
6934
+ exports.AnimationFeature = Animation;
6890
6935
  exports.DragControls = DragControls;
6936
+ exports.DragFeature = Drag;
6937
+ exports.ExitFeature = Exit;
6938
+ exports.GesturesFeature = Gestures;
6939
+ exports.MotionConfig = MotionConfig;
6940
+ exports.MotionConfigContext = MotionConfigContext;
6891
6941
  exports.MotionContext = MotionContext;
6892
- exports.MotionPluginContext = MotionPluginContext;
6893
- exports.MotionPlugins = MotionPlugins;
6894
6942
  exports.MotionValue = MotionValue;
6895
6943
  exports.PresenceContext = PresenceContext;
6896
6944
  exports.ReducedMotion = ReducedMotion;