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