@legendapp/list 0.3.1 → 0.3.3
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 +6 -2
- package/index.d.mts +3 -2
- package/index.d.ts +3 -2
- package/index.js +242 -212
- package/index.mjs +229 -199
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React6 = require('react');
|
|
4
4
|
var reactNative = require('react-native');
|
|
5
5
|
|
|
6
6
|
function _interopNamespace(e) {
|
|
@@ -21,40 +21,37 @@ function _interopNamespace(e) {
|
|
|
21
21
|
return Object.freeze(n);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
var
|
|
24
|
+
var React6__namespace = /*#__PURE__*/_interopNamespace(React6);
|
|
25
25
|
|
|
26
26
|
// src/LegendList.tsx
|
|
27
|
-
var LeanView =
|
|
28
|
-
return
|
|
27
|
+
var LeanView = React6__namespace.forwardRef((props, ref) => {
|
|
28
|
+
return React6__namespace.createElement("RCTView", { ...props, ref });
|
|
29
29
|
});
|
|
30
30
|
LeanView.displayName = "RCTView";
|
|
31
|
-
var ContextListener =
|
|
31
|
+
var ContextListener = React6__namespace.createContext(null);
|
|
32
32
|
function StateProvider({ children }) {
|
|
33
|
-
const [value] =
|
|
33
|
+
const [value] = React6__namespace.useState(() => ({
|
|
34
34
|
listeners: /* @__PURE__ */ new Map(),
|
|
35
35
|
values: /* @__PURE__ */ new Map()
|
|
36
36
|
}));
|
|
37
|
-
return /* @__PURE__ */
|
|
37
|
+
return /* @__PURE__ */ React6__namespace.createElement(ContextListener.Provider, { value }, children);
|
|
38
38
|
}
|
|
39
39
|
function useStateContext() {
|
|
40
|
-
return
|
|
40
|
+
return React6__namespace.useContext(ContextListener);
|
|
41
41
|
}
|
|
42
42
|
function use$(signalName) {
|
|
43
|
-
const { listeners, values } =
|
|
44
|
-
const [
|
|
45
|
-
|
|
46
|
-
const render = () => setState((prev) => prev > 1e4 ? 0 : prev + 1);
|
|
47
|
-
listeners.set(signalName, render);
|
|
48
|
-
}, []);
|
|
43
|
+
const { listeners, values } = React6__namespace.useContext(ContextListener);
|
|
44
|
+
const [, forceUpdate] = React6__namespace.useReducer((x) => x + 1, 0);
|
|
45
|
+
listeners.set(signalName, forceUpdate);
|
|
49
46
|
return values.get(signalName);
|
|
50
47
|
}
|
|
51
|
-
function peek$(
|
|
52
|
-
const { values } = ctx
|
|
48
|
+
function peek$(ctx, signalName) {
|
|
49
|
+
const { values } = ctx;
|
|
53
50
|
return values.get(signalName);
|
|
54
51
|
}
|
|
55
|
-
function set$(
|
|
52
|
+
function set$(ctx, signalName, value) {
|
|
56
53
|
var _a;
|
|
57
|
-
const { listeners, values } = ctx
|
|
54
|
+
const { listeners, values } = ctx;
|
|
58
55
|
if (values.get(signalName) !== value) {
|
|
59
56
|
values.set(signalName, value);
|
|
60
57
|
(_a = listeners.get(signalName)) == null ? void 0 : _a();
|
|
@@ -65,7 +62,7 @@ function set$(signalName, ctx, value) {
|
|
|
65
62
|
function $View({ $key, $style, ...rest }) {
|
|
66
63
|
use$($key);
|
|
67
64
|
const style = $style();
|
|
68
|
-
return /* @__PURE__ */
|
|
65
|
+
return /* @__PURE__ */ React6__namespace.createElement(LeanView, { style, ...rest });
|
|
69
66
|
}
|
|
70
67
|
function InnerContainer({ id, getRenderedItem, recycleItems, ItemSeparatorComponent }) {
|
|
71
68
|
const itemIndex = use$(`containerIndex${id}`);
|
|
@@ -74,7 +71,7 @@ function InnerContainer({ id, getRenderedItem, recycleItems, ItemSeparatorCompon
|
|
|
74
71
|
return null;
|
|
75
72
|
}
|
|
76
73
|
const renderedItem = getRenderedItem(itemIndex);
|
|
77
|
-
return /* @__PURE__ */
|
|
74
|
+
return /* @__PURE__ */ React6__namespace.createElement(React6__namespace.Fragment, { key: recycleItems ? void 0 : itemIndex }, renderedItem, ItemSeparatorComponent && itemIndex < numItems - 1 && ItemSeparatorComponent);
|
|
78
75
|
}
|
|
79
76
|
var Container = ({
|
|
80
77
|
id,
|
|
@@ -86,7 +83,7 @@ var Container = ({
|
|
|
86
83
|
}) => {
|
|
87
84
|
const ctx = useStateContext();
|
|
88
85
|
const createStyle = () => {
|
|
89
|
-
const position = peek$(`containerPosition${id}
|
|
86
|
+
const position = peek$(ctx, `containerPosition${id}`);
|
|
90
87
|
return horizontal ? {
|
|
91
88
|
flexDirection: "row",
|
|
92
89
|
position: "absolute",
|
|
@@ -102,20 +99,20 @@ var Container = ({
|
|
|
102
99
|
opacity: position < 0 ? 0 : 1
|
|
103
100
|
};
|
|
104
101
|
};
|
|
105
|
-
return /* @__PURE__ */
|
|
102
|
+
return /* @__PURE__ */ React6__namespace.createElement(
|
|
106
103
|
$View,
|
|
107
104
|
{
|
|
108
105
|
$key: `containerPosition${id}`,
|
|
109
106
|
$style: createStyle,
|
|
110
107
|
onLayout: (event) => {
|
|
111
|
-
const index = peek$(`containerIndex${id}
|
|
108
|
+
const index = peek$(ctx, `containerIndex${id}`);
|
|
112
109
|
if (index >= 0) {
|
|
113
110
|
const length = Math.round(event.nativeEvent.layout[horizontal ? "width" : "height"]);
|
|
114
111
|
onLayout(index, length);
|
|
115
112
|
}
|
|
116
113
|
}
|
|
117
114
|
},
|
|
118
|
-
/* @__PURE__ */
|
|
115
|
+
/* @__PURE__ */ React6__namespace.createElement(
|
|
119
116
|
InnerContainer,
|
|
120
117
|
{
|
|
121
118
|
id,
|
|
@@ -128,11 +125,11 @@ var Container = ({
|
|
|
128
125
|
};
|
|
129
126
|
|
|
130
127
|
// src/Containers.tsx
|
|
131
|
-
var Containers =
|
|
128
|
+
var Containers = React6__namespace.memo(function Containers2({
|
|
132
129
|
horizontal,
|
|
133
130
|
recycleItems,
|
|
134
131
|
ItemSeparatorComponent,
|
|
135
|
-
|
|
132
|
+
updateItemSize,
|
|
136
133
|
getRenderedItem
|
|
137
134
|
}) {
|
|
138
135
|
const ctx = useStateContext();
|
|
@@ -140,7 +137,7 @@ var Containers = React2__namespace.memo(function Containers2({
|
|
|
140
137
|
const containers = [];
|
|
141
138
|
for (let i = 0; i < numContainers; i++) {
|
|
142
139
|
containers.push(
|
|
143
|
-
/* @__PURE__ */
|
|
140
|
+
/* @__PURE__ */ React6__namespace.createElement(
|
|
144
141
|
Container,
|
|
145
142
|
{
|
|
146
143
|
id: i,
|
|
@@ -148,20 +145,20 @@ var Containers = React2__namespace.memo(function Containers2({
|
|
|
148
145
|
recycleItems,
|
|
149
146
|
horizontal,
|
|
150
147
|
getRenderedItem,
|
|
151
|
-
onLayout:
|
|
148
|
+
onLayout: updateItemSize,
|
|
152
149
|
ItemSeparatorComponent
|
|
153
150
|
}
|
|
154
151
|
)
|
|
155
152
|
);
|
|
156
153
|
}
|
|
157
|
-
return /* @__PURE__ */
|
|
154
|
+
return /* @__PURE__ */ React6__namespace.createElement(
|
|
158
155
|
$View,
|
|
159
156
|
{
|
|
160
157
|
$key: "totalLength",
|
|
161
158
|
$style: () => horizontal ? {
|
|
162
|
-
width: peek$("totalLength"
|
|
159
|
+
width: peek$(ctx, "totalLength")
|
|
163
160
|
} : {
|
|
164
|
-
height: peek$("totalLength"
|
|
161
|
+
height: peek$(ctx, "totalLength")
|
|
165
162
|
}
|
|
166
163
|
},
|
|
167
164
|
containers
|
|
@@ -170,15 +167,15 @@ var Containers = React2__namespace.memo(function Containers2({
|
|
|
170
167
|
|
|
171
168
|
// src/ListComponent.tsx
|
|
172
169
|
var getComponent = (Component) => {
|
|
173
|
-
if (
|
|
170
|
+
if (React6__namespace.isValidElement(Component)) {
|
|
174
171
|
return Component;
|
|
175
172
|
}
|
|
176
173
|
if (Component) {
|
|
177
|
-
return /* @__PURE__ */
|
|
174
|
+
return /* @__PURE__ */ React6__namespace.createElement(Component, null);
|
|
178
175
|
}
|
|
179
176
|
return null;
|
|
180
177
|
};
|
|
181
|
-
var ListComponent =
|
|
178
|
+
var ListComponent = React6__namespace.memo(function ListComponent2({
|
|
182
179
|
style,
|
|
183
180
|
contentContainerStyle,
|
|
184
181
|
horizontal,
|
|
@@ -193,12 +190,12 @@ var ListComponent = React2__namespace.memo(function ListComponent2({
|
|
|
193
190
|
ListFooterComponent,
|
|
194
191
|
ListFooterComponentStyle,
|
|
195
192
|
getRenderedItem,
|
|
196
|
-
|
|
193
|
+
updateItemSize,
|
|
197
194
|
refScroller,
|
|
198
195
|
...rest
|
|
199
196
|
}) {
|
|
200
197
|
const ctx = useStateContext();
|
|
201
|
-
return /* @__PURE__ */
|
|
198
|
+
return /* @__PURE__ */ React6__namespace.createElement(
|
|
202
199
|
reactNative.ScrollView,
|
|
203
200
|
{
|
|
204
201
|
...rest,
|
|
@@ -211,35 +208,35 @@ var ListComponent = React2__namespace.memo(function ListComponent2({
|
|
|
211
208
|
],
|
|
212
209
|
onScroll: handleScroll,
|
|
213
210
|
onLayout,
|
|
214
|
-
scrollEventThrottle: 32,
|
|
215
211
|
horizontal,
|
|
216
212
|
contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
|
|
217
213
|
ref: refScroller
|
|
218
214
|
},
|
|
219
|
-
alignItemsAtEnd && /* @__PURE__ */
|
|
220
|
-
ListHeaderComponent && /* @__PURE__ */
|
|
221
|
-
/* @__PURE__ */
|
|
215
|
+
alignItemsAtEnd && /* @__PURE__ */ React6__namespace.createElement($View, { $key: "paddingTop", $style: () => ({ height: peek$(ctx, "paddingTop") }) }),
|
|
216
|
+
ListHeaderComponent && /* @__PURE__ */ React6__namespace.createElement(reactNative.View, { style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
|
|
217
|
+
/* @__PURE__ */ React6__namespace.createElement(
|
|
222
218
|
Containers,
|
|
223
219
|
{
|
|
224
220
|
horizontal,
|
|
225
221
|
recycleItems,
|
|
226
222
|
getRenderedItem,
|
|
227
223
|
ItemSeparatorComponent: ItemSeparatorComponent && getComponent(ItemSeparatorComponent),
|
|
228
|
-
|
|
224
|
+
updateItemSize
|
|
229
225
|
}
|
|
230
226
|
),
|
|
231
|
-
ListFooterComponent && /* @__PURE__ */
|
|
227
|
+
ListFooterComponent && /* @__PURE__ */ React6__namespace.createElement(reactNative.View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
|
|
232
228
|
);
|
|
233
229
|
});
|
|
234
230
|
|
|
235
231
|
// src/LegendList.tsx
|
|
236
232
|
var DEFAULT_SCROLL_BUFFER = 0;
|
|
237
233
|
var POSITION_OUT_OF_VIEW = -1e4;
|
|
238
|
-
var LegendList =
|
|
239
|
-
return /* @__PURE__ */
|
|
234
|
+
var LegendList = React6.forwardRef(function LegendList2(props, forwardedRef) {
|
|
235
|
+
return /* @__PURE__ */ React6__namespace.createElement(StateProvider, null, /* @__PURE__ */ React6__namespace.createElement(LegendListInner, { ...props, ref: forwardedRef }));
|
|
240
236
|
});
|
|
241
|
-
var LegendListInner =
|
|
237
|
+
var LegendListInner = React6.forwardRef(
|
|
242
238
|
function LegendListInner2(props, forwardedRef) {
|
|
239
|
+
var _a, _b;
|
|
243
240
|
const {
|
|
244
241
|
data,
|
|
245
242
|
initialScrollIndex,
|
|
@@ -247,7 +244,7 @@ var LegendListInner = React2.forwardRef(
|
|
|
247
244
|
horizontal,
|
|
248
245
|
style: styleProp,
|
|
249
246
|
contentContainerStyle: contentContainerStyleProp,
|
|
250
|
-
|
|
247
|
+
initialNumContainers,
|
|
251
248
|
drawDistance,
|
|
252
249
|
recycleItems = true,
|
|
253
250
|
onEndReachedThreshold = 0.5,
|
|
@@ -257,38 +254,58 @@ var LegendListInner = React2.forwardRef(
|
|
|
257
254
|
onScroll: onScrollProp,
|
|
258
255
|
keyExtractor,
|
|
259
256
|
renderItem,
|
|
260
|
-
|
|
257
|
+
estimatedItemSize,
|
|
258
|
+
getEstimatedItemSize,
|
|
261
259
|
onEndReached,
|
|
262
260
|
onViewableRangeChanged,
|
|
263
261
|
...rest
|
|
264
262
|
} = props;
|
|
265
263
|
const ctx = useStateContext();
|
|
266
|
-
const internalRef =
|
|
264
|
+
const internalRef = React6.useRef(null);
|
|
267
265
|
const refScroller = forwardedRef || internalRef;
|
|
268
266
|
const scrollBuffer = drawDistance != null ? drawDistance : DEFAULT_SCROLL_BUFFER;
|
|
269
267
|
const styleFlattened = reactNative.StyleSheet.flatten(styleProp);
|
|
270
|
-
const style =
|
|
268
|
+
const style = React6.useMemo(() => styleFlattened, [JSON.stringify(styleProp)]);
|
|
271
269
|
const contentContainerStyleFlattened = reactNative.StyleSheet.flatten(contentContainerStyleProp);
|
|
272
|
-
const contentContainerStyle =
|
|
270
|
+
const contentContainerStyle = React6.useMemo(
|
|
273
271
|
() => contentContainerStyleFlattened,
|
|
274
272
|
[JSON.stringify(contentContainerStyleProp)]
|
|
275
273
|
);
|
|
276
|
-
const refState =
|
|
274
|
+
const refState = React6.useRef();
|
|
277
275
|
const getId = (index) => {
|
|
278
|
-
var
|
|
279
|
-
const data2 = (
|
|
276
|
+
var _a2;
|
|
277
|
+
const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
|
|
280
278
|
if (!data2) {
|
|
281
279
|
return "";
|
|
282
280
|
}
|
|
283
281
|
const ret = index < data2.length ? keyExtractor ? keyExtractor(data2[index], index) : index : null;
|
|
284
282
|
return ret + "";
|
|
285
283
|
};
|
|
284
|
+
const getItemLength = (index, data2) => {
|
|
285
|
+
return getEstimatedItemSize ? getEstimatedItemSize(index, data2) : estimatedItemSize;
|
|
286
|
+
};
|
|
287
|
+
const calculateInitialOffset = () => {
|
|
288
|
+
if (initialScrollIndex) {
|
|
289
|
+
if (getEstimatedItemSize) {
|
|
290
|
+
let offset = 0;
|
|
291
|
+
for (let i = 0; i < initialScrollIndex; i++) {
|
|
292
|
+
offset += getEstimatedItemSize(i, data[i]);
|
|
293
|
+
}
|
|
294
|
+
return offset;
|
|
295
|
+
} else if (estimatedItemSize) {
|
|
296
|
+
return initialScrollIndex * estimatedItemSize;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return void 0;
|
|
300
|
+
};
|
|
301
|
+
const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : React6.useMemo(calculateInitialOffset, [initialScrollIndex, estimatedItemSize]);
|
|
286
302
|
if (!refState.current) {
|
|
287
303
|
refState.current = {
|
|
288
304
|
lengths: /* @__PURE__ */ new Map(),
|
|
289
305
|
positions: /* @__PURE__ */ new Map(),
|
|
290
306
|
pendingAdjust: 0,
|
|
291
|
-
|
|
307
|
+
animFrameScroll: null,
|
|
308
|
+
animFrameLayout: null,
|
|
292
309
|
isStartReached: false,
|
|
293
310
|
isEndReached: false,
|
|
294
311
|
isAtBottom: false,
|
|
@@ -300,35 +317,36 @@ var LegendListInner = React2.forwardRef(
|
|
|
300
317
|
startNoBuffer: 0,
|
|
301
318
|
endBuffered: 0,
|
|
302
319
|
endNoBuffer: 0,
|
|
303
|
-
scroll: 0
|
|
304
|
-
topPad: 0
|
|
320
|
+
scroll: initialContentOffset || 0
|
|
305
321
|
};
|
|
306
322
|
refState.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
|
|
307
323
|
}
|
|
308
324
|
refState.current.data = data;
|
|
309
|
-
set$(`numItems`,
|
|
310
|
-
|
|
311
|
-
const
|
|
312
|
-
|
|
325
|
+
set$(ctx, `numItems`, data.length);
|
|
326
|
+
set$(ctx, `stylePaddingTop`, (_b = (_a = styleFlattened == null ? void 0 : styleFlattened.paddingTop) != null ? _a : contentContainerStyleFlattened == null ? void 0 : contentContainerStyleFlattened.paddingTop) != null ? _b : 0);
|
|
327
|
+
const addTotalSize = (add) => {
|
|
328
|
+
const length = (peek$(ctx, `totalLength`) || 0) + add;
|
|
329
|
+
set$(ctx, `totalLength`, length);
|
|
313
330
|
const screenLength = refState.current.scrollLength;
|
|
314
331
|
if (alignItemsAtEnd) {
|
|
315
|
-
const listPaddingTop = (
|
|
316
|
-
set$(`paddingTop`,
|
|
332
|
+
const listPaddingTop = peek$(ctx, `stylePaddingTop`);
|
|
333
|
+
set$(ctx, `paddingTop`, Math.max(0, screenLength - length - listPaddingTop));
|
|
317
334
|
}
|
|
318
335
|
};
|
|
319
|
-
const allocateContainers =
|
|
336
|
+
const allocateContainers = React6.useCallback(() => {
|
|
320
337
|
const scrollLength = refState.current.scrollLength;
|
|
321
|
-
const
|
|
338
|
+
const averageItemSize = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, data[0]);
|
|
339
|
+
const numContainers = initialNumContainers || Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize) + 4;
|
|
322
340
|
for (let i = 0; i < numContainers; i++) {
|
|
323
|
-
set$(`containerIndex${i}`,
|
|
324
|
-
set$(`containerPosition${i}`,
|
|
341
|
+
set$(ctx, `containerIndex${i}`, -1);
|
|
342
|
+
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
325
343
|
}
|
|
326
|
-
set$(`numContainers`,
|
|
344
|
+
set$(ctx, `numContainers`, numContainers);
|
|
327
345
|
}, []);
|
|
328
|
-
const getRenderedItem =
|
|
346
|
+
const getRenderedItem = React6.useCallback(
|
|
329
347
|
(index) => {
|
|
330
|
-
var
|
|
331
|
-
const data2 = (
|
|
348
|
+
var _a2;
|
|
349
|
+
const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
|
|
332
350
|
if (!data2) {
|
|
333
351
|
return null;
|
|
334
352
|
}
|
|
@@ -340,147 +358,165 @@ var LegendListInner = React2.forwardRef(
|
|
|
340
358
|
},
|
|
341
359
|
[renderItem]
|
|
342
360
|
);
|
|
343
|
-
const calculateItemsInView =
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
}
|
|
358
|
-
const scroll = scrollState - topPad;
|
|
359
|
-
const { lengths, positions } = refState.current;
|
|
360
|
-
let top = 0;
|
|
361
|
-
let startNoBuffer = null;
|
|
362
|
-
let startBuffered = null;
|
|
363
|
-
let endNoBuffer = null;
|
|
364
|
-
let endBuffered = null;
|
|
365
|
-
for (let i = 0; i < data2.length; i++) {
|
|
366
|
-
const id = getId(i);
|
|
367
|
-
const length = (_a = lengths.get(id)) != null ? _a : estimatedItemLength(i);
|
|
368
|
-
if (positions.get(id) !== top) {
|
|
369
|
-
positions.set(id, top);
|
|
370
|
-
}
|
|
371
|
-
if (startNoBuffer === null && top + length > scroll) {
|
|
372
|
-
startNoBuffer = i;
|
|
361
|
+
const calculateItemsInView = React6.useCallback(() => {
|
|
362
|
+
reactNative.unstable_batchedUpdates(() => {
|
|
363
|
+
var _a2, _b2, _c;
|
|
364
|
+
const {
|
|
365
|
+
data: data2,
|
|
366
|
+
scrollLength,
|
|
367
|
+
scroll: scrollState,
|
|
368
|
+
startNoBuffer: startNoBufferState,
|
|
369
|
+
startBuffered: startBufferedState,
|
|
370
|
+
endNoBuffer: endNoBufferState,
|
|
371
|
+
endBuffered: endBufferedState
|
|
372
|
+
} = refState.current;
|
|
373
|
+
if (!data2) {
|
|
374
|
+
return;
|
|
373
375
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
+
const topPad = (peek$(ctx, `stylePaddingTop`) || 0) + (peek$(ctx, `headerSize`) || 0);
|
|
377
|
+
const scroll = scrollState - topPad;
|
|
378
|
+
const { lengths, positions } = refState.current;
|
|
379
|
+
let startNoBuffer = null;
|
|
380
|
+
let startBuffered = null;
|
|
381
|
+
let endNoBuffer = null;
|
|
382
|
+
let endBuffered = null;
|
|
383
|
+
let loopStart = startBufferedState || 0;
|
|
384
|
+
if (startBufferedState) {
|
|
385
|
+
for (let i = startBufferedState; i >= 0; i--) {
|
|
386
|
+
const id = getId(i);
|
|
387
|
+
const top2 = positions.get(id);
|
|
388
|
+
if (top2 !== void 0) {
|
|
389
|
+
const length = (_a2 = lengths.get(id)) != null ? _a2 : getItemLength(i, data2[i]);
|
|
390
|
+
const bottom = top2 + length;
|
|
391
|
+
if (bottom > scroll - scrollBuffer) {
|
|
392
|
+
loopStart = i;
|
|
393
|
+
} else {
|
|
394
|
+
break;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
376
398
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
399
|
+
let top = loopStart > 0 ? positions.get(getId(loopStart)) : 0;
|
|
400
|
+
for (let i = loopStart; i < data2.length; i++) {
|
|
401
|
+
const id = getId(i);
|
|
402
|
+
const length = (_b2 = lengths.get(id)) != null ? _b2 : getItemLength(i, data2[i]);
|
|
403
|
+
if (positions.get(id) !== top) {
|
|
404
|
+
positions.set(id, top);
|
|
380
405
|
}
|
|
381
|
-
if (
|
|
382
|
-
|
|
383
|
-
} else {
|
|
384
|
-
break;
|
|
406
|
+
if (startNoBuffer === null && top + length > scroll) {
|
|
407
|
+
startNoBuffer = i;
|
|
385
408
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
const prevNumContainers = ctx.values.get("numContainers");
|
|
397
|
-
let numContainers = prevNumContainers;
|
|
398
|
-
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
399
|
-
let isContained = false;
|
|
400
|
-
for (let j = 0; j < numContainers; j++) {
|
|
401
|
-
const index = peek$(`containerIndex${j}`, ctx);
|
|
402
|
-
if (index === i) {
|
|
403
|
-
isContained = true;
|
|
409
|
+
if (startBuffered === null && top + length > scroll - scrollBuffer) {
|
|
410
|
+
startBuffered = i;
|
|
411
|
+
}
|
|
412
|
+
if (startNoBuffer !== null) {
|
|
413
|
+
if (top <= scroll + scrollLength) {
|
|
414
|
+
endNoBuffer = i;
|
|
415
|
+
}
|
|
416
|
+
if (top <= scroll + scrollLength + scrollBuffer) {
|
|
417
|
+
endBuffered = i;
|
|
418
|
+
} else {
|
|
404
419
|
break;
|
|
405
420
|
}
|
|
406
421
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
422
|
+
top += length;
|
|
423
|
+
}
|
|
424
|
+
Object.assign(refState.current, {
|
|
425
|
+
startBuffered,
|
|
426
|
+
startNoBuffer,
|
|
427
|
+
endBuffered,
|
|
428
|
+
endNoBuffer
|
|
429
|
+
});
|
|
430
|
+
if (startBuffered !== null && endBuffered !== null) {
|
|
431
|
+
const prevNumContainers = ctx.values.get("numContainers");
|
|
432
|
+
let numContainers = prevNumContainers;
|
|
433
|
+
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
434
|
+
let isContained = false;
|
|
435
|
+
for (let j = 0; j < numContainers; j++) {
|
|
436
|
+
const index = peek$(ctx, `containerIndex${j}`);
|
|
437
|
+
if (index === i) {
|
|
438
|
+
isContained = true;
|
|
414
439
|
break;
|
|
415
440
|
}
|
|
416
441
|
}
|
|
417
|
-
if (!
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
442
|
+
if (!isContained) {
|
|
443
|
+
let didRecycle = false;
|
|
444
|
+
for (let u = 0; u < numContainers; u++) {
|
|
445
|
+
const index = peek$(ctx, `containerIndex${u}`);
|
|
446
|
+
if (index < startBuffered || index > endBuffered) {
|
|
447
|
+
set$(ctx, `containerIndex${u}`, i);
|
|
448
|
+
didRecycle = true;
|
|
449
|
+
break;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
if (!didRecycle) {
|
|
453
|
+
if (__DEV__) {
|
|
454
|
+
console.warn(
|
|
455
|
+
"[legend-list] No container to recycle, consider increasing initialContainers or estimatedItemSize",
|
|
456
|
+
i
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
const id = numContainers;
|
|
460
|
+
numContainers++;
|
|
461
|
+
set$(ctx, `containerIndex${id}`, i);
|
|
462
|
+
set$(ctx, `containerPosition${id}`, POSITION_OUT_OF_VIEW);
|
|
423
463
|
}
|
|
424
|
-
const id = numContainers;
|
|
425
|
-
numContainers++;
|
|
426
|
-
set$(`containerIndex${id}`, ctx, i);
|
|
427
|
-
set$(`containerPosition${id}`, ctx, POSITION_OUT_OF_VIEW);
|
|
428
464
|
}
|
|
429
465
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
466
|
+
if (numContainers !== prevNumContainers) {
|
|
467
|
+
set$(ctx, `numContainers`, numContainers);
|
|
468
|
+
}
|
|
469
|
+
for (let i = 0; i < numContainers; i++) {
|
|
470
|
+
const itemIndex = peek$(ctx, `containerIndex${i}`);
|
|
471
|
+
const item = data2[itemIndex];
|
|
472
|
+
if (item) {
|
|
473
|
+
const id = getId(itemIndex);
|
|
474
|
+
if (itemIndex < startBuffered || itemIndex > endBuffered) {
|
|
475
|
+
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
476
|
+
} else {
|
|
477
|
+
const pos = (_c = positions.get(id)) != null ? _c : -1;
|
|
478
|
+
const prevPos = peek$(ctx, `containerPosition${i}`);
|
|
479
|
+
if (pos >= 0 && pos !== prevPos) {
|
|
480
|
+
set$(ctx, `containerPosition${i}`, pos);
|
|
481
|
+
}
|
|
446
482
|
}
|
|
447
483
|
}
|
|
448
484
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
}
|
|
485
|
+
if (onViewableRangeChanged) {
|
|
486
|
+
if (startNoBuffer !== startNoBufferState || startBuffered !== startBufferedState || endNoBuffer !== endNoBufferState || endBuffered !== endBufferedState) {
|
|
487
|
+
onViewableRangeChanged({
|
|
488
|
+
start: startNoBuffer,
|
|
489
|
+
startBuffered,
|
|
490
|
+
end: endNoBuffer,
|
|
491
|
+
endBuffered,
|
|
492
|
+
items: data2.slice(startNoBuffer, endNoBuffer + 1)
|
|
493
|
+
});
|
|
494
|
+
}
|
|
459
495
|
}
|
|
460
496
|
}
|
|
461
|
-
}
|
|
497
|
+
});
|
|
462
498
|
}, [data]);
|
|
463
|
-
|
|
464
|
-
var
|
|
499
|
+
React6.useMemo(() => {
|
|
500
|
+
var _a2, _b2;
|
|
465
501
|
allocateContainers();
|
|
466
502
|
calculateItemsInView();
|
|
467
|
-
const lengths = (
|
|
503
|
+
const lengths = (_a2 = refState.current) == null ? void 0 : _a2.lengths;
|
|
468
504
|
let totalLength = 0;
|
|
469
505
|
for (let i = 0; i < data.length; i++) {
|
|
470
506
|
const id = getId(i);
|
|
471
|
-
totalLength += (
|
|
507
|
+
totalLength += (_b2 = lengths.get(id)) != null ? _b2 : getItemLength(i, data[i]);
|
|
472
508
|
}
|
|
473
|
-
|
|
509
|
+
addTotalSize(totalLength);
|
|
474
510
|
}, []);
|
|
475
511
|
const checkAtBottom = () => {
|
|
476
|
-
var
|
|
512
|
+
var _a2;
|
|
477
513
|
const { scrollLength, scroll } = refState.current;
|
|
478
|
-
const totalLength = peek$("totalLength"
|
|
514
|
+
const totalLength = peek$(ctx, "totalLength");
|
|
479
515
|
const distanceFromEnd = totalLength - scroll - scrollLength;
|
|
480
516
|
if (refState.current) {
|
|
481
517
|
refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
482
518
|
}
|
|
483
|
-
if (onEndReached && !((
|
|
519
|
+
if (onEndReached && !((_a2 = refState.current) == null ? void 0 : _a2.isEndReached)) {
|
|
484
520
|
if (distanceFromEnd < onEndReachedThreshold * scrollLength) {
|
|
485
521
|
if (refState.current) {
|
|
486
522
|
refState.current.isEndReached = true;
|
|
@@ -489,58 +525,65 @@ var LegendListInner = React2.forwardRef(
|
|
|
489
525
|
}
|
|
490
526
|
}
|
|
491
527
|
};
|
|
492
|
-
|
|
528
|
+
React6.useMemo(() => {
|
|
493
529
|
if (refState.current) {
|
|
494
530
|
refState.current.isEndReached = false;
|
|
495
531
|
}
|
|
496
532
|
calculateItemsInView();
|
|
497
533
|
checkAtBottom();
|
|
498
534
|
}, [data]);
|
|
499
|
-
const
|
|
500
|
-
var
|
|
501
|
-
const data2 = (
|
|
535
|
+
const updateItemSize = React6.useCallback((index, length) => {
|
|
536
|
+
var _a2, _b2, _c, _d;
|
|
537
|
+
const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
|
|
502
538
|
if (!data2) {
|
|
503
539
|
return;
|
|
504
540
|
}
|
|
505
|
-
const lengths = (
|
|
541
|
+
const lengths = (_b2 = refState.current) == null ? void 0 : _b2.lengths;
|
|
506
542
|
const id = getId(index);
|
|
507
543
|
const wasInFirstRender = (_c = refState.current) == null ? void 0 : _c.idsInFirstRender.has(id);
|
|
508
|
-
const prevLength = lengths.get(id) || (wasInFirstRender ?
|
|
544
|
+
const prevLength = lengths.get(id) || (wasInFirstRender ? getItemLength(index, data2[index]) : 0);
|
|
509
545
|
if (!prevLength || prevLength !== length) {
|
|
510
546
|
lengths.set(id, length);
|
|
511
|
-
|
|
512
|
-
setTotalLength(totalLength + (length - prevLength));
|
|
547
|
+
addTotalSize(length - prevLength);
|
|
513
548
|
if (((_d = refState.current) == null ? void 0 : _d.isAtBottom) && maintainScrollAtEnd) {
|
|
514
549
|
requestAnimationFrame(() => {
|
|
515
|
-
var
|
|
516
|
-
(
|
|
550
|
+
var _a3;
|
|
551
|
+
(_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
|
|
517
552
|
animated: true
|
|
518
553
|
});
|
|
519
554
|
});
|
|
520
555
|
}
|
|
521
|
-
|
|
522
|
-
|
|
556
|
+
const state = refState.current;
|
|
557
|
+
if (!state.animFrameScroll && !state.animFrameLayout) {
|
|
558
|
+
state.animFrameLayout = requestAnimationFrame(() => {
|
|
559
|
+
state.animFrameLayout = null;
|
|
560
|
+
calculateItemsInView();
|
|
561
|
+
});
|
|
523
562
|
}
|
|
524
563
|
}
|
|
525
564
|
}, []);
|
|
526
|
-
const handleScrollDebounced =
|
|
565
|
+
const handleScrollDebounced = React6.useCallback(() => {
|
|
527
566
|
calculateItemsInView();
|
|
528
567
|
checkAtBottom();
|
|
529
568
|
if (refState.current) {
|
|
530
|
-
refState.current.
|
|
569
|
+
refState.current.animFrameScroll = null;
|
|
531
570
|
}
|
|
532
571
|
}, []);
|
|
533
|
-
const onLayout =
|
|
572
|
+
const onLayout = React6.useCallback((event) => {
|
|
534
573
|
const scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
535
574
|
refState.current.scrollLength = scrollLength;
|
|
536
575
|
}, []);
|
|
537
|
-
const handleScroll =
|
|
576
|
+
const handleScroll = React6.useCallback(
|
|
538
577
|
(event, fromSelf) => {
|
|
578
|
+
var _a2, _b2, _c;
|
|
579
|
+
if (((_b2 = (_a2 = event.nativeEvent) == null ? void 0 : _a2.contentSize) == null ? void 0 : _b2.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
539
582
|
refState.current.hasScrolled = true;
|
|
540
583
|
const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
|
|
541
584
|
refState.current.scroll = newScroll;
|
|
542
|
-
if (refState.current && !refState.current.
|
|
543
|
-
refState.current.
|
|
585
|
+
if (refState.current && !refState.current.animFrameScroll) {
|
|
586
|
+
refState.current.animFrameScroll = requestAnimationFrame(handleScrollDebounced);
|
|
544
587
|
}
|
|
545
588
|
if (!fromSelf) {
|
|
546
589
|
onScrollProp == null ? void 0 : onScrollProp(event);
|
|
@@ -548,20 +591,7 @@ var LegendListInner = React2.forwardRef(
|
|
|
548
591
|
},
|
|
549
592
|
[]
|
|
550
593
|
);
|
|
551
|
-
|
|
552
|
-
if (initialContentOffset) {
|
|
553
|
-
const offset = horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset };
|
|
554
|
-
handleScroll(
|
|
555
|
-
{
|
|
556
|
-
nativeEvent: { contentOffset: offset }
|
|
557
|
-
},
|
|
558
|
-
/*fromSelf*/
|
|
559
|
-
true
|
|
560
|
-
);
|
|
561
|
-
calculateItemsInView();
|
|
562
|
-
}
|
|
563
|
-
}, []);
|
|
564
|
-
return /* @__PURE__ */ React2__namespace.createElement(
|
|
594
|
+
return /* @__PURE__ */ React6__namespace.createElement(
|
|
565
595
|
ListComponent,
|
|
566
596
|
{
|
|
567
597
|
...rest,
|
|
@@ -571,7 +601,7 @@ var LegendListInner = React2.forwardRef(
|
|
|
571
601
|
refScroller,
|
|
572
602
|
initialContentOffset,
|
|
573
603
|
getRenderedItem,
|
|
574
|
-
|
|
604
|
+
updateItemSize,
|
|
575
605
|
handleScroll,
|
|
576
606
|
onLayout,
|
|
577
607
|
recycleItems,
|