@legendapp/list 1.0.11 → 1.0.13
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 +14 -0
- package/index.d.mts +2 -0
- package/index.d.ts +2 -0
- package/index.js +118 -68
- package/index.mjs +118 -68
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## 1.0.13
|
|
2
|
+
- Fix: Missing React import in ListHeaderComponentContainer crashing some environments
|
|
3
|
+
- Fix: `initialScrollIndex` was off by padding if using "padding" or "paddingVertical" props
|
|
4
|
+
|
|
5
|
+
## 1.0.12
|
|
6
|
+
- Fix: Initial scroll index and scrollTo were not compensating for top padding
|
|
7
|
+
- Fix: Removed an overly aggressive optimization that was sometimes causing blank spaces after scrolling
|
|
8
|
+
- Fix: Adding a lot of items to the end with maintainScrollAtEnd could result in a large blank space
|
|
9
|
+
- Fix: ListHeaderComponent sometimes not positioned correctly with maintainVisibleContentPosition
|
|
10
|
+
- Fix: Gap styles not working with maintainVisibleContentPosition
|
|
11
|
+
|
|
12
|
+
## 1.0.11
|
|
13
|
+
- Fix: scrollTo was sometimes showing gaps at the bottom or bottom after reaching the destination
|
|
14
|
+
|
|
1
15
|
## 1.0.10
|
|
2
16
|
- Fix: Removed an optimization that only checked newly visible items, which could sometimes cause gaps in lists
|
|
3
17
|
- Fix: Scroll history resets properly during scroll operations, which was causing gaps after scroll
|
package/index.d.mts
CHANGED
|
@@ -244,6 +244,7 @@ interface InternalState {
|
|
|
244
244
|
startNoBuffer: number;
|
|
245
245
|
endBuffered: number;
|
|
246
246
|
endNoBuffer: number;
|
|
247
|
+
scrollPending: number;
|
|
247
248
|
scroll: number;
|
|
248
249
|
scrollTime: number;
|
|
249
250
|
scrollPrev: number;
|
|
@@ -278,6 +279,7 @@ interface InternalState {
|
|
|
278
279
|
ignoreScrollFromCalcTotal?: boolean;
|
|
279
280
|
disableScrollJumpsFrom?: number;
|
|
280
281
|
scrollingToOffset?: number | undefined;
|
|
282
|
+
previousTotalSize?: number;
|
|
281
283
|
averageSizes: Record<string, {
|
|
282
284
|
num: number;
|
|
283
285
|
avg: number;
|
package/index.d.ts
CHANGED
|
@@ -244,6 +244,7 @@ interface InternalState {
|
|
|
244
244
|
startNoBuffer: number;
|
|
245
245
|
endBuffered: number;
|
|
246
246
|
endNoBuffer: number;
|
|
247
|
+
scrollPending: number;
|
|
247
248
|
scroll: number;
|
|
248
249
|
scrollTime: number;
|
|
249
250
|
scrollPrev: number;
|
|
@@ -278,6 +279,7 @@ interface InternalState {
|
|
|
278
279
|
ignoreScrollFromCalcTotal?: boolean;
|
|
279
280
|
disableScrollJumpsFrom?: number;
|
|
280
281
|
scrollingToOffset?: number | undefined;
|
|
282
|
+
previousTotalSize?: number;
|
|
281
283
|
averageSizes: Record<string, {
|
|
282
284
|
num: number;
|
|
283
285
|
avg: number;
|
package/index.js
CHANGED
|
@@ -206,6 +206,13 @@ function comparatorByDistance(a, b) {
|
|
|
206
206
|
function comparatorDefault(a, b) {
|
|
207
207
|
return a - b;
|
|
208
208
|
}
|
|
209
|
+
function getPadding(s) {
|
|
210
|
+
var _a, _b, _c;
|
|
211
|
+
return (_c = (_b = (_a = s.paddingTop) != null ? _a : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
|
|
212
|
+
}
|
|
213
|
+
function extractPaddingTop(style, contentContainerStyle) {
|
|
214
|
+
return getPadding(style) + getPadding(contentContainerStyle);
|
|
215
|
+
}
|
|
209
216
|
var symbolFirst = Symbol();
|
|
210
217
|
function useInit(cb) {
|
|
211
218
|
const refValue = React2.useRef(symbolFirst);
|
|
@@ -449,7 +456,7 @@ var Container = ({
|
|
|
449
456
|
anchorStyle.borderColor = position.type === "top" ? "red" : "blue";
|
|
450
457
|
anchorStyle.borderWidth = 1;
|
|
451
458
|
}
|
|
452
|
-
return /* @__PURE__ */ React2__namespace.default.createElement(LeanView, { style }, /* @__PURE__ */ React2__namespace.default.createElement(LeanView, { style: anchorStyle, onLayout, ref }, contentFragment, __DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React2__namespace.default.createElement(reactNative.Text, { style: { position: "absolute", top: 0, left: 0, zIndex: 1e3 } }, position.top)));
|
|
459
|
+
return /* @__PURE__ */ React2__namespace.default.createElement(LeanView, { style }, /* @__PURE__ */ React2__namespace.default.createElement(LeanView, { style: [anchorStyle, paddingStyles], onLayout, ref }, contentFragment, __DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React2__namespace.default.createElement(reactNative.Text, { style: { position: "absolute", top: 0, left: 0, zIndex: 1e3 } }, position.top)));
|
|
453
460
|
}
|
|
454
461
|
return /* @__PURE__ */ React2__namespace.default.createElement(LeanView, { style, onLayout, ref }, contentFragment);
|
|
455
462
|
};
|
|
@@ -535,6 +542,31 @@ var Containers = typedMemo(function Containers2({
|
|
|
535
542
|
}
|
|
536
543
|
return /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { style }, containers);
|
|
537
544
|
});
|
|
545
|
+
function ListHeaderComponentContainer({
|
|
546
|
+
children,
|
|
547
|
+
style,
|
|
548
|
+
ctx,
|
|
549
|
+
horizontal,
|
|
550
|
+
waitForInitialLayout
|
|
551
|
+
}) {
|
|
552
|
+
const scrollAdjust = useValue$("scrollAdjust", (v) => v, true);
|
|
553
|
+
const animOpacity = waitForInitialLayout ? useValue$("containersDidLayout", (value) => value ? 1 : 0) : void 0;
|
|
554
|
+
const additionalSize = {
|
|
555
|
+
transform: [{ translateY: reactNative.Animated.multiply(scrollAdjust, -1) }],
|
|
556
|
+
opacity: animOpacity
|
|
557
|
+
};
|
|
558
|
+
return /* @__PURE__ */ React2__namespace.createElement(
|
|
559
|
+
reactNative.Animated.View,
|
|
560
|
+
{
|
|
561
|
+
style: [style, additionalSize],
|
|
562
|
+
onLayout: (event) => {
|
|
563
|
+
const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
564
|
+
set$(ctx, "headerSize", size);
|
|
565
|
+
}
|
|
566
|
+
},
|
|
567
|
+
children
|
|
568
|
+
);
|
|
569
|
+
}
|
|
538
570
|
|
|
539
571
|
// src/ListComponent.tsx
|
|
540
572
|
var getComponent = (Component) => {
|
|
@@ -648,13 +680,12 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
648
680
|
},
|
|
649
681
|
!ListEmptyComponent && (ENABLE_DEVMODE ? /* @__PURE__ */ React2__namespace.createElement(PaddingAndAdjustDevMode, null) : /* @__PURE__ */ React2__namespace.createElement(PaddingAndAdjust, null)),
|
|
650
682
|
ListHeaderComponent && /* @__PURE__ */ React2__namespace.createElement(
|
|
651
|
-
|
|
683
|
+
ListHeaderComponentContainer,
|
|
652
684
|
{
|
|
653
685
|
style: ListHeaderComponentStyle,
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
}
|
|
686
|
+
ctx,
|
|
687
|
+
horizontal,
|
|
688
|
+
waitForInitialLayout
|
|
658
689
|
},
|
|
659
690
|
getComponent(ListHeaderComponent)
|
|
660
691
|
),
|
|
@@ -1003,7 +1034,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1003
1034
|
callbacks.current.onEndReached = rest.onEndReached;
|
|
1004
1035
|
const contentContainerStyle = { ...reactNative.StyleSheet.flatten(contentContainerStyleProp) };
|
|
1005
1036
|
const style = { ...reactNative.StyleSheet.flatten(styleProp) };
|
|
1006
|
-
const stylePaddingTopState = (
|
|
1037
|
+
const stylePaddingTopState = extractPaddingTop(style, contentContainerStyle);
|
|
1007
1038
|
if (style == null ? void 0 : style.paddingTop) {
|
|
1008
1039
|
style.paddingTop = void 0;
|
|
1009
1040
|
}
|
|
@@ -1052,8 +1083,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1052
1083
|
state.sizes.set(key, size);
|
|
1053
1084
|
return size;
|
|
1054
1085
|
};
|
|
1055
|
-
const calculateOffsetForIndex = (
|
|
1086
|
+
const calculateOffsetForIndex = (indexParam) => {
|
|
1056
1087
|
var _a;
|
|
1088
|
+
const isFromInit = indexParam === void 0;
|
|
1089
|
+
const index = isFromInit ? initialScrollIndex : indexParam;
|
|
1057
1090
|
const data = dataProp;
|
|
1058
1091
|
if (index !== void 0) {
|
|
1059
1092
|
let offset = 0;
|
|
@@ -1072,11 +1105,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1072
1105
|
offset = index * estimatedItemSize;
|
|
1073
1106
|
}
|
|
1074
1107
|
const adjust = peek$(ctx, "containersDidLayout") ? ((_a = refState.current) == null ? void 0 : _a.scrollAdjustHandler.getAppliedAdjust()) || 0 : 0;
|
|
1075
|
-
|
|
1108
|
+
const stylePaddingTop = isFromInit ? stylePaddingTopState : peek$(ctx, "stylePaddingTop");
|
|
1109
|
+
const topPad = (stylePaddingTop != null ? stylePaddingTop : 0) + peek$(ctx, "headerSize");
|
|
1110
|
+
return offset / numColumnsProp - adjust + topPad;
|
|
1076
1111
|
}
|
|
1077
1112
|
return 0;
|
|
1078
1113
|
};
|
|
1079
|
-
const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : React2.useMemo(calculateOffsetForIndex, []);
|
|
1114
|
+
const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : React2.useMemo(() => calculateOffsetForIndex(void 0), []);
|
|
1080
1115
|
if (!refState.current) {
|
|
1081
1116
|
const initialScrollLength = reactNative.Dimensions.get("window")[horizontal ? "width" : "height"];
|
|
1082
1117
|
refState.current = {
|
|
@@ -1105,6 +1140,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1105
1140
|
scrollPrev: 0,
|
|
1106
1141
|
scrollPrevTime: 0,
|
|
1107
1142
|
scrollTime: 0,
|
|
1143
|
+
scrollPending: 0,
|
|
1108
1144
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
1109
1145
|
scrollHistory: [],
|
|
1110
1146
|
scrollVelocity: 0,
|
|
@@ -1173,11 +1209,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1173
1209
|
const firstIndexOffset = calculateOffsetForIndex(index);
|
|
1174
1210
|
let firstIndexScrollPostion = firstIndexOffset - viewOffset;
|
|
1175
1211
|
const diff = Math.abs(state.scroll - firstIndexScrollPostion);
|
|
1212
|
+
const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
|
|
1176
1213
|
const needsReanchoring = maintainVisibleContentPosition && diff > 100;
|
|
1177
1214
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
1178
1215
|
if (needsReanchoring) {
|
|
1179
1216
|
const id = getId(index);
|
|
1180
|
-
state.anchorElement = { id, coordinate: firstIndexOffset };
|
|
1217
|
+
state.anchorElement = { id, coordinate: firstIndexOffset - topPad };
|
|
1181
1218
|
(_a = state.belowAnchorElementPositions) == null ? void 0 : _a.clear();
|
|
1182
1219
|
state.positions.clear();
|
|
1183
1220
|
calcTotalSizesAndPositions({ forgetPositions: true });
|
|
@@ -1297,6 +1334,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1297
1334
|
state.scrollHistory.length = 0;
|
|
1298
1335
|
setTimeout(() => {
|
|
1299
1336
|
state.disableScrollJumpsFrom = void 0;
|
|
1337
|
+
if (state.scrollPending !== void 0 && state.scrollPending !== state.scroll) {
|
|
1338
|
+
updateScroll(state.scrollPending);
|
|
1339
|
+
}
|
|
1300
1340
|
}, timeout);
|
|
1301
1341
|
}
|
|
1302
1342
|
};
|
|
@@ -1410,7 +1450,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1410
1450
|
const numColumns = peek$(ctx, "numColumns");
|
|
1411
1451
|
const previousScrollAdjust = scrollAdjustHandler.getAppliedAdjust();
|
|
1412
1452
|
let scrollState = state.scroll;
|
|
1413
|
-
const scrollExtra =
|
|
1453
|
+
const scrollExtra = 0;
|
|
1414
1454
|
const useAverageSize = !state.disableScrollJumpsFrom && speed >= 0 && peek$(ctx, "containersDidLayout");
|
|
1415
1455
|
if (!state.queuedInitialLayout && initialScrollIndex) {
|
|
1416
1456
|
const updatedOffset = calculateOffsetForIndex(initialScrollIndex);
|
|
@@ -1719,6 +1759,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1719
1759
|
if (paddingTop > 0) {
|
|
1720
1760
|
state.scroll = 0;
|
|
1721
1761
|
}
|
|
1762
|
+
state.disableScrollJumpsFrom = void 0;
|
|
1722
1763
|
requestAnimationFrame(() => {
|
|
1723
1764
|
var _a;
|
|
1724
1765
|
state.maintainingScrollAtEnd = true;
|
|
@@ -1808,8 +1849,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1808
1849
|
if (state) {
|
|
1809
1850
|
state.data = dataProp;
|
|
1810
1851
|
if (!isFirst2) {
|
|
1811
|
-
|
|
1812
|
-
|
|
1852
|
+
const totalSizeBefore = state.previousTotalSize;
|
|
1853
|
+
const totalSizeAfter = state.totalSize;
|
|
1854
|
+
const scrollDiff = state.scroll - state.scrollPrev;
|
|
1855
|
+
const sizeDiff = totalSizeAfter - totalSizeBefore;
|
|
1856
|
+
if (Math.abs(scrollDiff - sizeDiff) < 10) {
|
|
1857
|
+
disableScrollJumps(1e3);
|
|
1858
|
+
}
|
|
1813
1859
|
const numContainers = peek$(ctx, "numContainers");
|
|
1814
1860
|
for (let i = 0; i < numContainers; i++) {
|
|
1815
1861
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
@@ -2020,6 +2066,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2020
2066
|
refState.current.sizes.clear();
|
|
2021
2067
|
refState.current.positions.clear();
|
|
2022
2068
|
}
|
|
2069
|
+
refState.current.previousTotalSize = peek$(ctx, "totalSize");
|
|
2023
2070
|
calcTotalSizesAndPositions({ forgetPositions: false });
|
|
2024
2071
|
}
|
|
2025
2072
|
React2.useEffect(() => {
|
|
@@ -2227,73 +2274,76 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2227
2274
|
}
|
|
2228
2275
|
}, []);
|
|
2229
2276
|
const handleScroll = React2.useCallback(
|
|
2230
|
-
(event
|
|
2277
|
+
(event) => {
|
|
2231
2278
|
var _a, _b, _c, _d;
|
|
2232
2279
|
if (((_b = (_a = event.nativeEvent) == null ? void 0 : _a.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
|
|
2233
2280
|
return;
|
|
2234
2281
|
}
|
|
2235
2282
|
const state = refState.current;
|
|
2236
|
-
const scrollingToOffset = state.scrollingToOffset;
|
|
2237
2283
|
const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
|
|
2284
|
+
state.scrollPending = newScroll;
|
|
2238
2285
|
if (state.ignoreScrollFromCalcTotal && newScroll !== 0) {
|
|
2239
2286
|
return;
|
|
2240
2287
|
}
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2288
|
+
updateScroll(newScroll);
|
|
2289
|
+
(_d = state.onScroll) == null ? void 0 : _d.call(state, event);
|
|
2290
|
+
},
|
|
2291
|
+
[]
|
|
2292
|
+
);
|
|
2293
|
+
const updateScroll = React2.useCallback((newScroll) => {
|
|
2294
|
+
const state = refState.current;
|
|
2295
|
+
const scrollingToOffset = state.scrollingToOffset;
|
|
2296
|
+
if (scrollingToOffset !== void 0 && Math.abs(newScroll - scrollingToOffset) < 10) {
|
|
2297
|
+
finishScrollTo();
|
|
2298
|
+
}
|
|
2299
|
+
if (state.disableScrollJumpsFrom !== void 0) {
|
|
2300
|
+
const scrollMinusAdjust = newScroll - state.scrollAdjustHandler.getAppliedAdjust();
|
|
2301
|
+
if (Math.abs(scrollMinusAdjust - state.disableScrollJumpsFrom) > 200) {
|
|
2302
|
+
return;
|
|
2250
2303
|
}
|
|
2251
|
-
state.
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
state.scrollTimer
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
if (oldest) {
|
|
2278
|
-
const scrollDiff = newest.scroll - oldest.scroll;
|
|
2279
|
-
const timeDiff = newest.time - oldest.time;
|
|
2280
|
-
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
2304
|
+
state.disableScrollJumpsFrom = void 0;
|
|
2305
|
+
}
|
|
2306
|
+
state.hasScrolled = true;
|
|
2307
|
+
state.lastBatchingAction = Date.now();
|
|
2308
|
+
const currentTime = performance.now();
|
|
2309
|
+
if (scrollingToOffset === void 0 && !(state.scrollHistory.length === 0 && newScroll === initialContentOffset)) {
|
|
2310
|
+
state.scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
2311
|
+
}
|
|
2312
|
+
if (state.scrollHistory.length > 5) {
|
|
2313
|
+
state.scrollHistory.shift();
|
|
2314
|
+
}
|
|
2315
|
+
if (state.scrollTimer !== void 0) {
|
|
2316
|
+
clearTimeout(state.scrollTimer);
|
|
2317
|
+
}
|
|
2318
|
+
state.scrollTimer = setTimeout(() => {
|
|
2319
|
+
state.scrollVelocity = 0;
|
|
2320
|
+
}, 500);
|
|
2321
|
+
let velocity = 0;
|
|
2322
|
+
if (state.scrollHistory.length >= 2) {
|
|
2323
|
+
const newest = state.scrollHistory[state.scrollHistory.length - 1];
|
|
2324
|
+
let oldest;
|
|
2325
|
+
for (let i = 0; i < state.scrollHistory.length - 1; i++) {
|
|
2326
|
+
const entry = state.scrollHistory[i];
|
|
2327
|
+
if (newest.time - entry.time <= 100) {
|
|
2328
|
+
oldest = entry;
|
|
2329
|
+
break;
|
|
2281
2330
|
}
|
|
2282
2331
|
}
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
state.scrollVelocity = velocity;
|
|
2288
|
-
calculateItemsInView();
|
|
2289
|
-
checkAtBottom();
|
|
2290
|
-
checkAtTop();
|
|
2291
|
-
if (!fromSelf) {
|
|
2292
|
-
(_d = state.onScroll) == null ? void 0 : _d.call(state, event);
|
|
2332
|
+
if (oldest) {
|
|
2333
|
+
const scrollDiff = newest.scroll - oldest.scroll;
|
|
2334
|
+
const timeDiff = newest.time - oldest.time;
|
|
2335
|
+
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
2293
2336
|
}
|
|
2294
|
-
}
|
|
2295
|
-
|
|
2296
|
-
|
|
2337
|
+
}
|
|
2338
|
+
state.scrollPrev = state.scroll;
|
|
2339
|
+
state.scrollPrevTime = state.scrollTime;
|
|
2340
|
+
state.scroll = newScroll;
|
|
2341
|
+
state.scrollTime = currentTime;
|
|
2342
|
+
state.scrollVelocity = velocity;
|
|
2343
|
+
calculateItemsInView();
|
|
2344
|
+
checkAtBottom();
|
|
2345
|
+
checkAtTop();
|
|
2346
|
+
}, []);
|
|
2297
2347
|
React2.useImperativeHandle(
|
|
2298
2348
|
forwardedRef,
|
|
2299
2349
|
() => {
|
package/index.mjs
CHANGED
|
@@ -185,6 +185,13 @@ function comparatorByDistance(a, b) {
|
|
|
185
185
|
function comparatorDefault(a, b) {
|
|
186
186
|
return a - b;
|
|
187
187
|
}
|
|
188
|
+
function getPadding(s) {
|
|
189
|
+
var _a, _b, _c;
|
|
190
|
+
return (_c = (_b = (_a = s.paddingTop) != null ? _a : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
|
|
191
|
+
}
|
|
192
|
+
function extractPaddingTop(style, contentContainerStyle) {
|
|
193
|
+
return getPadding(style) + getPadding(contentContainerStyle);
|
|
194
|
+
}
|
|
188
195
|
var symbolFirst = Symbol();
|
|
189
196
|
function useInit(cb) {
|
|
190
197
|
const refValue = useRef(symbolFirst);
|
|
@@ -428,7 +435,7 @@ var Container = ({
|
|
|
428
435
|
anchorStyle.borderColor = position.type === "top" ? "red" : "blue";
|
|
429
436
|
anchorStyle.borderWidth = 1;
|
|
430
437
|
}
|
|
431
|
-
return /* @__PURE__ */ React2__default.createElement(LeanView, { style }, /* @__PURE__ */ React2__default.createElement(LeanView, { style: anchorStyle, onLayout, ref }, contentFragment, __DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React2__default.createElement(Text, { style: { position: "absolute", top: 0, left: 0, zIndex: 1e3 } }, position.top)));
|
|
438
|
+
return /* @__PURE__ */ React2__default.createElement(LeanView, { style }, /* @__PURE__ */ React2__default.createElement(LeanView, { style: [anchorStyle, paddingStyles], onLayout, ref }, contentFragment, __DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React2__default.createElement(Text, { style: { position: "absolute", top: 0, left: 0, zIndex: 1e3 } }, position.top)));
|
|
432
439
|
}
|
|
433
440
|
return /* @__PURE__ */ React2__default.createElement(LeanView, { style, onLayout, ref }, contentFragment);
|
|
434
441
|
};
|
|
@@ -514,6 +521,31 @@ var Containers = typedMemo(function Containers2({
|
|
|
514
521
|
}
|
|
515
522
|
return /* @__PURE__ */ React2.createElement(Animated.View, { style }, containers);
|
|
516
523
|
});
|
|
524
|
+
function ListHeaderComponentContainer({
|
|
525
|
+
children,
|
|
526
|
+
style,
|
|
527
|
+
ctx,
|
|
528
|
+
horizontal,
|
|
529
|
+
waitForInitialLayout
|
|
530
|
+
}) {
|
|
531
|
+
const scrollAdjust = useValue$("scrollAdjust", (v) => v, true);
|
|
532
|
+
const animOpacity = waitForInitialLayout ? useValue$("containersDidLayout", (value) => value ? 1 : 0) : void 0;
|
|
533
|
+
const additionalSize = {
|
|
534
|
+
transform: [{ translateY: Animated.multiply(scrollAdjust, -1) }],
|
|
535
|
+
opacity: animOpacity
|
|
536
|
+
};
|
|
537
|
+
return /* @__PURE__ */ React2.createElement(
|
|
538
|
+
Animated.View,
|
|
539
|
+
{
|
|
540
|
+
style: [style, additionalSize],
|
|
541
|
+
onLayout: (event) => {
|
|
542
|
+
const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
543
|
+
set$(ctx, "headerSize", size);
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
children
|
|
547
|
+
);
|
|
548
|
+
}
|
|
517
549
|
|
|
518
550
|
// src/ListComponent.tsx
|
|
519
551
|
var getComponent = (Component) => {
|
|
@@ -627,13 +659,12 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
627
659
|
},
|
|
628
660
|
!ListEmptyComponent && (ENABLE_DEVMODE ? /* @__PURE__ */ React2.createElement(PaddingAndAdjustDevMode, null) : /* @__PURE__ */ React2.createElement(PaddingAndAdjust, null)),
|
|
629
661
|
ListHeaderComponent && /* @__PURE__ */ React2.createElement(
|
|
630
|
-
|
|
662
|
+
ListHeaderComponentContainer,
|
|
631
663
|
{
|
|
632
664
|
style: ListHeaderComponentStyle,
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
}
|
|
665
|
+
ctx,
|
|
666
|
+
horizontal,
|
|
667
|
+
waitForInitialLayout
|
|
637
668
|
},
|
|
638
669
|
getComponent(ListHeaderComponent)
|
|
639
670
|
),
|
|
@@ -982,7 +1013,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
982
1013
|
callbacks.current.onEndReached = rest.onEndReached;
|
|
983
1014
|
const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
|
|
984
1015
|
const style = { ...StyleSheet.flatten(styleProp) };
|
|
985
|
-
const stylePaddingTopState = (
|
|
1016
|
+
const stylePaddingTopState = extractPaddingTop(style, contentContainerStyle);
|
|
986
1017
|
if (style == null ? void 0 : style.paddingTop) {
|
|
987
1018
|
style.paddingTop = void 0;
|
|
988
1019
|
}
|
|
@@ -1031,8 +1062,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1031
1062
|
state.sizes.set(key, size);
|
|
1032
1063
|
return size;
|
|
1033
1064
|
};
|
|
1034
|
-
const calculateOffsetForIndex = (
|
|
1065
|
+
const calculateOffsetForIndex = (indexParam) => {
|
|
1035
1066
|
var _a;
|
|
1067
|
+
const isFromInit = indexParam === void 0;
|
|
1068
|
+
const index = isFromInit ? initialScrollIndex : indexParam;
|
|
1036
1069
|
const data = dataProp;
|
|
1037
1070
|
if (index !== void 0) {
|
|
1038
1071
|
let offset = 0;
|
|
@@ -1051,11 +1084,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1051
1084
|
offset = index * estimatedItemSize;
|
|
1052
1085
|
}
|
|
1053
1086
|
const adjust = peek$(ctx, "containersDidLayout") ? ((_a = refState.current) == null ? void 0 : _a.scrollAdjustHandler.getAppliedAdjust()) || 0 : 0;
|
|
1054
|
-
|
|
1087
|
+
const stylePaddingTop = isFromInit ? stylePaddingTopState : peek$(ctx, "stylePaddingTop");
|
|
1088
|
+
const topPad = (stylePaddingTop != null ? stylePaddingTop : 0) + peek$(ctx, "headerSize");
|
|
1089
|
+
return offset / numColumnsProp - adjust + topPad;
|
|
1055
1090
|
}
|
|
1056
1091
|
return 0;
|
|
1057
1092
|
};
|
|
1058
|
-
const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : useMemo(calculateOffsetForIndex, []);
|
|
1093
|
+
const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : useMemo(() => calculateOffsetForIndex(void 0), []);
|
|
1059
1094
|
if (!refState.current) {
|
|
1060
1095
|
const initialScrollLength = Dimensions.get("window")[horizontal ? "width" : "height"];
|
|
1061
1096
|
refState.current = {
|
|
@@ -1084,6 +1119,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1084
1119
|
scrollPrev: 0,
|
|
1085
1120
|
scrollPrevTime: 0,
|
|
1086
1121
|
scrollTime: 0,
|
|
1122
|
+
scrollPending: 0,
|
|
1087
1123
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
1088
1124
|
scrollHistory: [],
|
|
1089
1125
|
scrollVelocity: 0,
|
|
@@ -1152,11 +1188,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1152
1188
|
const firstIndexOffset = calculateOffsetForIndex(index);
|
|
1153
1189
|
let firstIndexScrollPostion = firstIndexOffset - viewOffset;
|
|
1154
1190
|
const diff = Math.abs(state.scroll - firstIndexScrollPostion);
|
|
1191
|
+
const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
|
|
1155
1192
|
const needsReanchoring = maintainVisibleContentPosition && diff > 100;
|
|
1156
1193
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
1157
1194
|
if (needsReanchoring) {
|
|
1158
1195
|
const id = getId(index);
|
|
1159
|
-
state.anchorElement = { id, coordinate: firstIndexOffset };
|
|
1196
|
+
state.anchorElement = { id, coordinate: firstIndexOffset - topPad };
|
|
1160
1197
|
(_a = state.belowAnchorElementPositions) == null ? void 0 : _a.clear();
|
|
1161
1198
|
state.positions.clear();
|
|
1162
1199
|
calcTotalSizesAndPositions({ forgetPositions: true });
|
|
@@ -1276,6 +1313,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1276
1313
|
state.scrollHistory.length = 0;
|
|
1277
1314
|
setTimeout(() => {
|
|
1278
1315
|
state.disableScrollJumpsFrom = void 0;
|
|
1316
|
+
if (state.scrollPending !== void 0 && state.scrollPending !== state.scroll) {
|
|
1317
|
+
updateScroll(state.scrollPending);
|
|
1318
|
+
}
|
|
1279
1319
|
}, timeout);
|
|
1280
1320
|
}
|
|
1281
1321
|
};
|
|
@@ -1389,7 +1429,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1389
1429
|
const numColumns = peek$(ctx, "numColumns");
|
|
1390
1430
|
const previousScrollAdjust = scrollAdjustHandler.getAppliedAdjust();
|
|
1391
1431
|
let scrollState = state.scroll;
|
|
1392
|
-
const scrollExtra =
|
|
1432
|
+
const scrollExtra = 0;
|
|
1393
1433
|
const useAverageSize = !state.disableScrollJumpsFrom && speed >= 0 && peek$(ctx, "containersDidLayout");
|
|
1394
1434
|
if (!state.queuedInitialLayout && initialScrollIndex) {
|
|
1395
1435
|
const updatedOffset = calculateOffsetForIndex(initialScrollIndex);
|
|
@@ -1698,6 +1738,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1698
1738
|
if (paddingTop > 0) {
|
|
1699
1739
|
state.scroll = 0;
|
|
1700
1740
|
}
|
|
1741
|
+
state.disableScrollJumpsFrom = void 0;
|
|
1701
1742
|
requestAnimationFrame(() => {
|
|
1702
1743
|
var _a;
|
|
1703
1744
|
state.maintainingScrollAtEnd = true;
|
|
@@ -1787,8 +1828,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1787
1828
|
if (state) {
|
|
1788
1829
|
state.data = dataProp;
|
|
1789
1830
|
if (!isFirst2) {
|
|
1790
|
-
|
|
1791
|
-
|
|
1831
|
+
const totalSizeBefore = state.previousTotalSize;
|
|
1832
|
+
const totalSizeAfter = state.totalSize;
|
|
1833
|
+
const scrollDiff = state.scroll - state.scrollPrev;
|
|
1834
|
+
const sizeDiff = totalSizeAfter - totalSizeBefore;
|
|
1835
|
+
if (Math.abs(scrollDiff - sizeDiff) < 10) {
|
|
1836
|
+
disableScrollJumps(1e3);
|
|
1837
|
+
}
|
|
1792
1838
|
const numContainers = peek$(ctx, "numContainers");
|
|
1793
1839
|
for (let i = 0; i < numContainers; i++) {
|
|
1794
1840
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
@@ -1999,6 +2045,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1999
2045
|
refState.current.sizes.clear();
|
|
2000
2046
|
refState.current.positions.clear();
|
|
2001
2047
|
}
|
|
2048
|
+
refState.current.previousTotalSize = peek$(ctx, "totalSize");
|
|
2002
2049
|
calcTotalSizesAndPositions({ forgetPositions: false });
|
|
2003
2050
|
}
|
|
2004
2051
|
useEffect(() => {
|
|
@@ -2206,73 +2253,76 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2206
2253
|
}
|
|
2207
2254
|
}, []);
|
|
2208
2255
|
const handleScroll = useCallback(
|
|
2209
|
-
(event
|
|
2256
|
+
(event) => {
|
|
2210
2257
|
var _a, _b, _c, _d;
|
|
2211
2258
|
if (((_b = (_a = event.nativeEvent) == null ? void 0 : _a.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
|
|
2212
2259
|
return;
|
|
2213
2260
|
}
|
|
2214
2261
|
const state = refState.current;
|
|
2215
|
-
const scrollingToOffset = state.scrollingToOffset;
|
|
2216
2262
|
const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
|
|
2263
|
+
state.scrollPending = newScroll;
|
|
2217
2264
|
if (state.ignoreScrollFromCalcTotal && newScroll !== 0) {
|
|
2218
2265
|
return;
|
|
2219
2266
|
}
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2267
|
+
updateScroll(newScroll);
|
|
2268
|
+
(_d = state.onScroll) == null ? void 0 : _d.call(state, event);
|
|
2269
|
+
},
|
|
2270
|
+
[]
|
|
2271
|
+
);
|
|
2272
|
+
const updateScroll = useCallback((newScroll) => {
|
|
2273
|
+
const state = refState.current;
|
|
2274
|
+
const scrollingToOffset = state.scrollingToOffset;
|
|
2275
|
+
if (scrollingToOffset !== void 0 && Math.abs(newScroll - scrollingToOffset) < 10) {
|
|
2276
|
+
finishScrollTo();
|
|
2277
|
+
}
|
|
2278
|
+
if (state.disableScrollJumpsFrom !== void 0) {
|
|
2279
|
+
const scrollMinusAdjust = newScroll - state.scrollAdjustHandler.getAppliedAdjust();
|
|
2280
|
+
if (Math.abs(scrollMinusAdjust - state.disableScrollJumpsFrom) > 200) {
|
|
2281
|
+
return;
|
|
2229
2282
|
}
|
|
2230
|
-
state.
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
state.scrollTimer
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
if (oldest) {
|
|
2257
|
-
const scrollDiff = newest.scroll - oldest.scroll;
|
|
2258
|
-
const timeDiff = newest.time - oldest.time;
|
|
2259
|
-
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
2283
|
+
state.disableScrollJumpsFrom = void 0;
|
|
2284
|
+
}
|
|
2285
|
+
state.hasScrolled = true;
|
|
2286
|
+
state.lastBatchingAction = Date.now();
|
|
2287
|
+
const currentTime = performance.now();
|
|
2288
|
+
if (scrollingToOffset === void 0 && !(state.scrollHistory.length === 0 && newScroll === initialContentOffset)) {
|
|
2289
|
+
state.scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
2290
|
+
}
|
|
2291
|
+
if (state.scrollHistory.length > 5) {
|
|
2292
|
+
state.scrollHistory.shift();
|
|
2293
|
+
}
|
|
2294
|
+
if (state.scrollTimer !== void 0) {
|
|
2295
|
+
clearTimeout(state.scrollTimer);
|
|
2296
|
+
}
|
|
2297
|
+
state.scrollTimer = setTimeout(() => {
|
|
2298
|
+
state.scrollVelocity = 0;
|
|
2299
|
+
}, 500);
|
|
2300
|
+
let velocity = 0;
|
|
2301
|
+
if (state.scrollHistory.length >= 2) {
|
|
2302
|
+
const newest = state.scrollHistory[state.scrollHistory.length - 1];
|
|
2303
|
+
let oldest;
|
|
2304
|
+
for (let i = 0; i < state.scrollHistory.length - 1; i++) {
|
|
2305
|
+
const entry = state.scrollHistory[i];
|
|
2306
|
+
if (newest.time - entry.time <= 100) {
|
|
2307
|
+
oldest = entry;
|
|
2308
|
+
break;
|
|
2260
2309
|
}
|
|
2261
2310
|
}
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
state.scrollVelocity = velocity;
|
|
2267
|
-
calculateItemsInView();
|
|
2268
|
-
checkAtBottom();
|
|
2269
|
-
checkAtTop();
|
|
2270
|
-
if (!fromSelf) {
|
|
2271
|
-
(_d = state.onScroll) == null ? void 0 : _d.call(state, event);
|
|
2311
|
+
if (oldest) {
|
|
2312
|
+
const scrollDiff = newest.scroll - oldest.scroll;
|
|
2313
|
+
const timeDiff = newest.time - oldest.time;
|
|
2314
|
+
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
2272
2315
|
}
|
|
2273
|
-
}
|
|
2274
|
-
|
|
2275
|
-
|
|
2316
|
+
}
|
|
2317
|
+
state.scrollPrev = state.scroll;
|
|
2318
|
+
state.scrollPrevTime = state.scrollTime;
|
|
2319
|
+
state.scroll = newScroll;
|
|
2320
|
+
state.scrollTime = currentTime;
|
|
2321
|
+
state.scrollVelocity = velocity;
|
|
2322
|
+
calculateItemsInView();
|
|
2323
|
+
checkAtBottom();
|
|
2324
|
+
checkAtTop();
|
|
2325
|
+
}, []);
|
|
2276
2326
|
useImperativeHandle(
|
|
2277
2327
|
forwardedRef,
|
|
2278
2328
|
() => {
|
package/package.json
CHANGED