@legendapp/list 2.0.9 → 2.0.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/CHANGELOG.md +11 -0
- package/index.d.mts +10 -2
- package/index.d.ts +10 -2
- package/index.js +256 -179
- package/index.mjs +257 -180
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -182,11 +182,6 @@ function useInterval(callback, delay) {
|
|
|
182
182
|
return () => clearInterval(interval);
|
|
183
183
|
}, [delay]);
|
|
184
184
|
}
|
|
185
|
-
var LeanViewComponent = React2__namespace.forwardRef((props, ref) => {
|
|
186
|
-
return React2__namespace.createElement("RCTView", { ...props, ref });
|
|
187
|
-
});
|
|
188
|
-
LeanViewComponent.displayName = "RCTView";
|
|
189
|
-
var LeanView = reactNative.Platform.OS === "android" || reactNative.Platform.OS === "ios" ? LeanViewComponent : reactNative.View;
|
|
190
185
|
|
|
191
186
|
// src/constants.ts
|
|
192
187
|
var POSITION_OUT_OF_VIEW = -1e7;
|
|
@@ -248,7 +243,7 @@ var PositionViewState = typedMemo(function PositionView({
|
|
|
248
243
|
}) {
|
|
249
244
|
const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
|
|
250
245
|
return /* @__PURE__ */ React2__namespace.createElement(
|
|
251
|
-
|
|
246
|
+
reactNative.View,
|
|
252
247
|
{
|
|
253
248
|
ref: refView,
|
|
254
249
|
style: [
|
|
@@ -289,7 +284,7 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
|
289
284
|
}) {
|
|
290
285
|
const [position = POSITION_OUT_OF_VIEW, headerSize] = useArr$([`containerPosition${id}`, "headerSize"]);
|
|
291
286
|
const transform = React2__namespace.useMemo(() => {
|
|
292
|
-
if (animatedScrollY && stickyOffset) {
|
|
287
|
+
if (animatedScrollY && stickyOffset !== void 0) {
|
|
293
288
|
const stickyPosition = animatedScrollY.interpolate({
|
|
294
289
|
extrapolate: "clamp",
|
|
295
290
|
inputRange: [position + headerSize, position + 5e3 + headerSize],
|
|
@@ -454,6 +449,29 @@ function Separator({ ItemSeparatorComponent, leadingItem }) {
|
|
|
454
449
|
const isLastItem = useIsLastItem();
|
|
455
450
|
return isLastItem ? null : /* @__PURE__ */ React2__namespace.createElement(ItemSeparatorComponent, { leadingItem });
|
|
456
451
|
}
|
|
452
|
+
function useOnLayoutSync({
|
|
453
|
+
ref,
|
|
454
|
+
onLayoutProp,
|
|
455
|
+
onLayoutChange
|
|
456
|
+
}, deps = []) {
|
|
457
|
+
const onLayout = React2.useCallback(
|
|
458
|
+
(event) => {
|
|
459
|
+
onLayoutChange(event.nativeEvent.layout, false);
|
|
460
|
+
onLayoutProp == null ? void 0 : onLayoutProp(event);
|
|
461
|
+
},
|
|
462
|
+
[onLayoutChange]
|
|
463
|
+
);
|
|
464
|
+
if (IsNewArchitecture) {
|
|
465
|
+
React2.useLayoutEffect(() => {
|
|
466
|
+
if (ref.current) {
|
|
467
|
+
ref.current.measure((x, y, width, height) => {
|
|
468
|
+
onLayoutChange({ height, width, x, y }, true);
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
}, deps);
|
|
472
|
+
}
|
|
473
|
+
return { onLayout };
|
|
474
|
+
}
|
|
457
475
|
|
|
458
476
|
// src/components/Container.tsx
|
|
459
477
|
var Container = typedMemo(function Container2({
|
|
@@ -480,7 +498,7 @@ var Container = typedMemo(function Container2({
|
|
|
480
498
|
const [layoutRenderCount, forceLayoutRender] = React2.useState(0);
|
|
481
499
|
const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
|
|
482
500
|
const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
|
|
483
|
-
|
|
501
|
+
const didLayoutRef = React2.useRef(false);
|
|
484
502
|
const style = React2.useMemo(() => {
|
|
485
503
|
let paddingStyles;
|
|
486
504
|
if (columnWrapperStyle) {
|
|
@@ -530,15 +548,16 @@ var Container = typedMemo(function Container2({
|
|
|
530
548
|
value: data
|
|
531
549
|
};
|
|
532
550
|
}, [id, itemKey, index, data]);
|
|
533
|
-
const
|
|
551
|
+
const onLayoutChange = (rectangle) => {
|
|
534
552
|
var _a, _b;
|
|
535
553
|
if (!isNullOrUndefined(itemKey)) {
|
|
536
|
-
|
|
537
|
-
let layout =
|
|
538
|
-
const size =
|
|
554
|
+
didLayoutRef.current = true;
|
|
555
|
+
let layout = rectangle;
|
|
556
|
+
const size = Math.floor(rectangle[horizontal ? "width" : "height"] * 8) / 8;
|
|
539
557
|
const doUpdate = () => {
|
|
540
558
|
refLastSize.current = { height: layout.height, width: layout.width };
|
|
541
559
|
updateItemSize2(itemKey, layout);
|
|
560
|
+
didLayoutRef.current = true;
|
|
542
561
|
};
|
|
543
562
|
if (IsNewArchitecture || size > 0) {
|
|
544
563
|
doUpdate();
|
|
@@ -550,25 +569,20 @@ var Container = typedMemo(function Container2({
|
|
|
550
569
|
}
|
|
551
570
|
}
|
|
552
571
|
};
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
updateItemSize2(itemKey, measured);
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
}, [itemKey, layoutRenderCount]);
|
|
566
|
-
} else {
|
|
572
|
+
const { onLayout } = useOnLayoutSync(
|
|
573
|
+
{
|
|
574
|
+
onLayoutChange,
|
|
575
|
+
ref
|
|
576
|
+
},
|
|
577
|
+
[itemKey, layoutRenderCount]
|
|
578
|
+
);
|
|
579
|
+
if (!IsNewArchitecture) {
|
|
567
580
|
React2.useEffect(() => {
|
|
568
581
|
if (!isNullOrUndefined(itemKey)) {
|
|
569
582
|
const timeout = setTimeout(() => {
|
|
570
|
-
if (!
|
|
583
|
+
if (!didLayoutRef.current && refLastSize.current) {
|
|
571
584
|
updateItemSize2(itemKey, refLastSize.current);
|
|
585
|
+
didLayoutRef.current = true;
|
|
572
586
|
}
|
|
573
587
|
}, 16);
|
|
574
588
|
return () => {
|
|
@@ -657,6 +671,11 @@ var Containers = typedMemo(function Containers2({
|
|
|
657
671
|
}
|
|
658
672
|
return /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { style }, containers);
|
|
659
673
|
});
|
|
674
|
+
var LayoutView = ({ onLayoutChange, refView, ...rest }) => {
|
|
675
|
+
const ref = refView != null ? refView : React2.useRef();
|
|
676
|
+
const { onLayout } = useOnLayoutSync({ onLayoutChange, ref });
|
|
677
|
+
return /* @__PURE__ */ React2__namespace.createElement(reactNative.View, { ...rest, onLayout, ref });
|
|
678
|
+
};
|
|
660
679
|
function ScrollAdjust() {
|
|
661
680
|
const bias = 1e7;
|
|
662
681
|
const [scrollAdjust, scrollAdjustUserOffset] = useArr$(["scrollAdjust", "scrollAdjustUserOffset"]);
|
|
@@ -678,68 +697,6 @@ function SnapWrapper({ ScrollComponent, ...props }) {
|
|
|
678
697
|
const [snapToOffsets] = useArr$(["snapToOffsets"]);
|
|
679
698
|
return /* @__PURE__ */ React2__namespace.default.createElement(ScrollComponent, { ...props, snapToOffsets });
|
|
680
699
|
}
|
|
681
|
-
function useThrottleDebounce(mode) {
|
|
682
|
-
const timeoutRef = React2.useRef(null);
|
|
683
|
-
const lastCallTimeRef = React2.useRef(0);
|
|
684
|
-
const lastArgsRef = React2.useRef(null);
|
|
685
|
-
const clearTimeoutRef = () => {
|
|
686
|
-
if (timeoutRef.current) {
|
|
687
|
-
clearTimeout(timeoutRef.current);
|
|
688
|
-
timeoutRef.current = null;
|
|
689
|
-
}
|
|
690
|
-
};
|
|
691
|
-
const execute = React2.useCallback(
|
|
692
|
-
(callback, delay, ...args) => {
|
|
693
|
-
{
|
|
694
|
-
const now = Date.now();
|
|
695
|
-
lastArgsRef.current = args;
|
|
696
|
-
if (now - lastCallTimeRef.current >= delay) {
|
|
697
|
-
lastCallTimeRef.current = now;
|
|
698
|
-
callback(...args);
|
|
699
|
-
clearTimeoutRef();
|
|
700
|
-
} else {
|
|
701
|
-
clearTimeoutRef();
|
|
702
|
-
timeoutRef.current = setTimeout(
|
|
703
|
-
() => {
|
|
704
|
-
if (lastArgsRef.current) {
|
|
705
|
-
lastCallTimeRef.current = Date.now();
|
|
706
|
-
callback(...lastArgsRef.current);
|
|
707
|
-
timeoutRef.current = null;
|
|
708
|
-
lastArgsRef.current = null;
|
|
709
|
-
}
|
|
710
|
-
},
|
|
711
|
-
delay - (now - lastCallTimeRef.current)
|
|
712
|
-
);
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
},
|
|
716
|
-
[mode]
|
|
717
|
-
);
|
|
718
|
-
return execute;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
// src/hooks/useSyncLayout.tsx
|
|
722
|
-
function useSyncLayout2({
|
|
723
|
-
onChange
|
|
724
|
-
}) {
|
|
725
|
-
const ref = React2.useRef(null);
|
|
726
|
-
const onLayout = React2.useCallback(
|
|
727
|
-
(event) => {
|
|
728
|
-
onChange(event.nativeEvent.layout, false);
|
|
729
|
-
},
|
|
730
|
-
[onChange]
|
|
731
|
-
);
|
|
732
|
-
if (IsNewArchitecture) {
|
|
733
|
-
React2.useLayoutEffect(() => {
|
|
734
|
-
if (ref.current) {
|
|
735
|
-
ref.current.measure((x, y, width, height) => {
|
|
736
|
-
onChange({ height, width, x, y }, true);
|
|
737
|
-
});
|
|
738
|
-
}
|
|
739
|
-
}, []);
|
|
740
|
-
}
|
|
741
|
-
return { onLayout, ref };
|
|
742
|
-
}
|
|
743
700
|
|
|
744
701
|
// src/components/ListComponent.tsx
|
|
745
702
|
var getComponent = (Component) => {
|
|
@@ -800,9 +757,6 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
800
757
|
...rest
|
|
801
758
|
}) {
|
|
802
759
|
const ctx = useStateContext();
|
|
803
|
-
const { onLayout: onLayoutHeaderSync, ref: refHeader } = useSyncLayout2({
|
|
804
|
-
onChange: onLayoutHeader
|
|
805
|
-
});
|
|
806
760
|
const ScrollComponent = renderScrollComponent ? React2.useMemo(
|
|
807
761
|
() => React2__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
|
|
808
762
|
[renderScrollComponent]
|
|
@@ -836,7 +790,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
836
790
|
},
|
|
837
791
|
maintainVisibleContentPosition && /* @__PURE__ */ React2__namespace.createElement(ScrollAdjust, null),
|
|
838
792
|
ENABLE_DEVMODE ? /* @__PURE__ */ React2__namespace.createElement(PaddingDevMode, null) : /* @__PURE__ */ React2__namespace.createElement(Padding, null),
|
|
839
|
-
ListHeaderComponent && /* @__PURE__ */ React2__namespace.createElement(
|
|
793
|
+
ListHeaderComponent && /* @__PURE__ */ React2__namespace.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
|
|
840
794
|
ListEmptyComponent && getComponent(ListEmptyComponent),
|
|
841
795
|
canRender && !ListEmptyComponent && /* @__PURE__ */ React2__namespace.createElement(
|
|
842
796
|
Containers,
|
|
@@ -850,10 +804,10 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
850
804
|
}
|
|
851
805
|
),
|
|
852
806
|
ListFooterComponent && /* @__PURE__ */ React2__namespace.createElement(
|
|
853
|
-
|
|
807
|
+
LayoutView,
|
|
854
808
|
{
|
|
855
|
-
|
|
856
|
-
const size =
|
|
809
|
+
onLayoutChange: (layout) => {
|
|
810
|
+
const size = layout[horizontal ? "width" : "height"];
|
|
857
811
|
set$(ctx, "footerSize", size);
|
|
858
812
|
},
|
|
859
813
|
style: ListFooterComponentStyle
|
|
@@ -888,7 +842,7 @@ function getId(state, index) {
|
|
|
888
842
|
}
|
|
889
843
|
const ret = index < data.length ? keyExtractor ? keyExtractor(data[index], index) : index : null;
|
|
890
844
|
const id = ret;
|
|
891
|
-
state.idCache
|
|
845
|
+
state.idCache[index] = id;
|
|
892
846
|
return id;
|
|
893
847
|
}
|
|
894
848
|
|
|
@@ -1112,6 +1066,68 @@ function prepareMVCP(ctx, state, dataChanged) {
|
|
|
1112
1066
|
};
|
|
1113
1067
|
}
|
|
1114
1068
|
|
|
1069
|
+
// src/core/prepareColumnStartState.ts
|
|
1070
|
+
function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
|
|
1071
|
+
var _a;
|
|
1072
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
1073
|
+
let rowStartIndex = startIndex;
|
|
1074
|
+
const columnAtStart = state.columns.get(state.idCache[startIndex]);
|
|
1075
|
+
if (columnAtStart !== 1) {
|
|
1076
|
+
rowStartIndex = findRowStartIndex(state, numColumns, startIndex);
|
|
1077
|
+
}
|
|
1078
|
+
let currentRowTop = 0;
|
|
1079
|
+
const curId = state.idCache[rowStartIndex];
|
|
1080
|
+
const column = state.columns.get(curId);
|
|
1081
|
+
if (rowStartIndex > 0) {
|
|
1082
|
+
const prevIndex = rowStartIndex - 1;
|
|
1083
|
+
const prevId = state.idCache[prevIndex];
|
|
1084
|
+
const prevPosition = (_a = state.positions.get(prevId)) != null ? _a : 0;
|
|
1085
|
+
const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
|
|
1086
|
+
const prevRowHeight = calculateRowMaxSize(state, prevRowStart, prevIndex, useAverageSize);
|
|
1087
|
+
currentRowTop = prevPosition + prevRowHeight;
|
|
1088
|
+
}
|
|
1089
|
+
return {
|
|
1090
|
+
column,
|
|
1091
|
+
currentRowTop,
|
|
1092
|
+
startIndex: rowStartIndex
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
function findRowStartIndex(state, numColumns, index) {
|
|
1096
|
+
if (numColumns <= 1) {
|
|
1097
|
+
return Math.max(0, index);
|
|
1098
|
+
}
|
|
1099
|
+
let rowStart = Math.max(0, index);
|
|
1100
|
+
while (rowStart > 0) {
|
|
1101
|
+
const columnForIndex = state.columns.get(state.idCache[rowStart]);
|
|
1102
|
+
if (columnForIndex === 1) {
|
|
1103
|
+
break;
|
|
1104
|
+
}
|
|
1105
|
+
rowStart--;
|
|
1106
|
+
}
|
|
1107
|
+
return rowStart;
|
|
1108
|
+
}
|
|
1109
|
+
function calculateRowMaxSize(state, startIndex, endIndex, useAverageSize) {
|
|
1110
|
+
if (endIndex < startIndex) {
|
|
1111
|
+
return 0;
|
|
1112
|
+
}
|
|
1113
|
+
const { data } = state.props;
|
|
1114
|
+
if (!data) {
|
|
1115
|
+
return 0;
|
|
1116
|
+
}
|
|
1117
|
+
let maxSize = 0;
|
|
1118
|
+
for (let i = startIndex; i <= endIndex; i++) {
|
|
1119
|
+
if (i < 0 || i >= data.length) {
|
|
1120
|
+
continue;
|
|
1121
|
+
}
|
|
1122
|
+
const id = state.idCache[i];
|
|
1123
|
+
const size = getItemSize(state, id, i, data[i], useAverageSize);
|
|
1124
|
+
if (size > maxSize) {
|
|
1125
|
+
maxSize = size;
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
return maxSize;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1115
1131
|
// src/utils/setPaddingTop.ts
|
|
1116
1132
|
function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
|
|
1117
1133
|
if (stylePaddingTop !== void 0) {
|
|
@@ -1206,7 +1222,7 @@ function updateSnapToOffsets(ctx, state) {
|
|
|
1206
1222
|
|
|
1207
1223
|
// src/core/updateItemPositions.ts
|
|
1208
1224
|
function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottomBuffered } = { scrollBottomBuffered: -1, startIndex: 0 }) {
|
|
1209
|
-
var _a, _b, _c, _d
|
|
1225
|
+
var _a, _b, _c, _d;
|
|
1210
1226
|
const {
|
|
1211
1227
|
columns,
|
|
1212
1228
|
indexByKey,
|
|
@@ -1216,41 +1232,47 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1216
1232
|
props: { getEstimatedItemSize, snapToIndices, enableAverages }
|
|
1217
1233
|
} = state;
|
|
1218
1234
|
const data = state.props.data;
|
|
1235
|
+
const dataLength = data.length;
|
|
1219
1236
|
const numColumns = peek$(ctx, "numColumns");
|
|
1237
|
+
const hasColumns = numColumns > 1;
|
|
1220
1238
|
const indexByKeyForChecking = __DEV__ ? /* @__PURE__ */ new Map() : void 0;
|
|
1221
1239
|
const maxVisibleArea = scrollBottomBuffered + 1e3;
|
|
1222
1240
|
const useAverageSize = enableAverages && !getEstimatedItemSize;
|
|
1223
1241
|
let currentRowTop = 0;
|
|
1224
1242
|
let column = 1;
|
|
1225
1243
|
let maxSizeInRow = 0;
|
|
1226
|
-
const hasColumns = numColumns > 1;
|
|
1227
1244
|
if (startIndex > 0) {
|
|
1228
|
-
const prevIndex = startIndex - 1;
|
|
1229
|
-
const prevId = (_a = idCache.get(prevIndex)) != null ? _a : getId(state, prevIndex);
|
|
1230
|
-
const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
|
|
1231
1245
|
if (hasColumns) {
|
|
1232
|
-
const
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1246
|
+
const { startIndex: processedStartIndex, currentRowTop: initialRowTop } = prepareColumnStartState(
|
|
1247
|
+
ctx,
|
|
1248
|
+
state,
|
|
1249
|
+
startIndex,
|
|
1250
|
+
useAverageSize
|
|
1251
|
+
);
|
|
1252
|
+
startIndex = processedStartIndex;
|
|
1253
|
+
currentRowTop = initialRowTop;
|
|
1254
|
+
} else if (startIndex < dataLength) {
|
|
1255
|
+
const prevIndex = startIndex - 1;
|
|
1256
|
+
const prevId = getId(state, prevIndex);
|
|
1257
|
+
const prevPosition = (_a = positions.get(prevId)) != null ? _a : 0;
|
|
1258
|
+
const prevSize = (_b = sizesKnown.get(prevId)) != null ? _b : getItemSize(state, prevId, prevIndex, data[prevIndex], useAverageSize);
|
|
1237
1259
|
currentRowTop = prevPosition + prevSize;
|
|
1238
1260
|
}
|
|
1239
1261
|
}
|
|
1240
1262
|
const needsIndexByKey = dataChanged || indexByKey.size === 0;
|
|
1241
1263
|
let didBreakEarly = false;
|
|
1242
1264
|
let breakAt;
|
|
1243
|
-
const dataLength = data.length;
|
|
1244
1265
|
for (let i = startIndex; i < dataLength; i++) {
|
|
1245
1266
|
if (breakAt && i > breakAt) {
|
|
1246
1267
|
didBreakEarly = true;
|
|
1247
1268
|
break;
|
|
1248
1269
|
}
|
|
1249
|
-
if (!dataChanged && currentRowTop > maxVisibleArea) {
|
|
1250
|
-
|
|
1270
|
+
if (breakAt === void 0 && !dataChanged && currentRowTop > maxVisibleArea) {
|
|
1271
|
+
const itemsPerRow = hasColumns ? numColumns : 1;
|
|
1272
|
+
breakAt = i + itemsPerRow + 10;
|
|
1251
1273
|
}
|
|
1252
|
-
const id = (
|
|
1253
|
-
const size = (
|
|
1274
|
+
const id = (_c = idCache[i]) != null ? _c : getId(state, i);
|
|
1275
|
+
const size = (_d = sizesKnown.get(id)) != null ? _d : getItemSize(state, id, i, data[i], useAverageSize);
|
|
1254
1276
|
if (__DEV__ && needsIndexByKey) {
|
|
1255
1277
|
if (indexByKeyForChecking.has(id)) {
|
|
1256
1278
|
console.error(
|
|
@@ -1487,9 +1509,12 @@ function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
|
|
|
1487
1509
|
var batchedUpdates = reactNative.unstable_batchedUpdates || ((callback) => callback());
|
|
1488
1510
|
|
|
1489
1511
|
// src/utils/checkAllSizesKnown.ts
|
|
1512
|
+
function isNullOrUndefined2(value) {
|
|
1513
|
+
return value === null || value === void 0;
|
|
1514
|
+
}
|
|
1490
1515
|
function checkAllSizesKnown(state) {
|
|
1491
1516
|
const { startBuffered, endBuffered, sizesKnown } = state;
|
|
1492
|
-
if (endBuffered
|
|
1517
|
+
if (!isNullOrUndefined2(endBuffered) && !isNullOrUndefined2(startBuffered) && startBuffered >= 0 && endBuffered >= 0) {
|
|
1493
1518
|
let areAllKnown = true;
|
|
1494
1519
|
for (let i = startBuffered; areAllKnown && i <= endBuffered; i++) {
|
|
1495
1520
|
const key = getId(state, i);
|
|
@@ -1506,6 +1531,8 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1506
1531
|
const { stickyContainerPool, containerItemTypes } = state;
|
|
1507
1532
|
const result = [];
|
|
1508
1533
|
const availableContainers = [];
|
|
1534
|
+
const pendingRemovalSet = new Set(pendingRemoval);
|
|
1535
|
+
let pendingRemovalChanged = false;
|
|
1509
1536
|
const stickyIndicesSet = state.props.stickyIndicesSet;
|
|
1510
1537
|
const stickyItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => stickyIndicesSet.has(index))) || [];
|
|
1511
1538
|
const canReuseContainer = (containerIndex, requiredType) => {
|
|
@@ -1521,12 +1548,11 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1521
1548
|
let foundContainer = false;
|
|
1522
1549
|
for (const containerIndex of stickyContainerPool) {
|
|
1523
1550
|
const key = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1524
|
-
const isPendingRemoval =
|
|
1551
|
+
const isPendingRemoval = pendingRemovalSet.has(containerIndex);
|
|
1525
1552
|
if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType)) {
|
|
1526
1553
|
result.push(containerIndex);
|
|
1527
|
-
if (isPendingRemoval) {
|
|
1528
|
-
|
|
1529
|
-
pendingRemoval.splice(index, 1);
|
|
1554
|
+
if (isPendingRemoval && pendingRemovalSet.delete(containerIndex)) {
|
|
1555
|
+
pendingRemovalChanged = true;
|
|
1530
1556
|
}
|
|
1531
1557
|
foundContainer = true;
|
|
1532
1558
|
if (requiredItemTypes) typeIndex++;
|
|
@@ -1546,13 +1572,11 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1546
1572
|
}
|
|
1547
1573
|
const key = peek$(ctx, `containerItemKey${u}`);
|
|
1548
1574
|
let isOk = key === void 0;
|
|
1549
|
-
if (!isOk) {
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
isOk = canReuseContainer(u, requiredType);
|
|
1555
|
-
}
|
|
1575
|
+
if (!isOk && pendingRemovalSet.has(u)) {
|
|
1576
|
+
pendingRemovalSet.delete(u);
|
|
1577
|
+
pendingRemovalChanged = true;
|
|
1578
|
+
const requiredType = neededTypes[typeIndex];
|
|
1579
|
+
isOk = canReuseContainer(u, requiredType);
|
|
1556
1580
|
}
|
|
1557
1581
|
if (isOk) {
|
|
1558
1582
|
result.push(u);
|
|
@@ -1610,6 +1634,12 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1610
1634
|
}
|
|
1611
1635
|
}
|
|
1612
1636
|
}
|
|
1637
|
+
if (pendingRemovalChanged) {
|
|
1638
|
+
pendingRemoval.length = 0;
|
|
1639
|
+
for (const value of pendingRemovalSet) {
|
|
1640
|
+
pendingRemoval.push(value);
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1613
1643
|
return result.sort(comparatorDefault);
|
|
1614
1644
|
}
|
|
1615
1645
|
function comparatorByDistance(a, b) {
|
|
@@ -1769,7 +1799,8 @@ function findCurrentStickyIndex(stickyArray, scroll, state) {
|
|
|
1769
1799
|
const idCache = state.idCache;
|
|
1770
1800
|
const positions = state.positions;
|
|
1771
1801
|
for (let i = stickyArray.length - 1; i >= 0; i--) {
|
|
1772
|
-
const
|
|
1802
|
+
const stickyIndex = stickyArray[i];
|
|
1803
|
+
const stickyId = (_a = idCache[stickyIndex]) != null ? _a : getId(state, stickyIndex);
|
|
1773
1804
|
const stickyPos = stickyId ? positions.get(stickyId) : void 0;
|
|
1774
1805
|
if (stickyPos !== void 0 && scroll >= stickyPos) {
|
|
1775
1806
|
return i;
|
|
@@ -1782,40 +1813,43 @@ function getActiveStickyIndices(ctx, state, stickyIndices) {
|
|
|
1782
1813
|
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))
|
|
1783
1814
|
);
|
|
1784
1815
|
}
|
|
1785
|
-
function handleStickyActivation(ctx, state, stickyIndices, stickyArray,
|
|
1816
|
+
function handleStickyActivation(ctx, state, stickyIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
|
|
1786
1817
|
var _a;
|
|
1787
1818
|
const activeIndices = getActiveStickyIndices(ctx, state, stickyIndices);
|
|
1788
|
-
const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
|
|
1789
1819
|
state.activeStickyIndex = currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : void 0;
|
|
1790
1820
|
for (let offset = 0; offset <= 1; offset++) {
|
|
1791
1821
|
const idx = currentStickyIdx - offset;
|
|
1792
1822
|
if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
|
|
1793
1823
|
const stickyIndex = stickyArray[idx];
|
|
1794
|
-
const stickyId = (_a = state.idCache
|
|
1824
|
+
const stickyId = (_a = state.idCache[stickyIndex]) != null ? _a : getId(state, stickyIndex);
|
|
1795
1825
|
if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered)) {
|
|
1796
1826
|
needNewContainers.push(stickyIndex);
|
|
1797
1827
|
}
|
|
1798
1828
|
}
|
|
1799
1829
|
}
|
|
1800
|
-
function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, pendingRemoval) {
|
|
1830
|
+
function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
|
|
1801
1831
|
var _a, _b, _c;
|
|
1802
|
-
const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
|
|
1803
1832
|
for (const containerIndex of state.stickyContainerPool) {
|
|
1804
1833
|
const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1805
1834
|
const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
|
|
1806
1835
|
if (itemIndex === void 0) continue;
|
|
1807
1836
|
const arrayIdx = stickyArray.indexOf(itemIndex);
|
|
1808
|
-
if (arrayIdx === -1)
|
|
1837
|
+
if (arrayIdx === -1) {
|
|
1838
|
+
state.stickyContainerPool.delete(containerIndex);
|
|
1839
|
+
set$(ctx, `containerSticky${containerIndex}`, false);
|
|
1840
|
+
set$(ctx, `containerStickyOffset${containerIndex}`, void 0);
|
|
1841
|
+
continue;
|
|
1842
|
+
}
|
|
1809
1843
|
const isRecentSticky = arrayIdx >= currentStickyIdx - 1 && arrayIdx <= currentStickyIdx + 1;
|
|
1810
1844
|
if (isRecentSticky) continue;
|
|
1811
1845
|
const nextIndex = stickyArray[arrayIdx + 1];
|
|
1812
1846
|
let shouldRecycle = false;
|
|
1813
1847
|
if (nextIndex) {
|
|
1814
|
-
const nextId = (_a = state.idCache
|
|
1848
|
+
const nextId = (_a = state.idCache[nextIndex]) != null ? _a : getId(state, nextIndex);
|
|
1815
1849
|
const nextPos = nextId ? state.positions.get(nextId) : void 0;
|
|
1816
1850
|
shouldRecycle = nextPos !== void 0 && scroll > nextPos + scrollBuffer * 2;
|
|
1817
1851
|
} else {
|
|
1818
|
-
const currentId = (_b = state.idCache
|
|
1852
|
+
const currentId = (_b = state.idCache[itemIndex]) != null ? _b : getId(state, itemIndex);
|
|
1819
1853
|
if (currentId) {
|
|
1820
1854
|
const currentPos = state.positions.get(currentId);
|
|
1821
1855
|
const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(state, currentId, itemIndex, state.props.data[itemIndex]);
|
|
@@ -1843,7 +1877,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1843
1877
|
sizes,
|
|
1844
1878
|
startBufferedId: startBufferedIdOrig,
|
|
1845
1879
|
viewabilityConfigCallbackPairs,
|
|
1846
|
-
props: { getItemType, initialScroll, itemsAreEqual, keyExtractor, scrollBuffer }
|
|
1880
|
+
props: { getItemType, initialScroll, itemsAreEqual, keyExtractor, onStickyHeaderChange, scrollBuffer }
|
|
1847
1881
|
} = state;
|
|
1848
1882
|
const { data } = state.props;
|
|
1849
1883
|
const stickyIndicesArr = state.props.stickyIndicesArr || [];
|
|
@@ -1878,6 +1912,10 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1878
1912
|
set$(ctx, "debugRawScroll", scrollState);
|
|
1879
1913
|
set$(ctx, "debugComputedScroll", scroll);
|
|
1880
1914
|
}
|
|
1915
|
+
const previousStickyIndex = state.activeStickyIndex;
|
|
1916
|
+
const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
|
|
1917
|
+
const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : void 0;
|
|
1918
|
+
state.activeStickyIndex = nextActiveStickyIndex;
|
|
1881
1919
|
let scrollBufferTop = scrollBuffer;
|
|
1882
1920
|
let scrollBufferBottom = scrollBuffer;
|
|
1883
1921
|
if (speed > 0 || speed === 0 && scroll < Math.max(50, scrollBuffer)) {
|
|
@@ -1899,7 +1937,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1899
1937
|
const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
|
|
1900
1938
|
if (dataChanged) {
|
|
1901
1939
|
indexByKey.clear();
|
|
1902
|
-
idCache.
|
|
1940
|
+
idCache.length = 0;
|
|
1903
1941
|
positions.clear();
|
|
1904
1942
|
}
|
|
1905
1943
|
const startIndex = dataChanged ? 0 : (_a = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _a : 0;
|
|
@@ -1915,7 +1953,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1915
1953
|
let endBuffered = null;
|
|
1916
1954
|
let loopStart = !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
|
|
1917
1955
|
for (let i = loopStart; i >= 0; i--) {
|
|
1918
|
-
const id = (_b = idCache
|
|
1956
|
+
const id = (_b = idCache[i]) != null ? _b : getId(state, i);
|
|
1919
1957
|
const top = positions.get(id);
|
|
1920
1958
|
const size = (_c = sizes.get(id)) != null ? _c : getItemSize(state, id, i, data[i]);
|
|
1921
1959
|
const bottom = top + size;
|
|
@@ -1943,7 +1981,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1943
1981
|
let firstFullyOnScreenIndex;
|
|
1944
1982
|
const dataLength = data.length;
|
|
1945
1983
|
for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
|
|
1946
|
-
const id = (_d = idCache
|
|
1984
|
+
const id = (_d = idCache[i]) != null ? _d : getId(state, i);
|
|
1947
1985
|
const size = (_e = sizes.get(id)) != null ? _e : getItemSize(state, id, i, data[i]);
|
|
1948
1986
|
const top = positions.get(id);
|
|
1949
1987
|
if (!foundEnd) {
|
|
@@ -1973,7 +2011,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1973
2011
|
}
|
|
1974
2012
|
const idsInView = [];
|
|
1975
2013
|
for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
|
|
1976
|
-
const id = (_f = idCache
|
|
2014
|
+
const id = (_f = idCache[i]) != null ? _f : getId(state, i);
|
|
1977
2015
|
idsInView.push(id);
|
|
1978
2016
|
}
|
|
1979
2017
|
Object.assign(state, {
|
|
@@ -2005,7 +2043,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2005
2043
|
let numContainers2 = prevNumContainers;
|
|
2006
2044
|
const needNewContainers = [];
|
|
2007
2045
|
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
2008
|
-
const id = (_g = idCache
|
|
2046
|
+
const id = (_g = idCache[i]) != null ? _g : getId(state, i);
|
|
2009
2047
|
if (!containerItemKeys.has(id)) {
|
|
2010
2048
|
needNewContainers.push(i);
|
|
2011
2049
|
}
|
|
@@ -2016,7 +2054,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2016
2054
|
state,
|
|
2017
2055
|
stickyIndicesSet,
|
|
2018
2056
|
stickyIndicesArr,
|
|
2019
|
-
|
|
2057
|
+
currentStickyIdx,
|
|
2020
2058
|
needNewContainers,
|
|
2021
2059
|
startBuffered,
|
|
2022
2060
|
endBuffered
|
|
@@ -2042,7 +2080,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2042
2080
|
for (let idx = 0; idx < needNewContainers.length; idx++) {
|
|
2043
2081
|
const i = needNewContainers[idx];
|
|
2044
2082
|
const containerIndex = availableContainers[idx];
|
|
2045
|
-
const id = (_h = idCache
|
|
2083
|
+
const id = (_h = idCache[i]) != null ? _h : getId(state, i);
|
|
2046
2084
|
const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
2047
2085
|
if (oldKey && oldKey !== id) {
|
|
2048
2086
|
containerItemKeys.delete(oldKey);
|
|
@@ -2056,7 +2094,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2056
2094
|
if (stickyIndicesSet.has(i)) {
|
|
2057
2095
|
set$(ctx, `containerSticky${containerIndex}`, true);
|
|
2058
2096
|
const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
2059
|
-
set$(ctx, `containerStickyOffset${containerIndex}`,
|
|
2097
|
+
set$(ctx, `containerStickyOffset${containerIndex}`, topPadding);
|
|
2060
2098
|
state.stickyContainerPool.add(containerIndex);
|
|
2061
2099
|
} else {
|
|
2062
2100
|
set$(ctx, `containerSticky${containerIndex}`, false);
|
|
@@ -2075,7 +2113,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2075
2113
|
}
|
|
2076
2114
|
}
|
|
2077
2115
|
if (stickyIndicesArr.length > 0) {
|
|
2078
|
-
handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, pendingRemoval);
|
|
2116
|
+
handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
|
|
2079
2117
|
}
|
|
2080
2118
|
for (let i = 0; i < numContainers; i++) {
|
|
2081
2119
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
@@ -2097,7 +2135,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2097
2135
|
const itemIndex = indexByKey.get(itemKey);
|
|
2098
2136
|
const item = data[itemIndex];
|
|
2099
2137
|
if (item !== void 0) {
|
|
2100
|
-
const id = (_i = idCache
|
|
2138
|
+
const id = (_i = idCache[itemIndex]) != null ? _i : getId(state, itemIndex);
|
|
2101
2139
|
const position = positions.get(id);
|
|
2102
2140
|
if (position === void 0) {
|
|
2103
2141
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
@@ -2127,6 +2165,12 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2127
2165
|
if (viewabilityConfigCallbackPairs) {
|
|
2128
2166
|
updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollLength, startNoBuffer, endNoBuffer);
|
|
2129
2167
|
}
|
|
2168
|
+
if (onStickyHeaderChange && stickyIndicesArr.length > 0 && nextActiveStickyIndex !== void 0 && nextActiveStickyIndex !== previousStickyIndex) {
|
|
2169
|
+
const item = data[nextActiveStickyIndex];
|
|
2170
|
+
if (item !== void 0) {
|
|
2171
|
+
onStickyHeaderChange({ index: nextActiveStickyIndex, item });
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2130
2174
|
});
|
|
2131
2175
|
}
|
|
2132
2176
|
|
|
@@ -2285,7 +2329,9 @@ function doInitialAllocateContainers(ctx, state) {
|
|
|
2285
2329
|
let totalSize = 0;
|
|
2286
2330
|
const num = Math.min(20, data.length);
|
|
2287
2331
|
for (let i = 0; i < num; i++) {
|
|
2288
|
-
|
|
2332
|
+
const item = data[i];
|
|
2333
|
+
const itemType = getItemType ? (_a = getItemType(item, i)) != null ? _a : "" : "";
|
|
2334
|
+
totalSize += fn(i, item, itemType);
|
|
2289
2335
|
}
|
|
2290
2336
|
averageItemSize = totalSize / num;
|
|
2291
2337
|
} else {
|
|
@@ -2314,7 +2360,9 @@ function doInitialAllocateContainers(ctx, state) {
|
|
|
2314
2360
|
// src/core/handleLayout.ts
|
|
2315
2361
|
function handleLayout(ctx, state, layout, setCanRender) {
|
|
2316
2362
|
const { maintainScrollAtEnd } = state.props;
|
|
2317
|
-
const
|
|
2363
|
+
const measuredLength = layout[state.props.horizontal ? "width" : "height"];
|
|
2364
|
+
const previousLength = state.scrollLength;
|
|
2365
|
+
const scrollLength = measuredLength > 0 ? measuredLength : previousLength;
|
|
2318
2366
|
const otherAxisSize = layout[state.props.horizontal ? "height" : "width"];
|
|
2319
2367
|
const needsCalculate = !state.lastLayout || scrollLength > state.scrollLength || state.lastLayout.x !== layout.x || state.lastLayout.y !== layout.y;
|
|
2320
2368
|
state.lastLayout = layout;
|
|
@@ -2325,7 +2373,9 @@ function handleLayout(ctx, state, layout, setCanRender) {
|
|
|
2325
2373
|
state.otherAxisSize = otherAxisSize;
|
|
2326
2374
|
state.lastBatchingAction = Date.now();
|
|
2327
2375
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
2328
|
-
|
|
2376
|
+
if (scrollLength > 0) {
|
|
2377
|
+
doInitialAllocateContainers(ctx, state);
|
|
2378
|
+
}
|
|
2329
2379
|
if (needsCalculate) {
|
|
2330
2380
|
calculateItemsInView(ctx, state, { doMVCP: true });
|
|
2331
2381
|
}
|
|
@@ -2341,14 +2391,14 @@ function handleLayout(ctx, state, layout, setCanRender) {
|
|
|
2341
2391
|
if (state) {
|
|
2342
2392
|
state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
|
|
2343
2393
|
}
|
|
2344
|
-
if (__DEV__ &&
|
|
2394
|
+
if (__DEV__ && measuredLength === 0) {
|
|
2345
2395
|
warnDevOnce(
|
|
2346
2396
|
"height0",
|
|
2347
2397
|
`List ${state.props.horizontal ? "width" : "height"} is 0. You may need to set a style or \`flex: \` for the list, because children are absolutely positioned.`
|
|
2348
2398
|
);
|
|
2349
2399
|
}
|
|
2350
|
-
setCanRender(true);
|
|
2351
2400
|
}
|
|
2401
|
+
setCanRender(true);
|
|
2352
2402
|
}
|
|
2353
2403
|
|
|
2354
2404
|
// src/core/onScroll.ts
|
|
@@ -2598,18 +2648,59 @@ function getRenderedItem(ctx, state, key) {
|
|
|
2598
2648
|
return null;
|
|
2599
2649
|
}
|
|
2600
2650
|
let renderedItem = null;
|
|
2601
|
-
|
|
2651
|
+
const extraData = peek$(ctx, "extraData");
|
|
2652
|
+
const item = data[index];
|
|
2653
|
+
if (renderItem && !isNullOrUndefined(item)) {
|
|
2602
2654
|
const itemProps = {
|
|
2603
2655
|
data,
|
|
2604
|
-
extraData
|
|
2656
|
+
extraData,
|
|
2605
2657
|
index,
|
|
2606
|
-
item
|
|
2607
|
-
type: getItemType ? (_a = getItemType(
|
|
2658
|
+
item,
|
|
2659
|
+
type: getItemType ? (_a = getItemType(item, index)) != null ? _a : "" : ""
|
|
2608
2660
|
};
|
|
2609
2661
|
renderedItem = isFunction(renderItem) ? renderItem(itemProps) : React2__namespace.default.createElement(renderItem, itemProps);
|
|
2610
2662
|
}
|
|
2611
2663
|
return { index, item: data[index], renderedItem };
|
|
2612
2664
|
}
|
|
2665
|
+
function useThrottleDebounce(mode) {
|
|
2666
|
+
const timeoutRef = React2.useRef(null);
|
|
2667
|
+
const lastCallTimeRef = React2.useRef(0);
|
|
2668
|
+
const lastArgsRef = React2.useRef(null);
|
|
2669
|
+
const clearTimeoutRef = () => {
|
|
2670
|
+
if (timeoutRef.current) {
|
|
2671
|
+
clearTimeout(timeoutRef.current);
|
|
2672
|
+
timeoutRef.current = null;
|
|
2673
|
+
}
|
|
2674
|
+
};
|
|
2675
|
+
const execute = React2.useCallback(
|
|
2676
|
+
(callback, delay, ...args) => {
|
|
2677
|
+
{
|
|
2678
|
+
const now = Date.now();
|
|
2679
|
+
lastArgsRef.current = args;
|
|
2680
|
+
if (now - lastCallTimeRef.current >= delay) {
|
|
2681
|
+
lastCallTimeRef.current = now;
|
|
2682
|
+
callback(...args);
|
|
2683
|
+
clearTimeoutRef();
|
|
2684
|
+
} else {
|
|
2685
|
+
clearTimeoutRef();
|
|
2686
|
+
timeoutRef.current = setTimeout(
|
|
2687
|
+
() => {
|
|
2688
|
+
if (lastArgsRef.current) {
|
|
2689
|
+
lastCallTimeRef.current = Date.now();
|
|
2690
|
+
callback(...lastArgsRef.current);
|
|
2691
|
+
timeoutRef.current = null;
|
|
2692
|
+
lastArgsRef.current = null;
|
|
2693
|
+
}
|
|
2694
|
+
},
|
|
2695
|
+
delay - (now - lastCallTimeRef.current)
|
|
2696
|
+
);
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
},
|
|
2700
|
+
[mode]
|
|
2701
|
+
);
|
|
2702
|
+
return execute;
|
|
2703
|
+
}
|
|
2613
2704
|
|
|
2614
2705
|
// src/utils/throttledOnScroll.ts
|
|
2615
2706
|
function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
|
|
@@ -2673,6 +2764,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2673
2764
|
onScroll: onScrollProp,
|
|
2674
2765
|
onStartReached,
|
|
2675
2766
|
onStartReachedThreshold = 0.5,
|
|
2767
|
+
onStickyHeaderChange,
|
|
2676
2768
|
onViewableItemsChanged,
|
|
2677
2769
|
progressViewOffset,
|
|
2678
2770
|
recycleItems = false,
|
|
@@ -2720,7 +2812,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2720
2812
|
endNoBuffer: -1,
|
|
2721
2813
|
endReachedBlockedByTimer: false,
|
|
2722
2814
|
firstFullyOnScreenIndex: -1,
|
|
2723
|
-
idCache:
|
|
2815
|
+
idCache: [],
|
|
2724
2816
|
idsInView: [],
|
|
2725
2817
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
2726
2818
|
initialScroll,
|
|
@@ -2795,6 +2887,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2795
2887
|
onScroll: throttleScrollFn,
|
|
2796
2888
|
onStartReached,
|
|
2797
2889
|
onStartReachedThreshold,
|
|
2890
|
+
onStickyHeaderChange,
|
|
2798
2891
|
recycleItems: !!recycleItems,
|
|
2799
2892
|
renderItem,
|
|
2800
2893
|
scrollBuffer,
|
|
@@ -2889,7 +2982,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2889
2982
|
}
|
|
2890
2983
|
}, [snapToIndices]);
|
|
2891
2984
|
React2.useLayoutEffect(() => {
|
|
2892
|
-
const didAllocateContainers = dataProp.length > 0 &&
|
|
2985
|
+
const didAllocateContainers = dataProp.length > 0 && doInitialAllocateContainers(ctx, state);
|
|
2893
2986
|
if (!didAllocateContainers) {
|
|
2894
2987
|
checkResetContainers(
|
|
2895
2988
|
ctx,
|
|
@@ -2903,30 +2996,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2903
2996
|
React2.useLayoutEffect(() => {
|
|
2904
2997
|
set$(ctx, "extraData", extraData);
|
|
2905
2998
|
}, [extraData]);
|
|
2906
|
-
React2.useLayoutEffect(() => {
|
|
2907
|
-
var _a2;
|
|
2908
|
-
if (IsNewArchitecture) {
|
|
2909
|
-
let measured;
|
|
2910
|
-
(_a2 = refScroller.current) == null ? void 0 : _a2.measure((x, y, width, height) => {
|
|
2911
|
-
measured = { height, width, x, y };
|
|
2912
|
-
});
|
|
2913
|
-
if (measured) {
|
|
2914
|
-
const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
|
|
2915
|
-
if (size) {
|
|
2916
|
-
handleLayout(ctx, state, measured, setCanRender);
|
|
2917
|
-
}
|
|
2918
|
-
}
|
|
2919
|
-
}
|
|
2920
|
-
}, []);
|
|
2921
2999
|
React2.useLayoutEffect(initializeStateVars, [
|
|
2922
3000
|
memoizedLastItemKeys.join(","),
|
|
2923
3001
|
numColumnsProp,
|
|
2924
3002
|
stylePaddingTopState,
|
|
2925
3003
|
stylePaddingBottomState
|
|
2926
3004
|
]);
|
|
2927
|
-
const doInitialAllocateContainersCallback = () => {
|
|
2928
|
-
return doInitialAllocateContainers(ctx, state);
|
|
2929
|
-
};
|
|
2930
3005
|
React2.useEffect(() => {
|
|
2931
3006
|
const viewability = setupViewability({
|
|
2932
3007
|
onViewableItemsChanged,
|
|
@@ -2938,16 +3013,18 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2938
3013
|
}, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
|
|
2939
3014
|
if (!IsNewArchitecture) {
|
|
2940
3015
|
useInit(() => {
|
|
2941
|
-
|
|
3016
|
+
doInitialAllocateContainers(ctx, state);
|
|
2942
3017
|
});
|
|
2943
3018
|
}
|
|
2944
|
-
const
|
|
2945
|
-
const layout = event.nativeEvent.layout;
|
|
3019
|
+
const onLayoutChange = React2.useCallback((layout) => {
|
|
2946
3020
|
handleLayout(ctx, state, layout, setCanRender);
|
|
2947
|
-
if (onLayoutProp) {
|
|
2948
|
-
onLayoutProp(event);
|
|
2949
|
-
}
|
|
2950
3021
|
}, []);
|
|
3022
|
+
const { onLayout } = useOnLayoutSync({
|
|
3023
|
+
onLayoutChange,
|
|
3024
|
+
onLayoutProp,
|
|
3025
|
+
ref: refScroller
|
|
3026
|
+
// the type of ScrollView doesn't include measure?
|
|
3027
|
+
});
|
|
2951
3028
|
React2.useImperativeHandle(forwardedRef, () => {
|
|
2952
3029
|
const scrollIndexIntoView = (options) => {
|
|
2953
3030
|
const state2 = refState.current;
|