framer-motion 12.23.2 → 12.23.5

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.
@@ -2688,14 +2688,6 @@
2688
2688
  ((type === "spring" || isGenerator(type)) && velocity));
2689
2689
  }
2690
2690
 
2691
- /**
2692
- * Checks if an element is an HTML element in a way
2693
- * that works across iframes
2694
- */
2695
- function isHTMLElement(element) {
2696
- return isObject(element) && "offsetHeight" in element;
2697
- }
2698
-
2699
2691
  /**
2700
2692
  * A list of values that can be hardware-accelerated.
2701
2693
  */
@@ -2710,7 +2702,14 @@
2710
2702
  const supportsWaapi = /*@__PURE__*/ memo(() => Object.hasOwnProperty.call(Element.prototype, "animate"));
2711
2703
  function supportsBrowserAnimation(options) {
2712
2704
  const { motionValue, name, repeatDelay, repeatType, damping, type } = options;
2713
- if (!isHTMLElement(motionValue?.owner?.current)) {
2705
+ const subject = motionValue?.owner?.current;
2706
+ /**
2707
+ * We use this check instead of isHTMLElement() because we explicitly
2708
+ * **don't** want elements in different timing contexts (i.e. popups)
2709
+ * to be accelerated, as it's not possible to sync these animations
2710
+ * properly with those driven from the main window frameloop.
2711
+ */
2712
+ if (!(subject instanceof HTMLElement)) {
2714
2713
  return false;
2715
2714
  }
2716
2715
  const { onUpdate, transformTemplate } = motionValue.owner.getProps();
@@ -3583,6 +3582,14 @@
3583
3582
  }, undefined, false);
3584
3583
  });
3585
3584
 
3585
+ /**
3586
+ * Checks if an element is an HTML element in a way
3587
+ * that works across iframes
3588
+ */
3589
+ function isHTMLElement(element) {
3590
+ return isObject(element) && "offsetHeight" in element;
3591
+ }
3592
+
3586
3593
  /**
3587
3594
  * Maximum time between the value of two frames, beyond which we
3588
3595
  * assume the velocity has since been 0.
@@ -12340,6 +12347,7 @@
12340
12347
  exports.invariant(Boolean(numSubjects), "No valid elements provided.", "no-valid-elements");
12341
12348
  for (let i = 0; i < numSubjects; i++) {
12342
12349
  const thisSubject = subjects[i];
12350
+ exports.invariant(thisSubject !== null, "You're trying to perform an animation on null. Ensure that selectors are correctly finding elements and refs are correctly hydrated.", "animate-null");
12343
12351
  const createVisualElement = thisSubject instanceof Element
12344
12352
  ? createDOMVisualElement
12345
12353
  : createObjectVisualElement;
@@ -13022,24 +13030,23 @@
13022
13030
  React$1.useInsertionEffect(() => value.on(event, callback), [value, event, callback]);
13023
13031
  }
13024
13032
 
13025
- function refWarning(name, ref) {
13026
- exports.warning(Boolean(!ref || ref.current), `You have defined a ${name} options but the provided ref is not yet hydrated, probably because it's defined higher up the tree. Try calling useScroll() in the same component as the ref, or setting its \`layoutEffect: false\` option.`);
13027
- }
13028
13033
  const createScrollMotionValues = () => ({
13029
13034
  scrollX: motionValue(0),
13030
13035
  scrollY: motionValue(0),
13031
13036
  scrollXProgress: motionValue(0),
13032
13037
  scrollYProgress: motionValue(0),
13033
13038
  });
13034
- function useScroll({ container, target, layoutEffect = true, ...options } = {}) {
13039
+ const isRefPending = (ref) => {
13040
+ if (!ref)
13041
+ return false;
13042
+ return !ref.current;
13043
+ };
13044
+ function useScroll({ container, target, ...options } = {}) {
13035
13045
  const values = useConstant(createScrollMotionValues);
13036
- const useLifecycleEffect = layoutEffect
13037
- ? useIsomorphicLayoutEffect
13038
- : React$1.useEffect;
13039
- useLifecycleEffect(() => {
13040
- refWarning("target", target);
13041
- refWarning("container", container);
13042
- return scroll((_progress, { x, y, }) => {
13046
+ const scrollAnimation = React$1.useRef(null);
13047
+ const needsStart = React$1.useRef(false);
13048
+ const start = React$1.useCallback(() => {
13049
+ scrollAnimation.current = scroll((_progress, { x, y, }) => {
13043
13050
  values.scrollX.set(x.current);
13044
13051
  values.scrollXProgress.set(x.progress);
13045
13052
  values.scrollY.set(y.current);
@@ -13049,7 +13056,30 @@
13049
13056
  container: container?.current || undefined,
13050
13057
  target: target?.current || undefined,
13051
13058
  });
13059
+ return () => {
13060
+ scrollAnimation.current?.();
13061
+ };
13052
13062
  }, [container, target, JSON.stringify(options.offset)]);
13063
+ useIsomorphicLayoutEffect(() => {
13064
+ needsStart.current = false;
13065
+ if (isRefPending(container) || isRefPending(target)) {
13066
+ needsStart.current = true;
13067
+ return;
13068
+ }
13069
+ else {
13070
+ return start();
13071
+ }
13072
+ }, [start]);
13073
+ React$1.useEffect(() => {
13074
+ if (needsStart.current) {
13075
+ exports.invariant(!isRefPending(container), "Container ref is defined but not hydrated", "use-scroll-ref");
13076
+ exports.invariant(!isRefPending(target), "Target ref is defined but not hydrated", "use-scroll-ref");
13077
+ return start();
13078
+ }
13079
+ else {
13080
+ return;
13081
+ }
13082
+ }, [start]);
13053
13083
  return values;
13054
13084
  }
13055
13085