@shopify/flash-list 2.0.4-alpha.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AnimatedFlashList.js +4 -6
- package/dist/AnimatedFlashList.js.map +1 -1
- package/dist/FlashList.js +1 -5
- package/dist/FlashList.js.map +1 -1
- package/dist/FlashListProps.d.ts +41 -1
- package/dist/FlashListProps.d.ts.map +1 -1
- package/dist/FlashListProps.js +1 -4
- package/dist/FlashListProps.js.map +1 -1
- package/dist/FlashListRef.js +1 -2
- package/dist/benchmark/AutoScrollHelper.js +22 -30
- package/dist/benchmark/AutoScrollHelper.js.map +1 -1
- package/dist/benchmark/JSFPSMonitor.js +27 -33
- package/dist/benchmark/JSFPSMonitor.js.map +1 -1
- package/dist/benchmark/roundToDecimalPlaces.js +2 -5
- package/dist/benchmark/roundToDecimalPlaces.js.map +1 -1
- package/dist/benchmark/useBenchmark.d.ts +9 -1
- package/dist/benchmark/useBenchmark.d.ts.map +1 -1
- package/dist/benchmark/useBenchmark.js +86 -95
- package/dist/benchmark/useBenchmark.js.map +1 -1
- package/dist/benchmark/useDataMultiplier.js +6 -10
- package/dist/benchmark/useDataMultiplier.js.map +1 -1
- package/dist/benchmark/useFlatListBenchmark.d.ts +4 -1
- package/dist/benchmark/useFlatListBenchmark.d.ts.map +1 -1
- package/dist/benchmark/useFlatListBenchmark.js +73 -81
- package/dist/benchmark/useFlatListBenchmark.js.map +1 -1
- package/dist/errors/ErrorMessages.js +1 -4
- package/dist/errors/ErrorMessages.js.map +1 -1
- package/dist/errors/WarningMessages.js +1 -4
- package/dist/errors/WarningMessages.js.map +1 -1
- package/dist/index.js +17 -35
- package/dist/index.js.map +1 -1
- package/dist/isNewArch.js +6 -9
- package/dist/isNewArch.js.map +1 -1
- package/dist/native/config/PlatformHelper.android.js +2 -5
- package/dist/native/config/PlatformHelper.android.js.map +1 -1
- package/dist/native/config/PlatformHelper.ios.js +2 -5
- package/dist/native/config/PlatformHelper.ios.js.map +1 -1
- package/dist/native/config/PlatformHelper.js +2 -5
- package/dist/native/config/PlatformHelper.js.map +1 -1
- package/dist/native/config/PlatformHelper.web.js +2 -5
- package/dist/native/config/PlatformHelper.web.js.map +1 -1
- package/dist/recyclerview/LayoutCommitObserver.js +20 -24
- package/dist/recyclerview/LayoutCommitObserver.js.map +1 -1
- package/dist/recyclerview/RecyclerView.d.ts.map +1 -1
- package/dist/recyclerview/RecyclerView.js +134 -111
- package/dist/recyclerview/RecyclerView.js.map +1 -1
- package/dist/recyclerview/RecyclerViewContextProvider.js +7 -12
- package/dist/recyclerview/RecyclerViewContextProvider.js.map +1 -1
- package/dist/recyclerview/RecyclerViewManager.js +138 -167
- package/dist/recyclerview/RecyclerViewManager.js.map +1 -1
- package/dist/recyclerview/RecyclerViewProps.js +1 -2
- package/dist/recyclerview/RenderStackManager.js +97 -188
- package/dist/recyclerview/RenderStackManager.js.map +1 -1
- package/dist/recyclerview/ViewHolder.d.ts +2 -0
- package/dist/recyclerview/ViewHolder.d.ts.map +1 -1
- package/dist/recyclerview/ViewHolder.js +19 -21
- package/dist/recyclerview/ViewHolder.js.map +1 -1
- package/dist/recyclerview/ViewHolderCollection.d.ts +4 -0
- package/dist/recyclerview/ViewHolderCollection.d.ts.map +1 -1
- package/dist/recyclerview/ViewHolderCollection.js +26 -30
- package/dist/recyclerview/ViewHolderCollection.js.map +1 -1
- package/dist/recyclerview/components/CompatScroller.js +6 -7
- package/dist/recyclerview/components/CompatScroller.js.map +1 -1
- package/dist/recyclerview/components/CompatView.js +6 -7
- package/dist/recyclerview/components/CompatView.js.map +1 -1
- package/dist/recyclerview/components/ScrollAnchor.js +10 -15
- package/dist/recyclerview/components/ScrollAnchor.js.map +1 -1
- package/dist/recyclerview/components/StickyHeaders.d.ts +5 -1
- package/dist/recyclerview/components/StickyHeaders.d.ts.map +1 -1
- package/dist/recyclerview/components/StickyHeaders.js +77 -51
- package/dist/recyclerview/components/StickyHeaders.js.map +1 -1
- package/dist/recyclerview/helpers/ConsecutiveNumbers.js +39 -66
- package/dist/recyclerview/helpers/ConsecutiveNumbers.js.map +1 -1
- package/dist/recyclerview/helpers/EngagedIndicesTracker.js +57 -63
- package/dist/recyclerview/helpers/EngagedIndicesTracker.js.map +1 -1
- package/dist/recyclerview/helpers/RenderTimeTracker.js +19 -24
- package/dist/recyclerview/helpers/RenderTimeTracker.js.map +1 -1
- package/dist/recyclerview/helpers/VelocityTracker.js +16 -22
- package/dist/recyclerview/helpers/VelocityTracker.js.map +1 -1
- package/dist/recyclerview/hooks/useBoundDetection.js +37 -40
- package/dist/recyclerview/hooks/useBoundDetection.js.map +1 -1
- package/dist/recyclerview/hooks/useLayoutState.js +9 -15
- package/dist/recyclerview/hooks/useLayoutState.js.map +1 -1
- package/dist/recyclerview/hooks/useMappingHelper.js +6 -10
- package/dist/recyclerview/hooks/useMappingHelper.js.map +1 -1
- package/dist/recyclerview/hooks/useOnLoad.js +16 -22
- package/dist/recyclerview/hooks/useOnLoad.js.map +1 -1
- package/dist/recyclerview/hooks/useRecyclerViewController.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useRecyclerViewController.js +169 -188
- package/dist/recyclerview/hooks/useRecyclerViewController.js.map +1 -1
- package/dist/recyclerview/hooks/useRecyclerViewManager.js +12 -17
- package/dist/recyclerview/hooks/useRecyclerViewManager.js.map +1 -1
- package/dist/recyclerview/hooks/useRecyclingState.js +10 -14
- package/dist/recyclerview/hooks/useRecyclingState.js.map +1 -1
- package/dist/recyclerview/hooks/useSecondaryProps.d.ts +2 -0
- package/dist/recyclerview/hooks/useSecondaryProps.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useSecondaryProps.js +39 -30
- package/dist/recyclerview/hooks/useSecondaryProps.js.map +1 -1
- package/dist/recyclerview/hooks/useUnmountAwareCallbacks.js +17 -22
- package/dist/recyclerview/hooks/useUnmountAwareCallbacks.js.map +1 -1
- package/dist/recyclerview/hooks/useUnmountFlag.js +5 -9
- package/dist/recyclerview/hooks/useUnmountFlag.js.map +1 -1
- package/dist/recyclerview/layout-managers/GridLayoutManager.js +61 -80
- package/dist/recyclerview/layout-managers/GridLayoutManager.js.map +1 -1
- package/dist/recyclerview/layout-managers/LayoutManager.js +83 -123
- package/dist/recyclerview/layout-managers/LayoutManager.js.map +1 -1
- package/dist/recyclerview/layout-managers/LinearLayoutManager.js +51 -91
- package/dist/recyclerview/layout-managers/LinearLayoutManager.js.map +1 -1
- package/dist/recyclerview/layout-managers/MasonryLayoutManager.js +77 -96
- package/dist/recyclerview/layout-managers/MasonryLayoutManager.js.map +1 -1
- package/dist/recyclerview/utils/adjustOffsetForRTL.js +1 -4
- package/dist/recyclerview/utils/adjustOffsetForRTL.js.map +1 -1
- package/dist/recyclerview/utils/componentUtils.js +4 -9
- package/dist/recyclerview/utils/componentUtils.js.map +1 -1
- package/dist/recyclerview/utils/findVisibleIndex.js +9 -13
- package/dist/recyclerview/utils/findVisibleIndex.js.map +1 -1
- package/dist/recyclerview/utils/measureLayout.js +12 -20
- package/dist/recyclerview/utils/measureLayout.js.map +1 -1
- package/dist/recyclerview/utils/measureLayout.web.js +15 -23
- package/dist/recyclerview/utils/measureLayout.web.js.map +1 -1
- package/dist/recyclerview/viewability/ViewToken.js +1 -2
- package/dist/recyclerview/viewability/ViewabilityHelper.js +34 -41
- package/dist/recyclerview/viewability/ViewabilityHelper.js.map +1 -1
- package/dist/recyclerview/viewability/ViewabilityManager.js +48 -61
- package/dist/recyclerview/viewability/ViewabilityManager.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/AverageWindow.js +28 -39
- package/dist/utils/AverageWindow.js.map +1 -1
- package/package.json +4 -6
- package/src/FlashListProps.ts +51 -1
- package/src/benchmark/useBenchmark.ts +47 -4
- package/src/benchmark/useFlatListBenchmark.ts +38 -5
- package/src/recyclerview/RecyclerView.tsx +42 -8
- package/src/recyclerview/ViewHolder.tsx +6 -1
- package/src/recyclerview/ViewHolderCollection.tsx +10 -0
- package/src/recyclerview/components/StickyHeaders.tsx +54 -13
- package/src/recyclerview/hooks/useRecyclerViewController.tsx +7 -4
- package/src/recyclerview/hooks/useSecondaryProps.tsx +23 -0
- package/dist/__tests__/AverageWindow.test.d.ts +0 -2
- package/dist/__tests__/AverageWindow.test.d.ts.map +0 -1
- package/dist/__tests__/AverageWindow.test.js +0 -104
- package/dist/__tests__/AverageWindow.test.js.map +0 -1
- package/dist/__tests__/ConsecutiveNumbers.test.d.ts +0 -2
- package/dist/__tests__/ConsecutiveNumbers.test.d.ts.map +0 -1
- package/dist/__tests__/ConsecutiveNumbers.test.js +0 -224
- package/dist/__tests__/ConsecutiveNumbers.test.js.map +0 -1
- package/dist/__tests__/GridLayoutManager.test.d.ts +0 -2
- package/dist/__tests__/GridLayoutManager.test.d.ts.map +0 -1
- package/dist/__tests__/GridLayoutManager.test.js +0 -69
- package/dist/__tests__/GridLayoutManager.test.js.map +0 -1
- package/dist/__tests__/LayoutCommitObserver.test.d.ts +0 -2
- package/dist/__tests__/LayoutCommitObserver.test.d.ts.map +0 -1
- package/dist/__tests__/LayoutCommitObserver.test.js +0 -37
- package/dist/__tests__/LayoutCommitObserver.test.js.map +0 -1
- package/dist/__tests__/LinearLayoutManager.test.d.ts +0 -2
- package/dist/__tests__/LinearLayoutManager.test.d.ts.map +0 -1
- package/dist/__tests__/LinearLayoutManager.test.js +0 -140
- package/dist/__tests__/LinearLayoutManager.test.js.map +0 -1
- package/dist/__tests__/MasonryLayoutManager.test.d.ts +0 -2
- package/dist/__tests__/MasonryLayoutManager.test.d.ts.map +0 -1
- package/dist/__tests__/MasonryLayoutManager.test.js +0 -148
- package/dist/__tests__/MasonryLayoutManager.test.js.map +0 -1
- package/dist/__tests__/RecyclerView.test.d.ts +0 -2
- package/dist/__tests__/RecyclerView.test.d.ts.map +0 -1
- package/dist/__tests__/RecyclerView.test.js +0 -103
- package/dist/__tests__/RecyclerView.test.js.map +0 -1
- package/dist/__tests__/RecyclerViewManager.test.d.ts +0 -2
- package/dist/__tests__/RecyclerViewManager.test.d.ts.map +0 -1
- package/dist/__tests__/RecyclerViewManager.test.js +0 -56
- package/dist/__tests__/RecyclerViewManager.test.js.map +0 -1
- package/dist/__tests__/RenderStackManager.test.d.ts +0 -2
- package/dist/__tests__/RenderStackManager.test.d.ts.map +0 -1
- package/dist/__tests__/RenderStackManager.test.js +0 -485
- package/dist/__tests__/RenderStackManager.test.js.map +0 -1
- package/dist/__tests__/ViewabilityHelper.test.d.ts +0 -2
- package/dist/__tests__/ViewabilityHelper.test.d.ts.map +0 -1
- package/dist/__tests__/ViewabilityHelper.test.js +0 -186
- package/dist/__tests__/ViewabilityHelper.test.js.map +0 -1
- package/dist/__tests__/findVisibleIndex.test.d.ts +0 -2
- package/dist/__tests__/findVisibleIndex.test.d.ts.map +0 -1
- package/dist/__tests__/findVisibleIndex.test.js +0 -259
- package/dist/__tests__/findVisibleIndex.test.js.map +0 -1
- package/dist/__tests__/helpers/createLayoutManager.d.ts +0 -34
- package/dist/__tests__/helpers/createLayoutManager.d.ts.map +0 -1
- package/dist/__tests__/helpers/createLayoutManager.js +0 -110
- package/dist/__tests__/helpers/createLayoutManager.js.map +0 -1
- package/dist/__tests__/useUnmountAwareCallbacks.test.d.ts +0 -2
- package/dist/__tests__/useUnmountAwareCallbacks.test.d.ts.map +0 -1
- package/dist/__tests__/useUnmountAwareCallbacks.test.js +0 -185
- package/dist/__tests__/useUnmountAwareCallbacks.test.js.map +0 -1
- package/src/__tests__/AverageWindow.test.ts +0 -128
- package/src/__tests__/ConsecutiveNumbers.test.ts +0 -232
- package/src/__tests__/GridLayoutManager.test.ts +0 -113
- package/src/__tests__/LayoutCommitObserver.test.tsx +0 -63
- package/src/__tests__/LinearLayoutManager.test.ts +0 -227
- package/src/__tests__/MasonryLayoutManager.test.ts +0 -202
- package/src/__tests__/RecyclerView.test.tsx +0 -144
- package/src/__tests__/RecyclerViewManager.test.ts +0 -74
- package/src/__tests__/RenderStackManager.test.ts +0 -574
- package/src/__tests__/ViewabilityHelper.test.ts +0 -282
- package/src/__tests__/findVisibleIndex.test.ts +0 -369
- package/src/__tests__/helpers/createLayoutManager.ts +0 -141
- package/src/__tests__/useUnmountAwareCallbacks.test.tsx +0 -285
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createPopulatedLayoutManager,
|
|
3
|
-
getAllLayouts,
|
|
4
|
-
LayoutManagerType,
|
|
5
|
-
createLayoutParams,
|
|
6
|
-
} from "./helpers/createLayoutManager";
|
|
7
|
-
|
|
8
|
-
describe("GridLayoutManager", () => {
|
|
9
|
-
const windowSize = { width: 400, height: 900 };
|
|
10
|
-
const defaultParams = { windowSize, maxColumns: 2 };
|
|
11
|
-
|
|
12
|
-
describe("Basic grid layout", () => {
|
|
13
|
-
it("should arrange items in rows with equal widths", () => {
|
|
14
|
-
const manager = createPopulatedLayoutManager(
|
|
15
|
-
LayoutManagerType.GRID,
|
|
16
|
-
4,
|
|
17
|
-
defaultParams
|
|
18
|
-
);
|
|
19
|
-
const layouts = getAllLayouts(manager);
|
|
20
|
-
|
|
21
|
-
expect(layouts[0].x).toBe(0);
|
|
22
|
-
expect(layouts[0].width).toBe(200);
|
|
23
|
-
expect(layouts[1].x).toBe(200);
|
|
24
|
-
|
|
25
|
-
expect(layouts[2].y).toBe(layouts[0].height);
|
|
26
|
-
expect(layouts[3].x).toBe(200);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it("should respect maxColumns configuration", () => {
|
|
30
|
-
const manager = createPopulatedLayoutManager(LayoutManagerType.GRID, 6, {
|
|
31
|
-
...defaultParams,
|
|
32
|
-
maxColumns: 3,
|
|
33
|
-
});
|
|
34
|
-
const layouts = getAllLayouts(manager);
|
|
35
|
-
|
|
36
|
-
expect(layouts[0].width).toBeCloseTo(400 / 3);
|
|
37
|
-
expect(layouts[3].x).toBe(0);
|
|
38
|
-
expect(layouts[3].y).toBe(layouts[0].height);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
describe("Multi-column items", () => {
|
|
43
|
-
it("should handle items spanning multiple columns", () => {
|
|
44
|
-
const manager = createPopulatedLayoutManager(LayoutManagerType.GRID, 3, {
|
|
45
|
-
...defaultParams,
|
|
46
|
-
maxColumns: 3,
|
|
47
|
-
overrideItemLayout: (index, layout) => {
|
|
48
|
-
layout.span = index === 0 ? 2 : undefined;
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
const layouts = getAllLayouts(manager);
|
|
52
|
-
|
|
53
|
-
// First item spans 2 columns
|
|
54
|
-
expect(layouts[0].width).toBeCloseTo((400 / 3) * 2);
|
|
55
|
-
// Next item starts in third column
|
|
56
|
-
expect(layouts[1].x).toBeCloseTo((400 / 3) * 2);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it("should wrap items that exceed column count", () => {
|
|
60
|
-
const manager = createPopulatedLayoutManager(LayoutManagerType.GRID, 4, {
|
|
61
|
-
...defaultParams,
|
|
62
|
-
overrideItemLayout: (index, layout) => {
|
|
63
|
-
layout.span = index % 2 === 0 ? 2 : 1;
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
const layouts = getAllLayouts(manager);
|
|
67
|
-
|
|
68
|
-
// Row 1: 2 columns (span 2 + span 2 would exceed 2 columns)
|
|
69
|
-
expect(layouts[0].width).toBe(400);
|
|
70
|
-
expect(layouts[1].x).toBe(0);
|
|
71
|
-
expect(layouts[1].y).toBe(layouts[0].height);
|
|
72
|
-
expect(layouts[2].x).toBe(0);
|
|
73
|
-
expect(layouts[2].y).toBe(layouts[1].height + layouts[0].height);
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
describe("Layout recalculations", () => {
|
|
78
|
-
it("should adjust layout when window size changes", () => {
|
|
79
|
-
const manager = createPopulatedLayoutManager(
|
|
80
|
-
LayoutManagerType.GRID,
|
|
81
|
-
4,
|
|
82
|
-
defaultParams
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
// Update window size
|
|
86
|
-
manager.updateLayoutParams(
|
|
87
|
-
createLayoutParams({
|
|
88
|
-
...defaultParams,
|
|
89
|
-
windowSize: { width: 600, height: 900 },
|
|
90
|
-
})
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
const updatedWidth = getAllLayouts(manager)[0].width;
|
|
94
|
-
expect(updatedWidth).toBe(300); // 600 / 2 columns
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it("should maintain positions when adding new items", () => {
|
|
98
|
-
const manager = createPopulatedLayoutManager(
|
|
99
|
-
LayoutManagerType.GRID,
|
|
100
|
-
2,
|
|
101
|
-
defaultParams
|
|
102
|
-
);
|
|
103
|
-
const initialLayouts = getAllLayouts(manager);
|
|
104
|
-
|
|
105
|
-
// Add two more items
|
|
106
|
-
manager.modifyLayout([], 4);
|
|
107
|
-
|
|
108
|
-
const updatedLayouts = getAllLayouts(manager);
|
|
109
|
-
expect(updatedLayouts[0]).toEqual(initialLayouts[0]);
|
|
110
|
-
expect(updatedLayouts[3].y).toBe(initialLayouts[0].height);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
});
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { render } from "@quilted/react-testing";
|
|
3
|
-
|
|
4
|
-
import { useFlashListContext } from "../recyclerview/RecyclerViewContextProvider";
|
|
5
|
-
import { LayoutCommitObserver } from "../recyclerview/LayoutCommitObserver";
|
|
6
|
-
import { FlashList } from "..";
|
|
7
|
-
|
|
8
|
-
describe("LayoutCommitObserver", () => {
|
|
9
|
-
it("should not alter ref captured by child", () => {
|
|
10
|
-
const ChildComponent = () => {
|
|
11
|
-
const context = useFlashListContext();
|
|
12
|
-
expect(context?.getRef()?.props.testID).toBe("child");
|
|
13
|
-
expect(context?.getParentRef()?.props.testID).toBe("parent");
|
|
14
|
-
expect(context?.getScrollViewRef()?.props.testID).toBe("child");
|
|
15
|
-
expect(context?.getParentScrollViewRef()?.props.testID).toBe("parent");
|
|
16
|
-
|
|
17
|
-
return null;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
let commitLayoutEffectCount = 0;
|
|
21
|
-
|
|
22
|
-
const content = (
|
|
23
|
-
<FlashList
|
|
24
|
-
testID="parent"
|
|
25
|
-
data={[1]}
|
|
26
|
-
renderItem={() => (
|
|
27
|
-
<LayoutCommitObserver
|
|
28
|
-
onCommitLayoutEffect={() => {
|
|
29
|
-
commitLayoutEffectCount++;
|
|
30
|
-
}}
|
|
31
|
-
>
|
|
32
|
-
<FlashList
|
|
33
|
-
testID="child"
|
|
34
|
-
data={[1]}
|
|
35
|
-
renderItem={() => (
|
|
36
|
-
<LayoutCommitObserver
|
|
37
|
-
onCommitLayoutEffect={() => {
|
|
38
|
-
commitLayoutEffectCount++;
|
|
39
|
-
}}
|
|
40
|
-
>
|
|
41
|
-
<LayoutCommitObserver
|
|
42
|
-
onCommitLayoutEffect={() => {
|
|
43
|
-
commitLayoutEffectCount++;
|
|
44
|
-
}}
|
|
45
|
-
>
|
|
46
|
-
<ChildComponent />
|
|
47
|
-
</LayoutCommitObserver>
|
|
48
|
-
</LayoutCommitObserver>
|
|
49
|
-
)}
|
|
50
|
-
/>
|
|
51
|
-
</LayoutCommitObserver>
|
|
52
|
-
)}
|
|
53
|
-
/>
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
const renderResult = render(content);
|
|
57
|
-
|
|
58
|
-
expect(commitLayoutEffectCount).toBe(3);
|
|
59
|
-
|
|
60
|
-
// Force unmount to trigger cleanup of async operations
|
|
61
|
-
renderResult.unmount();
|
|
62
|
-
});
|
|
63
|
-
});
|
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createPopulatedLayoutManager,
|
|
3
|
-
getAllLayouts,
|
|
4
|
-
LayoutManagerType,
|
|
5
|
-
createLayoutParams,
|
|
6
|
-
createLayoutManager,
|
|
7
|
-
createMockLayoutInfo,
|
|
8
|
-
} from "./helpers/createLayoutManager";
|
|
9
|
-
|
|
10
|
-
describe("LinearLayoutManager", () => {
|
|
11
|
-
const windowSize = { width: 400, height: 900 };
|
|
12
|
-
const defaultParams = { windowSize, horizontal: false };
|
|
13
|
-
const horizontalParams = { windowSize, horizontal: true };
|
|
14
|
-
|
|
15
|
-
describe("Vertical layout", () => {
|
|
16
|
-
it("should stack items vertically", () => {
|
|
17
|
-
const manager = createPopulatedLayoutManager(
|
|
18
|
-
LayoutManagerType.LINEAR,
|
|
19
|
-
3,
|
|
20
|
-
defaultParams,
|
|
21
|
-
100, // itemWidth
|
|
22
|
-
100 // itemHeight
|
|
23
|
-
);
|
|
24
|
-
const layouts = getAllLayouts(manager);
|
|
25
|
-
|
|
26
|
-
expect(layouts.length).toBe(3);
|
|
27
|
-
expect(layouts[0].y).toBe(0);
|
|
28
|
-
expect(layouts[1].y).toBe(100);
|
|
29
|
-
expect(layouts[2].y).toBe(200);
|
|
30
|
-
expect(layouts[0].x).toBe(0);
|
|
31
|
-
expect(layouts[0].width).toBe(400); // Should take full width
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it("should handle variable item heights", () => {
|
|
35
|
-
const manager = createLayoutManager(
|
|
36
|
-
LayoutManagerType.LINEAR,
|
|
37
|
-
defaultParams
|
|
38
|
-
);
|
|
39
|
-
const layoutInfos = [
|
|
40
|
-
createMockLayoutInfo(0, 400, 100),
|
|
41
|
-
createMockLayoutInfo(1, 400, 150),
|
|
42
|
-
createMockLayoutInfo(2, 400, 50),
|
|
43
|
-
];
|
|
44
|
-
manager.modifyLayout(layoutInfos, 3);
|
|
45
|
-
const layouts = getAllLayouts(manager);
|
|
46
|
-
|
|
47
|
-
expect(layouts[0].height).toBe(100);
|
|
48
|
-
expect(layouts[1].height).toBe(150);
|
|
49
|
-
expect(layouts[2].height).toBe(50);
|
|
50
|
-
|
|
51
|
-
expect(layouts[0].y).toBe(0);
|
|
52
|
-
expect(layouts[1].y).toBe(100); // 0 + 100
|
|
53
|
-
expect(layouts[2].y).toBe(250); // 100 + 150
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it("should calculate total layout size correctly", () => {
|
|
57
|
-
const manager = createPopulatedLayoutManager(
|
|
58
|
-
LayoutManagerType.LINEAR,
|
|
59
|
-
3,
|
|
60
|
-
defaultParams,
|
|
61
|
-
100,
|
|
62
|
-
100
|
|
63
|
-
);
|
|
64
|
-
const layoutSize = manager.getLayoutSize();
|
|
65
|
-
expect(layoutSize.width).toBe(400);
|
|
66
|
-
expect(layoutSize.height).toBe(300); // 3 items * 100 height
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
describe("Horizontal layout", () => {
|
|
71
|
-
it("should stack items horizontally", () => {
|
|
72
|
-
const manager = createPopulatedLayoutManager(
|
|
73
|
-
LayoutManagerType.LINEAR,
|
|
74
|
-
3,
|
|
75
|
-
horizontalParams,
|
|
76
|
-
100, // itemWidth
|
|
77
|
-
100 // itemHeight - should take full height
|
|
78
|
-
);
|
|
79
|
-
const layouts = getAllLayouts(manager);
|
|
80
|
-
|
|
81
|
-
expect(layouts.length).toBe(3);
|
|
82
|
-
expect(layouts[0].x).toBe(0);
|
|
83
|
-
expect(layouts[1].x).toBe(100);
|
|
84
|
-
expect(layouts[2].x).toBe(200);
|
|
85
|
-
expect(layouts[0].y).toBe(0);
|
|
86
|
-
expect(layouts[0].minHeight).toBe(900); // Should take full height
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it("should handle variable item widths", () => {
|
|
90
|
-
const manager = createLayoutManager(
|
|
91
|
-
LayoutManagerType.LINEAR,
|
|
92
|
-
horizontalParams
|
|
93
|
-
);
|
|
94
|
-
const layoutInfos = [
|
|
95
|
-
createMockLayoutInfo(0, 100, 900),
|
|
96
|
-
createMockLayoutInfo(1, 150, 900),
|
|
97
|
-
createMockLayoutInfo(2, 50, 900),
|
|
98
|
-
];
|
|
99
|
-
manager.modifyLayout(layoutInfos, 3);
|
|
100
|
-
const layouts = getAllLayouts(manager);
|
|
101
|
-
|
|
102
|
-
expect(layouts[0].width).toBe(100);
|
|
103
|
-
expect(layouts[1].width).toBe(150);
|
|
104
|
-
expect(layouts[2].width).toBe(50);
|
|
105
|
-
|
|
106
|
-
expect(layouts[0].x).toBe(0);
|
|
107
|
-
expect(layouts[1].x).toBe(100); // 0 + 100
|
|
108
|
-
expect(layouts[2].x).toBe(250); // 100 + 150
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it("should calculate total layout size correctly in horizontal mode", () => {
|
|
112
|
-
const manager = createPopulatedLayoutManager(
|
|
113
|
-
LayoutManagerType.LINEAR,
|
|
114
|
-
3,
|
|
115
|
-
horizontalParams,
|
|
116
|
-
100,
|
|
117
|
-
100
|
|
118
|
-
);
|
|
119
|
-
const layoutSize = manager.getLayoutSize();
|
|
120
|
-
expect(layoutSize.width).toBe(300); // 3 items * 100 width
|
|
121
|
-
expect(layoutSize.height).toBe(900);
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
describe("Layout modifications", () => {
|
|
126
|
-
it("should update layout when items are added", () => {
|
|
127
|
-
const manager = createPopulatedLayoutManager(
|
|
128
|
-
LayoutManagerType.LINEAR,
|
|
129
|
-
2,
|
|
130
|
-
defaultParams,
|
|
131
|
-
100,
|
|
132
|
-
100
|
|
133
|
-
);
|
|
134
|
-
const initialLayouts = getAllLayouts(manager);
|
|
135
|
-
expect(initialLayouts.length).toBe(2);
|
|
136
|
-
|
|
137
|
-
// Add one more item
|
|
138
|
-
const newLayoutInfo = [createMockLayoutInfo(2, 400, 120)];
|
|
139
|
-
manager.modifyLayout(newLayoutInfo, 3);
|
|
140
|
-
|
|
141
|
-
const updatedLayouts = getAllLayouts(manager);
|
|
142
|
-
expect(updatedLayouts.length).toBe(3);
|
|
143
|
-
expect(updatedLayouts[2].y).toBe(200); // 100 + 100
|
|
144
|
-
expect(updatedLayouts[2].height).toBe(120);
|
|
145
|
-
expect(manager.getLayoutSize().height).toBe(320); // 100 + 100 + 120
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it("should update layout when items are removed", () => {
|
|
149
|
-
const manager = createPopulatedLayoutManager(
|
|
150
|
-
LayoutManagerType.LINEAR,
|
|
151
|
-
3,
|
|
152
|
-
defaultParams,
|
|
153
|
-
100,
|
|
154
|
-
100
|
|
155
|
-
);
|
|
156
|
-
expect(getAllLayouts(manager).length).toBe(3);
|
|
157
|
-
expect(manager.getLayoutSize().height).toBe(300);
|
|
158
|
-
|
|
159
|
-
// Remove the last item
|
|
160
|
-
manager.modifyLayout([], 2);
|
|
161
|
-
|
|
162
|
-
const updatedLayouts = getAllLayouts(manager);
|
|
163
|
-
expect(updatedLayouts.length).toBe(2);
|
|
164
|
-
expect(manager.getLayoutSize().height).toBe(200);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it("should handle replacing all items", () => {
|
|
168
|
-
const manager = createPopulatedLayoutManager(
|
|
169
|
-
LayoutManagerType.LINEAR,
|
|
170
|
-
3,
|
|
171
|
-
defaultParams,
|
|
172
|
-
100,
|
|
173
|
-
100
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
const newLayoutInfos = [
|
|
177
|
-
createMockLayoutInfo(0, 400, 50),
|
|
178
|
-
createMockLayoutInfo(1, 400, 60),
|
|
179
|
-
];
|
|
180
|
-
manager.modifyLayout(newLayoutInfos, 2);
|
|
181
|
-
|
|
182
|
-
const layouts = getAllLayouts(manager);
|
|
183
|
-
expect(layouts.length).toBe(2);
|
|
184
|
-
expect(layouts[0].height).toBe(50);
|
|
185
|
-
expect(layouts[1].height).toBe(60);
|
|
186
|
-
expect(layouts[1].y).toBe(50);
|
|
187
|
-
expect(manager.getLayoutSize().height).toBe(110); // 50 + 60
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
it("should recalculate layout when window size changes", () => {
|
|
191
|
-
const manager = createPopulatedLayoutManager(
|
|
192
|
-
LayoutManagerType.LINEAR,
|
|
193
|
-
3,
|
|
194
|
-
defaultParams,
|
|
195
|
-
100,
|
|
196
|
-
100
|
|
197
|
-
);
|
|
198
|
-
const initialLayouts = getAllLayouts(manager);
|
|
199
|
-
expect(initialLayouts[0].width).toBe(400);
|
|
200
|
-
|
|
201
|
-
manager.updateLayoutParams(
|
|
202
|
-
createLayoutParams({
|
|
203
|
-
...defaultParams,
|
|
204
|
-
windowSize: { width: 600, height: 900 },
|
|
205
|
-
})
|
|
206
|
-
);
|
|
207
|
-
|
|
208
|
-
const updatedLayouts = getAllLayouts(manager);
|
|
209
|
-
expect(updatedLayouts[0].width).toBe(600); // Width should adapt
|
|
210
|
-
expect(updatedLayouts[1].y).toBe(initialLayouts[1].y); // Vertical position shouldn't change
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
describe("Empty layout", () => {
|
|
215
|
-
it("should return zero size for empty layout", () => {
|
|
216
|
-
const manager = createLayoutManager(
|
|
217
|
-
LayoutManagerType.LINEAR,
|
|
218
|
-
defaultParams
|
|
219
|
-
);
|
|
220
|
-
manager.modifyLayout([], 0);
|
|
221
|
-
const layoutSize = manager.getLayoutSize();
|
|
222
|
-
expect(layoutSize.width).toBe(0);
|
|
223
|
-
expect(layoutSize.height).toBe(0);
|
|
224
|
-
expect(getAllLayouts(manager).length).toBe(0);
|
|
225
|
-
});
|
|
226
|
-
});
|
|
227
|
-
});
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import { RVLayoutManager } from "../recyclerview/layout-managers/LayoutManager";
|
|
2
|
-
import { RVMasonryLayoutManagerImpl } from "../recyclerview/layout-managers/MasonryLayoutManager";
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
getAllLayouts,
|
|
6
|
-
LayoutManagerType,
|
|
7
|
-
createLayoutParams,
|
|
8
|
-
createLayoutManager,
|
|
9
|
-
createMockLayoutInfo,
|
|
10
|
-
} from "./helpers/createLayoutManager";
|
|
11
|
-
|
|
12
|
-
describe("MasonryLayoutManager", () => {
|
|
13
|
-
const windowSize = { width: 400, height: 900 };
|
|
14
|
-
const defaultParams = {
|
|
15
|
-
windowSize,
|
|
16
|
-
maxColumns: 2,
|
|
17
|
-
optimizeItemArrangement: true,
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
// Helper to get column heights
|
|
21
|
-
const getColumnHeights = (manager: RVLayoutManager): number[] => {
|
|
22
|
-
return (manager as RVMasonryLayoutManagerImpl)["columnHeights"];
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
describe("Vertical Masonry Layout", () => {
|
|
26
|
-
it("should distribute items into columns based on height", () => {
|
|
27
|
-
const manager = createLayoutManager(
|
|
28
|
-
LayoutManagerType.MASONRY,
|
|
29
|
-
defaultParams
|
|
30
|
-
);
|
|
31
|
-
const layoutInfos = [
|
|
32
|
-
createMockLayoutInfo(0, 200, 100), // Col 0
|
|
33
|
-
createMockLayoutInfo(1, 200, 150), // Col 1
|
|
34
|
-
createMockLayoutInfo(2, 200, 120), // Col 0 (shorter)
|
|
35
|
-
createMockLayoutInfo(3, 200, 80), // Col 1 (shorter)
|
|
36
|
-
createMockLayoutInfo(4, 200, 200), // Col 0 (shorter)
|
|
37
|
-
];
|
|
38
|
-
manager.modifyLayout(layoutInfos, 5);
|
|
39
|
-
const layouts = getAllLayouts(manager);
|
|
40
|
-
|
|
41
|
-
expect(layouts[0].x).toBe(0);
|
|
42
|
-
expect(layouts[0].y).toBe(0);
|
|
43
|
-
|
|
44
|
-
expect(layouts[1].x).toBe(200); // Second column
|
|
45
|
-
expect(layouts[1].y).toBe(0);
|
|
46
|
-
|
|
47
|
-
expect(layouts[2].x).toBe(0); // Back to first column
|
|
48
|
-
expect(layouts[2].y).toBe(100); // Below item 0
|
|
49
|
-
|
|
50
|
-
expect(layouts[3].x).toBe(200); // Still first column
|
|
51
|
-
expect(layouts[3].y).toBe(150); // Below item 2 (100 + 120)
|
|
52
|
-
|
|
53
|
-
expect(layouts[4].x).toBe(0); // Second column
|
|
54
|
-
expect(layouts[4].y).toBe(220); // Below item 1
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("should respect maxColumns configuration", () => {
|
|
58
|
-
const manager = createLayoutManager(LayoutManagerType.MASONRY, {
|
|
59
|
-
...defaultParams,
|
|
60
|
-
maxColumns: 3,
|
|
61
|
-
});
|
|
62
|
-
const layoutInfos = [
|
|
63
|
-
createMockLayoutInfo(0, 133, 100), // Col 0
|
|
64
|
-
createMockLayoutInfo(1, 133, 150), // Col 1
|
|
65
|
-
createMockLayoutInfo(2, 133, 120), // Col 2
|
|
66
|
-
createMockLayoutInfo(3, 133, 80), // Col 0
|
|
67
|
-
];
|
|
68
|
-
manager.modifyLayout(layoutInfos, 4);
|
|
69
|
-
const layouts = getAllLayouts(manager);
|
|
70
|
-
const colWidth = windowSize.width / 3;
|
|
71
|
-
|
|
72
|
-
expect(layouts[0].x).toBeCloseTo(0);
|
|
73
|
-
expect(layouts[1].x).toBeCloseTo(colWidth);
|
|
74
|
-
expect(layouts[2].x).toBeCloseTo(colWidth * 2);
|
|
75
|
-
expect(layouts[3].x).toBeCloseTo(0); // Placed in the shortest column (Col 0)
|
|
76
|
-
expect(layouts[3].y).toBeCloseTo(100); // Below item 0
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it("should calculate total layout size correctly", () => {
|
|
80
|
-
const manager = createLayoutManager(
|
|
81
|
-
LayoutManagerType.MASONRY,
|
|
82
|
-
defaultParams
|
|
83
|
-
);
|
|
84
|
-
const layoutInfos = [
|
|
85
|
-
createMockLayoutInfo(0, 200, 100), // Col 0
|
|
86
|
-
createMockLayoutInfo(1, 200, 150), // Col 1
|
|
87
|
-
createMockLayoutInfo(2, 200, 120), // Col 0
|
|
88
|
-
];
|
|
89
|
-
manager.modifyLayout(layoutInfos, 3);
|
|
90
|
-
const layoutSize = manager.getLayoutSize();
|
|
91
|
-
|
|
92
|
-
expect(layoutSize.width).toBe(400);
|
|
93
|
-
// Height is the tallest column height
|
|
94
|
-
const heights = getColumnHeights(manager);
|
|
95
|
-
expect(layoutSize.height).toBeCloseTo(Math.max(...heights)); // Max of [220, 150]
|
|
96
|
-
expect(layoutSize.height).toBeCloseTo(220);
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
describe("Layout Modifications", () => {
|
|
101
|
-
it("should update layout when items are added", () => {
|
|
102
|
-
const manager = createLayoutManager(
|
|
103
|
-
LayoutManagerType.MASONRY,
|
|
104
|
-
defaultParams
|
|
105
|
-
);
|
|
106
|
-
const initialInfos = [
|
|
107
|
-
createMockLayoutInfo(0, 200, 100), // Col 0 H=100
|
|
108
|
-
createMockLayoutInfo(1, 200, 150), // Col 1 H=150
|
|
109
|
-
];
|
|
110
|
-
manager.modifyLayout(initialInfos, 2);
|
|
111
|
-
expect(getAllLayouts(manager).length).toBe(2);
|
|
112
|
-
expect(getColumnHeights(manager)).toEqual([100, 150]);
|
|
113
|
-
|
|
114
|
-
// Add item, should go to Col 0
|
|
115
|
-
const newLayoutInfos = [createMockLayoutInfo(2, 200, 120)];
|
|
116
|
-
manager.modifyLayout(newLayoutInfos, 3);
|
|
117
|
-
|
|
118
|
-
const layouts = getAllLayouts(manager);
|
|
119
|
-
expect(layouts.length).toBe(3);
|
|
120
|
-
expect(layouts[2].x).toBe(0); // Col 0
|
|
121
|
-
expect(layouts[2].y).toBe(100); // Below item 0
|
|
122
|
-
expect(getColumnHeights(manager)).toEqual([220, 150]); // 100+120, 150
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it("should handle removing items (requires full recalculation)", () => {
|
|
126
|
-
const manager = createLayoutManager(
|
|
127
|
-
LayoutManagerType.MASONRY,
|
|
128
|
-
defaultParams
|
|
129
|
-
);
|
|
130
|
-
const initialInfos = [
|
|
131
|
-
createMockLayoutInfo(0, 200, 100), // Col 0 H=100
|
|
132
|
-
createMockLayoutInfo(1, 200, 150), // Col 1 H=150
|
|
133
|
-
createMockLayoutInfo(2, 200, 120), // Col 0 H=220
|
|
134
|
-
];
|
|
135
|
-
manager.modifyLayout(initialInfos, 3);
|
|
136
|
-
expect(getColumnHeights(manager)).toEqual([220, 150]);
|
|
137
|
-
|
|
138
|
-
// Remove item 2 (from Col 0) - Masonry usually recalculates fully
|
|
139
|
-
// We simulate this by passing the remaining items
|
|
140
|
-
const remainingInfos = [
|
|
141
|
-
createMockLayoutInfo(0, 200, 100),
|
|
142
|
-
createMockLayoutInfo(1, 200, 150),
|
|
143
|
-
];
|
|
144
|
-
manager.modifyLayout(remainingInfos, 2);
|
|
145
|
-
|
|
146
|
-
const layouts = getAllLayouts(manager);
|
|
147
|
-
expect(layouts.length).toBe(2);
|
|
148
|
-
expect(getColumnHeights(manager)).toEqual([100, 150]); // Back to original state
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it("should recalculate layout when window size changes", () => {
|
|
152
|
-
const manager = createLayoutManager(
|
|
153
|
-
LayoutManagerType.MASONRY,
|
|
154
|
-
defaultParams
|
|
155
|
-
);
|
|
156
|
-
const initialInfos = [
|
|
157
|
-
createMockLayoutInfo(0, 200, 100), // Col 0
|
|
158
|
-
createMockLayoutInfo(1, 200, 150), // Col 1
|
|
159
|
-
createMockLayoutInfo(2, 200, 120), // Col 0
|
|
160
|
-
];
|
|
161
|
-
manager.modifyLayout(initialInfos, 3);
|
|
162
|
-
const initialLayouts = getAllLayouts(manager);
|
|
163
|
-
expect(initialLayouts[1].x).toBe(200);
|
|
164
|
-
|
|
165
|
-
// Change window size and columns
|
|
166
|
-
manager.updateLayoutParams(
|
|
167
|
-
createLayoutParams({
|
|
168
|
-
...defaultParams,
|
|
169
|
-
maxColumns: 3,
|
|
170
|
-
windowSize: { width: 600, height: 900 },
|
|
171
|
-
})
|
|
172
|
-
);
|
|
173
|
-
// modifyLayout needs to be called again as dimensions depend on width
|
|
174
|
-
const updatedInfos = [
|
|
175
|
-
createMockLayoutInfo(0, 200, 100), // New width = 600/3 = 200
|
|
176
|
-
createMockLayoutInfo(1, 200, 150),
|
|
177
|
-
createMockLayoutInfo(2, 200, 120),
|
|
178
|
-
];
|
|
179
|
-
manager.modifyLayout(updatedInfos, 3);
|
|
180
|
-
|
|
181
|
-
const updatedLayouts = getAllLayouts(manager);
|
|
182
|
-
expect(updatedLayouts[0].width).toBe(200);
|
|
183
|
-
expect(updatedLayouts[1].x).toBe(200); // Col 1 starts at 200
|
|
184
|
-
expect(updatedLayouts[2].x).toBe(400); // Col 2 starts at 400
|
|
185
|
-
expect(getColumnHeights(manager)).toEqual([100, 150, 120]);
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
describe("Empty Layout", () => {
|
|
190
|
-
it("should return zero size for empty layout", () => {
|
|
191
|
-
const manager = createLayoutManager(
|
|
192
|
-
LayoutManagerType.MASONRY,
|
|
193
|
-
defaultParams
|
|
194
|
-
);
|
|
195
|
-
manager.modifyLayout([], 0);
|
|
196
|
-
const layoutSize = manager.getLayoutSize();
|
|
197
|
-
expect(layoutSize.width).toBe(0);
|
|
198
|
-
expect(layoutSize.height).toBe(0);
|
|
199
|
-
expect(getAllLayouts(manager).length).toBe(0);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
});
|