framer-motion 10.4.0 → 10.5.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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var wrap = require('./wrap-58c66ad3.js');
5
+ var wrap = require('./wrap-bf172f81.js');
6
6
 
7
7
 
8
8
 
@@ -16,6 +16,7 @@ exports.circIn = wrap.circIn;
16
16
  exports.circInOut = wrap.circInOut;
17
17
  exports.circOut = wrap.circOut;
18
18
  exports.clamp = wrap.clamp;
19
+ exports.createScopedAnimate = wrap.createScopedAnimate;
19
20
  exports.cubicBezier = wrap.cubicBezier;
20
21
  exports.delay = wrap.delay;
21
22
  exports.distance = wrap.distance;
package/dist/cjs/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var React = require('react');
6
- var wrap = require('./wrap-58c66ad3.js');
6
+ var wrap = require('./wrap-bf172f81.js');
7
7
 
8
8
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
9
 
@@ -5557,6 +5557,18 @@ function animationControls() {
5557
5557
  return controls;
5558
5558
  }
5559
5559
 
5560
+ function useAnimate() {
5561
+ const scope = useConstant(() => ({
5562
+ current: null,
5563
+ animations: [],
5564
+ }));
5565
+ const animate = useConstant(() => wrap.createScopedAnimate(scope));
5566
+ useUnmountEffect(() => {
5567
+ scope.animations.forEach((animation) => animation.stop());
5568
+ });
5569
+ return [scope, animate];
5570
+ }
5571
+
5560
5572
  /**
5561
5573
  * Creates `AnimationControls`, which can be used to manually start, stop
5562
5574
  * and sequence animations on one or more components.
@@ -6074,6 +6086,7 @@ exports.clamp = wrap.clamp;
6074
6086
  exports.color = wrap.color;
6075
6087
  exports.complex = wrap.complex;
6076
6088
  exports.createBox = wrap.createBox;
6089
+ exports.createScopedAnimate = wrap.createScopedAnimate;
6077
6090
  exports.cubicBezier = wrap.cubicBezier;
6078
6091
  exports.delay = wrap.delay;
6079
6092
  exports.distance = wrap.distance;
@@ -6139,6 +6152,7 @@ exports.motion = motion;
6139
6152
  exports.resolveMotionValue = resolveMotionValue;
6140
6153
  exports.startOptimizedAppearAnimation = startOptimizedAppearAnimation;
6141
6154
  exports.unwrapMotionComponent = unwrapMotionComponent;
6155
+ exports.useAnimate = useAnimate;
6142
6156
  exports.useAnimation = useAnimation;
6143
6157
  exports.useAnimationControls = useAnimationControls;
6144
6158
  exports.useAnimationFrame = useAnimationFrame;
@@ -1930,12 +1930,18 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
1930
1930
  startTime = animationDriver.now() - newTime;
1931
1931
  }
1932
1932
  },
1933
+ get state() {
1934
+ return playState;
1935
+ },
1933
1936
  play,
1934
1937
  pause: () => {
1935
1938
  playState = "paused";
1936
1939
  holdTime = time;
1937
1940
  },
1938
1941
  stop: () => {
1942
+ if (playState === "idle")
1943
+ return;
1944
+ playState = "idle";
1939
1945
  onStop && onStop();
1940
1946
  animationDriver && animationDriver.stop();
1941
1947
  animationDriver = undefined;
@@ -2068,6 +2074,8 @@ function createAcceleratedAnimation(value, valueName, { onUpdate, onComplete, ..
2068
2074
  play: () => animation.play(),
2069
2075
  pause: () => animation.pause(),
2070
2076
  stop: () => {
2077
+ if (animation.playState === "idle")
2078
+ return;
2071
2079
  /**
2072
2080
  * WAAPI doesn't natively have any interruption capabilities.
2073
2081
  *
@@ -2488,7 +2496,7 @@ class MotionValue {
2488
2496
  * This will be replaced by the build step with the latest version number.
2489
2497
  * When MotionValues are provided to motion components, warn if versions are mixed.
2490
2498
  */
