framer-motion 12.24.3 → 12.24.4

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.
@@ -1,12 +1,27 @@
1
1
  "use client";
2
- import { useCallback } from 'react';
2
+ import { useRef, useCallback } from 'react';
3
3
  import { isRefObject } from '../../utils/is-ref-object.mjs';
4
4
 
5
+ /**
6
+ * Set a given ref to a given value
7
+ * This utility takes care of different types of refs: callback refs and RefObject(s)
8
+ * Returns a cleanup function if the ref callback returns one (React 19 feature)
9
+ */
10
+ function setRef(ref, value) {
11
+ if (typeof ref === "function") {
12
+ return ref(value);
13
+ }
14
+ else if (isRefObject(ref)) {
15
+ ref.current = value;
16
+ }
17
+ }
5
18
  /**
6
19
  * Creates a ref function that, when called, hydrates the provided
7
20
  * external ref and VisualElement.
8
21
  */
9
22
  function useMotionRef(visualState, visualElement, externalRef) {
23
+ // Store the cleanup function from external ref if it returns one
24
+ const externalRefCleanupRef = useRef(null);
10
25
  return useCallback((instance) => {
11
26
  if (instance) {
12
27
  visualState.onMount && visualState.onMount(instance);
@@ -20,19 +35,30 @@ function useMotionRef(visualState, visualElement, externalRef) {
20
35
  }
21
36
  }
22
37
  if (externalRef) {
23
- if (typeof externalRef === "function") {
24
- externalRef(instance);
38
+ if (instance) {
39
+ // Mount: call the external ref and store any cleanup function
40
+ const cleanup = setRef(externalRef, instance);
41
+ if (typeof cleanup === "function") {
42
+ externalRefCleanupRef.current = cleanup;
43
+ }
25
44
  }
26
- else if (isRefObject(externalRef)) {
27
- externalRef.current = instance;
45
+ else {
46
+ // Unmount: call stored cleanup function if available, otherwise call ref with null
47
+ if (externalRefCleanupRef.current) {
48
+ externalRefCleanupRef.current();
49
+ externalRefCleanupRef.current = null;
50
+ }
51
+ else {
52
+ // Fallback to React <19 behavior for refs that don't return cleanup
53
+ setRef(externalRef, instance);
54
+ }
28
55
  }
29
56
  }
30
57
  },
31
58
  /**
32
- * Include externalRef in dependencies to ensure the callback updates
33
- * when the ref changes, allowing proper ref forwarding.
59
+ * Include all dependencies to ensure the callback updates correctly
34
60
  */
35
- [visualElement]);
61
+ [visualElement, visualState, externalRef]);
36
62
  }
37
63
 
38
64
  export { useMotionRef };
@@ -1 +1 @@
1
- {"version":3,"file":"use-motion-ref.mjs","sources":["../../../../src/motion/utils/use-motion-ref.ts"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { useCallback } from \"react\"\nimport type { VisualElement } from \"../../render/VisualElement\"\nimport { isRefObject } from \"../../utils/is-ref-object\"\nimport { VisualState } from \"./use-visual-state\"\n\n/**\n * Creates a ref function that, when called, hydrates the provided\n * external ref and VisualElement.\n */\nexport function useMotionRef<Instance, RenderState>(\n visualState: VisualState<Instance, RenderState>,\n visualElement?: VisualElement<Instance> | null,\n externalRef?: React.Ref<Instance>\n): React.Ref<Instance> {\n return useCallback(\n (instance: Instance) => {\n if (instance) {\n visualState.onMount && visualState.onMount(instance)\n }\n\n if (visualElement) {\n if (instance) {\n visualElement.mount(instance)\n } else {\n visualElement.unmount()\n }\n }\n\n if (externalRef) {\n if (typeof externalRef === \"function\") {\n externalRef(instance)\n } else if (isRefObject(externalRef)) {\n ;(externalRef as any).current = instance\n }\n }\n },\n /**\n * Include externalRef in dependencies to ensure the callback updates\n * when the ref changes, allowing proper ref forwarding.\n */\n [visualElement]\n )\n}\n"],"names":[],"mappings":";;;;AAQA;;;AAGG;;AAMC;;;;;;AAQgB;;;;;;;AAOJ;;;AAEO;AACD;;;;AAId;;;AAGG;;AAGX;;"}
1
+ {"version":3,"file":"use-motion-ref.mjs","sources":["../../../../src/motion/utils/use-motion-ref.ts"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { useCallback, useRef } from \"react\"\nimport type { VisualElement } from \"../../render/VisualElement\"\nimport { isRefObject } from \"../../utils/is-ref-object\"\nimport { VisualState } from \"./use-visual-state\"\n\n/**\n * Set a given ref to a given value\n * This utility takes care of different types of refs: callback refs and RefObject(s)\n * Returns a cleanup function if the ref callback returns one (React 19 feature)\n */\nfunction setRef<T>(ref: React.Ref<T>, value: T): void | (() => void) {\n if (typeof ref === \"function\") {\n return ref(value)\n } else if (isRefObject(ref)) {\n ;(ref as any).current = value\n }\n}\n\n/**\n * Creates a ref function that, when called, hydrates the provided\n * external ref and VisualElement.\n */\nexport function useMotionRef<Instance, RenderState>(\n visualState: VisualState<Instance, RenderState>,\n visualElement?: VisualElement<Instance> | null,\n externalRef?: React.Ref<Instance>\n): React.Ref<Instance> {\n // Store the cleanup function from external ref if it returns one\n const externalRefCleanupRef = useRef<(() => void) | null>(null)\n\n return useCallback(\n (instance: Instance) => {\n if (instance) {\n visualState.onMount && visualState.onMount(instance)\n }\n\n if (visualElement) {\n if (instance) {\n visualElement.mount(instance)\n } else {\n visualElement.unmount()\n }\n }\n\n if (externalRef) {\n if (instance) {\n // Mount: call the external ref and store any cleanup function\n const cleanup = setRef(externalRef, instance)\n if (typeof cleanup === \"function\") {\n externalRefCleanupRef.current = cleanup\n }\n } else {\n // Unmount: call stored cleanup function if available, otherwise call ref with null\n if (externalRefCleanupRef.current) {\n externalRefCleanupRef.current()\n externalRefCleanupRef.current = null\n } else {\n // Fallback to React <19 behavior for refs that don't return cleanup\n setRef(externalRef, instance)\n }\n }\n }\n },\n /**\n * Include all dependencies to ensure the callback updates correctly\n */\n [visualElement, visualState, externalRef]\n )\n}\n"],"names":[],"mappings":";;;;AAQA;;;;AAIG;AACH;AACI;AACI;;AACG;AACD;;AAEV;AAEA;;;AAGG;;;AAOC;AAEA;;;;;;AAQgB;;;;;;;;;;AAUA;AACI;;;;;AAIJ;;AAEI;;;;AAGA;;;;;AAKhB;;AAEG;AACH;AAER;;"}
@@ -5108,7 +5108,7 @@
5108
5108
  * Set a given ref to a given value
5109
5109
  * This utility takes care of different types of refs: callback refs and RefObject(s)
5110
5110
  */
5111
- function setRef(ref, value) {
5111
+ function setRef$1(ref, value) {
5112
5112
  if (typeof ref === "function") {
5113
5113
  return ref(value);
5114
5114
  }
@@ -5124,7 +5124,7 @@
5124
5124
  return (node) => {
5125
5125
  let hasCleanup = false;
5126
5126
  const cleanups = refs.map((ref) => {
5127
- const cleanup = setRef(ref, node);
5127
+ const cleanup = setRef$1(ref, node);
5128
5128
  if (!hasCleanup && typeof cleanup === "function") {
5129
5129
  hasCleanup = true;
5130
5130
  }
@@ -5142,7 +5142,7 @@
5142
5142
  cleanup();
5143
5143
  }
5144
5144
  else {
5145
- setRef(refs[i], null);
5145
+ setRef$1(refs[i], null);
5146
5146
  }
5147
5147
  }
5148
5148
  };
@@ -9702,11 +9702,26 @@
9702
9702
  Object.prototype.hasOwnProperty.call(ref, "current"));
9703
9703
  }
9704
9704
 
9705
+ /**
9706
+ * Set a given ref to a given value
9707
+ * This utility takes care of different types of refs: callback refs and RefObject(s)
9708
+ * Returns a cleanup function if the ref callback returns one (React 19 feature)
9709
+ */
9710
+ function setRef(ref, value) {
9711
+ if (typeof ref === "function") {
9712
+ return ref(value);
9713
+ }
9714
+ else if (isRefObject(ref)) {
9715
+ ref.current = value;
9716
+ }
9717
+ }
9705
9718
  /**
9706
9719
  * Creates a ref function that, when called, hydrates the provided
9707
9720
  * external ref and VisualElement.
9708
9721
  */
9709
9722
  function useMotionRef(visualState, visualElement, externalRef) {
9723
+ // Store the cleanup function from external ref if it returns one
9724
+ const externalRefCleanupRef = React$1.useRef(null);
9710
9725
  return React$1.useCallback((instance) => {
9711
9726
  if (instance) {
9712
9727
  visualState.onMount && visualState.onMount(instance);
@@ -9720,19 +9735,30 @@
9720
9735
  }
9721
9736
  }
9722
9737
  if (externalRef) {
9723
- if (typeof externalRef === "function") {
9724
- externalRef(instance);
9738
+ if (instance) {
9739
+ // Mount: call the external ref and store any cleanup function
9740
+ const cleanup = setRef(externalRef, instance);
9741
+ if (typeof cleanup === "function") {
9742
+ externalRefCleanupRef.current = cleanup;
9743
+ }
9725
9744
  }
9726
- else if (isRefObject(externalRef)) {
9727
- externalRef.current = instance;
9745
+ else {
9746
+ // Unmount: call stored cleanup function if available, otherwise call ref with null
9747
+ if (externalRefCleanupRef.current) {
9748
+ externalRefCleanupRef.current();
9749
+ externalRefCleanupRef.current = null;
9750
+ }
9751
+ else {
9752
+ // Fallback to React <19 behavior for refs that don't return cleanup
9753
+ setRef(externalRef, instance);
9754
+ }
9728
9755
  }
9729
9756
  }
9730
9757
  },
9731
9758
  /**
9732
- * Include externalRef in dependencies to ensure the callback updates
9733
- * when the ref changes, allowing proper ref forwarding.
9759
+ * Include all dependencies to ensure the callback updates correctly
9734
9760
  */
9735
- [visualElement]);
9761
+ [visualElement, visualState, externalRef]);
9736
9762
  }
9737
9763
 
9738
9764
  /**