@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.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React2 from 'react';
|
|
2
|
-
import React2__default, { useReducer, useEffect, createContext, useRef, useState, useMemo,
|
|
2
|
+
import React2__default, { useReducer, useEffect, createContext, useRef, useState, useMemo, useCallback, useLayoutEffect, useImperativeHandle, forwardRef, memo, useContext } from 'react';
|
|
3
3
|
import { View, Text, Platform, Animated, StyleSheet, Dimensions, RefreshControl, unstable_batchedUpdates } from 'react-native';
|
|
4
4
|
import { useSyncExternalStore } from 'use-sync-external-store/shim';
|
|
5
5
|
|
|
@@ -161,11 +161,6 @@ function useInterval(callback, delay) {
|
|
|
161
161
|
return () => clearInterval(interval);
|
|
162
162
|
}, [delay]);
|
|
163
163
|
}
|
|
164
|
-
var LeanViewComponent = React2.forwardRef((props, ref) => {
|
|
165
|
-
return React2.createElement("RCTView", { ...props, ref });
|
|
166
|
-
});
|
|
167
|
-
LeanViewComponent.displayName = "RCTView";
|
|
168
|
-
var LeanView = Platform.OS === "android" || Platform.OS === "ios" ? LeanViewComponent : View;
|
|
169
164
|
|
|
170
165
|
// src/constants.ts
|
|
171
166
|
var POSITION_OUT_OF_VIEW = -1e7;
|
|
@@ -227,7 +222,7 @@ var PositionViewState = typedMemo(function PositionView({
|
|
|
227
222
|
}) {
|
|
228
223
|
const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
|
|
229
224
|
return /* @__PURE__ */ React2.createElement(
|
|
230
|
-
|
|
225
|
+
View,
|
|
231
226
|
{
|
|
232
227
|
ref: refView,
|
|
233
228
|
style: [
|
|
@@ -268,7 +263,7 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
|
268
263
|
}) {
|
|
269
264
|
const [position = POSITION_OUT_OF_VIEW, headerSize] = useArr$([`containerPosition${id}`, "headerSize"]);
|
|
270
265
|
const transform = React2.useMemo(() => {
|
|
271
|
-
if (animatedScrollY && stickyOffset) {
|
|
266
|
+
if (animatedScrollY && stickyOffset !== void 0) {
|
|
272
267
|
const stickyPosition = animatedScrollY.interpolate({
|
|
273
268
|
extrapolate: "clamp",
|
|
274
269
|
inputRange: [position + headerSize, position + 5e3 + headerSize],
|
|
@@ -433,6 +428,29 @@ function Separator({ ItemSeparatorComponent, leadingItem }) {
|
|
|
433
428
|
const isLastItem = useIsLastItem();
|
|
434
429
|
return isLastItem ? null : /* @__PURE__ */ React2.createElement(ItemSeparatorComponent, { leadingItem });
|
|
435
430
|
}
|
|
431
|
+
function useOnLayoutSync({
|
|
432
|
+
ref,
|
|
433
|
+
onLayoutProp,
|
|
434
|
+
onLayoutChange
|
|
435
|
+
}, deps = []) {
|
|
436
|
+
const onLayout = useCallback(
|
|
437
|
+
(event) => {
|
|
438
|
+
onLayoutChange(event.nativeEvent.layout, false);
|
|
439
|
+
onLayoutProp == null ? void 0 : onLayoutProp(event);
|
|
440
|
+
},
|
|
441
|
+
[onLayoutChange]
|
|
442
|
+
);
|
|
443
|
+
if (IsNewArchitecture) {
|
|
444
|
+
useLayoutEffect(() => {
|
|
445
|
+
if (ref.current) {
|
|
446
|
+
ref.current.measure((x, y, width, height) => {
|
|
447
|
+
onLayoutChange({ height, width, x, y }, true);
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
}, deps);
|
|
451
|
+
}
|
|
452
|
+
return { onLayout };
|
|
453
|
+
}
|
|
436
454
|
|
|
437
455
|
// src/components/Container.tsx
|
|
438
456
|
var Container = typedMemo(function Container2({
|
|
@@ -459,7 +477,7 @@ var Container = typedMemo(function Container2({
|
|
|
459
477
|
const [layoutRenderCount, forceLayoutRender] = useState(0);
|
|
460
478
|
const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
|
|
461
479
|
const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
|
|
462
|
-
|
|
480
|
+
const didLayoutRef = useRef(false);
|
|
463
481
|
const style = useMemo(() => {
|
|
464
482
|
let paddingStyles;
|
|
465
483
|
if (columnWrapperStyle) {
|
|
@@ -509,15 +527,16 @@ var Container = typedMemo(function Container2({
|
|
|
509
527
|
value: data
|
|
510
528
|
};
|
|
511
529
|
}, [id, itemKey, index, data]);
|
|
512
|
-
const
|
|
530
|
+
const onLayoutChange = (rectangle) => {
|
|
513
531
|
var _a, _b;
|
|
514
532
|
if (!isNullOrUndefined(itemKey)) {
|
|
515
|
-
|
|
516
|
-
let layout =
|
|
517
|
-
const size =
|
|
533
|
+
didLayoutRef.current = true;
|
|
534
|
+
let layout = rectangle;
|
|
535
|
+
const size = Math.floor(rectangle[horizontal ? "width" : "height"] * 8) / 8;
|
|
518
536
|
const doUpdate = () => {
|
|
519
537
|
refLastSize.current = { height: layout.height, width: layout.width };
|
|
520
538
|
updateItemSize2(itemKey, layout);
|
|
539
|
+
didLayoutRef.current = true;
|
|
521
540
|
};
|
|
522
541
|
if (IsNewArchitecture || size > 0) {
|
|
523
542
|
doUpdate();
|
|
@@ -529,25 +548,20 @@ var Container = typedMemo(function Container2({
|
|
|
529
548
|
}
|
|
530
549
|
}
|
|
531
550
|
};
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
updateItemSize2(itemKey, measured);
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
}, [itemKey, layoutRenderCount]);
|
|
545
|
-
} else {
|
|
551
|
+
const { onLayout } = useOnLayoutSync(
|
|
552
|
+
{
|
|
553
|
+
onLayoutChange,
|
|
554
|
+
ref
|
|
555
|
+
},
|
|
556
|
+
[itemKey, layoutRenderCount]
|
|
557
|
+
);
|
|
558
|
+
if (!IsNewArchitecture) {
|
|
546
559
|
useEffect(() => {
|
|
547
560
|
if (!isNullOrUndefined(itemKey)) {
|
|
548
561
|
const timeout = setTimeout(() => {
|
|
549
|
-
if (!
|
|
562
|
+
if (!didLayoutRef.current && refLastSize.current) {
|
|
550
563
|
updateItemSize2(itemKey, refLastSize.current);
|
|
564
|
+
didLayoutRef.current = true;
|
|
551
565
|
}
|
|
552
566
|
}, 16);
|
|
553
567
|
return () => {
|
|
@@ -636,6 +650,11 @@ var Containers = typedMemo(function Containers2({
|
|
|
636
650
|
}
|
|
637
651
|
return /* @__PURE__ */ React2.createElement(Animated.View, { style }, containers);
|
|
638
652
|
});
|
|
653
|
+
var LayoutView = ({ onLayoutChange, refView, ...rest }) => {
|
|
654
|
+
const ref = refView != null ? refView : useRef();
|
|
655
|
+
const { onLayout } = useOnLayoutSync({ onLayoutChange, ref });
|
|
656
|
+
return /* @__PURE__ */ React2.createElement(View, { ...rest, onLayout, ref });
|
|
657
|
+
};
|
|
639
658
|
function ScrollAdjust() {
|
|
640
659
|
const bias = 1e7;
|
|
641
660
|
const [scrollAdjust, scrollAdjustUserOffset] = useArr$(["scrollAdjust", "scrollAdjustUserOffset"]);
|
|
@@ -657,68 +676,6 @@ function SnapWrapper({ ScrollComponent, ...props }) {
|
|
|
657
676
|
const [snapToOffsets] = useArr$(["snapToOffsets"]);
|
|
658
677
|
return /* @__PURE__ */ React2__default.createElement(ScrollComponent, { ...props, snapToOffsets });
|
|
659
678
|
}
|
|
660
|
-
function useThrottleDebounce(mode) {
|
|
661
|
-
const timeoutRef = useRef(null);
|
|
662
|
-
const lastCallTimeRef = useRef(0);
|
|
663
|
-
const lastArgsRef = useRef(null);
|
|
664
|
-
const clearTimeoutRef = () => {
|
|
665
|
-
if (timeoutRef.current) {
|
|
666
|
-
clearTimeout(timeoutRef.current);
|
|
667
|
-
timeoutRef.current = null;
|
|
668
|
-
}
|
|
669
|
-
};
|
|
670
|
-
const execute = useCallback(
|
|
671
|
-
(callback, delay, ...args) => {
|
|
672
|
-
{
|
|
673
|
-
const now = Date.now();
|
|
674
|
-
lastArgsRef.current = args;
|
|
675
|
-
if (now - lastCallTimeRef.current >= delay) {
|
|
676
|
-
lastCallTimeRef.current = now;
|
|
677
|
-
callback(...args);
|
|
678
|
-
clearTimeoutRef();
|
|
679
|
-
} else {
|
|
680
|
-
clearTimeoutRef();
|
|
681
|
-
timeoutRef.current = setTimeout(
|
|
682
|
-
() => {
|
|
683
|
-
if (lastArgsRef.current) {
|
|
684
|
-
lastCallTimeRef.current = Date.now();
|
|
685
|
-
callback(...lastArgsRef.current);
|
|
686
|
-
timeoutRef.current = null;
|
|
687
|
-
lastArgsRef.current = null;
|
|
688
|
-
}
|
|
689
|
-
},
|
|
690
|
-
delay - (now - lastCallTimeRef.current)
|
|
691
|
-
);
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
},
|
|
695
|
-
[mode]
|
|
696
|
-
);
|
|
697
|
-
return execute;
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
// src/hooks/useSyncLayout.tsx
|
|
701
|
-
function useSyncLayout2({
|
|
702
|
-
onChange
|
|
703
|
-
}) {
|
|
704
|
-
const ref = useRef(null);
|
|
705
|
-
const onLayout = useCallback(
|
|
706
|
-
(event) => {
|
|
707
|
-
onChange(event.nativeEvent.layout, false);
|
|
708
|
-
},
|
|
709
|
-
[onChange]
|
|
710
|
-
);
|
|
711
|
-
if (IsNewArchitecture) {
|
|
712
|
-
useLayoutEffect(() => {
|
|
713
|
-
if (ref.current) {
|
|
714
|
-
ref.current.measure((x, y, width, height) => {
|
|
715
|
-
onChange({ height, width, x, y }, true);
|
|
716
|
-
});
|
|
717
|
-
}
|
|
718
|
-
}, []);
|
|
719
|
-
}
|
|
720
|
-
return { onLayout, ref };
|
|
721
|
-
}
|
|
722
679
|
|
|
723
680
|
// src/components/ListComponent.tsx
|
|
724
681
|
var getComponent = (Component) => {
|
|
@@ -779,9 +736,6 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
779
736
|
...rest
|
|
780
737
|
}) {
|
|
781
738
|
const ctx = useStateContext();
|
|
782
|
-
const { onLayout: onLayoutHeaderSync, ref: refHeader } = useSyncLayout2({
|
|
783
|
-
onChange: onLayoutHeader
|
|
784
|
-
});
|
|
785
739
|
const ScrollComponent = renderScrollComponent ? useMemo(
|
|
786
740
|
() => React2.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
|
|
787
741
|
[renderScrollComponent]
|
|
@@ -815,7 +769,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
815
769
|
},
|
|
816
770
|
maintainVisibleContentPosition && /* @__PURE__ */ React2.createElement(ScrollAdjust, null),
|
|
817
771
|
ENABLE_DEVMODE ? /* @__PURE__ */ React2.createElement(PaddingDevMode, null) : /* @__PURE__ */ React2.createElement(Padding, null),
|
|
818
|
-
ListHeaderComponent && /* @__PURE__ */ React2.createElement(
|
|
772
|
+
ListHeaderComponent && /* @__PURE__ */ React2.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
|
|
819
773
|
ListEmptyComponent && getComponent(ListEmptyComponent),
|
|
820
774
|
canRender && !ListEmptyComponent && /* @__PURE__ */ React2.createElement(
|
|
821
775
|
Containers,
|
|
@@ -829,10 +783,10 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
829
783
|
}
|
|
830
784
|
),
|
|
831
785
|
ListFooterComponent && /* @__PURE__ */ React2.createElement(
|
|
832
|
-
|
|
786
|
+
LayoutView,
|
|
833
787
|
{
|
|
834
|
-
|
|
835
|
-
const size =
|
|
788
|
+
onLayoutChange: (layout) => {
|
|
789
|
+
const size = layout[horizontal ? "width" : "height"];
|
|
836
790
|
set$(ctx, "footerSize", size);
|
|
837
791
|
},
|
|
838
792
|
style: ListFooterComponentStyle
|
|
@@ -867,7 +821,7 @@ function getId(state, index) {
|
|
|
867
821
|
}
|
|
868
822
|
const ret = index < data.length ? keyExtractor ? keyExtractor(data[index], index) : index : null;
|
|
869
823
|
const id = ret;
|
|
870
|
-
state.idCache
|
|
824
|
+
state.idCache[index] = id;
|
|
871
825
|
return id;
|
|
872
826
|
}
|
|
873
827
|
|
|
@@ -1091,6 +1045,68 @@ function prepareMVCP(ctx, state, dataChanged) {
|
|
|
1091
1045
|
};
|
|
1092
1046
|
}
|
|
1093
1047
|
|
|
1048
|
+
// src/core/prepareColumnStartState.ts
|
|
1049
|
+
function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
|
|
1050
|
+
var _a;
|
|
1051
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
1052
|
+
let rowStartIndex = startIndex;
|
|
1053
|
+
const columnAtStart = state.columns.get(state.idCache[startIndex]);
|
|
1054
|
+
if (columnAtStart !== 1) {
|
|
1055
|
+
rowStartIndex = findRowStartIndex(state, numColumns, startIndex);
|
|
1056
|
+
}
|
|
1057
|
+
let currentRowTop = 0;
|
|
1058
|
+
const curId = state.idCache[rowStartIndex];
|
|
1059
|
+
const column = state.columns.get(curId);
|
|
1060
|
+
if (rowStartIndex > 0) {
|
|
1061
|
+
const prevIndex = rowStartIndex - 1;
|
|
1062
|
+
const prevId = state.idCache[prevIndex];
|
|
1063
|
+
const prevPosition = (_a = state.positions.get(prevId)) != null ? _a : 0;
|
|
1064
|
+
const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
|
|
1065
|
+
const prevRowHeight = calculateRowMaxSize(state, prevRowStart, prevIndex, useAverageSize);
|
|
1066
|
+
currentRowTop = prevPosition + prevRowHeight;
|
|
1067
|
+
}
|
|
1068
|
+
return {
|
|
1069
|
+
column,
|
|
1070
|
+
currentRowTop,
|
|
1071
|
+
startIndex: rowStartIndex
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
function findRowStartIndex(state, numColumns, index) {
|
|
1075
|
+
if (numColumns <= 1) {
|
|
1076
|
+
return Math.max(0, index);
|
|
1077
|
+
}
|
|
1078
|
+
let rowStart = Math.max(0, index);
|
|
1079
|
+
while (rowStart > 0) {
|
|
1080
|
+
const columnForIndex = state.columns.get(state.idCache[rowStart]);
|
|
1081
|
+
if (columnForIndex === 1) {
|
|
1082
|
+
break;
|
|
1083
|
+
}
|
|
1084
|
+
rowStart--;
|
|
1085
|
+
}
|
|
1086
|
+
return rowStart;
|
|
1087
|
+
}
|
|
1088
|
+
function calculateRowMaxSize(state, startIndex, endIndex, useAverageSize) {
|
|
1089
|
+
if (endIndex < startIndex) {
|
|
1090
|
+
return 0;
|
|
1091
|
+
}
|
|
1092
|
+
const { data } = state.props;
|
|
1093
|
+
if (!data) {
|
|
1094
|
+
return 0;
|
|
1095
|
+
}
|
|
1096
|
+
let maxSize = 0;
|
|
1097
|
+
for (let i = startIndex; i <= endIndex; i++) {
|
|
1098
|
+
if (i < 0 || i >= data.length) {
|
|
1099
|
+
continue;
|
|
1100
|
+
}
|
|
1101
|
+
const id = state.idCache[i];
|
|
1102
|
+
const size = getItemSize(state, id, i, data[i], useAverageSize);
|
|
1103
|
+
if (size > maxSize) {
|
|
1104
|
+
maxSize = size;
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
return maxSize;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1094
1110
|
// src/utils/setPaddingTop.ts
|
|
1095
1111
|
function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
|
|
1096
1112
|
if (stylePaddingTop !== void 0) {
|
|
@@ -1185,7 +1201,7 @@ function updateSnapToOffsets(ctx, state) {
|
|
|
1185
1201
|
|
|
1186
1202
|
// src/core/updateItemPositions.ts
|
|
1187
1203
|
function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottomBuffered } = { scrollBottomBuffered: -1, startIndex: 0 }) {
|
|
1188
|
-
var _a, _b, _c, _d
|
|
1204
|
+
var _a, _b, _c, _d;
|
|
1189
1205
|
const {
|
|
1190
1206
|
columns,
|
|
1191
1207
|
indexByKey,
|
|
@@ -1195,41 +1211,47 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1195
1211
|
props: { getEstimatedItemSize, snapToIndices, enableAverages }
|
|
1196
1212
|
} = state;
|
|
1197
1213
|
const data = state.props.data;
|
|
1214
|
+
const dataLength = data.length;
|
|
1198
1215
|
const numColumns = peek$(ctx, "numColumns");
|
|
1216
|
+
const hasColumns = numColumns > 1;
|
|
1199
1217
|
const indexByKeyForChecking = __DEV__ ? /* @__PURE__ */ new Map() : void 0;
|
|
1200
1218
|
const maxVisibleArea = scrollBottomBuffered + 1e3;
|
|
1201
1219
|
const useAverageSize = enableAverages && !getEstimatedItemSize;
|
|
1202
1220
|
let currentRowTop = 0;
|
|
1203
1221
|
let column = 1;
|
|
1204
1222
|
let maxSizeInRow = 0;
|
|
1205
|
-
const hasColumns = numColumns > 1;
|
|
1206
1223
|
if (startIndex > 0) {
|
|
1207
|
-
const prevIndex = startIndex - 1;
|
|
1208
|
-
const prevId = (_a = idCache.get(prevIndex)) != null ? _a : getId(state, prevIndex);
|
|
1209
|
-
const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
|
|
1210
1224
|
if (hasColumns) {
|
|
1211
|
-
const
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1225
|
+
const { startIndex: processedStartIndex, currentRowTop: initialRowTop } = prepareColumnStartState(
|
|
1226
|
+
ctx,
|
|
1227
|
+
state,
|
|
1228
|
+
startIndex,
|
|
1229
|
+
useAverageSize
|
|
1230
|
+
);
|
|
1231
|
+
startIndex = processedStartIndex;
|
|
1232
|
+
currentRowTop = initialRowTop;
|
|
1233
|
+
} else if (startIndex < dataLength) {
|
|
1234
|
+
const prevIndex = startIndex - 1;
|
|
1235
|
+
const prevId = getId(state, prevIndex);
|
|
1236
|
+
const prevPosition = (_a = positions.get(prevId)) != null ? _a : 0;
|
|
1237
|
+
const prevSize = (_b = sizesKnown.get(prevId)) != null ? _b : getItemSize(state, prevId, prevIndex, data[prevIndex], useAverageSize);
|
|
1216
1238
|
currentRowTop = prevPosition + prevSize;
|
|
1217
1239
|
}
|
|
1218
1240
|
}
|
|
1219
1241
|
const needsIndexByKey = dataChanged || indexByKey.size === 0;
|
|
1220
1242
|
let didBreakEarly = false;
|
|
1221
1243
|
let breakAt;
|
|
1222
|
-
const dataLength = data.length;
|
|
1223
1244
|
for (let i = startIndex; i < dataLength; i++) {
|
|
1224
1245
|
if (breakAt && i > breakAt) {
|
|
1225
1246
|
didBreakEarly = true;
|
|
1226
1247
|
break;
|
|
1227
1248
|
}
|
|
1228
|
-
if (!dataChanged && currentRowTop > maxVisibleArea) {
|
|
1229
|
-
|
|
1249
|
+
if (breakAt === void 0 && !dataChanged && currentRowTop > maxVisibleArea) {
|
|
1250
|
+
const itemsPerRow = hasColumns ? numColumns : 1;
|
|
1251
|
+
breakAt = i + itemsPerRow + 10;
|
|
1230
1252
|
}
|
|
1231
|
-
const id = (
|
|
1232
|
-
const size = (
|
|
1253
|
+
const id = (_c = idCache[i]) != null ? _c : getId(state, i);
|
|
1254
|
+
const size = (_d = sizesKnown.get(id)) != null ? _d : getItemSize(state, id, i, data[i], useAverageSize);
|
|
1233
1255
|
if (__DEV__ && needsIndexByKey) {
|
|
1234
1256
|
if (indexByKeyForChecking.has(id)) {
|
|
1235
1257
|
console.error(
|
|
@@ -1466,9 +1488,12 @@ function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
|
|
|
1466
1488
|
var batchedUpdates = unstable_batchedUpdates || ((callback) => callback());
|
|
1467
1489
|
|
|
1468
1490
|
// src/utils/checkAllSizesKnown.ts
|
|
1491
|
+
function isNullOrUndefined2(value) {
|
|
1492
|
+
return value === null || value === void 0;
|
|
1493
|
+
}
|
|
1469
1494
|
function checkAllSizesKnown(state) {
|
|
1470
1495
|
const { startBuffered, endBuffered, sizesKnown } = state;
|
|
1471
|
-
if (endBuffered
|
|
1496
|
+
if (!isNullOrUndefined2(endBuffered) && !isNullOrUndefined2(startBuffered) && startBuffered >= 0 && endBuffered >= 0) {
|
|
1472
1497
|
let areAllKnown = true;
|
|
1473
1498
|
for (let i = startBuffered; areAllKnown && i <= endBuffered; i++) {
|
|
1474
1499
|
const key = getId(state, i);
|
|
@@ -1485,6 +1510,8 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1485
1510
|
const { stickyContainerPool, containerItemTypes } = state;
|
|
1486
1511
|
const result = [];
|
|
1487
1512
|
const availableContainers = [];
|
|
1513
|
+
const pendingRemovalSet = new Set(pendingRemoval);
|
|
1514
|
+
let pendingRemovalChanged = false;
|
|
1488
1515
|
const stickyIndicesSet = state.props.stickyIndicesSet;
|
|
1489
1516
|
const stickyItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => stickyIndicesSet.has(index))) || [];
|
|
1490
1517
|
const canReuseContainer = (containerIndex, requiredType) => {
|
|
@@ -1500,12 +1527,11 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1500
1527
|
let foundContainer = false;
|
|
1501
1528
|
for (const containerIndex of stickyContainerPool) {
|
|
1502
1529
|
const key = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1503
|
-
const isPendingRemoval =
|
|
1530
|
+
const isPendingRemoval = pendingRemovalSet.has(containerIndex);
|
|
1504
1531
|
if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType)) {
|
|
1505
1532
|
result.push(containerIndex);
|
|
1506
|
-
if (isPendingRemoval) {
|
|
1507
|
-
|
|
1508
|
-
pendingRemoval.splice(index, 1);
|
|
1533
|
+
if (isPendingRemoval && pendingRemovalSet.delete(containerIndex)) {
|
|
1534
|
+
pendingRemovalChanged = true;
|
|
1509
1535
|
}
|
|
1510
1536
|
foundContainer = true;
|
|
1511
1537
|
if (requiredItemTypes) typeIndex++;
|
|
@@ -1525,13 +1551,11 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1525
1551
|
}
|
|
1526
1552
|
const key = peek$(ctx, `containerItemKey${u}`);
|
|
1527
1553
|
let isOk = key === void 0;
|
|
1528
|
-
if (!isOk) {
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
isOk = canReuseContainer(u, requiredType);
|
|
1534
|
-
}
|
|
1554
|
+
if (!isOk && pendingRemovalSet.has(u)) {
|
|
1555
|
+
pendingRemovalSet.delete(u);
|
|
1556
|
+
pendingRemovalChanged = true;
|
|
1557
|
+
const requiredType = neededTypes[typeIndex];
|
|
1558
|
+
isOk = canReuseContainer(u, requiredType);
|
|
1535
1559
|
}
|
|
1536
1560
|
if (isOk) {
|
|
1537
1561
|
result.push(u);
|
|
@@ -1589,6 +1613,12 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1589
1613
|
}
|
|
1590
1614
|
}
|
|
1591
1615
|
}
|
|
1616
|
+
if (pendingRemovalChanged) {
|
|
1617
|
+
pendingRemoval.length = 0;
|
|
1618
|
+
for (const value of pendingRemovalSet) {
|
|
1619
|
+
pendingRemoval.push(value);
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1592
1622
|
return result.sort(comparatorDefault);
|
|
1593
1623
|
}
|
|
1594
1624
|
function comparatorByDistance(a, b) {
|
|
@@ -1748,7 +1778,8 @@ function findCurrentStickyIndex(stickyArray, scroll, state) {
|
|
|
1748
1778
|
const idCache = state.idCache;
|
|
1749
1779
|
const positions = state.positions;
|
|
1750
1780
|
for (let i = stickyArray.length - 1; i >= 0; i--) {
|
|
1751
|
-
const
|
|
1781
|
+
const stickyIndex = stickyArray[i];
|
|
1782
|
+
const stickyId = (_a = idCache[stickyIndex]) != null ? _a : getId(state, stickyIndex);
|
|
1752
1783
|
const stickyPos = stickyId ? positions.get(stickyId) : void 0;
|
|
1753
1784
|
if (stickyPos !== void 0 && scroll >= stickyPos) {
|
|
1754
1785
|
return i;
|
|
@@ -1761,40 +1792,43 @@ function getActiveStickyIndices(ctx, state, stickyIndices) {
|
|
|
1761
1792
|
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))
|
|
1762
1793
|
);
|
|
1763
1794
|
}
|
|
1764
|
-
function handleStickyActivation(ctx, state, stickyIndices, stickyArray,
|
|
1795
|
+
function handleStickyActivation(ctx, state, stickyIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
|
|
1765
1796
|
var _a;
|
|
1766
1797
|
const activeIndices = getActiveStickyIndices(ctx, state, stickyIndices);
|
|
1767
|
-
const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
|
|
1768
1798
|
state.activeStickyIndex = currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : void 0;
|
|
1769
1799
|
for (let offset = 0; offset <= 1; offset++) {
|
|
1770
1800
|
const idx = currentStickyIdx - offset;
|
|
1771
1801
|
if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
|
|
1772
1802
|
const stickyIndex = stickyArray[idx];
|
|
1773
|
-
const stickyId = (_a = state.idCache
|
|
1803
|
+
const stickyId = (_a = state.idCache[stickyIndex]) != null ? _a : getId(state, stickyIndex);
|
|
1774
1804
|
if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered)) {
|
|
1775
1805
|
needNewContainers.push(stickyIndex);
|
|
1776
1806
|
}
|
|
1777
1807
|
}
|
|
1778
1808
|
}
|
|
1779
|
-
function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, pendingRemoval) {
|
|
1809
|
+
function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
|
|
1780
1810
|
var _a, _b, _c;
|
|
1781
|
-
const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
|
|
1782
1811
|
for (const containerIndex of state.stickyContainerPool) {
|
|
1783
1812
|
const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1784
1813
|
const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
|
|
1785
1814
|
if (itemIndex === void 0) continue;
|
|
1786
1815
|
const arrayIdx = stickyArray.indexOf(itemIndex);
|
|
1787
|
-
if (arrayIdx === -1)
|
|
1816
|
+
if (arrayIdx === -1) {
|
|
1817
|
+
state.stickyContainerPool.delete(containerIndex);
|
|
1818
|
+
set$(ctx, `containerSticky${containerIndex}`, false);
|
|
1819
|
+
set$(ctx, `containerStickyOffset${containerIndex}`, void 0);
|
|
1820
|
+
continue;
|
|
1821
|
+
}
|
|
1788
1822
|
const isRecentSticky = arrayIdx >= currentStickyIdx - 1 && arrayIdx <= currentStickyIdx + 1;
|
|
1789
1823
|
if (isRecentSticky) continue;
|
|
1790
1824
|
const nextIndex = stickyArray[arrayIdx + 1];
|
|
1791
1825
|
let shouldRecycle = false;
|
|
1792
1826
|
if (nextIndex) {
|
|
1793
|
-
const nextId = (_a = state.idCache
|
|
1827
|
+
const nextId = (_a = state.idCache[nextIndex]) != null ? _a : getId(state, nextIndex);
|
|
1794
1828
|
const nextPos = nextId ? state.positions.get(nextId) : void 0;
|
|
1795
1829
|
shouldRecycle = nextPos !== void 0 && scroll > nextPos + scrollBuffer * 2;
|
|
1796
1830
|
} else {
|
|
1797
|
-
const currentId = (_b = state.idCache
|
|
1831
|
+
const currentId = (_b = state.idCache[itemIndex]) != null ? _b : getId(state, itemIndex);
|
|
1798
1832
|
if (currentId) {
|
|
1799
1833
|
const currentPos = state.positions.get(currentId);
|
|
1800
1834
|
const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(state, currentId, itemIndex, state.props.data[itemIndex]);
|
|
@@ -1822,7 +1856,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1822
1856
|
sizes,
|
|
1823
1857
|
startBufferedId: startBufferedIdOrig,
|
|
1824
1858
|
viewabilityConfigCallbackPairs,
|
|
1825
|
-
props: { getItemType, initialScroll, itemsAreEqual, keyExtractor, scrollBuffer }
|
|
1859
|
+
props: { getItemType, initialScroll, itemsAreEqual, keyExtractor, onStickyHeaderChange, scrollBuffer }
|
|
1826
1860
|
} = state;
|
|
1827
1861
|
const { data } = state.props;
|
|
1828
1862
|
const stickyIndicesArr = state.props.stickyIndicesArr || [];
|
|
@@ -1857,6 +1891,10 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1857
1891
|
set$(ctx, "debugRawScroll", scrollState);
|
|
1858
1892
|
set$(ctx, "debugComputedScroll", scroll);
|
|
1859
1893
|
}
|
|
1894
|
+
const previousStickyIndex = state.activeStickyIndex;
|
|
1895
|
+
const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
|
|
1896
|
+
const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : void 0;
|
|
1897
|
+
state.activeStickyIndex = nextActiveStickyIndex;
|
|
1860
1898
|
let scrollBufferTop = scrollBuffer;
|
|
1861
1899
|
let scrollBufferBottom = scrollBuffer;
|
|
1862
1900
|
if (speed > 0 || speed === 0 && scroll < Math.max(50, scrollBuffer)) {
|
|
@@ -1878,7 +1916,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1878
1916
|
const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
|
|
1879
1917
|
if (dataChanged) {
|
|
1880
1918
|
indexByKey.clear();
|
|
1881
|
-
idCache.
|
|
1919
|
+
idCache.length = 0;
|
|
1882
1920
|
positions.clear();
|
|
1883
1921
|
}
|
|
1884
1922
|
const startIndex = dataChanged ? 0 : (_a = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _a : 0;
|
|
@@ -1894,7 +1932,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1894
1932
|
let endBuffered = null;
|
|
1895
1933
|
let loopStart = !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
|
|
1896
1934
|
for (let i = loopStart; i >= 0; i--) {
|
|
1897
|
-
const id = (_b = idCache
|
|
1935
|
+
const id = (_b = idCache[i]) != null ? _b : getId(state, i);
|
|
1898
1936
|
const top = positions.get(id);
|
|
1899
1937
|
const size = (_c = sizes.get(id)) != null ? _c : getItemSize(state, id, i, data[i]);
|
|
1900
1938
|
const bottom = top + size;
|
|
@@ -1922,7 +1960,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1922
1960
|
let firstFullyOnScreenIndex;
|
|
1923
1961
|
const dataLength = data.length;
|
|
1924
1962
|
for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
|
|
1925
|
-
const id = (_d = idCache
|
|
1963
|
+
const id = (_d = idCache[i]) != null ? _d : getId(state, i);
|
|
1926
1964
|
const size = (_e = sizes.get(id)) != null ? _e : getItemSize(state, id, i, data[i]);
|
|
1927
1965
|
const top = positions.get(id);
|
|
1928
1966
|
if (!foundEnd) {
|
|
@@ -1952,7 +1990,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1952
1990
|
}
|
|
1953
1991
|
const idsInView = [];
|
|
1954
1992
|
for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
|
|
1955
|
-
const id = (_f = idCache
|
|
1993
|
+
const id = (_f = idCache[i]) != null ? _f : getId(state, i);
|
|
1956
1994
|
idsInView.push(id);
|
|
1957
1995
|
}
|
|
1958
1996
|
Object.assign(state, {
|
|
@@ -1984,7 +2022,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1984
2022
|
let numContainers2 = prevNumContainers;
|
|
1985
2023
|
const needNewContainers = [];
|
|
1986
2024
|
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
1987
|
-
const id = (_g = idCache
|
|
2025
|
+
const id = (_g = idCache[i]) != null ? _g : getId(state, i);
|
|
1988
2026
|
if (!containerItemKeys.has(id)) {
|
|
1989
2027
|
needNewContainers.push(i);
|
|
1990
2028
|
}
|
|
@@ -1995,7 +2033,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1995
2033
|
state,
|
|
1996
2034
|
stickyIndicesSet,
|
|
1997
2035
|
stickyIndicesArr,
|
|
1998
|
-
|
|
2036
|
+
currentStickyIdx,
|
|
1999
2037
|
needNewContainers,
|
|
2000
2038
|
startBuffered,
|
|
2001
2039
|
endBuffered
|
|
@@ -2021,7 +2059,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2021
2059
|
for (let idx = 0; idx < needNewContainers.length; idx++) {
|
|
2022
2060
|
const i = needNewContainers[idx];
|
|
2023
2061
|
const containerIndex = availableContainers[idx];
|
|
2024
|
-
const id = (_h = idCache
|
|
2062
|
+
const id = (_h = idCache[i]) != null ? _h : getId(state, i);
|
|
2025
2063
|
const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
2026
2064
|
if (oldKey && oldKey !== id) {
|
|
2027
2065
|
containerItemKeys.delete(oldKey);
|
|
@@ -2035,7 +2073,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2035
2073
|
if (stickyIndicesSet.has(i)) {
|
|
2036
2074
|
set$(ctx, `containerSticky${containerIndex}`, true);
|
|
2037
2075
|
const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
2038
|
-
set$(ctx, `containerStickyOffset${containerIndex}`,
|
|
2076
|
+
set$(ctx, `containerStickyOffset${containerIndex}`, topPadding);
|
|
2039
2077
|
state.stickyContainerPool.add(containerIndex);
|
|
2040
2078
|
} else {
|
|
2041
2079
|
set$(ctx, `containerSticky${containerIndex}`, false);
|
|
@@ -2054,7 +2092,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2054
2092
|
}
|
|
2055
2093
|
}
|
|
2056
2094
|
if (stickyIndicesArr.length > 0) {
|
|
2057
|
-
handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, pendingRemoval);
|
|
2095
|
+
handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
|
|
2058
2096
|
}
|
|
2059
2097
|
for (let i = 0; i < numContainers; i++) {
|
|
2060
2098
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
@@ -2076,7 +2114,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2076
2114
|
const itemIndex = indexByKey.get(itemKey);
|
|
2077
2115
|
const item = data[itemIndex];
|
|
2078
2116
|
if (item !== void 0) {
|
|
2079
|
-
const id = (_i = idCache
|
|
2117
|
+
const id = (_i = idCache[itemIndex]) != null ? _i : getId(state, itemIndex);
|
|
2080
2118
|
const position = positions.get(id);
|
|
2081
2119
|
if (position === void 0) {
|
|
2082
2120
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
@@ -2106,6 +2144,12 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2106
2144
|
if (viewabilityConfigCallbackPairs) {
|
|
2107
2145
|
updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollLength, startNoBuffer, endNoBuffer);
|
|
2108
2146
|
}
|
|
2147
|
+
if (onStickyHeaderChange && stickyIndicesArr.length > 0 && nextActiveStickyIndex !== void 0 && nextActiveStickyIndex !== previousStickyIndex) {
|
|
2148
|
+
const item = data[nextActiveStickyIndex];
|
|
2149
|
+
if (item !== void 0) {
|
|
2150
|
+
onStickyHeaderChange({ index: nextActiveStickyIndex, item });
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2109
2153
|
});
|
|
2110
2154
|
}
|
|
2111
2155
|
|
|
@@ -2264,7 +2308,9 @@ function doInitialAllocateContainers(ctx, state) {
|
|
|
2264
2308
|
let totalSize = 0;
|
|
2265
2309
|
const num = Math.min(20, data.length);
|
|
2266
2310
|
for (let i = 0; i < num; i++) {
|
|
2267
|
-
|
|
2311
|
+
const item = data[i];
|
|
2312
|
+
const itemType = getItemType ? (_a = getItemType(item, i)) != null ? _a : "" : "";
|
|
2313
|
+
totalSize += fn(i, item, itemType);
|
|
2268
2314
|
}
|
|
2269
2315
|
averageItemSize = totalSize / num;
|
|
2270
2316
|
} else {
|
|
@@ -2293,7 +2339,9 @@ function doInitialAllocateContainers(ctx, state) {
|
|
|
2293
2339
|
// src/core/handleLayout.ts
|
|
2294
2340
|
function handleLayout(ctx, state, layout, setCanRender) {
|
|
2295
2341
|
const { maintainScrollAtEnd } = state.props;
|
|
2296
|
-
const
|
|
2342
|
+
const measuredLength = layout[state.props.horizontal ? "width" : "height"];
|
|
2343
|
+
const previousLength = state.scrollLength;
|
|
2344
|
+
const scrollLength = measuredLength > 0 ? measuredLength : previousLength;
|
|
2297
2345
|
const otherAxisSize = layout[state.props.horizontal ? "height" : "width"];
|
|
2298
2346
|
const needsCalculate = !state.lastLayout || scrollLength > state.scrollLength || state.lastLayout.x !== layout.x || state.lastLayout.y !== layout.y;
|
|
2299
2347
|
state.lastLayout = layout;
|
|
@@ -2304,7 +2352,9 @@ function handleLayout(ctx, state, layout, setCanRender) {
|
|
|
2304
2352
|
state.otherAxisSize = otherAxisSize;
|
|
2305
2353
|
state.lastBatchingAction = Date.now();
|
|
2306
2354
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
2307
|
-
|
|
2355
|
+
if (scrollLength > 0) {
|
|
2356
|
+
doInitialAllocateContainers(ctx, state);
|
|
2357
|
+
}
|
|
2308
2358
|
if (needsCalculate) {
|
|
2309
2359
|
calculateItemsInView(ctx, state, { doMVCP: true });
|
|
2310
2360
|
}
|
|
@@ -2320,14 +2370,14 @@ function handleLayout(ctx, state, layout, setCanRender) {
|
|
|
2320
2370
|
if (state) {
|
|
2321
2371
|
state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
|
|
2322
2372
|
}
|
|
2323
|
-
if (__DEV__ &&
|
|
2373
|
+
if (__DEV__ && measuredLength === 0) {
|
|
2324
2374
|
warnDevOnce(
|
|
2325
2375
|
"height0",
|
|
2326
2376
|
`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.`
|
|
2327
2377
|
);
|
|
2328
2378
|
}
|
|
2329
|
-
setCanRender(true);
|
|
2330
2379
|
}
|
|
2380
|
+
setCanRender(true);
|
|
2331
2381
|
}
|
|
2332
2382
|
|
|
2333
2383
|
// src/core/onScroll.ts
|
|
@@ -2577,18 +2627,59 @@ function getRenderedItem(ctx, state, key) {
|
|
|
2577
2627
|
return null;
|
|
2578
2628
|
}
|
|
2579
2629
|
let renderedItem = null;
|
|
2580
|
-
|
|
2630
|
+
const extraData = peek$(ctx, "extraData");
|
|
2631
|
+
const item = data[index];
|
|
2632
|
+
if (renderItem && !isNullOrUndefined(item)) {
|
|
2581
2633
|
const itemProps = {
|
|
2582
2634
|
data,
|
|
2583
|
-
extraData
|
|
2635
|
+
extraData,
|
|
2584
2636
|
index,
|
|
2585
|
-
item
|
|
2586
|
-
type: getItemType ? (_a = getItemType(
|
|
2637
|
+
item,
|
|
2638
|
+
type: getItemType ? (_a = getItemType(item, index)) != null ? _a : "" : ""
|
|
2587
2639
|
};
|
|
2588
2640
|
renderedItem = isFunction(renderItem) ? renderItem(itemProps) : React2__default.createElement(renderItem, itemProps);
|
|
2589
2641
|
}
|
|
2590
2642
|
return { index, item: data[index], renderedItem };
|
|
2591
2643
|
}
|
|
2644
|
+
function useThrottleDebounce(mode) {
|
|
2645
|
+
const timeoutRef = useRef(null);
|
|
2646
|
+
const lastCallTimeRef = useRef(0);
|
|
2647
|
+
const lastArgsRef = useRef(null);
|
|
2648
|
+
const clearTimeoutRef = () => {
|
|
2649
|
+
if (timeoutRef.current) {
|
|
2650
|
+
clearTimeout(timeoutRef.current);
|
|
2651
|
+
timeoutRef.current = null;
|
|
2652
|
+
}
|
|
2653
|
+
};
|
|
2654
|
+
const execute = useCallback(
|
|
2655
|
+
(callback, delay, ...args) => {
|
|
2656
|
+
{
|
|
2657
|
+
const now = Date.now();
|
|
2658
|
+
lastArgsRef.current = args;
|
|
2659
|
+
if (now - lastCallTimeRef.current >= delay) {
|
|
2660
|
+
lastCallTimeRef.current = now;
|
|
2661
|
+
callback(...args);
|
|
2662
|
+
clearTimeoutRef();
|
|
2663
|
+
} else {
|
|
2664
|
+
clearTimeoutRef();
|
|
2665
|
+
timeoutRef.current = setTimeout(
|
|
2666
|
+
() => {
|
|
2667
|
+
if (lastArgsRef.current) {
|
|
2668
|
+
lastCallTimeRef.current = Date.now();
|
|
2669
|
+
callback(...lastArgsRef.current);
|
|
2670
|
+
timeoutRef.current = null;
|
|
2671
|
+
lastArgsRef.current = null;
|
|
2672
|
+
}
|
|
2673
|
+
},
|
|
2674
|
+
delay - (now - lastCallTimeRef.current)
|
|
2675
|
+
);
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
},
|
|
2679
|
+
[mode]
|
|
2680
|
+
);
|
|
2681
|
+
return execute;
|
|
2682
|
+
}
|
|
2592
2683
|
|
|
2593
2684
|
// src/utils/throttledOnScroll.ts
|
|
2594
2685
|
function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
|
|
@@ -2652,6 +2743,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2652
2743
|
onScroll: onScrollProp,
|
|
2653
2744
|
onStartReached,
|
|
2654
2745
|
onStartReachedThreshold = 0.5,
|
|
2746
|
+
onStickyHeaderChange,
|
|
2655
2747
|
onViewableItemsChanged,
|
|
2656
2748
|
progressViewOffset,
|
|
2657
2749
|
recycleItems = false,
|
|
@@ -2699,7 +2791,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2699
2791
|
endNoBuffer: -1,
|
|
2700
2792
|
endReachedBlockedByTimer: false,
|
|
2701
2793
|
firstFullyOnScreenIndex: -1,
|
|
2702
|
-
idCache:
|
|
2794
|
+
idCache: [],
|
|
2703
2795
|
idsInView: [],
|
|
2704
2796
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
2705
2797
|
initialScroll,
|
|
@@ -2774,6 +2866,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2774
2866
|
onScroll: throttleScrollFn,
|
|
2775
2867
|
onStartReached,
|
|
2776
2868
|
onStartReachedThreshold,
|
|
2869
|
+
onStickyHeaderChange,
|
|
2777
2870
|
recycleItems: !!recycleItems,
|
|
2778
2871
|
renderItem,
|
|
2779
2872
|
scrollBuffer,
|
|
@@ -2868,7 +2961,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2868
2961
|
}
|
|
2869
2962
|
}, [snapToIndices]);
|
|
2870
2963
|
useLayoutEffect(() => {
|
|
2871
|
-
const didAllocateContainers = dataProp.length > 0 &&
|
|
2964
|
+
const didAllocateContainers = dataProp.length > 0 && doInitialAllocateContainers(ctx, state);
|
|
2872
2965
|
if (!didAllocateContainers) {
|
|
2873
2966
|
checkResetContainers(
|
|
2874
2967
|
ctx,
|
|
@@ -2882,30 +2975,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2882
2975
|
useLayoutEffect(() => {
|
|
2883
2976
|
set$(ctx, "extraData", extraData);
|
|
2884
2977
|
}, [extraData]);
|
|
2885
|
-
useLayoutEffect(() => {
|
|
2886
|
-
var _a2;
|
|
2887
|
-
if (IsNewArchitecture) {
|
|
2888
|
-
let measured;
|
|
2889
|
-
(_a2 = refScroller.current) == null ? void 0 : _a2.measure((x, y, width, height) => {
|
|
2890
|
-
measured = { height, width, x, y };
|
|
2891
|
-
});
|
|
2892
|
-
if (measured) {
|
|
2893
|
-
const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
|
|
2894
|
-
if (size) {
|
|
2895
|
-
handleLayout(ctx, state, measured, setCanRender);
|
|
2896
|
-
}
|
|
2897
|
-
}
|
|
2898
|
-
}
|
|
2899
|
-
}, []);
|
|
2900
2978
|
useLayoutEffect(initializeStateVars, [
|
|
2901
2979
|
memoizedLastItemKeys.join(","),
|
|
2902
2980
|
numColumnsProp,
|
|
2903
2981
|
stylePaddingTopState,
|
|
2904
2982
|
stylePaddingBottomState
|
|
2905
2983
|
]);
|
|
2906
|
-
const doInitialAllocateContainersCallback = () => {
|
|
2907
|
-
return doInitialAllocateContainers(ctx, state);
|
|
2908
|
-
};
|
|
2909
2984
|
useEffect(() => {
|
|
2910
2985
|
const viewability = setupViewability({
|
|
2911
2986
|
onViewableItemsChanged,
|
|
@@ -2917,16 +2992,18 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2917
2992
|
}, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
|
|
2918
2993
|
if (!IsNewArchitecture) {
|
|
2919
2994
|
useInit(() => {
|
|
2920
|
-
|
|
2995
|
+
doInitialAllocateContainers(ctx, state);
|
|
2921
2996
|
});
|
|
2922
2997
|
}
|
|
2923
|
-
const
|
|
2924
|
-
const layout = event.nativeEvent.layout;
|
|
2998
|
+
const onLayoutChange = useCallback((layout) => {
|
|
2925
2999
|
handleLayout(ctx, state, layout, setCanRender);
|
|
2926
|
-
if (onLayoutProp) {
|
|
2927
|
-
onLayoutProp(event);
|
|
2928
|
-
}
|
|
2929
3000
|
}, []);
|
|
3001
|
+
const { onLayout } = useOnLayoutSync({
|
|
3002
|
+
onLayoutChange,
|
|
3003
|
+
onLayoutProp,
|
|
3004
|
+
ref: refScroller
|
|
3005
|
+
// the type of ScrollView doesn't include measure?
|
|
3006
|
+
});
|
|
2930
3007
|
useImperativeHandle(forwardedRef, () => {
|
|
2931
3008
|
const scrollIndexIntoView = (options) => {
|
|
2932
3009
|
const state2 = refState.current;
|