@legendapp/list 0.4.6 → 0.5.1
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/index.d.mts +24 -4
- package/index.d.ts +24 -4
- package/index.js +506 -367
- package/index.mjs +494 -355
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { forwardRef, useRef, useMemo, useCallback,
|
|
3
|
-
import {
|
|
1
|
+
import * as React7 from 'react';
|
|
2
|
+
import React7__default, { forwardRef, useRef, useMemo, useCallback, useImperativeHandle, useEffect, useState } from 'react';
|
|
3
|
+
import { Platform, StyleSheet, ScrollView, View, Dimensions } from 'react-native';
|
|
4
4
|
|
|
5
5
|
// src/LegendList.tsx
|
|
6
|
-
var
|
|
7
|
-
|
|
8
|
-
});
|
|
9
|
-
LeanView.displayName = "RCTView";
|
|
10
|
-
var ContextState = React6.createContext(null);
|
|
6
|
+
var USE_CONTENT_INSET = Platform.OS === "ios";
|
|
7
|
+
var ContextState = React7.createContext(null);
|
|
11
8
|
function StateProvider({ children }) {
|
|
12
|
-
const [value] =
|
|
9
|
+
const [value] = React7.useState(() => ({
|
|
13
10
|
hooks: /* @__PURE__ */ new Map(),
|
|
14
11
|
listeners: /* @__PURE__ */ new Map(),
|
|
15
12
|
values: /* @__PURE__ */ new Map(),
|
|
@@ -18,14 +15,14 @@ function StateProvider({ children }) {
|
|
|
18
15
|
mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
|
|
19
16
|
mapViewabilityAmountValues: /* @__PURE__ */ new Map()
|
|
20
17
|
}));
|
|
21
|
-
return /* @__PURE__ */
|
|
18
|
+
return /* @__PURE__ */ React7.createElement(ContextState.Provider, { value }, children);
|
|
22
19
|
}
|
|
23
20
|
function useStateContext() {
|
|
24
|
-
return
|
|
21
|
+
return React7.useContext(ContextState);
|
|
25
22
|
}
|
|
26
23
|
function use$(signalName) {
|
|
27
|
-
const { hooks, values } =
|
|
28
|
-
const [, forceUpdate] =
|
|
24
|
+
const { hooks, values } = React7.useContext(ContextState);
|
|
25
|
+
const [, forceUpdate] = React7.useReducer((x) => x + 1, 0);
|
|
29
26
|
hooks.set(signalName, forceUpdate);
|
|
30
27
|
return values.get(signalName);
|
|
31
28
|
}
|
|
@@ -58,27 +55,46 @@ function set$(ctx, signalName, value) {
|
|
|
58
55
|
}
|
|
59
56
|
}
|
|
60
57
|
|
|
58
|
+
// src/$ScrollView.tsx
|
|
59
|
+
var OFFSET_TEST = 0;
|
|
60
|
+
var $ScrollView = React7.forwardRef(function $ScrollView2(props, ref) {
|
|
61
|
+
const { style, horizontal, ...rest } = props;
|
|
62
|
+
const scrollAdjust = use$("scrollAdjust");
|
|
63
|
+
const adjustProps = {};
|
|
64
|
+
if (scrollAdjust !== 0) {
|
|
65
|
+
if (USE_CONTENT_INSET) {
|
|
66
|
+
adjustProps.contentInset = horizontal ? { left: -scrollAdjust } : { top: -scrollAdjust + OFFSET_TEST };
|
|
67
|
+
} else {
|
|
68
|
+
adjustProps.style = horizontal ? { marginLeft: -scrollAdjust } : { marginTop: -scrollAdjust };
|
|
69
|
+
if (style) {
|
|
70
|
+
adjustProps.style = StyleSheet.compose(style, adjustProps.style);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return /* @__PURE__ */ React7.createElement(ScrollView, { ...rest, style, horizontal, ...adjustProps, ref });
|
|
75
|
+
});
|
|
76
|
+
var LeanView = React7.forwardRef((props, ref) => {
|
|
77
|
+
return React7.createElement("RCTView", { ...props, ref });
|
|
78
|
+
});
|
|
79
|
+
LeanView.displayName = "RCTView";
|
|
80
|
+
|
|
61
81
|
// src/$View.tsx
|
|
62
|
-
function $View({ $key, $style, ...rest }) {
|
|
82
|
+
function $View({ $key, $key2, $style, ...rest }) {
|
|
63
83
|
use$($key);
|
|
84
|
+
if ($key2) {
|
|
85
|
+
use$($key2);
|
|
86
|
+
}
|
|
64
87
|
const style = $style();
|
|
65
|
-
return /* @__PURE__ */
|
|
88
|
+
return /* @__PURE__ */ React7.createElement(LeanView, { style, ...rest });
|
|
66
89
|
}
|
|
67
|
-
function InnerContainer({
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
if (
|
|
90
|
+
function InnerContainer({ containerId, getRenderedItem, recycleItems, ItemSeparatorComponent }) {
|
|
91
|
+
const lastItemKey = use$("lastItemKey");
|
|
92
|
+
const itemKey = use$(`containerItemKey${containerId}`);
|
|
93
|
+
if (itemKey === void 0) {
|
|
71
94
|
return null;
|
|
72
95
|
}
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
function RenderedItem({
|
|
76
|
-
itemIndex,
|
|
77
|
-
id,
|
|
78
|
-
getRenderedItem
|
|
79
|
-
}) {
|
|
80
|
-
const renderedItem = getRenderedItem(itemIndex, id);
|
|
81
|
-
return renderedItem;
|
|
96
|
+
const renderedItem = getRenderedItem(itemKey, containerId);
|
|
97
|
+
return /* @__PURE__ */ React7__default.createElement(React7__default.Fragment, { key: recycleItems ? void 0 : itemKey }, renderedItem, ItemSeparatorComponent && itemKey !== lastItemKey && ItemSeparatorComponent);
|
|
82
98
|
}
|
|
83
99
|
var Container = ({
|
|
84
100
|
id,
|
|
@@ -91,38 +107,44 @@ var Container = ({
|
|
|
91
107
|
const ctx = useStateContext();
|
|
92
108
|
const createStyle = () => {
|
|
93
109
|
const position = peek$(ctx, `containerPosition${id}`);
|
|
110
|
+
const visible = peek$(ctx, `containerDidLayout${id}`);
|
|
94
111
|
return horizontal ? {
|
|
95
112
|
flexDirection: "row",
|
|
96
113
|
position: "absolute",
|
|
97
|
-
top: 0,
|
|
114
|
+
top: visible ? 0 : -1e7,
|
|
98
115
|
bottom: 0,
|
|
99
|
-
left: position
|
|
100
|
-
opacity: position < 0 ? 0 : 1
|
|
116
|
+
left: position
|
|
101
117
|
} : {
|
|
102
118
|
position: "absolute",
|
|
103
|
-
left: 0,
|
|
119
|
+
left: visible ? 0 : -1e7,
|
|
104
120
|
right: 0,
|
|
105
|
-
top: position
|
|
106
|
-
opacity: position < 0 ? 0 : 1
|
|
121
|
+
top: position
|
|
107
122
|
};
|
|
108
123
|
};
|
|
109
|
-
return /* @__PURE__ */
|
|
124
|
+
return /* @__PURE__ */ React7__default.createElement(
|
|
110
125
|
$View,
|
|
111
126
|
{
|
|
112
127
|
$key: `containerPosition${id}`,
|
|
128
|
+
$key2: `containerDidLayout${id}`,
|
|
113
129
|
$style: createStyle,
|
|
114
130
|
onLayout: (event) => {
|
|
115
|
-
const
|
|
116
|
-
if (
|
|
131
|
+
const key = peek$(ctx, `containerItemKey${id}`);
|
|
132
|
+
if (key !== void 0) {
|
|
117
133
|
const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
118
|
-
onLayout(
|
|
134
|
+
onLayout(key, size);
|
|
135
|
+
const measured = peek$(ctx, `containerDidLayout${id}`);
|
|
136
|
+
if (!measured) {
|
|
137
|
+
requestAnimationFrame(() => {
|
|
138
|
+
set$(ctx, `containerDidLayout${id}`, true);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
119
141
|
}
|
|
120
142
|
}
|
|
121
143
|
},
|
|
122
|
-
/* @__PURE__ */
|
|
144
|
+
/* @__PURE__ */ React7__default.createElement(
|
|
123
145
|
InnerContainer,
|
|
124
146
|
{
|
|
125
|
-
id,
|
|
147
|
+
containerId: id,
|
|
126
148
|
getRenderedItem,
|
|
127
149
|
recycleItems,
|
|
128
150
|
ItemSeparatorComponent
|
|
@@ -132,7 +154,7 @@ var Container = ({
|
|
|
132
154
|
};
|
|
133
155
|
|
|
134
156
|
// src/Containers.tsx
|
|
135
|
-
var Containers =
|
|
157
|
+
var Containers = React7.memo(function Containers2({
|
|
136
158
|
horizontal,
|
|
137
159
|
recycleItems,
|
|
138
160
|
ItemSeparatorComponent,
|
|
@@ -140,11 +162,11 @@ var Containers = React6.memo(function Containers2({
|
|
|
140
162
|
getRenderedItem
|
|
141
163
|
}) {
|
|
142
164
|
const ctx = useStateContext();
|
|
143
|
-
const numContainers = use$("
|
|
165
|
+
const numContainers = use$("numContainersPooled");
|
|
144
166
|
const containers = [];
|
|
145
167
|
for (let i = 0; i < numContainers; i++) {
|
|
146
168
|
containers.push(
|
|
147
|
-
/* @__PURE__ */
|
|
169
|
+
/* @__PURE__ */ React7.createElement(
|
|
148
170
|
Container,
|
|
149
171
|
{
|
|
150
172
|
id: i,
|
|
@@ -158,14 +180,18 @@ var Containers = React6.memo(function Containers2({
|
|
|
158
180
|
)
|
|
159
181
|
);
|
|
160
182
|
}
|
|
161
|
-
return /* @__PURE__ */
|
|
183
|
+
return /* @__PURE__ */ React7.createElement(
|
|
162
184
|
$View,
|
|
163
185
|
{
|
|
164
186
|
$key: "totalSize",
|
|
165
|
-
$
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
187
|
+
$key2: "scrollAdjust",
|
|
188
|
+
$style: () => {
|
|
189
|
+
const size = peek$(ctx, "totalSize") + peek$(ctx, "scrollAdjust");
|
|
190
|
+
return horizontal ? {
|
|
191
|
+
width: size
|
|
192
|
+
} : {
|
|
193
|
+
height: size
|
|
194
|
+
};
|
|
169
195
|
}
|
|
170
196
|
},
|
|
171
197
|
containers
|
|
@@ -174,15 +200,15 @@ var Containers = React6.memo(function Containers2({
|
|
|
174
200
|
|
|
175
201
|
// src/ListComponent.tsx
|
|
176
202
|
var getComponent = (Component) => {
|
|
177
|
-
if (
|
|
203
|
+
if (React7.isValidElement(Component)) {
|
|
178
204
|
return Component;
|
|
179
205
|
}
|
|
180
206
|
if (Component) {
|
|
181
|
-
return /* @__PURE__ */
|
|
207
|
+
return /* @__PURE__ */ React7.createElement(Component, null);
|
|
182
208
|
}
|
|
183
209
|
return null;
|
|
184
210
|
};
|
|
185
|
-
var ListComponent =
|
|
211
|
+
var ListComponent = React7.memo(function ListComponent2({
|
|
186
212
|
style,
|
|
187
213
|
contentContainerStyle,
|
|
188
214
|
horizontal,
|
|
@@ -205,8 +231,8 @@ var ListComponent = React6.memo(function ListComponent2({
|
|
|
205
231
|
...rest
|
|
206
232
|
}) {
|
|
207
233
|
const ctx = useStateContext();
|
|
208
|
-
return /* @__PURE__ */
|
|
209
|
-
ScrollView,
|
|
234
|
+
return /* @__PURE__ */ React7.createElement(
|
|
235
|
+
$ScrollView,
|
|
210
236
|
{
|
|
211
237
|
...rest,
|
|
212
238
|
style,
|
|
@@ -218,29 +244,35 @@ var ListComponent = React6.memo(function ListComponent2({
|
|
|
218
244
|
],
|
|
219
245
|
onScroll: handleScroll,
|
|
220
246
|
onLayout,
|
|
221
|
-
scrollEventThrottle: 32,
|
|
222
247
|
horizontal,
|
|
223
248
|
contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
|
|
224
249
|
ref: refScroller
|
|
225
250
|
},
|
|
226
|
-
alignItemsAtEnd && /* @__PURE__ */
|
|
227
|
-
ListHeaderComponent && /* @__PURE__ */
|
|
228
|
-
View,
|
|
251
|
+
alignItemsAtEnd && /* @__PURE__ */ React7.createElement($View, { $key: "paddingTop", $style: () => ({ height: peek$(ctx, "paddingTop") }) }),
|
|
252
|
+
ListHeaderComponent && /* @__PURE__ */ React7.createElement(
|
|
253
|
+
$View,
|
|
229
254
|
{
|
|
230
|
-
|
|
255
|
+
$key: "scrollAdjust",
|
|
256
|
+
$style: () => StyleSheet.compose(ListHeaderComponentStyle, { top: peek$(ctx, "scrollAdjust") }),
|
|
231
257
|
onLayout: (event) => {
|
|
232
258
|
const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
233
259
|
const prevSize = peek$(ctx, "headerSize") || 0;
|
|
234
260
|
if (size !== prevSize) {
|
|
235
261
|
set$(ctx, "headerSize", size);
|
|
236
|
-
addTotalSize(size - prevSize);
|
|
237
262
|
}
|
|
238
263
|
}
|
|
239
264
|
},
|
|
240
265
|
getComponent(ListHeaderComponent)
|
|
241
266
|
),
|
|
242
|
-
ListEmptyComponent && /* @__PURE__ */
|
|
243
|
-
|
|
267
|
+
ListEmptyComponent && /* @__PURE__ */ React7.createElement(
|
|
268
|
+
$View,
|
|
269
|
+
{
|
|
270
|
+
$key: "scrollAdjust",
|
|
271
|
+
$style: () => StyleSheet.compose(ListEmptyComponentStyle, { top: peek$(ctx, "scrollAdjust") })
|
|
272
|
+
},
|
|
273
|
+
getComponent(ListEmptyComponent)
|
|
274
|
+
),
|
|
275
|
+
/* @__PURE__ */ React7.createElement(
|
|
244
276
|
Containers,
|
|
245
277
|
{
|
|
246
278
|
horizontal,
|
|
@@ -250,7 +282,7 @@ var ListComponent = React6.memo(function ListComponent2({
|
|
|
250
282
|
updateItemSize
|
|
251
283
|
}
|
|
252
284
|
),
|
|
253
|
-
ListFooterComponent && /* @__PURE__ */
|
|
285
|
+
ListFooterComponent && /* @__PURE__ */ React7.createElement(View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
|
|
254
286
|
);
|
|
255
287
|
});
|
|
256
288
|
var symbolFirst = Symbol();
|
|
@@ -266,14 +298,17 @@ function useInit(cb) {
|
|
|
266
298
|
var mapViewabilityConfigCallbackPairs = /* @__PURE__ */ new Map();
|
|
267
299
|
function setupViewability(props) {
|
|
268
300
|
let { viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged } = props;
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
301
|
+
if (viewabilityConfig || onViewableItemsChanged) {
|
|
302
|
+
viewabilityConfigCallbackPairs = [
|
|
303
|
+
...viewabilityConfigCallbackPairs || [],
|
|
304
|
+
{
|
|
305
|
+
viewabilityConfig: viewabilityConfig || {
|
|
306
|
+
viewAreaCoveragePercentThreshold: 0
|
|
307
|
+
},
|
|
308
|
+
onViewableItemsChanged
|
|
309
|
+
}
|
|
310
|
+
];
|
|
311
|
+
}
|
|
277
312
|
if (viewabilityConfigCallbackPairs) {
|
|
278
313
|
for (const pair of viewabilityConfigCallbackPairs) {
|
|
279
314
|
mapViewabilityConfigCallbackPairs.set(pair.viewabilityConfig.id, {
|
|
@@ -369,7 +404,7 @@ function isViewable(state, ctx, viewabilityConfig, key, scrollSize, item, index)
|
|
|
369
404
|
const percentOfScroller = size ? 100 * (sizeVisible / scrollSize) : 0;
|
|
370
405
|
const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
|
|
371
406
|
const isViewable2 = percent >= viewablePercentThreshold;
|
|
372
|
-
const containerId = findContainerId(
|
|
407
|
+
const containerId = findContainerId(ctx, key);
|
|
373
408
|
const value = {
|
|
374
409
|
index,
|
|
375
410
|
isViewable: isViewable2,
|
|
@@ -389,11 +424,11 @@ function isViewable(state, ctx, viewabilityConfig, key, scrollSize, item, index)
|
|
|
389
424
|
}
|
|
390
425
|
return isViewable2;
|
|
391
426
|
}
|
|
392
|
-
function findContainerId(
|
|
427
|
+
function findContainerId(ctx, key) {
|
|
393
428
|
const numContainers = peek$(ctx, "numContainers");
|
|
394
429
|
for (let i = 0; i < numContainers; i++) {
|
|
395
|
-
const
|
|
396
|
-
if (
|
|
430
|
+
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
431
|
+
if (itemKey === key) {
|
|
397
432
|
return i;
|
|
398
433
|
}
|
|
399
434
|
}
|
|
@@ -407,47 +442,43 @@ function maybeUpdateViewabilityCallback(ctx, configId, viewToken) {
|
|
|
407
442
|
}
|
|
408
443
|
|
|
409
444
|
// src/LegendList.tsx
|
|
410
|
-
var
|
|
411
|
-
var
|
|
445
|
+
var DEFAULT_DRAW_DISTANCE = 250;
|
|
446
|
+
var INITIAL_SCROLL_ADJUST = 1e4;
|
|
447
|
+
var POSITION_OUT_OF_VIEW = -1e7;
|
|
412
448
|
var LegendList = forwardRef(function LegendList2(props, forwardedRef) {
|
|
413
|
-
return /* @__PURE__ */
|
|
449
|
+
return /* @__PURE__ */ React7.createElement(StateProvider, null, /* @__PURE__ */ React7.createElement(LegendListInner, { ...props, ref: forwardedRef }));
|
|
414
450
|
});
|
|
415
451
|
var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef) {
|
|
416
|
-
var _a, _b;
|
|
452
|
+
var _a, _b, _c, _d, _e;
|
|
417
453
|
const {
|
|
418
454
|
data,
|
|
419
455
|
initialScrollIndex,
|
|
420
456
|
initialScrollOffset,
|
|
421
457
|
horizontal,
|
|
422
|
-
style: styleProp,
|
|
423
|
-
contentContainerStyle: contentContainerStyleProp,
|
|
424
458
|
initialNumContainers,
|
|
425
459
|
drawDistance = 250,
|
|
426
460
|
recycleItems = false,
|
|
427
461
|
onEndReachedThreshold = 0.5,
|
|
462
|
+
onStartReachedThreshold = 0.5,
|
|
428
463
|
maintainScrollAtEnd = false,
|
|
429
464
|
maintainScrollAtEndThreshold = 0.1,
|
|
430
465
|
alignItemsAtEnd = false,
|
|
466
|
+
maintainVisibleContentPosition = false,
|
|
431
467
|
onScroll: onScrollProp,
|
|
432
468
|
keyExtractor,
|
|
433
469
|
renderItem,
|
|
434
470
|
estimatedItemSize,
|
|
435
471
|
getEstimatedItemSize,
|
|
436
472
|
onEndReached,
|
|
473
|
+
onStartReached,
|
|
437
474
|
ListEmptyComponent,
|
|
438
475
|
...rest
|
|
439
476
|
} = props;
|
|
477
|
+
const { style, contentContainerStyle } = rest;
|
|
440
478
|
const ctx = useStateContext();
|
|
441
479
|
const internalRef = useRef(null);
|
|
442
480
|
const refScroller = internalRef;
|
|
443
|
-
const scrollBuffer = drawDistance != null ? drawDistance :
|
|
444
|
-
const styleFlattened = StyleSheet.flatten(styleProp);
|
|
445
|
-
const style = useMemo(() => styleFlattened, [JSON.stringify(styleFlattened)]);
|
|
446
|
-
const contentContainerStyleFlattened = StyleSheet.flatten(contentContainerStyleProp);
|
|
447
|
-
const contentContainerStyle = useMemo(
|
|
448
|
-
() => contentContainerStyleFlattened,
|
|
449
|
-
[JSON.stringify(contentContainerStyleProp)]
|
|
450
|
-
);
|
|
481
|
+
const scrollBuffer = drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE;
|
|
451
482
|
const refState = useRef();
|
|
452
483
|
const getId = (index) => {
|
|
453
484
|
var _a2;
|
|
@@ -458,21 +489,26 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
458
489
|
const ret = index < data2.length ? keyExtractor ? keyExtractor(data2[index], index) : index : null;
|
|
459
490
|
return `${ret}`;
|
|
460
491
|
};
|
|
461
|
-
const getItemSize = (index, data2) => {
|
|
462
|
-
|
|
492
|
+
const getItemSize = (key, index, data2) => {
|
|
493
|
+
const sizeKnown = refState.current.sizes.get(key);
|
|
494
|
+
if (sizeKnown !== void 0) {
|
|
495
|
+
return sizeKnown;
|
|
496
|
+
}
|
|
497
|
+
const size = getEstimatedItemSize ? getEstimatedItemSize(index, data2) : estimatedItemSize;
|
|
498
|
+
refState.current.sizes.set(key, size);
|
|
499
|
+
return size;
|
|
463
500
|
};
|
|
464
501
|
const calculateInitialOffset = (index = initialScrollIndex) => {
|
|
465
502
|
if (index) {
|
|
503
|
+
let offset = 0;
|
|
466
504
|
if (getEstimatedItemSize) {
|
|
467
|
-
let offset = 0;
|
|
468
505
|
for (let i = 0; i < index; i++) {
|
|
469
506
|
offset += getEstimatedItemSize(i, data[i]);
|
|
470
507
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
if (estimatedItemSize) {
|
|
474
|
-
return index * estimatedItemSize;
|
|
508
|
+
} else if (estimatedItemSize) {
|
|
509
|
+
offset = index * estimatedItemSize;
|
|
475
510
|
}
|
|
511
|
+
return offset + (maintainVisibleContentPosition ? INITIAL_SCROLL_ADJUST : 0);
|
|
476
512
|
}
|
|
477
513
|
return void 0;
|
|
478
514
|
};
|
|
@@ -482,12 +518,12 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
482
518
|
sizes: /* @__PURE__ */ new Map(),
|
|
483
519
|
positions: /* @__PURE__ */ new Map(),
|
|
484
520
|
pendingAdjust: 0,
|
|
485
|
-
animFrameScroll: null,
|
|
486
521
|
animFrameLayout: null,
|
|
487
522
|
animFrameTotalSize: null,
|
|
488
523
|
isStartReached: false,
|
|
489
524
|
isEndReached: false,
|
|
490
525
|
isAtBottom: false,
|
|
526
|
+
isAtTop: false,
|
|
491
527
|
data,
|
|
492
528
|
idsInFirstRender: void 0,
|
|
493
529
|
hasScrolled: false,
|
|
@@ -500,51 +536,324 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
500
536
|
totalSize: 0,
|
|
501
537
|
timeouts: /* @__PURE__ */ new Set(),
|
|
502
538
|
viewabilityConfigCallbackPairs: void 0,
|
|
503
|
-
renderItem: void 0
|
|
539
|
+
renderItem: void 0,
|
|
540
|
+
scrollAdjustPending: maintainVisibleContentPosition ? INITIAL_SCROLL_ADJUST : 0,
|
|
541
|
+
nativeMarginTop: 0,
|
|
542
|
+
scrollPrev: 0,
|
|
543
|
+
scrollPrevTime: 0,
|
|
544
|
+
scrollTime: 0,
|
|
545
|
+
indexByKey: /* @__PURE__ */ new Map(),
|
|
546
|
+
scrollHistory: [],
|
|
547
|
+
scrollVelocity: 0,
|
|
548
|
+
contentSize: { width: 0, height: 0 }
|
|
504
549
|
};
|
|
505
550
|
refState.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
|
|
551
|
+
set$(ctx, "scrollAdjust", refState.current.scrollAdjustPending);
|
|
506
552
|
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
refState.current
|
|
514
|
-
const
|
|
553
|
+
const adjustScroll = (diff) => {
|
|
554
|
+
if (maintainVisibleContentPosition && refScroller.current) {
|
|
555
|
+
refState.current.scrollAdjustPending -= diff;
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
const addTotalSize = useCallback((key, add, set) => {
|
|
559
|
+
const state = refState.current;
|
|
560
|
+
const index = key === null ? 0 : state.indexByKey.get(key);
|
|
561
|
+
const isAbove = index < (state.startNoBuffer || 0);
|
|
562
|
+
const prev = state.totalSize;
|
|
563
|
+
if (set) {
|
|
564
|
+
state.totalSize = add;
|
|
565
|
+
} else {
|
|
566
|
+
state.totalSize += add;
|
|
567
|
+
}
|
|
515
568
|
const doAdd = () => {
|
|
516
|
-
|
|
569
|
+
const totalSize = state.totalSize;
|
|
570
|
+
state.animFrameTotalSize = null;
|
|
517
571
|
set$(ctx, "totalSize", totalSize);
|
|
518
|
-
const screenLength = refState.current.scrollLength;
|
|
519
572
|
if (alignItemsAtEnd) {
|
|
520
|
-
|
|
521
|
-
set$(ctx, "paddingTop", Math.max(0, screenLength - totalSize - listPaddingTop));
|
|
573
|
+
doUpdatePaddingTop();
|
|
522
574
|
}
|
|
523
575
|
};
|
|
524
|
-
if (
|
|
576
|
+
if (isAbove) {
|
|
577
|
+
adjustScroll(add);
|
|
578
|
+
}
|
|
579
|
+
if (!prev || set) {
|
|
525
580
|
doAdd();
|
|
526
|
-
} else if (!
|
|
527
|
-
|
|
581
|
+
} else if (!state.animFrameTotalSize) {
|
|
582
|
+
state.animFrameTotalSize = requestAnimationFrame(doAdd);
|
|
528
583
|
}
|
|
529
584
|
}, []);
|
|
530
|
-
const
|
|
531
|
-
var _a2, _b2,
|
|
532
|
-
const
|
|
585
|
+
const calculateItemsInView = useCallback((speed = 0) => {
|
|
586
|
+
var _a2, _b2, _c2;
|
|
587
|
+
const state = refState.current;
|
|
588
|
+
const { data: data2, scrollLength, scroll: scrollState, startBuffered: startBufferedState, positions } = state;
|
|
589
|
+
if (state.animFrameLayout) {
|
|
590
|
+
cancelAnimationFrame(state.animFrameLayout);
|
|
591
|
+
state.animFrameLayout = null;
|
|
592
|
+
}
|
|
533
593
|
if (!data2) {
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
597
|
+
const scrollAdjustPending = (_a2 = state.scrollAdjustPending) != null ? _a2 : 0;
|
|
598
|
+
const scrollExtra = Math.max(-16, Math.min(16, speed)) * 32;
|
|
599
|
+
const scroll = Math.max(
|
|
600
|
+
0,
|
|
601
|
+
scrollState - topPad - (USE_CONTENT_INSET ? scrollAdjustPending : 0) + scrollExtra
|
|
602
|
+
);
|
|
603
|
+
let startNoBuffer = null;
|
|
604
|
+
let startBuffered = null;
|
|
605
|
+
let endNoBuffer = null;
|
|
606
|
+
let endBuffered = null;
|
|
607
|
+
let loopStart = startBufferedState || 0;
|
|
608
|
+
if (startBufferedState) {
|
|
609
|
+
for (let i = startBufferedState; i >= 0; i--) {
|
|
610
|
+
const id = getId(i);
|
|
611
|
+
const top2 = positions.get(id);
|
|
612
|
+
if (top2 !== void 0) {
|
|
613
|
+
const size = getItemSize(id, i, data2[i]);
|
|
614
|
+
const bottom = top2 + size;
|
|
615
|
+
if (bottom > scroll - scrollBuffer) {
|
|
616
|
+
loopStart = i;
|
|
617
|
+
} else {
|
|
618
|
+
break;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
let top = loopStart > 0 ? positions.get(getId(loopStart)) : 0;
|
|
624
|
+
for (let i = loopStart; i < data2.length; i++) {
|
|
625
|
+
const id = getId(i);
|
|
626
|
+
const size = getItemSize(id, i, data2[i]);
|
|
627
|
+
if (positions.get(id) !== top) {
|
|
628
|
+
positions.set(id, top);
|
|
629
|
+
}
|
|
630
|
+
if (startNoBuffer === null && top + size > scroll) {
|
|
631
|
+
startNoBuffer = i;
|
|
632
|
+
}
|
|
633
|
+
if (startBuffered === null && top + size > scroll - scrollBuffer) {
|
|
634
|
+
startBuffered = i;
|
|
635
|
+
}
|
|
636
|
+
if (startNoBuffer !== null) {
|
|
637
|
+
if (top <= scroll + scrollLength) {
|
|
638
|
+
endNoBuffer = i;
|
|
639
|
+
}
|
|
640
|
+
if (top <= scroll + scrollLength + scrollBuffer) {
|
|
641
|
+
endBuffered = i;
|
|
642
|
+
} else {
|
|
643
|
+
break;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
top += size;
|
|
647
|
+
}
|
|
648
|
+
Object.assign(refState.current, {
|
|
649
|
+
startBuffered,
|
|
650
|
+
startNoBuffer,
|
|
651
|
+
endBuffered,
|
|
652
|
+
endNoBuffer
|
|
653
|
+
});
|
|
654
|
+
if (startBuffered !== null && endBuffered !== null) {
|
|
655
|
+
const prevNumContainers = ctx.values.get("numContainers");
|
|
656
|
+
let numContainers = prevNumContainers;
|
|
657
|
+
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
658
|
+
let isContained = false;
|
|
659
|
+
const id = getId(i);
|
|
660
|
+
for (let j = 0; j < numContainers; j++) {
|
|
661
|
+
const key = peek$(ctx, `containerItemKey${j}`);
|
|
662
|
+
if (key === id) {
|
|
663
|
+
isContained = true;
|
|
664
|
+
break;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
if (!isContained) {
|
|
668
|
+
const top2 = (positions.get(id) || 0) + scrollAdjustPending;
|
|
669
|
+
let furthestIndex = -1;
|
|
670
|
+
let furthestDistance = 0;
|
|
671
|
+
for (let u = 0; u < numContainers; u++) {
|
|
672
|
+
const key = peek$(ctx, `containerItemKey${u}`);
|
|
673
|
+
if (key === void 0) {
|
|
674
|
+
furthestIndex = u;
|
|
675
|
+
break;
|
|
676
|
+
}
|
|
677
|
+
const index = (_b2 = refState.current) == null ? void 0 : _b2.indexByKey.get(key);
|
|
678
|
+
const pos = peek$(ctx, `containerPosition${u}`);
|
|
679
|
+
if (index < startBuffered || index > endBuffered) {
|
|
680
|
+
const distance = Math.abs(pos - top2);
|
|
681
|
+
if (index < 0 || distance > furthestDistance) {
|
|
682
|
+
furthestDistance = distance;
|
|
683
|
+
furthestIndex = u;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
if (furthestIndex >= 0) {
|
|
688
|
+
set$(ctx, `containerItemKey${furthestIndex}`, id);
|
|
689
|
+
} else {
|
|
690
|
+
const containerId = numContainers;
|
|
691
|
+
numContainers++;
|
|
692
|
+
set$(ctx, `containerItemKey${containerId}`, id);
|
|
693
|
+
set$(ctx, `containerPosition${containerId}`, POSITION_OUT_OF_VIEW);
|
|
694
|
+
if (__DEV__ && numContainers > peek$(ctx, "numContainersPooled")) {
|
|
695
|
+
console.warn(
|
|
696
|
+
"[legend-list] No container to recycle, consider increasing initialContainers or estimatedItemSize. numContainers:",
|
|
697
|
+
numContainers
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
if (numContainers !== prevNumContainers) {
|
|
704
|
+
set$(ctx, "numContainers", numContainers);
|
|
705
|
+
if (numContainers > peek$(ctx, "numContainersPooled")) {
|
|
706
|
+
set$(ctx, "numContainersPooled", numContainers);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
for (let i = 0; i < numContainers; i++) {
|
|
710
|
+
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
711
|
+
const itemIndex = (_c2 = refState.current) == null ? void 0 : _c2.indexByKey.get(itemKey);
|
|
712
|
+
const item = data2[itemIndex];
|
|
713
|
+
if (item) {
|
|
714
|
+
const id = getId(itemIndex);
|
|
715
|
+
if (!(itemKey !== id || itemIndex < startBuffered || itemIndex > endBuffered)) {
|
|
716
|
+
const pos = (positions.get(id) || 0) + scrollAdjustPending;
|
|
717
|
+
const prevPos = peek$(ctx, `containerPosition${i}`);
|
|
718
|
+
if (pos >= 0 && pos !== prevPos) {
|
|
719
|
+
set$(ctx, `containerPosition${i}`, pos);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
if (refState.current.viewabilityConfigCallbackPairs) {
|
|
726
|
+
updateViewableItems(
|
|
727
|
+
refState.current,
|
|
728
|
+
ctx,
|
|
729
|
+
refState.current.viewabilityConfigCallbackPairs,
|
|
730
|
+
getId,
|
|
731
|
+
scrollLength,
|
|
732
|
+
startNoBuffer,
|
|
733
|
+
endNoBuffer
|
|
734
|
+
);
|
|
735
|
+
}
|
|
736
|
+
}, []);
|
|
737
|
+
const doUpdatePaddingTop = () => {
|
|
738
|
+
if (alignItemsAtEnd) {
|
|
739
|
+
const { scrollLength, totalSize } = refState.current;
|
|
740
|
+
const listPaddingTop = peek$(ctx, "stylePaddingTop") || 0;
|
|
741
|
+
const paddingTop = Math.max(0, Math.floor(scrollLength - totalSize - listPaddingTop));
|
|
742
|
+
set$(ctx, "paddingTop", paddingTop);
|
|
743
|
+
}
|
|
744
|
+
};
|
|
745
|
+
const doMaintainScrollAtEnd = (animated) => {
|
|
746
|
+
var _a2;
|
|
747
|
+
if (((_a2 = refState.current) == null ? void 0 : _a2.isAtBottom) && maintainScrollAtEnd) {
|
|
748
|
+
refState.current.scroll = refState.current.totalSize - refState.current.scrollLength;
|
|
749
|
+
requestAnimationFrame(() => {
|
|
750
|
+
var _a3;
|
|
751
|
+
(_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
|
|
752
|
+
animated
|
|
753
|
+
});
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
};
|
|
757
|
+
const checkAtBottom = () => {
|
|
758
|
+
var _a2;
|
|
759
|
+
const { scrollLength, scroll, contentSize } = refState.current;
|
|
760
|
+
const distanceFromEnd = contentSize[horizontal ? "width" : "height"] - scroll - scrollLength;
|
|
761
|
+
if (refState.current) {
|
|
762
|
+
refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
763
|
+
}
|
|
764
|
+
if (onEndReached && !((_a2 = refState.current) == null ? void 0 : _a2.isEndReached)) {
|
|
765
|
+
if (distanceFromEnd < onEndReachedThreshold * scrollLength) {
|
|
766
|
+
if (refState.current) {
|
|
767
|
+
refState.current.isEndReached = true;
|
|
768
|
+
}
|
|
769
|
+
onEndReached({ distanceFromEnd });
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
};
|
|
773
|
+
const checkAtTop = () => {
|
|
774
|
+
var _a2;
|
|
775
|
+
const { scrollLength, scroll } = refState.current;
|
|
776
|
+
if (refState.current) {
|
|
777
|
+
refState.current.isAtTop = scroll === 0;
|
|
778
|
+
}
|
|
779
|
+
if (onStartReached && !((_a2 = refState.current) == null ? void 0 : _a2.isStartReached)) {
|
|
780
|
+
if (scroll < onStartReachedThreshold * scrollLength) {
|
|
781
|
+
if (refState.current) {
|
|
782
|
+
refState.current.isStartReached = true;
|
|
783
|
+
}
|
|
784
|
+
onStartReached({ distanceFromStart: scroll });
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
};
|
|
788
|
+
const isFirst = !refState.current.renderItem;
|
|
789
|
+
if (isFirst || data !== refState.current.data) {
|
|
790
|
+
refState.current.data = data;
|
|
791
|
+
let totalSize = 0;
|
|
792
|
+
const indexByKey = /* @__PURE__ */ new Map();
|
|
793
|
+
for (let i = 0; i < data.length; i++) {
|
|
794
|
+
const key = getId(i);
|
|
795
|
+
indexByKey.set(key, i);
|
|
796
|
+
totalSize += getItemSize(key, i, data[i]);
|
|
797
|
+
if (maintainVisibleContentPosition && i < refState.current.startNoBuffer && !refState.current.indexByKey.has(key)) {
|
|
798
|
+
const size = getItemSize(key, i, data[i]);
|
|
799
|
+
adjustScroll(size);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
addTotalSize(null, totalSize, true);
|
|
803
|
+
if (maintainVisibleContentPosition) {
|
|
804
|
+
for (const [key, index] of refState.current.indexByKey) {
|
|
805
|
+
if (index < refState.current.startNoBuffer && !indexByKey.has(key)) {
|
|
806
|
+
const size = (_a = refState.current.sizes.get(key)) != null ? _a : 0;
|
|
807
|
+
if (size) {
|
|
808
|
+
adjustScroll(-size);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
refState.current.indexByKey = indexByKey;
|
|
814
|
+
if (!isFirst) {
|
|
815
|
+
refState.current.isEndReached = false;
|
|
816
|
+
const numContainers = peek$(ctx, "numContainers");
|
|
817
|
+
for (let i = 0; i < numContainers; i++) {
|
|
818
|
+
set$(ctx, `containerItemKey${i}`, void 0);
|
|
819
|
+
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
820
|
+
}
|
|
821
|
+
calculateItemsInView();
|
|
822
|
+
doMaintainScrollAtEnd(false);
|
|
823
|
+
checkAtTop();
|
|
824
|
+
checkAtBottom();
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
refState.current.renderItem = renderItem;
|
|
828
|
+
set$(ctx, "lastItemKey", getId(data[data.length - 1]));
|
|
829
|
+
set$(
|
|
830
|
+
ctx,
|
|
831
|
+
"stylePaddingTop",
|
|
832
|
+
(_e = (_d = (_b = StyleSheet.flatten(style)) == null ? void 0 : _b.paddingTop) != null ? _d : (_c = StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _c.paddingTop) != null ? _e : 0
|
|
833
|
+
);
|
|
834
|
+
const getRenderedItem = useCallback((key, containerId) => {
|
|
835
|
+
var _a2, _b2;
|
|
836
|
+
const state = refState.current;
|
|
837
|
+
if (!state) {
|
|
838
|
+
return null;
|
|
839
|
+
}
|
|
840
|
+
const { data: data2, indexByKey } = state;
|
|
841
|
+
const index = indexByKey.get(key);
|
|
842
|
+
if (index === void 0) {
|
|
534
843
|
return null;
|
|
535
844
|
}
|
|
536
845
|
const useViewability = (configId, callback) => {
|
|
537
|
-
const
|
|
846
|
+
const key2 = containerId + configId;
|
|
538
847
|
useInit(() => {
|
|
539
|
-
const value = ctx.mapViewabilityValues.get(
|
|
848
|
+
const value = ctx.mapViewabilityValues.get(key2);
|
|
540
849
|
if (value) {
|
|
541
850
|
callback(value);
|
|
542
851
|
}
|
|
543
852
|
});
|
|
544
|
-
ctx.mapViewabilityCallbacks.set(
|
|
853
|
+
ctx.mapViewabilityCallbacks.set(key2, callback);
|
|
545
854
|
useEffect(
|
|
546
855
|
() => () => {
|
|
547
|
-
ctx.mapViewabilityCallbacks.delete(
|
|
856
|
+
ctx.mapViewabilityCallbacks.delete(key2);
|
|
548
857
|
},
|
|
549
858
|
[]
|
|
550
859
|
);
|
|
@@ -566,14 +875,15 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
566
875
|
};
|
|
567
876
|
const useRecyclingEffect = (effect) => {
|
|
568
877
|
useEffect(() => {
|
|
569
|
-
const
|
|
878
|
+
const state2 = refState.current;
|
|
570
879
|
let prevIndex = index;
|
|
571
|
-
let prevItem =
|
|
572
|
-
const signal = `
|
|
573
|
-
|
|
574
|
-
const data3 =
|
|
880
|
+
let prevItem = state2.data[index];
|
|
881
|
+
const signal = `containerItemKey${containerId}`;
|
|
882
|
+
const run = () => {
|
|
883
|
+
const data3 = state2.data;
|
|
575
884
|
if (data3) {
|
|
576
|
-
const
|
|
885
|
+
const newKey = peek$(ctx, signal);
|
|
886
|
+
const newIndex = state2.indexByKey.get(newKey);
|
|
577
887
|
const newItem = data3[newIndex];
|
|
578
888
|
if (newItem) {
|
|
579
889
|
effect({
|
|
@@ -586,7 +896,9 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
586
896
|
prevIndex = newIndex;
|
|
587
897
|
prevItem = newItem;
|
|
588
898
|
}
|
|
589
|
-
}
|
|
899
|
+
};
|
|
900
|
+
run();
|
|
901
|
+
listen$(ctx, signal, run);
|
|
590
902
|
}, []);
|
|
591
903
|
};
|
|
592
904
|
const useRecyclingState = (updateState) => {
|
|
@@ -598,13 +910,13 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
598
910
|
prevItem: void 0
|
|
599
911
|
})
|
|
600
912
|
);
|
|
601
|
-
useRecyclingEffect((
|
|
602
|
-
const newState = updateState(
|
|
913
|
+
useRecyclingEffect((state2) => {
|
|
914
|
+
const newState = updateState(state2);
|
|
603
915
|
stateInfo[1](newState);
|
|
604
916
|
});
|
|
605
917
|
return stateInfo;
|
|
606
918
|
};
|
|
607
|
-
const renderedItem = (
|
|
919
|
+
const renderedItem = (_b2 = (_a2 = refState.current).renderItem) == null ? void 0 : _b2.call(_a2, {
|
|
608
920
|
item: data2[index],
|
|
609
921
|
index,
|
|
610
922
|
useViewability,
|
|
@@ -614,250 +926,62 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
614
926
|
});
|
|
615
927
|
return renderedItem;
|
|
616
928
|
}, []);
|
|
617
|
-
const calculateItemsInView = useCallback(() => {
|
|
618
|
-
unstable_batchedUpdates(() => {
|
|
619
|
-
var _a2, _b2, _c;
|
|
620
|
-
const {
|
|
621
|
-
data: data2,
|
|
622
|
-
scrollLength,
|
|
623
|
-
scroll: scrollState,
|
|
624
|
-
startBuffered: startBufferedState
|
|
625
|
-
} = refState.current;
|
|
626
|
-
if (!data2) {
|
|
627
|
-
return;
|
|
628
|
-
}
|
|
629
|
-
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
630
|
-
const scroll = scrollState - topPad;
|
|
631
|
-
const { sizes, positions } = refState.current;
|
|
632
|
-
let startNoBuffer = null;
|
|
633
|
-
let startBuffered = null;
|
|
634
|
-
let endNoBuffer = null;
|
|
635
|
-
let endBuffered = null;
|
|
636
|
-
let loopStart = startBufferedState || 0;
|
|
637
|
-
if (startBufferedState) {
|
|
638
|
-
for (let i = startBufferedState; i >= 0; i--) {
|
|
639
|
-
const id = getId(i);
|
|
640
|
-
const top2 = positions.get(id);
|
|
641
|
-
if (top2 !== void 0) {
|
|
642
|
-
const size = (_a2 = sizes.get(id)) != null ? _a2 : getItemSize(i, data2[i]);
|
|
643
|
-
const bottom = top2 + size;
|
|
644
|
-
if (bottom > scroll - scrollBuffer) {
|
|
645
|
-
loopStart = i;
|
|
646
|
-
} else {
|
|
647
|
-
break;
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
let top = loopStart > 0 ? positions.get(getId(loopStart)) : 0;
|
|
653
|
-
for (let i = loopStart; i < data2.length; i++) {
|
|
654
|
-
const id = getId(i);
|
|
655
|
-
const size = (_b2 = sizes.get(id)) != null ? _b2 : getItemSize(i, data2[i]);
|
|
656
|
-
if (positions.get(id) !== top) {
|
|
657
|
-
positions.set(id, top);
|
|
658
|
-
}
|
|
659
|
-
if (startNoBuffer === null && top + size > scroll) {
|
|
660
|
-
startNoBuffer = i;
|
|
661
|
-
}
|
|
662
|
-
if (startBuffered === null && top + size > scroll - scrollBuffer) {
|
|
663
|
-
startBuffered = i;
|
|
664
|
-
}
|
|
665
|
-
if (startNoBuffer !== null) {
|
|
666
|
-
if (top <= scroll + scrollLength) {
|
|
667
|
-
endNoBuffer = i;
|
|
668
|
-
}
|
|
669
|
-
if (top <= scroll + scrollLength + scrollBuffer) {
|
|
670
|
-
endBuffered = i;
|
|
671
|
-
} else {
|
|
672
|
-
break;
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
top += size;
|
|
676
|
-
}
|
|
677
|
-
Object.assign(refState.current, {
|
|
678
|
-
startBuffered,
|
|
679
|
-
startNoBuffer,
|
|
680
|
-
endBuffered,
|
|
681
|
-
endNoBuffer
|
|
682
|
-
});
|
|
683
|
-
if (startBuffered !== null && endBuffered !== null) {
|
|
684
|
-
const prevNumContainers = ctx.values.get("numContainers");
|
|
685
|
-
let numContainers = prevNumContainers;
|
|
686
|
-
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
687
|
-
let isContained = false;
|
|
688
|
-
const id = getId(i);
|
|
689
|
-
for (let j = 0; j < numContainers; j++) {
|
|
690
|
-
const index = peek$(ctx, `containerItemIndex${j}`);
|
|
691
|
-
const key = peek$(ctx, `containerItemKey${j}`);
|
|
692
|
-
if (index === i && key === id) {
|
|
693
|
-
isContained = true;
|
|
694
|
-
break;
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
if (!isContained) {
|
|
698
|
-
const top2 = positions.get(id) || 0;
|
|
699
|
-
let furthestIndex = -1;
|
|
700
|
-
let furthestDistance = 0;
|
|
701
|
-
for (let u = 0; u < numContainers; u++) {
|
|
702
|
-
const index = peek$(ctx, `containerItemIndex${u}`);
|
|
703
|
-
if (index < 0) {
|
|
704
|
-
furthestIndex = u;
|
|
705
|
-
break;
|
|
706
|
-
}
|
|
707
|
-
const pos = peek$(ctx, `containerPosition${u}`);
|
|
708
|
-
if (index < startBuffered || index > endBuffered) {
|
|
709
|
-
const distance = Math.abs(pos - top2);
|
|
710
|
-
if (index < 0 || distance > furthestDistance) {
|
|
711
|
-
furthestDistance = distance;
|
|
712
|
-
furthestIndex = u;
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
if (furthestIndex >= 0) {
|
|
717
|
-
set$(ctx, `containerItemIndex${furthestIndex}`, i);
|
|
718
|
-
set$(ctx, `containerItemKey${furthestIndex}`, id);
|
|
719
|
-
} else {
|
|
720
|
-
if (__DEV__) {
|
|
721
|
-
console.warn(
|
|
722
|
-
"[legend-list] No container to recycle, consider increasing initialContainers or estimatedItemSize",
|
|
723
|
-
i
|
|
724
|
-
);
|
|
725
|
-
}
|
|
726
|
-
const containerId = numContainers;
|
|
727
|
-
numContainers++;
|
|
728
|
-
set$(ctx, `containerItemIndex${containerId}`, i);
|
|
729
|
-
set$(ctx, `containerItemKey${containerId}`, id);
|
|
730
|
-
set$(ctx, `containerPosition${containerId}`, POSITION_OUT_OF_VIEW);
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
if (numContainers !== prevNumContainers) {
|
|
735
|
-
set$(ctx, "numContainers", numContainers);
|
|
736
|
-
}
|
|
737
|
-
for (let i = 0; i < numContainers; i++) {
|
|
738
|
-
const itemIndex = peek$(ctx, `containerItemIndex${i}`);
|
|
739
|
-
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
740
|
-
const item = data2[itemIndex];
|
|
741
|
-
if (item) {
|
|
742
|
-
const id = getId(itemIndex);
|
|
743
|
-
if (itemKey !== id || itemIndex < startBuffered || itemIndex > endBuffered) {
|
|
744
|
-
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
745
|
-
} else {
|
|
746
|
-
const pos = (_c = positions.get(id)) != null ? _c : -1;
|
|
747
|
-
const prevPos = peek$(ctx, `containerPosition${i}`);
|
|
748
|
-
if (pos >= 0 && pos !== prevPos) {
|
|
749
|
-
set$(ctx, `containerPosition${i}`, pos);
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
if (refState.current.viewabilityConfigCallbackPairs) {
|
|
756
|
-
updateViewableItems(
|
|
757
|
-
refState.current,
|
|
758
|
-
ctx,
|
|
759
|
-
refState.current.viewabilityConfigCallbackPairs,
|
|
760
|
-
getId,
|
|
761
|
-
scrollLength,
|
|
762
|
-
startNoBuffer,
|
|
763
|
-
endNoBuffer
|
|
764
|
-
);
|
|
765
|
-
}
|
|
766
|
-
});
|
|
767
|
-
}, []);
|
|
768
929
|
useInit(() => {
|
|
769
|
-
var _a2;
|
|
770
930
|
refState.current.viewabilityConfigCallbackPairs = setupViewability(props);
|
|
771
931
|
const scrollLength = refState.current.scrollLength;
|
|
772
932
|
const averageItemSize = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, data[0]);
|
|
773
|
-
const numContainers = initialNumContainers || Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize)
|
|
933
|
+
const numContainers = initialNumContainers || Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize);
|
|
774
934
|
for (let i = 0; i < numContainers; i++) {
|
|
775
|
-
set$(ctx, `containerItemIndex${i}`, -1);
|
|
776
935
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
777
936
|
}
|
|
778
937
|
set$(ctx, "numContainers", numContainers);
|
|
938
|
+
set$(ctx, "numContainersPooled", numContainers * 2);
|
|
779
939
|
calculateItemsInView();
|
|
780
|
-
const sizes = refState.current.sizes;
|
|
781
|
-
let totalSize = 0;
|
|
782
|
-
for (let i = 0; i < data.length; i++) {
|
|
783
|
-
const id = getId(i);
|
|
784
|
-
totalSize += (_a2 = sizes.get(id)) != null ? _a2 : getItemSize(i, data[i]);
|
|
785
|
-
}
|
|
786
|
-
addTotalSize(totalSize);
|
|
787
940
|
});
|
|
788
|
-
const
|
|
941
|
+
const updateItemSize = useCallback((key, size) => {
|
|
789
942
|
var _a2;
|
|
790
|
-
const { scrollLength, scroll } = refState.current;
|
|
791
|
-
const totalSize = peek$(ctx, "totalSize");
|
|
792
|
-
const distanceFromEnd = totalSize - scroll - scrollLength;
|
|
793
|
-
if (refState.current) {
|
|
794
|
-
refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
795
|
-
}
|
|
796
|
-
if (onEndReached && !((_a2 = refState.current) == null ? void 0 : _a2.isEndReached)) {
|
|
797
|
-
if (distanceFromEnd < onEndReachedThreshold * scrollLength) {
|
|
798
|
-
if (refState.current) {
|
|
799
|
-
refState.current.isEndReached = true;
|
|
800
|
-
}
|
|
801
|
-
onEndReached({ distanceFromEnd });
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
};
|
|
805
|
-
useEffect(() => {
|
|
806
|
-
if (refState.current) {
|
|
807
|
-
refState.current.isEndReached = false;
|
|
808
|
-
}
|
|
809
|
-
const numContainers = peek$(ctx, "numContainers");
|
|
810
|
-
if (data.length < numContainers) {
|
|
811
|
-
for (let i = 0; i < numContainers; i++) {
|
|
812
|
-
const itemIndex = peek$(ctx, `containerItemIndex${i}`);
|
|
813
|
-
if (itemIndex >= data.length) {
|
|
814
|
-
set$(ctx, `containerItemIndex${i}`, -1);
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
calculateItemsInView();
|
|
819
|
-
checkAtBottom();
|
|
820
|
-
}, [data]);
|
|
821
|
-
const updateItemSize = useCallback((index, size) => {
|
|
822
|
-
var _a2, _b2, _c;
|
|
823
943
|
const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
|
|
824
944
|
if (!data2) {
|
|
825
945
|
return;
|
|
826
946
|
}
|
|
827
|
-
const sizes = refState.current
|
|
828
|
-
const
|
|
829
|
-
const wasInFirstRender =
|
|
830
|
-
const prevSize = sizes.get(
|
|
947
|
+
const { sizes, indexByKey, idsInFirstRender } = refState.current;
|
|
948
|
+
const index = indexByKey.get(key);
|
|
949
|
+
const wasInFirstRender = idsInFirstRender.has(key);
|
|
950
|
+
const prevSize = sizes.get(key) || (wasInFirstRender ? getItemSize(key, index, data2[index]) : 0);
|
|
831
951
|
if (!prevSize || Math.abs(prevSize - size) > 0.5) {
|
|
832
|
-
sizes.set(
|
|
833
|
-
addTotalSize(size - prevSize);
|
|
834
|
-
|
|
835
|
-
requestAnimationFrame(() => {
|
|
836
|
-
var _a3;
|
|
837
|
-
(_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
|
|
838
|
-
animated: true
|
|
839
|
-
});
|
|
840
|
-
});
|
|
841
|
-
}
|
|
952
|
+
sizes.set(key, size);
|
|
953
|
+
addTotalSize(key, size - prevSize);
|
|
954
|
+
doMaintainScrollAtEnd(true);
|
|
842
955
|
const state = refState.current;
|
|
843
|
-
|
|
956
|
+
const scrollVelocity = state.scrollVelocity;
|
|
957
|
+
if (!state.animFrameLayout && (Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1)) {
|
|
844
958
|
state.animFrameLayout = requestAnimationFrame(() => {
|
|
845
959
|
state.animFrameLayout = null;
|
|
846
|
-
calculateItemsInView();
|
|
960
|
+
calculateItemsInView(state.scrollVelocity);
|
|
847
961
|
});
|
|
848
962
|
}
|
|
849
963
|
}
|
|
850
964
|
}, []);
|
|
851
|
-
const handleScrollDebounced = useCallback(() => {
|
|
852
|
-
|
|
965
|
+
const handleScrollDebounced = useCallback((velocity) => {
|
|
966
|
+
var _a2, _b2;
|
|
967
|
+
const scrollAdjustPending = (_b2 = (_a2 = refState.current) == null ? void 0 : _a2.scrollAdjustPending) != null ? _b2 : 0;
|
|
968
|
+
set$(ctx, "scrollAdjust", scrollAdjustPending);
|
|
969
|
+
calculateItemsInView(velocity);
|
|
853
970
|
checkAtBottom();
|
|
854
|
-
|
|
855
|
-
refState.current.animFrameScroll = null;
|
|
856
|
-
}
|
|
971
|
+
checkAtTop();
|
|
857
972
|
}, []);
|
|
858
973
|
const onLayout = useCallback((event) => {
|
|
859
|
-
|
|
974
|
+
let scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
975
|
+
if (!USE_CONTENT_INSET) {
|
|
976
|
+
scrollLength += event.nativeEvent.layout[horizontal ? "x" : "y"];
|
|
977
|
+
}
|
|
860
978
|
refState.current.scrollLength = scrollLength;
|
|
979
|
+
if (refState.current.hasScrolled) {
|
|
980
|
+
doMaintainScrollAtEnd(false);
|
|
981
|
+
doUpdatePaddingTop();
|
|
982
|
+
checkAtBottom();
|
|
983
|
+
checkAtTop();
|
|
984
|
+
}
|
|
861
985
|
if (__DEV__) {
|
|
862
986
|
const isWidthZero = event.nativeEvent.layout.width === 0;
|
|
863
987
|
const isHeightZero = event.nativeEvent.layout.height === 0;
|
|
@@ -870,16 +994,33 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
870
994
|
}, []);
|
|
871
995
|
const handleScroll = useCallback(
|
|
872
996
|
(event, fromSelf) => {
|
|
873
|
-
var _a2, _b2,
|
|
874
|
-
if (((_b2 = (_a2 = event.nativeEvent) == null ? void 0 : _a2.contentSize) == null ? void 0 : _b2.height) === 0 && ((
|
|
997
|
+
var _a2, _b2, _c2;
|
|
998
|
+
if (((_b2 = (_a2 = event.nativeEvent) == null ? void 0 : _a2.contentSize) == null ? void 0 : _b2.height) === 0 && ((_c2 = event.nativeEvent.contentSize) == null ? void 0 : _c2.width) === 0) {
|
|
875
999
|
return;
|
|
876
1000
|
}
|
|
877
|
-
refState.current
|
|
1001
|
+
const state = refState.current;
|
|
1002
|
+
state.hasScrolled = true;
|
|
1003
|
+
state.contentSize = event.nativeEvent.contentSize;
|
|
1004
|
+
const currentTime = performance.now();
|
|
878
1005
|
const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
|
|
879
|
-
|
|
880
|
-
if (
|
|
881
|
-
|
|
1006
|
+
state.scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
1007
|
+
if (state.scrollHistory.length > 5) {
|
|
1008
|
+
state.scrollHistory.shift();
|
|
1009
|
+
}
|
|
1010
|
+
let velocity = 0;
|
|
1011
|
+
if (state.scrollHistory.length >= 2) {
|
|
1012
|
+
const newest = state.scrollHistory[state.scrollHistory.length - 1];
|
|
1013
|
+
const oldest = state.scrollHistory[0];
|
|
1014
|
+
const scrollDiff = newest.scroll - oldest.scroll;
|
|
1015
|
+
const timeDiff = newest.time - oldest.time;
|
|
1016
|
+
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
882
1017
|
}
|
|
1018
|
+
state.scrollPrev = state.scroll;
|
|
1019
|
+
state.scrollPrevTime = state.scrollTime;
|
|
1020
|
+
state.scroll = newScroll;
|
|
1021
|
+
state.scrollTime = currentTime;
|
|
1022
|
+
state.scrollVelocity = velocity;
|
|
1023
|
+
handleScrollDebounced(velocity);
|
|
883
1024
|
if (!fromSelf) {
|
|
884
1025
|
onScrollProp == null ? void 0 : onScrollProp(event);
|
|
885
1026
|
}
|
|
@@ -915,12 +1056,10 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
915
1056
|
},
|
|
916
1057
|
[]
|
|
917
1058
|
);
|
|
918
|
-
return /* @__PURE__ */
|
|
1059
|
+
return /* @__PURE__ */ React7.createElement(
|
|
919
1060
|
ListComponent,
|
|
920
1061
|
{
|
|
921
1062
|
...rest,
|
|
922
|
-
contentContainerStyle,
|
|
923
|
-
style: [style],
|
|
924
1063
|
horizontal,
|
|
925
1064
|
refScroller,
|
|
926
1065
|
initialContentOffset,
|