@r0b0t3d/react-native-collapsible 1.5.2 → 1.6.0-alpha.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.
Files changed (129) hide show
  1. package/lib/commonjs/components/CollapsibleContainer.js +19 -21
  2. package/lib/commonjs/components/CollapsibleContainer.js.map +1 -1
  3. package/lib/commonjs/components/CollapsibleView.js +38 -30
  4. package/lib/commonjs/components/CollapsibleView.js.map +1 -1
  5. package/lib/commonjs/components/header/AnimatedTopView.js +5 -7
  6. package/lib/commonjs/components/header/AnimatedTopView.js.map +1 -1
  7. package/lib/commonjs/components/header/CollapsibleHeaderConsumer.js +10 -13
  8. package/lib/commonjs/components/header/CollapsibleHeaderConsumer.js.map +1 -1
  9. package/lib/commonjs/components/header/CollapsibleHeaderContainer.js +22 -17
  10. package/lib/commonjs/components/header/CollapsibleHeaderContainer.js.map +1 -1
  11. package/lib/commonjs/components/header/CollapsibleHeaderContainerProvider.js +12 -15
  12. package/lib/commonjs/components/header/CollapsibleHeaderContainerProvider.js.map +1 -1
  13. package/lib/commonjs/components/header/StickyView.js +18 -25
  14. package/lib/commonjs/components/header/StickyView.js.map +1 -1
  15. package/lib/commonjs/components/scrollable/CollapsibleFlatList.js +27 -41
  16. package/lib/commonjs/components/scrollable/CollapsibleFlatList.js.map +1 -1
  17. package/lib/commonjs/components/scrollable/CollapsibleScrollView.js +12 -15
  18. package/lib/commonjs/components/scrollable/CollapsibleScrollView.js.map +1 -1
  19. package/lib/commonjs/components/scrollable/CollapsibleSectionList.js +22 -36
  20. package/lib/commonjs/components/scrollable/CollapsibleSectionList.js.map +1 -1
  21. package/lib/commonjs/components/scrollable/useAnimatedScroll.js +44 -24
  22. package/lib/commonjs/components/scrollable/useAnimatedScroll.js.map +1 -1
  23. package/lib/commonjs/hooks/useCollapsibleContext.js +1 -2
  24. package/lib/commonjs/hooks/useCollapsibleContext.js.map +1 -1
  25. package/lib/commonjs/hooks/useCollapsibleHeaderConsumerContext.js +1 -2
  26. package/lib/commonjs/hooks/useCollapsibleHeaderConsumerContext.js.map +1 -1
  27. package/lib/commonjs/hooks/useCollapsibleHeaderContext.js +1 -2
  28. package/lib/commonjs/hooks/useCollapsibleHeaderContext.js.map +1 -1
  29. package/lib/commonjs/hooks/useInternalCollapsibleContext.js +1 -2
  30. package/lib/commonjs/hooks/useInternalCollapsibleContext.js.map +1 -1
  31. package/lib/commonjs/hooks/useKeyboardShowEvent.js.map +1 -1
  32. package/lib/commonjs/index.js +3 -12
  33. package/lib/commonjs/index.js.map +1 -1
  34. package/lib/commonjs/plugins/CollapsibleFlashList.js +14 -17
  35. package/lib/commonjs/plugins/CollapsibleFlashList.js.map +1 -1
  36. package/lib/commonjs/plugins/CollapsibleLegendList.js +15 -15
  37. package/lib/commonjs/plugins/CollapsibleLegendList.js.map +1 -1
  38. package/lib/commonjs/types.js.map +1 -1
  39. package/lib/commonjs/utils/debounce.js +2 -6
  40. package/lib/commonjs/utils/debounce.js.map +1 -1
  41. package/lib/commonjs/utils/useSharedValueRef.js +33 -3
  42. package/lib/commonjs/utils/useSharedValueRef.js.map +1 -1
  43. package/lib/commonjs/withCollapsibleContext.js +3 -4
  44. package/lib/commonjs/withCollapsibleContext.js.map +1 -1
  45. package/lib/module/components/CollapsibleContainer.js +18 -19
  46. package/lib/module/components/CollapsibleContainer.js.map +1 -1
  47. package/lib/module/components/CollapsibleView.js +38 -29
  48. package/lib/module/components/CollapsibleView.js.map +1 -1
  49. package/lib/module/components/header/AnimatedTopView.js +3 -4
  50. package/lib/module/components/header/AnimatedTopView.js.map +1 -1
  51. package/lib/module/components/header/CollapsibleHeaderConsumer.js +8 -10
  52. package/lib/module/components/header/CollapsibleHeaderConsumer.js.map +1 -1
  53. package/lib/module/components/header/CollapsibleHeaderContainer.js +21 -15
  54. package/lib/module/components/header/CollapsibleHeaderContainer.js.map +1 -1
  55. package/lib/module/components/header/CollapsibleHeaderContainerProvider.js +10 -12
  56. package/lib/module/components/header/CollapsibleHeaderContainerProvider.js.map +1 -1
  57. package/lib/module/components/header/StickyView.js +18 -23
  58. package/lib/module/components/header/StickyView.js.map +1 -1
  59. package/lib/module/components/scrollable/CollapsibleFlatList.js +27 -41
  60. package/lib/module/components/scrollable/CollapsibleFlatList.js.map +1 -1
  61. package/lib/module/components/scrollable/CollapsibleScrollView.js +10 -12
  62. package/lib/module/components/scrollable/CollapsibleScrollView.js.map +1 -1
  63. package/lib/module/components/scrollable/CollapsibleSectionList.js +22 -35
  64. package/lib/module/components/scrollable/CollapsibleSectionList.js.map +1 -1
  65. package/lib/module/components/scrollable/useAnimatedScroll.js +44 -23
  66. package/lib/module/components/scrollable/useAnimatedScroll.js.map +1 -1
  67. package/lib/module/hooks/useCollapsibleContext.js.map +1 -1
  68. package/lib/module/hooks/useCollapsibleHeaderConsumerContext.js.map +1 -1
  69. package/lib/module/hooks/useCollapsibleHeaderContext.js.map +1 -1
  70. package/lib/module/hooks/useInternalCollapsibleContext.js.map +1 -1
  71. package/lib/module/hooks/useKeyboardShowEvent.js.map +1 -1
  72. package/lib/module/index.js +0 -1
  73. package/lib/module/index.js.map +1 -1
  74. package/lib/module/plugins/CollapsibleFlashList.js +12 -14
  75. package/lib/module/plugins/CollapsibleFlashList.js.map +1 -1
  76. package/lib/module/plugins/CollapsibleLegendList.js +13 -12
  77. package/lib/module/plugins/CollapsibleLegendList.js.map +1 -1
  78. package/lib/module/types.js.map +1 -1
  79. package/lib/module/utils/debounce.js +2 -6
  80. package/lib/module/utils/debounce.js.map +1 -1
  81. package/lib/module/utils/useSharedValueRef.js +33 -3
  82. package/lib/module/utils/useSharedValueRef.js.map +1 -1
  83. package/lib/module/withCollapsibleContext.js +2 -2
  84. package/lib/module/withCollapsibleContext.js.map +1 -1
  85. package/lib/typescript/components/CollapsibleContainer.d.ts +1 -1
  86. package/lib/typescript/components/CollapsibleContainer.d.ts.map +1 -1
  87. package/lib/typescript/components/CollapsibleView.d.ts +4 -4
  88. package/lib/typescript/components/CollapsibleView.d.ts.map +1 -1
  89. package/lib/typescript/components/header/AnimatedTopView.d.ts +2 -2
  90. package/lib/typescript/components/header/AnimatedTopView.d.ts.map +1 -1
  91. package/lib/typescript/components/header/CollapsibleHeaderContainer.d.ts.map +1 -1
  92. package/lib/typescript/components/header/StickyView.d.ts +1 -1
  93. package/lib/typescript/components/header/StickyView.d.ts.map +1 -1
  94. package/lib/typescript/components/scrollable/CollapsibleFlatList.d.ts.map +1 -1
  95. package/lib/typescript/components/scrollable/CollapsibleSectionList.d.ts.map +1 -1
  96. package/lib/typescript/components/scrollable/useAnimatedScroll.d.ts +2 -2
  97. package/lib/typescript/components/scrollable/useAnimatedScroll.d.ts.map +1 -1
  98. package/lib/typescript/hooks/useCollapsibleContext.d.ts +0 -1
  99. package/lib/typescript/hooks/useCollapsibleContext.d.ts.map +1 -1
  100. package/lib/typescript/hooks/useCollapsibleHeaderContext.d.ts +2 -3
  101. package/lib/typescript/hooks/useCollapsibleHeaderContext.d.ts.map +1 -1
  102. package/lib/typescript/hooks/useInternalCollapsibleContext.d.ts +0 -1
  103. package/lib/typescript/hooks/useInternalCollapsibleContext.d.ts.map +1 -1
  104. package/lib/typescript/index.d.ts +0 -1
  105. package/lib/typescript/index.d.ts.map +1 -1
  106. package/lib/typescript/plugins/CollapsibleFlashList.d.ts.map +1 -1
  107. package/lib/typescript/plugins/CollapsibleLegendList.d.ts.map +1 -1
  108. package/lib/typescript/types.d.ts +12 -12
  109. package/lib/typescript/types.d.ts.map +1 -1
  110. package/lib/typescript/utils/debounce.d.ts.map +1 -1
  111. package/lib/typescript/utils/useSharedValueRef.d.ts +2 -2
  112. package/lib/typescript/utils/useSharedValueRef.d.ts.map +1 -1
  113. package/lib/typescript/withCollapsibleContext.d.ts.map +1 -1
  114. package/package.json +54 -18
  115. package/src/components/CollapsibleContainer.tsx +13 -4
  116. package/src/components/CollapsibleView.tsx +31 -10
  117. package/src/components/header/AnimatedTopView.tsx +5 -2
  118. package/src/components/header/CollapsibleHeaderContainer.tsx +18 -13
  119. package/src/components/header/StickyView.tsx +9 -16
  120. package/src/components/scrollable/CollapsibleFlatList.tsx +27 -46
  121. package/src/components/scrollable/CollapsibleSectionList.tsx +21 -41
  122. package/src/components/scrollable/useAnimatedScroll.ts +36 -22
  123. package/src/hooks/useCollapsibleHeaderContext.ts +2 -2
  124. package/src/index.tsx +0 -2
  125. package/src/plugins/CollapsibleFlashList.tsx +9 -9
  126. package/src/plugins/CollapsibleLegendList.tsx +8 -2
  127. package/src/types.ts +12 -12
  128. package/src/utils/useSharedValueRef.ts +37 -6
  129. package/src/withCollapsibleContext.tsx +7 -4
