@shopify/flash-list 2.0.0-alpha.9 → 2.0.0-rc.1
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.
- package/README.md +37 -97
- package/dist/AnimatedFlashList.d.ts.map +1 -1
- package/dist/AnimatedFlashList.js +3 -3
- package/dist/AnimatedFlashList.js.map +1 -1
- package/dist/FlashList.d.ts +9 -0
- package/dist/FlashList.d.ts.map +1 -1
- package/dist/FlashList.js +20 -0
- package/dist/FlashList.js.map +1 -1
- package/dist/FlashListProps.d.ts +15 -8
- package/dist/FlashListProps.d.ts.map +1 -1
- package/dist/FlashListProps.js.map +1 -1
- package/dist/FlashListRef.d.ts +305 -0
- package/dist/FlashListRef.d.ts.map +1 -0
- package/dist/FlashListRef.js +3 -0
- package/dist/FlashListRef.js.map +1 -0
- package/dist/MasonryFlashList.js.map +1 -1
- package/dist/__tests__/RecyclerView.test.js +62 -27
- package/dist/__tests__/RecyclerView.test.js.map +1 -1
- package/dist/__tests__/RenderStackManager.test.d.ts +2 -0
- package/dist/__tests__/RenderStackManager.test.d.ts.map +1 -0
- package/dist/__tests__/RenderStackManager.test.js +486 -0
- package/dist/__tests__/RenderStackManager.test.js.map +1 -0
- package/dist/__tests__/helpers/createLayoutManager.d.ts.map +1 -1
- package/dist/__tests__/helpers/createLayoutManager.js +3 -4
- package/dist/__tests__/helpers/createLayoutManager.js.map +1 -1
- package/dist/__tests__/useUnmountAwareCallbacks.test.js +1 -1
- package/dist/__tests__/useUnmountAwareCallbacks.test.js.map +1 -1
- package/dist/benchmark/useFlatListBenchmark.js +8 -7
- package/dist/benchmark/useFlatListBenchmark.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/native/config/PlatformHelper.android.d.ts +1 -0
- package/dist/native/config/PlatformHelper.android.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.android.js +1 -0
- package/dist/native/config/PlatformHelper.android.js.map +1 -1
- package/dist/native/config/PlatformHelper.d.ts +1 -0
- package/dist/native/config/PlatformHelper.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.ios.d.ts +1 -0
- package/dist/native/config/PlatformHelper.ios.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.ios.js +1 -0
- package/dist/native/config/PlatformHelper.ios.js.map +1 -1
- package/dist/native/config/PlatformHelper.js +1 -0
- package/dist/native/config/PlatformHelper.js.map +1 -1
- package/dist/native/config/PlatformHelper.web.d.ts +1 -0
- package/dist/native/config/PlatformHelper.web.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.web.js +1 -0
- package/dist/native/config/PlatformHelper.web.js.map +1 -1
- package/dist/recyclerview/RecyclerView.d.ts +2 -1
- package/dist/recyclerview/RecyclerView.d.ts.map +1 -1
- package/dist/recyclerview/RecyclerView.js +63 -45
- package/dist/recyclerview/RecyclerView.js.map +1 -1
- package/dist/recyclerview/RecyclerViewContextProvider.d.ts +6 -5
- package/dist/recyclerview/RecyclerViewContextProvider.d.ts.map +1 -1
- package/dist/recyclerview/RecyclerViewContextProvider.js.map +1 -1
- package/dist/recyclerview/RecyclerViewManager.d.ts +21 -7
- package/dist/recyclerview/RecyclerViewManager.d.ts.map +1 -1
- package/dist/recyclerview/RecyclerViewManager.js +105 -113
- package/dist/recyclerview/RecyclerViewManager.js.map +1 -1
- package/dist/recyclerview/RenderStackManager.d.ts +85 -0
- package/dist/recyclerview/RenderStackManager.d.ts.map +1 -0
- package/dist/recyclerview/RenderStackManager.js +324 -0
- package/dist/recyclerview/RenderStackManager.js.map +1 -0
- package/dist/recyclerview/ViewHolder.d.ts.map +1 -1
- package/dist/recyclerview/ViewHolder.js +5 -3
- package/dist/recyclerview/ViewHolder.js.map +1 -1
- package/dist/recyclerview/ViewHolderCollection.d.ts +3 -1
- package/dist/recyclerview/ViewHolderCollection.d.ts.map +1 -1
- package/dist/recyclerview/ViewHolderCollection.js +23 -8
- package/dist/recyclerview/ViewHolderCollection.js.map +1 -1
- package/dist/recyclerview/components/ScrollAnchor.d.ts +2 -2
- package/dist/recyclerview/components/ScrollAnchor.d.ts.map +1 -1
- package/dist/recyclerview/components/ScrollAnchor.js +9 -5
- package/dist/recyclerview/components/ScrollAnchor.js.map +1 -1
- package/dist/recyclerview/components/StickyHeaders.d.ts +1 -1
- package/dist/recyclerview/components/StickyHeaders.d.ts.map +1 -1
- package/dist/recyclerview/components/StickyHeaders.js +39 -32
- package/dist/recyclerview/components/StickyHeaders.js.map +1 -1
- package/dist/recyclerview/helpers/EngagedIndicesTracker.d.ts +45 -1
- package/dist/recyclerview/helpers/EngagedIndicesTracker.d.ts.map +1 -1
- package/dist/recyclerview/helpers/EngagedIndicesTracker.js +77 -20
- package/dist/recyclerview/helpers/EngagedIndicesTracker.js.map +1 -1
- package/dist/recyclerview/helpers/RenderTimeTracker.d.ts +10 -0
- package/dist/recyclerview/helpers/RenderTimeTracker.d.ts.map +1 -0
- package/dist/recyclerview/helpers/RenderTimeTracker.js +39 -0
- package/dist/recyclerview/helpers/RenderTimeTracker.js.map +1 -0
- package/dist/recyclerview/helpers/VelocityTracker.d.ts +29 -0
- package/dist/recyclerview/helpers/VelocityTracker.d.ts.map +1 -0
- package/dist/recyclerview/helpers/VelocityTracker.js +70 -0
- package/dist/recyclerview/helpers/VelocityTracker.js.map +1 -0
- package/dist/recyclerview/hooks/useBoundDetection.d.ts +1 -2
- package/dist/recyclerview/hooks/useBoundDetection.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useBoundDetection.js +19 -16
- package/dist/recyclerview/hooks/useBoundDetection.js.map +1 -1
- package/dist/recyclerview/hooks/useMappingHelper.d.ts +1 -1
- package/dist/recyclerview/hooks/useMappingHelper.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useMappingHelper.js +1 -1
- package/dist/recyclerview/hooks/useMappingHelper.js.map +1 -1
- package/dist/recyclerview/hooks/useOnLoad.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useOnLoad.js +4 -6
- package/dist/recyclerview/hooks/useOnLoad.js.map +1 -1
- package/dist/recyclerview/hooks/useRecyclerViewController.d.ts +3 -48
- package/dist/recyclerview/hooks/useRecyclerViewController.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useRecyclerViewController.js +174 -123
- package/dist/recyclerview/hooks/useRecyclerViewController.js.map +1 -1
- package/dist/recyclerview/hooks/useRecyclerViewManager.d.ts +2 -0
- package/dist/recyclerview/hooks/useRecyclerViewManager.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useRecyclerViewManager.js +10 -1
- package/dist/recyclerview/hooks/useRecyclerViewManager.js.map +1 -1
- package/dist/recyclerview/hooks/useSecondaryProps.js +1 -1
- package/dist/recyclerview/hooks/useUnmountAwareCallbacks.d.ts +10 -3
- package/dist/recyclerview/hooks/useUnmountAwareCallbacks.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useUnmountAwareCallbacks.js +33 -4
- package/dist/recyclerview/hooks/useUnmountAwareCallbacks.js.map +1 -1
- package/dist/recyclerview/layout-managers/GridLayoutManager.d.ts +6 -0
- package/dist/recyclerview/layout-managers/GridLayoutManager.d.ts.map +1 -1
- package/dist/recyclerview/layout-managers/GridLayoutManager.js +27 -5
- package/dist/recyclerview/layout-managers/GridLayoutManager.js.map +1 -1
- package/dist/recyclerview/layout-managers/LayoutManager.d.ts +10 -16
- package/dist/recyclerview/layout-managers/LayoutManager.d.ts.map +1 -1
- package/dist/recyclerview/layout-managers/LayoutManager.js +4 -14
- package/dist/recyclerview/layout-managers/LayoutManager.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/viewability/ViewToken.d.ts +2 -2
- package/dist/viewability/ViewToken.d.ts.map +1 -1
- package/dist/viewability/ViewabilityHelper.js +1 -1
- package/dist/viewability/ViewabilityHelper.js.map +1 -1
- package/dist/viewability/ViewabilityManager.d.ts.map +1 -1
- package/dist/viewability/ViewabilityManager.js +1 -2
- package/dist/viewability/ViewabilityManager.js.map +1 -1
- package/jestSetup.js +30 -11
- package/package.json +2 -1
- package/src/AnimatedFlashList.ts +3 -2
- package/src/FlashList.tsx +24 -0
- package/src/FlashListProps.ts +20 -8
- package/src/FlashListRef.ts +320 -0
- package/src/MasonryFlashList.tsx +2 -2
- package/src/__tests__/RecyclerView.test.tsx +83 -29
- package/src/__tests__/RenderStackManager.test.ts +575 -0
- package/src/__tests__/helpers/createLayoutManager.ts +2 -3
- package/src/__tests__/useUnmountAwareCallbacks.test.tsx +12 -12
- package/src/benchmark/useFlatListBenchmark.ts +2 -2
- package/src/index.ts +1 -0
- package/src/native/config/PlatformHelper.android.ts +1 -0
- package/src/native/config/PlatformHelper.ios.ts +1 -0
- package/src/native/config/PlatformHelper.ts +1 -0
- package/src/native/config/PlatformHelper.web.ts +1 -0
- package/src/recyclerview/RecyclerView.tsx +82 -52
- package/src/recyclerview/RecyclerViewContextProvider.ts +12 -6
- package/src/recyclerview/RecyclerViewManager.ts +123 -98
- package/src/recyclerview/RenderStackManager.ts +291 -0
- package/src/recyclerview/ViewHolder.tsx +5 -3
- package/src/recyclerview/ViewHolderCollection.tsx +33 -12
- package/src/recyclerview/components/ScrollAnchor.tsx +21 -9
- package/src/recyclerview/components/StickyHeaders.tsx +62 -44
- package/src/recyclerview/helpers/EngagedIndicesTracker.ts +118 -23
- package/src/recyclerview/helpers/RenderTimeTracker.ts +38 -0
- package/src/recyclerview/helpers/VelocityTracker.ts +77 -0
- package/src/recyclerview/hooks/useBoundDetection.ts +25 -18
- package/src/recyclerview/hooks/useMappingHelper.ts +1 -1
- package/src/recyclerview/hooks/useOnLoad.ts +4 -6
- package/src/recyclerview/hooks/useRecyclerViewController.tsx +199 -176
- package/src/recyclerview/hooks/useRecyclerViewManager.ts +11 -1
- package/src/recyclerview/hooks/useSecondaryProps.tsx +1 -1
- package/src/recyclerview/hooks/useUnmountAwareCallbacks.ts +39 -3
- package/src/recyclerview/layout-managers/GridLayoutManager.ts +30 -7
- package/src/recyclerview/layout-managers/LayoutManager.ts +12 -21
- package/src/viewability/ViewToken.ts +2 -2
- package/src/viewability/ViewabilityHelper.ts +1 -1
- package/src/viewability/ViewabilityManager.ts +6 -3
- package/dist/__tests__/RecycleKeyManager.test.d.ts +0 -2
- package/dist/__tests__/RecycleKeyManager.test.d.ts.map +0 -1
- package/dist/__tests__/RecycleKeyManager.test.js +0 -210
- package/dist/__tests__/RecycleKeyManager.test.js.map +0 -1
- package/dist/recyclerview/RecycleKeyManager.d.ts +0 -82
- package/dist/recyclerview/RecycleKeyManager.d.ts.map +0 -1
- package/dist/recyclerview/RecycleKeyManager.js +0 -135
- package/dist/recyclerview/RecycleKeyManager.js.map +0 -1
- package/src/__tests__/RecycleKeyManager.test.ts +0 -254
- package/src/recyclerview/RecycleKeyManager.ts +0 -185
|
@@ -25,7 +25,7 @@ export function useFlatListBenchmark(
|
|
|
25
25
|
) {
|
|
26
26
|
useEffect(() => {
|
|
27
27
|
const cancellable = new Cancellable();
|
|
28
|
-
if (flatListRef.current) {
|
|
28
|
+
if (flatListRef.current && flatListRef.current.props) {
|
|
29
29
|
if (!(Number(flatListRef.current.props.data?.length) > 0)) {
|
|
30
30
|
throw new Error("Data is empty, cannot run benchmark");
|
|
31
31
|
}
|
|
@@ -71,7 +71,7 @@ async function runScrollBenchmark(
|
|
|
71
71
|
scrollSpeedMultiplier: number
|
|
72
72
|
): Promise<void> {
|
|
73
73
|
if (flatListRef.current) {
|
|
74
|
-
const horizontal = flatListRef.current.props
|
|
74
|
+
const horizontal = Boolean(flatListRef.current.props?.horizontal);
|
|
75
75
|
|
|
76
76
|
const fromX = 0;
|
|
77
77
|
const fromY = 0;
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { BaseItemAnimator } from "recyclerlistview";
|
|
|
3
3
|
const PlatformConfig = {
|
|
4
4
|
defaultDrawDistance: 250,
|
|
5
5
|
supportsOffsetCorrection: true,
|
|
6
|
+
trackAverageRenderTimeForOffsetProjection: true,
|
|
6
7
|
// Using rotate instead of scaleY on Android to avoid performance issues. Issue: https://github.com/Shopify/flash-list/issues/751
|
|
7
8
|
invertedTransformStyle: { transform: [{ rotate: "180deg" }] },
|
|
8
9
|
invertedTransformStyleHorizontal: { transform: [{ rotate: "180deg" }] },
|
|
@@ -3,6 +3,7 @@ import { BaseItemAnimator } from "recyclerlistview";
|
|
|
3
3
|
const PlatformConfig = {
|
|
4
4
|
defaultDrawDistance: 250,
|
|
5
5
|
supportsOffsetCorrection: true,
|
|
6
|
+
trackAverageRenderTimeForOffsetProjection: false,
|
|
6
7
|
invertedTransformStyle: { transform: [{ scaleY: -1 }] },
|
|
7
8
|
invertedTransformStyleHorizontal: { transform: [{ scaleX: -1 }] },
|
|
8
9
|
};
|
|
@@ -4,6 +4,7 @@ import { DefaultJSItemAnimator } from "recyclerlistview/dist/reactnative/platfor
|
|
|
4
4
|
const PlatformConfig = {
|
|
5
5
|
defaultDrawDistance: 250,
|
|
6
6
|
supportsOffsetCorrection: false,
|
|
7
|
+
trackAverageRenderTimeForOffsetProjection: false,
|
|
7
8
|
invertedTransformStyle: { transform: [{ scaleY: -1 }] },
|
|
8
9
|
invertedTransformStyleHorizontal: { transform: [{ scaleX: -1 }] },
|
|
9
10
|
};
|
|
@@ -6,6 +6,7 @@ import { DefaultJSItemAnimator } from "recyclerlistview/dist/reactnative/platfor
|
|
|
6
6
|
const PlatformConfig = {
|
|
7
7
|
defaultDrawDistance: 500,
|
|
8
8
|
supportsOffsetCorrection: false,
|
|
9
|
+
trackAverageRenderTimeForOffsetProjection: false,
|
|
9
10
|
invertedTransformStyle: { transform: [{ scaleY: -1 }] },
|
|
10
11
|
invertedTransformStyleHorizontal: { transform: [{ scaleX: -1 }] },
|
|
11
12
|
};
|
|
@@ -19,6 +19,8 @@ import {
|
|
|
19
19
|
NativeSyntheticEvent,
|
|
20
20
|
} from "react-native";
|
|
21
21
|
|
|
22
|
+
import { FlashListRef } from "../FlashListRef";
|
|
23
|
+
|
|
22
24
|
import { RVDimension } from "./layout-managers/LayoutManager";
|
|
23
25
|
import {
|
|
24
26
|
areDimensionsNotEqual,
|
|
@@ -47,6 +49,7 @@ import { useSecondaryProps } from "./hooks/useSecondaryProps";
|
|
|
47
49
|
import { StickyHeaders, StickyHeaderRef } from "./components/StickyHeaders";
|
|
48
50
|
import { ScrollAnchor, ScrollAnchorRef } from "./components/ScrollAnchor";
|
|
49
51
|
import { useRecyclerViewController } from "./hooks/useRecyclerViewController";
|
|
52
|
+
import { RenderTimeTracker } from "./helpers/RenderTimeTracker";
|
|
50
53
|
|
|
51
54
|
/**
|
|
52
55
|
* Main RecyclerView component that handles list rendering, scrolling, and item recycling.
|
|
@@ -54,7 +57,7 @@ import { useRecyclerViewController } from "./hooks/useRecyclerViewController";
|
|
|
54
57
|
*/
|
|
55
58
|
const RecyclerViewComponent = <T,>(
|
|
56
59
|
props: RecyclerViewProps<T>,
|
|
57
|
-
ref: React.Ref<
|
|
60
|
+
ref: React.Ref<FlashListRef<T>>
|
|
58
61
|
) => {
|
|
59
62
|
// Destructure props and initialize refs
|
|
60
63
|
const {
|
|
@@ -75,8 +78,6 @@ const RecyclerViewComponent = <T,>(
|
|
|
75
78
|
ListFooterComponentStyle,
|
|
76
79
|
ItemSeparatorComponent,
|
|
77
80
|
renderScrollComponent,
|
|
78
|
-
onScroll,
|
|
79
|
-
disableRecycling,
|
|
80
81
|
style,
|
|
81
82
|
stickyHeaderIndices,
|
|
82
83
|
maintainVisibleContentPosition,
|
|
@@ -84,6 +85,10 @@ const RecyclerViewComponent = <T,>(
|
|
|
84
85
|
...rest
|
|
85
86
|
} = props;
|
|
86
87
|
|
|
88
|
+
const [renderTimeTracker] = useState(() => new RenderTimeTracker());
|
|
89
|
+
|
|
90
|
+
renderTimeTracker.startTracking();
|
|
91
|
+
|
|
87
92
|
// Core refs for managing scroll view, internal view, and child container
|
|
88
93
|
const scrollViewRef = useRef<CompatScroller>(null);
|
|
89
94
|
const internalViewRef = useRef<CompatView>(null);
|
|
@@ -109,14 +114,14 @@ const RecyclerViewComponent = <T,>(
|
|
|
109
114
|
);
|
|
110
115
|
|
|
111
116
|
// Initialize core RecyclerView manager and content offset management
|
|
112
|
-
const { recyclerViewManager } =
|
|
113
|
-
|
|
117
|
+
const { recyclerViewManager, velocityTracker } =
|
|
118
|
+
useRecyclerViewManager(props);
|
|
119
|
+
const { applyContentOffset, applyInitialScrollIndex, handlerMethods } =
|
|
114
120
|
useRecyclerViewController(
|
|
115
121
|
recyclerViewManager,
|
|
116
122
|
ref,
|
|
117
123
|
scrollViewRef,
|
|
118
|
-
scrollAnchorRef
|
|
119
|
-
props
|
|
124
|
+
scrollAnchorRef
|
|
120
125
|
);
|
|
121
126
|
|
|
122
127
|
// Initialize view holder collection ref
|
|
@@ -126,11 +131,7 @@ const RecyclerViewComponent = <T,>(
|
|
|
126
131
|
useOnListLoad(recyclerViewManager, onLoad);
|
|
127
132
|
|
|
128
133
|
// Hook to detect when scrolling reaches list bounds
|
|
129
|
-
const { checkBounds } = useBoundDetection(
|
|
130
|
-
recyclerViewManager,
|
|
131
|
-
props,
|
|
132
|
-
scrollViewRef
|
|
133
|
-
);
|
|
134
|
+
const { checkBounds } = useBoundDetection(recyclerViewManager, scrollViewRef);
|
|
134
135
|
|
|
135
136
|
const isHorizontalRTL = I18nManager.isRTL && horizontal;
|
|
136
137
|
|
|
@@ -176,6 +177,7 @@ const RecyclerViewComponent = <T,>(
|
|
|
176
177
|
* Effect to handle layout updates for list items
|
|
177
178
|
* This ensures proper positioning and recycling of items
|
|
178
179
|
*/
|
|
180
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
179
181
|
useLayoutEffect(() => {
|
|
180
182
|
if (pendingChildIds.size > 0) {
|
|
181
183
|
return;
|
|
@@ -183,7 +185,7 @@ const RecyclerViewComponent = <T,>(
|
|
|
183
185
|
const layoutInfo = Array.from(refHolder, ([index, viewHolderRef]) => {
|
|
184
186
|
const layout = measureItemLayout(
|
|
185
187
|
viewHolderRef.current!,
|
|
186
|
-
recyclerViewManager.
|
|
188
|
+
recyclerViewManager.tryGetLayout(index)
|
|
187
189
|
);
|
|
188
190
|
|
|
189
191
|
// comapre height with stored layout
|
|
@@ -221,23 +223,11 @@ const RecyclerViewComponent = <T,>(
|
|
|
221
223
|
if (recyclerViewManager.ignoreScrollEvents) {
|
|
222
224
|
return;
|
|
223
225
|
}
|
|
224
|
-
let velocity = event.nativeEvent.velocity;
|
|
225
226
|
|
|
226
227
|
let scrollOffset = horizontal
|
|
227
228
|
? event.nativeEvent.contentOffset.x
|
|
228
229
|
: event.nativeEvent.contentOffset.y;
|
|
229
230
|
|
|
230
|
-
if (!velocity) {
|
|
231
|
-
const velocityValue =
|
|
232
|
-
recyclerViewManager.getAbsoluteLastScrollOffset() < scrollOffset
|
|
233
|
-
? 1
|
|
234
|
-
: -1;
|
|
235
|
-
velocity = {
|
|
236
|
-
x: horizontal ? velocityValue : 0,
|
|
237
|
-
y: horizontal ? 0 : velocityValue,
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
|
|
241
231
|
// Handle RTL (Right-to-Left) layout adjustments
|
|
242
232
|
if (isHorizontalRTL) {
|
|
243
233
|
scrollOffset = adjustOffsetForRTL(
|
|
@@ -245,18 +235,30 @@ const RecyclerViewComponent = <T,>(
|
|
|
245
235
|
event.nativeEvent.contentSize.width,
|
|
246
236
|
event.nativeEvent.layoutMeasurement.width
|
|
247
237
|
);
|
|
248
|
-
if (velocity) {
|
|
249
|
-
velocity = {
|
|
250
|
-
x: -velocity.x,
|
|
251
|
-
y: velocity.y,
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
// Update scroll position and trigger re-render if needed
|
|
256
|
-
if (recyclerViewManager.updateScrollOffset(scrollOffset, velocity)) {
|
|
257
|
-
setRenderId((prev) => prev + 1);
|
|
258
238
|
}
|
|
259
239
|
|
|
240
|
+
velocityTracker.computeVelocity(
|
|
241
|
+
scrollOffset,
|
|
242
|
+
recyclerViewManager.getAbsoluteLastScrollOffset(),
|
|
243
|
+
Boolean(horizontal),
|
|
244
|
+
(velocity, isMomentumEnd) => {
|
|
245
|
+
if (recyclerViewManager.ignoreScrollEvents) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (isMomentumEnd) {
|
|
250
|
+
if (!recyclerViewManager.isOffsetProjectionEnabled) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
recyclerViewManager.resetVelocityCompute();
|
|
254
|
+
}
|
|
255
|
+
// Update scroll position and trigger re-render if needed
|
|
256
|
+
if (recyclerViewManager.updateScrollOffset(scrollOffset, velocity)) {
|
|
257
|
+
setRenderId((prev) => prev + 1);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
);
|
|
261
|
+
|
|
260
262
|
// Update sticky headers and check bounds
|
|
261
263
|
stickyHeaderRef.current?.reportScrollEvent(event.nativeEvent);
|
|
262
264
|
checkBounds();
|
|
@@ -266,22 +268,31 @@ const RecyclerViewComponent = <T,>(
|
|
|
266
268
|
recyclerViewManager.computeItemViewability();
|
|
267
269
|
|
|
268
270
|
// Call user-provided onScroll handler
|
|
269
|
-
onScroll?.(event);
|
|
271
|
+
recyclerViewManager.props.onScroll?.(event);
|
|
270
272
|
},
|
|
271
|
-
[
|
|
273
|
+
[
|
|
274
|
+
checkBounds,
|
|
275
|
+
horizontal,
|
|
276
|
+
isHorizontalRTL,
|
|
277
|
+
recyclerViewManager,
|
|
278
|
+
velocityTracker,
|
|
279
|
+
]
|
|
272
280
|
);
|
|
273
281
|
|
|
274
282
|
// Create context for child components
|
|
275
|
-
const recyclerViewContext: RecyclerViewContext = useMemo(() => {
|
|
283
|
+
const recyclerViewContext: RecyclerViewContext<T> = useMemo(() => {
|
|
276
284
|
return {
|
|
277
285
|
layout: () => {
|
|
278
286
|
setLayoutTreeId((prev) => prev + 1);
|
|
279
287
|
},
|
|
280
288
|
getRef: () => {
|
|
281
|
-
|
|
289
|
+
if (recyclerViewManager.isDisposed) {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
return handlerMethods;
|
|
282
293
|
},
|
|
283
294
|
getScrollViewRef: () => {
|
|
284
|
-
return scrollViewRef;
|
|
295
|
+
return scrollViewRef.current;
|
|
285
296
|
},
|
|
286
297
|
markChildLayoutAsPending: (id: string) => {
|
|
287
298
|
pendingChildIds.add(id);
|
|
@@ -293,7 +304,7 @@ const RecyclerViewComponent = <T,>(
|
|
|
293
304
|
}
|
|
294
305
|
},
|
|
295
306
|
};
|
|
296
|
-
}, [setLayoutTreeId]);
|
|
307
|
+
}, [handlerMethods, pendingChildIds, recyclerViewManager, setLayoutTreeId]);
|
|
297
308
|
|
|
298
309
|
const parentRecyclerViewContext = useRecyclerViewContext();
|
|
299
310
|
const recyclerViewId = useId();
|
|
@@ -328,7 +339,7 @@ const RecyclerViewComponent = <T,>(
|
|
|
328
339
|
recyclerViewContext.layout();
|
|
329
340
|
}
|
|
330
341
|
},
|
|
331
|
-
[recyclerViewManager]
|
|
342
|
+
[recyclerViewContext, recyclerViewManager]
|
|
332
343
|
);
|
|
333
344
|
|
|
334
345
|
// Get secondary props and components
|
|
@@ -368,7 +379,14 @@ const RecyclerViewComponent = <T,>(
|
|
|
368
379
|
);
|
|
369
380
|
}
|
|
370
381
|
return null;
|
|
371
|
-
}, [
|
|
382
|
+
}, [
|
|
383
|
+
data,
|
|
384
|
+
stickyHeaderIndices,
|
|
385
|
+
renderItem,
|
|
386
|
+
scrollY,
|
|
387
|
+
recyclerViewManager,
|
|
388
|
+
extraData,
|
|
389
|
+
]);
|
|
372
390
|
|
|
373
391
|
// Set up scroll event handling with animation support for sticky headers
|
|
374
392
|
const animatedEvent = useMemo(() => {
|
|
@@ -379,21 +397,23 @@ const RecyclerViewComponent = <T,>(
|
|
|
379
397
|
);
|
|
380
398
|
}
|
|
381
399
|
return onScrollHandler;
|
|
382
|
-
}, [onScrollHandler, stickyHeaders]);
|
|
400
|
+
}, [onScrollHandler, scrollY, stickyHeaders]);
|
|
401
|
+
|
|
402
|
+
const shouldMaintainVisibleContentPosition =
|
|
403
|
+
recyclerViewManager.shouldMaintainVisibleContentPosition();
|
|
383
404
|
|
|
384
405
|
const maintainVisibleContentPositionInternal = useMemo(() => {
|
|
385
|
-
if (
|
|
386
|
-
return undefined;
|
|
387
|
-
} else {
|
|
406
|
+
if (shouldMaintainVisibleContentPosition) {
|
|
388
407
|
return {
|
|
389
408
|
...maintainVisibleContentPosition,
|
|
390
409
|
minIndexForVisible: 0,
|
|
391
410
|
};
|
|
392
411
|
}
|
|
393
|
-
|
|
412
|
+
return undefined;
|
|
413
|
+
}, [maintainVisibleContentPosition, shouldMaintainVisibleContentPosition]);
|
|
394
414
|
|
|
395
415
|
const shouldRenderFromBottom =
|
|
396
|
-
|
|
416
|
+
maintainVisibleContentPosition?.startRenderingFromBottom ?? false;
|
|
397
417
|
|
|
398
418
|
// Calculate minimum height adjustment for bottom rendering
|
|
399
419
|
const adjustmentMinHeight = recyclerViewManager.hasLayout()
|
|
@@ -466,7 +486,10 @@ const RecyclerViewComponent = <T,>(
|
|
|
466
486
|
>
|
|
467
487
|
{/* Scroll anchor for maintaining content position */}
|
|
468
488
|
{maintainVisibleContentPositionInternal && (
|
|
469
|
-
<ScrollAnchor
|
|
489
|
+
<ScrollAnchor
|
|
490
|
+
horizontal={Boolean(horizontal)}
|
|
491
|
+
scrollAnchorRef={scrollAnchorRef}
|
|
492
|
+
/>
|
|
470
493
|
)}
|
|
471
494
|
{isHorizontalRTL && viewToMeasureBoundedSize}
|
|
472
495
|
{renderHeader}
|
|
@@ -490,10 +513,14 @@ const RecyclerViewComponent = <T,>(
|
|
|
490
513
|
onCommitLayoutEffect?.();
|
|
491
514
|
}}
|
|
492
515
|
onCommitEffect={() => {
|
|
516
|
+
renderTimeTracker.markRenderComplete();
|
|
517
|
+
recyclerViewManager.updateAverageRenderTime(
|
|
518
|
+
renderTimeTracker.getAverageRenderTime()
|
|
519
|
+
);
|
|
493
520
|
applyInitialScrollIndex();
|
|
494
521
|
checkBounds();
|
|
495
522
|
recyclerViewManager.computeItemViewability();
|
|
496
|
-
recyclerViewManager.disableRecycling
|
|
523
|
+
recyclerViewManager.disableRecycling(false);
|
|
497
524
|
}}
|
|
498
525
|
CellRendererComponent={CellRendererComponent}
|
|
499
526
|
ItemSeparatorComponent={ItemSeparatorComponent}
|
|
@@ -512,9 +539,12 @@ const RecyclerViewComponent = <T,>(
|
|
|
512
539
|
);
|
|
513
540
|
};
|
|
514
541
|
|
|
542
|
+
// Set displayName for the inner component
|
|
543
|
+
RecyclerViewComponent.displayName = "FlashList";
|
|
544
|
+
|
|
515
545
|
// Type definition for the RecyclerView component
|
|
516
546
|
type RecyclerViewType = <T>(
|
|
517
|
-
props: RecyclerViewProps<T> & { ref?: React.Ref<
|
|
547
|
+
props: RecyclerViewProps<T> & { ref?: React.Ref<FlashListRef<T>> }
|
|
518
548
|
) => React.JSX.Element;
|
|
519
549
|
|
|
520
550
|
// Create and export the memoized, forwarded ref component
|
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
import { createContext, useContext } from "react";
|
|
2
2
|
|
|
3
|
+
import { FlashListRef } from "../FlashListRef";
|
|
4
|
+
|
|
3
5
|
import { CompatScroller } from "./components/CompatScroller";
|
|
4
6
|
|
|
5
|
-
export interface RecyclerViewContext {
|
|
7
|
+
export interface RecyclerViewContext<T> {
|
|
6
8
|
layout: () => void;
|
|
7
|
-
getRef: () =>
|
|
8
|
-
getScrollViewRef: () =>
|
|
9
|
+
getRef: () => FlashListRef<T> | null;
|
|
10
|
+
getScrollViewRef: () => CompatScroller | null;
|
|
9
11
|
markChildLayoutAsPending: (id: string) => void;
|
|
10
12
|
unmarkChildLayoutAsPending: (id: string) => void;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
const RecyclerViewContextInstance = createContext<
|
|
14
|
-
RecyclerViewContext | undefined
|
|
16
|
+
RecyclerViewContext<unknown> | undefined
|
|
15
17
|
>(undefined);
|
|
16
18
|
|
|
17
19
|
export const RecyclerViewContextProvider = RecyclerViewContextInstance.Provider;
|
|
18
|
-
export function useRecyclerViewContext()
|
|
19
|
-
|
|
20
|
+
export function useRecyclerViewContext<T>():
|
|
21
|
+
| RecyclerViewContext<T>
|
|
22
|
+
| undefined {
|
|
23
|
+
return useContext(RecyclerViewContextInstance) as
|
|
24
|
+
| RecyclerViewContext<T>
|
|
25
|
+
| undefined;
|
|
20
26
|
}
|