framer-motion 11.11.0 → 11.11.2

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.
@@ -1788,6 +1788,8 @@ const isEasingArray = (ease) => {
1788
1788
  return Array.isArray(ease) && typeof ease[0] !== "number";
1789
1789
  };
1790
1790
 
1791
+ const isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
1792
+
1791
1793
  const easingLookup = {
1792
1794
  linear: noop,
1793
1795
  easeIn,
@@ -1802,7 +1804,7 @@ const easingLookup = {
1802
1804
  anticipate,
1803
1805
  };
1804
1806
  const easingDefinitionToFunction = (definition) => {
1805
- if (Array.isArray(definition)) {
1807
+ if (isBezierDefinition(definition)) {
1806
1808
  // If cubic bezier definition, create bezier curve
1807
1809
  invariant(definition.length === 4, `Cubic bezier arrays must contain four numerical values.`);
1808
1810
  const [x1, y1, x2, y2] = definition;
@@ -2593,8 +2595,6 @@ const acceleratedValues = new Set([
2593
2595
  // "background-color"
2594
2596
  ]);
2595
2597
 
2596
- const isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
2597
-
2598
2598
  // Create a linear easing point for every 10 ms
2599
2599
  const resolution = 10;
2600
2600
  const generateLinearEasing = (easing, duration // as milliseconds
@@ -3279,7 +3279,7 @@ class MotionValue {
3279
3279
  * This will be replaced by the build step with the latest version number.
3280
3280
  * When MotionValues are provided to motion components, warn if versions are mixed.
3281
3281
  */
3282
- this.version = "11.11.0";
3282
+ this.version = "11.11.2";
3283
3283
  /**
3284
3284
  * Tracks whether this value can output a velocity. Currently this is only true
3285
3285
  * if the value is numerical, but we might be able to widen the scope here and support
@@ -5877,7 +5877,7 @@ function updateMotionValuesFromProps(element, next, prev) {
5877
5877
  * and warn against mismatches.
5878
5878
  */
5879
5879
  if (process.env.NODE_ENV === "development") {
5880
- warnOnce(nextValue.version === "11.11.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 11.11.0 may not work as expected.`);
5880
+ warnOnce(nextValue.version === "11.11.2", `Attempting to mix Framer Motion versions ${nextValue.version} with 11.11.2 may not work as expected.`);
5881
5881
  }
5882
5882
  }
5883
5883
  else if (isMotionValue(prevValue)) {
@@ -8971,9 +8971,8 @@ const useIsomorphicLayoutEffect = isBrowser ? react.useLayoutEffect : react.useE
8971
8971
 
8972
8972
  const LazyContext = react.createContext({ strict: false });
8973
8973
 
8974
- let scheduleHandoffComplete = false;
8975
8974
  function useVisualElement(Component, visualState, props, createVisualElement, ProjectionNodeConstructor) {
8976
- var _a;
8975
+ var _a, _b;
8977
8976
  const { visualElement: parent } = react.useContext(MotionContext);
8978
8977
  const lazyContext = react.useContext(LazyContext);
8979
8978
  const presenceContext = react.useContext(PresenceContext);
@@ -9016,11 +9015,12 @@ function useVisualElement(Component, visualState, props, createVisualElement, Pr
9016
9015
  */
9017
9016
  const optimisedAppearId = props[optimizedAppearDataAttribute];
9018
9017
  const wantsHandoff = react.useRef(Boolean(optimisedAppearId) &&
9019
- !window.MotionHandoffIsComplete &&
9020
- ((_a = window.MotionHasOptimisedAnimation) === null || _a === void 0 ? void 0 : _a.call(window, optimisedAppearId)));
9018
+ !((_a = window.MotionHandoffIsComplete) === null || _a === void 0 ? void 0 : _a.call(window, optimisedAppearId)) &&
9019
+ ((_b = window.MotionHasOptimisedAnimation) === null || _b === void 0 ? void 0 : _b.call(window, optimisedAppearId)));
9021
9020
  useIsomorphicLayoutEffect(() => {
9022
9021
  if (!visualElement)
9023
9022
  return;
9023
+ window.MotionIsMounted = true;
9024
9024
  visualElement.updateFeatures();
9025
9025
  microtask.render(visualElement.render);
9026
9026
  /**
@@ -9043,18 +9043,17 @@ function useVisualElement(Component, visualState, props, createVisualElement, Pr
9043
9043
  if (!wantsHandoff.current && visualElement.animationState) {
9044
9044
  visualElement.animationState.animateChanges();
9045
9045
  }
9046
- wantsHandoff.current = false;
9047
- // This ensures all future calls to animateChanges() will run in useEffect
9048
- if (!scheduleHandoffComplete) {
9049
- scheduleHandoffComplete = true;
9050
- queueMicrotask(completeHandoff);
9046
+ if (wantsHandoff.current) {
9047
+ // This ensures all future calls to animateChanges() in this component will run in useEffect
9048
+ queueMicrotask(() => {
9049
+ var _a;
9050
+ (_a = window.MotionHandoffMarkAsComplete) === null || _a === void 0 ? void 0 : _a.call(window, optimisedAppearId);
9051
+ });
9052
+ wantsHandoff.current = false;
9051
9053
  }
9052
9054
  });
9053
9055
  return visualElement;
9054
9056
  }
9055
- function completeHandoff() {
9056
- window.MotionHandoffIsComplete = true;
9057
- }
9058
9057
  function createProjectionNode(visualElement, props, ProjectionNodeConstructor, initialPromotionConfig) {
9059
9058
  const { layoutId, layout, drag, dragConstraints, layoutScroll, layoutRoot, } = props;
9060
9059
  visualElement.projection = new ProjectionNodeConstructor(visualElement.latestValues, props["data-framer-portal-id"]
package/dist/cjs/dom.js CHANGED
@@ -279,7 +279,7 @@ class MotionValue {
279
279
  * This will be replaced by the build step with the latest version number.
280
280
  * When MotionValues are provided to motion components, warn if versions are mixed.
281
281
  */
282
- this.version = "11.11.0";
282
+ this.version = "11.11.2";
283
283
  /**
284
284
  * Tracks whether this value can output a velocity. Currently this is only true
285
285
  * if the value is numerical, but we might be able to widen the scope here and support
@@ -2571,6 +2571,8 @@ const easeIn = /*@__PURE__*/ cubicBezier(0.42, 0, 1, 1);
2571
2571
  const easeOut = /*@__PURE__*/ cubicBezier(0, 0, 0.58, 1);
2572
2572
  const easeInOut = /*@__PURE__*/ cubicBezier(0.42, 0, 0.58, 1);
2573
2573
 
2574
+ const isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
2575
+
2574
2576
  const easingLookup = {
2575
2577
  linear: noop,
2576
2578
  easeIn,
@@ -2585,7 +2587,7 @@ const easingLookup = {
2585
2587
  anticipate,
2586
2588
  };
2587
2589
  const easingDefinitionToFunction = (definition) => {
2588
- if (Array.isArray(definition)) {
2590
+ if (isBezierDefinition(definition)) {
2589
2591
  // If cubic bezier definition, create bezier curve
2590
2592
  exports.invariant(definition.length === 4, `Cubic bezier arrays must contain four numerical values.`);
2591
2593
  const [x1, y1, x2, y2] = definition;
@@ -3304,8 +3306,6 @@ const acceleratedValues = new Set([
3304
3306
  // "background-color"
3305
3307
  ]);
3306
3308
 
3307
- const isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
3308
-
3309
3309
  // Create a linear easing point for every 10 ms
3310
3310
  const resolution = 10;
3311
3311
  const generateLinearEasing = (easing, duration // as milliseconds
@@ -4106,7 +4106,7 @@ function updateMotionValuesFromProps(element, next, prev) {
4106
4106
  * and warn against mismatches.
4107
4107
  */
4108
4108
  if (process.env.NODE_ENV === "development") {
4109
- warnOnce(nextValue.version === "11.11.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 11.11.0 may not work as expected.`);
4109
+ warnOnce(nextValue.version === "11.11.2", `Attempting to mix Framer Motion versions ${nextValue.version} with 11.11.2 may not work as expected.`);
4110
4110
  }
4111
4111
  }
4112
4112
  else if (isMotionValue(prevValue)) {
package/dist/cjs/index.js CHANGED
@@ -1858,6 +1858,8 @@ const isEasingArray = (ease) => {
1858
1858
  return Array.isArray(ease) && typeof ease[0] !== "number";
1859
1859
  };
1860
1860
 
1861
+ const isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
1862
+
1861
1863
  const easingLookup = {
1862
1864
  linear: noop,
1863
1865
  easeIn,
@@ -1872,7 +1874,7 @@ const easingLookup = {
1872
1874
  anticipate,
1873
1875
  };
1874
1876
  const easingDefinitionToFunction = (definition) => {
1875
- if (Array.isArray(definition)) {
1877
+ if (isBezierDefinition(definition)) {
1876
1878
  // If cubic bezier definition, create bezier curve
1877
1879
  exports.invariant(definition.length === 4, `Cubic bezier arrays must contain four numerical values.`);
1878
1880
  const [x1, y1, x2, y2] = definition;
@@ -2667,8 +2669,6 @@ const acceleratedValues = new Set([
2667
2669
  // "background-color"
2668
2670
  ]);
2669
2671
 
2670
- const isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
2671
-
2672
2672
  // Create a linear easing point for every 10 ms
2673
2673
  const resolution = 10;
2674
2674
  const generateLinearEasing = (easing, duration // as milliseconds
@@ -3362,7 +3362,7 @@ class MotionValue {
3362
3362
  * This will be replaced by the build step with the latest version number.
3363
3363
  * When MotionValues are provided to motion components, warn if versions are mixed.
3364
3364
  */
3365
- this.version = "11.11.0";
3365
+ this.version = "11.11.2";
3366
3366
  /**
3367
3367
  * Tracks whether this value can output a velocity. Currently this is only true
3368
3368
  * if the value is numerical, but we might be able to widen the scope here and support
@@ -6305,7 +6305,7 @@ function updateMotionValuesFromProps(element, next, prev) {
6305
6305
  * and warn against mismatches.
6306
6306
  */
6307
6307
  if (process.env.NODE_ENV === "development") {
6308
- warnOnce(nextValue.version === "11.11.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 11.11.0 may not work as expected.`);
6308
+ warnOnce(nextValue.version === "11.11.2", `Attempting to mix Framer Motion versions ${nextValue.version} with 11.11.2 may not work as expected.`);
6309
6309
  }
6310
6310
  }
6311
6311
  else if (isMotionValue(prevValue)) {
@@ -10467,9 +10467,8 @@ const useIsomorphicLayoutEffect = isBrowser ? React.useLayoutEffect : React.useE
10467
10467
 
10468
10468
  const LazyContext = React.createContext({ strict: false });
10469
10469
 
10470
- let scheduleHandoffComplete = false;
10471
10470
  function useVisualElement(Component, visualState, props, createVisualElement, ProjectionNodeConstructor) {
10472
- var _a;
10471
+ var _a, _b;
10473
10472
  const { visualElement: parent } = React.useContext(MotionContext);
10474
10473
  const lazyContext = React.useContext(LazyContext);
10475
10474
  const presenceContext = React.useContext(PresenceContext);
@@ -10512,11 +10511,12 @@ function useVisualElement(Component, visualState, props, createVisualElement, Pr
10512
10511
  */
10513
10512
  const optimisedAppearId = props[optimizedAppearDataAttribute];
10514
10513
  const wantsHandoff = React.useRef(Boolean(optimisedAppearId) &&
10515
- !window.MotionHandoffIsComplete &&
10516
- ((_a = window.MotionHasOptimisedAnimation) === null || _a === void 0 ? void 0 : _a.call(window, optimisedAppearId)));
10514
+ !((_a = window.MotionHandoffIsComplete) === null || _a === void 0 ? void 0 : _a.call(window, optimisedAppearId)) &&
10515
+ ((_b = window.MotionHasOptimisedAnimation) === null || _b === void 0 ? void 0 : _b.call(window, optimisedAppearId)));
10517
10516
  useIsomorphicLayoutEffect(() => {
10518
10517
  if (!visualElement)
10519
10518
  return;
10519
+ window.MotionIsMounted = true;
10520
10520
  visualElement.updateFeatures();
10521
10521
  microtask.render(visualElement.render);
10522
10522
  /**
@@ -10539,18 +10539,17 @@ function useVisualElement(Component, visualState, props, createVisualElement, Pr
10539
10539
  if (!wantsHandoff.current && visualElement.animationState) {
10540
10540
  visualElement.animationState.animateChanges();
10541
10541
  }
10542
- wantsHandoff.current = false;
10543
- // This ensures all future calls to animateChanges() will run in useEffect
10544
- if (!scheduleHandoffComplete) {
10545
- scheduleHandoffComplete = true;
10546
- queueMicrotask(completeHandoff);
10542
+ if (wantsHandoff.current) {
10543
+ // This ensures all future calls to animateChanges() in this component will run in useEffect
10544
+ queueMicrotask(() => {
10545
+ var _a;
10546
+ (_a = window.MotionHandoffMarkAsComplete) === null || _a === void 0 ? void 0 : _a.call(window, optimisedAppearId);
10547
+ });
10548
+ wantsHandoff.current = false;
10547
10549
  }
10548
10550
  });
10549
10551
  return visualElement;
10550
10552
  }
10551
- function completeHandoff() {
10552
- window.MotionHandoffIsComplete = true;
10553
- }
10554
10553
  function createProjectionNode(visualElement, props, ProjectionNodeConstructor, initialPromotionConfig) {
10555
10554
  const { layoutId, layout, drag, dragConstraints, layoutScroll, layoutRoot, } = props;
10556
10555
  visualElement.projection = new ProjectionNodeConstructor(visualElement.latestValues, props["data-framer-portal-id"]
@@ -12551,9 +12550,10 @@ const appearStoreId = (elementId, valueName) => {
12551
12550
  };
12552
12551
 
12553
12552
  const appearAnimationStore = new Map();
12554
- const elementsWithAppearAnimations = new Set();
12553
+ const appearComplete = new Map();
12555
12554
 
12556
12555
  function handoffOptimizedAppearAnimation(elementId, valueName, frame) {
12556
+ var _a;
12557
12557
  const storeId = appearStoreId(elementId, valueName);
12558
12558
  const optimisedAnimation = appearAnimationStore.get(storeId);
12559
12559
  if (!optimisedAnimation) {
@@ -12572,7 +12572,7 @@ function handoffOptimizedAppearAnimation(elementId, valueName, frame) {
12572
12572
  * older browsers.
12573
12573
  */
12574
12574
  animation.onfinish = cancelAnimation;
12575
- if (startTime === null || window.MotionHandoffIsComplete) {
12575
+ if (startTime === null || ((_a = window.MotionHandoffIsComplete) === null || _a === void 0 ? void 0 : _a.call(window, elementId))) {
12576
12576
  /**
12577
12577
  * If the startTime is null, this animation is the Paint Ready detection animation
12578
12578
  * and we can cancel it immediately without handoff.
@@ -12615,8 +12615,7 @@ function resumeSuspendedAnimations() {
12615
12615
  }
12616
12616
  function startOptimizedAppearAnimation(element, name, keyframes, options, onReady) {
12617
12617
  // Prevent optimised appear animations if Motion has already started animating.
12618
- if (window.MotionHandoffIsComplete) {
12619
- window.MotionHandoffAnimation = undefined;
12618
+ if (window.MotionIsMounted) {
12620
12619
  return;
12621
12620
  }
12622
12621
  const id = element.dataset[optimizedAppearDataId];
@@ -12653,11 +12652,19 @@ function startOptimizedAppearAnimation(element, name, keyframes, options, onRead
12653
12652
  * breakpoint.
12654
12653
  */
12655
12654
  if (!valueName) {
12656
- return elementsWithAppearAnimations.has(elementId);
12655
+ return appearComplete.has(elementId);
12657
12656
  }
12658
12657
  const animationId = appearStoreId(elementId, valueName);
12659
12658
  return Boolean(appearAnimationStore.get(animationId));
12660
12659
  };
12660
+ window.MotionHandoffMarkAsComplete = (elementId) => {
12661
+ if (appearComplete.has(elementId)) {
12662
+ appearComplete.set(elementId, true);
12663
+ }
12664
+ };
12665
+ window.MotionHandoffIsComplete = (elementId) => {
12666
+ return appearComplete.get(elementId) === true;
12667
+ };
12661
12668
  /**
12662
12669
  * We only need to cancel transform animations as
12663
12670
  * they're the ones that will interfere with the
@@ -12736,7 +12743,7 @@ function startOptimizedAppearAnimation(element, name, keyframes, options, onRead
12736
12743
  if (onReady)
12737
12744
  onReady(appearAnimation);
12738
12745
  };
12739
- elementsWithAppearAnimations.add(id);
12746
+ appearComplete.set(id, false);
12740
12747
  if (readyAnimation.ready) {
12741
12748
  readyAnimation.ready.then(startAnimation).catch(noop);
12742
12749
  }
package/dist/cjs/m.js CHANGED
@@ -195,9 +195,8 @@ function isRefObject(ref) {
195
195
  */
196
196
  const SwitchLayoutGroupContext = react.createContext({});
197
197
 
198
- let scheduleHandoffComplete = false;
199
198
  function useVisualElement(Component, visualState, props, createVisualElement, ProjectionNodeConstructor) {
200
- var _a;
199
+ var _a, _b;
201
200
  const { visualElement: parent } = react.useContext(MotionContext);
202
201
  const lazyContext = react.useContext(LazyContext);
203
202
  const presenceContext = react.useContext(PresenceContext);
@@ -240,11 +239,12 @@ function useVisualElement(Component, visualState, props, createVisualElement, Pr
240
239
  */
241
240
  const optimisedAppearId = props[optimizedAppearDataAttribute];
242
241
  const wantsHandoff = react.useRef(Boolean(optimisedAppearId) &&
243
- !window.MotionHandoffIsComplete &&
244
- ((_a = window.MotionHasOptimisedAnimation) === null || _a === void 0 ? void 0 : _a.call(window, optimisedAppearId)));
242
+ !((_a = window.MotionHandoffIsComplete) === null || _a === void 0 ? void 0 : _a.call(window, optimisedAppearId)) &&
243
+ ((_b = window.MotionHasOptimisedAnimation) === null || _b === void 0 ? void 0 : _b.call(window, optimisedAppearId)));
245
244
  useIsomorphicLayoutEffect(() => {
246
245
  if (!visualElement)
247
246
  return;
247
+ window.MotionIsMounted = true;
248
248
  visualElement.updateFeatures();
249
249
  microtask.render(visualElement.render);
250
250
  /**
@@ -267,18 +267,17 @@ function useVisualElement(Component, visualState, props, createVisualElement, Pr
267
267
  if (!wantsHandoff.current && visualElement.animationState) {
268
268
  visualElement.animationState.animateChanges();
269
269
  }
270
- wantsHandoff.current = false;
271
- // This ensures all future calls to animateChanges() will run in useEffect
272
- if (!scheduleHandoffComplete) {
273
- scheduleHandoffComplete = true;
274
- queueMicrotask(completeHandoff);
270
+ if (wantsHandoff.current) {
271
+ // This ensures all future calls to animateChanges() in this component will run in useEffect
272
+ queueMicrotask(() => {
273
+ var _a;
274
+ (_a = window.MotionHandoffMarkAsComplete) === null || _a === void 0 ? void 0 : _a.call(window, optimisedAppearId);
275
+ });
276
+ wantsHandoff.current = false;
275
277
  }
276
278
  });
277
279
  return visualElement;
278
280
  }
279
- function completeHandoff() {
280
- window.MotionHandoffIsComplete = true;
281
- }
282
281
  function createProjectionNode(visualElement, props, ProjectionNodeConstructor, initialPromotionConfig) {
283
282
  const { layoutId, layout, drag, dragConstraints, layoutScroll, layoutRoot, } = props;
284
283
  visualElement.projection = new ProjectionNodeConstructor(visualElement.latestValues, props["data-framer-portal-id"]
package/dist/client.d.ts CHANGED
@@ -3,7 +3,7 @@ import * as React$1 from 'react';
3
3
  import { SVGAttributes, CSSProperties, PropsWithoutRef, RefAttributes, ReactHTML, DetailedHTMLFactory, HTMLAttributes } from 'react';
4
4
 
5
5
  type EasingFunction = (v: number) => number;
6
- type BezierDefinition = [number, number, number, number];
6
+ type BezierDefinition = readonly [number, number, number, number];
7
7
  type EasingDefinition = BezierDefinition | "linear" | "easeIn" | "easeOut" | "easeInOut" | "circIn" | "circOut" | "circInOut" | "backIn" | "backOut" | "backInOut" | "anticipate";
8
8
  /**
9
9
  * The easing function to use. Set as one of:
@@ -2387,10 +2387,12 @@ type HandoffFunction = (storeId: string, valueName: string, frame: Batcher) => n
2387
2387
  declare global {
2388
2388
  interface Window {
2389
2389
  MotionHandoffAnimation?: HandoffFunction;
2390
- MotionHandoffIsComplete?: boolean;
2390
+ MotionHandoffMarkAsComplete?: (elementId: string) => void;
2391
+ MotionHandoffIsComplete?: (elementId: string) => boolean;
2391
2392
  MotionHasOptimisedAnimation?: (elementId?: string, valueName?: string) => boolean;
2392
2393
  MotionCancelOptimisedAnimation?: (elementId?: string, valueName?: string, frame?: Batcher, canResume?: boolean) => void;
2393
2394
  MotionCheckAppearSync?: (visualElement: WithAppearProps, valueName: string, value: MotionValue) => VoidFunction | void;
2395
+ MotionIsMounted?: boolean;
2394
2396
  }
2395
2397
  }
2396
2398
 
@@ -1,5 +1,5 @@
1
1
  type EasingFunction = (v: number) => number;
2
- type BezierDefinition = [number, number, number, number];
2
+ type BezierDefinition = readonly [number, number, number, number];
3
3
  type EasingDefinition = BezierDefinition | "linear" | "easeIn" | "easeOut" | "easeInOut" | "circIn" | "circOut" | "circInOut" | "backIn" | "backOut" | "backInOut" | "anticipate";
4
4
  /**
5
5
  * The easing function to use. Set as one of:
package/dist/dom.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  type EasingFunction = (v: number) => number;
2
2
  type EasingModifier = (easing: EasingFunction) => EasingFunction;
3
- type BezierDefinition = [number, number, number, number];
3
+ type BezierDefinition = readonly [number, number, number, number];
4
4
  type EasingDefinition = BezierDefinition | "linear" | "easeIn" | "easeOut" | "easeInOut" | "circIn" | "circOut" | "circInOut" | "backIn" | "backOut" | "backInOut" | "anticipate";
5
5
  /**
6
6
  * The easing function to use. Set as one of:
@@ -915,10 +915,12 @@ type HandoffFunction = (storeId: string, valueName: string, frame: Batcher) => n
915
915
  declare global {
916
916
  interface Window {
917
917
  MotionHandoffAnimation?: HandoffFunction;
918
- MotionHandoffIsComplete?: boolean;
918
+ MotionHandoffMarkAsComplete?: (elementId: string) => void;
919
+ MotionHandoffIsComplete?: (elementId: string) => boolean;
919
920
  MotionHasOptimisedAnimation?: (elementId?: string, valueName?: string) => boolean;
920
921
  MotionCancelOptimisedAnimation?: (elementId?: string, valueName?: string, frame?: Batcher, canResume?: boolean) => void;
921
922
  MotionCheckAppearSync?: (visualElement: WithAppearProps, valueName: string, value: MotionValue) => VoidFunction | void;
923
+ MotionIsMounted?: boolean;
922
924
  }
923
925
  }
924
926