@@ -1,12 +1,11 @@
1
- /* eslint-disable react-hooks/exhaustive-deps */
2
- import { useCallback, useEffect } from 'react';
1
+ import { useCallback, useEffect, useRef } from 'react';
3
2
  import { Dimensions, SectionListScrollParams } from 'react-native';
4
3
  import {
5
4
  runOnJS,
6
5
  useAnimatedScrollHandler,
7
6
  useSharedValue,
8
7
  } from 'react-native-reanimated';
9
- import type { ScrollToIndexParams } from '../../types';
8
+ import type { CollapsibleHandles, ScrollToIndexParams } from '../../types';
10
9
  import useCollapsibleContext from '../../hooks/useCollapsibleContext';
11
10
  import useInternalCollapsibleContext from '../../hooks/useInternalCollapsibleContext';
12
11
 
@@ -30,37 +29,52 @@ export default function useAnimatedScroll({
30
29
  const { setCollapsibleHandlers, fixedHeaderHeight } =
31
30
  useInternalCollapsibleContext();
32
31
 
32
+ // Keep a ref to the latest handlers so we can publish stable function
33
+ // references to setCollapsibleHandlers() that always delegate to the most
34
+ // recent closures. This avoids re-running the publish effect on every
35
+ // scrollable re-render.
36
+ const handlersRef = useRef<{
37
+ scrollTo: (y: number, animated?: boolean) => void;
38
+ scrollToIndex: (p: ScrollToIndexParams) => void;
39
+ scrollToLocation: (p: SectionListScrollParams) => void;
40
+ }>({ scrollTo, scrollToIndex, scrollToLocation });
41
+ handlersRef.current = { scrollTo, scrollToIndex, scrollToLocation };
42
+
33
43
  useEffect(() => {
34
44
  if (scrollY.value > 0) {
35
- requestAnimationFrame(() => scrollTo(scrollY.value, false));
45
+ requestAnimationFrame(() =>
46
+ handlersRef.current.scrollTo(scrollY.value, false)
47
+ );
36
48
  }
49
+ // eslint-disable-next-line react-hooks/exhaustive-deps
37
50
  }, []);
38
51
 
39
52
  const collapse = useCallback(
40
53
  (animated = true) => {
41
- scrollTo(fixedHeaderHeight.value, animated);
54
+ handlersRef.current.scrollTo(fixedHeaderHeight.value, animated);
42
55
  },
43
- [scrollTo]
56
+ [fixedHeaderHeight]
44
57
  );
45
58
 
46
- const expand = useCallback(() => scrollTo(0), [scrollTo]);
59
+ const expand = useCallback(() => handlersRef.current.scrollTo(0), []);
60
+
61
+ // Stable trampoline for use inside worklets: runOnJS captures the function
62
+ // reference at worklet-build time, so we must pass a stable function that
63
+ // dereferences handlersRef.current at JS-thread call time.
64
+ const scrollToOnJS = useCallback((y: number) => {
65
+ handlersRef.current.scrollTo(y);
66
+ }, []);
47
67
 
48
68
  useEffect(() => {
49
- setCollapsibleHandlers({
69
+ const handlers: CollapsibleHandles = {
50
70
  collapse,
51
71
  expand,
52
- scrollTo,
53
- scrollToIndex,
54
- scrollToLocation,
55
- });
56
- }, [
57
- setCollapsibleHandlers,
58
- collapse,
59
- expand,
60
- scrollTo,
61
- scrollToIndex,
62
- scrollToLocation,
63
- ]);
72
+ scrollTo: (y, a) => handlersRef.current.scrollTo(y, a),
73
+ scrollToIndex: (p) => handlersRef.current.scrollToIndex(p),
74
+ scrollToLocation: (p) => handlersRef.current.scrollToLocation(p),
75
+ };
76
+ setCollapsibleHandlers(handlers);
77
+ }, [setCollapsibleHandlers, collapse, expand]);
64
78
 