2491
- this.version = "10.4.0";
2499
+ this.version = "10.5.0";
2492
2500
  /**
2493
2501
  * Duration, in milliseconds, since last updating frame.
2494
2502
  *
@@ -3220,15 +3228,20 @@ function delay(callback, timeout) {
3220
3228
  return () => cancelSync.read(checkElapsed);
3221
3229
  }
3222
3230
 
3223
- function resolveElements(elements, selectorCache) {
3231
+ function resolveElements(elements, scope, selectorCache) {
3224
3232
  var _a;
3225
3233
  if (typeof elements === "string") {
3234
+ let root = document;
3235
+ if (scope) {
3236
+ exports.invariant(Boolean(scope.current), "Scope provided, but no element detected.");
3237
+ root = scope.current;
3238
+ }
3226
3239
  if (selectorCache) {
3227
- (_a = selectorCache[elements]) !== null && _a !== void 0 ? _a : (selectorCache[elements] = document.querySelectorAll(elements));
3240
+ (_a = selectorCache[elements]) !== null && _a !== void 0 ? _a : (selectorCache[elements] = root.querySelectorAll(elements));
3228
3241
  elements = selectorCache[elements];
3229
3242
  }
3230
3243
  else {
3231
- elements = document.querySelectorAll(elements);
3244
+ elements = root.querySelectorAll(elements);
3232
3245
  }
3233
3246
  }
3234
3247
  else if (elements instanceof Element) {
@@ -3628,7 +3641,7 @@ function updateMotionValuesFromProps(element, next, prev) {
3628
3641
  * and warn against mismatches.
3629
3642
  */
