@legendapp/list 3.1.0 → 3.1.1
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 +5 -1
- package/animated.d.ts +1 -0
- package/package.json +1 -1
- package/react-native.d.ts +1 -0
- package/react-native.js +86 -71
- package/react-native.mjs +86 -71
- package/react-native.web.d.ts +1 -0
- package/react-native.web.js +86 -71
- package/react-native.web.mjs +86 -71
- package/react.d.ts +1 -0
- package/react.js +86 -71
- package/react.mjs +86 -71
- package/reanimated.d.ts +1 -0
- package/section-list.d.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
## 3.1.1
|
|
2
|
+
|
|
3
|
+
- 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.
|
|
4
|
+
|
|
1
5
|
## 3.1.0
|
|
2
6
|
|
|
3
|
-
- Feat: Add `experimental_adaptiveRender` with `useAdaptiveRender` and `useAdaptiveRenderChange
|
|
7
|
+
- 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
8
|
- 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
9
|
- 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
10
|
- 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;
|
|
@@ -2184,10 +2245,12 @@ function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
|
2184
2245
|
// src/core/updateContentMetrics.ts
|
|
2185
2246
|
var SCROLL_ADJUST_EPSILON = 0.1;
|
|
2186
2247
|
function setContentLengthSignal(ctx, signalName, size) {
|
|
2187
|
-
|
|
2248
|
+
const didChange = peek$(ctx, signalName) !== size;
|
|
2249
|
+
if (didChange) {
|
|
2188
2250
|
set$(ctx, signalName, size);
|
|
2189
2251
|
updateContentMetricsState(ctx);
|
|
2190
2252
|
}
|
|
2253
|
+
return didChange;
|
|
2191
2254
|
}
|
|
2192
2255
|
function shouldAdjustForHeaderSizeChange(ctx, previousHeaderSize, nextHeaderSize) {
|
|
2193
2256
|
const { didContainersLayout, didFinishInitialScroll, props, scroll, scrollingTo } = ctx.state;
|
|
@@ -2211,7 +2274,7 @@ function setHeaderSize(ctx, size) {
|
|
|
2211
2274
|
state.didMeasureHeader = true;
|
|
2212
2275
|
}
|
|
2213
2276
|
function setFooterSize(ctx, size) {
|
|
2214
|
-
setContentLengthSignal(ctx, "footerSize", size);
|
|
2277
|
+
return setContentLengthSignal(ctx, "footerSize", size);
|
|
2215
2278
|
}
|
|
2216
2279
|
function areInsetsEqual(left, right) {
|
|
2217
2280
|
var _a3, _b, _c, _d, _e, _f, _g, _h;
|
|
@@ -2312,14 +2375,25 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
2312
2375
|
);
|
|
2313
2376
|
const ScrollComponent = renderScrollComponent ? CustomScrollComponent : ListComponentScrollView;
|
|
2314
2377
|
const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
|
|
2378
|
+
const updateFooterSize = React2.useCallback(
|
|
2379
|
+
(size, afterSizeUpdate) => {
|
|
2380
|
+
var _a3;
|
|
2381
|
+
const didFooterSizeChange = setFooterSize(ctx, size);
|
|
2382
|
+
afterSizeUpdate == null ? void 0 : afterSizeUpdate();
|
|
2383
|
+
if (didFooterSizeChange && ((_a3 = ctx.state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onFooterLayout)) {
|
|
2384
|
+
doMaintainScrollAtEnd(ctx);
|
|
2385
|
+
}
|
|
2386
|
+
},
|
|
2387
|
+
[ctx]
|
|
2388
|
+
);
|
|
2315
2389
|
React2.useLayoutEffect(() => {
|
|
2316
2390
|
if (!ListHeaderComponent) {
|
|
2317
2391
|
setHeaderSize(ctx, 0);
|
|
2318
2392
|
}
|
|
2319
2393
|
if (!ListFooterComponent) {
|
|
2320
|
-
|
|
2394
|
+
updateFooterSize(0);
|
|
2321
2395
|
}
|
|
2322
|
-
}, [ListHeaderComponent, ListFooterComponent, ctx]);
|
|
2396
|
+
}, [ListHeaderComponent, ListFooterComponent, ctx, updateFooterSize]);
|
|
2323
2397
|
const onLayoutHeader = React2.useCallback(
|
|
2324
2398
|
(rect) => {
|
|
2325
2399
|
const size = rect[horizontal ? "width" : "height"];
|
|
@@ -2330,10 +2404,11 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
2330
2404
|
const onLayoutFooterInternal = React2.useCallback(
|
|
2331
2405
|
(rect, fromLayoutEffect) => {
|
|
2332
2406
|
const size = rect[horizontal ? "width" : "height"];
|
|
2333
|
-
|
|
2334
|
-
|
|
2407
|
+
updateFooterSize(size, () => {
|
|
2408
|
+
onLayoutFooter == null ? void 0 : onLayoutFooter(rect, fromLayoutEffect);
|
|
2409
|
+
});
|
|
2335
2410
|
},
|
|
2336
|
-
[
|
|
2411
|
+
[horizontal, onLayoutFooter, updateFooterSize]
|
|
2337
2412
|
);
|
|
2338
2413
|
return /* @__PURE__ */ React2__namespace.createElement(
|
|
2339
2414
|
SnapOrScroll,
|
|
@@ -2438,67 +2513,6 @@ function useDevChecksNoop(_props) {
|
|
|
2438
2513
|
}
|
|
2439
2514
|
var useDevChecks = IS_DEV ? useDevChecksImpl : useDevChecksNoop;
|
|
2440
2515
|
|
|
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
2516
|
// src/core/mvcp.ts
|
|
2503
2517
|
var MVCP_POSITION_EPSILON = 0.1;
|
|
2504
2518
|
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
@@ -6210,12 +6224,13 @@ function getRenderedItem(ctx, key) {
|
|
|
6210
6224
|
|
|
6211
6225
|
// src/utils/normalizeMaintainScrollAtEnd.ts
|
|
6212
6226
|
function normalizeMaintainScrollAtEndOn(on, hasExplicitOn) {
|
|
6213
|
-
var _a3, _b, _c;
|
|
6227
|
+
var _a3, _b, _c, _d;
|
|
6214
6228
|
return {
|
|
6215
6229
|
animated: false,
|
|
6216
6230
|
onDataChange: hasExplicitOn ? (_a3 = on == null ? void 0 : on.dataChange) != null ? _a3 : false : true,
|
|
6217
|
-
|
|
6218
|
-
|
|
6231
|
+
onFooterLayout: hasExplicitOn ? (_b = on == null ? void 0 : on.footerLayout) != null ? _b : false : true,
|
|
6232
|
+
onItemLayout: hasExplicitOn ? (_c = on == null ? void 0 : on.itemLayout) != null ? _c : false : true,
|
|
6233
|
+
onLayout: hasExplicitOn ? (_d = on == null ? void 0 : on.layout) != null ? _d : false : true
|
|
6219
6234
|
};
|
|
6220
6235
|
}
|
|
6221
6236
|
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;
|
|
@@ -2163,10 +2224,12 @@ function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
|
2163
2224
|
// src/core/updateContentMetrics.ts
|
|
2164
2225
|
var SCROLL_ADJUST_EPSILON = 0.1;
|
|
2165
2226
|
function setContentLengthSignal(ctx, signalName, size) {
|
|
2166
|
-
|
|
2227
|
+
const didChange = peek$(ctx, signalName) !== size;
|
|
2228
|
+
if (didChange) {
|
|
2167
2229
|
set$(ctx, signalName, size);
|
|
2168
2230
|
updateContentMetricsState(ctx);
|
|
2169
2231
|
}
|
|
2232
|
+
return didChange;
|
|
2170
2233
|
}
|
|
2171
2234
|
function shouldAdjustForHeaderSizeChange(ctx, previousHeaderSize, nextHeaderSize) {
|
|
2172
2235
|
const { didContainersLayout, didFinishInitialScroll, props, scroll, scrollingTo } = ctx.state;
|
|
@@ -2190,7 +2253,7 @@ function setHeaderSize(ctx, size) {
|
|
|
2190
2253
|
state.didMeasureHeader = true;
|
|
2191
2254
|
}
|
|
2192
2255
|
function setFooterSize(ctx, size) {
|
|
2193
|
-
setContentLengthSignal(ctx, "footerSize", size);
|
|
2256
|
+
return setContentLengthSignal(ctx, "footerSize", size);
|
|
2194
2257
|
}
|
|
2195
2258
|
function areInsetsEqual(left, right) {
|
|
2196
2259
|
var _a3, _b, _c, _d, _e, _f, _g, _h;
|
|
@@ -2291,14 +2354,25 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
2291
2354
|
);
|
|
2292
2355
|
const ScrollComponent = renderScrollComponent ? CustomScrollComponent : ListComponentScrollView;
|
|
2293
2356
|
const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
|
|
2357
|
+
const updateFooterSize = useCallback(
|
|
2358
|
+
(size, afterSizeUpdate) => {
|
|
2359
|
+
var _a3;
|
|
2360
|
+
const didFooterSizeChange = setFooterSize(ctx, size);
|
|
2361
|
+
afterSizeUpdate == null ? void 0 : afterSizeUpdate();
|
|
2362
|
+
if (didFooterSizeChange && ((_a3 = ctx.state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onFooterLayout)) {
|
|
2363
|
+
doMaintainScrollAtEnd(ctx);
|
|
2364
|
+
}
|
|
2365
|
+
},
|
|
2366
|
+
[ctx]
|
|
2367
|
+
);
|
|
2294
2368
|
useLayoutEffect(() => {
|
|
2295
2369
|
if (!ListHeaderComponent) {
|
|
2296
2370
|
setHeaderSize(ctx, 0);
|
|
2297
2371
|
}
|
|
2298
2372
|
if (!ListFooterComponent) {
|
|
2299
|
-
|
|
2373
|
+
updateFooterSize(0);
|
|
2300
2374
|
}
|
|
2301
|
-
}, [ListHeaderComponent, ListFooterComponent, ctx]);
|
|
2375
|
+
}, [ListHeaderComponent, ListFooterComponent, ctx, updateFooterSize]);
|
|
2302
2376
|
const onLayoutHeader = useCallback(
|
|
2303
2377
|
(rect) => {
|
|
2304
2378
|
const size = rect[horizontal ? "width" : "height"];
|
|
@@ -2309,10 +2383,11 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
2309
2383
|
const onLayoutFooterInternal = useCallback(
|
|
2310
2384
|
(rect, fromLayoutEffect) => {
|
|
2311
2385
|
const size = rect[horizontal ? "width" : "height"];
|
|
2312
|
-
|
|
2313
|
-
|
|
2386
|
+
updateFooterSize(size, () => {
|
|
2387
|
+
onLayoutFooter == null ? void 0 : onLayoutFooter(rect, fromLayoutEffect);
|
|
2388
|
+
});
|
|
2314
2389
|
},
|
|
2315
|
-
[
|
|
2390
|
+
[horizontal, onLayoutFooter, updateFooterSize]
|
|
2316
2391
|
);
|
|
2317
2392
|
return /* @__PURE__ */ React2.createElement(
|
|
2318
2393
|
SnapOrScroll,
|
|
@@ -2417,67 +2492,6 @@ function useDevChecksNoop(_props) {
|
|
|
2417
2492
|
}
|
|
2418
2493
|
var useDevChecks = IS_DEV ? useDevChecksImpl : useDevChecksNoop;
|
|
2419
2494
|
|
|
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
2495
|
// src/core/mvcp.ts
|
|
2482
2496
|
var MVCP_POSITION_EPSILON = 0.1;
|
|
2483
2497
|
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
@@ -6189,12 +6203,13 @@ function getRenderedItem(ctx, key) {
|
|
|
6189
6203
|
|
|
6190
6204
|
// src/utils/normalizeMaintainScrollAtEnd.ts
|
|
6191
6205
|
function normalizeMaintainScrollAtEndOn(on, hasExplicitOn) {
|
|
6192
|
-
var _a3, _b, _c;
|
|
6206
|
+
var _a3, _b, _c, _d;
|
|
6193
6207
|
return {
|
|
6194
6208
|
animated: false,
|
|
6195
6209
|
onDataChange: hasExplicitOn ? (_a3 = on == null ? void 0 : on.dataChange) != null ? _a3 : false : true,
|
|
6196
|
-
|
|
6197
|
-
|
|
6210
|
+
onFooterLayout: hasExplicitOn ? (_b = on == null ? void 0 : on.footerLayout) != null ? _b : false : true,
|
|
6211
|
+
onItemLayout: hasExplicitOn ? (_c = on == null ? void 0 : on.itemLayout) != null ? _c : false : true,
|
|
6212
|
+
onLayout: hasExplicitOn ? (_d = on == null ? void 0 : on.layout) != null ? _d : false : true
|
|
6198
6213
|
};
|
|
6199
6214
|
}
|
|
6200
6215
|
function normalizeMaintainScrollAtEnd(value) {
|