@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.js
CHANGED
|
@@ -28,6 +28,7 @@ var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
|
|
|
28
28
|
var ContextState = React3__namespace.createContext(null);
|
|
29
29
|
function StateProvider({ children }) {
|
|
30
30
|
const [value] = React3__namespace.useState(() => ({
|
|
31
|
+
animatedScrollY: new reactNative.Animated.Value(0),
|
|
31
32
|
columnWrapperStyle: void 0,
|
|
32
33
|
listeners: /* @__PURE__ */ new Map(),
|
|
33
34
|
mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
|
|
@@ -185,18 +186,128 @@ var LeanViewComponent = React3__namespace.forwardRef((props, ref) => {
|
|
|
185
186
|
LeanViewComponent.displayName = "RCTView";
|
|
186
187
|
var LeanView = reactNative.Platform.OS === "android" || reactNative.Platform.OS === "ios" ? LeanViewComponent : reactNative.View;
|
|
187
188
|
|
|
188
|
-
// src/components/Separator.tsx
|
|
189
|
-
function Separator({ ItemSeparatorComponent, itemKey, leadingItem }) {
|
|
190
|
-
const [lastItemKeys] = useArr$(["lastItemKeys"]);
|
|
191
|
-
const isALastItem = lastItemKeys.includes(itemKey);
|
|
192
|
-
return isALastItem ? null : /* @__PURE__ */ React.createElement(ItemSeparatorComponent, { leadingItem });
|
|
193
|
-
}
|
|
194
|
-
|
|
195
189
|
// src/constants.ts
|
|
196
190
|
var POSITION_OUT_OF_VIEW = -1e7;
|
|
197
191
|
var ENABLE_DEVMODE = __DEV__ && false;
|
|
198
192
|
var ENABLE_DEBUG_VIEW = __DEV__ && false;
|
|
199
193
|
var IsNewArchitecture = global.nativeFabricUIManager != null;
|
|
194
|
+
var useAnimatedValue = (initialValue) => {
|
|
195
|
+
return React3.useRef(new reactNative.Animated.Value(initialValue)).current;
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
// src/hooks/useValue$.ts
|
|
199
|
+
function useValue$(key, params) {
|
|
200
|
+
var _a;
|
|
201
|
+
const { getValue, delay } = params || {};
|
|
202
|
+
const ctx = useStateContext();
|
|
203
|
+
const animValue = useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
|
|
204
|
+
React3.useMemo(() => {
|
|
205
|
+
let newValue;
|
|
206
|
+
let prevValue;
|
|
207
|
+
let didQueueTask = false;
|
|
208
|
+
listen$(ctx, key, (v) => {
|
|
209
|
+
newValue = getValue ? getValue(v) : v;
|
|
210
|
+
if (delay !== void 0) {
|
|
211
|
+
const fn = () => {
|
|
212
|
+
didQueueTask = false;
|
|
213
|
+
if (newValue !== void 0) {
|
|
214
|
+
animValue.setValue(newValue);
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
const delayValue = typeof delay === "function" ? delay(newValue, prevValue) : delay;
|
|
218
|
+
prevValue = newValue;
|
|
219
|
+
if (!didQueueTask) {
|
|
220
|
+
didQueueTask = true;
|
|
221
|
+
if (delayValue === 0) {
|
|
222
|
+
queueMicrotask(fn);
|
|
223
|
+
} else {
|
|
224
|
+
setTimeout(fn, delayValue);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
} else {
|
|
228
|
+
animValue.setValue(newValue);
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}, []);
|
|
232
|
+
return animValue;
|
|
233
|
+
}
|
|
234
|
+
var typedForwardRef = React3.forwardRef;
|
|
235
|
+
var typedMemo = React3.memo;
|
|
236
|
+
|
|
237
|
+
// src/components/PositionView.tsx
|
|
238
|
+
var PositionViewState = typedMemo(function PositionView({
|
|
239
|
+
id,
|
|
240
|
+
horizontal,
|
|
241
|
+
style,
|
|
242
|
+
refView,
|
|
243
|
+
...rest
|
|
244
|
+
}) {
|
|
245
|
+
const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
|
|
246
|
+
return /* @__PURE__ */ React3__namespace.createElement(
|
|
247
|
+
LeanView,
|
|
248
|
+
{
|
|
249
|
+
ref: refView,
|
|
250
|
+
style: [
|
|
251
|
+
style,
|
|
252
|
+
horizontal ? { transform: [{ translateX: position }] } : { transform: [{ translateY: position }] }
|
|
253
|
+
],
|
|
254
|
+
...rest
|
|
255
|
+
}
|
|
256
|
+
);
|
|
257
|
+
});
|
|
258
|
+
var PositionViewAnimated = typedMemo(function PositionView2({
|
|
259
|
+
id,
|
|
260
|
+
horizontal,
|
|
261
|
+
style,
|
|
262
|
+
refView,
|
|
263
|
+
...rest
|
|
264
|
+
}) {
|
|
265
|
+
const position$ = useValue$(`containerPosition${id}`, {
|
|
266
|
+
getValue: (v) => v != null ? v : POSITION_OUT_OF_VIEW
|
|
267
|
+
});
|
|
268
|
+
return /* @__PURE__ */ React3__namespace.createElement(
|
|
269
|
+
reactNative.Animated.View,
|
|
270
|
+
{
|
|
271
|
+
ref: refView,
|
|
272
|
+
style: [
|
|
273
|
+
style,
|
|
274
|
+
horizontal ? { transform: [{ translateX: position$ }] } : { transform: [{ translateY: position$ }] }
|
|
275
|
+
],
|
|
276
|
+
...rest
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
});
|
|
280
|
+
var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
281
|
+
id,
|
|
282
|
+
horizontal,
|
|
283
|
+
style,
|
|
284
|
+
refView,
|
|
285
|
+
animatedScrollY,
|
|
286
|
+
stickyOffset,
|
|
287
|
+
index,
|
|
288
|
+
...rest
|
|
289
|
+
}) {
|
|
290
|
+
const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
|
|
291
|
+
const transform = React3__namespace.useMemo(() => {
|
|
292
|
+
if (animatedScrollY && stickyOffset) {
|
|
293
|
+
const stickyPosition = animatedScrollY.interpolate({
|
|
294
|
+
extrapolate: "clamp",
|
|
295
|
+
inputRange: [position, position + 5e3],
|
|
296
|
+
outputRange: [position, position + 5e3]
|
|
297
|
+
});
|
|
298
|
+
return horizontal ? [{ translateX: stickyPosition }] : [{ translateY: stickyPosition }];
|
|
299
|
+
}
|
|
300
|
+
}, [position, horizontal, animatedScrollY, stickyOffset]);
|
|
301
|
+
console.log("index", index, position, transform);
|
|
302
|
+
const viewStyle = React3__namespace.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
|
|
303
|
+
return /* @__PURE__ */ React3__namespace.createElement(reactNative.Animated.View, { ref: refView, style: viewStyle, ...rest });
|
|
304
|
+
});
|
|
305
|
+
var PositionView3 = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
|
|
306
|
+
function Separator({ ItemSeparatorComponent, itemKey, leadingItem }) {
|
|
307
|
+
const [lastItemKeys] = useArr$(["lastItemKeys"]);
|
|
308
|
+
const isALastItem = lastItemKeys.includes(itemKey);
|
|
309
|
+
return isALastItem ? null : /* @__PURE__ */ React3__namespace.createElement(ItemSeparatorComponent, { leadingItem });
|
|
310
|
+
}
|
|
200
311
|
var symbolFirst = Symbol();
|
|
201
312
|
function useInit(cb) {
|
|
202
313
|
const refValue = React3.useRef(symbolFirst);
|
|
@@ -333,8 +444,6 @@ function useListScrollSize() {
|
|
|
333
444
|
const [scrollSize] = useArr$(["scrollSize"]);
|
|
334
445
|
return scrollSize;
|
|
335
446
|
}
|
|
336
|
-
var typedForwardRef = React3.forwardRef;
|
|
337
|
-
var typedMemo = React3.memo;
|
|
338
447
|
|
|
339
448
|
// src/components/Container.tsx
|
|
340
449
|
var Container = typedMemo(function Container2({
|
|
@@ -346,14 +455,15 @@ var Container = typedMemo(function Container2({
|
|
|
346
455
|
ItemSeparatorComponent
|
|
347
456
|
}) {
|
|
348
457
|
const ctx = useStateContext();
|
|
349
|
-
const columnWrapperStyle = ctx
|
|
350
|
-
const [column = 0, data, itemKey,
|
|
458
|
+
const { columnWrapperStyle, animatedScrollY } = ctx;
|
|
459
|
+
const [column = 0, data, itemKey, numColumns, extraData, isSticky, stickyOffset] = useArr$([
|
|
351
460
|
`containerColumn${id}`,
|
|
352
461
|
`containerItemData${id}`,
|
|
353
462
|
`containerItemKey${id}`,
|
|
354
|
-
`containerPosition${id}`,
|
|
355
463
|
"numColumns",
|
|
356
|
-
"extraData"
|
|
464
|
+
"extraData",
|
|
465
|
+
`containerSticky${id}`,
|
|
466
|
+
`containerStickyOffset${id}`
|
|
357
467
|
]);
|
|
358
468
|
const refLastSize = React3.useRef();
|
|
359
469
|
const ref = React3.useRef(null);
|
|
@@ -361,36 +471,38 @@ var Container = typedMemo(function Container2({
|
|
|
361
471
|
const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
|
|
362
472
|
const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
|
|
363
473
|
let didLayout = false;
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
474
|
+
const style = React3.useMemo(() => {
|
|
475
|
+
let paddingStyles;
|
|
476
|
+
if (columnWrapperStyle) {
|
|
477
|
+
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
478
|
+
if (horizontal) {
|
|
479
|
+
paddingStyles = {
|
|
480
|
+
paddingRight: columnGap || gap || void 0,
|
|
481
|
+
paddingVertical: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
|
|
482
|
+
};
|
|
483
|
+
} else {
|
|
484
|
+
paddingStyles = {
|
|
485
|
+
paddingBottom: rowGap || gap || void 0,
|
|
486
|
+
paddingHorizontal: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
|
|
487
|
+
};
|
|
488
|
+
}
|
|
377
489
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
};
|
|
490
|
+
return horizontal ? {
|
|
491
|
+
flexDirection: ItemSeparatorComponent ? "row" : void 0,
|
|
492
|
+
height: otherAxisSize,
|
|
493
|
+
left: 0,
|
|
494
|
+
position: "absolute",
|
|
495
|
+
top: otherAxisPos,
|
|
496
|
+
...paddingStyles || {}
|
|
497
|
+
} : {
|
|
498
|
+
left: otherAxisPos,
|
|
499
|
+
position: "absolute",
|
|
500
|
+
right: numColumns > 1 ? null : 0,
|
|
501
|
+
top: 0,
|
|
502
|
+
width: otherAxisSize,
|
|
503
|
+
...paddingStyles || {}
|
|
504
|
+
};
|
|
505
|
+
}, [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns]);
|
|
394
506
|
const renderedItemInfo = React3.useMemo(
|
|
395
507
|
() => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
|
|
396
508
|
[itemKey, data, extraData]
|
|
@@ -455,55 +567,30 @@ var Container = typedMemo(function Container2({
|
|
|
455
567
|
}
|
|
456
568
|
}, [itemKey]);
|
|
457
569
|
}
|
|
458
|
-
|
|
459
|
-
|
|
570
|
+
const PositionComponent = isSticky ? PositionViewSticky : PositionView3;
|
|
571
|
+
return /* @__PURE__ */ React3__namespace.createElement(
|
|
572
|
+
PositionComponent,
|
|
460
573
|
{
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
React3.useMemo(() => {
|
|
478
|
-
let newValue;
|
|
479
|
-
let prevValue;
|
|
480
|
-
let didQueueTask = false;
|
|
481
|
-
listen$(ctx, key, (v) => {
|
|
482
|
-
newValue = getValue ? getValue(v) : v;
|
|
483
|
-
if (delay !== void 0) {
|
|
484
|
-
const fn = () => {
|
|
485
|
-
didQueueTask = false;
|
|
486
|
-
if (newValue !== void 0) {
|
|
487
|
-
animValue.setValue(newValue);
|
|
488
|
-
}
|
|
489
|
-
};
|
|
490
|
-
const delayValue = typeof delay === "function" ? delay(newValue, prevValue) : delay;
|
|
491
|
-
prevValue = newValue;
|
|
492
|
-
if (!didQueueTask) {
|
|
493
|
-
didQueueTask = true;
|
|
494
|
-
if (delayValue === 0) {
|
|
495
|
-
queueMicrotask(fn);
|
|
496
|
-
} else {
|
|
497
|
-
setTimeout(fn, delayValue);
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
} else {
|
|
501
|
-
animValue.setValue(newValue);
|
|
574
|
+
animatedScrollY: isSticky ? animatedScrollY : void 0,
|
|
575
|
+
horizontal,
|
|
576
|
+
id,
|
|
577
|
+
index,
|
|
578
|
+
key: recycleItems ? void 0 : itemKey,
|
|
579
|
+
onLayout,
|
|
580
|
+
refView: ref,
|
|
581
|
+
stickyOffset: isSticky ? stickyOffset : void 0,
|
|
582
|
+
style
|
|
583
|
+
},
|
|
584
|
+
/* @__PURE__ */ React3__namespace.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React3__namespace.createElement(
|
|
585
|
+
Separator,
|
|
586
|
+
{
|
|
587
|
+
ItemSeparatorComponent,
|
|
588
|
+
itemKey,
|
|
589
|
+
leadingItem: renderedItemInfo.item
|
|
502
590
|
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
}
|
|
591
|
+
))
|
|
592
|
+
);
|
|
593
|
+
});
|
|
507
594
|
|
|
508
595
|
// src/components/Containers.tsx
|
|
509
596
|
var Containers = typedMemo(function Containers2({
|
|
@@ -663,6 +750,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
663
750
|
scrollAdjustHandler,
|
|
664
751
|
onLayoutHeader,
|
|
665
752
|
snapToIndices,
|
|
753
|
+
stickyIndices,
|
|
666
754
|
...rest
|
|
667
755
|
}) {
|
|
668
756
|
const ctx = useStateContext();
|
|
@@ -672,7 +760,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
672
760
|
const ScrollComponent = renderScrollComponent ? React3.useMemo(
|
|
673
761
|
() => React3__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
|
|
674
762
|
[renderScrollComponent]
|
|
675
|
-
) : reactNative.ScrollView;
|
|
763
|
+
) : reactNative.Animated.ScrollView;
|
|
676
764
|
React3__namespace.useEffect(() => {
|
|
677
765
|
if (canRender) {
|
|
678
766
|
setTimeout(() => {
|
|
@@ -725,9 +813,26 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
725
813
|
style: ListFooterComponentStyle
|
|
726
814
|
},
|
|
727
815
|
getComponent(ListFooterComponent)
|
|
728
|
-
)
|
|
816
|
+
),
|
|
817
|
+
__DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React3__namespace.createElement(DevNumbers, null)
|
|
729
818
|
);
|
|
730
819
|
});
|
|
820
|
+
var DevNumbers = __DEV__ && React3__namespace.memo(function DevNumbers2() {
|
|
821
|
+
return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React3__namespace.createElement(
|
|
822
|
+
reactNative.View,
|
|
823
|
+
{
|
|
824
|
+
key: index,
|
|
825
|
+
style: {
|
|
826
|
+
height: 100,
|
|
827
|
+
pointerEvents: "none",
|
|
828
|
+
position: "absolute",
|
|
829
|
+
top: index * 100,
|
|
830
|
+
width: "100%"
|
|
831
|
+
}
|
|
832
|
+
},
|
|
833
|
+
/* @__PURE__ */ React3__namespace.createElement(reactNative.Text, { style: { color: "red" } }, index * 100)
|
|
834
|
+
));
|
|
835
|
+
});
|
|
731
836
|
|
|
732
837
|
// src/utils/getId.ts
|
|
733
838
|
function getId(state, index) {
|
|
@@ -759,20 +864,36 @@ function calculateOffsetForIndex(ctx, state, index) {
|
|
|
759
864
|
}
|
|
760
865
|
|
|
761
866
|
// src/utils/getItemSize.ts
|
|
762
|
-
function getItemSize(state, key, index, data, useAverageSize) {
|
|
867
|
+
function getItemSize(state, key, index, data, useAverageSize, defaultAverageSize) {
|
|
868
|
+
var _a, _b;
|
|
763
869
|
const {
|
|
764
870
|
sizesKnown,
|
|
765
871
|
sizes,
|
|
766
872
|
scrollingTo,
|
|
767
|
-
|
|
873
|
+
averageSizes,
|
|
874
|
+
props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
|
|
768
875
|
} = state;
|
|
769
876
|
const sizeKnown = sizesKnown.get(key);
|
|
770
877
|
if (sizeKnown !== void 0) {
|
|
771
878
|
return sizeKnown;
|
|
772
879
|
}
|
|
773
880
|
let size;
|
|
774
|
-
|
|
775
|
-
|
|
881
|
+
const itemType = getItemType ? (_a = getItemType(data, index)) != null ? _a : "" : "";
|
|
882
|
+
if (getFixedItemSize) {
|
|
883
|
+
size = getFixedItemSize(index, data, itemType);
|
|
884
|
+
if (size !== void 0) {
|
|
885
|
+
sizesKnown.set(key, size);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
if (size === void 0 && useAverageSize && sizeKnown === void 0 && !scrollingTo) {
|
|
889
|
+
if (itemType === "") {
|
|
890
|
+
size = defaultAverageSize;
|
|
891
|
+
} else {
|
|
892
|
+
const averageSizeForType = (_b = averageSizes[itemType]) == null ? void 0 : _b.avg;
|
|
893
|
+
if (averageSizeForType !== void 0) {
|
|
894
|
+
size = roundSize(averageSizeForType);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
776
897
|
}
|
|
777
898
|
if (size === void 0) {
|
|
778
899
|
size = sizes.get(key);
|
|
@@ -781,7 +902,7 @@ function getItemSize(state, key, index, data, useAverageSize) {
|
|
|
781
902
|
}
|
|
782
903
|
}
|
|
783
904
|
if (size === void 0) {
|
|
784
|
-
size = getEstimatedItemSize ? getEstimatedItemSize(index, data) : estimatedItemSize;
|
|
905
|
+
size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
|
|
785
906
|
}
|
|
786
907
|
sizes.set(key, size);
|
|
787
908
|
return size;
|
|
@@ -800,6 +921,37 @@ function calculateOffsetWithOffsetPosition(state, offsetParam, params) {
|
|
|
800
921
|
return offset;
|
|
801
922
|
}
|
|
802
923
|
|
|
924
|
+
// src/core/finishScrollTo.ts
|
|
925
|
+
var finishScrollTo = (state) => {
|
|
926
|
+
if (state) {
|
|
927
|
+
state.scrollingTo = void 0;
|
|
928
|
+
state.scrollHistory.length = 0;
|
|
929
|
+
}
|
|
930
|
+
};
|
|
931
|
+
|
|
932
|
+
// src/core/scrollTo.ts
|
|
933
|
+
function scrollTo(state, params = {}) {
|
|
934
|
+
var _a;
|
|
935
|
+
const { animated } = params;
|
|
936
|
+
const {
|
|
937
|
+
refScroller,
|
|
938
|
+
props: { horizontal }
|
|
939
|
+
} = state;
|
|
940
|
+
const offset = calculateOffsetWithOffsetPosition(state, params.offset, params);
|
|
941
|
+
state.scrollHistory.length = 0;
|
|
942
|
+
state.scrollingTo = params;
|
|
943
|
+
state.scrollPending = offset;
|
|
944
|
+
(_a = refScroller.current) == null ? void 0 : _a.scrollTo({
|
|
945
|
+
animated: !!animated,
|
|
946
|
+
x: horizontal ? offset : 0,
|
|
947
|
+
y: horizontal ? 0 : offset
|
|
948
|
+
});
|
|
949
|
+
if (!animated) {
|
|
950
|
+
state.scroll = offset;
|
|
951
|
+
setTimeout(() => finishScrollTo(state), 100);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
|
|
803
955
|
// src/utils/requestAdjust.ts
|
|
804
956
|
function requestAdjust(ctx, state, positionDiff) {
|
|
805
957
|
if (Math.abs(positionDiff) > 0.1) {
|
|
@@ -833,37 +985,63 @@ function requestAdjust(ctx, state, positionDiff) {
|
|
|
833
985
|
}
|
|
834
986
|
|
|
835
987
|
// src/core/prepareMVCP.ts
|
|
836
|
-
function prepareMVCP(ctx, state) {
|
|
988
|
+
function prepareMVCP(ctx, state, dataChanged) {
|
|
837
989
|
const {
|
|
990
|
+
idsInView,
|
|
838
991
|
positions,
|
|
839
992
|
scrollingTo,
|
|
840
993
|
props: { maintainVisibleContentPosition }
|
|
841
994
|
} = state;
|
|
842
995
|
let prevPosition;
|
|
843
996
|
let targetId;
|
|
844
|
-
|
|
997
|
+
const idsInViewWithPositions = [];
|
|
845
998
|
const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
|
|
846
999
|
if (maintainVisibleContentPosition) {
|
|
847
1000
|
const indexByKey = state.indexByKey;
|
|
848
1001
|
if (scrollTarget !== void 0) {
|
|
849
1002
|
targetId = getId(state, scrollTarget);
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
1003
|
+
} else if (idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
|
|
1004
|
+
if (dataChanged) {
|
|
1005
|
+
for (let i = 0; i < idsInView.length; i++) {
|
|
1006
|
+
const id = idsInView[i];
|
|
1007
|
+
const index = indexByKey.get(id);
|
|
1008
|
+
if (index !== void 0) {
|
|
1009
|
+
idsInViewWithPositions.push({ id, position: positions.get(id) });
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
} else {
|
|
1013
|
+
targetId = state.idsInView.find((id) => indexByKey.get(id) !== void 0);
|
|
1014
|
+
}
|
|
854
1015
|
}
|
|
855
|
-
if (targetId !== void 0
|
|
1016
|
+
if (targetId !== void 0) {
|
|
856
1017
|
prevPosition = positions.get(targetId);
|
|
857
1018
|
}
|
|
858
1019
|
}
|
|
859
1020
|
return () => {
|
|
1021
|
+
let positionDiff;
|
|
1022
|
+
if (targetId === void 0) {
|
|
1023
|
+
for (let i = 0; i < idsInViewWithPositions.length; i++) {
|
|
1024
|
+
const { id, position } = idsInViewWithPositions[i];
|
|
1025
|
+
const newPosition = positions.get(id);
|
|
1026
|
+
if (newPosition !== void 0) {
|
|
1027
|
+
positionDiff = newPosition - position;
|
|
1028
|
+
break;
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
860
1032
|
if (targetId !== void 0 && prevPosition !== void 0) {
|
|
861
1033
|
const newPosition = positions.get(targetId);
|
|
862
1034
|
if (newPosition !== void 0) {
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
1035
|
+
positionDiff = newPosition - prevPosition;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
|
|
1039
|
+
if (reactNative.Platform.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff) {
|
|
1040
|
+
scrollTo(state, {
|
|
1041
|
+
offset: state.scroll + positionDiff
|
|
1042
|
+
});
|
|
1043
|
+
} else {
|
|
1044
|
+
requestAdjust(ctx, state, positionDiff);
|
|
867
1045
|
}
|
|
868
1046
|
}
|
|
869
1047
|
};
|
|
@@ -1004,7 +1182,7 @@ function updateAllPositions(ctx, state, dataChanged) {
|
|
|
1004
1182
|
firstFullyOnScreenIndex,
|
|
1005
1183
|
idCache,
|
|
1006
1184
|
sizesKnown,
|
|
1007
|
-
props: { snapToIndices }
|
|
1185
|
+
props: { getEstimatedItemSize, snapToIndices }
|
|
1008
1186
|
} = state;
|
|
1009
1187
|
const data = state.props.data;
|
|
1010
1188
|
const numColumns = peek$(ctx, "numColumns");
|
|
@@ -1013,7 +1191,9 @@ function updateAllPositions(ctx, state, dataChanged) {
|
|
|
1013
1191
|
if (dataChanged) {
|
|
1014
1192
|
indexByKey.clear();
|
|
1015
1193
|
idCache.clear();
|
|
1194
|
+
positions.clear();
|
|
1016
1195
|
}
|
|
1196
|
+
const useAverageSize = !getEstimatedItemSize;
|
|
1017
1197
|
const itemType = "";
|
|
1018
1198
|
let averageSize = (_a = averageSizes[itemType]) == null ? void 0 : _a.avg;
|
|
1019
1199
|
if (averageSize !== void 0) {
|
|
@@ -1029,7 +1209,7 @@ function updateAllPositions(ctx, state, dataChanged) {
|
|
|
1029
1209
|
let bailout = false;
|
|
1030
1210
|
for (let i = firstFullyOnScreenIndex - 1; i >= 0; i--) {
|
|
1031
1211
|
const id = (_b = idCache.get(i)) != null ? _b : getId(state, i);
|
|
1032
|
-
const size = (_c = sizesKnown.get(id)) != null ? _c : getItemSize(state, id, i, data[i], averageSize);
|
|
1212
|
+
const size = (_c = sizesKnown.get(id)) != null ? _c : getItemSize(state, id, i, data[i], useAverageSize, averageSize);
|
|
1033
1213
|
const itemColumn = columns.get(id);
|
|
1034
1214
|
maxSizeInRow2 = Math.max(maxSizeInRow2, size);
|
|
1035
1215
|
if (itemColumn === 1) {
|
|
@@ -1056,7 +1236,7 @@ function updateAllPositions(ctx, state, dataChanged) {
|
|
|
1056
1236
|
const dataLength = data.length;
|
|
1057
1237
|
for (let i = 0; i < dataLength; i++) {
|
|
1058
1238
|
const id = (_d = idCache.get(i)) != null ? _d : getId(state, i);
|
|
1059
|
-
const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(state, id, i, data[i], averageSize);
|
|
1239
|
+
const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(state, id, i, data[i], useAverageSize, averageSize);
|
|
1060
1240
|
if (__DEV__ && needsIndexByKey) {
|
|
1061
1241
|
if (indexByKeyForChecking.has(id)) {
|
|
1062
1242
|
console.error(
|
|
@@ -1295,35 +1475,84 @@ function checkAllSizesKnown(state) {
|
|
|
1295
1475
|
}
|
|
1296
1476
|
|
|
1297
1477
|
// src/utils/findAvailableContainers.ts
|
|
1298
|
-
function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval) {
|
|
1478
|
+
function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
|
|
1299
1479
|
const numContainers = peek$(ctx, "numContainers");
|
|
1480
|
+
const { stickyIndicesSet } = state.props;
|
|
1300
1481
|
const result = [];
|
|
1301
1482
|
const availableContainers = [];
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
if (!
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1483
|
+
const stickyItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => stickyIndicesSet.has(index))) || [];
|
|
1484
|
+
const nonStickyItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => !stickyIndicesSet.has(index))) || [];
|
|
1485
|
+
const canReuseContainer = (containerIndex, requiredType) => {
|
|
1486
|
+
if (!requiredType) return true;
|
|
1487
|
+
const existingType = state.containerItemTypes.get(containerIndex);
|
|
1488
|
+
if (!existingType) return true;
|
|
1489
|
+
return existingType === requiredType;
|
|
1490
|
+
};
|
|
1491
|
+
const neededTypes = requiredItemTypes ? [...requiredItemTypes] : [];
|
|
1492
|
+
let typeIndex = 0;
|
|
1493
|
+
for (let i = 0; i < stickyItemIndices.length; i++) {
|
|
1494
|
+
const requiredType = neededTypes[typeIndex];
|
|
1495
|
+
let foundContainer = false;
|
|
1496
|
+
for (const containerIndex of state.stickyContainerPool) {
|
|
1497
|
+
const key = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1498
|
+
const isPendingRemoval = pendingRemoval.includes(containerIndex);
|
|
1499
|
+
if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType)) {
|
|
1500
|
+
result.push(containerIndex);
|
|
1501
|
+
if (isPendingRemoval) {
|
|
1502
|
+
const index = pendingRemoval.indexOf(containerIndex);
|
|
1503
|
+
pendingRemoval.splice(index, 1);
|
|
1504
|
+
}
|
|
1505
|
+
foundContainer = true;
|
|
1506
|
+
if (requiredItemTypes) typeIndex++;
|
|
1507
|
+
break;
|
|
1310
1508
|
}
|
|
1311
1509
|
}
|
|
1312
|
-
if (
|
|
1313
|
-
result.
|
|
1314
|
-
|
|
1315
|
-
|
|
1510
|
+
if (!foundContainer) {
|
|
1511
|
+
const newContainerIndex = numContainers + result.filter((index) => index >= numContainers).length;
|
|
1512
|
+
result.push(newContainerIndex);
|
|
1513
|
+
state.stickyContainerPool.add(newContainerIndex);
|
|
1514
|
+
if (requiredItemTypes) typeIndex++;
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
if (nonStickyItemIndices.length > 0) {
|
|
1518
|
+
for (let u = 0; u < numContainers; u++) {
|
|
1519
|
+
if (state.stickyContainerPool.has(u)) {
|
|
1520
|
+
continue;
|
|
1521
|
+
}
|
|
1522
|
+
const key = peek$(ctx, `containerItemKey${u}`);
|
|
1523
|
+
let isOk = key === void 0;
|
|
1524
|
+
if (!isOk) {
|
|
1525
|
+
const index = pendingRemoval.indexOf(u);
|
|
1526
|
+
if (index !== -1) {
|
|
1527
|
+
pendingRemoval.splice(index, 1);
|
|
1528
|
+
const requiredType = neededTypes[typeIndex];
|
|
1529
|
+
isOk = canReuseContainer(u, requiredType);
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
if (isOk) {
|
|
1533
|
+
result.push(u);
|
|
1534
|
+
if (requiredItemTypes) {
|
|
1535
|
+
typeIndex++;
|
|
1536
|
+
}
|
|
1537
|
+
if (result.length >= numNeeded) {
|
|
1538
|
+
return result;
|
|
1539
|
+
}
|
|
1316
1540
|
}
|
|
1317
1541
|
}
|
|
1318
1542
|
}
|
|
1319
1543
|
for (let u = 0; u < numContainers; u++) {
|
|
1544
|
+
if (state.stickyContainerPool.has(u)) {
|
|
1545
|
+
continue;
|
|
1546
|
+
}
|
|
1320
1547
|
const key = peek$(ctx, `containerItemKey${u}`);
|
|
1321
1548
|
if (key === void 0) continue;
|
|
1322
1549
|
const index = state.indexByKey.get(key);
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1550
|
+
const isOutOfView = index < startBuffered || index > endBuffered;
|
|
1551
|
+
if (isOutOfView) {
|
|
1552
|
+
const distance = index < startBuffered ? startBuffered - index : index - endBuffered;
|
|
1553
|
+
if (!requiredItemTypes || typeIndex < neededTypes.length && canReuseContainer(u, neededTypes[typeIndex])) {
|
|
1554
|
+
availableContainers.push({ distance, index: u });
|
|
1555
|
+
}
|
|
1327
1556
|
}
|
|
1328
1557
|
}
|
|
1329
1558
|
const remaining = numNeeded - result.length;
|
|
@@ -1335,6 +1564,9 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1335
1564
|
}
|
|
1336
1565
|
for (const container of availableContainers) {
|
|
1337
1566
|
result.push(container.index);
|
|
1567
|
+
if (requiredItemTypes) {
|
|
1568
|
+
typeIndex++;
|
|
1569
|
+
}
|
|
1338
1570
|
}
|
|
1339
1571
|
}
|
|
1340
1572
|
const stillNeeded = numNeeded - result.length;
|
|
@@ -1363,37 +1595,6 @@ function comparatorByDistance(a, b) {
|
|
|
1363
1595
|
return b.distance - a.distance;
|
|
1364
1596
|
}
|
|
1365
1597
|
|
|
1366
|
-
// src/core/finishScrollTo.ts
|
|
1367
|
-
var finishScrollTo = (state) => {
|
|
1368
|
-
if (state) {
|
|
1369
|
-
state.scrollingTo = void 0;
|
|
1370
|
-
state.scrollHistory.length = 0;
|
|
1371
|
-
}
|
|
1372
|
-
};
|
|
1373
|
-
|
|
1374
|
-
// src/core/scrollTo.ts
|
|
1375
|
-
function scrollTo(state, params = {}) {
|
|
1376
|
-
var _a;
|
|
1377
|
-
const { animated } = params;
|
|
1378
|
-
const {
|
|
1379
|
-
refScroller,
|
|
1380
|
-
props: { horizontal }
|
|
1381
|
-
} = state;
|
|
1382
|
-
const offset = calculateOffsetWithOffsetPosition(state, params.offset, params);
|
|
1383
|
-
state.scrollHistory.length = 0;
|
|
1384
|
-
state.scrollingTo = params;
|
|
1385
|
-
state.scrollPending = offset;
|
|
1386
|
-
(_a = refScroller.current) == null ? void 0 : _a.scrollTo({
|
|
1387
|
-
animated: !!animated,
|
|
1388
|
-
x: horizontal ? offset : 0,
|
|
1389
|
-
y: horizontal ? 0 : offset
|
|
1390
|
-
});
|
|
1391
|
-
if (!animated) {
|
|
1392
|
-
state.scroll = offset;
|
|
1393
|
-
setTimeout(() => finishScrollTo(state), 100);
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
|
|
1397
1598
|
// src/core/scrollToIndex.ts
|
|
1398
1599
|
function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
|
|
1399
1600
|
if (index >= state.props.data.length) {
|
|
@@ -1481,16 +1682,90 @@ function setDidLayout(ctx, state) {
|
|
|
1481
1682
|
} = state;
|
|
1482
1683
|
state.queuedInitialLayout = true;
|
|
1483
1684
|
checkAtBottom(ctx, state);
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1685
|
+
const setIt = () => {
|
|
1686
|
+
set$(ctx, "containersDidLayout", true);
|
|
1687
|
+
if (onLoad) {
|
|
1688
|
+
onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
|
|
1689
|
+
}
|
|
1690
|
+
};
|
|
1691
|
+
if (reactNative.Platform.OS === "android" || !IsNewArchitecture) {
|
|
1692
|
+
if (initialScroll) {
|
|
1693
|
+
queueMicrotask(() => {
|
|
1694
|
+
scrollToIndex(ctx, state, { ...initialScroll, animated: false });
|
|
1695
|
+
requestAnimationFrame(() => {
|
|
1696
|
+
scrollToIndex(ctx, state, { ...initialScroll, animated: false });
|
|
1697
|
+
setIt();
|
|
1698
|
+
});
|
|
1699
|
+
});
|
|
1700
|
+
} else {
|
|
1701
|
+
queueMicrotask(setIt);
|
|
1702
|
+
}
|
|
1703
|
+
} else {
|
|
1704
|
+
setIt();
|
|
1490
1705
|
}
|
|
1491
1706
|
}
|
|
1492
1707
|
|
|
1493
1708
|
// src/core/calculateItemsInView.ts
|
|
1709
|
+
function findCurrentStickyIndex(stickyArray, scroll, state) {
|
|
1710
|
+
var _a;
|
|
1711
|
+
for (let i = stickyArray.length - 1; i >= 0; i--) {
|
|
1712
|
+
const stickyId = (_a = state.idCache.get(stickyArray[i])) != null ? _a : getId(state, stickyArray[i]);
|
|
1713
|
+
const stickyPos = stickyId ? state.positions.get(stickyId) : void 0;
|
|
1714
|
+
if (stickyPos !== void 0 && scroll >= stickyPos) {
|
|
1715
|
+
return i;
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
return -1;
|
|
1719
|
+
}
|
|
1720
|
+
function getActiveStickyIndices(ctx, state, stickyIndices) {
|
|
1721
|
+
return new Set(
|
|
1722
|
+
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))
|
|
1723
|
+
);
|
|
1724
|
+
}
|
|
1725
|
+
function handleStickyActivation(ctx, state, stickyIndices, stickyArray, scroll, needNewContainers, startBuffered, endBuffered) {
|
|
1726
|
+
var _a;
|
|
1727
|
+
const activeIndices = getActiveStickyIndices(ctx, state, stickyIndices);
|
|
1728
|
+
const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
|
|
1729
|
+
for (let offset = 0; offset <= 1; offset++) {
|
|
1730
|
+
const idx = currentStickyIdx - offset;
|
|
1731
|
+
if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
|
|
1732
|
+
const stickyIndex = stickyArray[idx];
|
|
1733
|
+
const stickyId = (_a = state.idCache.get(stickyIndex)) != null ? _a : getId(state, stickyIndex);
|
|
1734
|
+
if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered)) {
|
|
1735
|
+
needNewContainers.push(stickyIndex);
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, pendingRemoval) {
|
|
1740
|
+
var _a, _b, _c;
|
|
1741
|
+
const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
|
|
1742
|
+
for (const containerIndex of state.stickyContainerPool) {
|
|
1743
|
+
const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1744
|
+
const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
|
|
1745
|
+
if (itemIndex === void 0) continue;
|
|
1746
|
+
const arrayIdx = stickyArray.indexOf(itemIndex);
|
|
1747
|
+
if (arrayIdx === -1) continue;
|
|
1748
|
+
const isRecentSticky = arrayIdx >= currentStickyIdx - 1 && arrayIdx <= currentStickyIdx + 1;
|
|
1749
|
+
if (isRecentSticky) continue;
|
|
1750
|
+
const nextIndex = stickyArray[arrayIdx + 1];
|
|
1751
|
+
let shouldRecycle = false;
|
|
1752
|
+
if (nextIndex) {
|
|
1753
|
+
const nextId = (_a = state.idCache.get(nextIndex)) != null ? _a : getId(state, nextIndex);
|
|
1754
|
+
const nextPos = nextId ? state.positions.get(nextId) : void 0;
|
|
1755
|
+
shouldRecycle = nextPos !== void 0 && scroll > nextPos + scrollBuffer * 2;
|
|
1756
|
+
} else {
|
|
1757
|
+
const currentId = (_b = state.idCache.get(itemIndex)) != null ? _b : getId(state, itemIndex);
|
|
1758
|
+
if (currentId) {
|
|
1759
|
+
const currentPos = state.positions.get(currentId);
|
|
1760
|
+
const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(state, currentId, itemIndex, state.props.data[itemIndex]);
|
|
1761
|
+
shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
if (shouldRecycle) {
|
|
1765
|
+
pendingRemoval.push(containerIndex);
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1494
1769
|
function calculateItemsInView(ctx, state, params = {}) {
|
|
1495
1770
|
reactNative.unstable_batchedUpdates(() => {
|
|
1496
1771
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
@@ -1507,7 +1782,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1507
1782
|
enableScrollForNextCalculateItemsInView,
|
|
1508
1783
|
minIndexSizeChanged
|
|
1509
1784
|
} = state;
|
|
1510
|
-
const data = state.props
|
|
1785
|
+
const { data, stickyIndicesArr, stickyIndicesSet } = state.props;
|
|
1511
1786
|
const prevNumContainers = peek$(ctx, "numContainers");
|
|
1512
1787
|
if (!data || scrollLength === 0 || !prevNumContainers) {
|
|
1513
1788
|
return;
|
|
@@ -1519,7 +1794,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1519
1794
|
const { dataChanged, doMVCP } = params;
|
|
1520
1795
|
const speed = getScrollVelocity(state);
|
|
1521
1796
|
if (doMVCP || dataChanged) {
|
|
1522
|
-
const checkMVCP = doMVCP ? prepareMVCP(ctx, state) : void 0;
|
|
1797
|
+
const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
|
|
1523
1798
|
updateAllPositions(ctx, state, dataChanged);
|
|
1524
1799
|
checkMVCP == null ? void 0 : checkMVCP();
|
|
1525
1800
|
}
|
|
@@ -1669,14 +1944,23 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1669
1944
|
needNewContainers.push(i);
|
|
1670
1945
|
}
|
|
1671
1946
|
}
|
|
1947
|
+
if (stickyIndicesArr.length > 0) {
|
|
1948
|
+
handleStickyActivation(ctx, state, stickyIndicesSet, stickyIndicesArr, scroll, needNewContainers, startBuffered, endBuffered);
|
|
1949
|
+
}
|
|
1672
1950
|
if (needNewContainers.length > 0) {
|
|
1951
|
+
const requiredItemTypes = state.props.getItemType ? needNewContainers.map((i) => {
|
|
1952
|
+
const itemType = state.props.getItemType(data[i], i);
|
|
1953
|
+
return itemType ? String(itemType) : "";
|
|
1954
|
+
}) : void 0;
|
|
1673
1955
|
const availableContainers = findAvailableContainers(
|
|
1674
1956
|
ctx,
|
|
1675
1957
|
state,
|
|
1676
1958
|
needNewContainers.length,
|
|
1677
1959
|
startBuffered,
|
|
1678
1960
|
endBuffered,
|
|
1679
|
-
pendingRemoval
|
|
1961
|
+
pendingRemoval,
|
|
1962
|
+
requiredItemTypes,
|
|
1963
|
+
needNewContainers
|
|
1680
1964
|
);
|
|
1681
1965
|
for (let idx = 0; idx < needNewContainers.length; idx++) {
|
|
1682
1966
|
const i = needNewContainers[idx];
|
|
@@ -1688,7 +1972,18 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1688
1972
|
}
|
|
1689
1973
|
set$(ctx, `containerItemKey${containerIndex}`, id);
|
|
1690
1974
|
set$(ctx, `containerItemData${containerIndex}`, data[i]);
|
|
1975
|
+
if (requiredItemTypes) {
|
|
1976
|
+
state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
|
|
1977
|
+
}
|
|
1691
1978
|
containerItemKeys.add(id);
|
|
1979
|
+
if (stickyIndicesSet.has(i)) {
|
|
1980
|
+
set$(ctx, `containerSticky${containerIndex}`, true);
|
|
1981
|
+
const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
1982
|
+
set$(ctx, `containerStickyOffset${containerIndex}`, new reactNative.Animated.Value(topPadding));
|
|
1983
|
+
state.stickyContainerPool.add(containerIndex);
|
|
1984
|
+
} else {
|
|
1985
|
+
state.stickyContainerPool.delete(containerIndex);
|
|
1986
|
+
}
|
|
1692
1987
|
if (containerIndex >= numContainers2) {
|
|
1693
1988
|
numContainers2 = containerIndex + 1;
|
|
1694
1989
|
}
|
|
@@ -1701,12 +1996,21 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1701
1996
|
}
|
|
1702
1997
|
}
|
|
1703
1998
|
}
|
|
1999
|
+
if (stickyIndicesArr.length > 0) {
|
|
2000
|
+
handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, pendingRemoval);
|
|
2001
|
+
}
|
|
1704
2002
|
for (let i = 0; i < numContainers; i++) {
|
|
1705
2003
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1706
2004
|
if (pendingRemoval.includes(i)) {
|
|
1707
2005
|
if (itemKey) {
|
|
1708
2006
|
containerItemKeys.delete(itemKey);
|
|
1709
2007
|
}
|
|
2008
|
+
state.containerItemTypes.delete(i);
|
|
2009
|
+
if (state.stickyContainerPool.has(i)) {
|
|
2010
|
+
set$(ctx, `containerSticky${i}`, false);
|
|
2011
|
+
set$(ctx, `containerStickyOffset${i}`, void 0);
|
|
2012
|
+
state.stickyContainerPool.delete(i);
|
|
2013
|
+
}
|
|
1710
2014
|
set$(ctx, `containerItemKey${i}`, void 0);
|
|
1711
2015
|
set$(ctx, `containerItemData${i}`, void 0);
|
|
1712
2016
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
@@ -1757,10 +2061,14 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1757
2061
|
|
|
1758
2062
|
// src/core/doInitialAllocateContainers.ts
|
|
1759
2063
|
function doInitialAllocateContainers(ctx, state) {
|
|
1760
|
-
|
|
2064
|
+
var _a;
|
|
2065
|
+
const {
|
|
2066
|
+
scrollLength,
|
|
2067
|
+
props: { getItemType }
|
|
2068
|
+
} = state;
|
|
1761
2069
|
const data = state.props.data;
|
|
1762
2070
|
if (scrollLength > 0 && data.length > 0 && !peek$(ctx, "numContainers")) {
|
|
1763
|
-
const averageItemSize = state.props.getEstimatedItemSize ? state.props.getEstimatedItemSize(0, data[0]) : state.props.estimatedItemSize;
|
|
2071
|
+
const averageItemSize = state.props.getEstimatedItemSize ? state.props.getEstimatedItemSize(0, data[0], getItemType ? (_a = getItemType(data[0], 0)) != null ? _a : "" : "") : state.props.estimatedItemSize;
|
|
1764
2072
|
const Extra = 1.5;
|
|
1765
2073
|
const numContainers = Math.ceil(
|
|
1766
2074
|
(scrollLength + state.props.scrollBuffer * 2) / averageItemSize * state.props.numColumns * Extra
|
|
@@ -1797,16 +2105,18 @@ function doMaintainScrollAtEnd(ctx, state, animated) {
|
|
|
1797
2105
|
}
|
|
1798
2106
|
requestAnimationFrame(() => {
|
|
1799
2107
|
var _a;
|
|
1800
|
-
state.
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
(
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
2108
|
+
if (state == null ? void 0 : state.isAtEnd) {
|
|
2109
|
+
state.maintainingScrollAtEnd = true;
|
|
2110
|
+
(_a = refScroller.current) == null ? void 0 : _a.scrollToEnd({
|
|
2111
|
+
animated
|
|
2112
|
+
});
|
|
2113
|
+
setTimeout(
|
|
2114
|
+
() => {
|
|
2115
|
+
state.maintainingScrollAtEnd = false;
|
|
2116
|
+
},
|
|
2117
|
+
0
|
|
2118
|
+
);
|
|
2119
|
+
}
|
|
1810
2120
|
});
|
|
1811
2121
|
return true;
|
|
1812
2122
|
}
|
|
@@ -2026,7 +2336,22 @@ function updateItemSizes(ctx, state, itemUpdates) {
|
|
|
2026
2336
|
}
|
|
2027
2337
|
}
|
|
2028
2338
|
function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
2029
|
-
|
|
2339
|
+
var _a;
|
|
2340
|
+
const {
|
|
2341
|
+
queuedItemSizeUpdates,
|
|
2342
|
+
queuedItemSizeUpdatesWaiting,
|
|
2343
|
+
sizesKnown,
|
|
2344
|
+
props: { getFixedItemSize, getItemType }
|
|
2345
|
+
} = state;
|
|
2346
|
+
if (getFixedItemSize) {
|
|
2347
|
+
const index = state.indexByKey.get(itemKey);
|
|
2348
|
+
const itemData = state.props.data[index];
|
|
2349
|
+
const type = getItemType ? (_a = getItemType(itemData, index)) != null ? _a : "" : "";
|
|
2350
|
+
const size = getFixedItemSize(index, itemData, type);
|
|
2351
|
+
if (size !== void 0 && size === sizesKnown.get(itemKey)) {
|
|
2352
|
+
return;
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2030
2355
|
const containersDidLayout = peek$(ctx, "containersDidLayout");
|
|
2031
2356
|
if (!containersDidLayout || !queuedItemSizeUpdatesWaiting) {
|
|
2032
2357
|
updateItemSizes(ctx, state, [{ itemKey, sizeObj }]);
|
|
@@ -2043,25 +2368,28 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
2043
2368
|
}
|
|
2044
2369
|
}
|
|
2045
2370
|
function updateOneItemSize(state, itemKey, sizeObj) {
|
|
2371
|
+
var _a;
|
|
2046
2372
|
const {
|
|
2047
2373
|
sizes,
|
|
2048
2374
|
indexByKey,
|
|
2049
2375
|
sizesKnown,
|
|
2050
2376
|
averageSizes,
|
|
2051
|
-
props: { data, horizontal }
|
|
2377
|
+
props: { data, horizontal, getEstimatedItemSize, getItemType }
|
|
2052
2378
|
} = state;
|
|
2053
2379
|
if (!data) return 0;
|
|
2054
2380
|
const index = indexByKey.get(itemKey);
|
|
2055
2381
|
const prevSize = getItemSize(state, itemKey, index, data);
|
|
2056
2382
|
const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
|
|
2057
2383
|
sizesKnown.set(itemKey, size);
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
averages
|
|
2384
|
+
if (!getEstimatedItemSize) {
|
|
2385
|
+
const itemType = getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : "";
|
|
2386
|
+
let averages = averageSizes[itemType];
|
|
2387
|
+
if (!averages) {
|
|
2388
|
+
averages = averageSizes[itemType] = { avg: 0, num: 0 };
|
|
2389
|
+
}
|
|
2390
|
+
averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
|
|
2391
|
+
averages.num++;
|
|
2062
2392
|
}
|
|
2063
|
-
averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
|
|
2064
|
-
averages.num++;
|
|
2065
2393
|
if (!prevSize || Math.abs(prevSize - size) > 0.1) {
|
|
2066
2394
|
sizes.set(itemKey, size);
|
|
2067
2395
|
return size - prevSize;
|
|
@@ -2099,12 +2427,13 @@ function createColumnWrapperStyle(contentContainerStyle) {
|
|
|
2099
2427
|
}
|
|
2100
2428
|
}
|
|
2101
2429
|
function getRenderedItem(ctx, state, key) {
|
|
2430
|
+
var _a;
|
|
2102
2431
|
if (!state) {
|
|
2103
2432
|
return null;
|
|
2104
2433
|
}
|
|
2105
2434
|
const {
|
|
2106
2435
|
indexByKey,
|
|
2107
|
-
props: { data, renderItem: renderItem2 }
|
|
2436
|
+
props: { data, getItemType, renderItem: renderItem2 }
|
|
2108
2437
|
} = state;
|
|
2109
2438
|
const index = indexByKey.get(key);
|
|
2110
2439
|
if (index === void 0) {
|
|
@@ -2115,7 +2444,8 @@ function getRenderedItem(ctx, state, key) {
|
|
|
2115
2444
|
const itemProps = {
|
|
2116
2445
|
extraData: peek$(ctx, "extraData"),
|
|
2117
2446
|
index,
|
|
2118
|
-
item: data[index]
|
|
2447
|
+
item: data[index],
|
|
2448
|
+
type: getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : ""
|
|
2119
2449
|
};
|
|
2120
2450
|
renderedItem = React3__namespace.default.createElement(renderItem2, itemProps);
|
|
2121
2451
|
}
|
|
@@ -2131,49 +2461,52 @@ var LegendList = typedForwardRef(function LegendList2(props, forwardedRef) {
|
|
|
2131
2461
|
var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
|
|
2132
2462
|
var _a;
|
|
2133
2463
|
const {
|
|
2464
|
+
alignItemsAtEnd = false,
|
|
2465
|
+
columnWrapperStyle,
|
|
2466
|
+
contentContainerStyle: contentContainerStyleProp,
|
|
2134
2467
|
data: dataProp = [],
|
|
2468
|
+
drawDistance = 250,
|
|
2469
|
+
estimatedItemSize: estimatedItemSizeProp,
|
|
2470
|
+
estimatedListSize,
|
|
2471
|
+
extraData,
|
|
2472
|
+
getEstimatedItemSize,
|
|
2473
|
+
getFixedItemSize,
|
|
2474
|
+
getItemType,
|
|
2475
|
+
horizontal,
|
|
2476
|
+
initialContainerPoolRatio = 2,
|
|
2135
2477
|
initialScrollIndex: initialScrollIndexProp,
|
|
2136
2478
|
initialScrollOffset,
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
onEndReachedThreshold = 0.5,
|
|
2141
|
-
onStartReachedThreshold = 0.5,
|
|
2479
|
+
keyExtractor: keyExtractorProp,
|
|
2480
|
+
ListEmptyComponent,
|
|
2481
|
+
ListHeaderComponent,
|
|
2142
2482
|
maintainScrollAtEnd = false,
|
|
2143
2483
|
maintainScrollAtEndThreshold = 0.1,
|
|
2144
|
-
alignItemsAtEnd = false,
|
|
2145
2484
|
maintainVisibleContentPosition = false,
|
|
2146
|
-
onScroll: onScrollProp,
|
|
2147
|
-
onMomentumScrollEnd,
|
|
2148
2485
|
numColumns: numColumnsProp = 1,
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
renderItem: renderItem2,
|
|
2152
|
-
estimatedListSize,
|
|
2153
|
-
estimatedItemSize: estimatedItemSizeProp,
|
|
2154
|
-
getEstimatedItemSize,
|
|
2155
|
-
suggestEstimatedItemSize,
|
|
2156
|
-
ListHeaderComponent,
|
|
2157
|
-
ListEmptyComponent,
|
|
2486
|
+
onEndReached,
|
|
2487
|
+
onEndReachedThreshold = 0.5,
|
|
2158
2488
|
onItemSizeChanged,
|
|
2159
|
-
refScrollView,
|
|
2160
|
-
waitForInitialLayout = true,
|
|
2161
|
-
extraData,
|
|
2162
|
-
contentContainerStyle: contentContainerStyleProp,
|
|
2163
|
-
style: styleProp,
|
|
2164
2489
|
onLayout: onLayoutProp,
|
|
2490
|
+
onLoad,
|
|
2491
|
+
onMomentumScrollEnd,
|
|
2165
2492
|
onRefresh,
|
|
2166
|
-
|
|
2493
|
+
onScroll: onScrollProp,
|
|
2494
|
+
onStartReached,
|
|
2495
|
+
onStartReachedThreshold = 0.5,
|
|
2496
|
+
onViewableItemsChanged,
|
|
2167
2497
|
progressViewOffset,
|
|
2498
|
+
recycleItems = false,
|
|
2168
2499
|
refreshControl,
|
|
2169
|
-
|
|
2500
|
+
refreshing,
|
|
2501
|
+
refScrollView,
|
|
2502
|
+
renderItem: renderItem2,
|
|
2503
|
+
snapToIndices,
|
|
2504
|
+
stickyIndices,
|
|
2505
|
+
style: styleProp,
|
|
2506
|
+
suggestEstimatedItemSize,
|
|
2170
2507
|
viewabilityConfig,
|
|
2171
2508
|
viewabilityConfigCallbackPairs,
|
|
2172
|
-
|
|
2173
|
-
onViewableItemsChanged,
|
|
2174
|
-
onStartReached,
|
|
2175
|
-
onEndReached,
|
|
2176
|
-
onLoad,
|
|
2509
|
+
waitForInitialLayout = true,
|
|
2177
2510
|
...rest
|
|
2178
2511
|
} = props;
|
|
2179
2512
|
const [renderNum, setRenderNum] = React3.useState(0);
|
|
@@ -2195,9 +2528,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2195
2528
|
if (!refState.current) {
|
|
2196
2529
|
const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { height: 0, width: 0 } : reactNative.Dimensions.get("window"))[horizontal ? "width" : "height"];
|
|
2197
2530
|
refState.current = {
|
|
2531
|
+
activeStickyIndex: void 0,
|
|
2198
2532
|
averageSizes: {},
|
|
2199
2533
|
columns: /* @__PURE__ */ new Map(),
|
|
2200
2534
|
containerItemKeys: /* @__PURE__ */ new Set(),
|
|
2535
|
+
containerItemTypes: /* @__PURE__ */ new Map(),
|
|
2201
2536
|
enableScrollForNextCalculateItemsInView: true,
|
|
2202
2537
|
endBuffered: -1,
|
|
2203
2538
|
endNoBuffer: -1,
|
|
@@ -2236,6 +2571,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2236
2571
|
startBuffered: -1,
|
|
2237
2572
|
startNoBuffer: -1,
|
|
2238
2573
|
startReachedBlockedByTimer: false,
|
|
2574
|
+
stickyContainerPool: /* @__PURE__ */ new Set(),
|
|
2575
|
+
stickyContainers: /* @__PURE__ */ new Map(),
|
|
2239
2576
|
timeoutSizeMessage: 0,
|
|
2240
2577
|
timeouts: /* @__PURE__ */ new Set(),
|
|
2241
2578
|
totalSize: 0,
|
|
@@ -2252,6 +2589,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2252
2589
|
data: dataProp,
|
|
2253
2590
|
estimatedItemSize,
|
|
2254
2591
|
getEstimatedItemSize,
|
|
2592
|
+
getFixedItemSize,
|
|
2593
|
+
getItemType,
|
|
2255
2594
|
horizontal: !!horizontal,
|
|
2256
2595
|
initialContainerPoolRatio,
|
|
2257
2596
|
initialScroll,
|
|
@@ -2267,9 +2606,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2267
2606
|
onScroll: onScrollProp,
|
|
2268
2607
|
onStartReached,
|
|
2269
2608
|
onStartReachedThreshold,
|
|
2609
|
+
recycleItems: !!recycleItems,
|
|
2270
2610
|
renderItem: renderItem2,
|
|
2271
2611
|
scrollBuffer,
|
|
2272
2612
|
snapToIndices,
|
|
2613
|
+
stickyIndicesArr: stickyIndices != null ? stickyIndices : [],
|
|
2614
|
+
stickyIndicesSet: React3.useMemo(() => new Set(stickyIndices), [stickyIndices]),
|
|
2273
2615
|
stylePaddingBottom: stylePaddingBottomState,
|
|
2274
2616
|
stylePaddingTop: stylePaddingTopState,
|
|
2275
2617
|
suggestEstimatedItemSize: !!suggestEstimatedItemSize
|
|
@@ -2507,6 +2849,16 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2507
2849
|
}),
|
|
2508
2850
|
[]
|
|
2509
2851
|
);
|
|
2852
|
+
const animatedScrollHandler = React3.useMemo(() => {
|
|
2853
|
+
if (stickyIndices == null ? void 0 : stickyIndices.length) {
|
|
2854
|
+
const { animatedScrollY } = ctx;
|
|
2855
|
+
return reactNative.Animated.event([{ nativeEvent: { contentOffset: { [horizontal ? "x" : "y"]: animatedScrollY } } }], {
|
|
2856
|
+
listener: fns.onScroll,
|
|
2857
|
+
useNativeDriver: true
|
|
2858
|
+
});
|
|
2859
|
+
}
|
|
2860
|
+
return fns.onScroll;
|
|
2861
|
+
}, [stickyIndices, horizontal, onScroll]);
|
|
2510
2862
|
return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement(
|
|
2511
2863
|
ListComponent,
|
|
2512
2864
|
{
|
|
@@ -2523,14 +2875,20 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2523
2875
|
onLayout,
|
|
2524
2876
|
onLayoutHeader,
|
|
2525
2877
|
onMomentumScrollEnd: (event) => {
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2878
|
+
if (IsNewArchitecture) {
|
|
2879
|
+
requestAnimationFrame(() => {
|
|
2880
|
+
finishScrollTo(refState.current);
|
|
2881
|
+
});
|
|
2882
|
+
} else {
|
|
2883
|
+
setTimeout(() => {
|
|
2884
|
+
finishScrollTo(refState.current);
|
|
2885
|
+
}, 1e3);
|
|
2886
|
+
}
|
|
2529
2887
|
if (onMomentumScrollEnd) {
|
|
2530
2888
|
onMomentumScrollEnd(event);
|
|
2531
2889
|
}
|
|
2532
2890
|
},
|
|
2533
|
-
onScroll:
|
|
2891
|
+
onScroll: animatedScrollHandler,
|
|
2534
2892
|
recycleItems,
|
|
2535
2893
|
refreshControl: refreshControl ? stylePaddingTopState > 0 ? React3__namespace.cloneElement(refreshControl, {
|
|
2536
2894
|
progressViewOffset: (refreshControl.props.progressViewOffset || 0) + stylePaddingTopState
|
|
@@ -2546,6 +2904,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2546
2904
|
scrollAdjustHandler: (_a = refState.current) == null ? void 0 : _a.scrollAdjustHandler,
|
|
2547
2905
|
scrollEventThrottle: reactNative.Platform.OS === "web" ? 16 : void 0,
|
|
2548
2906
|
snapToIndices,
|
|
2907
|
+
stickyIndices,
|
|
2549
2908
|
style,
|
|
2550
2909
|
updateItemSize: fns.updateItemSize,
|
|
2551
2910
|
waitForInitialLayout
|