@legendapp/list 0.4.5 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.mts +20 -4
- package/index.d.ts +20 -4
- package/index.js +516 -369
- package/index.mjs +504 -357
- 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, _f;
|
|
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,80 +536,355 @@ 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
|
|
504
548
|
};
|
|
505
549
|
refState.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
|
|
550
|
+
set$(ctx, "scrollAdjust", refState.current.scrollAdjustPending);
|
|
506
551
|
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
refState.current
|
|
514
|
-
const
|
|
552
|
+
const adjustScroll = (diff) => {
|
|
553
|
+
if (maintainVisibleContentPosition && refScroller.current) {
|
|
554
|
+
refState.current.scrollAdjustPending -= diff;
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
const addTotalSize = useCallback((key, add, set) => {
|
|
558
|
+
const state = refState.current;
|
|
559
|
+
const index = key === null ? 0 : state.indexByKey.get(key);
|
|
560
|
+
const isAbove = index < (state.startNoBuffer || 0);
|
|
561
|
+
const prev = state.totalSize;
|
|
562
|
+
if (set) {
|
|
563
|
+
state.totalSize = add;
|
|
564
|
+
} else {
|
|
565
|
+
state.totalSize += add;
|
|
566
|
+
}
|
|
515
567
|
const doAdd = () => {
|
|
516
|
-
|
|
568
|
+
const totalSize = state.totalSize;
|
|
569
|
+
state.animFrameTotalSize = null;
|
|
517
570
|
set$(ctx, "totalSize", totalSize);
|
|
518
|
-
const screenLength = refState.current.scrollLength;
|
|
519
571
|
if (alignItemsAtEnd) {
|
|
520
|
-
|
|
521
|
-
set$(ctx, "paddingTop", Math.max(0, screenLength - totalSize - listPaddingTop));
|
|
572
|
+
doUpdatePaddingTop();
|
|
522
573
|
}
|
|
523
574
|
};
|
|
524
|
-
if (
|
|
575
|
+
if (isAbove) {
|
|
576
|
+
adjustScroll(add);
|
|
577
|
+
}
|
|
578
|
+
if (!prev || set) {
|
|
525
579
|
doAdd();
|
|
526
|
-
} else if (!
|
|
527
|
-
|
|
580
|
+
} else if (!state.animFrameTotalSize) {
|
|
581
|
+
state.animFrameTotalSize = requestAnimationFrame(doAdd);
|
|
528
582
|
}
|
|
529
583
|
}, []);
|
|
530
|
-
const
|
|
531
|
-
var _a2, _b2,
|
|
532
|
-
const
|
|
584
|
+
const calculateItemsInView = useCallback((speed = 0) => {
|
|
585
|
+
var _a2, _b2, _c2;
|
|
586
|
+
const state = refState.current;
|
|
587
|
+
const { data: data2, scrollLength, scroll: scrollState, startBuffered: startBufferedState, positions } = state;
|
|
588
|
+
if (state.animFrameLayout) {
|
|
589
|
+
cancelAnimationFrame(state.animFrameLayout);
|
|
590
|
+
state.animFrameLayout = null;
|
|
591
|
+
}
|
|
533
592
|
if (!data2) {
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
596
|
+
const scrollAdjustPending = (_a2 = state.scrollAdjustPending) != null ? _a2 : 0;
|
|
597
|
+
const scrollExtra = Math.max(-16, Math.min(16, speed)) * 32;
|
|
598
|
+
const scroll = Math.max(
|
|
599
|
+
0,
|
|
600
|
+
scrollState - topPad - (USE_CONTENT_INSET ? scrollAdjustPending : 0) + scrollExtra
|
|
601
|
+
);
|
|
602
|
+
let startNoBuffer = null;
|
|
603
|
+
let startBuffered = null;
|
|
604
|
+
let endNoBuffer = null;
|
|
605
|
+
let endBuffered = null;
|
|
606
|
+
let loopStart = startBufferedState || 0;
|
|
607
|
+
if (startBufferedState) {
|
|
608
|
+
for (let i = startBufferedState; i >= 0; i--) {
|
|
609
|
+
const id = getId(i);
|
|
610
|
+
const top2 = positions.get(id);
|
|
611
|
+
if (top2 !== void 0) {
|
|
612
|
+
const size = getItemSize(id, i, data2[i]);
|
|
613
|
+
const bottom = top2 + size;
|
|
614
|
+
if (bottom > scroll - scrollBuffer) {
|
|
615
|
+
loopStart = i;
|
|
616
|
+
} else {
|
|
617
|
+
break;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
let top = loopStart > 0 ? positions.get(getId(loopStart)) : 0;
|
|
623
|
+
for (let i = loopStart; i < data2.length; i++) {
|
|
624
|
+
const id = getId(i);
|
|
625
|
+
const size = getItemSize(id, i, data2[i]);
|
|
626
|
+
if (positions.get(id) !== top) {
|
|
627
|
+
positions.set(id, top);
|
|
628
|
+
}
|
|
629
|
+
if (startNoBuffer === null && top + size > scroll) {
|
|
630
|
+
startNoBuffer = i;
|
|
631
|
+
}
|
|
632
|
+
if (startBuffered === null && top + size > scroll - scrollBuffer) {
|
|
633
|
+
startBuffered = i;
|
|
634
|
+
}
|
|
635
|
+
if (startNoBuffer !== null) {
|
|
636
|
+
if (top <= scroll + scrollLength) {
|
|
637
|
+
endNoBuffer = i;
|
|
638
|
+
}
|
|
639
|
+
if (top <= scroll + scrollLength + scrollBuffer) {
|
|
640
|
+
endBuffered = i;
|
|
641
|
+
} else {
|
|
642
|
+
break;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
top += size;
|
|
646
|
+
}
|
|
647
|
+
Object.assign(refState.current, {
|
|
648
|
+
startBuffered,
|
|
649
|
+
startNoBuffer,
|
|
650
|
+
endBuffered,
|
|
651
|
+
endNoBuffer
|
|
652
|
+
});
|
|
653
|
+
if (startBuffered !== null && endBuffered !== null) {
|
|
654
|
+
const prevNumContainers = ctx.values.get("numContainers");
|
|
655
|
+
let numContainers = prevNumContainers;
|
|
656
|
+
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
657
|
+
let isContained = false;
|
|
658
|
+
const id = getId(i);
|
|
659
|
+
for (let j = 0; j < numContainers; j++) {
|
|
660
|
+
const key = peek$(ctx, `containerItemKey${j}`);
|
|
661
|
+
if (key === id) {
|
|
662
|
+
isContained = true;
|
|
663
|
+
break;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
if (!isContained) {
|
|
667
|
+
const top2 = (positions.get(id) || 0) + scrollAdjustPending;
|
|
668
|
+
let furthestIndex = -1;
|
|
669
|
+
let furthestDistance = 0;
|
|
670
|
+
for (let u = 0; u < numContainers; u++) {
|
|
671
|
+
const key = peek$(ctx, `containerItemKey${u}`);
|
|
672
|
+
if (key === void 0) {
|
|
673
|
+
furthestIndex = u;
|
|
674
|
+
break;
|
|
675
|
+
}
|
|
676
|
+
const index = (_b2 = refState.current) == null ? void 0 : _b2.indexByKey.get(key);
|
|
677
|
+
const pos = peek$(ctx, `containerPosition${u}`);
|
|
678
|
+
if (index < startBuffered || index > endBuffered) {
|
|
679
|
+
const distance = Math.abs(pos - top2);
|
|
680
|
+
if (index < 0 || distance > furthestDistance) {
|
|
681
|
+
furthestDistance = distance;
|
|
682
|
+
furthestIndex = u;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
if (furthestIndex >= 0) {
|
|
687
|
+
set$(ctx, `containerItemKey${furthestIndex}`, id);
|
|
688
|
+
} else {
|
|
689
|
+
const containerId = numContainers;
|
|
690
|
+
numContainers++;
|
|
691
|
+
set$(ctx, `containerItemKey${containerId}`, id);
|
|
692
|
+
set$(ctx, `containerPosition${containerId}`, POSITION_OUT_OF_VIEW);
|
|
693
|
+
if (__DEV__ && numContainers > peek$(ctx, "numContainersPooled")) {
|
|
694
|
+
console.warn(
|
|
695
|
+
"[legend-list] No container to recycle, consider increasing initialContainers or estimatedItemSize. numContainers:",
|
|
696
|
+
numContainers
|
|
697
|
+
);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
if (numContainers !== prevNumContainers) {
|
|
703
|
+
set$(ctx, "numContainers", numContainers);
|
|
704
|
+
if (numContainers > peek$(ctx, "numContainersPooled")) {
|
|
705
|
+
set$(ctx, "numContainersPooled", numContainers);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
for (let i = 0; i < numContainers; i++) {
|
|
709
|
+
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
710
|
+
const itemIndex = (_c2 = refState.current) == null ? void 0 : _c2.indexByKey.get(itemKey);
|
|
711
|
+
const item = data2[itemIndex];
|
|
712
|
+
if (item) {
|
|
713
|
+
const id = getId(itemIndex);
|
|
714
|
+
if (!(itemKey !== id || itemIndex < startBuffered || itemIndex > endBuffered)) {
|
|
715
|
+
const pos = (positions.get(id) || 0) + scrollAdjustPending;
|
|
716
|
+
const prevPos = peek$(ctx, `containerPosition${i}`);
|
|
717
|
+
if (pos >= 0 && pos !== prevPos) {
|
|
718
|
+
set$(ctx, `containerPosition${i}`, pos);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
if (refState.current.viewabilityConfigCallbackPairs) {
|
|
725
|
+
updateViewableItems(
|
|
726
|
+
refState.current,
|
|
727
|
+
ctx,
|
|
728
|
+
refState.current.viewabilityConfigCallbackPairs,
|
|
729
|
+
getId,
|
|
730
|
+
scrollLength,
|
|
731
|
+
startNoBuffer,
|
|
732
|
+
endNoBuffer
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
}, []);
|
|
736
|
+
const doUpdatePaddingTop = () => {
|
|
737
|
+
if (alignItemsAtEnd) {
|
|
738
|
+
const { scrollLength, totalSize } = refState.current;
|
|
739
|
+
const listPaddingTop = peek$(ctx, "stylePaddingTop") || 0;
|
|
740
|
+
const paddingTop = Math.max(0, Math.floor(scrollLength - totalSize - listPaddingTop));
|
|
741
|
+
set$(ctx, "paddingTop", paddingTop);
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
const doMaintainScrollAtEnd = (animated) => {
|
|
745
|
+
var _a2;
|
|
746
|
+
if (((_a2 = refState.current) == null ? void 0 : _a2.isAtBottom) && maintainScrollAtEnd) {
|
|
747
|
+
refState.current.scroll = refState.current.totalSize - refState.current.scrollLength;
|
|
748
|
+
requestAnimationFrame(() => {
|
|
749
|
+
var _a3;
|
|
750
|
+
(_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
|
|
751
|
+
animated
|
|
752
|
+
});
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
const checkAtBottom = () => {
|
|
757
|
+
var _a2;
|
|
758
|
+
const { scrollLength, scroll } = refState.current;
|
|
759
|
+
const totalSize = peek$(ctx, "totalSize");
|
|
760
|
+
const distanceFromEnd = totalSize - 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
|
+
(data == null ? void 0 : data.length) > ((_a = refState.current.data) == null ? void 0 : _a.length);
|
|
791
|
+
refState.current.data = data;
|
|
792
|
+
let totalSize = 0;
|
|
793
|
+
const indexByKey = /* @__PURE__ */ new Map();
|
|
794
|
+
for (let i = 0; i < data.length; i++) {
|
|
795
|
+
const key = getId(i);
|
|
796
|
+
indexByKey.set(key, i);
|
|
797
|
+
totalSize += getItemSize(key, i, data[i]);
|
|
798
|
+
if (maintainVisibleContentPosition && i < refState.current.startNoBuffer && !refState.current.indexByKey.has(key)) {
|
|
799
|
+
const size = getItemSize(key, i, data[i]);
|
|
800
|
+
adjustScroll(size);
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
addTotalSize(null, totalSize, true);
|
|
804
|
+
if (maintainVisibleContentPosition) {
|
|
805
|
+
for (const [key, index] of refState.current.indexByKey) {
|
|
806
|
+
if (index < refState.current.startNoBuffer && !indexByKey.has(key)) {
|
|
807
|
+
const size = (_b = refState.current.sizes.get(key)) != null ? _b : 0;
|
|
808
|
+
if (size) {
|
|
809
|
+
adjustScroll(-size);
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
refState.current.indexByKey = indexByKey;
|
|
815
|
+
if (!isFirst) {
|
|
816
|
+
refState.current.isEndReached = false;
|
|
817
|
+
const numContainers = peek$(ctx, "numContainers");
|
|
818
|
+
for (let i = 0; i < numContainers; i++) {
|
|
819
|
+
set$(ctx, `containerItemKey${i}`, void 0);
|
|
820
|
+
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
821
|
+
}
|
|
822
|
+
calculateItemsInView();
|
|
823
|
+
doMaintainScrollAtEnd(false);
|
|
824
|
+
}
|
|
825
|
+
checkAtBottom();
|
|
826
|
+
checkAtTop();
|
|
827
|
+
}
|
|
828
|
+
refState.current.renderItem = renderItem;
|
|
829
|
+
set$(ctx, "lastItemKey", getId(data[data.length - 1]));
|
|
830
|
+
set$(
|
|
831
|
+
ctx,
|
|
832
|
+
"stylePaddingTop",
|
|
833
|
+
(_f = (_e = (_c = StyleSheet.flatten(style)) == null ? void 0 : _c.paddingTop) != null ? _e : (_d = StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _d.paddingTop) != null ? _f : 0
|
|
834
|
+
);
|
|
835
|
+
const getRenderedItem = useCallback((key, containerId) => {
|
|
836
|
+
var _a2, _b2;
|
|
837
|
+
const state = refState.current;
|
|
838
|
+
if (!state) {
|
|
839
|
+
return null;
|
|
840
|
+
}
|
|
841
|
+
const { data: data2, indexByKey } = state;
|
|
842
|
+
const index = indexByKey.get(key);
|
|
843
|
+
if (index === void 0) {
|
|
534
844
|
return null;
|
|
535
845
|
}
|
|
536
846
|
const useViewability = (configId, callback) => {
|
|
537
|
-
const
|
|
847
|
+
const key2 = containerId + configId;
|
|
538
848
|
useInit(() => {
|
|
539
|
-
const value = ctx.mapViewabilityValues.get(
|
|
849
|
+
const value = ctx.mapViewabilityValues.get(key2);
|
|
540
850
|
if (value) {
|
|
541
851
|
callback(value);
|
|
542
852
|
}
|
|
543
853
|
});
|
|
544
|
-
ctx.mapViewabilityCallbacks.set(
|
|
854
|
+
ctx.mapViewabilityCallbacks.set(key2, callback);
|
|
545
855
|
useEffect(
|
|
546
856
|
() => () => {
|
|
547
|
-
ctx.mapViewabilityCallbacks.delete(
|
|
857
|
+
ctx.mapViewabilityCallbacks.delete(key2);
|
|
548
858
|
},
|
|
549
859
|
[]
|
|
550
860
|
);
|
|
551
861
|
};
|
|
552
862
|
const useViewabilityAmount = (callback) => {
|
|
553
863
|
useInit(() => {
|
|
554
|
-
const value = ctx.mapViewabilityAmountValues.get(
|
|
864
|
+
const value = ctx.mapViewabilityAmountValues.get(containerId);
|
|
555
865
|
if (value) {
|
|
556
866
|
callback(value);
|
|
557
867
|
}
|
|
558
868
|
});
|
|
559
|
-
ctx.mapViewabilityAmountCallbacks.set(
|
|
869
|
+
ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
|
|
560
870
|
useEffect(
|
|
561
871
|
() => () => {
|
|
562
|
-
ctx.mapViewabilityAmountCallbacks.delete(
|
|
872
|
+
ctx.mapViewabilityAmountCallbacks.delete(containerId);
|
|
563
873
|
},
|
|
564
874
|
[]
|
|
565
875
|
);
|
|
566
876
|
};
|
|
567
877
|
const useRecyclingEffect = (effect) => {
|
|
568
878
|
useEffect(() => {
|
|
569
|
-
const
|
|
879
|
+
const state2 = refState.current;
|
|
570
880
|
let prevIndex = index;
|
|
571
|
-
let prevItem =
|
|
572
|
-
const signal = `
|
|
573
|
-
|
|
574
|
-
const data3 =
|
|
881
|
+
let prevItem = state2.data[index];
|
|
882
|
+
const signal = `containerItemKey${containerId}`;
|
|
883
|
+
const run = () => {
|
|
884
|
+
const data3 = state2.data;
|
|
575
885
|
if (data3) {
|
|
576
|
-
const
|
|
886
|
+
const newKey = peek$(ctx, signal);
|
|
887
|
+
const newIndex = state2.indexByKey.get(newKey);
|
|
577
888
|
const newItem = data3[newIndex];
|
|
578
889
|
if (newItem) {
|
|
579
890
|
effect({
|
|
@@ -586,7 +897,9 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
586
897
|
prevIndex = newIndex;
|
|
587
898
|
prevItem = newItem;
|
|
588
899
|
}
|
|
589
|
-
}
|
|
900
|
+
};
|
|
901
|
+
run();
|
|
902
|
+
listen$(ctx, signal, run);
|
|
590
903
|
}, []);
|
|
591
904
|
};
|
|
592
905
|
const useRecyclingState = (updateState) => {
|
|
@@ -598,13 +911,13 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
598
911
|
prevItem: void 0
|
|
599
912
|
})
|
|
600
913
|
);
|
|
601
|
-
useRecyclingEffect((
|
|
602
|
-
const newState = updateState(
|
|
914
|
+
useRecyclingEffect((state2) => {
|
|
915
|
+
const newState = updateState(state2);
|
|
603
916
|
stateInfo[1](newState);
|
|
604
917
|
});
|
|
605
918
|
return stateInfo;
|
|
606
919
|
};
|
|
607
|
-
const renderedItem = (
|
|
920
|
+
const renderedItem = (_b2 = (_a2 = refState.current).renderItem) == null ? void 0 : _b2.call(_a2, {
|
|
608
921
|
item: data2[index],
|
|
609
922
|
index,
|
|
610
923
|
useViewability,
|
|
@@ -614,262 +927,98 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
614
927
|
});
|
|
615
928
|
return renderedItem;
|
|
616
929
|
}, []);
|
|
617
|
-
const calculateItemsInView = useCallback(() => {
|
|
618
|
-
unstable_batchedUpdates(() => {
|
|
619
|
-
var _a2, _b2, _c;
|
|
620
|
-
const {
|
|
621
|
-
data: data2,
|
|
622
|
-
scrollLength,
|
|
623
|
-
scroll: scrollState,
|
|
624
|
-
startNoBuffer: startNoBufferState,
|
|
625
|
-
startBuffered: startBufferedState,
|
|
626
|
-
endNoBuffer: endNoBufferState,
|
|
627
|
-
endBuffered: endBufferedState
|
|
628
|
-
} = refState.current;
|
|
629
|
-
if (!data2) {
|
|
630
|
-
return;
|
|
631
|
-
}
|
|
632
|
-
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
633
|
-
const scroll = scrollState - topPad;
|
|
634
|
-
const { sizes, positions } = refState.current;
|
|
635
|
-
let startNoBuffer = null;
|
|
636
|
-
let startBuffered = null;
|
|
637
|
-
let endNoBuffer = null;
|
|
638
|
-
let endBuffered = null;
|
|
639
|
-
let loopStart = startBufferedState || 0;
|
|
640
|
-
if (startBufferedState) {
|
|
641
|
-
for (let i = startBufferedState; i >= 0; i--) {
|
|
642
|
-
const id = getId(i);
|
|
643
|
-
const top2 = positions.get(id);
|
|
644
|
-
if (top2 !== void 0) {
|
|
645
|
-
const size = (_a2 = sizes.get(id)) != null ? _a2 : getItemSize(i, data2[i]);
|
|
646
|
-
const bottom = top2 + size;
|
|
647
|
-
if (bottom > scroll - scrollBuffer) {
|
|
648
|
-
loopStart = i;
|
|
649
|
-
} else {
|
|
650
|
-
break;
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
let top = loopStart > 0 ? positions.get(getId(loopStart)) : 0;
|
|
656
|
-
for (let i = loopStart; i < data2.length; i++) {
|
|
657
|
-
const id = getId(i);
|
|
658
|
-
const size = (_b2 = sizes.get(id)) != null ? _b2 : getItemSize(i, data2[i]);
|
|
659
|
-
if (positions.get(id) !== top) {
|
|
660
|
-
positions.set(id, top);
|
|
661
|
-
}
|
|
662
|
-
if (startNoBuffer === null && top + size > scroll) {
|
|
663
|
-
startNoBuffer = i;
|
|
664
|
-
}
|
|
665
|
-
if (startBuffered === null && top + size > scroll - scrollBuffer) {
|
|
666
|
-
startBuffered = i;
|
|
667
|
-
}
|
|
668
|
-
if (startNoBuffer !== null) {
|
|
669
|
-
if (top <= scroll + scrollLength) {
|
|
670
|
-
endNoBuffer = i;
|
|
671
|
-
}
|
|
672
|
-
if (top <= scroll + scrollLength + scrollBuffer) {
|
|
673
|
-
endBuffered = i;
|
|
674
|
-
} else {
|
|
675
|
-
break;
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
top += size;
|
|
679
|
-
}
|
|
680
|
-
Object.assign(refState.current, {
|
|
681
|
-
startBuffered,
|
|
682
|
-
startNoBuffer,
|
|
683
|
-
endBuffered,
|
|
684
|
-
endNoBuffer
|
|
685
|
-
});
|
|
686
|
-
if (startBuffered !== null && endBuffered !== null) {
|
|
687
|
-
const prevNumContainers = ctx.values.get("numContainers");
|
|
688
|
-
let numContainers = prevNumContainers;
|
|
689
|
-
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
690
|
-
let isContained = false;
|
|
691
|
-
for (let j = 0; j < numContainers; j++) {
|
|
692
|
-
const index = peek$(ctx, `containerIndex${j}`);
|
|
693
|
-
if (index === i) {
|
|
694
|
-
isContained = true;
|
|
695
|
-
break;
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
if (!isContained) {
|
|
699
|
-
const id = getId(i);
|
|
700
|
-
const top2 = positions.get(id) || 0;
|
|
701
|
-
let furthestIndex = -1;
|
|
702
|
-
let furthestDistance = 0;
|
|
703
|
-
for (let u = 0; u < numContainers; u++) {
|
|
704
|
-
const index = peek$(ctx, `containerIndex${u}`);
|
|
705
|
-
if (index < 0) {
|
|
706
|
-
furthestIndex = u;
|
|
707
|
-
break;
|
|
708
|
-
}
|
|
709
|
-
const pos = peek$(ctx, `containerPosition${u}`);
|
|
710
|
-
if (index < startBuffered || index > endBuffered) {
|
|
711
|
-
const distance = Math.abs(pos - top2);
|
|
712
|
-
if (index < 0 || distance > furthestDistance) {
|
|
713
|
-
furthestDistance = distance;
|
|
714
|
-
furthestIndex = u;
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
if (furthestIndex >= 0) {
|
|
719
|
-
set$(ctx, `containerIndex${furthestIndex}`, i);
|
|
720
|
-
} else {
|
|
721
|
-
if (__DEV__) {
|
|
722
|
-
console.warn(
|
|
723
|
-
"[legend-list] No container to recycle, consider increasing initialContainers or estimatedItemSize",
|
|
724
|
-
i
|
|
725
|
-
);
|
|
726
|
-
}
|
|
727
|
-
const containerId = numContainers;
|
|
728
|
-
numContainers++;
|
|
729
|
-
set$(ctx, `containerIndex${containerId}`, i);
|
|
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, `containerIndex${i}`);
|
|
739
|
-
const item = data2[itemIndex];
|
|
740
|
-
if (item) {
|
|
741
|
-
const id = getId(itemIndex);
|
|
742
|
-
if (itemIndex < startBuffered || itemIndex > endBuffered) {
|
|
743
|
-
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
744
|
-
} else {
|
|
745
|
-
const pos = (_c = positions.get(id)) != null ? _c : -1;
|
|
746
|
-
const prevPos = peek$(ctx, `containerPosition${i}`);
|
|
747
|
-
if (pos >= 0 && pos !== prevPos) {
|
|
748
|
-
set$(ctx, `containerPosition${i}`, pos);
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
if (refState.current.viewabilityConfigCallbackPairs) {
|
|
755
|
-
updateViewableItems(
|
|
756
|
-
refState.current,
|
|
757
|
-
ctx,
|
|
758
|
-
refState.current.viewabilityConfigCallbackPairs,
|
|
759
|
-
getId,
|
|
760
|
-
scrollLength,
|
|
761
|
-
startNoBuffer,
|
|
762
|
-
endNoBuffer
|
|
763
|
-
);
|
|
764
|
-
}
|
|
765
|
-
});
|
|
766
|
-
}, []);
|
|
767
930
|
useInit(() => {
|
|
768
|
-
var _a2, _b2;
|
|
769
931
|
refState.current.viewabilityConfigCallbackPairs = setupViewability(props);
|
|
770
932
|
const scrollLength = refState.current.scrollLength;
|
|
771
933
|
const averageItemSize = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, data[0]);
|
|
772
|
-
const numContainers = initialNumContainers || Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize)
|
|
934
|
+
const numContainers = initialNumContainers || Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize);
|
|
773
935
|
for (let i = 0; i < numContainers; i++) {
|
|
774
|
-
set$(ctx, `containerIndex${i}`, -1);
|
|
775
936
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
776
937
|
}
|
|
777
938
|
set$(ctx, "numContainers", numContainers);
|
|
939
|
+
set$(ctx, "numContainersPooled", numContainers * 2);
|
|
778
940
|
calculateItemsInView();
|
|
779
|
-
const sizes = (_a2 = refState.current) == null ? void 0 : _a2.sizes;
|
|
780
|
-
let totalSize = 0;
|
|
781
|
-
for (let i = 0; i < data.length; i++) {
|
|
782
|
-
const id = getId(i);
|
|
783
|
-
totalSize += (_b2 = sizes.get(id)) != null ? _b2 : getItemSize(i, data[i]);
|
|
784
|
-
}
|
|
785
|
-
addTotalSize(totalSize);
|
|
786
941
|
});
|
|
787
|
-
const
|
|
942
|
+
const updateItemSize = useCallback((key, size) => {
|
|
788
943
|
var _a2;
|
|
789
|
-
const { scrollLength, scroll } = refState.current;
|
|
790
|
-
const totalSize = peek$(ctx, "totalSize");
|
|
791
|
-
const distanceFromEnd = totalSize - scroll - scrollLength;
|
|
792
|
-
if (refState.current) {
|
|
793
|
-
refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
794
|
-
}
|
|
795
|
-
if (onEndReached && !((_a2 = refState.current) == null ? void 0 : _a2.isEndReached)) {
|
|
796
|
-
if (distanceFromEnd < onEndReachedThreshold * scrollLength) {
|
|
797
|
-
if (refState.current) {
|
|
798
|
-
refState.current.isEndReached = true;
|
|
799
|
-
}
|
|
800
|
-
onEndReached({ distanceFromEnd });
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
};
|
|
804
|
-
useEffect(() => {
|
|
805
|
-
if (refState.current) {
|
|
806
|
-
refState.current.isEndReached = false;
|
|
807
|
-
}
|
|
808
|
-
const numContainers = peek$(ctx, "numContainers");
|
|
809
|
-
if (data.length < numContainers) {
|
|
810
|
-
for (let i = 0; i < numContainers; i++) {
|
|
811
|
-
const itemIndex = peek$(ctx, `containerIndex${i}`);
|
|
812
|
-
if (itemIndex >= data.length) {
|
|
813
|
-
set$(ctx, `containerIndex${i}`, -1);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
calculateItemsInView();
|
|
818
|
-
checkAtBottom();
|
|
819
|
-
}, [data]);
|
|
820
|
-
const updateItemSize = useCallback((index, size) => {
|
|
821
|
-
var _a2, _b2, _c, _d;
|
|
822
944
|
const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
|
|
823
945
|
if (!data2) {
|
|
824
946
|
return;
|
|
825
947
|
}
|
|
826
|
-
const sizes
|
|
827
|
-
const
|
|
828
|
-
const wasInFirstRender =
|
|
829
|
-
const prevSize = sizes.get(
|
|
948
|
+
const { sizes, indexByKey, idsInFirstRender } = refState.current;
|
|
949
|
+
const index = indexByKey.get(key);
|
|
950
|
+
const wasInFirstRender = idsInFirstRender.has(key);
|
|
951
|
+
const prevSize = sizes.get(key) || (wasInFirstRender ? getItemSize(key, index, data2[index]) : 0);
|
|
830
952
|
if (!prevSize || Math.abs(prevSize - size) > 0.5) {
|
|
831
|
-
sizes.set(
|
|
832
|
-
addTotalSize(size - prevSize);
|
|
833
|
-
|
|
834
|
-
requestAnimationFrame(() => {
|
|
835
|
-
var _a3;
|
|
836
|
-
(_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
|
|
837
|
-
animated: true
|
|
838
|
-
});
|
|
839
|
-
});
|
|
840
|
-
}
|
|
953
|
+
sizes.set(key, size);
|
|
954
|
+
addTotalSize(key, size - prevSize);
|
|
955
|
+
doMaintainScrollAtEnd(true);
|
|
841
956
|
const state = refState.current;
|
|
842
|
-
|
|
957
|
+
const scrollVelocity = state.scrollVelocity;
|
|
958
|
+
if (!state.animFrameLayout && (Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1)) {
|
|
843
959
|
state.animFrameLayout = requestAnimationFrame(() => {
|
|
844
960
|
state.animFrameLayout = null;
|
|
845
|
-
calculateItemsInView();
|
|
961
|
+
calculateItemsInView(state.scrollVelocity);
|
|
846
962
|
});
|
|
847
963
|
}
|
|
848
964
|
}
|
|
849
965
|
}, []);
|
|
850
|
-
const handleScrollDebounced = useCallback(() => {
|
|
851
|
-
|
|
966
|
+
const handleScrollDebounced = useCallback((velocity) => {
|
|
967
|
+
var _a2, _b2;
|
|
968
|
+
const scrollAdjustPending = (_b2 = (_a2 = refState.current) == null ? void 0 : _a2.scrollAdjustPending) != null ? _b2 : 0;
|
|
969
|
+
set$(ctx, "scrollAdjust", scrollAdjustPending);
|
|
970
|
+
calculateItemsInView(velocity);
|
|
852
971
|
checkAtBottom();
|
|
853
|
-
|
|
854
|
-
refState.current.animFrameScroll = null;
|
|
855
|
-
}
|
|
972
|
+
checkAtTop();
|
|
856
973
|
}, []);
|
|
857
974
|
const onLayout = useCallback((event) => {
|
|
858
|
-
|
|
975
|
+
let scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
976
|
+
if (!USE_CONTENT_INSET) {
|
|
977
|
+
scrollLength += event.nativeEvent.layout[horizontal ? "x" : "y"];
|
|
978
|
+
}
|
|
859
979
|
refState.current.scrollLength = scrollLength;
|
|
980
|
+
doMaintainScrollAtEnd(false);
|
|
981
|
+
doUpdatePaddingTop();
|
|
982
|
+
checkAtBottom();
|
|
983
|
+
checkAtTop();
|
|
984
|
+
if (__DEV__) {
|
|
985
|
+
const isWidthZero = event.nativeEvent.layout.width === 0;
|
|
986
|
+
const isHeightZero = event.nativeEvent.layout.height === 0;
|
|
987
|
+
if (isWidthZero || isHeightZero) {
|
|
988
|
+
console.warn(
|
|
989
|
+
`[legend-list] List ${isWidthZero ? "width" : "height"} is 0. You may need to set a style or \`flex: \` for the list, because children are absolutely positioned.`
|
|
990
|
+
);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
860
993
|
}, []);
|
|
861
994
|
const handleScroll = useCallback(
|
|
862
995
|
(event, fromSelf) => {
|
|
863
|
-
var _a2, _b2,
|
|
864
|
-
if (((_b2 = (_a2 = event.nativeEvent) == null ? void 0 : _a2.contentSize) == null ? void 0 : _b2.height) === 0 && ((
|
|
996
|
+
var _a2, _b2, _c2;
|
|
997
|
+
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) {
|
|
865
998
|
return;
|
|
866
999
|
}
|
|
867
|
-
refState.current
|
|
1000
|
+
const state = refState.current;
|
|
1001
|
+
state.hasScrolled = true;
|
|
1002
|
+
const currentTime = performance.now();
|
|
868
1003
|
const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
|
|
869
|
-
|
|
870
|
-
if (
|
|
871
|
-
|
|
1004
|
+
state.scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
1005
|
+
if (state.scrollHistory.length > 5) {
|
|
1006
|
+
state.scrollHistory.shift();
|
|
1007
|
+
}
|
|
1008
|
+
let velocity = 0;
|
|
1009
|
+
if (state.scrollHistory.length >= 2) {
|
|
1010
|
+
const newest = state.scrollHistory[state.scrollHistory.length - 1];
|
|
1011
|
+
const oldest = state.scrollHistory[0];
|
|
1012
|
+
const scrollDiff = newest.scroll - oldest.scroll;
|
|
1013
|
+
const timeDiff = newest.time - oldest.time;
|
|
1014
|
+
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
872
1015
|
}
|
|
1016
|
+
state.scrollPrev = state.scroll;
|
|
1017
|
+
state.scrollPrevTime = state.scrollTime;
|
|
1018
|
+
state.scroll = newScroll;
|
|
1019
|
+
state.scrollTime = currentTime;
|
|
1020
|
+
state.scrollVelocity = velocity;
|
|
1021
|
+
handleScrollDebounced(velocity);
|
|
873
1022
|
if (!fromSelf) {
|
|
874
1023
|
onScrollProp == null ? void 0 : onScrollProp(event);
|
|
875
1024
|
}
|
|
@@ -905,12 +1054,10 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
905
1054
|
},
|
|
906
1055
|
[]
|
|
907
1056
|
);
|
|
908
|
-
return /* @__PURE__ */
|
|
1057
|
+
return /* @__PURE__ */ React7.createElement(
|
|
909
1058
|
ListComponent,
|
|
910
1059
|
{
|
|
911
1060
|
...rest,
|
|
912
|
-
contentContainerStyle,
|
|
913
|
-
style,
|
|
914
1061
|
horizontal,
|
|
915
1062
|
refScroller,
|
|
916
1063
|
initialContentOffset,
|