@legendapp/list 3.1.0 → 3.1.2
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 +9 -1
- package/animated.d.ts +1 -0
- package/package.json +1 -1
- package/react-native.d.ts +1 -0
- package/react-native.js +94 -73
- package/react-native.mjs +94 -73
- package/react-native.web.d.ts +1 -0
- package/react-native.web.js +94 -73
- package/react-native.web.mjs +94 -73
- package/react.d.ts +1 -0
- package/react.js +94 -73
- package/react.mjs +94 -73
- package/reanimated.d.ts +1 -0
- package/section-list.d.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
## 3.1.2
|
|
2
|
+
|
|
3
|
+
- Fix: On Android, end-aligned lists could double apply scroll clamping during MVCP and be slightly underscrolled
|
|
4
|
+
|
|
5
|
+
## 3.1.1
|
|
6
|
+
|
|
7
|
+
- Fix: `maintainScrollAtEnd` now stays pinned when a `ListFooterComponent` appears, disappears, or changes size, so chat typing indicators and other dynamic footers do not leave the list slightly above the end. If you use an explicit `maintainScrollAtEnd.on` config, add `footerLayout` to opt into footer size changes.
|
|
8
|
+
|
|
1
9
|
## 3.1.0
|
|
2
10
|
|
|
3
|
-
- Feat: Add `experimental_adaptiveRender` with `useAdaptiveRender` and `useAdaptiveRenderChange
|
|
11
|
+
- Feat: Add `experimental_adaptiveRender` prop, with `useAdaptiveRender` and `useAdaptiveRenderChange` hooks, so item components can render a lighter version while the list is moving quickly and return to normal after scrolling slows.
|
|
4
12
|
- Feat: Add `setItemSize` to the list ref for updating a known item's measured size directly when its content changes outside normal layout measurement.
|
|
5
13
|
- Fix: Web maintainVisibleContentPosition keeps the intended anchor when headers change, browser scroll anchoring runs, or an animated `scrollToEnd` is already in progress. #468 #463
|
|
6
14
|
- Fix: `initialScrollIndex` and `initialScrollAtEnd` use the latest initial scroll props when data starts empty and loads later, so lists do not scroll to an old startup target.
|
package/animated.d.ts
CHANGED
package/package.json
CHANGED
package/react-native.d.ts
CHANGED
package/react-native.js
CHANGED
|
@@ -1217,6 +1217,67 @@ function WebAnchoredEndSpace({ horizontal }) {
|
|
|
1217
1217
|
return /* @__PURE__ */ React2__namespace.createElement("div", { style }, null);
|
|
1218
1218
|
}
|
|
1219
1219
|
|
|
1220
|
+
// src/core/doMaintainScrollAtEnd.ts
|
|
1221
|
+
function doMaintainScrollAtEnd(ctx) {
|
|
1222
|
+
const state = ctx.state;
|
|
1223
|
+
const {
|
|
1224
|
+
didContainersLayout,
|
|
1225
|
+
pendingNativeMVCPAdjust,
|
|
1226
|
+
refScroller,
|
|
1227
|
+
props: { maintainScrollAtEnd }
|
|
1228
|
+
} = state;
|
|
1229
|
+
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1230
|
+
const shouldMaintainScrollAtEnd = !!(isWithinMaintainScrollAtEndThreshold && maintainScrollAtEnd && didContainersLayout);
|
|
1231
|
+
if (pendingNativeMVCPAdjust) {
|
|
1232
|
+
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
1233
|
+
return false;
|
|
1234
|
+
}
|
|
1235
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1236
|
+
if (shouldMaintainScrollAtEnd) {
|
|
1237
|
+
const contentSize = getContentSize(ctx);
|
|
1238
|
+
if (contentSize < state.scrollLength) {
|
|
1239
|
+
state.scroll = 0;
|
|
1240
|
+
}
|
|
1241
|
+
if (!state.maintainingScrollAtEnd) {
|
|
1242
|
+
const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
1243
|
+
const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
|
|
1244
|
+
state.maintainingScrollAtEnd = pendingState;
|
|
1245
|
+
requestAnimationFrame(() => {
|
|
1246
|
+
if (peek$(ctx, "isWithinMaintainScrollAtEndThreshold")) {
|
|
1247
|
+
state.maintainingScrollAtEnd = activeState;
|
|
1248
|
+
const scroller = refScroller.current;
|
|
1249
|
+
if (state.props.horizontal && isHorizontalRTL(state)) {
|
|
1250
|
+
const currentContentSize = getContentSize(ctx);
|
|
1251
|
+
const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
|
|
1252
|
+
const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
|
|
1253
|
+
scroller == null ? void 0 : scroller.scrollTo({
|
|
1254
|
+
animated: maintainScrollAtEnd.animated,
|
|
1255
|
+
x: nativeOffset,
|
|
1256
|
+
y: 0
|
|
1257
|
+
});
|
|
1258
|
+
} else {
|
|
1259
|
+
scroller == null ? void 0 : scroller.scrollToEnd({
|
|
1260
|
+
animated: maintainScrollAtEnd.animated
|
|
1261
|
+
});
|
|
1262
|
+
}
|
|
1263
|
+
setTimeout(
|
|
1264
|
+
() => {
|
|
1265
|
+
if (state.maintainingScrollAtEnd === activeState) {
|
|
1266
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1267
|
+
}
|
|
1268
|
+
},
|
|
1269
|
+
maintainScrollAtEnd.animated ? 500 : 0
|
|
1270
|
+
);
|
|
1271
|
+
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
1272
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1273
|
+
}
|
|
1274
|
+
});
|
|
1275
|
+
}
|
|
1276
|
+
return true;
|
|
1277
|
+
}
|
|
1278
|
+
return false;
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1220
1281
|
// src/core/calculateOffsetForIndex.ts
|
|
1221
1282
|
function calculateOffsetForIndex(ctx, index) {
|
|
1222
1283
|
const state = ctx.state;
|
|
@@ -1800,8 +1861,11 @@ function updateAdaptiveRender(ctx, scrollVelocity) {
|
|
|
1800
1861
|
// src/utils/getEffectiveDrawDistance.ts
|
|
1801
1862
|
var INITIAL_DRAW_DISTANCE = 100;
|
|
1802
1863
|
function getEffectiveDrawDistance(ctx) {
|
|
1864
|
+
var _a3;
|
|
1803
1865
|
const drawDistance = ctx.state.props.drawDistance;
|
|
1804
|
-
|
|
1866
|
+
const initialScroll = ctx.state.initialScroll;
|
|
1867
|
+
const needsFullInitialDrawDistance = initialScroll !== void 0 && ((_a3 = initialScroll.viewPosition) != null ? _a3 : 0) > 0;
|
|
1868
|
+
return peek$(ctx, "readyToRender") || needsFullInitialDrawDistance ? drawDistance : Math.min(drawDistance, INITIAL_DRAW_DISTANCE);
|
|
1805
1869
|
}
|
|
1806
1870
|
|
|
1807
1871
|
// src/utils/setInitialRenderState.ts
|
|
@@ -2184,10 +2248,12 @@ function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
|
2184
2248
|
// src/core/updateContentMetrics.ts
|
|
2185
2249
|
var SCROLL_ADJUST_EPSILON = 0.1;
|
|
2186
2250
|
function setContentLengthSignal(ctx, signalName, size) {
|
|
2187
|
-
|
|
2251
|
+
const didChange = peek$(ctx, signalName) !== size;
|
|
2252
|
+
if (didChange) {
|
|
2188
2253
|
set$(ctx, signalName, size);
|
|
2189
2254
|
updateContentMetricsState(ctx);
|
|
2190
2255
|
}
|
|
2256
|
+
return didChange;
|
|
2191
2257
|
}
|
|
2192
2258
|
function shouldAdjustForHeaderSizeChange(ctx, previousHeaderSize, nextHeaderSize) {
|
|
2193
2259
|
const { didContainersLayout, didFinishInitialScroll, props, scroll, scrollingTo } = ctx.state;
|
|
@@ -2211,7 +2277,7 @@ function setHeaderSize(ctx, size) {
|
|
|
2211
2277
|
state.didMeasureHeader = true;
|
|
2212
2278
|
}
|
|
2213
2279
|
function setFooterSize(ctx, size) {
|
|
2214
|
-
setContentLengthSignal(ctx, "footerSize", size);
|
|
2280
|
+
return setContentLengthSignal(ctx, "footerSize", size);
|
|
2215
2281
|
}
|
|
2216
2282
|
function areInsetsEqual(left, right) {
|
|
2217
2283
|
var _a3, _b, _c, _d, _e, _f, _g, _h;
|
|
@@ -2312,14 +2378,25 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
2312
2378
|
);
|
|
2313
2379
|
const ScrollComponent = renderScrollComponent ? CustomScrollComponent : ListComponentScrollView;
|
|
2314
2380
|
const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
|
|
2381
|
+
const updateFooterSize = React2.useCallback(
|
|
2382
|
+
(size, afterSizeUpdate) => {
|
|
2383
|
+
var _a3;
|
|
2384
|
+
const didFooterSizeChange = setFooterSize(ctx, size);
|
|
2385
|
+
afterSizeUpdate == null ? void 0 : afterSizeUpdate();
|
|
2386
|
+
if (didFooterSizeChange && ((_a3 = ctx.state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onFooterLayout)) {
|
|
2387
|
+
doMaintainScrollAtEnd(ctx);
|
|
2388
|
+
}
|
|
2389
|
+
},
|
|
2390
|
+
[ctx]
|
|
2391
|
+
);
|
|
2315
2392
|
React2.useLayoutEffect(() => {
|
|
2316
2393
|
if (!ListHeaderComponent) {
|
|
2317
2394
|
setHeaderSize(ctx, 0);
|
|
2318
2395
|
}
|
|
2319
2396
|
if (!ListFooterComponent) {
|
|
2320
|
-
|
|
2397
|
+
updateFooterSize(0);
|
|
2321
2398
|
}
|
|
2322
|
-
}, [ListHeaderComponent, ListFooterComponent, ctx]);
|
|
2399
|
+
}, [ListHeaderComponent, ListFooterComponent, ctx, updateFooterSize]);
|
|
2323
2400
|
const onLayoutHeader = React2.useCallback(
|
|
2324
2401
|
(rect) => {
|
|
2325
2402
|
const size = rect[horizontal ? "width" : "height"];
|
|
@@ -2330,10 +2407,11 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
2330
2407
|
const onLayoutFooterInternal = React2.useCallback(
|
|
2331
2408
|
(rect, fromLayoutEffect) => {
|
|
2332
2409
|
const size = rect[horizontal ? "width" : "height"];
|
|
2333
|
-
|
|
2334
|
-
|
|
2410
|
+
updateFooterSize(size, () => {
|
|
2411
|
+
onLayoutFooter == null ? void 0 : onLayoutFooter(rect, fromLayoutEffect);
|
|
2412
|
+
});
|
|
2335
2413
|
},
|
|
2336
|
-
[
|
|
2414
|
+
[horizontal, onLayoutFooter, updateFooterSize]
|
|
2337
2415
|
);
|
|
2338
2416
|
return /* @__PURE__ */ React2__namespace.createElement(
|
|
2339
2417
|
SnapOrScroll,
|
|
@@ -2438,67 +2516,6 @@ function useDevChecksNoop(_props) {
|
|
|
2438
2516
|
}
|
|
2439
2517
|
var useDevChecks = IS_DEV ? useDevChecksImpl : useDevChecksNoop;
|
|
2440
2518
|
|
|
2441
|
-
// src/core/doMaintainScrollAtEnd.ts
|
|
2442
|
-
function doMaintainScrollAtEnd(ctx) {
|
|
2443
|
-
const state = ctx.state;
|
|
2444
|
-
const {
|
|
2445
|
-
didContainersLayout,
|
|
2446
|
-
pendingNativeMVCPAdjust,
|
|
2447
|
-
refScroller,
|
|
2448
|
-
props: { maintainScrollAtEnd }
|
|
2449
|
-
} = state;
|
|
2450
|
-
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
2451
|
-
const shouldMaintainScrollAtEnd = !!(isWithinMaintainScrollAtEndThreshold && maintainScrollAtEnd && didContainersLayout);
|
|
2452
|
-
if (pendingNativeMVCPAdjust) {
|
|
2453
|
-
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
2454
|
-
return false;
|
|
2455
|
-
}
|
|
2456
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
2457
|
-
if (shouldMaintainScrollAtEnd) {
|
|
2458
|
-
const contentSize = getContentSize(ctx);
|
|
2459
|
-
if (contentSize < state.scrollLength) {
|
|
2460
|
-
state.scroll = 0;
|
|
2461
|
-
}
|
|
2462
|
-
if (!state.maintainingScrollAtEnd) {
|
|
2463
|
-
const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
2464
|
-
const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
|
|
2465
|
-
state.maintainingScrollAtEnd = pendingState;
|
|
2466
|
-
requestAnimationFrame(() => {
|
|
2467
|
-
if (peek$(ctx, "isWithinMaintainScrollAtEndThreshold")) {
|
|
2468
|
-
state.maintainingScrollAtEnd = activeState;
|
|
2469
|
-
const scroller = refScroller.current;
|
|
2470
|
-
if (state.props.horizontal && isHorizontalRTL(state)) {
|
|
2471
|
-
const currentContentSize = getContentSize(ctx);
|
|
2472
|
-
const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
|
|
2473
|
-
const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
|
|
2474
|
-
scroller == null ? void 0 : scroller.scrollTo({
|
|
2475
|
-
animated: maintainScrollAtEnd.animated,
|
|
2476
|
-
x: nativeOffset,
|
|
2477
|
-
y: 0
|
|
2478
|
-
});
|
|
2479
|
-
} else {
|
|
2480
|
-
scroller == null ? void 0 : scroller.scrollToEnd({
|
|
2481
|
-
animated: maintainScrollAtEnd.animated
|
|
2482
|
-
});
|
|
2483
|
-
}
|
|
2484
|
-
setTimeout(
|
|
2485
|
-
() => {
|
|
2486
|
-
if (state.maintainingScrollAtEnd === activeState) {
|
|
2487
|
-
state.maintainingScrollAtEnd = void 0;
|
|
2488
|
-
}
|
|
2489
|
-
},
|
|
2490
|
-
maintainScrollAtEnd.animated ? 500 : 0
|
|
2491
|
-
);
|
|
2492
|
-
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
2493
|
-
state.maintainingScrollAtEnd = void 0;
|
|
2494
|
-
}
|
|
2495
|
-
});
|
|
2496
|
-
}
|
|
2497
|
-
return true;
|
|
2498
|
-
}
|
|
2499
|
-
return false;
|
|
2500
|
-
}
|
|
2501
|
-
|
|
2502
2519
|
// src/core/mvcp.ts
|
|
2503
2520
|
var MVCP_POSITION_EPSILON = 0.1;
|
|
2504
2521
|
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
@@ -2749,6 +2766,9 @@ function prepareMVCP(ctx, dataChanged) {
|
|
|
2749
2766
|
if (diff > 0) {
|
|
2750
2767
|
diff = Math.max(0, totalSize - state.scroll - state.scrollLength);
|
|
2751
2768
|
} else {
|
|
2769
|
+
const maxScroll = Math.max(0, totalSize - state.scrollLength);
|
|
2770
|
+
state.scroll = maxScroll;
|
|
2771
|
+
state.scrollPending = maxScroll;
|
|
2752
2772
|
diff = 0;
|
|
2753
2773
|
}
|
|
2754
2774
|
}
|
|
@@ -4956,7 +4976,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4956
4976
|
const scrollAdjustPendingBeforeMVCP = (_f = peek$(ctx, "scrollAdjustPending")) != null ? _f : 0;
|
|
4957
4977
|
checkMVCP == null ? void 0 : checkMVCP();
|
|
4958
4978
|
const didMVCPAdjustScroll = !!checkMVCP && (state.scroll !== scrollBeforeMVCP || ((_g = peek$(ctx, "scrollAdjustPending")) != null ? _g : 0) !== scrollAdjustPendingBeforeMVCP);
|
|
4959
|
-
if (didMVCPAdjustScroll && initialScroll) {
|
|
4979
|
+
if (didMVCPAdjustScroll && (initialScroll || state.scrollingTo)) {
|
|
4960
4980
|
updateScroll2(state.scroll);
|
|
4961
4981
|
updateScrollRange();
|
|
4962
4982
|
}
|
|
@@ -6210,12 +6230,13 @@ function getRenderedItem(ctx, key) {
|
|
|
6210
6230
|
|
|
6211
6231
|
// src/utils/normalizeMaintainScrollAtEnd.ts
|
|
6212
6232
|
function normalizeMaintainScrollAtEndOn(on, hasExplicitOn) {
|
|
6213
|
-
var _a3, _b, _c;
|
|
6233
|
+
var _a3, _b, _c, _d;
|
|
6214
6234
|
return {
|
|
6215
6235
|
animated: false,
|
|
6216
6236
|
onDataChange: hasExplicitOn ? (_a3 = on == null ? void 0 : on.dataChange) != null ? _a3 : false : true,
|
|
6217
|
-
|
|
6218
|
-
|
|
6237
|
+
onFooterLayout: hasExplicitOn ? (_b = on == null ? void 0 : on.footerLayout) != null ? _b : false : true,
|
|
6238
|
+
onItemLayout: hasExplicitOn ? (_c = on == null ? void 0 : on.itemLayout) != null ? _c : false : true,
|
|
6239
|
+
onLayout: hasExplicitOn ? (_d = on == null ? void 0 : on.layout) != null ? _d : false : true
|
|
6219
6240
|
};
|
|
6220
6241
|
}
|
|
6221
6242
|
function normalizeMaintainScrollAtEnd(value) {
|
package/react-native.mjs
CHANGED
|
@@ -1196,6 +1196,67 @@ function WebAnchoredEndSpace({ horizontal }) {
|
|
|
1196
1196
|
return /* @__PURE__ */ React2.createElement("div", { style }, null);
|
|
1197
1197
|
}
|
|
1198
1198
|
|
|
1199
|
+
// src/core/doMaintainScrollAtEnd.ts
|
|
1200
|
+
function doMaintainScrollAtEnd(ctx) {
|
|
1201
|
+
const state = ctx.state;
|
|
1202
|
+
const {
|
|
1203
|
+
didContainersLayout,
|
|
1204
|
+
pendingNativeMVCPAdjust,
|
|
1205
|
+
refScroller,
|
|
1206
|
+
props: { maintainScrollAtEnd }
|
|
1207
|
+
} = state;
|
|
1208
|
+
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1209
|
+
const shouldMaintainScrollAtEnd = !!(isWithinMaintainScrollAtEndThreshold && maintainScrollAtEnd && didContainersLayout);
|
|
1210
|
+
if (pendingNativeMVCPAdjust) {
|
|
1211
|
+
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
1212
|
+
return false;
|
|
1213
|
+
}
|
|
1214
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1215
|
+
if (shouldMaintainScrollAtEnd) {
|
|
1216
|
+
const contentSize = getContentSize(ctx);
|
|
1217
|
+
if (contentSize < state.scrollLength) {
|
|
1218
|
+
state.scroll = 0;
|
|
1219
|
+
}
|
|
1220
|
+
if (!state.maintainingScrollAtEnd) {
|
|
1221
|
+
const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
1222
|
+
const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
|
|
1223
|
+
state.maintainingScrollAtEnd = pendingState;
|
|
1224
|
+
requestAnimationFrame(() => {
|
|
1225
|
+
if (peek$(ctx, "isWithinMaintainScrollAtEndThreshold")) {
|
|
1226
|
+
state.maintainingScrollAtEnd = activeState;
|
|
1227
|
+
const scroller = refScroller.current;
|
|
1228
|
+
if (state.props.horizontal && isHorizontalRTL(state)) {
|
|
1229
|
+
const currentContentSize = getContentSize(ctx);
|
|
1230
|
+
const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
|
|
1231
|
+
const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
|
|
1232
|
+
scroller == null ? void 0 : scroller.scrollTo({
|
|
1233
|
+
animated: maintainScrollAtEnd.animated,
|
|
1234
|
+
x: nativeOffset,
|
|
1235
|
+
y: 0
|
|
1236
|
+
});
|
|
1237
|
+
} else {
|
|
1238
|
+
scroller == null ? void 0 : scroller.scrollToEnd({
|
|
1239
|
+
animated: maintainScrollAtEnd.animated
|
|
1240
|
+
});
|
|
1241
|
+
}
|
|
1242
|
+
setTimeout(
|
|
1243
|
+
() => {
|
|
1244
|
+
if (state.maintainingScrollAtEnd === activeState) {
|
|
1245
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1246
|
+
}
|
|
1247
|
+
},
|
|
1248
|
+
maintainScrollAtEnd.animated ? 500 : 0
|
|
1249
|
+
);
|
|
1250
|
+
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
1251
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1252
|
+
}
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1255
|
+
return true;
|
|
1256
|
+
}
|
|
1257
|
+
return false;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1199
1260
|
// src/core/calculateOffsetForIndex.ts
|
|
1200
1261
|
function calculateOffsetForIndex(ctx, index) {
|
|
1201
1262
|
const state = ctx.state;
|
|
@@ -1779,8 +1840,11 @@ function updateAdaptiveRender(ctx, scrollVelocity) {
|
|
|
1779
1840
|
// src/utils/getEffectiveDrawDistance.ts
|
|
1780
1841
|
var INITIAL_DRAW_DISTANCE = 100;
|
|
1781
1842
|
function getEffectiveDrawDistance(ctx) {
|
|
1843
|
+
var _a3;
|
|
1782
1844
|
const drawDistance = ctx.state.props.drawDistance;
|
|
1783
|
-
|
|
1845
|
+
const initialScroll = ctx.state.initialScroll;
|
|
1846
|
+
const needsFullInitialDrawDistance = initialScroll !== void 0 && ((_a3 = initialScroll.viewPosition) != null ? _a3 : 0) > 0;
|
|
1847
|
+
return peek$(ctx, "readyToRender") || needsFullInitialDrawDistance ? drawDistance : Math.min(drawDistance, INITIAL_DRAW_DISTANCE);
|
|
1784
1848
|
}
|
|
1785
1849
|
|
|
1786
1850
|
// src/utils/setInitialRenderState.ts
|
|
@@ -2163,10 +2227,12 @@ function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
|
2163
2227
|
// src/core/updateContentMetrics.ts
|
|
2164
2228
|
var SCROLL_ADJUST_EPSILON = 0.1;
|
|
2165
2229
|
function setContentLengthSignal(ctx, signalName, size) {
|
|
2166
|
-
|
|
2230
|
+
const didChange = peek$(ctx, signalName) !== size;
|
|
2231
|
+
if (didChange) {
|
|
2167
2232
|
set$(ctx, signalName, size);
|
|
2168
2233
|
updateContentMetricsState(ctx);
|
|
2169
2234
|
}
|
|
2235
|
+
return didChange;
|
|
2170
2236
|
}
|
|
2171
2237
|
function shouldAdjustForHeaderSizeChange(ctx, previousHeaderSize, nextHeaderSize) {
|
|
2172
2238
|
const { didContainersLayout, didFinishInitialScroll, props, scroll, scrollingTo } = ctx.state;
|
|
@@ -2190,7 +2256,7 @@ function setHeaderSize(ctx, size) {
|
|
|
2190
2256
|
state.didMeasureHeader = true;
|
|
2191
2257
|
}
|
|
2192
2258
|
function setFooterSize(ctx, size) {
|
|
2193
|
-
setContentLengthSignal(ctx, "footerSize", size);
|
|
2259
|
+
return setContentLengthSignal(ctx, "footerSize", size);
|
|
2194
2260
|
}
|
|
2195
2261
|
function areInsetsEqual(left, right) {
|
|
2196
2262
|
var _a3, _b, _c, _d, _e, _f, _g, _h;
|
|
@@ -2291,14 +2357,25 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
2291
2357
|
);
|
|
2292
2358
|
const ScrollComponent = renderScrollComponent ? CustomScrollComponent : ListComponentScrollView;
|
|
2293
2359
|
const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
|
|
2360
|
+
const updateFooterSize = useCallback(
|
|
2361
|
+
(size, afterSizeUpdate) => {
|
|
2362
|
+
var _a3;
|
|
2363
|
+
const didFooterSizeChange = setFooterSize(ctx, size);
|
|
2364
|
+
afterSizeUpdate == null ? void 0 : afterSizeUpdate();
|
|
2365
|
+
if (didFooterSizeChange && ((_a3 = ctx.state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onFooterLayout)) {
|
|
2366
|
+
doMaintainScrollAtEnd(ctx);
|
|
2367
|
+
}
|
|
2368
|
+
},
|
|
2369
|
+
[ctx]
|
|
2370
|
+
);
|
|
2294
2371
|
useLayoutEffect(() => {
|
|
2295
2372
|
if (!ListHeaderComponent) {
|
|
2296
2373
|
setHeaderSize(ctx, 0);
|
|
2297
2374
|
}
|
|
2298
2375
|
if (!ListFooterComponent) {
|
|
2299
|
-
|
|
2376
|
+
updateFooterSize(0);
|
|
2300
2377
|
}
|
|
2301
|
-
}, [ListHeaderComponent, ListFooterComponent, ctx]);
|
|
2378
|
+
}, [ListHeaderComponent, ListFooterComponent, ctx, updateFooterSize]);
|
|
2302
2379
|
const onLayoutHeader = useCallback(
|
|
2303
2380
|
(rect) => {
|
|
2304
2381
|
const size = rect[horizontal ? "width" : "height"];
|
|
@@ -2309,10 +2386,11 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
2309
2386
|
const onLayoutFooterInternal = useCallback(
|
|
2310
2387
|
(rect, fromLayoutEffect) => {
|
|
2311
2388
|
const size = rect[horizontal ? "width" : "height"];
|
|
2312
|
-
|
|
2313
|
-
|
|
2389
|
+
updateFooterSize(size, () => {
|
|
2390
|
+
onLayoutFooter == null ? void 0 : onLayoutFooter(rect, fromLayoutEffect);
|
|
2391
|
+
});
|
|
2314
2392
|
},
|
|
2315
|
-
[
|
|
2393
|
+
[horizontal, onLayoutFooter, updateFooterSize]
|
|
2316
2394
|
);
|
|
2317
2395
|
return /* @__PURE__ */ React2.createElement(
|
|
2318
2396
|
SnapOrScroll,
|
|
@@ -2417,67 +2495,6 @@ function useDevChecksNoop(_props) {
|
|
|
2417
2495
|
}
|
|
2418
2496
|
var useDevChecks = IS_DEV ? useDevChecksImpl : useDevChecksNoop;
|
|
2419
2497
|
|
|
2420
|
-
// src/core/doMaintainScrollAtEnd.ts
|
|
2421
|
-
function doMaintainScrollAtEnd(ctx) {
|
|
2422
|
-
const state = ctx.state;
|
|
2423
|
-
const {
|
|
2424
|
-
didContainersLayout,
|
|
2425
|
-
pendingNativeMVCPAdjust,
|
|
2426
|
-
refScroller,
|
|
2427
|
-
props: { maintainScrollAtEnd }
|
|
2428
|
-
} = state;
|
|
2429
|
-
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
2430
|
-
const shouldMaintainScrollAtEnd = !!(isWithinMaintainScrollAtEndThreshold && maintainScrollAtEnd && didContainersLayout);
|
|
2431
|
-
if (pendingNativeMVCPAdjust) {
|
|
2432
|
-
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
2433
|
-
return false;
|
|
2434
|
-
}
|
|
2435
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
2436
|
-
if (shouldMaintainScrollAtEnd) {
|
|
2437
|
-
const contentSize = getContentSize(ctx);
|
|
2438
|
-
if (contentSize < state.scrollLength) {
|
|
2439
|
-
state.scroll = 0;
|
|
2440
|
-
}
|
|
2441
|
-
if (!state.maintainingScrollAtEnd) {
|
|
2442
|
-
const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
2443
|
-
const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
|
|
2444
|
-
state.maintainingScrollAtEnd = pendingState;
|
|
2445
|
-
requestAnimationFrame(() => {
|
|
2446
|
-
if (peek$(ctx, "isWithinMaintainScrollAtEndThreshold")) {
|
|
2447
|
-
state.maintainingScrollAtEnd = activeState;
|
|
2448
|
-
const scroller = refScroller.current;
|
|
2449
|
-
if (state.props.horizontal && isHorizontalRTL(state)) {
|
|
2450
|
-
const currentContentSize = getContentSize(ctx);
|
|
2451
|
-
const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
|
|
2452
|
-
const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
|
|
2453
|
-
scroller == null ? void 0 : scroller.scrollTo({
|
|
2454
|
-
animated: maintainScrollAtEnd.animated,
|
|
2455
|
-
x: nativeOffset,
|
|
2456
|
-
y: 0
|
|
2457
|
-
});
|
|
2458
|
-
} else {
|
|
2459
|
-
scroller == null ? void 0 : scroller.scrollToEnd({
|
|
2460
|
-
animated: maintainScrollAtEnd.animated
|
|
2461
|
-
});
|
|
2462
|
-
}
|
|
2463
|
-
setTimeout(
|
|
2464
|
-
() => {
|
|
2465
|
-
if (state.maintainingScrollAtEnd === activeState) {
|
|
2466
|
-
state.maintainingScrollAtEnd = void 0;
|
|
2467
|
-
}
|
|
2468
|
-
},
|
|
2469
|
-
maintainScrollAtEnd.animated ? 500 : 0
|
|
2470
|
-
);
|
|
2471
|
-
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
2472
|
-
state.maintainingScrollAtEnd = void 0;
|
|
2473
|
-
}
|
|
2474
|
-
});
|
|
2475
|
-
}
|
|
2476
|
-
return true;
|
|
2477
|
-
}
|
|
2478
|
-
return false;
|
|
2479
|
-
}
|
|
2480
|
-
|
|
2481
2498
|
// src/core/mvcp.ts
|
|
2482
2499
|
var MVCP_POSITION_EPSILON = 0.1;
|
|
2483
2500
|
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
@@ -2728,6 +2745,9 @@ function prepareMVCP(ctx, dataChanged) {
|
|
|
2728
2745
|
if (diff > 0) {
|
|
2729
2746
|
diff = Math.max(0, totalSize - state.scroll - state.scrollLength);
|
|
2730
2747
|
} else {
|
|
2748
|
+
const maxScroll = Math.max(0, totalSize - state.scrollLength);
|
|
2749
|
+
state.scroll = maxScroll;
|
|
2750
|
+
state.scrollPending = maxScroll;
|
|
2731
2751
|
diff = 0;
|
|
2732
2752
|
}
|
|
2733
2753
|
}
|
|
@@ -4935,7 +4955,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4935
4955
|
const scrollAdjustPendingBeforeMVCP = (_f = peek$(ctx, "scrollAdjustPending")) != null ? _f : 0;
|
|
4936
4956
|
checkMVCP == null ? void 0 : checkMVCP();
|
|
4937
4957
|
const didMVCPAdjustScroll = !!checkMVCP && (state.scroll !== scrollBeforeMVCP || ((_g = peek$(ctx, "scrollAdjustPending")) != null ? _g : 0) !== scrollAdjustPendingBeforeMVCP);
|
|
4938
|
-
if (didMVCPAdjustScroll && initialScroll) {
|
|
4958
|
+
if (didMVCPAdjustScroll && (initialScroll || state.scrollingTo)) {
|
|
4939
4959
|
updateScroll2(state.scroll);
|
|
4940
4960
|
updateScrollRange();
|
|
4941
4961
|
}
|
|
@@ -6189,12 +6209,13 @@ function getRenderedItem(ctx, key) {
|
|
|
6189
6209
|
|
|
6190
6210
|
// src/utils/normalizeMaintainScrollAtEnd.ts
|
|
6191
6211
|
function normalizeMaintainScrollAtEndOn(on, hasExplicitOn) {
|
|
6192
|
-
var _a3, _b, _c;
|
|
6212
|
+
var _a3, _b, _c, _d;
|
|
6193
6213
|
return {
|
|
6194
6214
|
animated: false,
|
|
6195
6215
|
onDataChange: hasExplicitOn ? (_a3 = on == null ? void 0 : on.dataChange) != null ? _a3 : false : true,
|
|
6196
|
-
|
|
6197
|
-
|
|
6216
|
+
onFooterLayout: hasExplicitOn ? (_b = on == null ? void 0 : on.footerLayout) != null ? _b : false : true,
|
|
6217
|
+
onItemLayout: hasExplicitOn ? (_c = on == null ? void 0 : on.itemLayout) != null ? _c : false : true,
|
|
6218
|
+
onLayout: hasExplicitOn ? (_d = on == null ? void 0 : on.layout) != null ? _d : false : true
|
|
6198
6219
|
};
|
|
6199
6220
|
}
|
|
6200
6221
|
function normalizeMaintainScrollAtEnd(value) {
|