65
79
  const scrollHandler = useAnimatedScrollHandler(
66
80
  {
@@ -81,12 +95,12 @@ export default function useAnimatedScroll({
81
95
  if (scrollDirection.value === 'up') {
82
96
  yValue = maxY;
83
97
  }
84
- runOnJS(scrollTo)(yValue);
98
+ runOnJS(scrollToOnJS)(yValue);
85
99
  }
86
100
  }
87
101
  },
88
102
  },
89
- [scrollTo]
103
+ [headerSnappable, fixedHeaderHeight, scrollY, scrollToOnJS]
90
104
  );
91
105
 
92
106
  return {
@@ -1,10 +1,10 @@
1
1
  import { createContext, useContext } from 'react';
2
2
  import { LayoutRectangle } from 'react-native';
3
- import Animated from 'react-native-reanimated';
3
+ import { SharedValue } from 'react-native-reanimated';
4
4
 
5
5
  export type CollapsibleContextHeaderType = {
6
6
  handleStickyViewLayout: (key: string, layout?: LayoutRectangle) => void;
7
- animatedY: Animated.SharedValue<number>;
7
+ animatedY: SharedValue<number>;
8
8
  };
9
9
 
10
10
  export const CollapsibleHeaderContext =
package/src/index.tsx CHANGED
@@ -9,5 +9,3 @@ export { default as CollapsibleHeaderContainer } from './components/header/Colla
9
9
  export { default as StickyView } from './components/header/StickyView';
10
10
  export { default as CollapsibleView } from './components/CollapsibleView';
11
11
  export * from './components/CollapsibleView';
12
-
13
- export { default as CollapsibleFlashList } from './plugins/CollapsibleFlashList';
@@ -1,18 +1,14 @@
1
1
  /* eslint-disable react-hooks/exhaustive-deps */
2
2
  import React, { useCallback, useEffect, useRef, useState } from 'react';
3
3
  import { View, StyleSheet } from 'react-native';
4
- import Animated, {
5
- runOnJS,
6
- useAnimatedReaction,
7
- } from 'react-native-reanimated';
4
+ import { runOnJS, useAnimatedReaction } from 'react-native-reanimated';
8
5
  import useAnimatedScroll from '../components/scrollable/useAnimatedScroll';
9
6
  import useInternalCollapsibleContext from '../hooks/useInternalCollapsibleContext';
10
7
  import type { CollapsibleProps } from '../types';
11
8
  import AnimatedTopView from '../components/header/AnimatedTopView';
12
9
  import useCollapsibleContext from '../hooks/useCollapsibleContext';
13
- import { FlashList, FlashListProps } from '@shopify/flash-list';
14
-
15
- const AnimatedFlashList = Animated.createAnimatedComponent(FlashList);
10
+ import { AnimatedFlashList, FlashListProps } from '@shopify/flash-list';
11
+ import type { ScrollToIndexParams } from '../types';
16
12
 
17
13
  type Props<Data> = FlashListProps<Data> & CollapsibleProps;
18
14
 
@@ -39,7 +35,7 @@ export default function CollapsibleFlashList<Data>({
39
35
  });
40
36
  }, []);
