@legendapp/list 2.0.0-next.10 → 2.0.0-next.11
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 +552 -212
- package/index.mjs +554 -214
- 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,130 @@ 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
|
|
|
189
|
+
// src/constants.ts
|
|
190
|
+
var POSITION_OUT_OF_VIEW = -1e7;
|
|
191
|
+
var ENABLE_DEVMODE = __DEV__ && false;
|
|
192
|
+
var ENABLE_DEBUG_VIEW = __DEV__ && false;
|
|
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
|
+
|
|
188
307
|
// src/components/Separator.tsx
|
|
189
308
|
function Separator({ ItemSeparatorComponent, itemKey, leadingItem }) {
|
|
190
309
|
const [lastItemKeys] = useArr$(["lastItemKeys"]);
|
|
191
310
|
const isALastItem = lastItemKeys.includes(itemKey);
|
|
192
311
|
return isALastItem ? null : /* @__PURE__ */ React.createElement(ItemSeparatorComponent, { leadingItem });
|
|
193
312
|
}
|
|
194
|
-
|
|
195
|
-
// src/constants.ts
|
|
196
|
-
var POSITION_OUT_OF_VIEW = -1e7;
|
|
197
|
-
var ENABLE_DEVMODE = __DEV__ && false;
|
|
198
|
-
var ENABLE_DEBUG_VIEW = __DEV__ && false;
|
|
199
|
-
var IsNewArchitecture = global.nativeFabricUIManager != null;
|
|
200
313
|
var symbolFirst = Symbol();
|
|
201
314
|
function useInit(cb) {
|
|
202
315
|
const refValue = React3.useRef(symbolFirst);
|
|
@@ -333,8 +446,6 @@ function useListScrollSize() {
|
|
|
333
446
|
const [scrollSize] = useArr$(["scrollSize"]);
|
|
334
447
|
return scrollSize;
|
|
335
448
|
}
|
|
336
|
-
var typedForwardRef = React3.forwardRef;
|
|
337
|
-
var typedMemo = React3.memo;
|
|
338
449
|
|
|
339
450
|
// src/components/Container.tsx
|
|
340
451
|
var Container = typedMemo(function Container2({
|
|
@@ -346,14 +457,15 @@ var Container = typedMemo(function Container2({
|
|
|
346
457
|
ItemSeparatorComponent
|
|
347
458
|
}) {
|
|
348
459
|
const ctx = useStateContext();
|
|
349
|
-
const columnWrapperStyle = ctx
|
|
350
|
-
const [column = 0, data, itemKey,
|
|
460
|
+
const { columnWrapperStyle, animatedScrollY } = ctx;
|
|
461
|
+
const [column = 0, data, itemKey, numColumns, extraData, isSticky, stickyOffset] = useArr$([
|
|
351
462
|
`containerColumn${id}`,
|
|
352
463
|
`containerItemData${id}`,
|
|
353
464
|
`containerItemKey${id}`,
|
|
354
|
-
`containerPosition${id}`,
|
|
355
465
|
"numColumns",
|
|
356
|
-
"extraData"
|
|
466
|
+
"extraData",
|
|
467
|
+
`containerSticky${id}`,
|
|
468
|
+
`containerStickyOffset${id}`
|
|
357
469
|
]);
|
|
358
470
|
const refLastSize = React3.useRef();
|
|
359
471
|
const ref = React3.useRef(null);
|
|
@@ -361,36 +473,38 @@ var Container = typedMemo(function Container2({
|
|
|
361
473
|
const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
|
|
362
474
|
const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
|
|
363
475
|
let didLayout = false;
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
476
|
+
const style = React3.useMemo(() => {
|
|
477
|
+
let paddingStyles;
|
|
478
|
+
if (columnWrapperStyle) {
|
|
479
|
+
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
480
|
+
if (horizontal) {
|
|
481
|
+
paddingStyles = {
|
|
482
|
+
paddingRight: columnGap || gap || void 0,
|
|
483
|
+
paddingVertical: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
|
|
484
|
+
};
|
|
485
|
+
} else {
|
|
486
|
+
paddingStyles = {
|
|
487
|
+
paddingBottom: rowGap || gap || void 0,
|
|
488
|
+
paddingHorizontal: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
|
|
489
|
+
};
|
|
490
|
+
}
|
|
377
491
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
};
|
|
492
|
+
return horizontal ? {
|
|
493
|
+
flexDirection: ItemSeparatorComponent ? "row" : void 0,
|
|
494
|
+
height: otherAxisSize,
|
|
495
|
+
left: 0,
|
|
496
|
+
position: "absolute",
|
|
497
|
+
top: otherAxisPos,
|
|
498
|
+
...paddingStyles || {}
|
|
499
|
+
} : {
|
|
500
|
+
left: otherAxisPos,
|
|
501
|
+
position: "absolute",
|
|
502
|
+
right: numColumns > 1 ? null : 0,
|
|
503
|
+
top: 0,
|
|
504
|
+
width: otherAxisSize,
|
|
505
|
+
...paddingStyles || {}
|
|
506
|
+
};
|
|
507
|
+
}, [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns]);
|
|
394
508
|
const renderedItemInfo = React3.useMemo(
|
|
395
509
|
() => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
|
|
396
510
|
[itemKey, data, extraData]
|
|
@@ -455,55 +569,30 @@ var Container = typedMemo(function Container2({
|
|
|
455
569
|
}
|
|
456
570
|
}, [itemKey]);
|
|
457
571
|
}
|
|
458
|
-
|
|
459
|
-
|
|
572
|
+
const PositionComponent = isSticky ? PositionViewSticky : PositionView3;
|
|
573
|
+
return /* @__PURE__ */ React3__namespace.createElement(
|
|
574
|
+
PositionComponent,
|
|
460
575
|
{
|
|
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);
|
|
576
|
+
animatedScrollY: isSticky ? animatedScrollY : void 0,
|
|
577
|
+
horizontal,
|
|
578
|
+
id,
|
|
579
|
+
index,
|
|
580
|
+
key: recycleItems ? void 0 : itemKey,
|
|
581
|
+
onLayout,
|
|
582
|
+
refView: ref,
|
|
583
|
+
stickyOffset: isSticky ? stickyOffset : void 0,
|
|
584
|
+
style
|
|
585
|
+
},
|
|
586
|
+
/* @__PURE__ */ React3__namespace.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React3__namespace.createElement(
|
|
587
|
+
Separator,
|
|
588
|
+
{
|
|
589
|
+
ItemSeparatorComponent,
|
|
590
|
+
itemKey,
|
|
591
|
+
leadingItem: renderedItemInfo.item
|
|
502
592
|
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
}
|
|
593
|
+
))
|
|
594
|
+
);
|
|
595
|
+
});
|
|
507
596
|
|
|
508
597
|
// src/components/Containers.tsx
|
|
509
598
|
var Containers = typedMemo(function Containers2({
|
|
@@ -663,6 +752,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
663
752
|
scrollAdjustHandler,
|
|
664
753
|
onLayoutHeader,
|
|
665
754
|
snapToIndices,
|
|
755
|
+
stickyIndices,
|
|
666
756
|
...rest
|
|
667
757
|
}) {
|
|
668
758
|
const ctx = useStateContext();
|
|
@@ -672,7 +762,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
672
762
|
const ScrollComponent = renderScrollComponent ? React3.useMemo(
|
|
673
763
|
() => React3__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
|
|
674
764
|
[renderScrollComponent]
|
|
675
|
-
) : reactNative.ScrollView;
|
|
765
|
+
) : reactNative.Animated.ScrollView;
|
|
676
766
|
React3__namespace.useEffect(() => {
|
|
677
767
|
if (canRender) {
|
|
678
768
|
setTimeout(() => {
|
|
@@ -725,9 +815,26 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
725
815
|
style: ListFooterComponentStyle
|
|
726
816
|
},
|
|
727
817
|
getComponent(ListFooterComponent)
|
|
728
|
-
)
|
|
818
|
+
),
|
|
819
|
+
__DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React3__namespace.createElement(DevNumbers, null)
|
|
729
820
|
);
|
|
730
821
|
});
|
|
822
|
+
var DevNumbers = __DEV__ && React3__namespace.memo(function DevNumbers2() {
|
|
823
|
+
return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React3__namespace.createElement(
|
|
824
|
+
reactNative.View,
|
|
825
|
+
{
|
|
826
|
+
key: index,
|
|
827
|
+
style: {
|
|
828
|
+
height: 100,
|
|
829
|
+
pointerEvents: "none",
|
|
830
|
+
position: "absolute",
|
|
831
|
+
top: index * 100,
|
|
832
|
+
width: "100%"
|
|
833
|
+
}
|
|
834
|
+
},
|
|
835
|
+
/* @__PURE__ */ React3__namespace.createElement(reactNative.Text, { style: { color: "red" } }, index * 100)
|
|
836
|
+
));
|
|
837
|
+
});
|
|
731
838
|
|
|
732
839
|
// src/utils/getId.ts
|
|
733
840
|
function getId(state, index) {
|
|
@@ -759,20 +866,36 @@ function calculateOffsetForIndex(ctx, state, index) {
|
|
|
759
866
|
}
|
|
760
867
|
|
|
761
868
|
// src/utils/getItemSize.ts
|
|
762
|
-
function getItemSize(state, key, index, data, useAverageSize) {
|
|
869
|
+
function getItemSize(state, key, index, data, useAverageSize, defaultAverageSize) {
|
|
870
|
+
var _a, _b;
|
|
763
871
|
const {
|
|
764
872
|
sizesKnown,
|
|
765
873
|
sizes,
|
|
766
874
|
scrollingTo,
|
|
767
|
-
|
|
875
|
+
averageSizes,
|
|
876
|
+
props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
|
|
768
877
|
} = state;
|
|
769
878
|
const sizeKnown = sizesKnown.get(key);
|
|
770
879
|
if (sizeKnown !== void 0) {
|
|
771
880
|
return sizeKnown;
|
|
772
881
|
}
|
|
773
882
|
let size;
|
|
774
|
-
|
|
775
|
-
|
|
883
|
+
const itemType = getItemType ? (_a = getItemType(data, index)) != null ? _a : "" : "";
|
|
884
|
+
if (getFixedItemSize) {
|
|
885
|
+
size = getFixedItemSize(index, data, itemType);
|
|
886
|
+
if (size !== void 0) {
|
|
887
|
+
sizesKnown.set(key, size);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
if (size === void 0 && useAverageSize && sizeKnown === void 0 && !scrollingTo) {
|
|
891
|
+
if (itemType === "") {
|
|
892
|
+
size = defaultAverageSize;
|
|
893
|
+
} else {
|
|
894
|
+
const averageSizeForType = (_b = averageSizes[itemType]) == null ? void 0 : _b.avg;
|
|
895
|
+
if (averageSizeForType !== void 0) {
|
|
896
|
+
size = roundSize(averageSizeForType);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
776
899
|
}
|
|
777
900
|
if (size === void 0) {
|
|
778
901
|
size = sizes.get(key);
|
|
@@ -781,7 +904,7 @@ function getItemSize(state, key, index, data, useAverageSize) {
|
|
|
781
904
|
}
|
|
782
905
|
}
|
|
783
906
|
if (size === void 0) {
|
|
784
|
-
size = getEstimatedItemSize ? getEstimatedItemSize(index, data) : estimatedItemSize;
|
|
907
|
+
size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
|
|
785
908
|
}
|
|
786
909
|
sizes.set(key, size);
|
|
787
910
|
return size;
|
|
@@ -800,6 +923,37 @@ function calculateOffsetWithOffsetPosition(state, offsetParam, params) {
|
|
|
800
923
|
return offset;
|
|
801
924
|
}
|
|
802
925
|
|
|
926
|
+
// src/core/finishScrollTo.ts
|
|
927
|
+
var finishScrollTo = (state) => {
|
|
928
|
+
if (state) {
|
|
929
|
+
state.scrollingTo = void 0;
|
|
930
|
+
state.scrollHistory.length = 0;
|
|
931
|
+
}
|
|
932
|
+
};
|
|
933
|
+
|
|
934
|
+
// src/core/scrollTo.ts
|
|
935
|
+
function scrollTo(state, params = {}) {
|
|
936
|
+
var _a;
|
|
937
|
+
const { animated } = params;
|
|
938
|
+
const {
|
|
939
|
+
refScroller,
|
|
940
|
+
props: { horizontal }
|
|
941
|
+
} = state;
|
|
942
|
+
const offset = calculateOffsetWithOffsetPosition(state, params.offset, params);
|
|
943
|
+
state.scrollHistory.length = 0;
|
|
944
|
+
state.scrollingTo = params;
|
|
945
|
+
state.scrollPending = offset;
|
|
946
|
+
(_a = refScroller.current) == null ? void 0 : _a.scrollTo({
|
|
947
|
+
animated: !!animated,
|
|
948
|
+
x: horizontal ? offset : 0,
|
|
949
|
+
y: horizontal ? 0 : offset
|
|
950
|
+
});
|
|
951
|
+
if (!animated) {
|
|
952
|
+
state.scroll = offset;
|
|
953
|
+
setTimeout(() => finishScrollTo(state), 100);
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
803
957
|
// src/utils/requestAdjust.ts
|
|
804
958
|
function requestAdjust(ctx, state, positionDiff) {
|
|
805
959
|
if (Math.abs(positionDiff) > 0.1) {
|
|
@@ -833,7 +987,7 @@ function requestAdjust(ctx, state, positionDiff) {
|
|
|
833
987
|
}
|
|
834
988
|
|
|
835
989
|
// src/core/prepareMVCP.ts
|
|
836
|
-
function prepareMVCP(ctx, state) {
|
|
990
|
+
function prepareMVCP(ctx, state, dataChanged) {
|
|
837
991
|
const {
|
|
838
992
|
positions,
|
|
839
993
|
scrollingTo,
|
|
@@ -862,7 +1016,13 @@ function prepareMVCP(ctx, state) {
|
|
|
862
1016
|
if (newPosition !== void 0) {
|
|
863
1017
|
const positionDiff = newPosition - prevPosition;
|
|
864
1018
|
if (Math.abs(positionDiff) > 0.1) {
|
|
865
|
-
|
|
1019
|
+
if (reactNative.Platform.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff) {
|
|
1020
|
+
scrollTo(state, {
|
|
1021
|
+
offset: state.scroll + positionDiff
|
|
1022
|
+
});
|
|
1023
|
+
} else {
|
|
1024
|
+
requestAdjust(ctx, state, positionDiff);
|
|
1025
|
+
}
|
|
866
1026
|
}
|
|
867
1027
|
}
|
|
868
1028
|
}
|
|
@@ -1004,7 +1164,7 @@ function updateAllPositions(ctx, state, dataChanged) {
|
|
|
1004
1164
|
firstFullyOnScreenIndex,
|
|
1005
1165
|
idCache,
|
|
1006
1166
|
sizesKnown,
|
|
1007
|
-
props: { snapToIndices }
|
|
1167
|
+
props: { getEstimatedItemSize, snapToIndices }
|
|
1008
1168
|
} = state;
|
|
1009
1169
|
const data = state.props.data;
|
|
1010
1170
|
const numColumns = peek$(ctx, "numColumns");
|
|
@@ -1014,6 +1174,7 @@ function updateAllPositions(ctx, state, dataChanged) {
|
|
|
1014
1174
|
indexByKey.clear();
|
|
1015
1175
|
idCache.clear();
|
|
1016
1176
|
}
|
|
1177
|
+
const useAverageSize = !getEstimatedItemSize;
|
|
1017
1178
|
const itemType = "";
|
|
1018
1179
|
let averageSize = (_a = averageSizes[itemType]) == null ? void 0 : _a.avg;
|
|
1019
1180
|
if (averageSize !== void 0) {
|
|
@@ -1029,7 +1190,7 @@ function updateAllPositions(ctx, state, dataChanged) {
|
|
|
1029
1190
|
let bailout = false;
|
|
1030
1191
|
for (let i = firstFullyOnScreenIndex - 1; i >= 0; i--) {
|
|
1031
1192
|
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);
|
|
1193
|
+
const size = (_c = sizesKnown.get(id)) != null ? _c : getItemSize(state, id, i, data[i], useAverageSize, averageSize);
|
|
1033
1194
|
const itemColumn = columns.get(id);
|
|
1034
1195
|
maxSizeInRow2 = Math.max(maxSizeInRow2, size);
|
|
1035
1196
|
if (itemColumn === 1) {
|
|
@@ -1056,7 +1217,7 @@ function updateAllPositions(ctx, state, dataChanged) {
|
|
|
1056
1217
|
const dataLength = data.length;
|
|
1057
1218
|
for (let i = 0; i < dataLength; i++) {
|
|
1058
1219
|
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);
|
|
1220
|
+
const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(state, id, i, data[i], useAverageSize, averageSize);
|
|
1060
1221
|
if (__DEV__ && needsIndexByKey) {
|
|
1061
1222
|
if (indexByKeyForChecking.has(id)) {
|
|
1062
1223
|
console.error(
|
|
@@ -1295,35 +1456,84 @@ function checkAllSizesKnown(state) {
|
|
|
1295
1456
|
}
|
|
1296
1457
|
|
|
1297
1458
|
// src/utils/findAvailableContainers.ts
|
|
1298
|
-
function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval) {
|
|
1459
|
+
function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
|
|
1299
1460
|
const numContainers = peek$(ctx, "numContainers");
|
|
1461
|
+
const { stickyIndicesSet } = state.props;
|
|
1300
1462
|
const result = [];
|
|
1301
1463
|
const availableContainers = [];
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
if (!
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1464
|
+
const stickyItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => stickyIndicesSet.has(index))) || [];
|
|
1465
|
+
const nonStickyItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => !stickyIndicesSet.has(index))) || [];
|
|
1466
|
+
const canReuseContainer = (containerIndex, requiredType) => {
|
|
1467
|
+
if (!requiredType) return true;
|
|
1468
|
+
const existingType = state.containerItemTypes.get(containerIndex);
|
|
1469
|
+
if (!existingType) return true;
|
|
1470
|
+
return existingType === requiredType;
|
|
1471
|
+
};
|
|
1472
|
+
const neededTypes = requiredItemTypes ? [...requiredItemTypes] : [];
|
|
1473
|
+
let typeIndex = 0;
|
|
1474
|
+
for (let i = 0; i < stickyItemIndices.length; i++) {
|
|
1475
|
+
const requiredType = neededTypes[typeIndex];
|
|
1476
|
+
let foundContainer = false;
|
|
1477
|
+
for (const containerIndex of state.stickyContainerPool) {
|
|
1478
|
+
const key = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1479
|
+
const isPendingRemoval = pendingRemoval.includes(containerIndex);
|
|
1480
|
+
if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType)) {
|
|
1481
|
+
result.push(containerIndex);
|
|
1482
|
+
if (isPendingRemoval) {
|
|
1483
|
+
const index = pendingRemoval.indexOf(containerIndex);
|
|
1484
|
+
pendingRemoval.splice(index, 1);
|
|
1485
|
+
}
|
|
1486
|
+
foundContainer = true;
|
|
1487
|
+
if (requiredItemTypes) typeIndex++;
|
|
1488
|
+
break;
|
|
1310
1489
|
}
|
|
1311
1490
|
}
|
|
1312
|
-
if (
|
|
1313
|
-
result.
|
|
1314
|
-
|
|
1315
|
-
|
|
1491
|
+
if (!foundContainer) {
|
|
1492
|
+
const newContainerIndex = numContainers + result.filter((index) => index >= numContainers).length;
|
|
1493
|
+
result.push(newContainerIndex);
|
|
1494
|
+
state.stickyContainerPool.add(newContainerIndex);
|
|
1495
|
+
if (requiredItemTypes) typeIndex++;
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
if (nonStickyItemIndices.length > 0) {
|
|
1499
|
+
for (let u = 0; u < numContainers; u++) {
|
|
1500
|
+
if (state.stickyContainerPool.has(u)) {
|
|
1501
|
+
continue;
|
|
1502
|
+
}
|
|
1503
|
+
const key = peek$(ctx, `containerItemKey${u}`);
|
|
1504
|
+
let isOk = key === void 0;
|
|
1505
|
+
if (!isOk) {
|
|
1506
|
+
const index = pendingRemoval.indexOf(u);
|
|
1507
|
+
if (index !== -1) {
|
|
1508
|
+
pendingRemoval.splice(index, 1);
|
|
1509
|
+
const requiredType = neededTypes[typeIndex];
|
|
1510
|
+
isOk = canReuseContainer(u, requiredType);
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
if (isOk) {
|
|
1514
|
+
result.push(u);
|
|
1515
|
+
if (requiredItemTypes) {
|
|
1516
|
+
typeIndex++;
|
|
1517
|
+
}
|
|
1518
|
+
if (result.length >= numNeeded) {
|
|
1519
|
+
return result;
|
|
1520
|
+
}
|
|
1316
1521
|
}
|
|
1317
1522
|
}
|
|
1318
1523
|
}
|
|
1319
1524
|
for (let u = 0; u < numContainers; u++) {
|
|
1525
|
+
if (state.stickyContainerPool.has(u)) {
|
|
1526
|
+
continue;
|
|
1527
|
+
}
|
|
1320
1528
|
const key = peek$(ctx, `containerItemKey${u}`);
|
|
1321
1529
|
if (key === void 0) continue;
|
|
1322
1530
|
const index = state.indexByKey.get(key);
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1531
|
+
const isOutOfView = index < startBuffered || index > endBuffered;
|
|
1532
|
+
if (isOutOfView) {
|
|
1533
|
+
const distance = index < startBuffered ? startBuffered - index : index - endBuffered;
|
|
1534
|
+
if (!requiredItemTypes || typeIndex < neededTypes.length && canReuseContainer(u, neededTypes[typeIndex])) {
|
|
1535
|
+
availableContainers.push({ distance, index: u });
|
|
1536
|
+
}
|
|
1327
1537
|
}
|
|
1328
1538
|
}
|
|
1329
1539
|
const remaining = numNeeded - result.length;
|
|
@@ -1335,6 +1545,9 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1335
1545
|
}
|
|
1336
1546
|
for (const container of availableContainers) {
|
|
1337
1547
|
result.push(container.index);
|
|
1548
|
+
if (requiredItemTypes) {
|
|
1549
|
+
typeIndex++;
|
|
1550
|
+
}
|
|
1338
1551
|
}
|
|
1339
1552
|
}
|
|
1340
1553
|
const stillNeeded = numNeeded - result.length;
|
|
@@ -1363,37 +1576,6 @@ function comparatorByDistance(a, b) {
|
|
|
1363
1576
|
return b.distance - a.distance;
|
|
1364
1577
|
}
|
|
1365
1578
|
|
|
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
1579
|
// src/core/scrollToIndex.ts
|
|
1398
1580
|
function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
|
|
1399
1581
|
if (index >= state.props.data.length) {
|
|
@@ -1481,16 +1663,90 @@ function setDidLayout(ctx, state) {
|
|
|
1481
1663
|
} = state;
|
|
1482
1664
|
state.queuedInitialLayout = true;
|
|
1483
1665
|
checkAtBottom(ctx, state);
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1666
|
+
const setIt = () => {
|
|
1667
|
+
set$(ctx, "containersDidLayout", true);
|
|
1668
|
+
if (onLoad) {
|
|
1669
|
+
onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
|
|
1670
|
+
}
|
|
1671
|
+
};
|
|
1672
|
+
if (reactNative.Platform.OS === "android" || !IsNewArchitecture) {
|
|
1673
|
+
if (initialScroll) {
|
|
1674
|
+
queueMicrotask(() => {
|
|
1675
|
+
scrollToIndex(ctx, state, { ...initialScroll, animated: false });
|
|
1676
|
+
requestAnimationFrame(() => {
|
|
1677
|
+
scrollToIndex(ctx, state, { ...initialScroll, animated: false });
|
|
1678
|
+
setIt();
|
|
1679
|
+
});
|
|
1680
|
+
});
|
|
1681
|
+
} else {
|
|
1682
|
+
queueMicrotask(setIt);
|
|
1683
|
+
}
|
|
1684
|
+
} else {
|
|
1685
|
+
setIt();
|
|
1490
1686
|
}
|
|
1491
1687
|
}
|
|
1492
1688
|
|
|
1493
1689
|
// src/core/calculateItemsInView.ts
|
|
1690
|
+
function findCurrentStickyIndex(stickyArray, scroll, state) {
|
|
1691
|
+
var _a;
|
|
1692
|
+
for (let i = stickyArray.length - 1; i >= 0; i--) {
|
|
1693
|
+
const stickyId = (_a = state.idCache.get(stickyArray[i])) != null ? _a : getId(state, stickyArray[i]);
|
|
1694
|
+
const stickyPos = stickyId ? state.positions.get(stickyId) : void 0;
|
|
1695
|
+
if (stickyPos !== void 0 && scroll >= stickyPos) {
|
|
1696
|
+
return i;
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
return -1;
|
|
1700
|
+
}
|
|
1701
|
+
function getActiveStickyIndices(ctx, state, stickyIndices) {
|
|
1702
|
+
return new Set(
|
|
1703
|
+
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))
|
|
1704
|
+
);
|
|
1705
|
+
}
|
|
1706
|
+
function handleStickyActivation(ctx, state, stickyIndices, stickyArray, scroll, needNewContainers, startBuffered, endBuffered) {
|
|
1707
|
+
var _a;
|
|
1708
|
+
const activeIndices = getActiveStickyIndices(ctx, state, stickyIndices);
|
|
1709
|
+
const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
|
|
1710
|
+
for (let offset = 0; offset <= 1; offset++) {
|
|
1711
|
+
const idx = currentStickyIdx - offset;
|
|
1712
|
+
if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
|
|
1713
|
+
const stickyIndex = stickyArray[idx];
|
|
1714
|
+
const stickyId = (_a = state.idCache.get(stickyIndex)) != null ? _a : getId(state, stickyIndex);
|
|
1715
|
+
if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered)) {
|
|
1716
|
+
needNewContainers.push(stickyIndex);
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, pendingRemoval) {
|
|
1721
|
+
var _a, _b, _c;
|
|
1722
|
+
const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
|
|
1723
|
+
for (const containerIndex of state.stickyContainerPool) {
|
|
1724
|
+
const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1725
|
+
const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
|
|
1726
|
+
if (itemIndex === void 0) continue;
|
|
1727
|
+
const arrayIdx = stickyArray.indexOf(itemIndex);
|
|
1728
|
+
if (arrayIdx === -1) continue;
|
|
1729
|
+
const isRecentSticky = arrayIdx >= currentStickyIdx - 1 && arrayIdx <= currentStickyIdx + 1;
|
|
1730
|
+
if (isRecentSticky) continue;
|
|
1731
|
+
const nextIndex = stickyArray[arrayIdx + 1];
|
|
1732
|
+
let shouldRecycle = false;
|
|
1733
|
+
if (nextIndex) {
|
|
1734
|
+
const nextId = (_a = state.idCache.get(nextIndex)) != null ? _a : getId(state, nextIndex);
|
|
1735
|
+
const nextPos = nextId ? state.positions.get(nextId) : void 0;
|
|
1736
|
+
shouldRecycle = nextPos !== void 0 && scroll > nextPos + scrollBuffer * 2;
|
|
1737
|
+
} else {
|
|
1738
|
+
const currentId = (_b = state.idCache.get(itemIndex)) != null ? _b : getId(state, itemIndex);
|
|
1739
|
+
if (currentId) {
|
|
1740
|
+
const currentPos = state.positions.get(currentId);
|
|
1741
|
+
const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(state, currentId, itemIndex, state.props.data[itemIndex]);
|
|
1742
|
+
shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
if (shouldRecycle) {
|
|
1746
|
+
pendingRemoval.push(containerIndex);
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1494
1750
|
function calculateItemsInView(ctx, state, params = {}) {
|
|
1495
1751
|
reactNative.unstable_batchedUpdates(() => {
|
|
1496
1752
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
@@ -1507,7 +1763,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1507
1763
|
enableScrollForNextCalculateItemsInView,
|
|
1508
1764
|
minIndexSizeChanged
|
|
1509
1765
|
} = state;
|
|
1510
|
-
const data = state.props
|
|
1766
|
+
const { data, stickyIndicesArr, stickyIndicesSet } = state.props;
|
|
1511
1767
|
const prevNumContainers = peek$(ctx, "numContainers");
|
|
1512
1768
|
if (!data || scrollLength === 0 || !prevNumContainers) {
|
|
1513
1769
|
return;
|
|
@@ -1519,7 +1775,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1519
1775
|
const { dataChanged, doMVCP } = params;
|
|
1520
1776
|
const speed = getScrollVelocity(state);
|
|
1521
1777
|
if (doMVCP || dataChanged) {
|
|
1522
|
-
const checkMVCP = doMVCP ? prepareMVCP(ctx, state) : void 0;
|
|
1778
|
+
const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
|
|
1523
1779
|
updateAllPositions(ctx, state, dataChanged);
|
|
1524
1780
|
checkMVCP == null ? void 0 : checkMVCP();
|
|
1525
1781
|
}
|
|
@@ -1669,14 +1925,23 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1669
1925
|
needNewContainers.push(i);
|
|
1670
1926
|
}
|
|
1671
1927
|
}
|
|
1928
|
+
if (stickyIndicesArr.length > 0) {
|
|
1929
|
+
handleStickyActivation(ctx, state, stickyIndicesSet, stickyIndicesArr, scroll, needNewContainers, startBuffered, endBuffered);
|
|
1930
|
+
}
|
|
1672
1931
|
if (needNewContainers.length > 0) {
|
|
1932
|
+
const requiredItemTypes = state.props.getItemType ? needNewContainers.map((i) => {
|
|
1933
|
+
const itemType = state.props.getItemType(data[i], i);
|
|
1934
|
+
return itemType ? String(itemType) : "";
|
|
1935
|
+
}) : void 0;
|
|
1673
1936
|
const availableContainers = findAvailableContainers(
|
|
1674
1937
|
ctx,
|
|
1675
1938
|
state,
|
|
1676
1939
|
needNewContainers.length,
|
|
1677
1940
|
startBuffered,
|
|
1678
1941
|
endBuffered,
|
|
1679
|
-
pendingRemoval
|
|
1942
|
+
pendingRemoval,
|
|
1943
|
+
requiredItemTypes,
|
|
1944
|
+
needNewContainers
|
|
1680
1945
|
);
|
|
1681
1946
|
for (let idx = 0; idx < needNewContainers.length; idx++) {
|
|
1682
1947
|
const i = needNewContainers[idx];
|
|
@@ -1688,7 +1953,18 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1688
1953
|
}
|
|
1689
1954
|
set$(ctx, `containerItemKey${containerIndex}`, id);
|
|
1690
1955
|
set$(ctx, `containerItemData${containerIndex}`, data[i]);
|
|
1956
|
+
if (requiredItemTypes) {
|
|
1957
|
+
state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
|
|
1958
|
+
}
|
|
1691
1959
|
containerItemKeys.add(id);
|
|
1960
|
+
if (stickyIndicesSet.has(i)) {
|
|
1961
|
+
set$(ctx, `containerSticky${containerIndex}`, true);
|
|
1962
|
+
const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
1963
|
+
set$(ctx, `containerStickyOffset${containerIndex}`, new reactNative.Animated.Value(topPadding));
|
|
1964
|
+
state.stickyContainerPool.add(containerIndex);
|
|
1965
|
+
} else {
|
|
1966
|
+
state.stickyContainerPool.delete(containerIndex);
|
|
1967
|
+
}
|
|
1692
1968
|
if (containerIndex >= numContainers2) {
|
|
1693
1969
|
numContainers2 = containerIndex + 1;
|
|
1694
1970
|
}
|
|
@@ -1701,12 +1977,21 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1701
1977
|
}
|
|
1702
1978
|
}
|
|
1703
1979
|
}
|
|
1980
|
+
if (stickyIndicesArr.length > 0) {
|
|
1981
|
+
handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, pendingRemoval);
|
|
1982
|
+
}
|
|
1704
1983
|
for (let i = 0; i < numContainers; i++) {
|
|
1705
1984
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1706
1985
|
if (pendingRemoval.includes(i)) {
|
|
1707
1986
|
if (itemKey) {
|
|
1708
1987
|
containerItemKeys.delete(itemKey);
|
|
1709
1988
|
}
|
|
1989
|
+
state.containerItemTypes.delete(i);
|
|
1990
|
+
if (state.stickyContainerPool.has(i)) {
|
|
1991
|
+
set$(ctx, `containerSticky${i}`, false);
|
|
1992
|
+
set$(ctx, `containerStickyOffset${i}`, void 0);
|
|
1993
|
+
state.stickyContainerPool.delete(i);
|
|
1994
|
+
}
|
|
1710
1995
|
set$(ctx, `containerItemKey${i}`, void 0);
|
|
1711
1996
|
set$(ctx, `containerItemData${i}`, void 0);
|
|
1712
1997
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
@@ -1757,10 +2042,14 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1757
2042
|
|
|
1758
2043
|
// src/core/doInitialAllocateContainers.ts
|
|
1759
2044
|
function doInitialAllocateContainers(ctx, state) {
|
|
1760
|
-
|
|
2045
|
+
var _a;
|
|
2046
|
+
const {
|
|
2047
|
+
scrollLength,
|
|
2048
|
+
props: { getItemType }
|
|
2049
|
+
} = state;
|
|
1761
2050
|
const data = state.props.data;
|
|
1762
2051
|
if (scrollLength > 0 && data.length > 0 && !peek$(ctx, "numContainers")) {
|
|
1763
|
-
const averageItemSize = state.props.getEstimatedItemSize ? state.props.getEstimatedItemSize(0, data[0]) : state.props.estimatedItemSize;
|
|
2052
|
+
const averageItemSize = state.props.getEstimatedItemSize ? state.props.getEstimatedItemSize(0, data[0], getItemType ? (_a = getItemType(data[0], 0)) != null ? _a : "" : "") : state.props.estimatedItemSize;
|
|
1764
2053
|
const Extra = 1.5;
|
|
1765
2054
|
const numContainers = Math.ceil(
|
|
1766
2055
|
(scrollLength + state.props.scrollBuffer * 2) / averageItemSize * state.props.numColumns * Extra
|
|
@@ -1797,16 +2086,18 @@ function doMaintainScrollAtEnd(ctx, state, animated) {
|
|
|
1797
2086
|
}
|
|
1798
2087
|
requestAnimationFrame(() => {
|
|
1799
2088
|
var _a;
|
|
1800
|
-
state.
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
(
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
2089
|
+
if (state == null ? void 0 : state.isAtEnd) {
|
|
2090
|
+
state.maintainingScrollAtEnd = true;
|
|
2091
|
+
(_a = refScroller.current) == null ? void 0 : _a.scrollToEnd({
|
|
2092
|
+
animated
|
|
2093
|
+
});
|
|
2094
|
+
setTimeout(
|
|
2095
|
+
() => {
|
|
2096
|
+
state.maintainingScrollAtEnd = false;
|
|
2097
|
+
},
|
|
2098
|
+
0
|
|
2099
|
+
);
|
|
2100
|
+
}
|
|
1810
2101
|
});
|
|
1811
2102
|
return true;
|
|
1812
2103
|
}
|
|
@@ -2026,7 +2317,22 @@ function updateItemSizes(ctx, state, itemUpdates) {
|
|
|
2026
2317
|
}
|
|
2027
2318
|
}
|
|
2028
2319
|
function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
2029
|
-
|
|
2320
|
+
var _a;
|
|
2321
|
+
const {
|
|
2322
|
+
queuedItemSizeUpdates,
|
|
2323
|
+
queuedItemSizeUpdatesWaiting,
|
|
2324
|
+
sizesKnown,
|
|
2325
|
+
props: { getFixedItemSize, getItemType }
|
|
2326
|
+
} = state;
|
|
2327
|
+
if (getFixedItemSize) {
|
|
2328
|
+
const index = state.indexByKey.get(itemKey);
|
|
2329
|
+
const itemData = state.props.data[index];
|
|
2330
|
+
const type = getItemType ? (_a = getItemType(itemData, index)) != null ? _a : "" : "";
|
|
2331
|
+
const size = getFixedItemSize(index, itemData, type);
|
|
2332
|
+
if (size !== void 0 && size === sizesKnown.get(itemKey)) {
|
|
2333
|
+
return;
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2030
2336
|
const containersDidLayout = peek$(ctx, "containersDidLayout");
|
|
2031
2337
|
if (!containersDidLayout || !queuedItemSizeUpdatesWaiting) {
|
|
2032
2338
|
updateItemSizes(ctx, state, [{ itemKey, sizeObj }]);
|
|
@@ -2043,25 +2349,28 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
2043
2349
|
}
|
|
2044
2350
|
}
|
|
2045
2351
|
function updateOneItemSize(state, itemKey, sizeObj) {
|
|
2352
|
+
var _a;
|
|
2046
2353
|
const {
|
|
2047
2354
|
sizes,
|
|
2048
2355
|
indexByKey,
|
|
2049
2356
|
sizesKnown,
|
|
2050
2357
|
averageSizes,
|
|
2051
|
-
props: { data, horizontal }
|
|
2358
|
+
props: { data, horizontal, getEstimatedItemSize, getItemType }
|
|
2052
2359
|
} = state;
|
|
2053
2360
|
if (!data) return 0;
|
|
2054
2361
|
const index = indexByKey.get(itemKey);
|
|
2055
2362
|
const prevSize = getItemSize(state, itemKey, index, data);
|
|
2056
2363
|
const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
|
|
2057
2364
|
sizesKnown.set(itemKey, size);
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
averages
|
|
2365
|
+
if (!getEstimatedItemSize) {
|
|
2366
|
+
const itemType = getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : "";
|
|
2367
|
+
let averages = averageSizes[itemType];
|
|
2368
|
+
if (!averages) {
|
|
2369
|
+
averages = averageSizes[itemType] = { avg: 0, num: 0 };
|
|
2370
|
+
}
|
|
2371
|
+
averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
|
|
2372
|
+
averages.num++;
|
|
2062
2373
|
}
|
|
2063
|
-
averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
|
|
2064
|
-
averages.num++;
|
|
2065
2374
|
if (!prevSize || Math.abs(prevSize - size) > 0.1) {
|
|
2066
2375
|
sizes.set(itemKey, size);
|
|
2067
2376
|
return size - prevSize;
|
|
@@ -2099,12 +2408,13 @@ function createColumnWrapperStyle(contentContainerStyle) {
|
|
|
2099
2408
|
}
|
|
2100
2409
|
}
|
|
2101
2410
|
function getRenderedItem(ctx, state, key) {
|
|
2411
|
+
var _a;
|
|
2102
2412
|
if (!state) {
|
|
2103
2413
|
return null;
|
|
2104
2414
|
}
|
|
2105
2415
|
const {
|
|
2106
2416
|
indexByKey,
|
|
2107
|
-
props: { data, renderItem: renderItem2 }
|
|
2417
|
+
props: { data, getItemType, renderItem: renderItem2 }
|
|
2108
2418
|
} = state;
|
|
2109
2419
|
const index = indexByKey.get(key);
|
|
2110
2420
|
if (index === void 0) {
|
|
@@ -2115,7 +2425,8 @@ function getRenderedItem(ctx, state, key) {
|
|
|
2115
2425
|
const itemProps = {
|
|
2116
2426
|
extraData: peek$(ctx, "extraData"),
|
|
2117
2427
|
index,
|
|
2118
|
-
item: data[index]
|
|
2428
|
+
item: data[index],
|
|
2429
|
+
type: getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : ""
|
|
2119
2430
|
};
|
|
2120
2431
|
renderedItem = React3__namespace.default.createElement(renderItem2, itemProps);
|
|
2121
2432
|
}
|
|
@@ -2131,49 +2442,52 @@ var LegendList = typedForwardRef(function LegendList2(props, forwardedRef) {
|
|
|
2131
2442
|
var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
|
|
2132
2443
|
var _a;
|
|
2133
2444
|
const {
|
|
2445
|
+
alignItemsAtEnd = false,
|
|
2446
|
+
columnWrapperStyle,
|
|
2447
|
+
contentContainerStyle: contentContainerStyleProp,
|
|
2134
2448
|
data: dataProp = [],
|
|
2449
|
+
drawDistance = 250,
|
|
2450
|
+
estimatedItemSize: estimatedItemSizeProp,
|
|
2451
|
+
estimatedListSize,
|
|
2452
|
+
extraData,
|
|
2453
|
+
getEstimatedItemSize,
|
|
2454
|
+
getFixedItemSize,
|
|
2455
|
+
getItemType,
|
|
2456
|
+
horizontal,
|
|
2457
|
+
initialContainerPoolRatio = 2,
|
|
2135
2458
|
initialScrollIndex: initialScrollIndexProp,
|
|
2136
2459
|
initialScrollOffset,
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
onEndReachedThreshold = 0.5,
|
|
2141
|
-
onStartReachedThreshold = 0.5,
|
|
2460
|
+
keyExtractor: keyExtractorProp,
|
|
2461
|
+
ListEmptyComponent,
|
|
2462
|
+
ListHeaderComponent,
|
|
2142
2463
|
maintainScrollAtEnd = false,
|
|
2143
2464
|
maintainScrollAtEndThreshold = 0.1,
|
|
2144
|
-
alignItemsAtEnd = false,
|
|
2145
2465
|
maintainVisibleContentPosition = false,
|
|
2146
|
-
onScroll: onScrollProp,
|
|
2147
|
-
onMomentumScrollEnd,
|
|
2148
2466
|
numColumns: numColumnsProp = 1,
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
renderItem: renderItem2,
|
|
2152
|
-
estimatedListSize,
|
|
2153
|
-
estimatedItemSize: estimatedItemSizeProp,
|
|
2154
|
-
getEstimatedItemSize,
|
|
2155
|
-
suggestEstimatedItemSize,
|
|
2156
|
-
ListHeaderComponent,
|
|
2157
|
-
ListEmptyComponent,
|
|
2467
|
+
onEndReached,
|
|
2468
|
+
onEndReachedThreshold = 0.5,
|
|
2158
2469
|
onItemSizeChanged,
|
|
2159
|
-
refScrollView,
|
|
2160
|
-
waitForInitialLayout = true,
|
|
2161
|
-
extraData,
|
|
2162
|
-
contentContainerStyle: contentContainerStyleProp,
|
|
2163
|
-
style: styleProp,
|
|
2164
2470
|
onLayout: onLayoutProp,
|
|
2471
|
+
onLoad,
|
|
2472
|
+
onMomentumScrollEnd,
|
|
2165
2473
|
onRefresh,
|
|
2166
|
-
|
|
2474
|
+
onScroll: onScrollProp,
|
|
2475
|
+
onStartReached,
|
|
2476
|
+
onStartReachedThreshold = 0.5,
|
|
2477
|
+
onViewableItemsChanged,
|
|
2167
2478
|
progressViewOffset,
|
|
2479
|
+
recycleItems = false,
|
|
2168
2480
|
refreshControl,
|
|
2169
|
-
|
|
2481
|
+
refreshing,
|
|
2482
|
+
refScrollView,
|
|
2483
|
+
renderItem: renderItem2,
|
|
2484
|
+
snapToIndices,
|
|
2485
|
+
stickyIndices,
|
|
2486
|
+
style: styleProp,
|
|
2487
|
+
suggestEstimatedItemSize,
|
|
2170
2488
|
viewabilityConfig,
|
|
2171
2489
|
viewabilityConfigCallbackPairs,
|
|
2172
|
-
|
|
2173
|
-
onViewableItemsChanged,
|
|
2174
|
-
onStartReached,
|
|
2175
|
-
onEndReached,
|
|
2176
|
-
onLoad,
|
|
2490
|
+
waitForInitialLayout = true,
|
|
2177
2491
|
...rest
|
|
2178
2492
|
} = props;
|
|
2179
2493
|
const [renderNum, setRenderNum] = React3.useState(0);
|
|
@@ -2195,9 +2509,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2195
2509
|
if (!refState.current) {
|
|
2196
2510
|
const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { height: 0, width: 0 } : reactNative.Dimensions.get("window"))[horizontal ? "width" : "height"];
|
|
2197
2511
|
refState.current = {
|
|
2512
|
+
activeStickyIndex: void 0,
|
|
2198
2513
|
averageSizes: {},
|
|
2199
2514
|
columns: /* @__PURE__ */ new Map(),
|
|
2200
2515
|
containerItemKeys: /* @__PURE__ */ new Set(),
|
|
2516
|
+
containerItemTypes: /* @__PURE__ */ new Map(),
|
|
2201
2517
|
enableScrollForNextCalculateItemsInView: true,
|
|
2202
2518
|
endBuffered: -1,
|
|
2203
2519
|
endNoBuffer: -1,
|
|
@@ -2236,6 +2552,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2236
2552
|
startBuffered: -1,
|
|
2237
2553
|
startNoBuffer: -1,
|
|
2238
2554
|
startReachedBlockedByTimer: false,
|
|
2555
|
+
stickyContainerPool: /* @__PURE__ */ new Set(),
|
|
2556
|
+
stickyContainers: /* @__PURE__ */ new Map(),
|
|
2239
2557
|
timeoutSizeMessage: 0,
|
|
2240
2558
|
timeouts: /* @__PURE__ */ new Set(),
|
|
2241
2559
|
totalSize: 0,
|
|
@@ -2252,6 +2570,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2252
2570
|
data: dataProp,
|
|
2253
2571
|
estimatedItemSize,
|
|
2254
2572
|
getEstimatedItemSize,
|
|
2573
|
+
getFixedItemSize,
|
|
2574
|
+
getItemType,
|
|
2255
2575
|
horizontal: !!horizontal,
|
|
2256
2576
|
initialContainerPoolRatio,
|
|
2257
2577
|
initialScroll,
|
|
@@ -2267,9 +2587,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2267
2587
|
onScroll: onScrollProp,
|
|
2268
2588
|
onStartReached,
|
|
2269
2589
|
onStartReachedThreshold,
|
|
2590
|
+
recycleItems: !!recycleItems,
|
|
2270
2591
|
renderItem: renderItem2,
|
|
2271
2592
|
scrollBuffer,
|
|
2272
2593
|
snapToIndices,
|
|
2594
|
+
stickyIndicesArr: stickyIndices != null ? stickyIndices : [],
|
|
2595
|
+
stickyIndicesSet: React3.useMemo(() => new Set(stickyIndices), [stickyIndices]),
|
|
2273
2596
|
stylePaddingBottom: stylePaddingBottomState,
|
|
2274
2597
|
stylePaddingTop: stylePaddingTopState,
|
|
2275
2598
|
suggestEstimatedItemSize: !!suggestEstimatedItemSize
|
|
@@ -2507,6 +2830,16 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2507
2830
|
}),
|
|
2508
2831
|
[]
|
|
2509
2832
|
);
|
|
2833
|
+
const animatedScrollHandler = React3.useMemo(() => {
|
|
2834
|
+
if (stickyIndices == null ? void 0 : stickyIndices.length) {
|
|
2835
|
+
const { animatedScrollY } = ctx;
|
|
2836
|
+
return reactNative.Animated.event([{ nativeEvent: { contentOffset: { [horizontal ? "x" : "y"]: animatedScrollY } } }], {
|
|
2837
|
+
listener: fns.onScroll,
|
|
2838
|
+
useNativeDriver: true
|
|
2839
|
+
});
|
|
2840
|
+
}
|
|
2841
|
+
return fns.onScroll;
|
|
2842
|
+
}, [stickyIndices, horizontal, onScroll]);
|
|
2510
2843
|
return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement(
|
|
2511
2844
|
ListComponent,
|
|
2512
2845
|
{
|
|
@@ -2523,14 +2856,20 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2523
2856
|
onLayout,
|
|
2524
2857
|
onLayoutHeader,
|
|
2525
2858
|
onMomentumScrollEnd: (event) => {
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2859
|
+
if (IsNewArchitecture) {
|
|
2860
|
+
requestAnimationFrame(() => {
|
|
2861
|
+
finishScrollTo(refState.current);
|
|
2862
|
+
});
|
|
2863
|
+
} else {
|
|
2864
|
+
setTimeout(() => {
|
|
2865
|
+
finishScrollTo(refState.current);
|
|
2866
|
+
}, 1e3);
|
|
2867
|
+
}
|
|
2529
2868
|
if (onMomentumScrollEnd) {
|
|
2530
2869
|
onMomentumScrollEnd(event);
|
|
2531
2870
|
}
|
|
2532
2871
|
},
|
|
2533
|
-
onScroll:
|
|
2872
|
+
onScroll: animatedScrollHandler,
|
|
2534
2873
|
recycleItems,
|
|
2535
2874
|
refreshControl: refreshControl ? stylePaddingTopState > 0 ? React3__namespace.cloneElement(refreshControl, {
|
|
2536
2875
|
progressViewOffset: (refreshControl.props.progressViewOffset || 0) + stylePaddingTopState
|
|
@@ -2546,6 +2885,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2546
2885
|
scrollAdjustHandler: (_a = refState.current) == null ? void 0 : _a.scrollAdjustHandler,
|
|
2547
2886
|
scrollEventThrottle: reactNative.Platform.OS === "web" ? 16 : void 0,
|
|
2548
2887
|
snapToIndices,
|
|
2888
|
+
stickyIndices,
|
|
2549
2889
|
style,
|
|
2550
2890
|
updateItemSize: fns.updateItemSize,
|
|
2551
2891
|
waitForInitialLayout
|