@shopify/flash-list 1.8.0 → 2.0.0-alpha.2
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 +147 -26
- package/dist/FlashListProps.d.ts +65 -2
- package/dist/FlashListProps.d.ts.map +1 -1
- package/dist/__tests__/AverageWindow.test.js +35 -0
- package/dist/__tests__/AverageWindow.test.js.map +1 -1
- package/dist/enableNewCore.d.ts +3 -0
- package/dist/enableNewCore.d.ts.map +1 -0
- package/dist/enableNewCore.js +25 -0
- package/dist/enableNewCore.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -8
- package/dist/index.js.map +1 -1
- package/dist/recyclerview/RecycleKeyManager.d.ts +82 -0
- package/dist/recyclerview/RecycleKeyManager.d.ts.map +1 -0
- package/dist/recyclerview/RecycleKeyManager.js +135 -0
- package/dist/recyclerview/RecycleKeyManager.js.map +1 -0
- package/dist/recyclerview/RecyclerView.d.ts +12 -0
- package/dist/recyclerview/RecyclerView.d.ts.map +1 -0
- package/dist/recyclerview/RecyclerView.js +283 -0
- package/dist/recyclerview/RecyclerView.js.map +1 -0
- package/dist/recyclerview/RecyclerViewContextProvider.d.ts +12 -0
- package/dist/recyclerview/RecyclerViewContextProvider.d.ts.map +1 -0
- package/dist/recyclerview/RecyclerViewContextProvider.js +11 -0
- package/dist/recyclerview/RecyclerViewContextProvider.js.map +1 -0
- package/dist/recyclerview/RecyclerViewManager.d.ts +52 -0
- package/dist/recyclerview/RecyclerViewManager.d.ts.map +1 -0
- package/dist/recyclerview/RecyclerViewManager.js +323 -0
- package/dist/recyclerview/RecyclerViewManager.js.map +1 -0
- package/dist/recyclerview/RecyclerViewProps.d.ts +9 -0
- package/dist/recyclerview/RecyclerViewProps.d.ts.map +1 -0
- package/dist/recyclerview/RecyclerViewProps.js +3 -0
- package/dist/recyclerview/RecyclerViewProps.js.map +1 -0
- package/dist/recyclerview/ViewHolder.d.ts +45 -0
- package/dist/recyclerview/ViewHolder.d.ts.map +1 -0
- package/dist/recyclerview/ViewHolder.js +96 -0
- package/dist/recyclerview/ViewHolder.js.map +1 -0
- package/dist/recyclerview/ViewHolderCollection.d.ts +57 -0
- package/dist/recyclerview/ViewHolderCollection.d.ts.map +1 -0
- package/dist/recyclerview/ViewHolderCollection.js +75 -0
- package/dist/recyclerview/ViewHolderCollection.js.map +1 -0
- package/dist/recyclerview/components/CompatScroller.d.ts +7 -0
- package/dist/recyclerview/components/CompatScroller.d.ts.map +1 -0
- package/dist/recyclerview/components/CompatScroller.js +8 -0
- package/dist/recyclerview/components/CompatScroller.js.map +1 -0
- package/dist/recyclerview/components/CompatView.d.ts +7 -0
- package/dist/recyclerview/components/CompatView.d.ts.map +1 -0
- package/dist/recyclerview/components/CompatView.js +8 -0
- package/dist/recyclerview/components/CompatView.js.map +1 -0
- package/dist/recyclerview/components/ScrollAnchor.d.ts +28 -0
- package/dist/recyclerview/components/ScrollAnchor.d.ts.map +1 -0
- package/dist/recyclerview/components/ScrollAnchor.js +35 -0
- package/dist/recyclerview/components/ScrollAnchor.js.map +1 -0
- package/dist/recyclerview/components/StickyHeaders.d.ts +38 -0
- package/dist/recyclerview/components/StickyHeaders.d.ts.map +1 -0
- package/dist/recyclerview/components/StickyHeaders.js +119 -0
- package/dist/recyclerview/components/StickyHeaders.js.map +1 -0
- package/dist/recyclerview/helpers/ConsecutiveNumbers.d.ts +51 -0
- package/dist/recyclerview/helpers/ConsecutiveNumbers.d.ts.map +1 -0
- package/dist/recyclerview/helpers/ConsecutiveNumbers.js +122 -0
- package/dist/recyclerview/helpers/ConsecutiveNumbers.js.map +1 -0
- package/dist/recyclerview/helpers/EngagedIndicesTracker.d.ts +59 -0
- package/dist/recyclerview/helpers/EngagedIndicesTracker.d.ts.map +1 -0
- package/dist/recyclerview/helpers/EngagedIndicesTracker.js +138 -0
- package/dist/recyclerview/helpers/EngagedIndicesTracker.js.map +1 -0
- package/dist/recyclerview/hooks/useBoundDetection.d.ts +19 -0
- package/dist/recyclerview/hooks/useBoundDetection.d.ts.map +1 -0
- package/dist/recyclerview/hooks/useBoundDetection.js +103 -0
- package/dist/recyclerview/hooks/useBoundDetection.js.map +1 -0
- package/dist/recyclerview/hooks/useLayoutState.d.ts +12 -0
- package/dist/recyclerview/hooks/useLayoutState.d.ts.map +1 -0
- package/dist/recyclerview/hooks/useLayoutState.js +43 -0
- package/dist/recyclerview/hooks/useLayoutState.js.map +1 -0
- package/dist/recyclerview/hooks/useOnLoad.d.ts +25 -0
- package/dist/recyclerview/hooks/useOnLoad.d.ts.map +1 -0
- package/dist/recyclerview/hooks/useOnLoad.js +73 -0
- package/dist/recyclerview/hooks/useOnLoad.js.map +1 -0
- package/dist/recyclerview/hooks/useRecyclerViewController.d.ts +72 -0
- package/dist/recyclerview/hooks/useRecyclerViewController.d.ts.map +1 -0
- package/dist/recyclerview/hooks/useRecyclerViewController.js +370 -0
- package/dist/recyclerview/hooks/useRecyclerViewController.js.map +1 -0
- package/dist/recyclerview/hooks/useRecyclerViewManager.d.ts +6 -0
- package/dist/recyclerview/hooks/useRecyclerViewManager.d.ts.map +1 -0
- package/dist/recyclerview/hooks/useRecyclerViewManager.js +27 -0
- package/dist/recyclerview/hooks/useRecyclerViewManager.js.map +1 -0
- package/dist/recyclerview/hooks/useRecyclingState.d.ts +16 -0
- package/dist/recyclerview/hooks/useRecyclingState.d.ts.map +1 -0
- package/dist/recyclerview/hooks/useRecyclingState.js +54 -0
- package/dist/recyclerview/hooks/useRecyclingState.js.map +1 -0
- package/dist/recyclerview/hooks/useSecondaryProps.d.ts +27 -0
- package/dist/recyclerview/hooks/useSecondaryProps.d.ts.map +1 -0
- package/dist/recyclerview/hooks/useSecondaryProps.js +93 -0
- package/dist/recyclerview/hooks/useSecondaryProps.js.map +1 -0
- package/dist/recyclerview/hooks/useUnmountFlag.d.ts +11 -0
- package/dist/recyclerview/hooks/useUnmountFlag.d.ts.map +1 -0
- package/dist/recyclerview/hooks/useUnmountFlag.js +28 -0
- package/dist/recyclerview/hooks/useUnmountFlag.js.map +1 -0
- package/dist/recyclerview/layout-managers/GridLayoutManager.d.ts +65 -0
- package/dist/recyclerview/layout-managers/GridLayoutManager.d.ts.map +1 -0
- package/dist/recyclerview/layout-managers/GridLayoutManager.js +204 -0
- package/dist/recyclerview/layout-managers/GridLayoutManager.js.map +1 -0
- package/dist/recyclerview/layout-managers/LayoutManager.d.ts +281 -0
- package/dist/recyclerview/layout-managers/LayoutManager.d.ts.map +1 -0
- package/dist/recyclerview/layout-managers/LayoutManager.js +250 -0
- package/dist/recyclerview/layout-managers/LayoutManager.js.map +1 -0
- package/dist/recyclerview/layout-managers/LinearLayoutManager.d.ts +52 -0
- package/dist/recyclerview/layout-managers/LinearLayoutManager.d.ts.map +1 -0
- package/dist/recyclerview/layout-managers/LinearLayoutManager.js +191 -0
- package/dist/recyclerview/layout-managers/LinearLayoutManager.js.map +1 -0
- package/dist/recyclerview/layout-managers/MasonryLayoutManager.d.ts +73 -0
- package/dist/recyclerview/layout-managers/MasonryLayoutManager.d.ts.map +1 -0
- package/dist/recyclerview/layout-managers/MasonryLayoutManager.js +274 -0
- package/dist/recyclerview/layout-managers/MasonryLayoutManager.js.map +1 -0
- package/dist/recyclerview/utils/adjustOffsetForRTL.d.ts +12 -0
- package/dist/recyclerview/utils/adjustOffsetForRTL.d.ts.map +1 -0
- package/dist/recyclerview/utils/adjustOffsetForRTL.js +18 -0
- package/dist/recyclerview/utils/adjustOffsetForRTL.js.map +1 -0
- package/dist/recyclerview/utils/componentUtils.d.ts +19 -0
- package/dist/recyclerview/utils/componentUtils.d.ts.map +1 -0
- package/dist/recyclerview/utils/componentUtils.js +32 -0
- package/dist/recyclerview/utils/componentUtils.js.map +1 -0
- package/dist/recyclerview/utils/findVisibleIndex.d.ts +24 -0
- package/dist/recyclerview/utils/findVisibleIndex.d.ts.map +1 -0
- package/dist/recyclerview/utils/findVisibleIndex.js +82 -0
- package/dist/recyclerview/utils/findVisibleIndex.js.map +1 -0
- package/dist/recyclerview/utils/measureLayout.d.ts +56 -0
- package/dist/recyclerview/utils/measureLayout.d.ts.map +1 -0
- package/dist/recyclerview/utils/measureLayout.js +77 -0
- package/dist/recyclerview/utils/measureLayout.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/AverageWindow.d.ts +13 -0
- package/dist/utils/AverageWindow.d.ts.map +1 -1
- package/dist/utils/AverageWindow.js +30 -1
- package/dist/utils/AverageWindow.js.map +1 -1
- package/package.json +1 -1
- package/src/FlashListProps.ts +73 -2
- package/src/__tests__/AverageWindow.test.ts +49 -1
- package/src/enableNewCore.ts +22 -0
- package/src/index.ts +21 -0
- package/src/recyclerview/RecycleKeyManager.ts +185 -0
- package/src/recyclerview/RecyclerView.tsx +500 -0
- package/src/recyclerview/RecyclerViewContextProvider.ts +19 -0
- package/src/recyclerview/RecyclerViewManager.ts +379 -0
- package/src/recyclerview/RecyclerViewProps.ts +10 -0
- package/src/recyclerview/ViewHolder.tsx +173 -0
- package/src/recyclerview/ViewHolderCollection.tsx +164 -0
- package/src/recyclerview/components/CompatScroller.ts +9 -0
- package/src/recyclerview/components/CompatView.ts +9 -0
- package/src/recyclerview/components/ScrollAnchor.tsx +53 -0
- package/src/recyclerview/components/StickyHeaders.tsx +210 -0
- package/src/recyclerview/helpers/ConsecutiveNumbers.ts +120 -0
- package/src/recyclerview/helpers/EngagedIndicesTracker.ts +191 -0
- package/src/recyclerview/hooks/useBoundDetection.ts +127 -0
- package/src/recyclerview/hooks/useLayoutState.ts +46 -0
- package/src/recyclerview/hooks/useOnLoad.ts +78 -0
- package/src/recyclerview/hooks/useRecyclerViewController.tsx +487 -0
- package/src/recyclerview/hooks/useRecyclerViewManager.ts +30 -0
- package/src/recyclerview/hooks/useRecyclingState.ts +63 -0
- package/src/recyclerview/hooks/useSecondaryProps.tsx +119 -0
- package/src/recyclerview/hooks/useUnmountFlag.ts +26 -0
- package/src/recyclerview/layout-managers/GridLayoutManager.ts +215 -0
- package/src/recyclerview/layout-managers/LayoutManager.ts +493 -0
- package/src/recyclerview/layout-managers/LinearLayoutManager.ts +167 -0
- package/src/recyclerview/layout-managers/MasonryLayoutManager.ts +302 -0
- package/src/recyclerview/utils/adjustOffsetForRTL.ts +17 -0
- package/src/recyclerview/utils/componentUtils.ts +28 -0
- package/src/recyclerview/utils/findVisibleIndex.ts +94 -0
- package/src/recyclerview/utils/measureLayout.ts +89 -0
- package/src/utils/AverageWindow.ts +33 -0
- package/src/viewability/ViewToken.ts +1 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useRef, useLayoutEffect } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hook that provides a way to track component unmounting state.
|
|
5
|
+
* This hook is particularly useful for preventing state updates or side effects
|
|
6
|
+
* after a component has unmounted, helping to avoid memory leaks and race conditions.
|
|
7
|
+
*
|
|
8
|
+
* @returns A ref containing a boolean flag that indicates whether the component is unmounted
|
|
9
|
+
* (true) or mounted (false)
|
|
10
|
+
*/
|
|
11
|
+
export const useUnmountFlag = () => {
|
|
12
|
+
// Create a ref to store the unmount state
|
|
13
|
+
// Using ref ensures the value persists between renders without causing re-renders
|
|
14
|
+
const isUnmounted = useRef(false);
|
|
15
|
+
|
|
16
|
+
// Use layoutEffect to set up cleanup on unmount
|
|
17
|
+
// This ensures the flag is set before any other cleanup effects run
|
|
18
|
+
useLayoutEffect(() => {
|
|
19
|
+
// Cleanup function that runs when the component unmounts
|
|
20
|
+
return () => {
|
|
21
|
+
isUnmounted.current = true;
|
|
22
|
+
};
|
|
23
|
+
}, []);
|
|
24
|
+
|
|
25
|
+
return isUnmounted;
|
|
26
|
+
};
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LayoutParams,
|
|
3
|
+
RVDimension,
|
|
4
|
+
RVLayout,
|
|
5
|
+
RVLayoutInfo,
|
|
6
|
+
RVLayoutManager,
|
|
7
|
+
} from "./LayoutManager";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* GridLayoutManager implementation that arranges items in a grid pattern.
|
|
11
|
+
* Items are placed in rows and columns, with support for items spanning multiple columns.
|
|
12
|
+
*/
|
|
13
|
+
export class RVGridLayoutManagerImpl extends RVLayoutManager {
|
|
14
|
+
/** The width of the bounded area for the grid */
|
|
15
|
+
private boundedSize: number;
|
|
16
|
+
|
|
17
|
+
constructor(params: LayoutParams, previousLayoutManager?: RVLayoutManager) {
|
|
18
|
+
super(params, previousLayoutManager);
|
|
19
|
+
this.boundedSize = params.windowSize.width;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Updates layout parameters and triggers recomputation if necessary.
|
|
24
|
+
* @param params New layout parameters
|
|
25
|
+
*/
|
|
26
|
+
updateLayoutParams(params: LayoutParams): void {
|
|
27
|
+
const prevNumColumns = this.maxColumns;
|
|
28
|
+
super.updateLayoutParams(params);
|
|
29
|
+
if (
|
|
30
|
+
this.boundedSize !== params.windowSize.width ||
|
|
31
|
+
prevNumColumns !== params.maxColumns
|
|
32
|
+
) {
|
|
33
|
+
this.boundedSize = params.windowSize.width;
|
|
34
|
+
if (this.layouts.length > 0) {
|
|
35
|
+
//update all widths
|
|
36
|
+
for (let i = 0; i < this.layouts.length; i++) {
|
|
37
|
+
this.layouts[i].width = this.getWidth(i);
|
|
38
|
+
}
|
|
39
|
+
//console.log("-----> recomputeLayouts");
|
|
40
|
+
|
|
41
|
+
this.recomputeLayouts(0, this.layouts.length - 1);
|
|
42
|
+
this.requiresRepaint = true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Processes layout information for items, updating their dimensions.
|
|
49
|
+
* @param layoutInfo Array of layout information for items
|
|
50
|
+
* @param itemCount Total number of items in the list
|
|
51
|
+
*/
|
|
52
|
+
processLayoutInfo(layoutInfo: RVLayoutInfo[], itemCount: number) {
|
|
53
|
+
for (const info of layoutInfo) {
|
|
54
|
+
const { index, dimensions } = info;
|
|
55
|
+
const layout = this.layouts[index];
|
|
56
|
+
layout.height = dimensions.height;
|
|
57
|
+
layout.isHeightMeasured = true;
|
|
58
|
+
layout.isWidthMeasured = true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Estimates layout dimensions for an item at the given index.
|
|
64
|
+
* @param index Index of the item to estimate layout for
|
|
65
|
+
*/
|
|
66
|
+
estimateLayout(index: number) {
|
|
67
|
+
const layout = this.layouts[index];
|
|
68
|
+
layout.width = this.getWidth(index);
|
|
69
|
+
layout.height = this.getEstimatedHeight(index);
|
|
70
|
+
|
|
71
|
+
layout.isWidthMeasured = true;
|
|
72
|
+
layout.enforcedWidth = true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Returns the total size of the layout area.
|
|
77
|
+
* @returns RVDimension containing width and height of the layout
|
|
78
|
+
*/
|
|
79
|
+
getLayoutSize(): RVDimension {
|
|
80
|
+
if (this.layouts.length === 0) return { width: 0, height: 0 };
|
|
81
|
+
const lastRowTallestItem = this.processAndReturnTallestItemInRow(
|
|
82
|
+
this.layouts.length - 1
|
|
83
|
+
);
|
|
84
|
+
return {
|
|
85
|
+
width: this.boundedSize,
|
|
86
|
+
height: lastRowTallestItem.y + lastRowTallestItem.height,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Recomputes layouts for items in the given range.
|
|
92
|
+
* @param startIndex Starting index of items to recompute
|
|
93
|
+
* @param endIndex Ending index of items to recompute
|
|
94
|
+
*/
|
|
95
|
+
recomputeLayouts(startIndex: number, endIndex: number): void {
|
|
96
|
+
const newStartIndex = this.locateFirstNeighbourIndex(startIndex);
|
|
97
|
+
const startVal = this.getLayout(newStartIndex);
|
|
98
|
+
|
|
99
|
+
let startX = startVal.x;
|
|
100
|
+
let startY = startVal.y;
|
|
101
|
+
|
|
102
|
+
for (let i = newStartIndex; i <= endIndex; i++) {
|
|
103
|
+
const layout = this.getLayout(i);
|
|
104
|
+
if (!this.checkBounds(startX, layout.width)) {
|
|
105
|
+
const tallestItem = this.processAndReturnTallestItemInRow(i);
|
|
106
|
+
startY = tallestItem.y + tallestItem.height;
|
|
107
|
+
startX = 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
layout.x = startX;
|
|
111
|
+
layout.y = startY;
|
|
112
|
+
startX += layout.width;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Calculates the width of an item based on its span.
|
|
118
|
+
* @param index Index of the item
|
|
119
|
+
* @returns Width of the item
|
|
120
|
+
*/
|
|
121
|
+
private getWidth(index: number): number {
|
|
122
|
+
const span = this.getSpanSizeInfo(index).span ?? 1;
|
|
123
|
+
return (this.boundedSize / this.maxColumns) * span;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Processes items in a row and returns the tallest item.
|
|
128
|
+
* Also handles height normalization for items in the same row.
|
|
129
|
+
* Tallest item per row helps in forcing tallest items height on neighbouring items.
|
|
130
|
+
* @param index Index of the last item in the row
|
|
131
|
+
* @returns The tallest item in the row
|
|
132
|
+
*/
|
|
133
|
+
private processAndReturnTallestItemInRow(index: number): RVLayout {
|
|
134
|
+
const startIndex = this.locateFirstNeighbourIndex(index);
|
|
135
|
+
const y = this.layouts[startIndex].y;
|
|
136
|
+
let tallestItem: RVLayout | undefined;
|
|
137
|
+
let maxHeight = 0;
|
|
138
|
+
let i = startIndex;
|
|
139
|
+
let isMeasured = false;
|
|
140
|
+
// TODO: Manage precision problems
|
|
141
|
+
while (Math.ceil(this.layouts[i].y) === Math.ceil(y)) {
|
|
142
|
+
const layout = this.layouts[i];
|
|
143
|
+
isMeasured = isMeasured || Boolean(layout.isHeightMeasured);
|
|
144
|
+
maxHeight = Math.max(maxHeight, layout.height);
|
|
145
|
+
if (
|
|
146
|
+
layout.height > (layout.minHeight ?? 0) &&
|
|
147
|
+
layout.height > (tallestItem?.height ?? 0)
|
|
148
|
+
) {
|
|
149
|
+
tallestItem = layout;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
i++;
|
|
153
|
+
if (i >= this.layouts.length) {
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
tallestItem = tallestItem ?? this.layouts[startIndex];
|
|
159
|
+
|
|
160
|
+
if (!isMeasured) {
|
|
161
|
+
return tallestItem;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (tallestItem) {
|
|
165
|
+
let targetHeight = tallestItem.height;
|
|
166
|
+
if (maxHeight - tallestItem.height > 1) {
|
|
167
|
+
targetHeight = 0;
|
|
168
|
+
this.requiresRepaint = true;
|
|
169
|
+
}
|
|
170
|
+
i = startIndex;
|
|
171
|
+
// TODO: Manage precision problems
|
|
172
|
+
while (Math.ceil(this.layouts[i].y) === Math.ceil(y)) {
|
|
173
|
+
this.layouts[i].minHeight = targetHeight;
|
|
174
|
+
if (targetHeight > 0) {
|
|
175
|
+
this.layouts[i].height = targetHeight;
|
|
176
|
+
}
|
|
177
|
+
i++;
|
|
178
|
+
if (i >= this.layouts.length) {
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
tallestItem.minHeight = 0;
|
|
183
|
+
}
|
|
184
|
+
return tallestItem;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Checks if an item can fit within the bounded width.
|
|
189
|
+
* @param itemX Starting X position of the item
|
|
190
|
+
* @param width Width of the item
|
|
191
|
+
* @returns True if the item fits within bounds
|
|
192
|
+
*/
|
|
193
|
+
private checkBounds(itemX: number, width: number): boolean {
|
|
194
|
+
// TODO: Manage precision problems
|
|
195
|
+
return itemX + width <= this.boundedSize + 0.9;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Locates the index of the first item in the current row.
|
|
200
|
+
* @param startIndex Index to start searching from
|
|
201
|
+
* @returns Index of the first item in the row
|
|
202
|
+
*/
|
|
203
|
+
private locateFirstNeighbourIndex(startIndex: number): number {
|
|
204
|
+
if (startIndex === 0) {
|
|
205
|
+
return 0;
|
|
206
|
+
}
|
|
207
|
+
let i = startIndex - 1;
|
|
208
|
+
for (; i >= 0; i--) {
|
|
209
|
+
if (this.layouts[i].x === 0) {
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return Math.max(i, 0);
|
|
214
|
+
}
|
|
215
|
+
}
|