@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
|
@@ -20,32 +20,43 @@ export abstract class RVLayoutManager {
|
|
|
20
20
|
protected layouts: RVLayout[];
|
|
21
21
|
/** Dimensions of the visible window/viewport */
|
|
22
22
|
protected windowSize: RVDimension;
|
|
23
|
-
/** Information about item spans and sizes */
|
|
24
|
-
protected spanSizeInfo: SpanSizeInfo = {};
|
|
25
23
|
/** Maximum number of columns in the layout */
|
|
26
24
|
protected maxColumns: number;
|
|
27
|
-
/** Optional callback to override default item layout */
|
|
28
|
-
protected overrideItemLayout?: (index: number, layout: SpanSizeInfo) => void;
|
|
29
25
|
|
|
30
26
|
/** Whether to optimize item placement for better space utilization */
|
|
31
27
|
protected optimizeItemArrangement: boolean;
|
|
32
28
|
|
|
33
29
|
/** Flag indicating if the layout requires repainting */
|
|
34
|
-
public requiresRepaint
|
|
30
|
+
public requiresRepaint = false;
|
|
35
31
|
|
|
32
|
+
/** Optional callback to override default item layout */
|
|
33
|
+
private overrideItemLayout: (index: number, layout: SpanSizeInfo) => void;
|
|
36
34
|
/** Optional function to determine item type */
|
|
37
|
-
private
|
|
35
|
+
private getItemType: (index: number) => string;
|
|
38
36
|
/** Window for tracking average heights by item type */
|
|
39
37
|
private heightAverageWindow: MultiTypeAverageWindow;
|
|
40
38
|
/** Window for tracking average widths by item type */
|
|
41
39
|
private widthAverageWindow: MultiTypeAverageWindow;
|
|
42
40
|
/** Maximum number of items to process in a single layout pass */
|
|
43
|
-
private maxItemsToProcess
|
|
41
|
+
private maxItemsToProcess = 250;
|
|
42
|
+
/** Information about item spans and sizes */
|
|
43
|
+
private spanSizeInfo: SpanSizeInfo = {};
|
|
44
|
+
/** Span tracker for each item */
|
|
45
|
+
private spanTracker: (number | undefined)[] = [];
|
|
46
|
+
|
|
47
|
+
/** Current max index with changed layout */
|
|
48
|
+
private currentMaxIndexWithChangedLayout = -1;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Last index that was skipped during layout computation.
|
|
52
|
+
* Used to determine if a layout needs to be recomputed.
|
|
53
|
+
*/
|
|
54
|
+
private lastSkippedLayoutIndex = Number.MAX_VALUE;
|
|
44
55
|
|
|
45
56
|
constructor(params: LayoutParams, previousLayoutManager?: RVLayoutManager) {
|
|
46
57
|
this.heightAverageWindow = new MultiTypeAverageWindow(5, 200);
|
|
47
58
|
this.widthAverageWindow = new MultiTypeAverageWindow(5, 200);
|
|
48
|
-
this.
|
|
59
|
+
this.getItemType = params.getItemType;
|
|
49
60
|
this.overrideItemLayout = params.overrideItemLayout;
|
|
50
61
|
this.layouts = previousLayoutManager?.layouts ?? [];
|
|
51
62
|
if (previousLayoutManager) {
|
|
@@ -57,15 +68,6 @@ export abstract class RVLayoutManager {
|
|
|
57
68
|
}
|
|
58
69
|
}
|
|
59
70
|
|
|
60
|
-
/**
|
|
61
|
-
* Gets the type of an item at the given index.
|
|
62
|
-
* @param index Index of the item
|
|
63
|
-
* @returns Item type or "default" if not specified
|
|
64
|
-
*/
|
|
65
|
-
private getItemType(index: number): string | number {
|
|
66
|
-
return this._getItemType?.(index) ?? "default";
|
|
67
|
-
}
|
|
68
|
-
|
|
69
71
|
/**
|
|
70
72
|
* Gets the estimated width for an item based on its type.
|
|
71
73
|
* @param index Index of the item
|
|
@@ -114,8 +116,8 @@ export abstract class RVLayoutManager {
|
|
|
114
116
|
/**
|
|
115
117
|
* Gets indices of items currently visible in the viewport.
|
|
116
118
|
* Uses binary search for efficient lookup.
|
|
117
|
-
* @param unboundDimensionStart Start position of viewport
|
|
118
|
-
* @param unboundDimensionEnd End position of viewport
|
|
119
|
+
* @param unboundDimensionStart Start position of viewport (start X or start Y)
|
|
120
|
+
* @param unboundDimensionEnd End position of viewport (end X or end Y)
|
|
119
121
|
* @returns ConsecutiveNumbers containing visible indices
|
|
120
122
|
*/
|
|
121
123
|
getVisibleLayouts(
|
|
@@ -157,7 +159,7 @@ export abstract class RVLayoutManager {
|
|
|
157
159
|
}
|
|
158
160
|
const startIndex = Math.min(...indices);
|
|
159
161
|
// Recompute layouts starting from the smallest index in the original indices array
|
|
160
|
-
this.
|
|
162
|
+
this._recomputeLayouts(
|
|
161
163
|
this.getMinRecomputeIndex(startIndex),
|
|
162
164
|
this.getMaxRecomputeIndex(startIndex)
|
|
163
165
|
);
|
|
@@ -169,41 +171,49 @@ export abstract class RVLayoutManager {
|
|
|
169
171
|
* @param totalItemCount Total number of items in the list
|
|
170
172
|
*/
|
|
171
173
|
modifyLayout(layoutInfo: RVLayoutInfo[], totalItemCount: number): void {
|
|
174
|
+
this.maxItemsToProcess = Math.max(
|
|
175
|
+
this.maxItemsToProcess,
|
|
176
|
+
layoutInfo.length * 10
|
|
177
|
+
);
|
|
172
178
|
let minRecomputeIndex = Number.MAX_VALUE;
|
|
173
179
|
|
|
174
180
|
if (this.layouts.length > totalItemCount) {
|
|
175
181
|
this.layouts.length = totalItemCount;
|
|
182
|
+
this.spanTracker.length = totalItemCount;
|
|
176
183
|
minRecomputeIndex = totalItemCount - 1; // <0 gets skipped so it's safe to set to totalItemCount - 1
|
|
177
184
|
}
|
|
178
185
|
// update average windows
|
|
179
186
|
minRecomputeIndex = Math.min(
|
|
180
187
|
minRecomputeIndex,
|
|
181
|
-
this.
|
|
188
|
+
this.computeEstimatesAndMinMaxChangedLayout(layoutInfo)
|
|
182
189
|
);
|
|
183
190
|
|
|
184
191
|
if (this.layouts.length < totalItemCount && totalItemCount > 0) {
|
|
185
192
|
const startIndex = this.layouts.length;
|
|
186
193
|
this.layouts.length = totalItemCount;
|
|
194
|
+
this.spanTracker.length = totalItemCount;
|
|
187
195
|
for (let i = startIndex; i < totalItemCount; i++) {
|
|
188
196
|
this.getLayout(i);
|
|
197
|
+
this.getSpan(i);
|
|
189
198
|
}
|
|
190
199
|
this.recomputeLayouts(startIndex, totalItemCount - 1);
|
|
191
200
|
}
|
|
192
|
-
|
|
193
|
-
minRecomputeIndex,
|
|
194
|
-
this.processLayoutInfo(layoutInfo, totalItemCount) ?? minRecomputeIndex
|
|
195
|
-
);
|
|
201
|
+
|
|
196
202
|
// compute minRecomputeIndex
|
|
203
|
+
|
|
197
204
|
minRecomputeIndex = Math.min(
|
|
198
205
|
minRecomputeIndex,
|
|
199
|
-
this.
|
|
206
|
+
this.lastSkippedLayoutIndex,
|
|
207
|
+
this.computeMinIndexWithChangedSpan(layoutInfo),
|
|
208
|
+
this.processLayoutInfo(layoutInfo, totalItemCount) ?? minRecomputeIndex,
|
|
209
|
+
this.computeEstimatesAndMinMaxChangedLayout(layoutInfo)
|
|
200
210
|
);
|
|
211
|
+
|
|
201
212
|
if (minRecomputeIndex >= 0 && minRecomputeIndex < totalItemCount) {
|
|
202
|
-
this.
|
|
203
|
-
|
|
204
|
-
this.getMaxRecomputeIndex(minRecomputeIndex)
|
|
205
|
-
);
|
|
213
|
+
const maxRecomputeIndex = this.getMaxRecomputeIndex(minRecomputeIndex);
|
|
214
|
+
this._recomputeLayouts(minRecomputeIndex, maxRecomputeIndex);
|
|
206
215
|
}
|
|
216
|
+
this.currentMaxIndexWithChangedLayout = -1;
|
|
207
217
|
}
|
|
208
218
|
|
|
209
219
|
/**
|
|
@@ -245,6 +255,10 @@ export abstract class RVLayoutManager {
|
|
|
245
255
|
params.optimizeItemArrangement ?? this.optimizeItemArrangement;
|
|
246
256
|
}
|
|
247
257
|
|
|
258
|
+
getLayoutCount(): number {
|
|
259
|
+
return this.layouts.length;
|
|
260
|
+
}
|
|
261
|
+
|
|
248
262
|
/**
|
|
249
263
|
* Abstract method to recompute layouts for items in the given range.
|
|
250
264
|
* @param startIndex Starting index of items to recompute
|
|
@@ -265,16 +279,30 @@ export abstract class RVLayoutManager {
|
|
|
265
279
|
protected abstract estimateLayout(index: number): void;
|
|
266
280
|
|
|
267
281
|
/**
|
|
268
|
-
* Gets span
|
|
282
|
+
* Gets span for an item, applying any overrides.
|
|
283
|
+
* This is intended to be called during a relayout call. The value is tracked and used to determine if a span change has occurred.
|
|
284
|
+
* If skipTracking is true, the operation is not tracked. Can be useful if span is required outside of a relayout call.
|
|
285
|
+
* The tracker is used to call handleSpanChange if a span change has occurred before relayout call.
|
|
286
|
+
* // TODO: improve this contract.
|
|
269
287
|
* @param index Index of the item
|
|
270
|
-
* @returns
|
|
288
|
+
* @returns Span for the item
|
|
271
289
|
*/
|
|
272
|
-
protected
|
|
290
|
+
protected getSpan(index: number, skipTracking = false): number {
|
|
273
291
|
this.spanSizeInfo.span = undefined;
|
|
274
|
-
this.overrideItemLayout
|
|
275
|
-
|
|
292
|
+
this.overrideItemLayout(index, this.spanSizeInfo);
|
|
293
|
+
const span = Math.min(this.spanSizeInfo.span ?? 1, this.maxColumns);
|
|
294
|
+
if (!skipTracking) {
|
|
295
|
+
this.spanTracker[index] = span;
|
|
296
|
+
}
|
|
297
|
+
return span;
|
|
276
298
|
}
|
|
277
299
|
|
|
300
|
+
/**
|
|
301
|
+
* Method to handle span change for an item. Can be overridden by subclasses.
|
|
302
|
+
* @param index Index of the item
|
|
303
|
+
*/
|
|
304
|
+
protected handleSpanChange(index: number) {}
|
|
305
|
+
|
|
278
306
|
/**
|
|
279
307
|
* Gets the maximum index to process in a single layout pass.
|
|
280
308
|
* @param startIndex Starting index
|
|
@@ -282,7 +310,8 @@ export abstract class RVLayoutManager {
|
|
|
282
310
|
*/
|
|
283
311
|
private getMaxRecomputeIndex(startIndex: number): number {
|
|
284
312
|
return Math.min(
|
|
285
|
-
startIndex
|
|
313
|
+
Math.max(startIndex, this.currentMaxIndexWithChangedLayout) +
|
|
314
|
+
this.maxItemsToProcess,
|
|
286
315
|
this.layouts.length - 1
|
|
287
316
|
);
|
|
288
317
|
}
|
|
@@ -296,12 +325,36 @@ export abstract class RVLayoutManager {
|
|
|
296
325
|
return startIndex;
|
|
297
326
|
}
|
|
298
327
|
|
|
328
|
+
private _recomputeLayouts(startIndex: number, endIndex: number): void {
|
|
329
|
+
this.recomputeLayouts(startIndex, endIndex);
|
|
330
|
+
if (
|
|
331
|
+
this.lastSkippedLayoutIndex >= startIndex &&
|
|
332
|
+
this.lastSkippedLayoutIndex <= endIndex
|
|
333
|
+
) {
|
|
334
|
+
this.lastSkippedLayoutIndex = Number.MAX_VALUE;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (endIndex + 1 < this.layouts.length) {
|
|
338
|
+
this.lastSkippedLayoutIndex = Math.min(
|
|
339
|
+
endIndex + 1,
|
|
340
|
+
this.lastSkippedLayoutIndex
|
|
341
|
+
);
|
|
342
|
+
const lastIndex = this.layouts.length - 1;
|
|
343
|
+
// Since layout managers derive height from last indices we need to make
|
|
344
|
+
// sure they're not too much out of sync.
|
|
345
|
+
if (this.layouts[lastIndex].y < this.layouts[endIndex].y) {
|
|
346
|
+
this.recomputeLayouts(this.lastSkippedLayoutIndex, lastIndex);
|
|
347
|
+
this.lastSkippedLayoutIndex = Number.MAX_VALUE;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
299
352
|
/**
|
|
300
353
|
* Computes size estimates and finds the minimum recompute index.
|
|
301
354
|
* @param layoutInfo Array of layout information for items
|
|
302
355
|
* @returns Minimum index that needs recomputation
|
|
303
356
|
*/
|
|
304
|
-
private
|
|
357
|
+
private computeEstimatesAndMinMaxChangedLayout(
|
|
305
358
|
layoutInfo: RVLayoutInfo[]
|
|
306
359
|
): number {
|
|
307
360
|
let minRecomputeIndex = Number.MAX_VALUE;
|
|
@@ -309,12 +362,18 @@ export abstract class RVLayoutManager {
|
|
|
309
362
|
const { index, dimensions } = info;
|
|
310
363
|
const storedLayout = this.layouts[index];
|
|
311
364
|
if (
|
|
365
|
+
index >= this.lastSkippedLayoutIndex ||
|
|
366
|
+
!storedLayout ||
|
|
312
367
|
!storedLayout.isHeightMeasured ||
|
|
313
368
|
!storedLayout.isWidthMeasured ||
|
|
314
369
|
areDimensionsNotEqual(storedLayout.height, dimensions.height) ||
|
|
315
370
|
areDimensionsNotEqual(storedLayout.width, dimensions.width)
|
|
316
371
|
) {
|
|
317
372
|
minRecomputeIndex = Math.min(minRecomputeIndex, index);
|
|
373
|
+
this.currentMaxIndexWithChangedLayout = Math.max(
|
|
374
|
+
this.currentMaxIndexWithChangedLayout,
|
|
375
|
+
index
|
|
376
|
+
);
|
|
318
377
|
}
|
|
319
378
|
this.heightAverageWindow.addValue(
|
|
320
379
|
dimensions.height,
|
|
@@ -327,6 +386,21 @@ export abstract class RVLayoutManager {
|
|
|
327
386
|
}
|
|
328
387
|
return minRecomputeIndex;
|
|
329
388
|
}
|
|
389
|
+
|
|
390
|
+
private computeMinIndexWithChangedSpan(layoutInfo: RVLayoutInfo[]): number {
|
|
391
|
+
let minIndexWithChangedSpan = Number.MAX_VALUE;
|
|
392
|
+
for (const info of layoutInfo) {
|
|
393
|
+
const { index } = info;
|
|
394
|
+
const span = this.getSpan(index, true);
|
|
395
|
+
const storedSpan = this.spanTracker[index];
|
|
396
|
+
if (span !== storedSpan) {
|
|
397
|
+
this.spanTracker[index] = span;
|
|
398
|
+
this.handleSpanChange(index);
|
|
399
|
+
minIndexWithChangedSpan = Math.min(minIndexWithChangedSpan, index);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return minIndexWithChangedSpan;
|
|
403
|
+
}
|
|
330
404
|
}
|
|
331
405
|
|
|
332
406
|
/**
|
|
@@ -343,31 +417,31 @@ export interface LayoutParams {
|
|
|
343
417
|
* Determines if the list scrolls horizontally (true) or vertically (false)
|
|
344
418
|
* Affects how items are positioned and which dimension is used for scrolling
|
|
345
419
|
*/
|
|
346
|
-
horizontal
|
|
420
|
+
horizontal: boolean;
|
|
347
421
|
|
|
348
422
|
/**
|
|
349
423
|
* Maximum number of columns in a grid layout
|
|
350
424
|
* Controls how many items can be placed side by side
|
|
351
425
|
*/
|
|
352
|
-
maxColumns
|
|
426
|
+
maxColumns: number;
|
|
353
427
|
|
|
354
428
|
/**
|
|
355
429
|
* When true, attempts to optimize item placement for better space utilization
|
|
356
430
|
* May affect the ordering of items to minimize empty space
|
|
357
431
|
*/
|
|
358
|
-
optimizeItemArrangement
|
|
432
|
+
optimizeItemArrangement: boolean;
|
|
359
433
|
|
|
360
434
|
/**
|
|
361
435
|
* Callback to manually override layout properties for specific items
|
|
362
436
|
* Allows custom control over span and size for individual items
|
|
363
437
|
*/
|
|
364
|
-
overrideItemLayout
|
|
438
|
+
overrideItemLayout: (index: number, layout: SpanSizeInfo) => void;
|
|
365
439
|
|
|
366
440
|
/**
|
|
367
441
|
* Function to determine the type of an item at a specific index
|
|
368
442
|
* Used for size estimation and optimization based on item types
|
|
369
443
|
*/
|
|
370
|
-
getItemType
|
|
444
|
+
getItemType: (index: number) => string;
|
|
371
445
|
}
|
|
372
446
|
|
|
373
447
|
/**
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
LayoutParams,
|
|
3
|
+
RVDimension,
|
|
4
|
+
RVLayoutInfo,
|
|
5
|
+
RVLayout,
|
|
6
|
+
RVLayoutManager,
|
|
7
|
+
} from "./LayoutManager";
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* LinearLayoutManager implementation that arranges items in a single row or column.
|
|
@@ -10,12 +14,12 @@ export class RVLinearLayoutManagerImpl extends RVLayoutManager {
|
|
|
10
14
|
/** The bounded size (width for vertical, height for horizontal) */
|
|
11
15
|
private boundedSize: number;
|
|
12
16
|
/** Whether the bounded size has been set */
|
|
13
|
-
private hasSize
|
|
17
|
+
private hasSize = false;
|
|
14
18
|
|
|
15
19
|
/** Reference to the tallest item in the layout */
|
|
16
20
|
private tallestItem?: RVLayout;
|
|
17
21
|
/** Height of the tallest item */
|
|
18
|
-
private tallestItemHeight
|
|
22
|
+
private tallestItemHeight = 0;
|
|
19
23
|
|
|
20
24
|
constructor(params: LayoutParams, previousLayoutManager?: RVLayoutManager) {
|
|
21
25
|
super(params, previousLayoutManager);
|
|
@@ -41,7 +45,7 @@ export class RVLinearLayoutManagerImpl extends RVLayoutManager {
|
|
|
41
45
|
prevHorizontal !== this.horizontal
|
|
42
46
|
) {
|
|
43
47
|
if (this.layouts.length > 0) {
|
|
44
|
-
//console.log("-----> recomputeLayouts", this.horizontal);
|
|
48
|
+
// console.log("-----> recomputeLayouts", this.horizontal);
|
|
45
49
|
this.recomputeLayouts(0, this.layouts.length - 1);
|
|
46
50
|
this.requiresRepaint = true;
|
|
47
51
|
}
|
|
@@ -96,7 +100,7 @@ export class RVLinearLayoutManagerImpl extends RVLayoutManager {
|
|
|
96
100
|
? lastLayout.x + lastLayout.width
|
|
97
101
|
: this.boundedSize,
|
|
98
102
|
height: this.horizontal
|
|
99
|
-
? this.tallestItem?.height ??
|
|
103
|
+
? this.tallestItem?.height ?? this.boundedSize
|
|
100
104
|
: lastLayout.y + lastLayout.height,
|
|
101
105
|
};
|
|
102
106
|
}
|
|
@@ -123,7 +127,7 @@ export class RVLinearLayoutManagerImpl extends RVLayoutManager {
|
|
|
123
127
|
this.requiresRepaint = true;
|
|
124
128
|
targetMinHeight = 0;
|
|
125
129
|
}
|
|
126
|
-
//set minHeight for all layouts
|
|
130
|
+
// set minHeight for all layouts
|
|
127
131
|
for (const layout of this.layouts) {
|
|
128
132
|
if (targetMinHeight > 0) {
|
|
129
133
|
layout.height = newTallestItem.height;
|
|
@@ -17,13 +17,16 @@ export class RVMasonryLayoutManagerImpl extends RVLayoutManager {
|
|
|
17
17
|
/** Array tracking the current height of each column */
|
|
18
18
|
private columnHeights: number[];
|
|
19
19
|
/** Current column index for sequential placement */
|
|
20
|
-
private currentColumn
|
|
20
|
+
private currentColumn = 0;
|
|
21
|
+
|
|
22
|
+
/** If there's a span change for masonry layout, we need to recompute all the widths */
|
|
23
|
+
private fullRelayoutRequired = false;
|
|
21
24
|
|
|
22
25
|
constructor(params: LayoutParams, previousLayoutManager?: RVLayoutManager) {
|
|
23
26
|
super(params, previousLayoutManager);
|
|
24
27
|
this.boundedSize = params.windowSize.width;
|
|
25
|
-
this.optimizeItemArrangement = params.optimizeItemArrangement
|
|
26
|
-
this.columnHeights = Array(this.maxColumns).fill(0);
|
|
28
|
+
this.optimizeItemArrangement = params.optimizeItemArrangement;
|
|
29
|
+
this.columnHeights = this.columnHeights ?? Array(this.maxColumns).fill(0);
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
/**
|
|
@@ -41,14 +44,10 @@ export class RVMasonryLayoutManagerImpl extends RVLayoutManager {
|
|
|
41
44
|
) {
|
|
42
45
|
this.boundedSize = params.windowSize.width;
|
|
43
46
|
if (this.layouts.length > 0) {
|
|
44
|
-
//console.log("-----> recomputeLayouts");
|
|
47
|
+
// console.log("-----> recomputeLayouts");
|
|
45
48
|
|
|
46
|
-
//update all widths
|
|
47
|
-
|
|
48
|
-
this.layouts[i].width = this.getWidth(i);
|
|
49
|
-
this.layouts[i].minHeight = undefined;
|
|
50
|
-
}
|
|
51
|
-
//TODO: Optimize masonry in general
|
|
49
|
+
// update all widths
|
|
50
|
+
this.updateAllWidths();
|
|
52
51
|
this.recomputeLayouts(0, this.layouts.length - 1);
|
|
53
52
|
this.requiresRepaint = true;
|
|
54
53
|
}
|
|
@@ -70,6 +69,13 @@ export class RVMasonryLayoutManagerImpl extends RVLayoutManager {
|
|
|
70
69
|
layout.isWidthMeasured = true;
|
|
71
70
|
this.layouts[index] = layout;
|
|
72
71
|
}
|
|
72
|
+
|
|
73
|
+
// TODO: Can be optimized
|
|
74
|
+
if (this.fullRelayoutRequired) {
|
|
75
|
+
this.updateAllWidths();
|
|
76
|
+
this.fullRelayoutRequired = false;
|
|
77
|
+
return 0;
|
|
78
|
+
}
|
|
73
79
|
}
|
|
74
80
|
|
|
75
81
|
/**
|
|
@@ -88,6 +94,14 @@ export class RVMasonryLayoutManagerImpl extends RVLayoutManager {
|
|
|
88
94
|
layout.enforcedWidth = true;
|
|
89
95
|
}
|
|
90
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Handles span change for an item.
|
|
99
|
+
* @param index Index of the item
|
|
100
|
+
*/
|
|
101
|
+
handleSpanChange(index: number) {
|
|
102
|
+
this.fullRelayoutRequired = true;
|
|
103
|
+
}
|
|
104
|
+
|
|
91
105
|
/**
|
|
92
106
|
* Returns the total size of the layout area.
|
|
93
107
|
* @returns RVDimension containing width and height of the layout
|
|
@@ -125,7 +139,8 @@ export class RVMasonryLayoutManagerImpl extends RVLayoutManager {
|
|
|
125
139
|
|
|
126
140
|
for (let i = startIndex; i < itemCount; i++) {
|
|
127
141
|
const layout = this.getLayout(i);
|
|
128
|
-
|
|
142
|
+
// Skip tracking span because we're not changing widths
|
|
143
|
+
const span = this.getSpan(i, true);
|
|
129
144
|
|
|
130
145
|
if (this.optimizeItemArrangement) {
|
|
131
146
|
if (span === 1) {
|
|
@@ -148,8 +163,14 @@ export class RVMasonryLayoutManagerImpl extends RVLayoutManager {
|
|
|
148
163
|
* @returns Width of the item
|
|
149
164
|
*/
|
|
150
165
|
private getWidth(index: number): number {
|
|
151
|
-
|
|
152
|
-
|
|
166
|
+
return (this.boundedSize / this.maxColumns) * this.getSpan(index);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private updateAllWidths() {
|
|
170
|
+
for (let i = 0; i < this.layouts.length; i++) {
|
|
171
|
+
this.layouts[i].width = this.getWidth(i);
|
|
172
|
+
this.layouts[i].minHeight = undefined;
|
|
173
|
+
}
|
|
153
174
|
}
|
|
154
175
|
|
|
155
176
|
/**
|
|
@@ -17,7 +17,7 @@ import React from "react";
|
|
|
17
17
|
* getValidComponent(<MyComponent />)
|
|
18
18
|
*/
|
|
19
19
|
export const getValidComponent = (
|
|
20
|
-
component: React.ComponentType
|
|
20
|
+
component: React.ComponentType | React.ReactElement | null | undefined
|
|
21
21
|
): React.ReactElement | null => {
|
|
22
22
|
if (React.isValidElement(component)) {
|
|
23
23
|
return component;
|
|
@@ -33,10 +33,9 @@ function binarySearchVisibleIndex(
|
|
|
33
33
|
const position = isSortedByX ? layout.x : layout.y;
|
|
34
34
|
const size = isSortedByX ? layout.width : layout.height;
|
|
35
35
|
|
|
36
|
-
//TODO: Will this find item bigger than viewport
|
|
37
36
|
if (findFirst) {
|
|
38
37
|
// Logic for finding the first visible index
|
|
39
|
-
if (position >= threshold || position + size
|
|
38
|
+
if (position >= threshold || position + size > threshold) {
|
|
40
39
|
// Potential visible index found, continue searching left for earlier visible items
|
|
41
40
|
visibleIndex = mid;
|
|
42
41
|
right = mid - 1;
|
|
@@ -15,7 +15,7 @@ interface Layout {
|
|
|
15
15
|
* @param view - The React Native View component to measure
|
|
16
16
|
* @returns An object containing x, y, width, and height measurements
|
|
17
17
|
*/
|
|
18
|
-
|
|
18
|
+
function measureLayout(view: View, oldLayout: Layout | undefined) {
|
|
19
19
|
// const layout = view.unstable_getBoundingClientRect();
|
|
20
20
|
// layout.width = roundOffPixel(layout.width);
|
|
21
21
|
// layout.height = roundOffPixel(layout.height);
|
|
@@ -31,7 +31,7 @@ export function measureLayout(view: View, oldLayout: Layout | undefined) {
|
|
|
31
31
|
* @param relativeTo - The reference view to measure against
|
|
32
32
|
* @returns An object containing x, y, width, and height measurements
|
|
33
33
|
*/
|
|
34
|
-
|
|
34
|
+
function measureLayoutRelative(
|
|
35
35
|
view: View,
|
|
36
36
|
relativeTo: View,
|
|
37
37
|
oldLayout: Layout | undefined
|
|
@@ -87,3 +87,42 @@ export function areDimensionsEqual(value1: number, value2: number): boolean {
|
|
|
87
87
|
export function roundOffPixel(value: number): number {
|
|
88
88
|
return PixelRatio.roundToNearestPixel(value);
|
|
89
89
|
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Specific method for easier mocking
|
|
93
|
+
* Measures the layout of parent of RecyclerView
|
|
94
|
+
* Returns the x, y coordinates and dimensions of the view.
|
|
95
|
+
* @param view - The React Native View component to measure
|
|
96
|
+
* @returns An object containing x, y, width, and height measurements
|
|
97
|
+
*/
|
|
98
|
+
export function measureParentSize(view: View): Layout {
|
|
99
|
+
return measureLayout(view, undefined);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Specific method for easier mocking
|
|
104
|
+
* Measures the layout of child container of RecyclerView
|
|
105
|
+
* @param childContainerView
|
|
106
|
+
* @param parentView
|
|
107
|
+
* @returns
|
|
108
|
+
*/
|
|
109
|
+
export function measureFirstChildLayout(
|
|
110
|
+
childContainerView: View,
|
|
111
|
+
parentView: View
|
|
112
|
+
): Layout {
|
|
113
|
+
return measureLayoutRelative(childContainerView, parentView, undefined);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Specific method for easier mocking
|
|
118
|
+
* Measures the layout of items of RecyclerView
|
|
119
|
+
* @param item
|
|
120
|
+
* @param oldLayout
|
|
121
|
+
* @returns
|
|
122
|
+
*/
|
|
123
|
+
export function measureItemLayout(
|
|
124
|
+
item: View,
|
|
125
|
+
oldLayout: Layout | undefined
|
|
126
|
+
): Layout {
|
|
127
|
+
return measureLayout(item, oldLayout);
|
|
128
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
interface Layout {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Gets scroll offsets from up to 3 parent elements
|
|
10
|
+
*/
|
|
11
|
+
function getScrollOffsets(element: Element, stopAt: Element) {
|
|
12
|
+
let scrollX = 0;
|
|
13
|
+
let scrollY = 0;
|
|
14
|
+
let currentElement: Element | null = element;
|
|
15
|
+
|
|
16
|
+
// Only check up to 3 parent elements
|
|
17
|
+
while (currentElement && currentElement !== stopAt) {
|
|
18
|
+
const htmlElement = currentElement as HTMLElement;
|
|
19
|
+
scrollX += htmlElement.scrollLeft ?? 0;
|
|
20
|
+
scrollY += htmlElement.scrollTop ?? 0;
|
|
21
|
+
currentElement = currentElement.parentElement;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return { scrollX, scrollY };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Checks if two dimension values are not equal, with a small tolerance.
|
|
29
|
+
*/
|
|
30
|
+
export function areDimensionsNotEqual(value1: number, value2: number): boolean {
|
|
31
|
+
return !areDimensionsEqual(value1, value2);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Checks if two dimension values are equal, with a small tolerance.
|
|
36
|
+
*/
|
|
37
|
+
export function areDimensionsEqual(value1: number, value2: number): boolean {
|
|
38
|
+
return Math.abs(value1 - value2) <= 1;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function roundOffPixel(value: number): number {
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Measures the layout of parent of RecyclerView
|
|
47
|
+
*/
|
|
48
|
+
export function measureParentSize(view: Element): Layout {
|
|
49
|
+
return {
|
|
50
|
+
x: 0,
|
|
51
|
+
y: 0,
|
|
52
|
+
width: view.clientWidth,
|
|
53
|
+
height: view.clientHeight,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Measures the layout of child container of RecyclerView
|
|
59
|
+
*/
|
|
60
|
+
export function measureFirstChildLayout(
|
|
61
|
+
childContainerView: Element,
|
|
62
|
+
parentView: Element
|
|
63
|
+
): Layout {
|
|
64
|
+
const childRect = childContainerView.getBoundingClientRect();
|
|
65
|
+
const parentRect = parentView.getBoundingClientRect();
|
|
66
|
+
|
|
67
|
+
// Get scroll offsets for child container (max 3 parents)
|
|
68
|
+
const scrollOffsets = getScrollOffsets(childContainerView, parentView);
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
x: childRect.left - parentRect.left + scrollOffsets.scrollX,
|
|
72
|
+
y: childRect.top - parentRect.top + scrollOffsets.scrollY,
|
|
73
|
+
width: roundOffPixel(childRect.width),
|
|
74
|
+
height: roundOffPixel(childRect.height),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Measures the layout of items of RecyclerView
|
|
80
|
+
*/
|
|
81
|
+
export function measureItemLayout(
|
|
82
|
+
item: Element,
|
|
83
|
+
oldLayout: Layout | undefined
|
|
84
|
+
): Layout {
|
|
85
|
+
const layout = {
|
|
86
|
+
x: 0,
|
|
87
|
+
y: 0,
|
|
88
|
+
width: item.clientWidth,
|
|
89
|
+
height: item.clientHeight,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
if (oldLayout) {
|
|
93
|
+
if (areDimensionsEqual(layout.width, oldLayout.width)) {
|
|
94
|
+
layout.width = oldLayout.width;
|
|
95
|
+
}
|
|
96
|
+
if (areDimensionsEqual(layout.height, oldLayout.height)) {
|
|
97
|
+
layout.height = oldLayout.height;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return layout;
|
|
102
|
+
}
|
|
@@ -89,8 +89,8 @@ class ViewabilityHelper {
|
|
|
89
89
|
const timeoutId = setTimeout(() => {
|
|
90
90
|
this.timers.delete(timeoutId);
|
|
91
91
|
this.checkViewableIndicesChanges(newViewableIndices);
|
|
92
|
-
this.timers.add(timeoutId);
|
|
93
92
|
}, minimumViewTime);
|
|
93
|
+
this.timers.add(timeoutId);
|
|
94
94
|
} else {
|
|
95
95
|
this.checkViewableIndicesChanges(newViewableIndices);
|
|
96
96
|
}
|