@legendapp/list 2.0.0-next.10 → 2.0.0-next.12
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/.DS_Store +0 -0
- package/animated.d.mts +5 -2
- package/animated.d.ts +5 -2
- package/index.d.mts +55 -35
- package/index.d.ts +55 -35
- package/index.js +581 -222
- package/index.mjs +583 -224
- package/keyboard-controller.d.mts +20 -8
- package/keyboard-controller.d.ts +20 -8
- package/package.json +1 -1
- package/reanimated.d.mts +1 -1
- package/reanimated.d.ts +1 -1
package/index.mjs
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import * as React3 from 'react';
|
|
2
|
-
import React3__default, { useReducer, useEffect, createContext, useRef, useState, useMemo, useLayoutEffect, useCallback, useImperativeHandle,
|
|
3
|
-
import { View, Text, Platform, Animated,
|
|
2
|
+
import React3__default, { useReducer, useEffect, createContext, useRef, useState, useMemo, useLayoutEffect, useCallback, useImperativeHandle, forwardRef, memo, useContext } from 'react';
|
|
3
|
+
import { View, Text, Platform, Animated, StyleSheet, Dimensions, RefreshControl, unstable_batchedUpdates } from 'react-native';
|
|
4
4
|
import { useSyncExternalStore } from 'use-sync-external-store/shim';
|
|
5
5
|
|
|
6
6
|
// src/components/LazyLegendList.tsx
|
|
7
7
|
var ContextState = React3.createContext(null);
|
|
8
8
|
function StateProvider({ children }) {
|
|
9
9
|
const [value] = React3.useState(() => ({
|
|
10
|
+
animatedScrollY: new Animated.Value(0),
|
|
10
11
|
columnWrapperStyle: void 0,
|
|
11
12
|
listeners: /* @__PURE__ */ new Map(),
|
|
12
13
|
mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
|
|
@@ -164,18 +165,128 @@ var LeanViewComponent = React3.forwardRef((props, ref) => {
|
|
|
164
165
|
LeanViewComponent.displayName = "RCTView";
|
|
165
166
|
var LeanView = Platform.OS === "android" || Platform.OS === "ios" ? LeanViewComponent : View;
|
|
166
167
|
|
|
167
|
-
// src/components/Separator.tsx
|
|
168
|
-
function Separator({ ItemSeparatorComponent, itemKey, leadingItem }) {
|
|
169
|
-
const [lastItemKeys] = useArr$(["lastItemKeys"]);
|
|
170
|
-
const isALastItem = lastItemKeys.includes(itemKey);
|
|
171
|
-
return isALastItem ? null : /* @__PURE__ */ React.createElement(ItemSeparatorComponent, { leadingItem });
|
|
172
|
-
}
|
|
173
|
-
|
|
174
168
|
// src/constants.ts
|
|
175
169
|
var POSITION_OUT_OF_VIEW = -1e7;
|
|
176
170
|
var ENABLE_DEVMODE = __DEV__ && false;
|
|
177
171
|
var ENABLE_DEBUG_VIEW = __DEV__ && false;
|
|
178
172
|
var IsNewArchitecture = global.nativeFabricUIManager != null;
|
|
173
|
+
var useAnimatedValue = (initialValue) => {
|
|
174
|
+
return useRef(new Animated.Value(initialValue)).current;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// src/hooks/useValue$.ts
|
|
178
|
+
function useValue$(key, params) {
|
|
179
|
+
var _a;
|
|
180
|
+
const { getValue, delay } = params || {};
|
|
181
|
+
const ctx = useStateContext();
|
|
182
|
+
const animValue = useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
|
|
183
|
+
useMemo(() => {
|
|
184
|
+
let newValue;
|
|
185
|
+
let prevValue;
|
|
186
|
+
let didQueueTask = false;
|
|
187
|
+
listen$(ctx, key, (v) => {
|
|
188
|
+
newValue = getValue ? getValue(v) : v;
|
|
189
|
+
if (delay !== void 0) {
|
|
190
|
+
const fn = () => {
|
|
191
|
+
didQueueTask = false;
|
|
192
|
+
if (newValue !== void 0) {
|
|
193
|
+
animValue.setValue(newValue);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
const delayValue = typeof delay === "function" ? delay(newValue, prevValue) : delay;
|
|
197
|
+
prevValue = newValue;
|
|
198
|
+
if (!didQueueTask) {
|
|
199
|
+
didQueueTask = true;
|
|
200
|
+
if (delayValue === 0) {
|
|
201
|
+
queueMicrotask(fn);
|
|
202
|
+
} else {
|
|
203
|
+
setTimeout(fn, delayValue);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
} else {
|
|
207
|
+
animValue.setValue(newValue);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}, []);
|
|
211
|
+
return animValue;
|
|
212
|
+
}
|
|
213
|
+
var typedForwardRef = forwardRef;
|
|
214
|
+
var typedMemo = memo;
|
|
215
|
+
|
|
216
|
+
// src/components/PositionView.tsx
|
|
217
|
+
var PositionViewState = typedMemo(function PositionView({
|
|
218
|
+
id,
|
|
219
|
+
horizontal,
|
|
220
|
+
style,
|
|
221
|
+
refView,
|
|
222
|
+
...rest
|
|
223
|
+
}) {
|
|
224
|
+
const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
|
|
225
|
+
return /* @__PURE__ */ React3.createElement(
|
|
226
|
+
LeanView,
|
|
227
|
+
{
|
|
228
|
+
ref: refView,
|
|
229
|
+
style: [
|
|
230
|
+
style,
|
|
231
|
+
horizontal ? { transform: [{ translateX: position }] } : { transform: [{ translateY: position }] }
|
|
232
|
+
],
|
|
233
|
+
...rest
|
|
234
|
+
}
|
|
235
|
+
);
|
|
236
|
+
});
|
|
237
|
+
var PositionViewAnimated = typedMemo(function PositionView2({
|
|
238
|
+
id,
|
|
239
|
+
horizontal,
|
|
240
|
+
style,
|
|
241
|
+
refView,
|
|
242
|
+
...rest
|
|
243
|
+
}) {
|
|
244
|
+
const position$ = useValue$(`containerPosition${id}`, {
|
|
245
|
+
getValue: (v) => v != null ? v : POSITION_OUT_OF_VIEW
|
|
246
|
+
});
|
|
247
|
+
return /* @__PURE__ */ React3.createElement(
|
|
248
|
+
Animated.View,
|
|
249
|
+
{
|
|
250
|
+
ref: refView,
|
|
251
|
+
style: [
|
|
252
|
+
style,
|
|
253
|
+
horizontal ? { transform: [{ translateX: position$ }] } : { transform: [{ translateY: position$ }] }
|
|
254
|
+
],
|
|
255
|
+
...rest
|
|
256
|
+
}
|
|
257
|
+
);
|
|
258
|
+
});
|
|
259
|
+
var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
260
|
+
id,
|
|
261
|
+
horizontal,
|
|
262
|
+
style,
|
|
263
|
+
refView,
|
|
264
|
+
animatedScrollY,
|
|
265
|
+
stickyOffset,
|
|
266
|
+
index,
|
|
267
|
+
...rest
|
|
268
|
+
}) {
|
|
269
|
+
const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
|
|
270
|
+
const transform = React3.useMemo(() => {
|
|
271
|
+
if (animatedScrollY && stickyOffset) {
|
|
272
|
+
const stickyPosition = animatedScrollY.interpolate({
|
|
273
|
+
extrapolate: "clamp",
|
|
274
|
+
inputRange: [position, position + 5e3],
|
|
275
|
+
outputRange: [position, position + 5e3]
|
|
276
|
+
});
|
|
277
|
+
return horizontal ? [{ translateX: stickyPosition }] : [{ translateY: stickyPosition }];
|
|
278
|
+
}
|
|
279
|
+
}, [position, horizontal, animatedScrollY, stickyOffset]);
|
|
280
|
+
console.log("index", index, position, transform);
|
|
281
|
+
const viewStyle = React3.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
|
|
282
|
+
return /* @__PURE__ */ React3.createElement(Animated.View, { ref: refView, style: viewStyle, ...rest });
|
|
283
|
+
});
|
|
284
|
+
var PositionView3 = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
|
|
285
|
+
function Separator({ ItemSeparatorComponent, itemKey, leadingItem }) {
|
|
286
|
+
const [lastItemKeys] = useArr$(["lastItemKeys"]);
|
|
287
|
+
const isALastItem = lastItemKeys.includes(itemKey);
|
|
288
|
+
return isALastItem ? null : /* @__PURE__ */ React3.createElement(ItemSeparatorComponent, { leadingItem });
|
|
289
|
+
}
|
|
179
290
|
var symbolFirst = Symbol();
|
|
180
291
|
function useInit(cb) {
|
|
181
292
|
const refValue = useRef(symbolFirst);
|
|
@@ -312,8 +423,6 @@ function useListScrollSize() {
|
|
|
312
423
|
const [scrollSize] = useArr$(["scrollSize"]);
|
|
313
424
|
return scrollSize;
|
|
314
425
|
}
|
|
315
|
-
var typedForwardRef = forwardRef;
|
|
316
|
-
var typedMemo = memo;
|
|
317
426
|
|
|
318
427
|
// src/components/Container.tsx
|
|
319
428
|
var Container = typedMemo(function Container2({
|
|
@@ -325,14 +434,15 @@ var Container = typedMemo(function Container2({
|
|
|
325
434
|
ItemSeparatorComponent
|
|
326
435
|
}) {
|
|
327
436
|
const ctx = useStateContext();
|
|
328
|
-
const columnWrapperStyle = ctx
|
|
329
|
-
const [column = 0, data, itemKey,
|
|
437
|
+
const { columnWrapperStyle, animatedScrollY } = ctx;
|
|
438
|
+
const [column = 0, data, itemKey, numColumns, extraData, isSticky, stickyOffset] = useArr$([
|
|
330
439
|
`containerColumn${id}`,
|
|
331
440
|
`containerItemData${id}`,
|
|
332
441
|
`containerItemKey${id}`,
|
|
333
|
-
`containerPosition${id}`,
|
|
334
442
|
"numColumns",
|
|
335
|
-
"extraData"
|
|
443
|
+
"extraData",
|
|
444
|
+
`containerSticky${id}`,
|
|
445
|
+
`containerStickyOffset${id}`
|
|
336
446
|
]);
|
|
337
447
|
const refLastSize = useRef();
|
|
338
448
|
const ref = useRef(null);
|
|
@@ -340,36 +450,38 @@ var Container = typedMemo(function Container2({
|
|
|
340
450
|
const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
|
|
341
451
|
const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
|
|
342
452
|
let didLayout = false;
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
453
|
+
const style = useMemo(() => {
|
|
454
|
+
let paddingStyles;
|
|
455
|
+
if (columnWrapperStyle) {
|
|
456
|
+
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
457
|
+
if (horizontal) {
|
|
458
|
+
paddingStyles = {
|
|
459
|
+
paddingRight: columnGap || gap || void 0,
|
|
460
|
+
paddingVertical: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
|
|
461
|
+
};
|
|
462
|
+
} else {
|
|
463
|
+
paddingStyles = {
|
|
464
|
+
paddingBottom: rowGap || gap || void 0,
|
|
465
|
+
paddingHorizontal: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
|
|
466
|
+
};
|
|
467
|
+
}
|
|
356
468
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
};
|
|
469
|
+
return horizontal ? {
|
|
470
|
+
flexDirection: ItemSeparatorComponent ? "row" : void 0,
|
|
471
|
+
height: otherAxisSize,
|
|
472
|
+
left: 0,
|
|
473
|
+
position: "absolute",
|
|
474
|
+
top: otherAxisPos,
|
|
475
|
+
...paddingStyles || {}
|
|
476
|
+
} : {
|
|
477
|
+
left: otherAxisPos,
|
|
478
|
+
position: "absolute",
|
|
479
|
+
right: numColumns > 1 ? null : 0,
|
|
480
|
+
top: 0,
|
|
481
|
+
width: otherAxisSize,
|
|
482
|
+
...paddingStyles || {}
|
|
483
|
+
};
|
|
484
|
+
}, [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns]);
|
|
373
485
|
const renderedItemInfo = useMemo(
|
|
374
486
|
() => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
|
|
375
487
|
[itemKey, data, extraData]
|
|
@@ -434,55 +546,30 @@ var Container = typedMemo(function Container2({
|
|
|
434
546
|
}
|
|
435
547
|
}, [itemKey]);
|
|
436
548
|
}
|
|
437
|
-
|
|
438
|
-
|
|
549
|
+
const PositionComponent = isSticky ? PositionViewSticky : PositionView3;
|
|
550
|
+
return /* @__PURE__ */ React3.createElement(
|
|
551
|
+
PositionComponent,
|
|
439
552
|
{
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
useMemo(() => {
|
|
457
|
-
let newValue;
|
|
458
|
-
let prevValue;
|
|
459
|
-
let didQueueTask = false;
|
|
460
|
-
listen$(ctx, key, (v) => {
|
|
461
|
-
newValue = getValue ? getValue(v) : v;
|
|
462
|
-
if (delay !== void 0) {
|
|
463
|
-
const fn = () => {
|
|
464
|
-
didQueueTask = false;
|
|
465
|
-
if (newValue !== void 0) {
|
|
466
|
-
animValue.setValue(newValue);
|
|
467
|
-
}
|
|
468
|
-
};
|
|
469
|
-
const delayValue = typeof delay === "function" ? delay(newValue, prevValue) : delay;
|
|
470
|
-
prevValue = newValue;
|
|
471
|
-
if (!didQueueTask) {
|
|
472
|
-
didQueueTask = true;
|
|
473
|
-
if (delayValue === 0) {
|
|
474
|
-
queueMicrotask(fn);
|
|
475
|
-
} else {
|
|
476
|
-
setTimeout(fn, delayValue);
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
} else {
|
|
480
|
-
animValue.setValue(newValue);
|
|
553
|
+
animatedScrollY: isSticky ? animatedScrollY : void 0,
|
|
554
|
+
horizontal,
|
|
555
|
+
id,
|
|
556
|
+
index,
|
|
557
|
+
key: recycleItems ? void 0 : itemKey,
|
|
558
|
+
onLayout,
|
|
559
|
+
refView: ref,
|
|
560
|
+
stickyOffset: isSticky ? stickyOffset : void 0,
|
|
561
|
+
style
|
|
562
|
+
},
|
|
563
|
+
/* @__PURE__ */ React3.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React3.createElement(
|
|
564
|
+
Separator,
|
|
565
|
+
{
|
|
566
|
+
ItemSeparatorComponent,
|
|
567
|
+
itemKey,
|
|
568
|
+
leadingItem: renderedItemInfo.item
|
|
481
569
|
}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
}
|
|
570
|
+
))
|
|
571
|
+
);
|
|
572
|
+
});
|
|
486
573
|
|
|
487
574
|
// src/components/Containers.tsx
|
|
488
575
|
var Containers = typedMemo(function Containers2({
|
|
@@ -642,6 +729,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
642
729
|
scrollAdjustHandler,
|
|
643
730
|
onLayoutHeader,
|
|
644
731
|
snapToIndices,
|
|
732
|
+
stickyIndices,
|
|
645
733
|
...rest
|
|
646
734
|
}) {
|
|
647
735
|
const ctx = useStateContext();
|
|
@@ -651,7 +739,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
651
739
|
const ScrollComponent = renderScrollComponent ? useMemo(
|
|
652
740
|
() => React3.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
|
|
653
741
|
[renderScrollComponent]
|
|
654
|
-
) : ScrollView;
|
|
742
|
+
) : Animated.ScrollView;
|
|
655
743
|
React3.useEffect(() => {
|
|
656
744
|
if (canRender) {
|
|
657
745
|
setTimeout(() => {
|
|
@@ -704,9 +792,26 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
704
792
|
style: ListFooterComponentStyle
|
|
705
793
|
},
|
|
706
794
|
getComponent(ListFooterComponent)
|
|
707
|
-
)
|
|
795
|
+
),
|
|
796
|
+
__DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React3.createElement(DevNumbers, null)
|
|
708
797
|
);
|
|
709
798
|
});
|
|
799
|
+
var DevNumbers = __DEV__ && React3.memo(function DevNumbers2() {
|
|
800
|
+
return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React3.createElement(
|
|
801
|
+
View,
|
|
802
|
+
{
|
|
803
|
+
key: index,
|
|
804
|
+
style: {
|
|
805
|
+
height: 100,
|
|
806
|
+
pointerEvents: "none",
|
|
807
|
+
position: "absolute",
|
|
808
|
+
top: index * 100,
|
|
809
|
+
width: "100%"
|
|
810
|
+
}
|
|
811
|
+
},
|
|
812
|
+
/* @__PURE__ */ React3.createElement(Text, { style: { color: "red" } }, index * 100)
|
|
813
|
+
));
|
|
814
|
+
});
|
|
710
815
|
|
|
711
816
|
// src/utils/getId.ts
|
|
712
817
|
function getId(state, index) {
|
|
@@ -738,20 +843,36 @@ function calculateOffsetForIndex(ctx, state, index) {
|
|
|
738
843
|
}
|
|
739
844
|
|
|
740
845
|
// src/utils/getItemSize.ts
|
|
741
|
-
function getItemSize(state, key, index, data, useAverageSize) {
|
|
846
|
+
function getItemSize(state, key, index, data, useAverageSize, defaultAverageSize) {
|
|
847
|
+
var _a, _b;
|
|
742
848
|
const {
|
|
743
849
|
sizesKnown,
|
|
744
850
|
sizes,
|
|
745
851
|
scrollingTo,
|
|
746
|
-
|
|
852
|
+
averageSizes,
|
|
853
|
+
props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
|
|
747
854
|
} = state;
|
|
748
855
|
const sizeKnown = sizesKnown.get(key);
|
|
749
856
|
if (sizeKnown !== void 0) {
|
|
750
857
|
return sizeKnown;
|
|
751
858
|
}
|
|
752
859
|
let size;
|
|
753
|
-
|
|
754
|
-
|
|
860
|
+
const itemType = getItemType ? (_a = getItemType(data, index)) != null ? _a : "" : "";
|
|
861
|
+
if (getFixedItemSize) {
|
|
862
|
+
size = getFixedItemSize(index, data, itemType);
|
|
863
|
+
if (size !== void 0) {
|
|
864
|
+
sizesKnown.set(key, size);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
if (size === void 0 && useAverageSize && sizeKnown === void 0 && !scrollingTo) {
|
|
868
|
+
if (itemType === "") {
|
|
869
|
+
size = defaultAverageSize;
|
|
870
|
+
} else {
|
|
871
|
+
const averageSizeForType = (_b = averageSizes[itemType]) == null ? void 0 : _b.avg;
|
|
872
|
+
if (averageSizeForType !== void 0) {
|
|
873
|
+
size = roundSize(averageSizeForType);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
755
876
|
}
|
|
756
877
|
if (size === void 0) {
|
|
757
878
|
size = sizes.get(key);
|
|
@@ -760,7 +881,7 @@ function getItemSize(state, key, index, data, useAverageSize) {
|
|
|
760
881
|
}
|
|
761
882
|
}
|
|
762
883
|
if (size === void 0) {
|
|
763
|
-
size = getEstimatedItemSize ? getEstimatedItemSize(index, data) : estimatedItemSize;
|
|
884
|
+
size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
|
|
764
885
|
}
|
|
765
886
|
sizes.set(key, size);
|
|
766
887
|
return size;
|
|
@@ -779,6 +900,37 @@ function calculateOffsetWithOffsetPosition(state, offsetParam, params) {
|
|
|
779
900
|
return offset;
|
|
780
901
|
}
|
|
781
902
|
|
|
903
|
+
// src/core/finishScrollTo.ts
|
|
904
|
+
var finishScrollTo = (state) => {
|
|
905
|
+
if (state) {
|
|
906
|
+
state.scrollingTo = void 0;
|
|
907
|
+
state.scrollHistory.length = 0;
|
|
908
|
+
}
|
|
909
|
+
};
|
|
910
|
+
|
|
911
|
+
// src/core/scrollTo.ts
|
|
912
|
+
function scrollTo(state, params = {}) {
|
|
913
|
+
var _a;
|
|
914
|
+
const { animated } = params;
|
|
915
|
+
const {
|
|
916
|
+
refScroller,
|
|
917
|
+
props: { horizontal }
|
|
918
|
+
} = state;
|
|
919
|
+
const offset = calculateOffsetWithOffsetPosition(state, params.offset, params);
|
|
920
|
+
state.scrollHistory.length = 0;
|
|
921
|
+
state.scrollingTo = params;
|
|
922
|
+
state.scrollPending = offset;
|
|
923
|
+
(_a = refScroller.current) == null ? void 0 : _a.scrollTo({
|
|
924
|
+
animated: !!animated,
|
|
925
|
+
x: horizontal ? offset : 0,
|
|
926
|
+
y: horizontal ? 0 : offset
|
|
927
|
+
});
|
|
928
|
+
if (!animated) {
|
|
929
|
+
state.scroll = offset;
|
|
930
|
+
setTimeout(() => finishScrollTo(state), 100);
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
|
|
782
934
|
// src/utils/requestAdjust.ts
|
|
783
935
|
function requestAdjust(ctx, state, positionDiff) {
|
|
784
936
|
if (Math.abs(positionDiff) > 0.1) {
|
|
@@ -812,37 +964,63 @@ function requestAdjust(ctx, state, positionDiff) {
|
|
|
812
964
|
}
|
|
813
965
|
|
|
814
966
|
// src/core/prepareMVCP.ts
|
|
815
|
-
function prepareMVCP(ctx, state) {
|
|
967
|
+
function prepareMVCP(ctx, state, dataChanged) {
|
|
816
968
|
const {
|
|
969
|
+
idsInView,
|
|
817
970
|
positions,
|
|
818
971
|
scrollingTo,
|
|
819
972
|
props: { maintainVisibleContentPosition }
|
|
820
973
|
} = state;
|
|
821
974
|
let prevPosition;
|
|
822
975
|
let targetId;
|
|
823
|
-
|
|
976
|
+
const idsInViewWithPositions = [];
|
|
824
977
|
const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
|
|
825
978
|
if (maintainVisibleContentPosition) {
|
|
826
979
|
const indexByKey = state.indexByKey;
|
|
827
980
|
if (scrollTarget !== void 0) {
|
|
828
981
|
targetId = getId(state, scrollTarget);
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
982
|
+
} else if (idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
|
|
983
|
+
if (dataChanged) {
|
|
984
|
+
for (let i = 0; i < idsInView.length; i++) {
|
|
985
|
+
const id = idsInView[i];
|
|
986
|
+
const index = indexByKey.get(id);
|
|
987
|
+
if (index !== void 0) {
|
|
988
|
+
idsInViewWithPositions.push({ id, position: positions.get(id) });
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
} else {
|
|
992
|
+
targetId = state.idsInView.find((id) => indexByKey.get(id) !== void 0);
|
|
993
|
+
}
|
|
833
994
|
}
|
|
834
|
-
if (targetId !== void 0
|
|
995
|
+
if (targetId !== void 0) {
|
|
835
996
|
prevPosition = positions.get(targetId);
|
|
836
997
|
}
|
|
837
998
|
}
|
|
838
999
|
return () => {
|
|
1000
|
+
let positionDiff;
|
|
1001
|
+
if (targetId === void 0) {
|
|
1002
|
+
for (let i = 0; i < idsInViewWithPositions.length; i++) {
|
|
1003
|
+
const { id, position } = idsInViewWithPositions[i];
|
|
1004
|
+
const newPosition = positions.get(id);
|
|
1005
|
+
if (newPosition !== void 0) {
|
|
1006
|
+
positionDiff = newPosition - position;
|
|
1007
|
+
break;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
839
1011
|
if (targetId !== void 0 && prevPosition !== void 0) {
|
|
840
1012
|
const newPosition = positions.get(targetId);
|
|
841
1013
|
if (newPosition !== void 0) {
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
1014
|
+
positionDiff = newPosition - prevPosition;
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
|
|
1018
|
+
if (Platform.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff) {
|
|
1019
|
+
scrollTo(state, {
|
|
1020
|
+
offset: state.scroll + positionDiff
|
|
1021
|
+
});
|
|
1022
|
+
} else {
|
|
1023
|
+
requestAdjust(ctx, state, positionDiff);
|
|
846
1024
|
}
|
|
847
1025
|
}
|
|
848
1026
|
};
|
|
@@ -983,7 +1161,7 @@ function updateAllPositions(ctx, state, dataChanged) {
|
|
|
983
1161
|
firstFullyOnScreenIndex,
|
|
984
1162
|
idCache,
|
|
985
1163
|
sizesKnown,
|
|
986
|
-
props: { snapToIndices }
|
|
1164
|
+
props: { getEstimatedItemSize, snapToIndices }
|
|
987
1165
|
} = state;
|
|
988
1166
|
const data = state.props.data;
|
|
989
1167
|
const numColumns = peek$(ctx, "numColumns");
|
|
@@ -992,7 +1170,9 @@ function updateAllPositions(ctx, state, dataChanged) {
|
|
|
992
1170
|
if (dataChanged) {
|
|
993
1171
|
indexByKey.clear();
|
|
994
1172
|
idCache.clear();
|
|
1173
|
+
positions.clear();
|
|
995
1174
|
}
|
|
1175
|
+
const useAverageSize = !getEstimatedItemSize;
|
|
996
1176
|
const itemType = "";
|
|
997
1177
|
let averageSize = (_a = averageSizes[itemType]) == null ? void 0 : _a.avg;
|
|
998
1178
|
if (averageSize !== void 0) {
|
|
@@ -1008,7 +1188,7 @@ function updateAllPositions(ctx, state, dataChanged) {
|
|
|
1008
1188
|
let bailout = false;
|
|
1009
1189
|
for (let i = firstFullyOnScreenIndex - 1; i >= 0; i--) {
|
|
1010
1190
|
const id = (_b = idCache.get(i)) != null ? _b : getId(state, i);
|
|
1011
|
-
const size = (_c = sizesKnown.get(id)) != null ? _c : getItemSize(state, id, i, data[i], averageSize);
|
|
1191
|
+
const size = (_c = sizesKnown.get(id)) != null ? _c : getItemSize(state, id, i, data[i], useAverageSize, averageSize);
|
|
1012
1192
|
const itemColumn = columns.get(id);
|
|
1013
1193
|
maxSizeInRow2 = Math.max(maxSizeInRow2, size);
|
|
1014
1194
|
if (itemColumn === 1) {
|
|
@@ -1035,7 +1215,7 @@ function updateAllPositions(ctx, state, dataChanged) {
|
|
|
1035
1215
|
const dataLength = data.length;
|
|
1036
1216
|
for (let i = 0; i < dataLength; i++) {
|
|
1037
1217
|
const id = (_d = idCache.get(i)) != null ? _d : getId(state, i);
|
|
1038
|
-
const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(state, id, i, data[i], averageSize);
|
|
1218
|
+
const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(state, id, i, data[i], useAverageSize, averageSize);
|
|
1039
1219
|
if (__DEV__ && needsIndexByKey) {
|
|
1040
1220
|
if (indexByKeyForChecking.has(id)) {
|
|
1041
1221
|
console.error(
|
|
@@ -1274,35 +1454,84 @@ function checkAllSizesKnown(state) {
|
|
|
1274
1454
|
}
|
|
1275
1455
|
|
|
1276
1456
|
// src/utils/findAvailableContainers.ts
|
|
1277
|
-
function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval) {
|
|
1457
|
+
function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
|
|
1278
1458
|
const numContainers = peek$(ctx, "numContainers");
|
|
1459
|
+
const { stickyIndicesSet } = state.props;
|
|
1279
1460
|
const result = [];
|
|
1280
1461
|
const availableContainers = [];
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
if (!
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1462
|
+
const stickyItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => stickyIndicesSet.has(index))) || [];
|
|
1463
|
+
const nonStickyItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => !stickyIndicesSet.has(index))) || [];
|
|
1464
|
+
const canReuseContainer = (containerIndex, requiredType) => {
|
|
1465
|
+
if (!requiredType) return true;
|
|
1466
|
+
const existingType = state.containerItemTypes.get(containerIndex);
|
|
1467
|
+
if (!existingType) return true;
|
|
1468
|
+
return existingType === requiredType;
|
|
1469
|
+
};
|
|
1470
|
+
const neededTypes = requiredItemTypes ? [...requiredItemTypes] : [];
|
|
1471
|
+
let typeIndex = 0;
|
|
1472
|
+
for (let i = 0; i < stickyItemIndices.length; i++) {
|
|
1473
|
+
const requiredType = neededTypes[typeIndex];
|
|
1474
|
+
let foundContainer = false;
|
|
1475
|
+
for (const containerIndex of state.stickyContainerPool) {
|
|
1476
|
+
const key = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1477
|
+
const isPendingRemoval = pendingRemoval.includes(containerIndex);
|
|
1478
|
+
if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType)) {
|
|
1479
|
+
result.push(containerIndex);
|
|
1480
|
+
if (isPendingRemoval) {
|
|
1481
|
+
const index = pendingRemoval.indexOf(containerIndex);
|
|
1482
|
+
pendingRemoval.splice(index, 1);
|
|
1483
|
+
}
|
|
1484
|
+
foundContainer = true;
|
|
1485
|
+
if (requiredItemTypes) typeIndex++;
|
|
1486
|
+
break;
|
|
1289
1487
|
}
|
|
1290
1488
|
}
|
|
1291
|
-
if (
|
|
1292
|
-
result.
|
|
1293
|
-
|
|
1294
|
-
|
|
1489
|
+
if (!foundContainer) {
|
|
1490
|
+
const newContainerIndex = numContainers + result.filter((index) => index >= numContainers).length;
|
|
1491
|
+
result.push(newContainerIndex);
|
|
1492
|
+
state.stickyContainerPool.add(newContainerIndex);
|
|
1493
|
+
if (requiredItemTypes) typeIndex++;
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
if (nonStickyItemIndices.length > 0) {
|
|
1497
|
+
for (let u = 0; u < numContainers; u++) {
|
|
1498
|
+
if (state.stickyContainerPool.has(u)) {
|
|
1499
|
+
continue;
|
|
1500
|
+
}
|
|
1501
|
+
const key = peek$(ctx, `containerItemKey${u}`);
|
|
1502
|
+
let isOk = key === void 0;
|
|
1503
|
+
if (!isOk) {
|
|
1504
|
+
const index = pendingRemoval.indexOf(u);
|
|
1505
|
+
if (index !== -1) {
|
|
1506
|
+
pendingRemoval.splice(index, 1);
|
|
1507
|
+
const requiredType = neededTypes[typeIndex];
|
|
1508
|
+
isOk = canReuseContainer(u, requiredType);
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
if (isOk) {
|
|
1512
|
+
result.push(u);
|
|
1513
|
+
if (requiredItemTypes) {
|
|
1514
|
+
typeIndex++;
|
|
1515
|
+
}
|
|
1516
|
+
if (result.length >= numNeeded) {
|
|
1517
|
+
return result;
|
|
1518
|
+
}
|
|
1295
1519
|
}
|
|
1296
1520
|
}
|
|
1297
1521
|
}
|
|
1298
1522
|
for (let u = 0; u < numContainers; u++) {
|
|
1523
|
+
if (state.stickyContainerPool.has(u)) {
|
|
1524
|
+
continue;
|
|
1525
|
+
}
|
|
1299
1526
|
const key = peek$(ctx, `containerItemKey${u}`);
|
|
1300
1527
|
if (key === void 0) continue;
|
|
1301
1528
|
const index = state.indexByKey.get(key);
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1529
|
+
const isOutOfView = index < startBuffered || index > endBuffered;
|
|
1530
|
+
if (isOutOfView) {
|
|
1531
|
+
const distance = index < startBuffered ? startBuffered - index : index - endBuffered;
|
|
1532
|
+
if (!requiredItemTypes || typeIndex < neededTypes.length && canReuseContainer(u, neededTypes[typeIndex])) {
|
|
1533
|
+
availableContainers.push({ distance, index: u });
|
|
1534
|
+
}
|
|
1306
1535
|
}
|
|
1307
1536
|
}
|
|
1308
1537
|
const remaining = numNeeded - result.length;
|
|
@@ -1314,6 +1543,9 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1314
1543
|
}
|
|
1315
1544
|
for (const container of availableContainers) {
|
|
1316
1545
|
result.push(container.index);
|
|
1546
|
+
if (requiredItemTypes) {
|
|
1547
|
+
typeIndex++;
|
|
1548
|
+
}
|
|
1317
1549
|
}
|
|
1318
1550
|
}
|
|
1319
1551
|
const stillNeeded = numNeeded - result.length;
|
|
@@ -1342,37 +1574,6 @@ function comparatorByDistance(a, b) {
|
|
|
1342
1574
|
return b.distance - a.distance;
|
|
1343
1575
|
}
|
|
1344
1576
|
|
|
1345
|
-
// src/core/finishScrollTo.ts
|
|
1346
|
-
var finishScrollTo = (state) => {
|
|
1347
|
-
if (state) {
|
|
1348
|
-
state.scrollingTo = void 0;
|
|
1349
|
-
state.scrollHistory.length = 0;
|
|
1350
|
-
}
|
|
1351
|
-
};
|
|
1352
|
-
|
|
1353
|
-
// src/core/scrollTo.ts
|
|
1354
|
-
function scrollTo(state, params = {}) {
|
|
1355
|
-
var _a;
|
|
1356
|
-
const { animated } = params;
|
|
1357
|
-
const {
|
|
1358
|
-
refScroller,
|
|
1359
|
-
props: { horizontal }
|
|
1360
|
-
} = state;
|
|
1361
|
-
const offset = calculateOffsetWithOffsetPosition(state, params.offset, params);
|
|
1362
|
-
state.scrollHistory.length = 0;
|
|
1363
|
-
state.scrollingTo = params;
|
|
1364
|
-
state.scrollPending = offset;
|
|
1365
|
-
(_a = refScroller.current) == null ? void 0 : _a.scrollTo({
|
|
1366
|
-
animated: !!animated,
|
|
1367
|
-
x: horizontal ? offset : 0,
|
|
1368
|
-
y: horizontal ? 0 : offset
|
|
1369
|
-
});
|
|
1370
|
-
if (!animated) {
|
|
1371
|
-
state.scroll = offset;
|
|
1372
|
-
setTimeout(() => finishScrollTo(state), 100);
|
|
1373
|
-
}
|
|
1374
|
-
}
|
|
1375
|
-
|
|
1376
1577
|
// src/core/scrollToIndex.ts
|
|
1377
1578
|
function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
|
|
1378
1579
|
if (index >= state.props.data.length) {
|
|
@@ -1460,16 +1661,90 @@ function setDidLayout(ctx, state) {
|
|
|
1460
1661
|
} = state;
|
|
1461
1662
|
state.queuedInitialLayout = true;
|
|
1462
1663
|
checkAtBottom(ctx, state);
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1664
|
+
const setIt = () => {
|
|
1665
|
+
set$(ctx, "containersDidLayout", true);
|
|
1666
|
+
if (onLoad) {
|
|
1667
|
+
onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
|
|
1668
|
+
}
|
|
1669
|
+
};
|
|
1670
|
+
if (Platform.OS === "android" || !IsNewArchitecture) {
|
|
1671
|
+
if (initialScroll) {
|
|
1672
|
+
queueMicrotask(() => {
|
|
1673
|
+
scrollToIndex(ctx, state, { ...initialScroll, animated: false });
|
|
1674
|
+
requestAnimationFrame(() => {
|
|
1675
|
+
scrollToIndex(ctx, state, { ...initialScroll, animated: false });
|
|
1676
|
+
setIt();
|
|
1677
|
+
});
|
|
1678
|
+
});
|
|
1679
|
+
} else {
|
|
1680
|
+
queueMicrotask(setIt);
|
|
1681
|
+
}
|
|
1682
|
+
} else {
|
|
1683
|
+
setIt();
|
|
1469
1684
|
}
|
|
1470
1685
|
}
|
|
1471
1686
|
|
|
1472
1687
|
// src/core/calculateItemsInView.ts
|
|
1688
|
+
function findCurrentStickyIndex(stickyArray, scroll, state) {
|
|
1689
|
+
var _a;
|
|
1690
|
+
for (let i = stickyArray.length - 1; i >= 0; i--) {
|
|
1691
|
+
const stickyId = (_a = state.idCache.get(stickyArray[i])) != null ? _a : getId(state, stickyArray[i]);
|
|
1692
|
+
const stickyPos = stickyId ? state.positions.get(stickyId) : void 0;
|
|
1693
|
+
if (stickyPos !== void 0 && scroll >= stickyPos) {
|
|
1694
|
+
return i;
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
return -1;
|
|
1698
|
+
}
|
|
1699
|
+
function getActiveStickyIndices(ctx, state, stickyIndices) {
|
|
1700
|
+
return new Set(
|
|
1701
|
+
Array.from(state.stickyContainerPool).map((i) => peek$(ctx, `containerItemKey${i}`)).map((key) => key ? state.indexByKey.get(key) : void 0).filter((idx) => idx !== void 0 && stickyIndices.has(idx))
|
|
1702
|
+
);
|
|
1703
|
+
}
|
|
1704
|
+
function handleStickyActivation(ctx, state, stickyIndices, stickyArray, scroll, needNewContainers, startBuffered, endBuffered) {
|
|
1705
|
+
var _a;
|
|
1706
|
+
const activeIndices = getActiveStickyIndices(ctx, state, stickyIndices);
|
|
1707
|
+
const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
|
|
1708
|
+
for (let offset = 0; offset <= 1; offset++) {
|
|
1709
|
+
const idx = currentStickyIdx - offset;
|
|
1710
|
+
if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
|
|
1711
|
+
const stickyIndex = stickyArray[idx];
|
|
1712
|
+
const stickyId = (_a = state.idCache.get(stickyIndex)) != null ? _a : getId(state, stickyIndex);
|
|
1713
|
+
if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered)) {
|
|
1714
|
+
needNewContainers.push(stickyIndex);
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, pendingRemoval) {
|
|
1719
|
+
var _a, _b, _c;
|
|
1720
|
+
const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
|
|
1721
|
+
for (const containerIndex of state.stickyContainerPool) {
|
|
1722
|
+
const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1723
|
+
const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
|
|
1724
|
+
if (itemIndex === void 0) continue;
|
|
1725
|
+
const arrayIdx = stickyArray.indexOf(itemIndex);
|
|
1726
|
+
if (arrayIdx === -1) continue;
|
|
1727
|
+
const isRecentSticky = arrayIdx >= currentStickyIdx - 1 && arrayIdx <= currentStickyIdx + 1;
|
|
1728
|
+
if (isRecentSticky) continue;
|
|
1729
|
+
const nextIndex = stickyArray[arrayIdx + 1];
|
|
1730
|
+
let shouldRecycle = false;
|
|
1731
|
+
if (nextIndex) {
|
|
1732
|
+
const nextId = (_a = state.idCache.get(nextIndex)) != null ? _a : getId(state, nextIndex);
|
|
1733
|
+
const nextPos = nextId ? state.positions.get(nextId) : void 0;
|
|
1734
|
+
shouldRecycle = nextPos !== void 0 && scroll > nextPos + scrollBuffer * 2;
|
|
1735
|
+
} else {
|
|
1736
|
+
const currentId = (_b = state.idCache.get(itemIndex)) != null ? _b : getId(state, itemIndex);
|
|
1737
|
+
if (currentId) {
|
|
1738
|
+
const currentPos = state.positions.get(currentId);
|
|
1739
|
+
const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(state, currentId, itemIndex, state.props.data[itemIndex]);
|
|
1740
|
+
shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
if (shouldRecycle) {
|
|
1744
|
+
pendingRemoval.push(containerIndex);
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1473
1748
|
function calculateItemsInView(ctx, state, params = {}) {
|
|
1474
1749
|
unstable_batchedUpdates(() => {
|
|
1475
1750
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
@@ -1486,7 +1761,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1486
1761
|
enableScrollForNextCalculateItemsInView,
|
|
1487
1762
|
minIndexSizeChanged
|
|
1488
1763
|
} = state;
|
|
1489
|
-
const data = state.props
|
|
1764
|
+
const { data, stickyIndicesArr, stickyIndicesSet } = state.props;
|
|
1490
1765
|
const prevNumContainers = peek$(ctx, "numContainers");
|
|
1491
1766
|
if (!data || scrollLength === 0 || !prevNumContainers) {
|
|
1492
1767
|
return;
|
|
@@ -1498,7 +1773,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1498
1773
|
const { dataChanged, doMVCP } = params;
|
|
1499
1774
|
const speed = getScrollVelocity(state);
|
|
1500
1775
|
if (doMVCP || dataChanged) {
|
|
1501
|
-
const checkMVCP = doMVCP ? prepareMVCP(ctx, state) : void 0;
|
|
1776
|
+
const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
|
|
1502
1777
|
updateAllPositions(ctx, state, dataChanged);
|
|
1503
1778
|
checkMVCP == null ? void 0 : checkMVCP();
|
|
1504
1779
|
}
|
|
@@ -1648,14 +1923,23 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1648
1923
|
needNewContainers.push(i);
|
|
1649
1924
|
}
|
|
1650
1925
|
}
|
|
1926
|
+
if (stickyIndicesArr.length > 0) {
|
|
1927
|
+
handleStickyActivation(ctx, state, stickyIndicesSet, stickyIndicesArr, scroll, needNewContainers, startBuffered, endBuffered);
|
|
1928
|
+
}
|
|
1651
1929
|
if (needNewContainers.length > 0) {
|
|
1930
|
+
const requiredItemTypes = state.props.getItemType ? needNewContainers.map((i) => {
|
|
1931
|
+
const itemType = state.props.getItemType(data[i], i);
|
|
1932
|
+
return itemType ? String(itemType) : "";
|
|
1933
|
+
}) : void 0;
|
|
1652
1934
|
const availableContainers = findAvailableContainers(
|
|
1653
1935
|
ctx,
|
|
1654
1936
|
state,
|
|
1655
1937
|
needNewContainers.length,
|
|
1656
1938
|
startBuffered,
|
|
1657
1939
|
endBuffered,
|
|
1658
|
-
pendingRemoval
|
|
1940
|
+
pendingRemoval,
|
|
1941
|
+
requiredItemTypes,
|
|
1942
|
+
needNewContainers
|
|
1659
1943
|
);
|
|
1660
1944
|
for (let idx = 0; idx < needNewContainers.length; idx++) {
|
|
1661
1945
|
const i = needNewContainers[idx];
|
|
@@ -1667,7 +1951,18 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1667
1951
|
}
|
|
1668
1952
|
set$(ctx, `containerItemKey${containerIndex}`, id);
|
|
1669
1953
|
set$(ctx, `containerItemData${containerIndex}`, data[i]);
|
|
1954
|
+
if (requiredItemTypes) {
|
|
1955
|
+
state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
|
|
1956
|
+
}
|
|
1670
1957
|
containerItemKeys.add(id);
|
|
1958
|
+
if (stickyIndicesSet.has(i)) {
|
|
1959
|
+
set$(ctx, `containerSticky${containerIndex}`, true);
|
|
1960
|
+
const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
1961
|
+
set$(ctx, `containerStickyOffset${containerIndex}`, new Animated.Value(topPadding));
|
|
1962
|
+
state.stickyContainerPool.add(containerIndex);
|
|
1963
|
+
} else {
|
|
1964
|
+
state.stickyContainerPool.delete(containerIndex);
|
|
1965
|
+
}
|
|
1671
1966
|
if (containerIndex >= numContainers2) {
|
|
1672
1967
|
numContainers2 = containerIndex + 1;
|
|
1673
1968
|
}
|
|
@@ -1680,12 +1975,21 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1680
1975
|
}
|
|
1681
1976
|
}
|
|
1682
1977
|
}
|
|
1978
|
+
if (stickyIndicesArr.length > 0) {
|
|
1979
|
+
handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, pendingRemoval);
|
|
1980
|
+
}
|
|
1683
1981
|
for (let i = 0; i < numContainers; i++) {
|
|
1684
1982
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1685
1983
|
if (pendingRemoval.includes(i)) {
|
|
1686
1984
|
if (itemKey) {
|
|
1687
1985
|
containerItemKeys.delete(itemKey);
|
|
1688
1986
|
}
|
|
1987
|
+
state.containerItemTypes.delete(i);
|
|
1988
|
+
if (state.stickyContainerPool.has(i)) {
|
|
1989
|
+
set$(ctx, `containerSticky${i}`, false);
|
|
1990
|
+
set$(ctx, `containerStickyOffset${i}`, void 0);
|
|
1991
|
+
state.stickyContainerPool.delete(i);
|
|
1992
|
+
}
|
|
1689
1993
|
set$(ctx, `containerItemKey${i}`, void 0);
|
|
1690
1994
|
set$(ctx, `containerItemData${i}`, void 0);
|
|
1691
1995
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
@@ -1736,10 +2040,14 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1736
2040
|
|
|
1737
2041
|
// src/core/doInitialAllocateContainers.ts
|
|
1738
2042
|
function doInitialAllocateContainers(ctx, state) {
|
|
1739
|
-
|
|
2043
|
+
var _a;
|
|
2044
|
+
const {
|
|
2045
|
+
scrollLength,
|
|
2046
|
+
props: { getItemType }
|
|
2047
|
+
} = state;
|
|
1740
2048
|
const data = state.props.data;
|
|
1741
2049
|
if (scrollLength > 0 && data.length > 0 && !peek$(ctx, "numContainers")) {
|
|
1742
|
-
const averageItemSize = state.props.getEstimatedItemSize ? state.props.getEstimatedItemSize(0, data[0]) : state.props.estimatedItemSize;
|
|
2050
|
+
const averageItemSize = state.props.getEstimatedItemSize ? state.props.getEstimatedItemSize(0, data[0], getItemType ? (_a = getItemType(data[0], 0)) != null ? _a : "" : "") : state.props.estimatedItemSize;
|
|
1743
2051
|
const Extra = 1.5;
|
|
1744
2052
|
const numContainers = Math.ceil(
|
|
1745
2053
|
(scrollLength + state.props.scrollBuffer * 2) / averageItemSize * state.props.numColumns * Extra
|
|
@@ -1776,16 +2084,18 @@ function doMaintainScrollAtEnd(ctx, state, animated) {
|
|
|
1776
2084
|
}
|
|
1777
2085
|
requestAnimationFrame(() => {
|
|
1778
2086
|
var _a;
|
|
1779
|
-
state.
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
(
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
2087
|
+
if (state == null ? void 0 : state.isAtEnd) {
|
|
2088
|
+
state.maintainingScrollAtEnd = true;
|
|
2089
|
+
(_a = refScroller.current) == null ? void 0 : _a.scrollToEnd({
|
|
2090
|
+
animated
|
|
2091
|
+
});
|
|
2092
|
+
setTimeout(
|
|
2093
|
+
() => {
|
|
2094
|
+
state.maintainingScrollAtEnd = false;
|
|
2095
|
+
},
|
|
2096
|
+
0
|
|
2097
|
+
);
|
|
2098
|
+
}
|
|
1789
2099
|
});
|
|
1790
2100
|
return true;
|
|
1791
2101
|
}
|
|
@@ -2005,7 +2315,22 @@ function updateItemSizes(ctx, state, itemUpdates) {
|
|
|
2005
2315
|
}
|
|
2006
2316
|
}
|
|
2007
2317
|
function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
2008
|
-
|
|
2318
|
+
var _a;
|
|
2319
|
+
const {
|
|
2320
|
+
queuedItemSizeUpdates,
|
|
2321
|
+
queuedItemSizeUpdatesWaiting,
|
|
2322
|
+
sizesKnown,
|
|
2323
|
+
props: { getFixedItemSize, getItemType }
|
|
2324
|
+
} = state;
|
|
2325
|
+
if (getFixedItemSize) {
|
|
2326
|
+
const index = state.indexByKey.get(itemKey);
|
|
2327
|
+
const itemData = state.props.data[index];
|
|
2328
|
+
const type = getItemType ? (_a = getItemType(itemData, index)) != null ? _a : "" : "";
|
|
2329
|
+
const size = getFixedItemSize(index, itemData, type);
|
|
2330
|
+
if (size !== void 0 && size === sizesKnown.get(itemKey)) {
|
|
2331
|
+
return;
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2009
2334
|
const containersDidLayout = peek$(ctx, "containersDidLayout");
|
|
2010
2335
|
if (!containersDidLayout || !queuedItemSizeUpdatesWaiting) {
|
|
2011
2336
|
updateItemSizes(ctx, state, [{ itemKey, sizeObj }]);
|
|
@@ -2022,25 +2347,28 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
2022
2347
|
}
|
|
2023
2348
|
}
|
|
2024
2349
|
function updateOneItemSize(state, itemKey, sizeObj) {
|
|
2350
|
+
var _a;
|
|
2025
2351
|
const {
|
|
2026
2352
|
sizes,
|
|
2027
2353
|
indexByKey,
|
|
2028
2354
|
sizesKnown,
|
|
2029
2355
|
averageSizes,
|
|
2030
|
-
props: { data, horizontal }
|
|
2356
|
+
props: { data, horizontal, getEstimatedItemSize, getItemType }
|
|
2031
2357
|
} = state;
|
|
2032
2358
|
if (!data) return 0;
|
|
2033
2359
|
const index = indexByKey.get(itemKey);
|
|
2034
2360
|
const prevSize = getItemSize(state, itemKey, index, data);
|
|
2035
2361
|
const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
|
|
2036
2362
|
sizesKnown.set(itemKey, size);
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
averages
|
|
2363
|
+
if (!getEstimatedItemSize) {
|
|
2364
|
+
const itemType = getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : "";
|
|
2365
|
+
let averages = averageSizes[itemType];
|
|
2366
|
+
if (!averages) {
|
|
2367
|
+
averages = averageSizes[itemType] = { avg: 0, num: 0 };
|
|
2368
|
+
}
|
|
2369
|
+
averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
|
|
2370
|
+
averages.num++;
|
|
2041
2371
|
}
|
|
2042
|
-
averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
|
|
2043
|
-
averages.num++;
|
|
2044
2372
|
if (!prevSize || Math.abs(prevSize - size) > 0.1) {
|
|
2045
2373
|
sizes.set(itemKey, size);
|
|
2046
2374
|
return size - prevSize;
|
|
@@ -2078,12 +2406,13 @@ function createColumnWrapperStyle(contentContainerStyle) {
|
|
|
2078
2406
|
}
|
|
2079
2407
|
}
|
|
2080
2408
|
function getRenderedItem(ctx, state, key) {
|
|
2409
|
+
var _a;
|
|
2081
2410
|
if (!state) {
|
|
2082
2411
|
return null;
|
|
2083
2412
|
}
|
|
2084
2413
|
const {
|
|
2085
2414
|
indexByKey,
|
|
2086
|
-
props: { data, renderItem: renderItem2 }
|
|
2415
|
+
props: { data, getItemType, renderItem: renderItem2 }
|
|
2087
2416
|
} = state;
|
|
2088
2417
|
const index = indexByKey.get(key);
|
|
2089
2418
|
if (index === void 0) {
|
|
@@ -2094,7 +2423,8 @@ function getRenderedItem(ctx, state, key) {
|
|
|
2094
2423
|
const itemProps = {
|
|
2095
2424
|
extraData: peek$(ctx, "extraData"),
|
|
2096
2425
|
index,
|
|
2097
|
-
item: data[index]
|
|
2426
|
+
item: data[index],
|
|
2427
|
+
type: getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : ""
|
|
2098
2428
|
};
|
|
2099
2429
|
renderedItem = React3__default.createElement(renderItem2, itemProps);
|
|
2100
2430
|
}
|
|
@@ -2110,49 +2440,52 @@ var LegendList = typedForwardRef(function LegendList2(props, forwardedRef) {
|
|
|
2110
2440
|
var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
|
|
2111
2441
|
var _a;
|
|
2112
2442
|
const {
|
|
2443
|
+
alignItemsAtEnd = false,
|
|
2444
|
+
columnWrapperStyle,
|
|
2445
|
+
contentContainerStyle: contentContainerStyleProp,
|
|
2113
2446
|
data: dataProp = [],
|
|
2447
|
+
drawDistance = 250,
|
|
2448
|
+
estimatedItemSize: estimatedItemSizeProp,
|
|
2449
|
+
estimatedListSize,
|
|
2450
|
+
extraData,
|
|
2451
|
+
getEstimatedItemSize,
|
|
2452
|
+
getFixedItemSize,
|
|
2453
|
+
getItemType,
|
|
2454
|
+
horizontal,
|
|
2455
|
+
initialContainerPoolRatio = 2,
|
|
2114
2456
|
initialScrollIndex: initialScrollIndexProp,
|
|
2115
2457
|
initialScrollOffset,
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
onEndReachedThreshold = 0.5,
|
|
2120
|
-
onStartReachedThreshold = 0.5,
|
|
2458
|
+
keyExtractor: keyExtractorProp,
|
|
2459
|
+
ListEmptyComponent,
|
|
2460
|
+
ListHeaderComponent,
|
|
2121
2461
|
maintainScrollAtEnd = false,
|
|
2122
2462
|
maintainScrollAtEndThreshold = 0.1,
|
|
2123
|
-
alignItemsAtEnd = false,
|
|
2124
2463
|
maintainVisibleContentPosition = false,
|
|
2125
|
-
onScroll: onScrollProp,
|
|
2126
|
-
onMomentumScrollEnd,
|
|
2127
2464
|
numColumns: numColumnsProp = 1,
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
renderItem: renderItem2,
|
|
2131
|
-
estimatedListSize,
|
|
2132
|
-
estimatedItemSize: estimatedItemSizeProp,
|
|
2133
|
-
getEstimatedItemSize,
|
|
2134
|
-
suggestEstimatedItemSize,
|
|
2135
|
-
ListHeaderComponent,
|
|
2136
|
-
ListEmptyComponent,
|
|
2465
|
+
onEndReached,
|
|
2466
|
+
onEndReachedThreshold = 0.5,
|
|
2137
2467
|
onItemSizeChanged,
|
|
2138
|
-
refScrollView,
|
|
2139
|
-
waitForInitialLayout = true,
|
|
2140
|
-
extraData,
|
|
2141
|
-
contentContainerStyle: contentContainerStyleProp,
|
|
2142
|
-
style: styleProp,
|
|
2143
2468
|
onLayout: onLayoutProp,
|
|
2469
|
+
onLoad,
|
|
2470
|
+
onMomentumScrollEnd,
|
|
2144
2471
|
onRefresh,
|
|
2145
|
-
|
|
2472
|
+
onScroll: onScrollProp,
|
|
2473
|
+
onStartReached,
|
|
2474
|
+
onStartReachedThreshold = 0.5,
|
|
2475
|
+
onViewableItemsChanged,
|
|
2146
2476
|
progressViewOffset,
|
|
2477
|
+
recycleItems = false,
|
|
2147
2478
|
refreshControl,
|
|
2148
|
-
|
|
2479
|
+
refreshing,
|
|
2480
|
+
refScrollView,
|
|
2481
|
+
renderItem: renderItem2,
|
|
2482
|
+
snapToIndices,
|
|
2483
|
+
stickyIndices,
|
|
2484
|
+
style: styleProp,
|
|
2485
|
+
suggestEstimatedItemSize,
|
|
2149
2486
|
viewabilityConfig,
|
|
2150
2487
|
viewabilityConfigCallbackPairs,
|
|
2151
|
-
|
|
2152
|
-
onViewableItemsChanged,
|
|
2153
|
-
onStartReached,
|
|
2154
|
-
onEndReached,
|
|
2155
|
-
onLoad,
|
|
2488
|
+
waitForInitialLayout = true,
|
|
2156
2489
|
...rest
|
|
2157
2490
|
} = props;
|
|
2158
2491
|
const [renderNum, setRenderNum] = useState(0);
|
|
@@ -2174,9 +2507,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2174
2507
|
if (!refState.current) {
|
|
2175
2508
|
const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { height: 0, width: 0 } : Dimensions.get("window"))[horizontal ? "width" : "height"];
|
|
2176
2509
|
refState.current = {
|
|
2510
|
+
activeStickyIndex: void 0,
|
|
2177
2511
|
averageSizes: {},
|
|
2178
2512
|
columns: /* @__PURE__ */ new Map(),
|
|
2179
2513
|
containerItemKeys: /* @__PURE__ */ new Set(),
|
|
2514
|
+
containerItemTypes: /* @__PURE__ */ new Map(),
|
|
2180
2515
|
enableScrollForNextCalculateItemsInView: true,
|
|
2181
2516
|
endBuffered: -1,
|
|
2182
2517
|
endNoBuffer: -1,
|
|
@@ -2215,6 +2550,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2215
2550
|
startBuffered: -1,
|
|
2216
2551
|
startNoBuffer: -1,
|
|
2217
2552
|
startReachedBlockedByTimer: false,
|
|
2553
|
+
stickyContainerPool: /* @__PURE__ */ new Set(),
|
|
2554
|
+
stickyContainers: /* @__PURE__ */ new Map(),
|
|
2218
2555
|
timeoutSizeMessage: 0,
|
|
2219
2556
|
timeouts: /* @__PURE__ */ new Set(),
|
|
2220
2557
|
totalSize: 0,
|
|
@@ -2231,6 +2568,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2231
2568
|
data: dataProp,
|
|
2232
2569
|
estimatedItemSize,
|
|
2233
2570
|
getEstimatedItemSize,
|
|
2571
|
+
getFixedItemSize,
|
|
2572
|
+
getItemType,
|
|
2234
2573
|
horizontal: !!horizontal,
|
|
2235
2574
|
initialContainerPoolRatio,
|
|
2236
2575
|
initialScroll,
|
|
@@ -2246,9 +2585,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2246
2585
|
onScroll: onScrollProp,
|
|
2247
2586
|
onStartReached,
|
|
2248
2587
|
onStartReachedThreshold,
|
|
2588
|
+
recycleItems: !!recycleItems,
|
|
2249
2589
|
renderItem: renderItem2,
|
|
2250
2590
|
scrollBuffer,
|
|
2251
2591
|
snapToIndices,
|
|
2592
|
+
stickyIndicesArr: stickyIndices != null ? stickyIndices : [],
|
|
2593
|
+
stickyIndicesSet: useMemo(() => new Set(stickyIndices), [stickyIndices]),
|
|
2252
2594
|
stylePaddingBottom: stylePaddingBottomState,
|
|
2253
2595
|
stylePaddingTop: stylePaddingTopState,
|
|
2254
2596
|
suggestEstimatedItemSize: !!suggestEstimatedItemSize
|
|
@@ -2486,6 +2828,16 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2486
2828
|
}),
|
|
2487
2829
|
[]
|
|
2488
2830
|
);
|
|
2831
|
+
const animatedScrollHandler = useMemo(() => {
|
|
2832
|
+
if (stickyIndices == null ? void 0 : stickyIndices.length) {
|
|
2833
|
+
const { animatedScrollY } = ctx;
|
|
2834
|
+
return Animated.event([{ nativeEvent: { contentOffset: { [horizontal ? "x" : "y"]: animatedScrollY } } }], {
|
|
2835
|
+
listener: fns.onScroll,
|
|
2836
|
+
useNativeDriver: true
|
|
2837
|
+
});
|
|
2838
|
+
}
|
|
2839
|
+
return fns.onScroll;
|
|
2840
|
+
}, [stickyIndices, horizontal, onScroll]);
|
|
2489
2841
|
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(
|
|
2490
2842
|
ListComponent,
|
|
2491
2843
|
{
|
|
@@ -2502,14 +2854,20 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2502
2854
|
onLayout,
|
|
2503
2855
|
onLayoutHeader,
|
|
2504
2856
|
onMomentumScrollEnd: (event) => {
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2857
|
+
if (IsNewArchitecture) {
|
|
2858
|
+
requestAnimationFrame(() => {
|
|
2859
|
+
finishScrollTo(refState.current);
|
|
2860
|
+
});
|
|
2861
|
+
} else {
|
|
2862
|
+
setTimeout(() => {
|
|
2863
|
+
finishScrollTo(refState.current);
|
|
2864
|
+
}, 1e3);
|
|
2865
|
+
}
|
|
2508
2866
|
if (onMomentumScrollEnd) {
|
|
2509
2867
|
onMomentumScrollEnd(event);
|
|
2510
2868
|
}
|
|
2511
2869
|
},
|
|
2512
|
-
onScroll:
|
|
2870
|
+
onScroll: animatedScrollHandler,
|
|
2513
2871
|
recycleItems,
|
|
2514
2872
|
refreshControl: refreshControl ? stylePaddingTopState > 0 ? React3.cloneElement(refreshControl, {
|
|
2515
2873
|
progressViewOffset: (refreshControl.props.progressViewOffset || 0) + stylePaddingTopState
|
|
@@ -2525,6 +2883,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2525
2883
|
scrollAdjustHandler: (_a = refState.current) == null ? void 0 : _a.scrollAdjustHandler,
|
|
2526
2884
|
scrollEventThrottle: Platform.OS === "web" ? 16 : void 0,
|
|
2527
2885
|
snapToIndices,
|
|
2886
|
+
stickyIndices,
|
|
2528
2887
|
style,
|
|
2529
2888
|
updateItemSize: fns.updateItemSize,
|
|
2530
2889
|
waitForInitialLayout
|