@legendapp/list 1.0.0-beta.4 → 1.0.0-beta.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -37
- package/animated.d.mts +53 -4
- package/animated.d.ts +53 -4
- package/index.d.mts +330 -61
- package/index.d.ts +330 -61
- package/index.js +961 -398
- package/index.mjs +936 -373
- package/keyboard-controller.d.mts +396 -0
- package/keyboard-controller.d.ts +396 -0
- package/keyboard-controller.js +46 -0
- package/keyboard-controller.mjs +25 -0
- package/package.json +3 -6
- package/reanimated.d.mts +13 -9
- package/reanimated.d.ts +13 -9
- package/reanimated.js +20 -16
- package/reanimated.mjs +21 -17
package/index.mjs
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
1
|
+
import * as React6 from 'react';
|
|
2
|
+
import React6__default, { memo, useReducer, useEffect, createContext, useMemo, useRef, useCallback, useImperativeHandle, useSyncExternalStore, useContext, useState, forwardRef, useLayoutEffect } from 'react';
|
|
3
|
+
import { View, Text, Platform, Animated, ScrollView, StyleSheet, Dimensions, RefreshControl } from 'react-native';
|
|
4
4
|
|
|
5
5
|
// src/LegendList.tsx
|
|
6
|
-
var ContextState =
|
|
6
|
+
var ContextState = React6.createContext(null);
|
|
7
7
|
function StateProvider({ children }) {
|
|
8
|
-
const [value] =
|
|
8
|
+
const [value] = React6.useState(() => ({
|
|
9
9
|
listeners: /* @__PURE__ */ new Map(),
|
|
10
10
|
values: /* @__PURE__ */ new Map(),
|
|
11
11
|
mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
|
|
12
12
|
mapViewabilityValues: /* @__PURE__ */ new Map(),
|
|
13
13
|
mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
|
|
14
|
-
mapViewabilityAmountValues: /* @__PURE__ */ new Map()
|
|
14
|
+
mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
|
|
15
|
+
columnWrapperStyle: void 0
|
|
15
16
|
}));
|
|
16
|
-
return /* @__PURE__ */
|
|
17
|
+
return /* @__PURE__ */ React6.createElement(ContextState.Provider, { value }, children);
|
|
17
18
|
}
|
|
18
19
|
function useStateContext() {
|
|
19
|
-
return
|
|
20
|
+
return React6.useContext(ContextState);
|
|
20
21
|
}
|
|
21
22
|
function createSelectorFunctions(ctx, signalName) {
|
|
22
23
|
return {
|
|
@@ -25,8 +26,8 @@ function createSelectorFunctions(ctx, signalName) {
|
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
28
|
function use$(signalName) {
|
|
28
|
-
const ctx =
|
|
29
|
-
const { subscribe, get } =
|
|
29
|
+
const ctx = React6.useContext(ContextState);
|
|
30
|
+
const { subscribe, get } = React6.useMemo(() => createSelectorFunctions(ctx, signalName), []);
|
|
30
31
|
const value = useSyncExternalStore(subscribe, get);
|
|
31
32
|
return value;
|
|
32
33
|
}
|
|
@@ -56,6 +57,66 @@ function set$(ctx, signalName, value) {
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
}
|
|
60
|
+
function getContentSize(ctx) {
|
|
61
|
+
const { values } = ctx;
|
|
62
|
+
const stylePaddingTop = values.get("stylePaddingTop") || 0;
|
|
63
|
+
const headerSize = values.get("headerSize") || 0;
|
|
64
|
+
const footerSize = values.get("footerSize") || 0;
|
|
65
|
+
const totalSize = values.get("totalSize") || 0;
|
|
66
|
+
return headerSize + footerSize + totalSize + stylePaddingTop;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/DebugView.tsx
|
|
70
|
+
var DebugRow = ({ children }) => {
|
|
71
|
+
return /* @__PURE__ */ React.createElement(View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" } }, children);
|
|
72
|
+
};
|
|
73
|
+
var DebugView = memo(function DebugView2({ state }) {
|
|
74
|
+
const ctx = useStateContext();
|
|
75
|
+
const totalSize = use$("totalSize") || 0;
|
|
76
|
+
const totalSizeWithScrollAdjust = use$("totalSizeWithScrollAdjust") || 0;
|
|
77
|
+
const scrollAdjust = use$("scrollAdjust") || 0;
|
|
78
|
+
const rawScroll = use$("debugRawScroll") || 0;
|
|
79
|
+
const scroll = use$("debugComputedScroll") || 0;
|
|
80
|
+
const contentSize = getContentSize(ctx);
|
|
81
|
+
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
82
|
+
use$("numContainers");
|
|
83
|
+
use$("numContainersPooled");
|
|
84
|
+
useInterval(() => {
|
|
85
|
+
forceUpdate();
|
|
86
|
+
}, 100);
|
|
87
|
+
return /* @__PURE__ */ React.createElement(
|
|
88
|
+
View,
|
|
89
|
+
{
|
|
90
|
+
style: {
|
|
91
|
+
position: "absolute",
|
|
92
|
+
top: 0,
|
|
93
|
+
right: 0,
|
|
94
|
+
paddingLeft: 4,
|
|
95
|
+
paddingBottom: 4,
|
|
96
|
+
// height: 100,
|
|
97
|
+
backgroundColor: "#FFFFFFCC",
|
|
98
|
+
padding: 4,
|
|
99
|
+
borderRadius: 4
|
|
100
|
+
},
|
|
101
|
+
pointerEvents: "none"
|
|
102
|
+
},
|
|
103
|
+
/* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(Text, null, "TotalSize:"), /* @__PURE__ */ React.createElement(Text, null, totalSize.toFixed(2))),
|
|
104
|
+
/* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(Text, null, "ContentSize:"), /* @__PURE__ */ React.createElement(Text, null, contentSize.toFixed(2))),
|
|
105
|
+
/* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(Text, null, "At end:"), /* @__PURE__ */ React.createElement(Text, null, String(state.isAtBottom))),
|
|
106
|
+
/* @__PURE__ */ React.createElement(Text, null),
|
|
107
|
+
/* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(Text, null, "ScrollAdjust:"), /* @__PURE__ */ React.createElement(Text, null, scrollAdjust.toFixed(2))),
|
|
108
|
+
/* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(Text, null, "TotalSizeReal: "), /* @__PURE__ */ React.createElement(Text, null, totalSizeWithScrollAdjust.toFixed(2))),
|
|
109
|
+
/* @__PURE__ */ React.createElement(Text, null),
|
|
110
|
+
/* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(Text, null, "RawScroll: "), /* @__PURE__ */ React.createElement(Text, null, rawScroll.toFixed(2))),
|
|
111
|
+
/* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(Text, null, "ComputedScroll: "), /* @__PURE__ */ React.createElement(Text, null, scroll.toFixed(2)))
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
function useInterval(callback, delay) {
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
const interval = setInterval(callback, delay);
|
|
117
|
+
return () => clearInterval(interval);
|
|
118
|
+
}, [delay]);
|
|
119
|
+
}
|
|
59
120
|
var symbolFirst = Symbol();
|
|
60
121
|
function useInit(cb) {
|
|
61
122
|
const refValue = useRef(symbolFirst);
|
|
@@ -141,10 +202,11 @@ function useRecyclingState(valueOrFun) {
|
|
|
141
202
|
});
|
|
142
203
|
return stateInfo;
|
|
143
204
|
}
|
|
144
|
-
var
|
|
145
|
-
return
|
|
205
|
+
var LeanViewComponent = React6.forwardRef((props, ref) => {
|
|
206
|
+
return React6.createElement("RCTView", { ...props, ref });
|
|
146
207
|
});
|
|
147
|
-
|
|
208
|
+
LeanViewComponent.displayName = "RCTView";
|
|
209
|
+
var LeanView = Platform.OS === "android" || Platform.OS === "ios" ? LeanViewComponent : View;
|
|
148
210
|
|
|
149
211
|
// src/constants.ts
|
|
150
212
|
var POSITION_OUT_OF_VIEW = -1e7;
|
|
@@ -153,6 +215,8 @@ var ANCHORED_POSITION_OUT_OF_VIEW = {
|
|
|
153
215
|
relativeCoordinate: POSITION_OUT_OF_VIEW,
|
|
154
216
|
top: POSITION_OUT_OF_VIEW
|
|
155
217
|
};
|
|
218
|
+
var ENABLE_DEVMODE = __DEV__ && false;
|
|
219
|
+
var ENABLE_DEBUG_VIEW = __DEV__ && false;
|
|
156
220
|
|
|
157
221
|
// src/Container.tsx
|
|
158
222
|
var isNewArchitecture = global.nativeFabricUIManager != null;
|
|
@@ -164,13 +228,27 @@ var Container = ({
|
|
|
164
228
|
updateItemSize,
|
|
165
229
|
ItemSeparatorComponent
|
|
166
230
|
}) => {
|
|
167
|
-
useStateContext();
|
|
231
|
+
const ctx = useStateContext();
|
|
232
|
+
const columnWrapperStyle = ctx.columnWrapperStyle;
|
|
168
233
|
const maintainVisibleContentPosition = use$("maintainVisibleContentPosition");
|
|
169
234
|
const position = use$(`containerPosition${id}`) || ANCHORED_POSITION_OUT_OF_VIEW;
|
|
170
235
|
const column = use$(`containerColumn${id}`) || 0;
|
|
171
236
|
const numColumns = use$("numColumns");
|
|
237
|
+
const lastItemKeys = use$("lastItemKeys");
|
|
238
|
+
const itemKey = use$(`containerItemKey${id}`);
|
|
239
|
+
const data = use$(`containerItemData${id}`);
|
|
240
|
+
const extraData = use$("extraData");
|
|
241
|
+
const refLastSize = useRef();
|
|
172
242
|
const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
|
|
173
243
|
const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
|
|
244
|
+
let verticalPaddingStyles;
|
|
245
|
+
if (columnWrapperStyle) {
|
|
246
|
+
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
247
|
+
verticalPaddingStyles = {
|
|
248
|
+
paddingBottom: !lastItemKeys.includes(itemKey) ? rowGap || gap || void 0 : void 0,
|
|
249
|
+
paddingHorizontal: (columnGap || gap || 0) / 2
|
|
250
|
+
};
|
|
251
|
+
}
|
|
174
252
|
const style = horizontal ? {
|
|
175
253
|
flexDirection: ItemSeparatorComponent ? "row" : void 0,
|
|
176
254
|
position: "absolute",
|
|
@@ -183,68 +261,96 @@ var Container = ({
|
|
|
183
261
|
left: otherAxisPos,
|
|
184
262
|
right: numColumns > 1 ? null : 0,
|
|
185
263
|
width: otherAxisSize,
|
|
186
|
-
top: position.relativeCoordinate
|
|
264
|
+
top: position.relativeCoordinate,
|
|
265
|
+
...verticalPaddingStyles || {}
|
|
187
266
|
};
|
|
188
|
-
const lastItemKey = use$("lastItemKey");
|
|
189
|
-
const itemKey = use$(`containerItemKey${id}`);
|
|
190
|
-
const data = use$(`containerItemData${id}`);
|
|
191
|
-
const extraData = use$("extraData");
|
|
192
267
|
const renderedItemInfo = useMemo(
|
|
193
|
-
() => itemKey !== void 0
|
|
268
|
+
() => itemKey !== void 0 ? getRenderedItem(itemKey) : null,
|
|
194
269
|
[itemKey, data, extraData]
|
|
195
270
|
);
|
|
196
271
|
const { index, renderedItem } = renderedItemInfo || {};
|
|
197
272
|
const onLayout = (event) => {
|
|
198
273
|
if (itemKey !== void 0) {
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
updateItemSize(id, itemKey, size);
|
|
274
|
+
const layout = event.nativeEvent.layout;
|
|
275
|
+
const size = Math.floor(layout[horizontal ? "width" : "height"] * 8) / 8;
|
|
276
|
+
refLastSize.current = size;
|
|
277
|
+
updateItemSize(itemKey, size);
|
|
205
278
|
}
|
|
206
279
|
};
|
|
207
280
|
const ref = useRef(null);
|
|
208
281
|
if (isNewArchitecture) {
|
|
209
282
|
useLayoutEffect(() => {
|
|
210
283
|
var _a, _b;
|
|
211
|
-
if (itemKey) {
|
|
284
|
+
if (itemKey !== void 0) {
|
|
212
285
|
const measured = (_b = (_a = ref.current) == null ? void 0 : _a.unstable_getBoundingClientRect) == null ? void 0 : _b.call(_a);
|
|
213
286
|
if (measured) {
|
|
214
287
|
const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
|
|
215
288
|
if (size) {
|
|
216
|
-
updateItemSize(
|
|
289
|
+
updateItemSize(itemKey, size);
|
|
217
290
|
}
|
|
218
291
|
}
|
|
219
292
|
}
|
|
220
293
|
}, [itemKey]);
|
|
294
|
+
} else {
|
|
295
|
+
useEffect(() => {
|
|
296
|
+
if (itemKey) {
|
|
297
|
+
const timeout = setTimeout(() => {
|
|
298
|
+
if (refLastSize.current) {
|
|
299
|
+
updateItemSize(itemKey, refLastSize.current);
|
|
300
|
+
}
|
|
301
|
+
}, 16);
|
|
302
|
+
return () => {
|
|
303
|
+
clearTimeout(timeout);
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
}, [itemKey]);
|
|
221
307
|
}
|
|
222
308
|
const contextValue = useMemo(
|
|
223
309
|
() => ({ containerId: id, itemKey, index, value: data }),
|
|
224
310
|
[id, itemKey, index, data]
|
|
225
311
|
);
|
|
226
|
-
const contentFragment = /* @__PURE__ */
|
|
312
|
+
const contentFragment = /* @__PURE__ */ React6__default.createElement(React6__default.Fragment, { key: recycleItems ? void 0 : itemKey }, /* @__PURE__ */ React6__default.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && !lastItemKeys.includes(itemKey) && /* @__PURE__ */ React6__default.createElement(ItemSeparatorComponent, { leadingItem: renderedItemInfo.item })));
|
|
227
313
|
if (maintainVisibleContentPosition) {
|
|
228
314
|
const anchorStyle = position.type === "top" ? { position: "absolute", top: 0, left: 0, right: 0 } : { position: "absolute", bottom: 0, left: 0, right: 0 };
|
|
229
|
-
|
|
315
|
+
if (ENABLE_DEVMODE) {
|
|
316
|
+
anchorStyle.borderColor = position.type === "top" ? "red" : "blue";
|
|
317
|
+
anchorStyle.borderWidth = 1;
|
|
318
|
+
}
|
|
319
|
+
return /* @__PURE__ */ React6__default.createElement(LeanView, { style }, /* @__PURE__ */ React6__default.createElement(LeanView, { style: anchorStyle, onLayout, ref }, contentFragment, ENABLE_DEVMODE && /* @__PURE__ */ React6__default.createElement(Text, { style: { position: "absolute", top: 0, left: 0, zIndex: 1e3 } }, position.top)));
|
|
230
320
|
}
|
|
231
|
-
return /* @__PURE__ */
|
|
321
|
+
return /* @__PURE__ */ React6__default.createElement(LeanView, { style, onLayout, ref }, contentFragment);
|
|
232
322
|
};
|
|
233
|
-
var
|
|
323
|
+
var typedForwardRef = forwardRef;
|
|
324
|
+
var typedMemo = memo;
|
|
325
|
+
var useAnimatedValue = (initialValue) => {
|
|
234
326
|
return useRef(new Animated.Value(initialValue)).current;
|
|
235
|
-
}
|
|
236
|
-
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
// src/useValue$.ts
|
|
330
|
+
function useValue$(key, getValue, useMicrotask) {
|
|
237
331
|
var _a;
|
|
238
332
|
const ctx = useStateContext();
|
|
239
333
|
const animValue = useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
|
|
240
334
|
useMemo(() => {
|
|
241
|
-
|
|
335
|
+
let newValue = void 0;
|
|
336
|
+
listen$(ctx, key, (v) => {
|
|
337
|
+
if (useMicrotask && newValue === void 0) {
|
|
338
|
+
queueMicrotask(() => {
|
|
339
|
+
animValue.setValue(newValue);
|
|
340
|
+
newValue = void 0;
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
newValue = getValue ? getValue(v) : v;
|
|
344
|
+
if (!useMicrotask) {
|
|
345
|
+
animValue.setValue(newValue);
|
|
346
|
+
}
|
|
347
|
+
});
|
|
242
348
|
}, []);
|
|
243
349
|
return animValue;
|
|
244
350
|
}
|
|
245
351
|
|
|
246
352
|
// src/Containers.tsx
|
|
247
|
-
var Containers =
|
|
353
|
+
var Containers = typedMemo(function Containers2({
|
|
248
354
|
horizontal,
|
|
249
355
|
recycleItems,
|
|
250
356
|
ItemSeparatorComponent,
|
|
@@ -252,13 +358,21 @@ var Containers = React5.memo(function Containers2({
|
|
|
252
358
|
updateItemSize,
|
|
253
359
|
getRenderedItem
|
|
254
360
|
}) {
|
|
361
|
+
const ctx = useStateContext();
|
|
362
|
+
const columnWrapperStyle = ctx.columnWrapperStyle;
|
|
363
|
+
const numColumns = use$("numColumns");
|
|
255
364
|
const numContainers = use$("numContainersPooled");
|
|
256
|
-
const animSize = useValue$(
|
|
365
|
+
const animSize = useValue$(
|
|
366
|
+
"totalSizeWithScrollAdjust",
|
|
367
|
+
void 0,
|
|
368
|
+
/*useMicrotask*/
|
|
369
|
+
true
|
|
370
|
+
);
|
|
257
371
|
const animOpacity = waitForInitialLayout ? useValue$("containersDidLayout", (value) => value ? 1 : 0) : void 0;
|
|
258
372
|
const containers = [];
|
|
259
373
|
for (let i = 0; i < numContainers; i++) {
|
|
260
374
|
containers.push(
|
|
261
|
-
/* @__PURE__ */
|
|
375
|
+
/* @__PURE__ */ React6.createElement(
|
|
262
376
|
Container,
|
|
263
377
|
{
|
|
264
378
|
id: i,
|
|
@@ -273,20 +387,78 @@ var Containers = React5.memo(function Containers2({
|
|
|
273
387
|
);
|
|
274
388
|
}
|
|
275
389
|
const style = horizontal ? { width: animSize, opacity: animOpacity } : { height: animSize, opacity: animOpacity };
|
|
276
|
-
|
|
390
|
+
if (columnWrapperStyle && !horizontal && numColumns > 1) {
|
|
391
|
+
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
392
|
+
const mx = (columnGap || gap || 0) / 2;
|
|
393
|
+
if (mx) {
|
|
394
|
+
style.marginHorizontal = -mx;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return /* @__PURE__ */ React6.createElement(Animated.View, { style }, containers);
|
|
277
398
|
});
|
|
278
399
|
|
|
279
400
|
// src/ListComponent.tsx
|
|
280
401
|
var getComponent = (Component) => {
|
|
281
|
-
if (
|
|
402
|
+
if (React6.isValidElement(Component)) {
|
|
282
403
|
return Component;
|
|
283
404
|
}
|
|
284
405
|
if (Component) {
|
|
285
|
-
return /* @__PURE__ */
|
|
406
|
+
return /* @__PURE__ */ React6.createElement(Component, null);
|
|
286
407
|
}
|
|
287
408
|
return null;
|
|
288
409
|
};
|
|
289
|
-
var
|
|
410
|
+
var PaddingAndAdjust = () => {
|
|
411
|
+
const animPaddingTop = useValue$("paddingTop", (v) => v, true);
|
|
412
|
+
const animScrollAdjust = useValue$("scrollAdjust", (v) => v, true);
|
|
413
|
+
const additionalSize = { marginTop: animScrollAdjust, paddingTop: animPaddingTop };
|
|
414
|
+
return /* @__PURE__ */ React6.createElement(Animated.View, { style: additionalSize });
|
|
415
|
+
};
|
|
416
|
+
var PaddingAndAdjustDevMode = () => {
|
|
417
|
+
const animPaddingTop = useValue$("paddingTop", (v) => v, true);
|
|
418
|
+
const animScrollAdjust = useValue$("scrollAdjust", (v) => v, true);
|
|
419
|
+
return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Animated.View, { style: { marginTop: animScrollAdjust } }), /* @__PURE__ */ React6.createElement(Animated.View, { style: { paddingTop: animPaddingTop } }), /* @__PURE__ */ React6.createElement(
|
|
420
|
+
Animated.View,
|
|
421
|
+
{
|
|
422
|
+
style: {
|
|
423
|
+
position: "absolute",
|
|
424
|
+
top: Animated.add(animScrollAdjust, Animated.multiply(animScrollAdjust, -1)),
|
|
425
|
+
height: animPaddingTop,
|
|
426
|
+
left: 0,
|
|
427
|
+
right: 0,
|
|
428
|
+
backgroundColor: "green"
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
), /* @__PURE__ */ React6.createElement(
|
|
432
|
+
Animated.View,
|
|
433
|
+
{
|
|
434
|
+
style: {
|
|
435
|
+
position: "absolute",
|
|
436
|
+
top: animPaddingTop,
|
|
437
|
+
height: animScrollAdjust,
|
|
438
|
+
left: -16,
|
|
439
|
+
right: -16,
|
|
440
|
+
backgroundColor: "lightblue"
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
), /* @__PURE__ */ React6.createElement(
|
|
444
|
+
Animated.View,
|
|
445
|
+
{
|
|
446
|
+
style: {
|
|
447
|
+
position: "absolute",
|
|
448
|
+
top: animPaddingTop,
|
|
449
|
+
height: Animated.multiply(animScrollAdjust, -1),
|
|
450
|
+
width: 8,
|
|
451
|
+
right: 4,
|
|
452
|
+
borderStyle: "dashed",
|
|
453
|
+
borderColor: "blue",
|
|
454
|
+
borderWidth: 1,
|
|
455
|
+
backgroundColor: "lightblue"
|
|
456
|
+
//backgroundColor: "blue",
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
));
|
|
460
|
+
};
|
|
461
|
+
var ListComponent = typedMemo(function ListComponent2({
|
|
290
462
|
style,
|
|
291
463
|
contentContainerStyle,
|
|
292
464
|
horizontal,
|
|
@@ -307,22 +479,22 @@ var ListComponent = React5.memo(function ListComponent2({
|
|
|
307
479
|
refScrollView,
|
|
308
480
|
maintainVisibleContentPosition,
|
|
309
481
|
renderScrollComponent,
|
|
482
|
+
onRefresh,
|
|
483
|
+
refreshing,
|
|
484
|
+
progressViewOffset,
|
|
310
485
|
...rest
|
|
311
486
|
}) {
|
|
312
487
|
const ctx = useStateContext();
|
|
313
|
-
const animPaddingTop = useValue$("paddingTop");
|
|
314
|
-
const animScrollAdjust = useValue$("scrollAdjust");
|
|
315
488
|
const ScrollComponent = renderScrollComponent ? useMemo(
|
|
316
|
-
() =>
|
|
489
|
+
() => React6.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
|
|
317
490
|
[renderScrollComponent]
|
|
318
491
|
) : ScrollView;
|
|
319
|
-
|
|
320
|
-
return /* @__PURE__ */ React5.createElement(
|
|
492
|
+
return /* @__PURE__ */ React6.createElement(
|
|
321
493
|
ScrollComponent,
|
|
322
494
|
{
|
|
323
495
|
...rest,
|
|
324
496
|
style,
|
|
325
|
-
maintainVisibleContentPosition: maintainVisibleContentPosition ? { minIndexForVisible: 0 } : void 0,
|
|
497
|
+
maintainVisibleContentPosition: maintainVisibleContentPosition && !ListEmptyComponent ? { minIndexForVisible: 0 } : void 0,
|
|
326
498
|
contentContainerStyle: [
|
|
327
499
|
contentContainerStyle,
|
|
328
500
|
horizontal ? {
|
|
@@ -335,34 +507,41 @@ var ListComponent = React5.memo(function ListComponent2({
|
|
|
335
507
|
contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
|
|
336
508
|
ref: refScrollView
|
|
337
509
|
},
|
|
338
|
-
/* @__PURE__ */
|
|
339
|
-
ListHeaderComponent && /* @__PURE__ */
|
|
340
|
-
|
|
510
|
+
!ListEmptyComponent && (ENABLE_DEVMODE ? /* @__PURE__ */ React6.createElement(PaddingAndAdjustDevMode, null) : /* @__PURE__ */ React6.createElement(PaddingAndAdjust, null)),
|
|
511
|
+
ListHeaderComponent && /* @__PURE__ */ React6.createElement(
|
|
512
|
+
View,
|
|
341
513
|
{
|
|
342
514
|
style: ListHeaderComponentStyle,
|
|
343
515
|
onLayout: (event) => {
|
|
344
516
|
const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
345
|
-
|
|
346
|
-
if (size !== prevSize) {
|
|
347
|
-
set$(ctx, "headerSize", size);
|
|
348
|
-
}
|
|
517
|
+
set$(ctx, "headerSize", size);
|
|
349
518
|
}
|
|
350
519
|
},
|
|
351
520
|
getComponent(ListHeaderComponent)
|
|
352
521
|
),
|
|
353
522
|
ListEmptyComponent && getComponent(ListEmptyComponent),
|
|
354
|
-
/* @__PURE__ */
|
|
523
|
+
/* @__PURE__ */ React6.createElement(
|
|
355
524
|
Containers,
|
|
356
525
|
{
|
|
357
526
|
horizontal,
|
|
358
527
|
recycleItems,
|
|
359
528
|
waitForInitialLayout,
|
|
360
529
|
getRenderedItem,
|
|
361
|
-
ItemSeparatorComponent
|
|
530
|
+
ItemSeparatorComponent,
|
|
362
531
|
updateItemSize
|
|
363
532
|
}
|
|
364
533
|
),
|
|
365
|
-
ListFooterComponent && /* @__PURE__ */
|
|
534
|
+
ListFooterComponent && /* @__PURE__ */ React6.createElement(
|
|
535
|
+
View,
|
|
536
|
+
{
|
|
537
|
+
style: ListFooterComponentStyle,
|
|
538
|
+
onLayout: (event) => {
|
|
539
|
+
const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
540
|
+
set$(ctx, "footerSize", size);
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
getComponent(ListFooterComponent)
|
|
544
|
+
)
|
|
366
545
|
);
|
|
367
546
|
});
|
|
368
547
|
|
|
@@ -371,36 +550,63 @@ var ScrollAdjustHandler = class {
|
|
|
371
550
|
constructor(ctx) {
|
|
372
551
|
this.ctx = ctx;
|
|
373
552
|
this.appliedAdjust = 0;
|
|
374
|
-
this.pendingAdjust = 0;
|
|
375
553
|
this.busy = false;
|
|
376
|
-
this.
|
|
554
|
+
this.isPaused = false;
|
|
555
|
+
this.isDisabled = false;
|
|
377
556
|
this.context = ctx;
|
|
378
557
|
}
|
|
558
|
+
doAjdust() {
|
|
559
|
+
set$(this.context, "scrollAdjust", this.appliedAdjust);
|
|
560
|
+
this.busy = false;
|
|
561
|
+
}
|
|
379
562
|
requestAdjust(adjust, onAdjusted) {
|
|
563
|
+
if (this.isDisabled) {
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
380
566
|
const oldAdjustTop = peek$(this.context, "scrollAdjust");
|
|
381
567
|
if (oldAdjustTop === adjust) {
|
|
382
568
|
return;
|
|
383
569
|
}
|
|
384
570
|
this.appliedAdjust = adjust;
|
|
385
|
-
this.
|
|
386
|
-
const doAjdust = () => {
|
|
387
|
-
set$(this.context, "scrollAdjust", this.pendingAdjust);
|
|
388
|
-
onAdjusted(oldAdjustTop - this.pendingAdjust);
|
|
389
|
-
this.busy = false;
|
|
390
|
-
};
|
|
391
|
-
if (!this.busy) {
|
|
571
|
+
if (!this.busy && !this.isPaused) {
|
|
392
572
|
this.busy = true;
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
setTimeout(doAjdust, 50);
|
|
396
|
-
} else {
|
|
397
|
-
doAjdust();
|
|
398
|
-
}
|
|
573
|
+
this.doAjdust();
|
|
574
|
+
onAdjusted(oldAdjustTop - adjust);
|
|
399
575
|
}
|
|
400
576
|
}
|
|
401
577
|
getAppliedAdjust() {
|
|
402
578
|
return this.appliedAdjust;
|
|
403
579
|
}
|
|
580
|
+
pauseAdjust() {
|
|
581
|
+
this.isPaused = true;
|
|
582
|
+
}
|
|
583
|
+
setDisableAdjust(disable) {
|
|
584
|
+
this.isDisabled = disable;
|
|
585
|
+
}
|
|
586
|
+
// return true if it was paused
|
|
587
|
+
unPauseAdjust() {
|
|
588
|
+
if (this.isPaused) {
|
|
589
|
+
this.isPaused = false;
|
|
590
|
+
this.doAjdust();
|
|
591
|
+
return true;
|
|
592
|
+
}
|
|
593
|
+
return false;
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
var useCombinedRef = (...refs) => {
|
|
597
|
+
const callback = useCallback((element) => {
|
|
598
|
+
for (const ref of refs) {
|
|
599
|
+
if (!ref) {
|
|
600
|
+
continue;
|
|
601
|
+
}
|
|
602
|
+
if (typeof ref === "function") {
|
|
603
|
+
ref(element);
|
|
604
|
+
} else {
|
|
605
|
+
ref.current = element;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}, refs);
|
|
609
|
+
return callback;
|
|
404
610
|
};
|
|
405
611
|
|
|
406
612
|
// src/viewability.ts
|
|
@@ -453,11 +659,37 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
|
|
|
453
659
|
const { viewabilityConfig, onViewableItemsChanged } = viewabilityConfigCallbackPair;
|
|
454
660
|
const configId = viewabilityConfig.id;
|
|
455
661
|
const viewabilityState = mapViewabilityConfigCallbackPairs.get(configId);
|
|
456
|
-
const { viewableItems: previousViewableItems, start,
|
|
662
|
+
const { viewableItems: previousViewableItems, start, end } = viewabilityState;
|
|
663
|
+
const viewabilityTokens = /* @__PURE__ */ new Map();
|
|
664
|
+
for (const [containerId, value] of ctx.mapViewabilityAmountValues) {
|
|
665
|
+
viewabilityTokens.set(
|
|
666
|
+
containerId,
|
|
667
|
+
computeViewability(
|
|
668
|
+
state,
|
|
669
|
+
ctx,
|
|
670
|
+
viewabilityConfig,
|
|
671
|
+
containerId,
|
|
672
|
+
value.key,
|
|
673
|
+
scrollSize,
|
|
674
|
+
value.item,
|
|
675
|
+
value.index
|
|
676
|
+
)
|
|
677
|
+
);
|
|
678
|
+
}
|
|
457
679
|
const changed = [];
|
|
458
680
|
if (previousViewableItems) {
|
|
459
681
|
for (const viewToken of previousViewableItems) {
|
|
460
|
-
|
|
682
|
+
const containerId = findContainerId(ctx, viewToken.key);
|
|
683
|
+
if (!isViewable(
|
|
684
|
+
state,
|
|
685
|
+
ctx,
|
|
686
|
+
viewabilityConfig,
|
|
687
|
+
containerId,
|
|
688
|
+
viewToken.key,
|
|
689
|
+
scrollSize,
|
|
690
|
+
viewToken.item,
|
|
691
|
+
viewToken.index
|
|
692
|
+
)) {
|
|
461
693
|
viewToken.isViewable = false;
|
|
462
694
|
changed.push(viewToken);
|
|
463
695
|
}
|
|
@@ -468,12 +700,14 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
|
|
|
468
700
|
const item = data[i];
|
|
469
701
|
if (item) {
|
|
470
702
|
const key = getId(i);
|
|
471
|
-
|
|
703
|
+
const containerId = findContainerId(ctx, key);
|
|
704
|
+
if (isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
|
|
472
705
|
const viewToken = {
|
|
473
706
|
item,
|
|
474
707
|
key,
|
|
475
708
|
index: i,
|
|
476
|
-
isViewable: true
|
|
709
|
+
isViewable: true,
|
|
710
|
+
containerId
|
|
477
711
|
};
|
|
478
712
|
viewableItems.push(viewToken);
|
|
479
713
|
if (!(previousViewableItems == null ? void 0 : previousViewableItems.find((v) => v.key === viewToken.key))) {
|
|
@@ -491,20 +725,27 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
|
|
|
491
725
|
viewabilityState.viewableItems = viewableItems;
|
|
492
726
|
for (let i = 0; i < changed.length; i++) {
|
|
493
727
|
const change = changed[i];
|
|
494
|
-
maybeUpdateViewabilityCallback(ctx, configId, change);
|
|
728
|
+
maybeUpdateViewabilityCallback(ctx, configId, change.containerId, change);
|
|
495
729
|
}
|
|
496
730
|
if (onViewableItemsChanged) {
|
|
497
731
|
onViewableItemsChanged({ viewableItems, changed });
|
|
498
732
|
}
|
|
499
733
|
}
|
|
734
|
+
for (const [containerId, value] of ctx.mapViewabilityAmountValues) {
|
|
735
|
+
if (value.sizeVisible < 0) {
|
|
736
|
+
ctx.mapViewabilityAmountValues.delete(containerId);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
500
739
|
}
|
|
501
|
-
function
|
|
502
|
-
const { sizes, positions, scroll } = state;
|
|
740
|
+
function computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
|
|
741
|
+
const { sizes, positions, scroll: scrollState, scrollAdjustHandler } = state;
|
|
503
742
|
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
504
743
|
const { itemVisiblePercentThreshold, viewAreaCoveragePercentThreshold } = viewabilityConfig;
|
|
505
744
|
const viewAreaMode = viewAreaCoveragePercentThreshold != null;
|
|
506
745
|
const viewablePercentThreshold = viewAreaMode ? viewAreaCoveragePercentThreshold : itemVisiblePercentThreshold;
|
|
507
|
-
const
|
|
746
|
+
const previousScrollAdjust = scrollAdjustHandler.getAppliedAdjust();
|
|
747
|
+
const scroll = scrollState - previousScrollAdjust - topPad;
|
|
748
|
+
const top = positions.get(key) - scroll;
|
|
508
749
|
const size = sizes.get(key) || 0;
|
|
509
750
|
const bottom = top + size;
|
|
510
751
|
const isEntirelyVisible = top >= 0 && bottom <= scrollSize && bottom > top;
|
|
@@ -513,7 +754,6 @@ function isViewable(state, ctx, viewabilityConfig, key, scrollSize, item, index)
|
|
|
513
754
|
const percentOfScroller = size ? 100 * (sizeVisible / scrollSize) : 0;
|
|
514
755
|
const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
|
|
515
756
|
const isViewable2 = percent >= viewablePercentThreshold;
|
|
516
|
-
const containerId = findContainerId(ctx, key);
|
|
517
757
|
const value = {
|
|
518
758
|
index,
|
|
519
759
|
isViewable: isViewable2,
|
|
@@ -523,15 +763,21 @@ function isViewable(state, ctx, viewabilityConfig, key, scrollSize, item, index)
|
|
|
523
763
|
percentOfScroller,
|
|
524
764
|
sizeVisible,
|
|
525
765
|
size,
|
|
526
|
-
|
|
527
|
-
|
|
766
|
+
scrollSize,
|
|
767
|
+
containerId
|
|
528
768
|
};
|
|
529
|
-
ctx.mapViewabilityAmountValues.
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
cb
|
|
769
|
+
if (JSON.stringify(value) !== JSON.stringify(ctx.mapViewabilityAmountValues.get(containerId))) {
|
|
770
|
+
ctx.mapViewabilityAmountValues.set(containerId, value);
|
|
771
|
+
const cb = ctx.mapViewabilityAmountCallbacks.get(containerId);
|
|
772
|
+
if (cb) {
|
|
773
|
+
cb(value);
|
|
774
|
+
}
|
|
533
775
|
}
|
|
534
|
-
return
|
|
776
|
+
return value;
|
|
777
|
+
}
|
|
778
|
+
function isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
|
|
779
|
+
const value = ctx.mapViewabilityAmountValues.get(containerId) || computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
|
|
780
|
+
return value.isViewable;
|
|
535
781
|
}
|
|
536
782
|
function findContainerId(ctx, key) {
|
|
537
783
|
const numContainers = peek$(ctx, "numContainers");
|
|
@@ -543,8 +789,8 @@ function findContainerId(ctx, key) {
|
|
|
543
789
|
}
|
|
544
790
|
return -1;
|
|
545
791
|
}
|
|
546
|
-
function maybeUpdateViewabilityCallback(ctx, configId, viewToken) {
|
|
547
|
-
const key =
|
|
792
|
+
function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
|
|
793
|
+
const key = containerId + configId;
|
|
548
794
|
ctx.mapViewabilityValues.set(key, viewToken);
|
|
549
795
|
const cb = ctx.mapViewabilityCallbacks.get(key);
|
|
550
796
|
cb == null ? void 0 : cb(viewToken);
|
|
@@ -553,13 +799,26 @@ function maybeUpdateViewabilityCallback(ctx, configId, viewToken) {
|
|
|
553
799
|
// src/LegendList.tsx
|
|
554
800
|
var DEFAULT_DRAW_DISTANCE = 250;
|
|
555
801
|
var DEFAULT_ITEM_SIZE = 100;
|
|
556
|
-
|
|
557
|
-
|
|
802
|
+
function createColumnWrapperStyle(contentContainerStyle) {
|
|
803
|
+
const { gap, columnGap, rowGap } = contentContainerStyle;
|
|
804
|
+
if (gap || columnGap || rowGap) {
|
|
805
|
+
contentContainerStyle.gap = void 0;
|
|
806
|
+
contentContainerStyle.columnGap = void 0;
|
|
807
|
+
contentContainerStyle.rowGap = void 0;
|
|
808
|
+
return {
|
|
809
|
+
gap,
|
|
810
|
+
columnGap,
|
|
811
|
+
rowGap
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
var LegendList = typedForwardRef(function LegendList2(props, forwardedRef) {
|
|
816
|
+
return /* @__PURE__ */ React6.createElement(StateProvider, null, /* @__PURE__ */ React6.createElement(LegendListInner, { ...props, ref: forwardedRef }));
|
|
558
817
|
});
|
|
559
|
-
var LegendListInner =
|
|
560
|
-
var _a, _b, _c, _d
|
|
818
|
+
var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
|
|
819
|
+
var _a, _b, _c, _d;
|
|
561
820
|
const {
|
|
562
|
-
data,
|
|
821
|
+
data: dataProp = [],
|
|
563
822
|
initialScrollIndex,
|
|
564
823
|
initialScrollOffset,
|
|
565
824
|
horizontal,
|
|
@@ -572,61 +831,89 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
572
831
|
alignItemsAtEnd = false,
|
|
573
832
|
maintainVisibleContentPosition = false,
|
|
574
833
|
onScroll: onScrollProp,
|
|
834
|
+
onMomentumScrollEnd,
|
|
575
835
|
numColumns: numColumnsProp = 1,
|
|
836
|
+
columnWrapperStyle,
|
|
576
837
|
keyExtractor: keyExtractorProp,
|
|
577
838
|
renderItem,
|
|
578
839
|
estimatedItemSize,
|
|
579
840
|
getEstimatedItemSize,
|
|
580
|
-
onEndReached,
|
|
581
|
-
onStartReached,
|
|
582
841
|
ListEmptyComponent,
|
|
583
842
|
onItemSizeChanged,
|
|
584
843
|
scrollEventThrottle,
|
|
585
844
|
refScrollView,
|
|
586
845
|
waitForInitialLayout = true,
|
|
587
846
|
extraData,
|
|
847
|
+
contentContainerStyle: contentContainerStyleProp,
|
|
848
|
+
onLayout: onLayoutProp,
|
|
849
|
+
onRefresh,
|
|
850
|
+
refreshing,
|
|
851
|
+
progressViewOffset,
|
|
852
|
+
refreshControl,
|
|
853
|
+
initialContainerPoolRatio = 2,
|
|
854
|
+
viewabilityConfig,
|
|
855
|
+
viewabilityConfigCallbackPairs,
|
|
856
|
+
onViewableItemsChanged,
|
|
588
857
|
...rest
|
|
589
858
|
} = props;
|
|
590
|
-
const { style
|
|
859
|
+
const { style } = props;
|
|
860
|
+
const callbacks = useRef({
|
|
861
|
+
onStartReached: rest.onStartReached,
|
|
862
|
+
onEndReached: rest.onEndReached
|
|
863
|
+
});
|
|
864
|
+
callbacks.current.onStartReached = rest.onStartReached;
|
|
865
|
+
callbacks.current.onEndReached = rest.onEndReached;
|
|
866
|
+
const contentContainerStyle = StyleSheet.flatten(contentContainerStyleProp);
|
|
591
867
|
const ctx = useStateContext();
|
|
868
|
+
ctx.columnWrapperStyle = columnWrapperStyle || (contentContainerStyle ? createColumnWrapperStyle(contentContainerStyle) : void 0);
|
|
592
869
|
const refScroller = useRef(null);
|
|
593
|
-
const
|
|
870
|
+
const combinedRef = useCombinedRef(refScroller, refScrollView);
|
|
871
|
+
const scrollBuffer = (drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE) || 1;
|
|
594
872
|
const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (item, index) => index.toString();
|
|
595
873
|
const refState = useRef();
|
|
596
874
|
const getId = (index) => {
|
|
597
875
|
var _a2;
|
|
598
|
-
const
|
|
599
|
-
if (!
|
|
876
|
+
const data = (_a2 = refState.current) == null ? void 0 : _a2.data;
|
|
877
|
+
if (!data) {
|
|
600
878
|
return "";
|
|
601
879
|
}
|
|
602
|
-
const ret = index <
|
|
880
|
+
const ret = index < data.length ? keyExtractor ? keyExtractor(data[index], index) : index : null;
|
|
603
881
|
return `${ret}`;
|
|
604
882
|
};
|
|
605
|
-
const getItemSize = (key, index,
|
|
883
|
+
const getItemSize = (key, index, data) => {
|
|
606
884
|
var _a2;
|
|
607
885
|
const sizeKnown = refState.current.sizes.get(key);
|
|
608
886
|
if (sizeKnown !== void 0) {
|
|
609
887
|
return sizeKnown;
|
|
610
888
|
}
|
|
611
|
-
const size = (_a2 = getEstimatedItemSize ? getEstimatedItemSize(index,
|
|
889
|
+
const size = (_a2 = getEstimatedItemSize ? getEstimatedItemSize(index, data) : estimatedItemSize) != null ? _a2 : DEFAULT_ITEM_SIZE;
|
|
612
890
|
refState.current.sizes.set(key, size);
|
|
613
891
|
return size;
|
|
614
892
|
};
|
|
615
|
-
const
|
|
616
|
-
|
|
893
|
+
const calculateOffsetForIndex = (index = initialScrollIndex) => {
|
|
894
|
+
var _a2;
|
|
895
|
+
const data = dataProp;
|
|
896
|
+
if (index !== void 0) {
|
|
617
897
|
let offset = 0;
|
|
618
|
-
|
|
898
|
+
const canGetSize = !!refState.current;
|
|
899
|
+
if (canGetSize || getEstimatedItemSize) {
|
|
900
|
+
const sizeFn = (index2) => {
|
|
901
|
+
if (canGetSize) {
|
|
902
|
+
return getItemSize(getId(index2), index2, data[index2]);
|
|
903
|
+
}
|
|
904
|
+
return getEstimatedItemSize(index2, data[index2]);
|
|
905
|
+
};
|
|
619
906
|
for (let i = 0; i < index; i++) {
|
|
620
|
-
offset +=
|
|
907
|
+
offset += sizeFn(i);
|
|
621
908
|
}
|
|
622
909
|
} else if (estimatedItemSize) {
|
|
623
910
|
offset = index * estimatedItemSize;
|
|
624
911
|
}
|
|
625
|
-
return offset / numColumnsProp;
|
|
912
|
+
return offset / numColumnsProp - (((_a2 = refState.current) == null ? void 0 : _a2.scrollAdjustHandler.getAppliedAdjust()) || 0);
|
|
626
913
|
}
|
|
627
914
|
return 0;
|
|
628
915
|
};
|
|
629
|
-
const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : useMemo(
|
|
916
|
+
const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : useMemo(calculateOffsetForIndex, []);
|
|
630
917
|
if (!refState.current) {
|
|
631
918
|
const initialScrollLength = Dimensions.get("window")[horizontal ? "width" : "height"];
|
|
632
919
|
refState.current = {
|
|
@@ -634,14 +921,11 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
634
921
|
positions: /* @__PURE__ */ new Map(),
|
|
635
922
|
columns: /* @__PURE__ */ new Map(),
|
|
636
923
|
pendingAdjust: 0,
|
|
637
|
-
waitingForMicrotask: false,
|
|
638
924
|
isStartReached: initialContentOffset < initialScrollLength * onStartReachedThreshold,
|
|
639
925
|
isEndReached: false,
|
|
640
926
|
isAtBottom: false,
|
|
641
927
|
isAtTop: false,
|
|
642
|
-
data,
|
|
643
|
-
idsInFirstRender: void 0,
|
|
644
|
-
hasScrolled: false,
|
|
928
|
+
data: dataProp,
|
|
645
929
|
scrollLength: initialScrollLength,
|
|
646
930
|
startBuffered: 0,
|
|
647
931
|
startNoBuffer: 0,
|
|
@@ -661,23 +945,29 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
661
945
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
662
946
|
scrollHistory: [],
|
|
663
947
|
scrollVelocity: 0,
|
|
664
|
-
|
|
948
|
+
sizesKnown: /* @__PURE__ */ new Map(),
|
|
665
949
|
timeoutSizeMessage: 0,
|
|
666
950
|
scrollTimer: void 0,
|
|
667
951
|
belowAnchorElementPositions: void 0,
|
|
668
952
|
rowHeights: /* @__PURE__ */ new Map(),
|
|
669
953
|
startReachedBlockedByTimer: false,
|
|
954
|
+
endReachedBlockedByTimer: false,
|
|
670
955
|
scrollForNextCalculateItemsInView: void 0,
|
|
671
|
-
enableScrollForNextCalculateItemsInView: true
|
|
956
|
+
enableScrollForNextCalculateItemsInView: true,
|
|
957
|
+
minIndexSizeChanged: 0,
|
|
958
|
+
numPendingInitialLayout: 0,
|
|
959
|
+
queuedCalculateItemsInView: 0,
|
|
960
|
+
lastBatchingAction: Date.now(),
|
|
961
|
+
onScroll: onScrollProp
|
|
672
962
|
};
|
|
673
|
-
|
|
674
|
-
if (maintainVisibleContentPosition) {
|
|
675
|
-
if (initialScrollIndex) {
|
|
963
|
+
const dataLength = dataProp.length;
|
|
964
|
+
if (maintainVisibleContentPosition && dataLength > 0) {
|
|
965
|
+
if (initialScrollIndex && initialScrollIndex < dataLength) {
|
|
676
966
|
refState.current.anchorElement = {
|
|
677
967
|
coordinate: initialContentOffset,
|
|
678
968
|
id: getId(initialScrollIndex)
|
|
679
969
|
};
|
|
680
|
-
} else if (
|
|
970
|
+
} else if (dataLength > 0) {
|
|
681
971
|
refState.current.anchorElement = {
|
|
682
972
|
coordinate: initialContentOffset,
|
|
683
973
|
id: getId(0)
|
|
@@ -690,6 +980,9 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
690
980
|
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
|
|
691
981
|
set$(ctx, "extraData", extraData);
|
|
692
982
|
}
|
|
983
|
+
const didDataChange = refState.current.data !== dataProp;
|
|
984
|
+
refState.current.data = dataProp;
|
|
985
|
+
refState.current.onScroll = onScrollProp;
|
|
693
986
|
const getAnchorElementIndex = () => {
|
|
694
987
|
const state = refState.current;
|
|
695
988
|
if (state.anchorElement) {
|
|
@@ -698,12 +991,34 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
698
991
|
}
|
|
699
992
|
return void 0;
|
|
700
993
|
};
|
|
994
|
+
const setDidLayout = () => {
|
|
995
|
+
var _a2;
|
|
996
|
+
refState.current.queuedInitialLayout = true;
|
|
997
|
+
checkAtBottom();
|
|
998
|
+
if (initialScrollIndex) {
|
|
999
|
+
const updatedOffset = calculateOffsetForIndex(initialScrollIndex);
|
|
1000
|
+
(_a2 = refState.current) == null ? void 0 : _a2.scrollAdjustHandler.setDisableAdjust(true);
|
|
1001
|
+
queueMicrotask(() => {
|
|
1002
|
+
scrollTo(updatedOffset, false);
|
|
1003
|
+
requestAnimationFrame(() => {
|
|
1004
|
+
var _a3;
|
|
1005
|
+
set$(ctx, "containersDidLayout", true);
|
|
1006
|
+
(_a3 = refState.current) == null ? void 0 : _a3.scrollAdjustHandler.setDisableAdjust(false);
|
|
1007
|
+
});
|
|
1008
|
+
});
|
|
1009
|
+
} else {
|
|
1010
|
+
queueMicrotask(() => {
|
|
1011
|
+
set$(ctx, "containersDidLayout", true);
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
};
|
|
701
1015
|
const addTotalSize = useCallback((key, add, totalSizeBelowAnchor) => {
|
|
702
1016
|
const state = refState.current;
|
|
703
|
-
const
|
|
1017
|
+
const { indexByKey, anchorElement } = state;
|
|
1018
|
+
const index = key === null ? 0 : indexByKey.get(key);
|
|
704
1019
|
let isAboveAnchor = false;
|
|
705
1020
|
if (maintainVisibleContentPosition) {
|
|
706
|
-
if (
|
|
1021
|
+
if (anchorElement && index < getAnchorElementIndex()) {
|
|
707
1022
|
isAboveAnchor = true;
|
|
708
1023
|
}
|
|
709
1024
|
}
|
|
@@ -716,29 +1031,30 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
716
1031
|
state.totalSizeBelowAnchor += add;
|
|
717
1032
|
}
|
|
718
1033
|
}
|
|
719
|
-
let applyAdjustValue =
|
|
720
|
-
|
|
721
|
-
|
|
1034
|
+
let applyAdjustValue = 0;
|
|
1035
|
+
let resultSize = state.totalSize;
|
|
1036
|
+
if (maintainVisibleContentPosition && anchorElement !== void 0) {
|
|
1037
|
+
const newAdjust = anchorElement.coordinate - state.totalSizeBelowAnchor;
|
|
722
1038
|
applyAdjustValue = -newAdjust;
|
|
723
1039
|
state.belowAnchorElementPositions = buildElementPositionsBelowAnchor();
|
|
724
1040
|
state.rowHeights.clear();
|
|
1041
|
+
if (applyAdjustValue !== void 0) {
|
|
1042
|
+
resultSize -= applyAdjustValue;
|
|
1043
|
+
state.scrollAdjustHandler.requestAdjust(applyAdjustValue, (diff) => {
|
|
1044
|
+
state.scroll -= diff;
|
|
1045
|
+
});
|
|
1046
|
+
}
|
|
725
1047
|
}
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
if (applyAdjustValue !== void 0) {
|
|
729
|
-
resultSize -= applyAdjustValue;
|
|
730
|
-
refState.current.scrollAdjustHandler.requestAdjust(applyAdjustValue, (diff) => {
|
|
731
|
-
state.scroll -= diff;
|
|
732
|
-
});
|
|
733
|
-
}
|
|
734
|
-
set$(ctx, "totalSize", resultSize);
|
|
1048
|
+
set$(ctx, "totalSize", state.totalSize);
|
|
1049
|
+
set$(ctx, "totalSizeWithScrollAdjust", resultSize);
|
|
735
1050
|
if (alignItemsAtEnd) {
|
|
736
1051
|
doUpdatePaddingTop();
|
|
737
1052
|
}
|
|
738
1053
|
}, []);
|
|
739
1054
|
const getRowHeight = (n) => {
|
|
740
|
-
const { rowHeights } = refState.current;
|
|
741
|
-
|
|
1055
|
+
const { rowHeights, data } = refState.current;
|
|
1056
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
1057
|
+
if (numColumns === 1) {
|
|
742
1058
|
const id = getId(n);
|
|
743
1059
|
return getItemSize(id, n, data[n]);
|
|
744
1060
|
}
|
|
@@ -746,8 +1062,8 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
746
1062
|
return rowHeights.get(n) || 0;
|
|
747
1063
|
}
|
|
748
1064
|
let rowHeight = 0;
|
|
749
|
-
const startEl = n *
|
|
750
|
-
for (let i = startEl; i < startEl +
|
|
1065
|
+
const startEl = n * numColumns;
|
|
1066
|
+
for (let i = startEl; i < startEl + numColumns && i < data.length; i++) {
|
|
751
1067
|
const id = getId(i);
|
|
752
1068
|
const size = getItemSize(id, i, data[i]);
|
|
753
1069
|
rowHeight = Math.max(rowHeight, size);
|
|
@@ -766,10 +1082,11 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
766
1082
|
return /* @__PURE__ */ new Map();
|
|
767
1083
|
}
|
|
768
1084
|
const map = state.belowAnchorElementPositions || /* @__PURE__ */ new Map();
|
|
1085
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
769
1086
|
for (let i = anchorIndex - 1; i >= 0; i--) {
|
|
770
1087
|
const id = getId(i);
|
|
771
|
-
const rowNumber = Math.floor(i /
|
|
772
|
-
if (i %
|
|
1088
|
+
const rowNumber = Math.floor(i / numColumns);
|
|
1089
|
+
if (i % numColumns === 0) {
|
|
773
1090
|
top -= getRowHeight(rowNumber);
|
|
774
1091
|
}
|
|
775
1092
|
map.set(id, top);
|
|
@@ -777,37 +1094,51 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
777
1094
|
return map;
|
|
778
1095
|
};
|
|
779
1096
|
const getElementPositionBelowAchor = (id) => {
|
|
1097
|
+
var _a2;
|
|
780
1098
|
const state = refState.current;
|
|
781
1099
|
if (!refState.current.belowAnchorElementPositions) {
|
|
782
1100
|
state.belowAnchorElementPositions = buildElementPositionsBelowAnchor();
|
|
783
1101
|
}
|
|
784
1102
|
const res = state.belowAnchorElementPositions.get(id);
|
|
785
1103
|
if (res === void 0) {
|
|
786
|
-
|
|
1104
|
+
console.warn(`Undefined position below achor ${id} ${(_a2 = state.anchorElement) == null ? void 0 : _a2.id}`);
|
|
1105
|
+
return 0;
|
|
787
1106
|
}
|
|
788
1107
|
return res;
|
|
789
1108
|
};
|
|
790
|
-
const calculateItemsInView = useCallback((
|
|
1109
|
+
const calculateItemsInView = useCallback(() => {
|
|
1110
|
+
var _a2;
|
|
791
1111
|
const state = refState.current;
|
|
792
1112
|
const {
|
|
793
|
-
data
|
|
1113
|
+
data,
|
|
794
1114
|
scrollLength,
|
|
795
|
-
scroll: scrollState,
|
|
796
1115
|
startBufferedId: startBufferedIdOrig,
|
|
797
1116
|
positions,
|
|
798
1117
|
columns,
|
|
799
|
-
scrollAdjustHandler
|
|
1118
|
+
scrollAdjustHandler,
|
|
1119
|
+
scrollVelocity: speed
|
|
800
1120
|
} = state;
|
|
801
|
-
if (
|
|
802
|
-
state.waitingForMicrotask = false;
|
|
803
|
-
}
|
|
804
|
-
if (!data2) {
|
|
1121
|
+
if (!data || scrollLength === 0) {
|
|
805
1122
|
return;
|
|
806
1123
|
}
|
|
1124
|
+
const totalSize = peek$(ctx, "totalSizeWithScrollAdjust");
|
|
807
1125
|
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
1126
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
808
1127
|
const previousScrollAdjust = scrollAdjustHandler.getAppliedAdjust();
|
|
809
1128
|
const scrollExtra = Math.max(-16, Math.min(16, speed)) * 16;
|
|
810
|
-
|
|
1129
|
+
let scrollState = state.scroll;
|
|
1130
|
+
if (!state.queuedInitialLayout && initialScrollIndex) {
|
|
1131
|
+
const updatedOffset = calculateOffsetForIndex(initialScrollIndex);
|
|
1132
|
+
scrollState = updatedOffset;
|
|
1133
|
+
}
|
|
1134
|
+
let scroll = scrollState - previousScrollAdjust - topPad;
|
|
1135
|
+
if (scroll + scrollLength > totalSize) {
|
|
1136
|
+
scroll = totalSize - scrollLength;
|
|
1137
|
+
}
|
|
1138
|
+
if (ENABLE_DEBUG_VIEW) {
|
|
1139
|
+
set$(ctx, "debugRawScroll", scrollState);
|
|
1140
|
+
set$(ctx, "debugComputedScroll", scroll);
|
|
1141
|
+
}
|
|
811
1142
|
let scrollBufferTop = scrollBuffer;
|
|
812
1143
|
let scrollBufferBottom = scrollBuffer;
|
|
813
1144
|
if (scrollExtra > 8) {
|
|
@@ -830,8 +1161,11 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
830
1161
|
let startBufferedId = null;
|
|
831
1162
|
let endNoBuffer = null;
|
|
832
1163
|
let endBuffered = null;
|
|
833
|
-
|
|
834
|
-
|
|
1164
|
+
let loopStart = startBufferedIdOrig ? state.indexByKey.get(startBufferedIdOrig) || 0 : 0;
|
|
1165
|
+
if (state.minIndexSizeChanged !== void 0) {
|
|
1166
|
+
loopStart = Math.min(state.minIndexSizeChanged, loopStart);
|
|
1167
|
+
state.minIndexSizeChanged = void 0;
|
|
1168
|
+
}
|
|
835
1169
|
const anchorElementIndex = getAnchorElementIndex();
|
|
836
1170
|
for (let i = loopStart; i >= 0; i--) {
|
|
837
1171
|
const id = getId(i);
|
|
@@ -844,7 +1178,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
844
1178
|
}
|
|
845
1179
|
const top2 = newPosition || positions.get(id);
|
|
846
1180
|
if (top2 !== void 0) {
|
|
847
|
-
const size = getItemSize(id, i,
|
|
1181
|
+
const size = getItemSize(id, i, data[i]);
|
|
848
1182
|
const bottom = top2 + size;
|
|
849
1183
|
if (bottom > scroll - scrollBuffer) {
|
|
850
1184
|
loopStart = i;
|
|
@@ -853,7 +1187,6 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
853
1187
|
}
|
|
854
1188
|
}
|
|
855
1189
|
}
|
|
856
|
-
const numColumns = peek$(ctx, "numColumns");
|
|
857
1190
|
const loopStartMod = loopStart % numColumns;
|
|
858
1191
|
if (loopStartMod > 0) {
|
|
859
1192
|
loopStart -= loopStartMod;
|
|
@@ -862,22 +1195,22 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
862
1195
|
let column = 1;
|
|
863
1196
|
let maxSizeInRow = 0;
|
|
864
1197
|
const getInitialTop = (i) => {
|
|
865
|
-
var
|
|
1198
|
+
var _a3;
|
|
866
1199
|
const id = getId(i);
|
|
867
1200
|
let topOffset = 0;
|
|
868
1201
|
if (positions.get(id)) {
|
|
869
1202
|
topOffset = positions.get(id);
|
|
870
1203
|
}
|
|
871
|
-
if (id === ((
|
|
872
|
-
topOffset =
|
|
1204
|
+
if (id === ((_a3 = state.anchorElement) == null ? void 0 : _a3.id)) {
|
|
1205
|
+
topOffset = state.anchorElement.coordinate;
|
|
873
1206
|
}
|
|
874
1207
|
return topOffset;
|
|
875
1208
|
};
|
|
876
|
-
for (let i = loopStart; i <
|
|
1209
|
+
for (let i = loopStart; i < data.length; i++) {
|
|
877
1210
|
const id = getId(i);
|
|
878
|
-
const size = getItemSize(id, i,
|
|
1211
|
+
const size = getItemSize(id, i, data[i]);
|
|
879
1212
|
maxSizeInRow = Math.max(maxSizeInRow, size);
|
|
880
|
-
if (top === void 0) {
|
|
1213
|
+
if (top === void 0 || id === ((_a2 = state.anchorElement) == null ? void 0 : _a2.id)) {
|
|
881
1214
|
top = getInitialTop(i);
|
|
882
1215
|
}
|
|
883
1216
|
if (positions.get(id) !== top) {
|
|
@@ -930,6 +1263,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
930
1263
|
if (startBuffered !== null && endBuffered !== null) {
|
|
931
1264
|
const prevNumContainers = ctx.values.get("numContainers");
|
|
932
1265
|
let numContainers = prevNumContainers;
|
|
1266
|
+
let didWarnMoreContainers = false;
|
|
933
1267
|
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
934
1268
|
let isContained = false;
|
|
935
1269
|
const id = getId(i);
|
|
@@ -963,18 +1297,19 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
963
1297
|
if (furthestIndex >= 0) {
|
|
964
1298
|
set$(ctx, `containerItemKey${furthestIndex}`, id);
|
|
965
1299
|
const index = state.indexByKey.get(id);
|
|
966
|
-
set$(ctx, `containerItemData${furthestIndex}`,
|
|
1300
|
+
set$(ctx, `containerItemData${furthestIndex}`, data[index]);
|
|
967
1301
|
} else {
|
|
968
1302
|
const containerId = numContainers;
|
|
969
1303
|
numContainers++;
|
|
970
1304
|
set$(ctx, `containerItemKey${containerId}`, id);
|
|
971
1305
|
const index = state.indexByKey.get(id);
|
|
972
|
-
set$(ctx, `containerItemData${containerId}`,
|
|
1306
|
+
set$(ctx, `containerItemData${containerId}`, data[index]);
|
|
973
1307
|
set$(ctx, `containerPosition${containerId}`, ANCHORED_POSITION_OUT_OF_VIEW);
|
|
974
1308
|
set$(ctx, `containerColumn${containerId}`, -1);
|
|
975
|
-
if (__DEV__ && numContainers > peek$(ctx, "numContainersPooled")) {
|
|
1309
|
+
if (__DEV__ && !didWarnMoreContainers && numContainers > peek$(ctx, "numContainersPooled")) {
|
|
1310
|
+
didWarnMoreContainers = true;
|
|
976
1311
|
console.warn(
|
|
977
|
-
"[legend-list] No container to recycle, so creating one on demand. This can be a performance issue and is likely caused by the estimatedItemSize being too
|
|
1312
|
+
"[legend-list] No container to recycle, so creating one on demand. This can be a minor performance issue and is likely caused by the estimatedItemSize being too large. Consider decreasing estimatedItemSize. numContainers:",
|
|
978
1313
|
numContainers
|
|
979
1314
|
);
|
|
980
1315
|
}
|
|
@@ -984,19 +1319,19 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
984
1319
|
if (numContainers !== prevNumContainers) {
|
|
985
1320
|
set$(ctx, "numContainers", numContainers);
|
|
986
1321
|
if (numContainers > peek$(ctx, "numContainersPooled")) {
|
|
987
|
-
set$(ctx, "numContainersPooled", numContainers);
|
|
1322
|
+
set$(ctx, "numContainersPooled", Math.ceil(numContainers * 1.5));
|
|
988
1323
|
}
|
|
989
1324
|
}
|
|
990
1325
|
for (let i = 0; i < numContainers; i++) {
|
|
991
1326
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
992
1327
|
const itemIndex = state.indexByKey.get(itemKey);
|
|
993
|
-
const item =
|
|
994
|
-
if (item) {
|
|
1328
|
+
const item = data[itemIndex];
|
|
1329
|
+
if (item !== void 0) {
|
|
995
1330
|
const id = getId(itemIndex);
|
|
996
1331
|
if (itemKey !== id || itemIndex < startBuffered || itemIndex > endBuffered) {
|
|
997
1332
|
const prevPos = peek$(ctx, `containerPosition${i}`).top;
|
|
998
1333
|
const pos = positions.get(id) || 0;
|
|
999
|
-
const size = getItemSize(id, itemIndex,
|
|
1334
|
+
const size = getItemSize(id, itemIndex, data[i]);
|
|
1000
1335
|
if (pos + size >= scroll && pos <= scrollBottom || prevPos + size >= scroll && prevPos <= scrollBottom) {
|
|
1001
1336
|
set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
|
|
1002
1337
|
}
|
|
@@ -1008,9 +1343,9 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1008
1343
|
};
|
|
1009
1344
|
const column2 = columns.get(id) || 1;
|
|
1010
1345
|
if (maintainVisibleContentPosition && itemIndex < anchorElementIndex) {
|
|
1011
|
-
const currentRow = Math.floor(itemIndex /
|
|
1346
|
+
const currentRow = Math.floor(itemIndex / numColumns);
|
|
1012
1347
|
const rowHeight = getRowHeight(currentRow);
|
|
1013
|
-
const elementHeight = getItemSize(id, itemIndex,
|
|
1348
|
+
const elementHeight = getItemSize(id, itemIndex, data[i]);
|
|
1014
1349
|
const diff = rowHeight - elementHeight;
|
|
1015
1350
|
pos.relativeCoordinate = pos.top + getRowHeight(currentRow) - diff;
|
|
1016
1351
|
pos.type = "bottom";
|
|
@@ -1025,13 +1360,25 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1025
1360
|
set$(ctx, `containerColumn${i}`, column2);
|
|
1026
1361
|
}
|
|
1027
1362
|
if (prevData !== item) {
|
|
1028
|
-
set$(ctx, `containerItemData${i}`,
|
|
1363
|
+
set$(ctx, `containerItemData${i}`, data[itemIndex]);
|
|
1029
1364
|
}
|
|
1030
1365
|
}
|
|
1031
1366
|
}
|
|
1032
1367
|
}
|
|
1033
1368
|
}
|
|
1034
|
-
|
|
1369
|
+
if (state.numPendingInitialLayout === 0) {
|
|
1370
|
+
state.numPendingInitialLayout = state.endBuffered - state.startBuffered + 1;
|
|
1371
|
+
}
|
|
1372
|
+
if (!state.queuedInitialLayout && endBuffered !== null) {
|
|
1373
|
+
let areAllKnown = true;
|
|
1374
|
+
for (let i = startBuffered; areAllKnown && i <= endBuffered; i++) {
|
|
1375
|
+
const key = getId(i);
|
|
1376
|
+
areAllKnown && (areAllKnown = state.sizesKnown.has(key));
|
|
1377
|
+
}
|
|
1378
|
+
if (areAllKnown) {
|
|
1379
|
+
setDidLayout();
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1035
1382
|
if (state.viewabilityConfigCallbackPairs) {
|
|
1036
1383
|
updateViewableItems(
|
|
1037
1384
|
state,
|
|
@@ -1046,16 +1393,27 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1046
1393
|
}, []);
|
|
1047
1394
|
const doUpdatePaddingTop = () => {
|
|
1048
1395
|
if (alignItemsAtEnd) {
|
|
1049
|
-
const { scrollLength
|
|
1050
|
-
const
|
|
1051
|
-
const paddingTop = Math.max(0, Math.floor(scrollLength -
|
|
1396
|
+
const { scrollLength } = refState.current;
|
|
1397
|
+
const contentSize = getContentSize(ctx);
|
|
1398
|
+
const paddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
|
|
1052
1399
|
set$(ctx, "paddingTop", paddingTop);
|
|
1053
1400
|
}
|
|
1054
1401
|
};
|
|
1402
|
+
const scrollTo = (offset, animated) => {
|
|
1403
|
+
var _a2;
|
|
1404
|
+
(_a2 = refScroller.current) == null ? void 0 : _a2.scrollTo({
|
|
1405
|
+
x: horizontal ? offset : 0,
|
|
1406
|
+
y: horizontal ? 0 : offset,
|
|
1407
|
+
animated: !!animated
|
|
1408
|
+
});
|
|
1409
|
+
};
|
|
1055
1410
|
const doMaintainScrollAtEnd = (animated) => {
|
|
1056
1411
|
const state = refState.current;
|
|
1057
|
-
if ((state == null ? void 0 : state.isAtBottom) && maintainScrollAtEnd) {
|
|
1058
|
-
|
|
1412
|
+
if ((state == null ? void 0 : state.isAtBottom) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
|
|
1413
|
+
const paddingTop = peek$(ctx, "paddingTop") || 0;
|
|
1414
|
+
if (paddingTop > 0) {
|
|
1415
|
+
state.scroll = 0;
|
|
1416
|
+
}
|
|
1059
1417
|
requestAnimationFrame(() => {
|
|
1060
1418
|
var _a2;
|
|
1061
1419
|
(_a2 = refScroller.current) == null ? void 0 : _a2.scrollToEnd({
|
|
@@ -1065,28 +1423,50 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1065
1423
|
return true;
|
|
1066
1424
|
}
|
|
1067
1425
|
};
|
|
1426
|
+
const checkThreshold = (distance, atThreshold, threshold, isReached, isBlockedByTimer, onReached, blockTimer) => {
|
|
1427
|
+
const distanceAbs = Math.abs(distance);
|
|
1428
|
+
const isAtThreshold = atThreshold || distanceAbs < threshold;
|
|
1429
|
+
if (!isReached && !isBlockedByTimer) {
|
|
1430
|
+
if (isAtThreshold) {
|
|
1431
|
+
onReached == null ? void 0 : onReached(distance);
|
|
1432
|
+
blockTimer == null ? void 0 : blockTimer(true);
|
|
1433
|
+
setTimeout(() => {
|
|
1434
|
+
blockTimer == null ? void 0 : blockTimer(false);
|
|
1435
|
+
}, 700);
|
|
1436
|
+
return true;
|
|
1437
|
+
}
|
|
1438
|
+
} else {
|
|
1439
|
+
if (distance >= 1.3 * threshold) {
|
|
1440
|
+
return false;
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
return isReached;
|
|
1444
|
+
};
|
|
1068
1445
|
const checkAtBottom = () => {
|
|
1069
1446
|
if (!refState.current) {
|
|
1070
1447
|
return;
|
|
1071
1448
|
}
|
|
1072
|
-
const { scrollLength, scroll
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
}
|
|
1449
|
+
const { queuedInitialLayout, scrollLength, scroll } = refState.current;
|
|
1450
|
+
const contentSize = getContentSize(ctx);
|
|
1451
|
+
if (contentSize > 0 && queuedInitialLayout) {
|
|
1452
|
+
const distanceFromEnd = contentSize - scroll - scrollLength;
|
|
1453
|
+
const distanceFromEndAbs = Math.abs(distanceFromEnd);
|
|
1454
|
+
const isContentLess = contentSize < scrollLength;
|
|
1455
|
+
refState.current.isAtBottom = isContentLess || distanceFromEndAbs < scrollLength * maintainScrollAtEndThreshold;
|
|
1456
|
+
refState.current.isEndReached = checkThreshold(
|
|
1457
|
+
distanceFromEnd,
|
|
1458
|
+
isContentLess,
|
|
1459
|
+
onEndReachedThreshold * scrollLength,
|
|
1460
|
+
refState.current.isEndReached,
|
|
1461
|
+
refState.current.endReachedBlockedByTimer,
|
|
1462
|
+
(distance) => {
|
|
1463
|
+
var _a2, _b2;
|
|
1464
|
+
return (_b2 = (_a2 = callbacks.current).onEndReached) == null ? void 0 : _b2.call(_a2, { distanceFromEnd: distance });
|
|
1465
|
+
},
|
|
1466
|
+
(block) => {
|
|
1467
|
+
refState.current.endReachedBlockedByTimer = block;
|
|
1088
1468
|
}
|
|
1089
|
-
|
|
1469
|
+
);
|
|
1090
1470
|
}
|
|
1091
1471
|
};
|
|
1092
1472
|
const checkAtTop = () => {
|
|
@@ -1095,112 +1475,119 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1095
1475
|
}
|
|
1096
1476
|
const { scrollLength, scroll } = refState.current;
|
|
1097
1477
|
const distanceFromTop = scroll;
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
}
|
|
1478
|
+
const distanceFromTopAbs = Math.abs(distanceFromTop);
|
|
1479
|
+
refState.current.isAtTop = distanceFromTopAbs < 0;
|
|
1480
|
+
refState.current.isStartReached = checkThreshold(
|
|
1481
|
+
distanceFromTop,
|
|
1482
|
+
false,
|
|
1483
|
+
onStartReachedThreshold * scrollLength,
|
|
1484
|
+
refState.current.isStartReached,
|
|
1485
|
+
refState.current.startReachedBlockedByTimer,
|
|
1486
|
+
(distance) => {
|
|
1487
|
+
var _a2, _b2;
|
|
1488
|
+
return (_b2 = (_a2 = callbacks.current).onStartReached) == null ? void 0 : _b2.call(_a2, { distanceFromStart: distance });
|
|
1489
|
+
},
|
|
1490
|
+
(block) => {
|
|
1491
|
+
refState.current.startReachedBlockedByTimer = block;
|
|
1113
1492
|
}
|
|
1114
|
-
|
|
1493
|
+
);
|
|
1115
1494
|
};
|
|
1116
|
-
const checkResetContainers = (
|
|
1495
|
+
const checkResetContainers = (isFirst2) => {
|
|
1117
1496
|
const state = refState.current;
|
|
1118
1497
|
if (state) {
|
|
1119
|
-
state.data =
|
|
1120
|
-
if (
|
|
1498
|
+
state.data = dataProp;
|
|
1499
|
+
if (!isFirst2) {
|
|
1121
1500
|
refState.current.scrollForNextCalculateItemsInView = void 0;
|
|
1122
1501
|
const numContainers = peek$(ctx, "numContainers");
|
|
1123
1502
|
for (let i = 0; i < numContainers; i++) {
|
|
1124
1503
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1125
1504
|
if (!keyExtractorProp || itemKey && state.indexByKey.get(itemKey) === void 0) {
|
|
1126
1505
|
set$(ctx, `containerItemKey${i}`, void 0);
|
|
1506
|
+
set$(ctx, `containerItemData${i}`, void 0);
|
|
1127
1507
|
set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
|
|
1128
1508
|
set$(ctx, `containerColumn${i}`, -1);
|
|
1129
1509
|
}
|
|
1130
1510
|
}
|
|
1131
1511
|
if (!keyExtractorProp) {
|
|
1132
|
-
state.sizes.clear();
|
|
1133
1512
|
state.positions.clear();
|
|
1134
1513
|
}
|
|
1135
|
-
calculateItemsInView(
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1514
|
+
calculateItemsInView();
|
|
1515
|
+
const didMaintainScrollAtEnd = doMaintainScrollAtEnd(false);
|
|
1516
|
+
if (!didMaintainScrollAtEnd && dataProp.length > state.data.length) {
|
|
1517
|
+
state.isEndReached = false;
|
|
1518
|
+
}
|
|
1519
|
+
checkAtTop();
|
|
1520
|
+
checkAtBottom();
|
|
1140
1521
|
}
|
|
1141
|
-
checkAtTop();
|
|
1142
|
-
checkAtBottom();
|
|
1143
1522
|
}
|
|
1144
1523
|
};
|
|
1145
|
-
const
|
|
1146
|
-
|
|
1147
|
-
if (!keyExtractorProp && !isFirst && data !== refState.current.data) {
|
|
1148
|
-
refState.current.sizes.clear();
|
|
1149
|
-
refState.current.positions.clear();
|
|
1150
|
-
}
|
|
1151
|
-
refState.current.data = data;
|
|
1524
|
+
const calcTotalSizesAndPositions = ({ forgetPositions = false }) => {
|
|
1525
|
+
var _a2, _b2;
|
|
1152
1526
|
let totalSize = 0;
|
|
1153
1527
|
let totalSizeBelowIndex = 0;
|
|
1154
1528
|
const indexByKey = /* @__PURE__ */ new Map();
|
|
1155
1529
|
const newPositions = /* @__PURE__ */ new Map();
|
|
1156
1530
|
let column = 1;
|
|
1157
1531
|
let maxSizeInRow = 0;
|
|
1158
|
-
|
|
1532
|
+
const numColumns = (_a2 = peek$(ctx, "numColumns")) != null ? _a2 : numColumnsProp;
|
|
1533
|
+
if (!refState.current) {
|
|
1534
|
+
return;
|
|
1535
|
+
}
|
|
1536
|
+
for (let i = 0; i < dataProp.length; i++) {
|
|
1159
1537
|
const key = getId(i);
|
|
1538
|
+
if (__DEV__) {
|
|
1539
|
+
if (indexByKey.has(key)) {
|
|
1540
|
+
console.error(
|
|
1541
|
+
`[legend-list] Error: Detected overlapping key (${key}) which causes missing items and gaps and other terrrible things. Check that keyExtractor returns unique values.`
|
|
1542
|
+
);
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1160
1545
|
indexByKey.set(key, i);
|
|
1161
|
-
if (refState.current.positions.get(key) != null && refState.current.indexByKey.get(key) === i) {
|
|
1546
|
+
if (!forgetPositions && refState.current.positions.get(key) != null && refState.current.indexByKey.get(key) === i) {
|
|
1162
1547
|
newPositions.set(key, refState.current.positions.get(key));
|
|
1163
1548
|
}
|
|
1164
1549
|
}
|
|
1165
1550
|
refState.current.indexByKey = indexByKey;
|
|
1166
1551
|
refState.current.positions = newPositions;
|
|
1167
|
-
if (
|
|
1168
|
-
if (
|
|
1169
|
-
if (
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1552
|
+
if (!forgetPositions && !isFirst) {
|
|
1553
|
+
if (maintainVisibleContentPosition) {
|
|
1554
|
+
if (refState.current.anchorElement == null || indexByKey.get(refState.current.anchorElement.id) == null) {
|
|
1555
|
+
if (dataProp.length) {
|
|
1556
|
+
const newAnchorElement = {
|
|
1557
|
+
coordinate: 0,
|
|
1558
|
+
id: getId(0)
|
|
1559
|
+
};
|
|
1560
|
+
refState.current.anchorElement = newAnchorElement;
|
|
1561
|
+
(_b2 = refState.current.belowAnchorElementPositions) == null ? void 0 : _b2.clear();
|
|
1562
|
+
scrollTo(0, false);
|
|
1563
|
+
setTimeout(() => {
|
|
1564
|
+
calculateItemsInView();
|
|
1565
|
+
}, 0);
|
|
1566
|
+
} else {
|
|
1567
|
+
refState.current.startBufferedId = void 0;
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
} else {
|
|
1571
|
+
if (refState.current.startBufferedId != null && newPositions.get(refState.current.startBufferedId) == null) {
|
|
1572
|
+
if (dataProp.length) {
|
|
1573
|
+
refState.current.startBufferedId = getId(0);
|
|
1574
|
+
} else {
|
|
1575
|
+
refState.current.startBufferedId = void 0;
|
|
1576
|
+
}
|
|
1577
|
+
scrollTo(0, false);
|
|
1177
1578
|
setTimeout(() => {
|
|
1178
|
-
calculateItemsInView(
|
|
1579
|
+
calculateItemsInView();
|
|
1179
1580
|
}, 0);
|
|
1180
|
-
} else {
|
|
1181
|
-
refState.current.startBufferedId = void 0;
|
|
1182
1581
|
}
|
|
1183
1582
|
}
|
|
1184
|
-
} else {
|
|
1185
|
-
if (refState.current.startBufferedId != null && newPositions.get(refState.current.startBufferedId) == null) {
|
|
1186
|
-
if (data.length) {
|
|
1187
|
-
refState.current.startBufferedId = getId(0);
|
|
1188
|
-
} else {
|
|
1189
|
-
refState.current.startBufferedId = void 0;
|
|
1190
|
-
}
|
|
1191
|
-
refScroller.current.scrollTo({ x: 0, y: 0, animated: false });
|
|
1192
|
-
setTimeout(() => {
|
|
1193
|
-
calculateItemsInView(0);
|
|
1194
|
-
}, 0);
|
|
1195
|
-
}
|
|
1196
1583
|
}
|
|
1197
1584
|
const anchorElementIndex = getAnchorElementIndex();
|
|
1198
|
-
for (let i = 0; i <
|
|
1585
|
+
for (let i = 0; i < dataProp.length; i++) {
|
|
1199
1586
|
const key = getId(i);
|
|
1200
|
-
const size = getItemSize(key, i,
|
|
1587
|
+
const size = getItemSize(key, i, dataProp[i]);
|
|
1201
1588
|
maxSizeInRow = Math.max(maxSizeInRow, size);
|
|
1202
1589
|
column++;
|
|
1203
|
-
if (column >
|
|
1590
|
+
if (column > numColumns) {
|
|
1204
1591
|
if (maintainVisibleContentPosition && anchorElementIndex !== void 0 && i < anchorElementIndex) {
|
|
1205
1592
|
totalSizeBelowIndex += maxSizeInRow;
|
|
1206
1593
|
}
|
|
@@ -1212,111 +1599,172 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1212
1599
|
if (maxSizeInRow > 0) {
|
|
1213
1600
|
totalSize += maxSizeInRow;
|
|
1214
1601
|
}
|
|
1602
|
+
const state = refState.current;
|
|
1603
|
+
state.ignoreScrollFromCalcTotal = true;
|
|
1604
|
+
requestAnimationFrame(() => {
|
|
1605
|
+
state.ignoreScrollFromCalcTotal = false;
|
|
1606
|
+
});
|
|
1215
1607
|
addTotalSize(null, totalSize, totalSizeBelowIndex);
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1608
|
+
};
|
|
1609
|
+
const isFirst = !refState.current.renderItem;
|
|
1610
|
+
const memoizedLastItemKeys = useMemo(() => {
|
|
1611
|
+
if (!dataProp.length) return [];
|
|
1612
|
+
return Array.from(
|
|
1613
|
+
{ length: Math.min(numColumnsProp, dataProp.length) },
|
|
1614
|
+
(_, i) => getId(dataProp.length - 1 - i)
|
|
1221
1615
|
);
|
|
1222
|
-
}, [
|
|
1223
|
-
|
|
1224
|
-
set$(ctx, "extraData", extraData);
|
|
1225
|
-
}, [extraData]);
|
|
1226
|
-
refState.current.renderItem = renderItem;
|
|
1227
|
-
const lastItemKey = data.length > 0 ? getId(data.length - 1) : void 0;
|
|
1228
|
-
const stylePaddingTop = (_e = (_d = (_b = StyleSheet.flatten(style)) == null ? void 0 : _b.paddingTop) != null ? _d : (_c = StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _c.paddingTop) != null ? _e : 0;
|
|
1616
|
+
}, [dataProp, numColumnsProp]);
|
|
1617
|
+
const stylePaddingTop = (_d = (_c = (_a = StyleSheet.flatten(style)) == null ? void 0 : _a.paddingTop) != null ? _c : (_b = StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _b.paddingTop) != null ? _d : 0;
|
|
1229
1618
|
const initalizeStateVars = () => {
|
|
1230
|
-
set$(ctx, "
|
|
1619
|
+
set$(ctx, "lastItemKeys", memoizedLastItemKeys);
|
|
1231
1620
|
set$(ctx, "numColumns", numColumnsProp);
|
|
1232
|
-
|
|
1621
|
+
if (maintainVisibleContentPosition) {
|
|
1622
|
+
const prevPaddingTop = peek$(ctx, "stylePaddingTop");
|
|
1623
|
+
const paddingDiff = stylePaddingTop - prevPaddingTop;
|
|
1624
|
+
if (paddingDiff) {
|
|
1625
|
+
scrollTo(refState.current.scroll + paddingDiff, false);
|
|
1626
|
+
}
|
|
1627
|
+
set$(ctx, "stylePaddingTop", stylePaddingTop);
|
|
1628
|
+
}
|
|
1233
1629
|
};
|
|
1234
1630
|
if (isFirst) {
|
|
1235
1631
|
initalizeStateVars();
|
|
1236
1632
|
}
|
|
1237
|
-
|
|
1633
|
+
if (isFirst || didDataChange || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
1634
|
+
refState.current.lastBatchingAction = Date.now();
|
|
1635
|
+
if (!keyExtractorProp && !isFirst && didDataChange) {
|
|
1636
|
+
refState.current.sizes.clear();
|
|
1637
|
+
refState.current.positions.clear();
|
|
1638
|
+
}
|
|
1639
|
+
calcTotalSizesAndPositions({ forgetPositions: false });
|
|
1640
|
+
}
|
|
1641
|
+
useEffect(() => {
|
|
1642
|
+
const didAllocateContainers = doInitialAllocateContainers();
|
|
1643
|
+
if (!didAllocateContainers) {
|
|
1644
|
+
checkResetContainers(
|
|
1645
|
+
/*isFirst*/
|
|
1646
|
+
isFirst
|
|
1647
|
+
);
|
|
1648
|
+
}
|
|
1649
|
+
}, [isFirst, dataProp, numColumnsProp]);
|
|
1650
|
+
useEffect(() => {
|
|
1651
|
+
set$(ctx, "extraData", extraData);
|
|
1652
|
+
}, [extraData]);
|
|
1653
|
+
refState.current.renderItem = renderItem;
|
|
1654
|
+
useEffect(initalizeStateVars, [memoizedLastItemKeys.join(","), numColumnsProp, stylePaddingTop]);
|
|
1238
1655
|
const getRenderedItem = useCallback((key) => {
|
|
1239
1656
|
var _a2, _b2;
|
|
1240
1657
|
const state = refState.current;
|
|
1241
1658
|
if (!state) {
|
|
1242
1659
|
return null;
|
|
1243
1660
|
}
|
|
1244
|
-
const { data
|
|
1661
|
+
const { data, indexByKey } = state;
|
|
1245
1662
|
const index = indexByKey.get(key);
|
|
1246
1663
|
if (index === void 0) {
|
|
1247
1664
|
return null;
|
|
1248
1665
|
}
|
|
1249
|
-
const useViewability2 = (configId, callback) => {
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1666
|
+
const useViewability2 = __DEV__ ? (configId, callback) => {
|
|
1667
|
+
console.warn(
|
|
1668
|
+
`[legend-list] useViewability has been moved from a render prop to a regular import: import { useViewability } from "@legendapp/list";`
|
|
1669
|
+
);
|
|
1670
|
+
} : void 0;
|
|
1671
|
+
const useViewabilityAmount2 = __DEV__ ? (callback) => {
|
|
1672
|
+
console.warn(
|
|
1673
|
+
`[legend-list] useViewabilityAmount has been moved from a render prop to a regular import: import { useViewabilityAmount } from "@legendapp/list";`
|
|
1674
|
+
);
|
|
1675
|
+
} : void 0;
|
|
1676
|
+
const useRecyclingEffect2 = __DEV__ ? (effect) => {
|
|
1677
|
+
console.warn(
|
|
1678
|
+
`[legend-list] useRecyclingEffect has been moved from a render prop to a regular import: import { useRecyclingEffect } from "@legendapp/list";`
|
|
1679
|
+
);
|
|
1680
|
+
} : void 0;
|
|
1681
|
+
const useRecyclingState2 = __DEV__ ? (valueOrFun) => {
|
|
1682
|
+
console.warn(
|
|
1683
|
+
`[legend-list] useRecyclingState has been moved from a render prop to a regular import: import { useRecyclingState } from "@legendapp/list";`
|
|
1684
|
+
);
|
|
1685
|
+
} : void 0;
|
|
1261
1686
|
const renderedItem = (_b2 = (_a2 = refState.current).renderItem) == null ? void 0 : _b2.call(_a2, {
|
|
1262
|
-
item:
|
|
1687
|
+
item: data[index],
|
|
1263
1688
|
index,
|
|
1689
|
+
extraData: peek$(ctx, "extraData"),
|
|
1690
|
+
// @ts-expect-error TODO: Remove these before 1.0
|
|
1264
1691
|
useViewability: useViewability2,
|
|
1265
1692
|
useViewabilityAmount: useViewabilityAmount2,
|
|
1266
1693
|
useRecyclingEffect: useRecyclingEffect2,
|
|
1267
1694
|
useRecyclingState: useRecyclingState2
|
|
1268
1695
|
});
|
|
1269
|
-
return { index, renderedItem };
|
|
1696
|
+
return { index, item: data[index], renderedItem };
|
|
1270
1697
|
}, []);
|
|
1271
|
-
|
|
1698
|
+
const doInitialAllocateContainers = () => {
|
|
1272
1699
|
var _a2;
|
|
1273
1700
|
const state = refState.current;
|
|
1274
|
-
const
|
|
1701
|
+
const { scrollLength, data } = state;
|
|
1702
|
+
if (scrollLength > 0 && data.length > 0 && !peek$(ctx, "numContainers")) {
|
|
1703
|
+
const averageItemSize = (_a2 = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, data[0])) != null ? _a2 : DEFAULT_ITEM_SIZE;
|
|
1704
|
+
const numContainers = Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize) * numColumnsProp;
|
|
1705
|
+
for (let i = 0; i < numContainers; i++) {
|
|
1706
|
+
set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
|
|
1707
|
+
set$(ctx, `containerColumn${i}`, -1);
|
|
1708
|
+
}
|
|
1709
|
+
set$(ctx, "numContainers", numContainers);
|
|
1710
|
+
set$(ctx, "numContainersPooled", numContainers * initialContainerPoolRatio);
|
|
1711
|
+
if (initialScrollIndex) {
|
|
1712
|
+
requestAnimationFrame(() => {
|
|
1713
|
+
calculateItemsInView();
|
|
1714
|
+
});
|
|
1715
|
+
} else {
|
|
1716
|
+
calculateItemsInView();
|
|
1717
|
+
}
|
|
1718
|
+
return true;
|
|
1719
|
+
}
|
|
1720
|
+
};
|
|
1721
|
+
useEffect(() => {
|
|
1722
|
+
const state = refState.current;
|
|
1723
|
+
const viewability = setupViewability({
|
|
1724
|
+
viewabilityConfig,
|
|
1725
|
+
viewabilityConfigCallbackPairs,
|
|
1726
|
+
onViewableItemsChanged
|
|
1727
|
+
});
|
|
1275
1728
|
state.viewabilityConfigCallbackPairs = viewability;
|
|
1276
1729
|
state.enableScrollForNextCalculateItemsInView = !viewability;
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
for (let i = 0; i < numContainers; i++) {
|
|
1281
|
-
set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
|
|
1282
|
-
set$(ctx, `containerColumn${i}`, -1);
|
|
1283
|
-
}
|
|
1284
|
-
set$(ctx, "numContainers", numContainers);
|
|
1285
|
-
set$(ctx, "numContainersPooled", numContainers * 2);
|
|
1286
|
-
calculateItemsInView(state.scrollVelocity);
|
|
1730
|
+
}, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
|
|
1731
|
+
useInit(() => {
|
|
1732
|
+
doInitialAllocateContainers();
|
|
1287
1733
|
});
|
|
1288
|
-
const updateItemSize = useCallback((
|
|
1289
|
-
|
|
1290
|
-
const
|
|
1291
|
-
if (!
|
|
1734
|
+
const updateItemSize = useCallback((itemKey, size) => {
|
|
1735
|
+
const state = refState.current;
|
|
1736
|
+
const { sizes, indexByKey, sizesKnown, data, rowHeights } = state;
|
|
1737
|
+
if (!data) {
|
|
1292
1738
|
return;
|
|
1293
1739
|
}
|
|
1294
|
-
const state = refState.current;
|
|
1295
|
-
const { sizes, indexByKey, columns, sizesLaidOut } = state;
|
|
1296
1740
|
const index = indexByKey.get(itemKey);
|
|
1297
1741
|
const numColumns = peek$(ctx, "numColumns");
|
|
1298
|
-
|
|
1299
|
-
const prevSize =
|
|
1742
|
+
state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, index) : index;
|
|
1743
|
+
const prevSize = getItemSize(itemKey, index, data);
|
|
1744
|
+
let needsCalculate = false;
|
|
1745
|
+
if (state.numPendingInitialLayout > 0) {
|
|
1746
|
+
state.numPendingInitialLayout--;
|
|
1747
|
+
if (state.numPendingInitialLayout === 0) {
|
|
1748
|
+
needsCalculate = true;
|
|
1749
|
+
state.numPendingInitialLayout = -1;
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
sizesKnown == null ? void 0 : sizesKnown.set(itemKey, size);
|
|
1300
1753
|
if (!prevSize || Math.abs(prevSize - size) > 0.5) {
|
|
1301
1754
|
let diff;
|
|
1755
|
+
needsCalculate = true;
|
|
1302
1756
|
if (numColumns > 1) {
|
|
1303
|
-
const
|
|
1757
|
+
const rowNumber = Math.floor(index / numColumnsProp);
|
|
1758
|
+
const prevSizeInRow = getRowHeight(rowNumber);
|
|
1304
1759
|
sizes.set(itemKey, size);
|
|
1305
|
-
|
|
1306
|
-
const
|
|
1307
|
-
|
|
1308
|
-
for (let i = loopStart; i < loopStart + numColumns && i < data2.length; i++) {
|
|
1309
|
-
const id = getId(i);
|
|
1310
|
-
const size2 = getItemSize(id, i, data2[i]);
|
|
1311
|
-
nextMaxSizeInRow = Math.max(nextMaxSizeInRow, size2);
|
|
1312
|
-
}
|
|
1313
|
-
diff = nextMaxSizeInRow - prevMaxSizeInRow;
|
|
1760
|
+
rowHeights.delete(rowNumber);
|
|
1761
|
+
const sizeInRow = getRowHeight(rowNumber);
|
|
1762
|
+
diff = sizeInRow - prevSizeInRow;
|
|
1314
1763
|
} else {
|
|
1315
1764
|
sizes.set(itemKey, size);
|
|
1316
1765
|
diff = size - prevSize;
|
|
1317
1766
|
}
|
|
1318
1767
|
if (__DEV__ && !estimatedItemSize && !getEstimatedItemSize) {
|
|
1319
|
-
sizesLaidOut.set(itemKey, size);
|
|
1320
1768
|
if (state.timeoutSizeMessage) {
|
|
1321
1769
|
clearTimeout(state.timeoutSizeMessage);
|
|
1322
1770
|
}
|
|
@@ -1324,7 +1772,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1324
1772
|
state.timeoutSizeMessage = void 0;
|
|
1325
1773
|
let total = 0;
|
|
1326
1774
|
let num = 0;
|
|
1327
|
-
for (const [
|
|
1775
|
+
for (const [_, size2] of sizesKnown) {
|
|
1328
1776
|
num++;
|
|
1329
1777
|
total += size2;
|
|
1330
1778
|
}
|
|
@@ -1336,38 +1784,48 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1336
1784
|
}
|
|
1337
1785
|
refState.current.scrollForNextCalculateItemsInView = void 0;
|
|
1338
1786
|
addTotalSize(itemKey, diff, 0);
|
|
1339
|
-
doMaintainScrollAtEnd(
|
|
1787
|
+
doMaintainScrollAtEnd(false);
|
|
1788
|
+
if (onItemSizeChanged) {
|
|
1789
|
+
onItemSizeChanged({
|
|
1790
|
+
size,
|
|
1791
|
+
previous: prevSize,
|
|
1792
|
+
index,
|
|
1793
|
+
itemKey,
|
|
1794
|
+
itemData: data[index]
|
|
1795
|
+
});
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
if (needsCalculate) {
|
|
1340
1799
|
const scrollVelocity = state.scrollVelocity;
|
|
1341
|
-
if (
|
|
1342
|
-
if (
|
|
1343
|
-
state.
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
});
|
|
1800
|
+
if ((Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1) && (!waitForInitialLayout || state.numPendingInitialLayout < 0)) {
|
|
1801
|
+
if (Date.now() - state.lastBatchingAction < 500) {
|
|
1802
|
+
if (!state.queuedCalculateItemsInView) {
|
|
1803
|
+
state.queuedCalculateItemsInView = requestAnimationFrame(() => {
|
|
1804
|
+
state.queuedCalculateItemsInView = void 0;
|
|
1805
|
+
calculateItemsInView();
|
|
1806
|
+
});
|
|
1807
|
+
}
|
|
1350
1808
|
} else {
|
|
1351
|
-
calculateItemsInView(
|
|
1809
|
+
calculateItemsInView();
|
|
1352
1810
|
}
|
|
1353
1811
|
}
|
|
1354
|
-
if (onItemSizeChanged) {
|
|
1355
|
-
onItemSizeChanged({ size, previous: prevSize, index, itemKey, itemData: data2[index] });
|
|
1356
|
-
}
|
|
1357
1812
|
}
|
|
1358
1813
|
}, []);
|
|
1359
|
-
const handleScrollDebounced = useCallback((velocity) => {
|
|
1360
|
-
calculateItemsInView(velocity);
|
|
1361
|
-
checkAtBottom();
|
|
1362
|
-
checkAtTop();
|
|
1363
|
-
}, []);
|
|
1364
1814
|
const onLayout = useCallback((event) => {
|
|
1815
|
+
const state = refState.current;
|
|
1365
1816
|
const scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
1366
|
-
|
|
1817
|
+
const didChange = scrollLength !== state.scrollLength;
|
|
1818
|
+
state.scrollLength = scrollLength;
|
|
1819
|
+
state.lastBatchingAction = Date.now();
|
|
1820
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
1821
|
+
doInitialAllocateContainers();
|
|
1367
1822
|
doMaintainScrollAtEnd(false);
|
|
1368
1823
|
doUpdatePaddingTop();
|
|
1369
1824
|
checkAtBottom();
|
|
1370
1825
|
checkAtTop();
|
|
1826
|
+
if (didChange) {
|
|
1827
|
+
calculateItemsInView();
|
|
1828
|
+
}
|
|
1371
1829
|
if (__DEV__) {
|
|
1372
1830
|
const isWidthZero = event.nativeEvent.layout.width === 0;
|
|
1373
1831
|
const isHeightZero = event.nativeEvent.layout.height === 0;
|
|
@@ -1377,17 +1835,24 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1377
1835
|
);
|
|
1378
1836
|
}
|
|
1379
1837
|
}
|
|
1838
|
+
if (onLayoutProp) {
|
|
1839
|
+
onLayoutProp(event);
|
|
1840
|
+
}
|
|
1380
1841
|
}, []);
|
|
1381
1842
|
const handleScroll = useCallback(
|
|
1382
1843
|
(event, fromSelf) => {
|
|
1383
|
-
var _a2, _b2, _c2;
|
|
1844
|
+
var _a2, _b2, _c2, _d2;
|
|
1384
1845
|
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) {
|
|
1385
1846
|
return;
|
|
1386
1847
|
}
|
|
1387
1848
|
const state = refState.current;
|
|
1849
|
+
const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
|
|
1850
|
+
if (state.ignoreScrollFromCalcTotal && newScroll !== 0) {
|
|
1851
|
+
return;
|
|
1852
|
+
}
|
|
1388
1853
|
state.hasScrolled = true;
|
|
1854
|
+
state.lastBatchingAction = Date.now();
|
|
1389
1855
|
const currentTime = performance.now();
|
|
1390
|
-
const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
|
|
1391
1856
|
if (!(state.scrollHistory.length === 0 && newScroll === initialContentOffset)) {
|
|
1392
1857
|
state.scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
1393
1858
|
}
|
|
@@ -1413,9 +1878,11 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1413
1878
|
state.scroll = newScroll;
|
|
1414
1879
|
state.scrollTime = currentTime;
|
|
1415
1880
|
state.scrollVelocity = velocity;
|
|
1416
|
-
|
|
1881
|
+
calculateItemsInView();
|
|
1882
|
+
checkAtBottom();
|
|
1883
|
+
checkAtTop();
|
|
1417
1884
|
if (!fromSelf) {
|
|
1418
|
-
|
|
1885
|
+
(_d2 = state.onScroll) == null ? void 0 : _d2.call(state, event);
|
|
1419
1886
|
}
|
|
1420
1887
|
},
|
|
1421
1888
|
[]
|
|
@@ -1423,61 +1890,157 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1423
1890
|
useImperativeHandle(
|
|
1424
1891
|
forwardedRef,
|
|
1425
1892
|
() => {
|
|
1426
|
-
const scrollToIndex = ({
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1893
|
+
const scrollToIndex = ({
|
|
1894
|
+
index,
|
|
1895
|
+
viewOffset = 0,
|
|
1896
|
+
animated = true,
|
|
1897
|
+
viewPosition = 0
|
|
1898
|
+
}) => {
|
|
1899
|
+
var _a2;
|
|
1900
|
+
const state = refState.current;
|
|
1901
|
+
const firstIndexOffset = calculateOffsetForIndex(index);
|
|
1902
|
+
let firstIndexScrollPostion = firstIndexOffset - viewOffset;
|
|
1903
|
+
const diff = Math.abs(state.scroll - firstIndexScrollPostion);
|
|
1904
|
+
const needsReanchoring = maintainVisibleContentPosition && diff > 100;
|
|
1905
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
1906
|
+
if (needsReanchoring) {
|
|
1907
|
+
const id = getId(index);
|
|
1908
|
+
state.anchorElement = { id, coordinate: firstIndexOffset };
|
|
1909
|
+
(_a2 = state.belowAnchorElementPositions) == null ? void 0 : _a2.clear();
|
|
1910
|
+
state.positions.clear();
|
|
1911
|
+
calcTotalSizesAndPositions({ forgetPositions: true });
|
|
1912
|
+
state.startBufferedId = id;
|
|
1913
|
+
state.minIndexSizeChanged = index;
|
|
1914
|
+
firstIndexScrollPostion = firstIndexOffset - viewOffset + state.scrollAdjustHandler.getAppliedAdjust();
|
|
1915
|
+
}
|
|
1916
|
+
if (viewPosition) {
|
|
1917
|
+
firstIndexScrollPostion -= viewPosition * (state.scrollLength - getItemSize(getId(index), index, state.data[index]));
|
|
1918
|
+
}
|
|
1919
|
+
state.scrollAdjustHandler.setDisableAdjust(true);
|
|
1920
|
+
state.scrollingToOffset = firstIndexScrollPostion;
|
|
1921
|
+
scrollTo(firstIndexScrollPostion, animated);
|
|
1922
|
+
};
|
|
1923
|
+
const scrollIndexIntoView = (options) => {
|
|
1924
|
+
if (refState.current) {
|
|
1925
|
+
const { index, ...rest2 } = options;
|
|
1926
|
+
const { startNoBuffer, endNoBuffer } = refState.current;
|
|
1927
|
+
if (index < startNoBuffer || index > endNoBuffer) {
|
|
1928
|
+
const viewPosition = index < startNoBuffer ? 0 : 1;
|
|
1929
|
+
scrollToIndex({
|
|
1930
|
+
...rest2,
|
|
1931
|
+
viewPosition,
|
|
1932
|
+
index
|
|
1933
|
+
});
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1430
1936
|
};
|
|
1431
1937
|
return {
|
|
1938
|
+
flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
|
|
1432
1939
|
getNativeScrollRef: () => refScroller.current,
|
|
1433
|
-
getScrollableNode: refScroller.current.getScrollableNode,
|
|
1434
|
-
getScrollResponder: refScroller.current.getScrollResponder,
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1940
|
+
getScrollableNode: () => refScroller.current.getScrollableNode(),
|
|
1941
|
+
getScrollResponder: () => refScroller.current.getScrollResponder(),
|
|
1942
|
+
getState: () => {
|
|
1943
|
+
const state = refState.current;
|
|
1944
|
+
return state ? {
|
|
1945
|
+
contentLength: state.totalSize,
|
|
1946
|
+
end: state.endNoBuffer,
|
|
1947
|
+
endBuffered: state.endBuffered,
|
|
1948
|
+
isAtEnd: state.isAtBottom,
|
|
1949
|
+
isAtStart: state.isAtTop,
|
|
1950
|
+
scroll: state.scroll,
|
|
1951
|
+
scrollLength: state.scrollLength,
|
|
1952
|
+
start: state.startNoBuffer,
|
|
1953
|
+
startBuffered: state.startBuffered
|
|
1954
|
+
} : {};
|
|
1440
1955
|
},
|
|
1441
|
-
|
|
1956
|
+
scrollIndexIntoView,
|
|
1957
|
+
scrollItemIntoView: ({ item, ...props2 }) => {
|
|
1958
|
+
const { data } = refState.current;
|
|
1442
1959
|
const index = data.indexOf(item);
|
|
1443
1960
|
if (index !== -1) {
|
|
1444
|
-
|
|
1961
|
+
scrollIndexIntoView({ index, ...props2 });
|
|
1445
1962
|
}
|
|
1446
1963
|
},
|
|
1447
|
-
|
|
1964
|
+
scrollToIndex,
|
|
1965
|
+
scrollToItem: ({ item, ...props2 }) => {
|
|
1966
|
+
const { data } = refState.current;
|
|
1967
|
+
const index = data.indexOf(item);
|
|
1968
|
+
if (index !== -1) {
|
|
1969
|
+
scrollToIndex({ index, ...props2 });
|
|
1970
|
+
}
|
|
1971
|
+
},
|
|
1972
|
+
scrollToOffset: ({ offset, animated }) => {
|
|
1973
|
+
scrollTo(offset, animated);
|
|
1974
|
+
},
|
|
1975
|
+
scrollToEnd: (options) => refScroller.current.scrollToEnd(options)
|
|
1448
1976
|
};
|
|
1449
1977
|
},
|
|
1450
1978
|
[]
|
|
1451
1979
|
);
|
|
1452
|
-
|
|
1980
|
+
if (Platform.OS === "web") {
|
|
1981
|
+
useEffect(() => {
|
|
1982
|
+
var _a2;
|
|
1983
|
+
if (initialContentOffset) {
|
|
1984
|
+
(_a2 = refState.current) == null ? void 0 : _a2.scrollAdjustHandler.setDisableAdjust(true);
|
|
1985
|
+
scrollTo(initialContentOffset, false);
|
|
1986
|
+
setTimeout(() => {
|
|
1987
|
+
var _a3;
|
|
1988
|
+
(_a3 = refState.current) == null ? void 0 : _a3.scrollAdjustHandler.setDisableAdjust(false);
|
|
1989
|
+
}, 0);
|
|
1990
|
+
}
|
|
1991
|
+
}, []);
|
|
1992
|
+
}
|
|
1993
|
+
return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(
|
|
1453
1994
|
ListComponent,
|
|
1454
1995
|
{
|
|
1455
1996
|
...rest,
|
|
1456
1997
|
horizontal,
|
|
1457
|
-
refScrollView:
|
|
1458
|
-
refScroller.current = r;
|
|
1459
|
-
if (refScrollView) {
|
|
1460
|
-
if (typeof refScrollView === "function") {
|
|
1461
|
-
refScrollView(r);
|
|
1462
|
-
} else {
|
|
1463
|
-
refScrollView.current = r;
|
|
1464
|
-
}
|
|
1465
|
-
}
|
|
1466
|
-
},
|
|
1998
|
+
refScrollView: combinedRef,
|
|
1467
1999
|
initialContentOffset,
|
|
1468
2000
|
getRenderedItem,
|
|
1469
2001
|
updateItemSize,
|
|
1470
2002
|
handleScroll,
|
|
2003
|
+
onMomentumScrollEnd: (event) => {
|
|
2004
|
+
var _a2;
|
|
2005
|
+
const scrollingToOffset = (_a2 = refState.current) == null ? void 0 : _a2.scrollingToOffset;
|
|
2006
|
+
if (scrollingToOffset !== void 0) {
|
|
2007
|
+
requestAnimationFrame(() => {
|
|
2008
|
+
scrollTo(scrollingToOffset, false);
|
|
2009
|
+
refState.current.scrollingToOffset = void 0;
|
|
2010
|
+
requestAnimationFrame(() => {
|
|
2011
|
+
refState.current.scrollAdjustHandler.setDisableAdjust(false);
|
|
2012
|
+
});
|
|
2013
|
+
});
|
|
2014
|
+
}
|
|
2015
|
+
const wasPaused = refState.current.scrollAdjustHandler.unPauseAdjust();
|
|
2016
|
+
if (wasPaused) {
|
|
2017
|
+
refState.current.scrollVelocity = 0;
|
|
2018
|
+
refState.current.scrollHistory = [];
|
|
2019
|
+
calculateItemsInView();
|
|
2020
|
+
}
|
|
2021
|
+
if (onMomentumScrollEnd) {
|
|
2022
|
+
onMomentumScrollEnd(event);
|
|
2023
|
+
}
|
|
2024
|
+
},
|
|
1471
2025
|
onLayout,
|
|
1472
2026
|
recycleItems,
|
|
1473
2027
|
alignItemsAtEnd,
|
|
1474
|
-
ListEmptyComponent:
|
|
2028
|
+
ListEmptyComponent: dataProp.length === 0 ? ListEmptyComponent : void 0,
|
|
1475
2029
|
maintainVisibleContentPosition,
|
|
1476
2030
|
scrollEventThrottle: scrollEventThrottle != null ? scrollEventThrottle : Platform.OS === "web" ? 16 : void 0,
|
|
1477
2031
|
waitForInitialLayout,
|
|
1478
|
-
|
|
2032
|
+
refreshControl: refreshControl != null ? refreshControl : onRefresh && /* @__PURE__ */ React6.createElement(
|
|
2033
|
+
RefreshControl,
|
|
2034
|
+
{
|
|
2035
|
+
refreshing: !!refreshing,
|
|
2036
|
+
onRefresh,
|
|
2037
|
+
progressViewOffset
|
|
2038
|
+
}
|
|
2039
|
+
),
|
|
2040
|
+
style,
|
|
2041
|
+
contentContainerStyle
|
|
1479
2042
|
}
|
|
1480
|
-
);
|
|
2043
|
+
), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React6.createElement(DebugView, { state: refState.current }));
|
|
1481
2044
|
});
|
|
1482
2045
|
|
|
1483
2046
|
export { LegendList, useRecyclingEffect, useRecyclingState, useViewability, useViewabilityAmount };
|