@shopify/flash-list 2.0.0-alpha.2 → 2.0.0-alpha.21
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 +67 -96
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/BlankAreaEvent.kt +2 -2
- package/dist/AnimatedFlashList.d.ts +0 -1
- 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 +22 -3
- package/dist/FlashList.js.map +1 -1
- package/dist/FlashListProps.d.ts +33 -13
- 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/GridLayoutProviderWithProps.js +1 -2
- package/dist/GridLayoutProviderWithProps.js.map +1 -1
- package/dist/MasonryFlashList.d.ts +2 -2
- package/dist/MasonryFlashList.d.ts.map +1 -1
- package/dist/MasonryFlashList.js.map +1 -1
- package/dist/PureComponentWrapper.js +1 -1
- package/dist/PureComponentWrapper.js.map +1 -1
- package/dist/__tests__/AverageWindow.test.js.map +1 -1
- package/dist/__tests__/ConsecutiveNumbers.test.d.ts +2 -0
- package/dist/__tests__/ConsecutiveNumbers.test.d.ts.map +1 -0
- package/dist/__tests__/ConsecutiveNumbers.test.js +224 -0
- package/dist/__tests__/ConsecutiveNumbers.test.js.map +1 -0
- package/dist/__tests__/FlashList.test.js.map +1 -1
- package/dist/__tests__/GridLayoutManager.test.d.ts +2 -0
- package/dist/__tests__/GridLayoutManager.test.d.ts.map +1 -0
- package/dist/__tests__/GridLayoutManager.test.js +69 -0
- package/dist/__tests__/GridLayoutManager.test.js.map +1 -0
- package/dist/__tests__/GridLayoutProviderWithProps.test.js.map +1 -1
- package/dist/__tests__/LayoutCommitObserver.test.d.ts +2 -0
- package/dist/__tests__/LayoutCommitObserver.test.d.ts.map +1 -0
- package/dist/__tests__/LayoutCommitObserver.test.js +35 -0
- package/dist/__tests__/LayoutCommitObserver.test.js.map +1 -0
- package/dist/__tests__/LinearLayoutManager.test.d.ts +2 -0
- package/dist/__tests__/LinearLayoutManager.test.d.ts.map +1 -0
- package/dist/__tests__/LinearLayoutManager.test.js +140 -0
- package/dist/__tests__/LinearLayoutManager.test.js.map +1 -0
- package/dist/__tests__/MasonryFlashList.test.js.map +1 -1
- package/dist/__tests__/MasonryLayoutManager.test.d.ts +2 -0
- package/dist/__tests__/MasonryLayoutManager.test.d.ts.map +1 -0
- package/dist/__tests__/MasonryLayoutManager.test.js +148 -0
- package/dist/__tests__/MasonryLayoutManager.test.js.map +1 -0
- package/dist/__tests__/RecyclerView.test.d.ts +2 -0
- package/dist/__tests__/RecyclerView.test.d.ts.map +1 -0
- package/dist/__tests__/RecyclerView.test.js +103 -0
- package/dist/__tests__/RecyclerView.test.js.map +1 -0
- 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 +485 -0
- package/dist/__tests__/RenderStackManager.test.js.map +1 -0
- package/dist/__tests__/ViewabilityHelper.test.js.map +1 -1
- package/dist/__tests__/findVisibleIndex.test.d.ts +2 -0
- package/dist/__tests__/findVisibleIndex.test.d.ts.map +1 -0
- package/dist/__tests__/findVisibleIndex.test.js +259 -0
- package/dist/__tests__/findVisibleIndex.test.js.map +1 -0
- package/dist/__tests__/helpers/createLayoutManager.d.ts +34 -0
- package/dist/__tests__/helpers/createLayoutManager.d.ts.map +1 -0
- package/dist/__tests__/helpers/createLayoutManager.js +110 -0
- package/dist/__tests__/helpers/createLayoutManager.js.map +1 -0
- package/dist/__tests__/helpers/mountFlashList.d.ts +2 -2
- package/dist/__tests__/helpers/mountFlashList.d.ts.map +1 -1
- package/dist/__tests__/helpers/mountFlashList.js +2 -2
- package/dist/__tests__/helpers/mountFlashList.js.map +1 -1
- package/dist/__tests__/helpers/mountMasonryFlashList.d.ts +2 -2
- package/dist/__tests__/helpers/mountMasonryFlashList.d.ts.map +1 -1
- package/dist/__tests__/helpers/mountMasonryFlashList.js +2 -2
- package/dist/__tests__/helpers/mountMasonryFlashList.js.map +1 -1
- package/dist/__tests__/useBlankAreaTracker.test.js.map +1 -1
- package/dist/__tests__/useUnmountAwareCallbacks.test.d.ts +2 -0
- package/dist/__tests__/useUnmountAwareCallbacks.test.d.ts.map +1 -0
- package/dist/__tests__/useUnmountAwareCallbacks.test.js +185 -0
- package/dist/__tests__/useUnmountAwareCallbacks.test.js.map +1 -0
- package/dist/benchmark/AutoScrollHelper.js +2 -2
- package/dist/benchmark/AutoScrollHelper.js.map +1 -1
- package/dist/benchmark/JSFPSMonitor.js.map +1 -1
- package/dist/benchmark/roundToDecimalPlaces.js +1 -2
- package/dist/benchmark/roundToDecimalPlaces.js.map +1 -1
- package/dist/benchmark/useBenchmark.js +2 -28
- package/dist/benchmark/useBenchmark.js.map +1 -1
- package/dist/benchmark/useBlankAreaTracker.js +1 -2
- package/dist/benchmark/useBlankAreaTracker.js.map +1 -1
- package/dist/benchmark/useDataMultiplier.js +1 -2
- package/dist/benchmark/useDataMultiplier.js.map +1 -1
- package/dist/benchmark/useFlatListBenchmark.d.ts +0 -1
- package/dist/benchmark/useFlatListBenchmark.d.ts.map +1 -1
- package/dist/benchmark/useFlatListBenchmark.js +9 -9
- package/dist/benchmark/useFlatListBenchmark.js.map +1 -1
- package/dist/enableNewCore.d.ts.map +1 -1
- package/dist/enableNewCore.js +4 -4
- package/dist/enableNewCore.js.map +1 -1
- package/dist/errors/CustomError.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -3
- package/dist/index.js.map +1 -1
- package/dist/native/auto-layout/AutoLayoutView.d.ts +1 -1
- package/dist/native/auto-layout/AutoLayoutView.d.ts.map +1 -1
- package/dist/native/auto-layout/AutoLayoutView.js +1 -1
- package/dist/native/auto-layout/AutoLayoutView.js.map +1 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.d.ts.map +1 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts +1 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.android.d.ts +2 -0
- package/dist/native/config/PlatformHelper.android.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.android.js +2 -0
- package/dist/native/config/PlatformHelper.android.js.map +1 -1
- package/dist/native/config/PlatformHelper.d.ts +2 -0
- package/dist/native/config/PlatformHelper.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.ios.d.ts +2 -0
- package/dist/native/config/PlatformHelper.ios.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.ios.js +2 -0
- package/dist/native/config/PlatformHelper.ios.js.map +1 -1
- package/dist/native/config/PlatformHelper.js +2 -0
- package/dist/native/config/PlatformHelper.js.map +1 -1
- package/dist/native/config/PlatformHelper.web.d.ts +2 -0
- package/dist/native/config/PlatformHelper.web.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.web.js +3 -1
- package/dist/native/config/PlatformHelper.web.js.map +1 -1
- package/dist/recyclerview/LayoutCommitObserver.d.ts +12 -0
- package/dist/recyclerview/LayoutCommitObserver.d.ts.map +1 -0
- package/dist/recyclerview/LayoutCommitObserver.js +62 -0
- package/dist/recyclerview/LayoutCommitObserver.js.map +1 -0
- package/dist/recyclerview/RecyclerView.d.ts +3 -2
- package/dist/recyclerview/RecyclerView.d.ts.map +1 -1
- package/dist/recyclerview/RecyclerView.js +133 -69
- package/dist/recyclerview/RecyclerView.js.map +1 -1
- package/dist/recyclerview/RecyclerViewContextProvider.d.ts +41 -7
- package/dist/recyclerview/RecyclerViewContextProvider.d.ts.map +1 -1
- package/dist/recyclerview/RecyclerViewContextProvider.js +6 -2
- package/dist/recyclerview/RecyclerViewContextProvider.js.map +1 -1
- package/dist/recyclerview/RecyclerViewManager.d.ts +31 -7
- package/dist/recyclerview/RecyclerViewManager.d.ts.map +1 -1
- package/dist/recyclerview/RecyclerViewManager.js +154 -117
- package/dist/recyclerview/RecyclerViewManager.js.map +1 -1
- package/dist/recyclerview/RecyclerViewProps.d.ts +1 -1
- package/dist/recyclerview/RecyclerViewProps.d.ts.map +1 -1
- package/dist/recyclerview/RenderStackManager.d.ts +86 -0
- package/dist/recyclerview/RenderStackManager.d.ts.map +1 -0
- package/dist/recyclerview/RenderStackManager.js +343 -0
- package/dist/recyclerview/RenderStackManager.js.map +1 -0
- package/dist/recyclerview/ViewHolder.d.ts.map +1 -1
- package/dist/recyclerview/ViewHolder.js +8 -6
- package/dist/recyclerview/ViewHolder.js.map +1 -1
- package/dist/recyclerview/ViewHolderCollection.d.ts +10 -4
- package/dist/recyclerview/ViewHolderCollection.d.ts.map +1 -1
- package/dist/recyclerview/ViewHolderCollection.js +26 -10
- package/dist/recyclerview/ViewHolderCollection.js.map +1 -1
- package/dist/recyclerview/components/ScrollAnchor.d.ts +2 -1
- package/dist/recyclerview/components/ScrollAnchor.d.ts.map +1 -1
- package/dist/recyclerview/components/ScrollAnchor.js +12 -9
- package/dist/recyclerview/components/ScrollAnchor.js.map +1 -1
- package/dist/recyclerview/components/StickyHeaders.d.ts +2 -2
- package/dist/recyclerview/components/StickyHeaders.d.ts.map +1 -1
- package/dist/recyclerview/components/StickyHeaders.js +44 -45
- package/dist/recyclerview/components/StickyHeaders.js.map +1 -1
- package/dist/recyclerview/helpers/ConsecutiveNumbers.d.ts +1 -1
- package/dist/recyclerview/helpers/ConsecutiveNumbers.d.ts.map +1 -1
- package/dist/recyclerview/helpers/ConsecutiveNumbers.js +2 -2
- package/dist/recyclerview/helpers/ConsecutiveNumbers.js.map +1 -1
- package/dist/recyclerview/helpers/EngagedIndicesTracker.d.ts +48 -2
- package/dist/recyclerview/helpers/EngagedIndicesTracker.d.ts.map +1 -1
- package/dist/recyclerview/helpers/EngagedIndicesTracker.js +89 -19
- package/dist/recyclerview/helpers/EngagedIndicesTracker.js.map +1 -1
- package/dist/recyclerview/helpers/RenderTimeTracker.d.ts +11 -0
- package/dist/recyclerview/helpers/RenderTimeTracker.d.ts.map +1 -0
- package/dist/recyclerview/helpers/RenderTimeTracker.js +42 -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 -3
- package/dist/recyclerview/hooks/useBoundDetection.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useBoundDetection.js +60 -28
- package/dist/recyclerview/hooks/useBoundDetection.js.map +1 -1
- package/dist/recyclerview/hooks/useLayoutState.d.ts +3 -1
- package/dist/recyclerview/hooks/useLayoutState.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useLayoutState.js +6 -5
- package/dist/recyclerview/hooks/useLayoutState.js.map +1 -1
- package/dist/recyclerview/hooks/useMappingHelper.d.ts +9 -0
- package/dist/recyclerview/hooks/useMappingHelper.d.ts.map +1 -0
- package/dist/recyclerview/hooks/useMappingHelper.js +19 -0
- package/dist/recyclerview/hooks/useMappingHelper.js.map +1 -0
- package/dist/recyclerview/hooks/useOnLoad.d.ts +2 -2
- package/dist/recyclerview/hooks/useOnLoad.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useOnLoad.js +9 -10
- package/dist/recyclerview/hooks/useOnLoad.js.map +1 -1
- package/dist/recyclerview/hooks/useRecyclerViewController.d.ts +5 -49
- package/dist/recyclerview/hooks/useRecyclerViewController.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useRecyclerViewController.js +343 -191
- 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 +11 -1
- package/dist/recyclerview/hooks/useRecyclerViewManager.js.map +1 -1
- package/dist/recyclerview/hooks/useRecyclingState.d.ts +4 -2
- package/dist/recyclerview/hooks/useRecyclingState.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useRecyclingState.js +3 -4
- package/dist/recyclerview/hooks/useRecyclingState.js.map +1 -1
- package/dist/recyclerview/hooks/useSecondaryProps.d.ts +1 -1
- package/dist/recyclerview/hooks/useSecondaryProps.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useSecondaryProps.js +15 -12
- package/dist/recyclerview/hooks/useSecondaryProps.js.map +1 -1
- package/dist/recyclerview/hooks/useUnmountAwareCallbacks.d.ts +15 -0
- package/dist/recyclerview/hooks/useUnmountAwareCallbacks.d.ts.map +1 -0
- package/dist/recyclerview/hooks/useUnmountAwareCallbacks.js +63 -0
- package/dist/recyclerview/hooks/useUnmountAwareCallbacks.js.map +1 -0
- package/dist/recyclerview/hooks/useUnmountFlag.d.ts +0 -1
- package/dist/recyclerview/hooks/useUnmountFlag.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useUnmountFlag.js +1 -0
- package/dist/recyclerview/hooks/useUnmountFlag.js.map +1 -1
- package/dist/recyclerview/layout-managers/GridLayoutManager.d.ts +18 -4
- package/dist/recyclerview/layout-managers/GridLayoutManager.d.ts.map +1 -1
- package/dist/recyclerview/layout-managers/GridLayoutManager.js +61 -25
- package/dist/recyclerview/layout-managers/GridLayoutManager.js.map +1 -1
- package/dist/recyclerview/layout-managers/LayoutManager.d.ts +36 -21
- package/dist/recyclerview/layout-managers/LayoutManager.d.ts.map +1 -1
- package/dist/recyclerview/layout-managers/LayoutManager.js +96 -28
- package/dist/recyclerview/layout-managers/LayoutManager.js.map +1 -1
- package/dist/recyclerview/layout-managers/LinearLayoutManager.d.ts +1 -2
- package/dist/recyclerview/layout-managers/LinearLayoutManager.d.ts.map +1 -1
- package/dist/recyclerview/layout-managers/LinearLayoutManager.js +3 -3
- package/dist/recyclerview/layout-managers/LinearLayoutManager.js.map +1 -1
- package/dist/recyclerview/layout-managers/MasonryLayoutManager.d.ts +9 -1
- package/dist/recyclerview/layout-managers/MasonryLayoutManager.d.ts.map +1 -1
- package/dist/recyclerview/layout-managers/MasonryLayoutManager.js +30 -16
- package/dist/recyclerview/layout-managers/MasonryLayoutManager.js.map +1 -1
- package/dist/recyclerview/utils/adjustOffsetForRTL.js +1 -2
- package/dist/recyclerview/utils/adjustOffsetForRTL.js.map +1 -1
- package/dist/recyclerview/utils/componentUtils.d.ts +1 -1
- package/dist/recyclerview/utils/componentUtils.d.ts.map +1 -1
- package/dist/recyclerview/utils/componentUtils.js.map +1 -1
- package/dist/recyclerview/utils/findVisibleIndex.d.ts.map +1 -1
- package/dist/recyclerview/utils/findVisibleIndex.js +3 -5
- package/dist/recyclerview/utils/findVisibleIndex.js.map +1 -1
- package/dist/recyclerview/utils/measureLayout.d.ts +24 -28
- package/dist/recyclerview/utils/measureLayout.d.ts.map +1 -1
- package/dist/recyclerview/utils/measureLayout.js +36 -6
- package/dist/recyclerview/utils/measureLayout.js.map +1 -1
- package/dist/recyclerview/utils/measureLayout.web.d.ts +29 -0
- package/dist/recyclerview/utils/measureLayout.web.d.ts.map +1 -0
- package/dist/recyclerview/utils/measureLayout.web.js +87 -0
- package/dist/recyclerview/utils/measureLayout.web.js.map +1 -0
- package/dist/specs/AutoLayoutNativeComponent.d.ts +1 -2
- package/dist/specs/AutoLayoutNativeComponent.d.ts.map +1 -1
- package/dist/specs/CellContainerNativeComponent.d.ts +0 -1
- package/dist/specs/CellContainerNativeComponent.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/AverageWindow.js.map +1 -1
- package/dist/utils/ContentContainerUtils.d.ts.map +1 -1
- package/dist/utils/ContentContainerUtils.js.map +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 +11 -5
- package/dist/viewability/ViewabilityManager.js.map +1 -1
- package/jestSetup.js +30 -11
- package/package.json +4 -3
- package/src/AnimatedFlashList.ts +3 -2
- package/src/FlashList.tsx +25 -1
- package/src/FlashListProps.ts +42 -11
- package/src/FlashListRef.ts +320 -0
- package/src/MasonryFlashList.tsx +2 -2
- package/src/__tests__/ConsecutiveNumbers.test.ts +232 -0
- package/src/__tests__/GridLayoutManager.test.ts +113 -0
- package/src/__tests__/LayoutCommitObserver.test.tsx +60 -0
- package/src/__tests__/LinearLayoutManager.test.ts +227 -0
- package/src/__tests__/MasonryLayoutManager.test.ts +202 -0
- package/src/__tests__/RecyclerView.test.tsx +144 -0
- package/src/__tests__/RenderStackManager.test.ts +574 -0
- package/src/__tests__/findVisibleIndex.test.ts +369 -0
- package/src/__tests__/helpers/createLayoutManager.ts +141 -0
- package/src/__tests__/useUnmountAwareCallbacks.test.tsx +285 -0
- package/src/benchmark/useBenchmark.ts +0 -37
- package/src/benchmark/useFlatListBenchmark.ts +2 -2
- package/src/enableNewCore.ts +3 -1
- package/src/index.ts +14 -3
- package/src/native/config/PlatformHelper.android.ts +2 -0
- package/src/native/config/PlatformHelper.ios.ts +2 -0
- package/src/native/config/PlatformHelper.ts +2 -0
- package/src/native/config/PlatformHelper.web.ts +3 -1
- package/src/recyclerview/LayoutCommitObserver.tsx +74 -0
- package/src/recyclerview/RecyclerView.tsx +178 -89
- package/src/recyclerview/RecyclerViewContextProvider.ts +53 -7
- package/src/recyclerview/RecyclerViewManager.ts +176 -97
- package/src/recyclerview/RecyclerViewProps.ts +2 -1
- package/src/recyclerview/RenderStackManager.ts +317 -0
- package/src/recyclerview/ViewHolder.tsx +13 -6
- package/src/recyclerview/ViewHolderCollection.tsx +45 -16
- package/src/recyclerview/components/ScrollAnchor.tsx +24 -11
- package/src/recyclerview/components/StickyHeaders.tsx +70 -58
- package/src/recyclerview/helpers/ConsecutiveNumbers.ts +2 -2
- package/src/recyclerview/helpers/EngagedIndicesTracker.ts +135 -25
- package/src/recyclerview/helpers/RenderTimeTracker.ts +42 -0
- package/src/recyclerview/helpers/VelocityTracker.ts +77 -0
- package/src/recyclerview/hooks/useBoundDetection.ts +74 -25
- package/src/recyclerview/hooks/useLayoutState.ts +15 -6
- package/src/recyclerview/hooks/useMappingHelper.ts +20 -0
- package/src/recyclerview/hooks/useOnLoad.ts +11 -10
- package/src/recyclerview/hooks/useRecyclerViewController.tsx +380 -241
- package/src/recyclerview/hooks/useRecyclerViewManager.ts +13 -1
- package/src/recyclerview/hooks/useRecyclingState.ts +11 -7
- package/src/recyclerview/hooks/useSecondaryProps.tsx +12 -7
- package/src/recyclerview/hooks/useUnmountAwareCallbacks.ts +73 -0
- package/src/recyclerview/hooks/useUnmountFlag.ts +1 -0
- package/src/recyclerview/layout-managers/GridLayoutManager.ts +68 -27
- package/src/recyclerview/layout-managers/LayoutManager.ts +116 -42
- package/src/recyclerview/layout-managers/LinearLayoutManager.ts +12 -8
- package/src/recyclerview/layout-managers/MasonryLayoutManager.ts +34 -13
- package/src/recyclerview/utils/componentUtils.ts +1 -1
- package/src/recyclerview/utils/findVisibleIndex.ts +1 -2
- package/src/recyclerview/utils/measureLayout.ts +41 -2
- package/src/recyclerview/utils/measureLayout.web.ts +102 -0
- package/src/viewability/ViewToken.ts +2 -2
- package/src/viewability/ViewabilityHelper.ts +1 -1
- package/src/viewability/ViewabilityManager.ts +16 -9
- 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/recyclerview/RecycleKeyManager.ts +0 -185
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@quilted/react-testing";
|
|
3
|
+
|
|
4
|
+
import { useUnmountAwareTimeout } from "../recyclerview/hooks/useUnmountAwareCallbacks";
|
|
5
|
+
|
|
6
|
+
const TestComponent = ({
|
|
7
|
+
onRender,
|
|
8
|
+
}: {
|
|
9
|
+
onRender: (api: ReturnType<typeof useUnmountAwareTimeout>) => void;
|
|
10
|
+
}) => {
|
|
11
|
+
const api = useUnmountAwareTimeout();
|
|
12
|
+
onRender(api);
|
|
13
|
+
return null;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
describe("useUnmountAwareCallbacks", () => {
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
jest.useFakeTimers();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
jest.clearAllTimers();
|
|
23
|
+
jest.clearAllMocks();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("returns a setTimeout function", () => {
|
|
27
|
+
let api: ReturnType<typeof useUnmountAwareTimeout> | undefined;
|
|
28
|
+
render(
|
|
29
|
+
<TestComponent
|
|
30
|
+
onRender={(hookApi) => {
|
|
31
|
+
api = hookApi;
|
|
32
|
+
}}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
expect(api).toBeDefined();
|
|
37
|
+
expect(api?.setTimeout).toBeDefined();
|
|
38
|
+
expect(typeof api?.setTimeout).toBe("function");
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("executes the callback after the specified delay", () => {
|
|
42
|
+
const callback = jest.fn();
|
|
43
|
+
let api: ReturnType<typeof useUnmountAwareTimeout> | undefined;
|
|
44
|
+
|
|
45
|
+
render(
|
|
46
|
+
<TestComponent
|
|
47
|
+
onRender={(hookApi) => {
|
|
48
|
+
api = hookApi;
|
|
49
|
+
}}
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
api?.setTimeout(callback, 1000);
|
|
54
|
+
|
|
55
|
+
expect(callback).not.toHaveBeenCalled();
|
|
56
|
+
|
|
57
|
+
// Fast-forward time
|
|
58
|
+
jest.advanceTimersByTime(1000);
|
|
59
|
+
|
|
60
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("executes multiple callbacks after their respective delays", () => {
|
|
64
|
+
const callback1 = jest.fn();
|
|
65
|
+
const callback2 = jest.fn();
|
|
66
|
+
let api: ReturnType<typeof useUnmountAwareTimeout> | undefined;
|
|
67
|
+
|
|
68
|
+
render(
|
|
69
|
+
<TestComponent
|
|
70
|
+
onRender={(hookApi) => {
|
|
71
|
+
api = hookApi;
|
|
72
|
+
}}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
api?.setTimeout(callback1, 1000);
|
|
77
|
+
api?.setTimeout(callback2, 2000);
|
|
78
|
+
|
|
79
|
+
expect(callback1).not.toHaveBeenCalled();
|
|
80
|
+
expect(callback2).not.toHaveBeenCalled();
|
|
81
|
+
|
|
82
|
+
// Fast-forward time by 1000ms
|
|
83
|
+
jest.advanceTimersByTime(1000);
|
|
84
|
+
|
|
85
|
+
expect(callback1).toHaveBeenCalledTimes(1);
|
|
86
|
+
expect(callback2).not.toHaveBeenCalled();
|
|
87
|
+
|
|
88
|
+
// Fast-forward time by another 1000ms
|
|
89
|
+
jest.advanceTimersByTime(1000);
|
|
90
|
+
|
|
91
|
+
expect(callback1).toHaveBeenCalledTimes(1);
|
|
92
|
+
expect(callback2).toHaveBeenCalledTimes(1);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("clears all timeouts when the component unmounts", () => {
|
|
96
|
+
const callback = jest.fn();
|
|
97
|
+
let api: ReturnType<typeof useUnmountAwareTimeout> | undefined;
|
|
98
|
+
|
|
99
|
+
const component = render(
|
|
100
|
+
<TestComponent
|
|
101
|
+
onRender={(hookApi) => {
|
|
102
|
+
api = hookApi;
|
|
103
|
+
}}
|
|
104
|
+
/>
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
api?.setTimeout(callback, 1000);
|
|
108
|
+
api?.setTimeout(callback, 2000);
|
|
109
|
+
|
|
110
|
+
// Spy on clearTimeout to verify it's called during unmount
|
|
111
|
+
const clearTimeoutSpy = jest.spyOn(global, "clearTimeout");
|
|
112
|
+
|
|
113
|
+
// Unmount the component
|
|
114
|
+
component.unmount();
|
|
115
|
+
|
|
116
|
+
// Fast-forward time
|
|
117
|
+
jest.advanceTimersByTime(2000);
|
|
118
|
+
|
|
119
|
+
// Expect callbacks not to be called because timeouts were cleared
|
|
120
|
+
expect(callback).not.toHaveBeenCalled();
|
|
121
|
+
expect(clearTimeoutSpy).toHaveBeenCalled();
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("removes timeout from tracking set once it executes", () => {
|
|
125
|
+
const callback = jest.fn();
|
|
126
|
+
let api: ReturnType<typeof useUnmountAwareTimeout> | undefined;
|
|
127
|
+
|
|
128
|
+
const component = render(
|
|
129
|
+
<TestComponent
|
|
130
|
+
onRender={(hookApi) => {
|
|
131
|
+
api = hookApi;
|
|
132
|
+
}}
|
|
133
|
+
/>
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
api?.setTimeout(callback, 1000);
|
|
137
|
+
|
|
138
|
+
// Fast-forward time
|
|
139
|
+
jest.advanceTimersByTime(1000);
|
|
140
|
+
|
|
141
|
+
// Verify callback was called
|
|
142
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
143
|
+
|
|
144
|
+
// We can't directly check the timeoutIds Set, so we'll verify indirectly
|
|
145
|
+
// by making sure no clearTimeout calls happen on unmount (since the timeout was already cleared)
|
|
146
|
+
const clearTimeoutSpy = jest.spyOn(global, "clearTimeout");
|
|
147
|
+
clearTimeoutSpy.mockClear(); // Reset the mock calls before unmount
|
|
148
|
+
|
|
149
|
+
// Unmount the component
|
|
150
|
+
component.unmount();
|
|
151
|
+
|
|
152
|
+
// If the timeout was properly removed from the set, clearTimeout won't be called on unmount
|
|
153
|
+
expect(clearTimeoutSpy).not.toHaveBeenCalled();
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("handles multiple timeouts correctly", () => {
|
|
157
|
+
const callback1 = jest.fn();
|
|
158
|
+
const callback2 = jest.fn();
|
|
159
|
+
const callback3 = jest.fn();
|
|
160
|
+
let api: ReturnType<typeof useUnmountAwareTimeout> | undefined;
|
|
161
|
+
|
|
162
|
+
const component = render(
|
|
163
|
+
<TestComponent
|
|
164
|
+
onRender={(hookApi) => {
|
|
165
|
+
api = hookApi;
|
|
166
|
+
}}
|
|
167
|
+
/>
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
// Set up three timeouts with different delays
|
|
171
|
+
api?.setTimeout(callback1, 1000);
|
|
172
|
+
api?.setTimeout(callback2, 2000);
|
|
173
|
+
api?.setTimeout(callback3, 3000);
|
|
174
|
+
|
|
175
|
+
// Fast-forward time by 1500ms (should trigger only the first callback)
|
|
176
|
+
jest.advanceTimersByTime(1500);
|
|
177
|
+
|
|
178
|
+
expect(callback1).toHaveBeenCalledTimes(1);
|
|
179
|
+
expect(callback2).not.toHaveBeenCalled();
|
|
180
|
+
expect(callback3).not.toHaveBeenCalled();
|
|
181
|
+
|
|
182
|
+
// Unmount the component (should clear remaining timeouts)
|
|
183
|
+
component.unmount();
|
|
184
|
+
|
|
185
|
+
// Fast-forward time to when all callbacks would have been called
|
|
186
|
+
jest.advanceTimersByTime(2000);
|
|
187
|
+
|
|
188
|
+
// Only the first callback should have been called
|
|
189
|
+
expect(callback1).toHaveBeenCalledTimes(1);
|
|
190
|
+
expect(callback2).not.toHaveBeenCalled();
|
|
191
|
+
expect(callback3).not.toHaveBeenCalled();
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it("handles callbacks that trigger new timeouts", () => {
|
|
195
|
+
const finalCallback = jest.fn();
|
|
196
|
+
let api: ReturnType<typeof useUnmountAwareTimeout> | undefined;
|
|
197
|
+
|
|
198
|
+
render(
|
|
199
|
+
<TestComponent
|
|
200
|
+
onRender={(hookApi) => {
|
|
201
|
+
api = hookApi;
|
|
202
|
+
}}
|
|
203
|
+
/>
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
const firstCallback = () => {
|
|
207
|
+
api?.setTimeout(finalCallback, 1000);
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
api?.setTimeout(firstCallback, 1000);
|
|
211
|
+
|
|
212
|
+
// Fast-forward time to trigger first callback
|
|
213
|
+
jest.advanceTimersByTime(1000);
|
|
214
|
+
|
|
215
|
+
expect(finalCallback).not.toHaveBeenCalled();
|
|
216
|
+
|
|
217
|
+
// Fast-forward time to trigger second callback
|
|
218
|
+
jest.advanceTimersByTime(1000);
|
|
219
|
+
|
|
220
|
+
expect(finalCallback).toHaveBeenCalledTimes(1);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it("handles zero delay timeouts", () => {
|
|
224
|
+
const callback = jest.fn();
|
|
225
|
+
let api: ReturnType<typeof useUnmountAwareTimeout> | undefined;
|
|
226
|
+
|
|
227
|
+
render(
|
|
228
|
+
<TestComponent
|
|
229
|
+
onRender={(hookApi) => {
|
|
230
|
+
api = hookApi;
|
|
231
|
+
}}
|
|
232
|
+
/>
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
api?.setTimeout(callback, 0);
|
|
236
|
+
|
|
237
|
+
expect(callback).not.toHaveBeenCalled();
|
|
238
|
+
|
|
239
|
+
// Even with zero delay, we need to advance the timer to execute
|
|
240
|
+
jest.advanceTimersByTime(0);
|
|
241
|
+
|
|
242
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it("handles errors in callbacks without affecting other timeouts", () => {
|
|
246
|
+
const errorCallback = jest.fn(() => {
|
|
247
|
+
throw new Error("Test error");
|
|
248
|
+
});
|
|
249
|
+
const successCallback = jest.fn();
|
|
250
|
+
let api: ReturnType<typeof useUnmountAwareTimeout> | undefined;
|
|
251
|
+
|
|
252
|
+
// Suppress error log during test
|
|
253
|
+
const originalConsoleError = console.error;
|
|
254
|
+
console.error = jest.fn();
|
|
255
|
+
|
|
256
|
+
render(
|
|
257
|
+
<TestComponent
|
|
258
|
+
onRender={(hookApi) => {
|
|
259
|
+
api = hookApi;
|
|
260
|
+
}}
|
|
261
|
+
/>
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
api?.setTimeout(errorCallback, 1000);
|
|
265
|
+
api?.setTimeout(successCallback, 2000);
|
|
266
|
+
|
|
267
|
+
// Fast-forward time to trigger error callback
|
|
268
|
+
try {
|
|
269
|
+
jest.advanceTimersByTime(1000);
|
|
270
|
+
} catch (error) {
|
|
271
|
+
// Expected error
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
expect(errorCallback).toHaveBeenCalledTimes(1);
|
|
275
|
+
expect(successCallback).not.toHaveBeenCalled();
|
|
276
|
+
|
|
277
|
+
// Fast-forward time to trigger success callback
|
|
278
|
+
jest.advanceTimersByTime(1000);
|
|
279
|
+
|
|
280
|
+
expect(successCallback).toHaveBeenCalledTimes(1);
|
|
281
|
+
|
|
282
|
+
// Restore console.error
|
|
283
|
+
console.error = originalConsoleError;
|
|
284
|
+
});
|
|
285
|
+
});
|
|
@@ -199,42 +199,5 @@ function computeSuggestions(
|
|
|
199
199
|
`Data count is low. Try to increase it to a large number (e.g 200) using the 'useDataMultiplier' hook.`
|
|
200
200
|
);
|
|
201
201
|
}
|
|
202
|
-
const distanceFromWindow = roundToDecimalPlaces(
|
|
203
|
-
flashListRef.current.firstItemOffset,
|
|
204
|
-
0
|
|
205
|
-
);
|
|
206
|
-
if (
|
|
207
|
-
(flashListRef.current.props.estimatedFirstItemOffset || 0) !==
|
|
208
|
-
distanceFromWindow
|
|
209
|
-
) {
|
|
210
|
-
suggestions.push(
|
|
211
|
-
`estimatedFirstItemOffset can be set to ${distanceFromWindow}`
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
const rlv = flashListRef.current.recyclerlistview_unsafe;
|
|
215
|
-
const horizontal = flashListRef.current.props.horizontal;
|
|
216
|
-
if (rlv) {
|
|
217
|
-
const sizeArray = rlv.props.dataProvider
|
|
218
|
-
.getAllData()
|
|
219
|
-
.map((_, index) =>
|
|
220
|
-
horizontal
|
|
221
|
-
? rlv.getLayout?.(index)?.width || 0
|
|
222
|
-
: rlv.getLayout?.(index)?.height || 0
|
|
223
|
-
);
|
|
224
|
-
const averageSize = Math.round(
|
|
225
|
-
sizeArray.reduce((prev, current) => prev + current, 0) /
|
|
226
|
-
sizeArray.length
|
|
227
|
-
);
|
|
228
|
-
if (
|
|
229
|
-
Math.abs(
|
|
230
|
-
averageSize -
|
|
231
|
-
(flashListRef.current.props.estimatedItemSize ??
|
|
232
|
-
flashListRef.current.state.layoutProvider
|
|
233
|
-
.defaultEstimatedItemSize)
|
|
234
|
-
) > 5
|
|
235
|
-
) {
|
|
236
|
-
suggestions.push(`estimatedItemSize can be set to ${averageSize}`);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
202
|
}
|
|
240
203
|
}
|
|
@@ -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/enableNewCore.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Platform } from "react-native";
|
|
2
|
+
|
|
1
3
|
let useNewCore: boolean | undefined;
|
|
2
4
|
export function enableNewCore(enable: boolean) {
|
|
3
5
|
useNewCore = enable;
|
|
@@ -15,7 +17,7 @@ function isReactNativeNewArchitecture(): boolean {
|
|
|
15
17
|
// Check for TurboModule system
|
|
16
18
|
const hasTurboModule = Boolean((global as any)?.__turboModuleProxy);
|
|
17
19
|
|
|
18
|
-
return hasFabricUIManager || hasTurboModule;
|
|
20
|
+
return hasFabricUIManager || hasTurboModule || Platform.OS === "web";
|
|
19
21
|
} catch {
|
|
20
22
|
return false;
|
|
21
23
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-named-default
|
|
1
2
|
import { default as OriginalFlashList } from "./FlashList";
|
|
2
3
|
import { isNewCoreEnabled } from "./enableNewCore";
|
|
3
4
|
import { RecyclerView } from "./recyclerview/RecyclerView";
|
|
4
5
|
|
|
5
6
|
// Keep this unmodified for TS type checking
|
|
6
7
|
export { default as FlashList } from "./FlashList";
|
|
8
|
+
export { FlashListRef } from "./FlashListRef";
|
|
7
9
|
export {
|
|
8
10
|
FlashListProps,
|
|
9
11
|
ContentStyle,
|
|
@@ -44,19 +46,28 @@ export {
|
|
|
44
46
|
} from "./MasonryFlashList";
|
|
45
47
|
export { useLayoutState } from "./recyclerview/hooks/useLayoutState";
|
|
46
48
|
export { useRecyclingState } from "./recyclerview/hooks/useRecyclingState";
|
|
49
|
+
export { useMappingHelper } from "./recyclerview/hooks/useMappingHelper";
|
|
47
50
|
export { JSFPSMonitor, JSFPSResult } from "./benchmark/JSFPSMonitor";
|
|
48
51
|
export { autoScroll, Cancellable } from "./benchmark/AutoScrollHelper";
|
|
49
52
|
export { default as ViewToken } from "./viewability/ViewToken";
|
|
50
53
|
export { default as CellContainer } from "./native/cell-container/CellContainer";
|
|
51
54
|
export { RecyclerView } from "./recyclerview/RecyclerView";
|
|
52
55
|
export { RecyclerViewProps } from "./recyclerview/RecyclerViewProps";
|
|
53
|
-
export {
|
|
56
|
+
export { useFlashListContext } from "./recyclerview/RecyclerViewContextProvider";
|
|
57
|
+
export {
|
|
58
|
+
LayoutCommitObserver,
|
|
59
|
+
LayoutCommitObserverProps,
|
|
60
|
+
} from "./recyclerview/LayoutCommitObserver";
|
|
54
61
|
|
|
55
62
|
// @ts-ignore - This is ignored by TypeScript but will be present in the compiled JS
|
|
56
63
|
// In the compiled JS, this will override the previous FlashList export with a conditional one
|
|
57
|
-
if (
|
|
64
|
+
if (
|
|
65
|
+
typeof module !== "undefined" &&
|
|
66
|
+
module.exports &&
|
|
67
|
+
process?.env?.NODE_ENV !== "test"
|
|
68
|
+
) {
|
|
58
69
|
Object.defineProperty(module.exports, "FlashList", {
|
|
59
|
-
get
|
|
70
|
+
get() {
|
|
60
71
|
return isNewCoreEnabled() ? RecyclerView : OriginalFlashList;
|
|
61
72
|
},
|
|
62
73
|
configurable: true,
|
|
@@ -2,6 +2,8 @@ import { BaseItemAnimator } from "recyclerlistview";
|
|
|
2
2
|
|
|
3
3
|
const PlatformConfig = {
|
|
4
4
|
defaultDrawDistance: 250,
|
|
5
|
+
supportsOffsetCorrection: true,
|
|
6
|
+
trackAverageRenderTimeForOffsetProjection: true,
|
|
5
7
|
// Using rotate instead of scaleY on Android to avoid performance issues. Issue: https://github.com/Shopify/flash-list/issues/751
|
|
6
8
|
invertedTransformStyle: { transform: [{ rotate: "180deg" }] },
|
|
7
9
|
invertedTransformStyleHorizontal: { transform: [{ rotate: "180deg" }] },
|
|
@@ -2,6 +2,8 @@ import { BaseItemAnimator } from "recyclerlistview";
|
|
|
2
2
|
|
|
3
3
|
const PlatformConfig = {
|
|
4
4
|
defaultDrawDistance: 250,
|
|
5
|
+
supportsOffsetCorrection: true,
|
|
6
|
+
trackAverageRenderTimeForOffsetProjection: false,
|
|
5
7
|
invertedTransformStyle: { transform: [{ scaleY: -1 }] },
|
|
6
8
|
invertedTransformStyleHorizontal: { transform: [{ scaleX: -1 }] },
|
|
7
9
|
};
|
|
@@ -3,6 +3,8 @@ import { DefaultJSItemAnimator } from "recyclerlistview/dist/reactnative/platfor
|
|
|
3
3
|
|
|
4
4
|
const PlatformConfig = {
|
|
5
5
|
defaultDrawDistance: 250,
|
|
6
|
+
supportsOffsetCorrection: false,
|
|
7
|
+
trackAverageRenderTimeForOffsetProjection: false,
|
|
6
8
|
invertedTransformStyle: { transform: [{ scaleY: -1 }] },
|
|
7
9
|
invertedTransformStyleHorizontal: { transform: [{ scaleX: -1 }] },
|
|
8
10
|
};
|
|
@@ -4,7 +4,9 @@ import { BaseItemAnimator } from "recyclerlistview";
|
|
|
4
4
|
import { DefaultJSItemAnimator } from "recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator";
|
|
5
5
|
|
|
6
6
|
const PlatformConfig = {
|
|
7
|
-
defaultDrawDistance:
|
|
7
|
+
defaultDrawDistance: 500,
|
|
8
|
+
supportsOffsetCorrection: false,
|
|
9
|
+
trackAverageRenderTimeForOffsetProjection: false,
|
|
8
10
|
invertedTransformStyle: { transform: [{ scaleY: -1 }] },
|
|
9
11
|
invertedTransformStyleHorizontal: { transform: [{ scaleX: -1 }] },
|
|
10
12
|
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React, { useLayoutEffect, useMemo, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
RecyclerViewContext,
|
|
5
|
+
RecyclerViewContextProvider,
|
|
6
|
+
useRecyclerViewContext,
|
|
7
|
+
} from "./RecyclerViewContextProvider";
|
|
8
|
+
import { useLayoutState } from "./hooks/useLayoutState";
|
|
9
|
+
|
|
10
|
+
export interface LayoutCommitObserverProps {
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
onCommitLayoutEffect?: () => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* LayoutCommitObserver can be used to observe when FlashList commits a layout.
|
|
17
|
+
* It is useful when your component has one or more FlashLists somewhere down the tree.
|
|
18
|
+
* LayoutCommitObserver will trigger `onCommitLayoutEffect` when all of the FlashLists in the tree have finished their first commit.
|
|
19
|
+
*/
|
|
20
|
+
export const LayoutCommitObserver = React.memo(
|
|
21
|
+
(props: LayoutCommitObserverProps) => {
|
|
22
|
+
const { children, onCommitLayoutEffect } = props;
|
|
23
|
+
const parentRecyclerViewContext = useRecyclerViewContext();
|
|
24
|
+
const [_, setRenderId] = useLayoutState(0);
|
|
25
|
+
const pendingChildIds = useRef<Set<string>>(new Set()).current;
|
|
26
|
+
|
|
27
|
+
useLayoutEffect(() => {
|
|
28
|
+
if (pendingChildIds.size > 0) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
onCommitLayoutEffect?.();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Create context for child components
|
|
35
|
+
const recyclerViewContext: RecyclerViewContext<unknown> = useMemo(() => {
|
|
36
|
+
return {
|
|
37
|
+
layout: () => {
|
|
38
|
+
setRenderId((prev) => prev + 1);
|
|
39
|
+
},
|
|
40
|
+
getRef: () => {
|
|
41
|
+
return parentRecyclerViewContext?.getRef() ?? null;
|
|
42
|
+
},
|
|
43
|
+
getParentRef: () => {
|
|
44
|
+
return parentRecyclerViewContext?.getParentRef() ?? null;
|
|
45
|
+
},
|
|
46
|
+
getParentScrollViewRef: () => {
|
|
47
|
+
return parentRecyclerViewContext?.getParentScrollViewRef() ?? null;
|
|
48
|
+
},
|
|
49
|
+
getScrollViewRef: () => {
|
|
50
|
+
return parentRecyclerViewContext?.getScrollViewRef() ?? null;
|
|
51
|
+
},
|
|
52
|
+
markChildLayoutAsPending: (id: string) => {
|
|
53
|
+
parentRecyclerViewContext?.markChildLayoutAsPending(id);
|
|
54
|
+
pendingChildIds.add(id);
|
|
55
|
+
},
|
|
56
|
+
unmarkChildLayoutAsPending: (id: string) => {
|
|
57
|
+
parentRecyclerViewContext?.unmarkChildLayoutAsPending(id);
|
|
58
|
+
if (pendingChildIds.has(id)) {
|
|
59
|
+
pendingChildIds.delete(id);
|
|
60
|
+
recyclerViewContext.layout();
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}, [parentRecyclerViewContext, pendingChildIds, setRenderId]);
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<RecyclerViewContextProvider value={recyclerViewContext}>
|
|
68
|
+
{children}
|
|
69
|
+
</RecyclerViewContextProvider>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
LayoutCommitObserver.displayName = "LayoutCommitObserver";
|