41
37
 
42
- const scrollToIndex = useCallback((params) => {
38
+ const scrollToIndex = useCallback((params: ScrollToIndexParams) => {
43
39
  scrollViewRef.current?.scrollToIndex?.(params);
44
40
  }, []);
45
41
 
@@ -73,11 +69,15 @@ export default function CollapsibleFlashList<Data>({
73
69
 
74
70
  const handleScrollToIndexFailed = useCallback(() => {}, []);
75
71
 
72
+ const ListHeaderComponent = props.ListHeaderComponent;
76
73
  function renderListHeader() {
77
74
  return (
78
75
  <View>
79
76
  <AnimatedTopView height={headerHeight} />
80
- {props.ListHeaderComponent}
77
+ {ListHeaderComponent &&
78
+ (typeof ListHeaderComponent === 'function'
79
+ ? React.createElement(ListHeaderComponent)
80
+ : ListHeaderComponent)}
81
81
  </View>
82
82
  );
83
83
  }
@@ -13,6 +13,7 @@ import type { CollapsibleProps } from '../types';
13
13
  import AnimatedTopView from '../components/header/AnimatedTopView';
14
14
  import useCollapsibleContext from '../hooks/useCollapsibleContext';
15
15
  import { AnimatedLegendList } from '@legendapp/list/reanimated';
16
+ import type { ScrollToIndexParams } from '../types';
16
17
 
17
18
  type Props<Data> = FlatListProps<Data> & CollapsibleProps;
18
19
 
@@ -38,7 +39,7 @@ export default function CollapsibleLegendList<Data>({
38
39
  });
39
40
  }, []);
40
41
 
41
- const scrollToIndex = useCallback((params) => {
42
+ const scrollToIndex = useCallback((params: ScrollToIndexParams) => {
42
43
  scrollViewRef.current?.scrollToIndex?.(params);
43
44
  }, []);
44
45
 
@@ -72,11 +73,15 @@ export default function CollapsibleLegendList<Data>({
72
73
 
73
74
  const handleScrollToIndexFailed = useCallback(() => {}, []);
74
75
 
76
+ const ListHeaderComponent = props.ListHeaderComponent;
75
77
  function renderListHeader() {
76
78
  return (
77
79
  <View>
78
80
  <AnimatedTopView height={headerHeight} />
79
- {props.ListHeaderComponent}
81
+ {ListHeaderComponent &&
82
+ (typeof ListHeaderComponent === 'function'
83
+ ? React.createElement(ListHeaderComponent)
84
+ : ListHeaderComponent)}
80
85
  </View>
81
86
  );
82
87
  }
@@ -101,6 +106,7 @@ export default function CollapsibleLegendList<Data>({
101
106
  ListHeaderComponent={renderListHeader()}
102
107
  //@ts-ignore
103
108
  simultaneousHandlers={[]}
109
+ // @ts-ignore
104
110
  animatedProps={animatedProps}
105
111
  />
106
112
  </View>
package/src/types.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type React from 'react';
2
2
  import type { LayoutRectangle, SectionListScrollParams } from 'react-native';
3
- import type Animated from 'react-native-reanimated';
3
+ import type { SharedValue } from 'react-native-reanimated';
4
4
 
5
5
  export type ScrollToIndexParams = {
6
6
  animated?: boolean | null;
@@ -27,9 +27,9 @@ export type CollapsibleHandles = {
27
27
  };
28
28
 
29
29
  export type CollapsibleContextType = CollapsibleHandles & {
30
- scrollY: Animated.SharedValue<number>;
31
- headerHeight: Animated.SharedValue<number>;
32
- headerCollapsed: Animated.SharedValue<boolean>;
30
+ scrollY: SharedValue<number>;
31
+ headerHeight: SharedValue<number>;
32
+ headerCollapsed: SharedValue<boolean>;
33
33
  /**
34
34
  * Scroll to specific view
35
35
  * @param ref View that you want to scroll to
@@ -49,13 +49,13 @@ export type LayoutParams = {
49
49
  export type CollapsibleContextInternalType = {
50
50
  scrollViewRef: React.RefObject<any>;
51
51
  containerRef: React.RefObject<any>;
52
- containerHeight: Animated.SharedValue<number>;
53
- contentMinHeight: Animated.SharedValue<number>;
54
- headerViewPositions: Animated.SharedValue<
52
+ containerHeight: SharedValue<number>;
53
+ contentMinHeight: SharedValue<number>;
54
+ headerViewPositions: SharedValue<
55
55
  Record<string, { top: number; stickyHeight: number }>
56
56
  >;
57
- fixedHeaderHeight: Animated.SharedValue<number>;
58
- headerHeight: Animated.SharedValue<number>;
57
+ fixedHeaderHeight: SharedValue<number>;
58
+ headerHeight: SharedValue<number>;
59
59
  handleHeaderContainerLayout: (
60
60
  key: string,
61
61
  layout?: LayoutRectangle,
@@ -69,7 +69,7 @@ export type CollapsibleProps = {
69
69
  };
70
70
 
71
71
  export type PullToRefreshContextType = {
72
- refreshValue: Animated.SharedValue<number>;
73
- internalRefreshing: Animated.SharedValue<boolean>;
74
- internalHeight: Animated.SharedValue<number>;
72
+ refreshValue: SharedValue<number>;
73
+ internalRefreshing: SharedValue<boolean>;
74
+ internalHeight: SharedValue<number>;
75
75
  };
@@ -1,18 +1,49 @@
1
1
  import { useCallback, useRef } from 'react';
2
- import Animated, { useSharedValue } from 'react-native-reanimated';
2
+ import { SharedValue, useSharedValue } from 'react-native-reanimated';
3
+
4
+ function shallowEqualKeys(
5
+ a: Record<string, unknown>,
6
+ b: Record<string, unknown>
7
+ ): boolean {
8
+ for (const k in a) {
9
+ if (a[k] !== b[k]) return false;
10
+ }
11
+ for (const k in b) {
12
+ if (!(k in a)) return false;
13
+ }
14
+ return true;
15
+ }
3
16
 
4
17
  export default function useSharedValueRef<T>(
5
18
  defaultValue: T
6
- ): [Animated.SharedValue<T>, (value: T) => void] {
19
+ ): [SharedValue<T>, (value: T) => void] {
7
20
  const sharedValue = useSharedValue<T>(defaultValue);
8
21
  const savedValue = useRef<T>(defaultValue);
9
22
 
10
23
  const appendValue = useCallback(
11
24
  (value: T) => {
12
- savedValue.current = {
13
- ...savedValue.current,
14
- ...value,
15
- };
25
+ const current = savedValue.current as Record<string, unknown>;
26
+ const next = value as Record<string, unknown>;
27
+ // Quick path: same reference means no change.
28
+ if (current === next) {
29
+ return;
30
+ }
31
+ // Build the merged map: take current, overlay next, then drop any
32
+ // resulting `undefined` slots so long-lived consumers don't
33
+ // accumulate stale keys across mount/unmount cycles.
34
+ const merged: Record<string, unknown> = { ...current, ...next };
35
+ for (const k in merged) {
36
+ if (merged[k] === undefined) {
37
+ delete merged[k];
38
+ }
39
+ }
40
+ // Skip the shared-value write if the merged map is shallow-equal to
41
+ // the previous one. This protects readers (useDerivedValue
42
+ // Object.values(...).reduce) from re-running on no-op updates.
43
+ if (shallowEqualKeys(merged, current)) {
44
+ return;
45
+ }
46
+ savedValue.current = merged as T;
16
47
  sharedValue.value = savedValue.current;
17
48
  },
18
49
  [sharedValue]
@@ -8,7 +8,7 @@ import type { LayoutRectangle, View } from 'react-native';
8
8
 
9
9
  export default function withCollapsibleContext<T>(Component: FC<T>) {
10
10
  return (props: T) => {
11
- const collapsibleHandlers = useRef<CollapsibleHandles>();
11
+ const collapsibleHandlers = useRef<CollapsibleHandles>(null);
12
12
  const headerHeight = useSharedValue(0);
13
13
  const scrollY = useSharedValue(0);
14
14
  const fixedHeaderHeight = useSharedValue(0);
@@ -20,9 +20,12 @@ export default function withCollapsibleContext<T>(Component: FC<T>) {
20
20
  >({});
21
21
  const headerViewPositions = useSharedValue({});
22
22
 
23
- const setCollapsibleHandlers = useCallback((handlers) => {
24
- collapsibleHandlers.current = handlers;
25
- }, []);
23
+ const setCollapsibleHandlers = useCallback(
24
+ (handlers: CollapsibleHandles) => {
25
+ collapsibleHandlers.current = handlers;
26
+ },
27
+ []
28
+ );
26
29
 
27
30
  const headerCollapsed = useDerivedValue(() => {
28
31
  const maxY = fixedHeaderHeight.value;