3630
3643
  if (process.env.NODE_ENV === "development") {
3631
- warnOnce(nextValue.version === "10.4.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 10.4.0 may not work as expected.`);
3644
+ warnOnce(nextValue.version === "10.5.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 10.5.0 may not work as expected.`);
3632
3645
  }
3633
3646
  }
3634
3647
  else if (isMotionValue(prevValue)) {
@@ -4304,8 +4317,8 @@ function animateSingleValue(value, keyframes, options) {
4304
4317
  return motionValue$1.animation;
4305
4318
  }
4306
4319
 
4307
- function animateElements(elementOrSelector, keyframes, options) {
4308
- const elements = resolveElements(elementOrSelector);
4320
+ function animateElements(elementOrSelector, keyframes, options, scope) {
4321
+ const elements = resolveElements(elementOrSelector, scope);
4309
4322
  const numElements = elements.length;
4310
4323
  exports.invariant(Boolean(numElements), "No valid element provided.");
4311
4324
  const animations = [];
@@ -4328,14 +4341,23 @@ function animateElements(elementOrSelector, keyframes, options) {
4328
4341
  }
4329
4342
  return new GroupPlaybackControls(animations);
4330
4343
  }
4331
- function animate(valueOrElement, keyframes, options = {}) {
4332
- if (isDOMKeyframes(keyframes)) {
4333
- return animateElements(valueOrElement, keyframes, options);
4334
- }
4335
- else {
4336
- return animateSingleValue(valueOrElement, keyframes, options);
4344
+ const createScopedAnimate = (scope) => {
4345
+ function scopedAnimate(valueOrElement, keyframes, options = {}) {
4346
+ let animation;
4347
+ if (isDOMKeyframes(keyframes)) {
4348
+ animation = animateElements(valueOrElement, keyframes, options, scope);
4349
+ }
4350
+ else {
4351
+ animation = animateSingleValue(valueOrElement, keyframes, options);
4352
+ }
4353
+ if (scope) {
4354
+ scope.animations.push(animation);
4355
+ }
4356
+ return animation;
4337
4357
  }
4338
- }
4358
+ return scopedAnimate;
4359
+ };
4360
+ const animate = createScopedAnimate();
4339
4361
 
4340
4362
  const resizeHandlers = new WeakMap();
4341
4363
  let observer;
@@ -4850,6 +4872,7 @@ exports.convertBoundingBoxToBox = convertBoundingBoxToBox;
4850
4872
  exports.convertBoxToBoundingBox = convertBoxToBoundingBox;
4851
4873
  exports.createBox = createBox;
4852
4874
  exports.createDelta = createDelta;
4875
+ exports.createScopedAnimate = createScopedAnimate;
4853
4876
  exports.cssVariableRegex = cssVariableRegex;
4854
4877
  exports.cubicBezier = cubicBezier;
4855
4878
  exports.delay = delay;
@@ -807,8 +807,12 @@ interface AnimationPlaybackLifecycles<V> {
807
807
  onRepeat?: () => void;
808
808
  onStop?: () => void;
809
809
  }
810
+ interface AnimationScope<T = any> {
811
+ readonly current: T;
812
+ animations: AnimationPlaybackControls[];
813
+ }
810
814
  declare type AnimateOptions<V = any> = Transition & AnimationPlaybackLifecycles<V>;
811
- declare type ElementOrSelector$1 = Element | Element[] | NodeListOf<Element> | string;
815
+ declare type ElementOrSelector = Element | Element[] | NodeListOf<Element> | string;
812
816
  /**
813
817
  * @public
814
818
  */
@@ -1005,20 +1009,20 @@ declare class MotionValue<V = any> {
1005
1009
  }
1006
1010
  declare function motionValue<V>(init: V, options?: MotionValueOptions): MotionValue<V>;
1007
1011
 
1008
- /**
1009
- * Animate a single value
1010
- */
1011
- declare function animate(from: string, to: string | GenericKeyframesTarget<string>, options?: AnimateOptions<string>): AnimationPlaybackControls;
1012
- declare function animate(from: number, to: number | GenericKeyframesTarget<number>, options?: AnimateOptions<number>): AnimationPlaybackControls;
1013
- /**
1014
- * Animate a MotionValue
1015
- */
1016
- declare function animate(value: MotionValue<string>, keyframes: string | GenericKeyframesTarget<string>, options?: AnimateOptions<string>): AnimationPlaybackControls;
1017
- declare function animate(value: MotionValue<number>, keyframes: number | GenericKeyframesTarget<number>, options?: AnimateOptions<number>): AnimationPlaybackControls;
1018
- /**
1019
- * Animate DOM
1020
- */
1021
- declare function animate<V>(value: ElementOrSelector$1, keyframes: DOMKeyframesDefinition, options?: AnimateOptions<V>): AnimationPlaybackControls;
1012
+ declare const createScopedAnimate: (scope?: AnimationScope) => {
1013
+ (from: string, to: string | GenericKeyframesTarget<string>, options?: AnimateOptions<string>): AnimationPlaybackControls;
1014
+ (from: number, to: number | GenericKeyframesTarget<number>, options?: AnimateOptions<number>): AnimationPlaybackControls;
1015
+ (value: MotionValue<string>, keyframes: string | GenericKeyframesTarget<string>, options?: AnimateOptions<string>): AnimationPlaybackControls;
1016
+ (value: MotionValue<number>, keyframes: number | GenericKeyframesTarget<number>, options?: AnimateOptions<number>): AnimationPlaybackControls;
1017
+ <V>(value: ElementOrSelector, keyframes: DOMKeyframesDefinition, options?: AnimateOptions<V> | undefined): AnimationPlaybackControls;
1018
+ };
1019
+ declare const animate: {
1020
+ (from: string, to: string | GenericKeyframesTarget<string>, options?: AnimateOptions<string>): AnimationPlaybackControls;
1021
+ (from: number, to: number | GenericKeyframesTarget<number>, options?: AnimateOptions<number>): AnimationPlaybackControls;
1022
+ (value: MotionValue<string>, keyframes: string | GenericKeyframesTarget<string>, options?: AnimateOptions<string>): AnimationPlaybackControls;
1023
+ (value: MotionValue<number>, keyframes: number | GenericKeyframesTarget<number>, options?: AnimateOptions<number>): AnimationPlaybackControls;
1024
+ <V>(value: ElementOrSelector, keyframes: DOMKeyframesDefinition, options?: AnimateOptions<V> | undefined): AnimationPlaybackControls;
1025
+ };
1022
1026
 
1023
1027
  interface AxisScrollInfo {
1024
1028
  current: number;
@@ -1056,8 +1060,6 @@ interface ScrollOptions {
1056
1060
 
1057
1061
  declare function scroll(onScroll: OnScroll, { container, ...options }?: ScrollOptions): () => void;
1058
1062
 
1059
- declare type ElementOrSelector = Element | Element[] | NodeListOf<Element> | string;
1060
-
1061
1063
  declare type ViewChangeHandler = (entry: IntersectionObserverEntry) => void;
1062
1064
  interface InViewOptions {
1063
1065
  root?: Element | Document;
@@ -1234,4 +1236,4 @@ declare const frameData: {
1234
1236
  isProcessing: boolean;
1235
1237
  };
1236
1238
 
1237
- export { DelayedFunction, DevMessage, InterpolateOptions, MixerFactory, MotionValue, PassiveEffect, Subscriber, animate, anticipate, backIn, backInOut, backOut, circIn, circInOut, circOut, clamp, cubicBezier, delay, distance, distance2D, easeIn, easeInOut, easeOut, frameData, inView, interpolate, invariant, mix, motionValue, pipe, progress, scroll, sync, transform, warning, wrap };
1239
+ export { DelayedFunction, DevMessage, InterpolateOptions, MixerFactory, MotionValue, PassiveEffect, Subscriber, animate, anticipate, backIn, backInOut, backOut, circIn, circInOut, circOut, clamp, createScopedAnimate, cubicBezier, delay, distance, distance2D, easeIn, easeInOut, easeOut, frameData, inView, interpolate, invariant, mix, motionValue, pipe, progress, scroll, sync, transform, warning, wrap };
@@ -7,8 +7,8 @@ import { animateTarget } from './interfaces/visual-element-target.mjs';
7
7
  import { createVisualElement } from './utils/create-visual-element.mjs';
8
8
  import { animateSingleValue } from './interfaces/single-value.mjs';
9
9
 
10
- function animateElements(elementOrSelector, keyframes, options) {
11
- const elements = resolveElements(elementOrSelector);
10
+ function animateElements(elementOrSelector, keyframes, options, scope) {
11
+ const elements = resolveElements(elementOrSelector, scope);
12
12
  const numElements = elements.length;
13
13
  invariant(Boolean(numElements), "No valid element provided.");
14
14
  const animations = [];
@@ -31,13 +31,22 @@ function animateElements(elementOrSelector, keyframes, options) {
31
31
  }
32
32
  return new GroupPlaybackControls(animations);
33
33
  }
34
- function animate(valueOrElement, keyframes, options = {}) {
35
- if (isDOMKeyframes(keyframes)) {
36
- return animateElements(valueOrElement, keyframes, options);
37
- }
38
- else {
39
- return animateSingleValue(valueOrElement, keyframes, options);
34
+ const createScopedAnimate = (scope) => {
35
+ function scopedAnimate(valueOrElement, keyframes, options = {}) {
36
+ let animation;
37
+ if (isDOMKeyframes(keyframes)) {
38
+ animation = animateElements(valueOrElement, keyframes, options, scope);
39
+ }
40
+ else {
41
+ animation = animateSingleValue(valueOrElement, keyframes, options);
42
+ }
43
+ if (scope) {
44
+ scope.animations.push(animation);
45
+ }
46
+ return animation;
40
47
  }
41
- }
48
+ return scopedAnimate;
49
+ };
50
+ const animate = createScopedAnimate();
42
51
 
43
- export { animate };
52
+ export { animate, createScopedAnimate };
@@ -215,12 +215,18 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
215
215
  startTime = animationDriver.now() - newTime;
216
216
  }
217
217
  },
218
+ get state() {
219
+ return playState;
220
+ },
218
221
  play,
219
222
  pause: () => {
220
223
  playState = "paused";
221
224
  holdTime = time;
222
225
  },
223
226
  stop: () => {
227
+ if (playState === "idle")
228
+ return;
229
+ playState = "idle";
224
230
  onStop && onStop();
225
231
  animationDriver && animationDriver.stop();
226
232
  animationDriver = undefined;
@@ -126,6 +126,8 @@ function createAcceleratedAnimation(value, valueName, { onUpdate, onComplete, ..
126
126
  play: () => animation.play(),
127
127
  pause: () => animation.pause(),
128
128
  stop: () => {
129
+ if (animation.playState === "idle")
130
+ return;
129
131
  /**
130
132
  * WAAPI doesn't natively have any interruption capabilities.
131
133
  *
@@ -0,0 +1,17 @@
1
+ import { useConstant } from '../../utils/use-constant.mjs';
2
+ import { useUnmountEffect } from '../../utils/use-unmount-effect.mjs';
3
+ import { createScopedAnimate } from '../animate.mjs';
4
+
5
+ function useAnimate() {
6
+ const scope = useConstant(() => ({
7
+ current: null,
8
+ animations: [],
9
+ }));
10
+ const animate = useConstant(() => createScopedAnimate(scope));
11
+ useUnmountEffect(() => {
12
+ scope.animations.forEach((animation) => animation.stop());
13
+ });
14
+ return [scope, animate];
15
+ }
16
+
17
+ export { useAnimate };
@@ -1,5 +1,5 @@
1
1
  export { MotionValue, motionValue } from './value/index.mjs';
2
- export { animate } from './animation/animate.mjs';
2
+ export { animate, createScopedAnimate } from './animation/animate.mjs';
3
3
  export { scroll } from './render/dom/scroll/index.mjs';
4
4
  export { inView } from './render/dom/viewport/index.mjs';
5
5
  export { anticipate } from './easing/anticipate.mjs';
package/dist/es/index.mjs CHANGED
@@ -22,6 +22,7 @@ export { useMotionValueEvent } from './utils/use-motion-value-event.mjs';
22
22
  export { useReducedMotion } from './utils/reduced-motion/use-reduced-motion.mjs';
23
23
  export { useReducedMotionConfig } from './utils/reduced-motion/use-reduced-motion-config.mjs';
24
24
  export { animationControls } from './animation/hooks/animation-controls.mjs';
25
+ export { useAnimate } from './animation/hooks/use-animate.mjs';
25
26
  export { useAnimation, useAnimationControls } from './animation/hooks/use-animation.mjs';
26
27
  export { useAnimationFrame } from './utils/use-animation-frame.mjs';
27
28
  export { animateVisualElement } from './animation/interfaces/visual-element.mjs';
@@ -58,7 +59,7 @@ export { useAnimatedState as useDeprecatedAnimatedState } from './animation/hook
58
59
  export { useInvertedScale as useDeprecatedInvertedScale } from './value/use-inverted-scale.mjs';
59
60
  export { AnimateSharedLayout } from './components/AnimateSharedLayout.mjs';
60
61
  export { MotionValue, motionValue } from './value/index.mjs';
61
- export { animate } from './animation/animate.mjs';
62
+ export { animate, createScopedAnimate } from './animation/animate.mjs';
62
63
  export { scroll } from './render/dom/scroll/index.mjs';
63
64
  export { inView } from './render/dom/viewport/index.mjs';
64
65
  export { transform } from './utils/transform.mjs';
@@ -1,12 +1,19 @@
1
- function resolveElements(elements, selectorCache) {
1
+ import { invariant } from '../../../utils/errors.mjs';
2
+
3
+ function resolveElements(elements, scope, selectorCache) {
2
4
  var _a;
3
5
  if (typeof elements === "string") {
6
+ let root = document;
7
+ if (scope) {
8
+ invariant(Boolean(scope.current), "Scope provided, but no element detected.");
9
+ root = scope.current;
10
+ }
4
11
  if (selectorCache) {
5
- (_a = selectorCache[elements]) !== null && _a !== void 0 ? _a : (selectorCache[elements] = document.querySelectorAll(elements));
12
+ (_a = selectorCache[elements]) !== null && _a !== void 0 ? _a : (selectorCache[elements] = root.querySelectorAll(elements));
6
13
  elements = selectorCache[elements];
7
14
  }
8
15
  else {
9
- elements = document.querySelectorAll(elements);
16
+ elements = root.querySelectorAll(elements);
10
17
  }
11
18
  }
12
19
  else if (elements instanceof Element) {
@@ -22,7 +22,7 @@ function updateMotionValuesFromProps(element, next, prev) {
22
22
  * and warn against mismatches.
23
23
  */
24
24
  if (process.env.NODE_ENV === "development") {
25
- warnOnce(nextValue.version === "10.4.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 10.4.0 may not work as expected.`);
25
+ warnOnce(nextValue.version === "10.5.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 10.5.0 may not work as expected.`);
26
26
  }
27
27
  }
28
28
  else if (isMotionValue(prevValue)) {
@@ -26,7 +26,7 @@ class MotionValue {
26
26
  * This will be replaced by the build step with the latest version number.
27
27
  * When MotionValues are provided to motion components, warn if versions are mixed.
28
28
  */
29
- this.version = "10.4.0";
29
+ this.version = "10.5.0";
30
30
  /**
31
31
  * Duration, in milliseconds, since last updating frame.
32
32
  *
@@ -3101,12 +3101,18 @@
3101
3101
  startTime = animationDriver.now() - newTime;
3102
3102
  }
3103
3103
  },
3104
+ get state() {
3105
+ return playState;
3106
+ },
3104
3107
  play,
3105
3108
  pause: () => {
3106
3109
  playState = "paused";
3107
3110
  holdTime = time;
3108
3111
  },
3109
3112
  stop: () => {
3113
+ if (playState === "idle")
3114
+ return;
3115
+ playState = "idle";
3110
3116
  onStop && onStop();
3111
3117
  animationDriver && animationDriver.stop();
3112
3118
  animationDriver = undefined;
@@ -3239,6 +3245,8 @@
3239
3245
  play: () => animation.play(),
3240
3246
  pause: () => animation.pause(),
3241
3247
  stop: () => {
3248
+ if (animation.playState === "idle")
3249
+ return;
3242
3250
  /**
3243
3251
  * WAAPI doesn't natively have any interruption capabilities.
3244
3252
  *
@@ -3659,7 +3667,7 @@
3659
3667
  * This will be replaced by the build step with the latest version number.
3660
3668
  * When MotionValues are provided to motion components, warn if versions are mixed.
3661
3669
  */
3662
- this.version = "10.4.0";
3670
+ this.version = "10.5.0";
3663
3671
  /**
3664
3672
  * Duration, in milliseconds, since last updating frame.
3665
3673
  *
@@ -5996,15 +6004,20 @@
5996
6004
  }
5997
6005
  }
5998
6006
 
5999
- function resolveElements(elements, selectorCache) {
6007
+ function resolveElements(elements, scope, selectorCache) {
6000
6008
  var _a;
6001
6009
  if (typeof elements === "string") {
6010
+ let root = document;
6011
+ if (scope) {
6012
+ exports.invariant(Boolean(scope.current), "Scope provided, but no element detected.");
6013
+ root = scope.current;
6014
+ }
6002
6015
  if (selectorCache) {
6003
- (_a = selectorCache[elements]) !== null && _a !== void 0 ? _a : (selectorCache[elements] = document.querySelectorAll(elements));
6016
+ (_a = selectorCache[elements]) !== null && _a !== void 0 ? _a : (selectorCache[elements] = root.querySelectorAll(elements));
6004
6017
  elements = selectorCache[elements];
6005
6018
  }
6006
6019
  else {
6007
- elements = document.querySelectorAll(elements);
6020
+ elements = root.querySelectorAll(elements);
6008
6021
  }
6009
6022
  }
6010
6023
  else if (elements instanceof Element) {
@@ -6404,7 +6417,7 @@
6404
6417
  * and warn against mismatches.
6405
6418
  */
6406
6419
  {
6407
- warnOnce(nextValue.version === "10.4.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 10.4.0 may not work as expected.`);
6420
+ warnOnce(nextValue.version === "10.5.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 10.5.0 may not work as expected.`);
6408
6421
  }
6409
6422
  }
6410
6423
  else if (isMotionValue(prevValue)) {
@@ -7079,8 +7092,8 @@
7079
7092
  return motionValue$1.animation;
7080
7093
  }
7081
7094
 
7082
- function animateElements(elementOrSelector, keyframes, options) {
7083
- const elements = resolveElements(elementOrSelector);
7095
+ function animateElements(elementOrSelector, keyframes, options, scope) {
7096
+ const elements = resolveElements(elementOrSelector, scope);
7084
7097
  const numElements = elements.length;
7085
7098
  exports.invariant(Boolean(numElements), "No valid element provided.");
7086
7099
  const animations = [];
@@ -7103,14 +7116,23 @@
7103
7116
  }
7104
7117
  return new GroupPlaybackControls(animations);
7105
7118
  }
7106
- function animate(valueOrElement, keyframes, options = {}) {
7107
- if (isDOMKeyframes(keyframes)) {
7108
- return animateElements(valueOrElement, keyframes, options);
7109
- }
7110
- else {
7111
- return animateSingleValue(valueOrElement, keyframes, options);
7119
+ const createScopedAnimate = (scope) => {
7120
+ function scopedAnimate(valueOrElement, keyframes, options = {}) {
7121
+ let animation;
7122
+ if (isDOMKeyframes(keyframes)) {
7123
+ animation = animateElements(valueOrElement, keyframes, options, scope);
7124
+ }
7125
+ else {
7126
+ animation = animateSingleValue(valueOrElement, keyframes, options);
7127
+ }
7128
+ if (scope) {
7129
+ scope.animations.push(animation);
7130
+ }
7131
+ return animation;
7112
7132
  }
7113
- }
7133
+ return scopedAnimate;
7134
+ };
7135
+ const animate = createScopedAnimate();
7114
7136
 
7115
7137
  const resizeHandlers = new WeakMap();
7116
7138
  let observer;
@@ -10369,6 +10391,18 @@
10369
10391
  return controls;
10370
10392
  }
10371
10393
 
10394
+ function useAnimate() {
10395
+ const scope = useConstant(() => ({
10396
+ current: null,
10397
+ animations: [],
10398
+ }));
10399
+ const animate = useConstant(() => createScopedAnimate(scope));
10400
+ useUnmountEffect(() => {
10401
+ scope.animations.forEach((animation) => animation.stop());
10402
+ });
10403
+ return [scope, animate];
10404
+ }
10405
+
10372
10406
  /**
10373
10407
  * Creates `AnimationControls`, which can be used to manually start, stop
10374
10408
  * and sequence animations on one or more components.
@@ -10908,6 +10942,7 @@
10908
10942
  exports.createBox = createBox;
10909
10943
  exports.createDomMotionComponent = createDomMotionComponent;
10910
10944
  exports.createMotionComponent = createMotionComponent;
10945
+ exports.createScopedAnimate = createScopedAnimate;
10911
10946
  exports.cubicBezier = cubicBezier;
10912
10947
  exports.delay = delay;
10913
10948
  exports.distance = distance;
@@ -10942,6 +10977,7 @@
10942
10977
  exports.sync = sync;
10943
10978
  exports.transform = transform;
10944
10979
  exports.unwrapMotionComponent = unwrapMotionComponent;
10980
+ exports.useAnimate = useAnimate;
10945
10981
  exports.useAnimation = useAnimation;
10946
10982
  exports.useAnimationControls = useAnimationControls;
10947
10983
  exports.useAnimationFrame = useAnimationFrame;