@legendapp/list 3.7.0 → 3.7.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.
@@ -324,27 +324,20 @@ function getContentInsetEnd(ctx, contentInsetEndAdjustmentOverride) {
324
324
  const { props } = state;
325
325
  const horizontal = props.horizontal;
326
326
  const baseInset = state.nativeContentInset;
327
- const baseEndInset = (horizontal ? getHorizontalInsetEnd(state, baseInset) : baseInset == null ? void 0 : baseInset.bottom) || 0;
328
327
  const contentInsetEndAdjustment = getContentInsetEndAdjustmentEnd(
329
328
  contentInsetEndAdjustmentOverride != null ? contentInsetEndAdjustmentOverride : props.contentInsetEndAdjustment
330
329
  );
331
330
  const anchoredEndSpaceSize = peek$(ctx, "anchoredEndSpaceSize");
332
331
  const anchoredEndInset = props.anchoredEndSpace && anchoredEndSpaceSize ? anchoredEndSpaceSize : 0;
333
332
  const overrideInset = (_a3 = state.contentInsetOverride) != null ? _a3 : void 0;
334
- const adjustedBaseEndInset = baseEndInset + contentInsetEndAdjustment;
335
- if (overrideInset) {
336
- const mergedInset = { bottom: 0, left: 0, right: 0, ...baseInset, ...overrideInset };
337
- return Math.max(
338
- ((horizontal ? getHorizontalInsetEnd(state, mergedInset) : mergedInset.bottom) || 0) + contentInsetEndAdjustment,
339
- anchoredEndInset
340
- );
341
- }
342
- return Math.max(adjustedBaseEndInset, anchoredEndInset);
333
+ const mergedInset = overrideInset ? { bottom: 0, left: 0, right: 0, ...baseInset, ...overrideInset } : baseInset;
334
+ const endInset = ((horizontal ? getHorizontalInsetEnd(state, mergedInset) : mergedInset == null ? void 0 : mergedInset.bottom) || 0) + contentInsetEndAdjustment;
335
+ return Math.max(endInset, anchoredEndInset);
343
336
  }
344
337
 
345
338
  // src/state/getContentSize.ts
346
- function getContentSize(ctx) {
347
- var _a3, _b;
339
+ function getContentSize(ctx, includeContentContainerMinSize = true) {
340
+ var _a3, _b, _c;
348
341
  const { values, state } = ctx;
349
342
  const stylePaddingStart = state.props.horizontal ? state.props.stylePaddingLeft || 0 : values.get("stylePaddingTop") || 0;
350
343
  const stylePaddingEnd = state.props.horizontal ? state.props.stylePaddingRight || 0 : state.props.stylePaddingBottom || 0;
@@ -354,7 +347,10 @@ function getContentSize(ctx) {
354
347
  const contentInsetEnd = getContentInsetEnd(ctx);
355
348
  const totalSize = (_b = (_a3 = state.pendingTotalSize) != null ? _a3 : state.totalSize) != null ? _b : values.get("totalSize");
356
349
  const layoutSize = Math.max(0, totalSize - (state.props.data.length > 0 ? ctx.scrollAxisGap : 0));
357
- return headerSize + footerSize + layoutSize + stylePaddingStart + alignItemsAtEndPadding + stylePaddingEnd + (contentInsetEnd || 0);
350
+ const contentSize = headerSize + footerSize + layoutSize + stylePaddingStart + alignItemsAtEndPadding + stylePaddingEnd;
351
+ const inContentInset = contentInsetEnd ;
352
+ const containerSize = contentSize + inContentInset;
353
+ return (includeContentContainerMinSize ? Math.max(containerSize, (_c = state.props.contentContainerMinSize) != null ? _c : 0) : containerSize) + contentInsetEnd - inContentInset;
358
354
  }
359
355
 
360
356
  // src/components/DebugView.tsx
@@ -470,6 +466,33 @@ function cancelImperativeScroll(state) {
470
466
  settlePendingImperativeScroll(state);
471
467
  }
472
468
 
469
+ // src/core/clampScrollOffset.ts
470
+ function getContentInsetTop(ctx) {
471
+ ctx.state;
472
+ {
473
+ return 0;
474
+ }
475
+ }
476
+ function getScrollRangeEnd(ctx, contentSize = getContentSize(ctx)) {
477
+ return Math.max(0 - getContentInsetTop(ctx), contentSize - ctx.state.scrollLength);
478
+ }
479
+ function clampScrollOffset(ctx, offset, scrollTarget) {
480
+ var _a3;
481
+ const state = ctx.state;
482
+ const minOffset = 0 - getContentInsetTop(ctx);
483
+ const contentSize = getContentSize(ctx, !scrollTarget || !!scrollTarget.clampToContentContainerMinSize);
484
+ let clampedOffset = offset;
485
+ if (Number.isFinite(contentSize) && Number.isFinite(state.scrollLength) && (Platform.OS !== "android")) {
486
+ const baseMaxOffset = getScrollRangeEnd(ctx, contentSize);
487
+ const viewOffset = (scrollTarget == null ? void 0 : scrollTarget.isInitialScroll) ? void 0 : scrollTarget == null ? void 0 : scrollTarget.viewOffset;
488
+ const extraEndOffset = typeof viewOffset === "number" && viewOffset < 0 ? -viewOffset : 0;
489
+ const isRawOffset = (scrollTarget == null ? void 0 : scrollTarget.offset) !== void 0 && (scrollTarget.index === void 0 || scrollTarget.isInitialScroll && ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset");
490
+ const maxOffset = Math.max(isRawOffset ? 0 : minOffset, baseMaxOffset + extraEndOffset);
491
+ clampedOffset = Math.min(offset, maxOffset);
492
+ }
493
+ return Math.max(minOffset, clampedOffset);
494
+ }
495
+
473
496
  // src/core/doScrollParams.ts
474
497
  function getNativeScrollPoint(ctx, offset, horizontal = ctx.state.props.horizontal) {
475
498
  var _a3;
@@ -647,23 +670,6 @@ function getObservedScrollOffset(ctx, fallbackOffset = ctx.state.scroll) {
647
670
  return state.props.horizontal ? peekLogicalHorizontalOffset(state, observed, (_c = scroller.getMaxScrollOffset) == null ? void 0 : _c.call(scroller)) : observed;
648
671
  }
649
672
 
650
- // src/core/clampScrollOffset.ts
651
- function clampScrollOffset(ctx, offset, scrollTarget) {
652
- const state = ctx.state;
653
- const minSize = (scrollTarget == null ? void 0 : scrollTarget.clampToContentContainerMinSize) ? state.props.contentContainerMinSize : void 0;
654
- const contentSize = minSize === void 0 ? getContentSize(ctx) : Math.max(getContentSize(ctx), minSize);
655
- let clampedOffset = offset;
656
- if (Number.isFinite(contentSize) && Number.isFinite(state.scrollLength) && (Platform.OS !== "android")) {
657
- const baseMaxOffset = Math.max(0, contentSize - state.scrollLength);
658
- const viewOffset = (scrollTarget == null ? void 0 : scrollTarget.isInitialScroll) ? void 0 : scrollTarget == null ? void 0 : scrollTarget.viewOffset;
659
- const extraEndOffset = typeof viewOffset === "number" && viewOffset < 0 ? -viewOffset : 0;
660
- const maxOffset = baseMaxOffset + extraEndOffset;
661
- clampedOffset = Math.min(offset, maxOffset);
662
- }
663
- clampedOffset = Math.max(0, clampedOffset);
664
- return clampedOffset;
665
- }
666
-
667
673
  // src/core/updateContentMetricsState.ts
668
674
  function getRawContentLength(ctx) {
669
675
  var _a3, _b, _c;
@@ -673,7 +679,7 @@ function getRawContentLength(ctx) {
673
679
  function getAlignItemsAtEndPadding(ctx) {
674
680
  const { state } = ctx;
675
681
  const shouldPad = !!state.props.alignItemsAtEndPaddingEnabled && !state.props.horizontal && state.props.data.length > 0 && state.scrollLength > 0;
676
- return shouldPad ? Math.max(0, state.scrollLength - getRawContentLength(ctx) - getContentInsetEnd(ctx)) : 0;
682
+ return shouldPad ? Math.max(0, state.scrollLength - getRawContentLength(ctx) - getContentInsetTop(ctx) - getContentInsetEnd(ctx)) : 0;
677
683
  }
678
684
  function updateContentMetricsState(ctx) {
679
685
  var _a3;
@@ -780,70 +786,66 @@ function isOutsideThresholdHysteresis(distance, atThreshold, threshold) {
780
786
  const absDistance = Math.abs(distance);
781
787
  return !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
782
788
  }
789
+ function didThresholdDataChange(snapshot, context) {
790
+ return !!snapshot && (snapshot.dataLength !== context.dataLength || snapshot.data !== context.data && snapshot.contentSize !== context.contentSize);
791
+ }
783
792
  var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
784
793
  const absDistance = Math.abs(distance);
785
- const within = atThreshold || threshold > 0 && absDistance <= threshold;
786
- const updateSnapshot = () => {
787
- setSnapshot({
788
- atThreshold,
789
- contentSize: context.contentSize,
790
- dataLength: context.dataLength,
791
- scrollPosition: context.scrollPosition
792
- });
793
- };
794
- let reached = !!wasReached;
795
- if (!wasReached) {
796
- if (within && onReached(distance)) {
797
- updateSnapshot();
798
- reached = true;
799
- }
800
- } else {
801
- const reset = isOutsideThresholdHysteresis(distance, atThreshold, threshold);
802
- if (reset) {
794
+ const within = context.dataLength !== 0 && (atThreshold || threshold > 0 && absDistance <= threshold);
795
+ const didScroll = (snapshot == null ? void 0 : snapshot.scroll) !== context.scroll;
796
+ if (snapshot) snapshot.scroll = context.scroll;
797
+ if (!within) {
798
+ if ((context.dataLength === 0 || didScroll && isOutsideThresholdHysteresis(distance, atThreshold, threshold)) && (wasReached || snapshot)) {
803
799
  setSnapshot(void 0);
804
- reached = false;
805
- } else if (within) {
806
- const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
807
- if (changed) {
808
- updateSnapshot();
809
- }
810
800
  }
801
+ return false;
811
802
  }
812
- return reached;
803
+ if ((!wasReached || didThresholdDataChange(snapshot, context)) && onReached(distance)) {
804
+ return true;
805
+ }
806
+ return !!wasReached;
813
807
  };
814
808
 
815
809
  // src/utils/edgeReachedGate.ts
816
- function resetEdgeLatch(ctx, edge) {
817
- const state = ctx.state;
818
- if (edge === "start") {
819
- state.isStartReached = false;
820
- state.startReachedSnapshot = void 0;
821
- } else {
822
- state.isEndReached = false;
823
- state.endReachedSnapshot = void 0;
824
- }
810
+ function getDistanceFromStart(ctx) {
811
+ return ctx.state.scroll + getContentInsetTop(ctx);
825
812
  }
826
813
  function resetSharedEdgeGateIfOutsideHysteresis(ctx) {
827
814
  const state = ctx.state;
828
- if (!state.edgeReachedGate) {
815
+ if (!state.edgeReachedGate || state.edgeReachedGateScroll === state.scroll) {
829
816
  return;
830
817
  }
818
+ state.edgeReachedGateScroll = state.scroll;
831
819
  const contentSize = getContentSize(ctx);
832
820
  const endDistance = contentSize - state.scroll - state.scrollLength;
833
821
  const isContentLess = contentSize < state.scrollLength;
834
822
  const startThreshold = state.props.onStartReachedThreshold * state.scrollLength;
835
823
  const endThreshold = state.props.onEndReachedThreshold * state.scrollLength;
836
- const isOutsideStart = isOutsideThresholdHysteresis(state.scroll, false, startThreshold);
824
+ const isOutsideStart = isOutsideThresholdHysteresis(getDistanceFromStart(ctx), false, startThreshold);
837
825
  const isOutsideEnd = isOutsideThresholdHysteresis(endDistance, isContentLess, endThreshold);
838
826
  if (isOutsideStart && isOutsideEnd) {
839
827
  state.edgeReachedGate = void 0;
840
828
  }
841
829
  }
842
830
  function canDispatchReachedEdge(ctx, edge, allowedEdge, allowGateCreatedInCurrentCheck) {
843
- return !ctx.state.edgeReachedGate || allowedEdge === edge || !!allowGateCreatedInCurrentCheck;
831
+ const state = ctx.state;
832
+ return !state.edgeReachedGate || allowedEdge === edge || !!allowGateCreatedInCurrentCheck || didThresholdDataChange(
833
+ edge === "start" ? state.startReachedSnapshot : state.endReachedSnapshot,
834
+ getThresholdSnapshot(ctx)
835
+ );
844
836
  }
845
- function markReachedEdge(ctx) {
846
- ctx.state.edgeReachedGate = "closed";
837
+ function markReachedEdge(ctx, edge) {
838
+ const state = ctx.state;
839
+ state.edgeReachedGate = "closed";
840
+ state.edgeReachedGateScroll = state.scroll;
841
+ const snapshotKey = edge === "start" ? "startReachedSnapshot" : "endReachedSnapshot";
842
+ const snapshot = getThresholdSnapshot(ctx);
843
+ snapshot.didRearmForData = didThresholdDataChange(state[snapshotKey], snapshot);
844
+ state[snapshotKey] = snapshot;
845
+ }
846
+ function getThresholdSnapshot(ctx) {
847
+ const { data } = ctx.state.props;
848
+ return { contentSize: getContentSize(ctx), data, dataLength: data.length, scroll: ctx.state.scroll };
847
849
  }
848
850
  function prepareReachedEdgeForNextUserScroll(ctx) {
849
851
  if (ctx.state.edgeReachedGate) {
@@ -852,11 +854,19 @@ function prepareReachedEdgeForNextUserScroll(ctx) {
852
854
  }
853
855
  function beginReachedEdgeUserScroll(ctx, scrollDelta) {
854
856
  const state = ctx.state;
855
- if (state.edgeReachedGate !== "prepared") {
857
+ const allowedEdge = scrollDelta < 0 ? "start" : "end";
858
+ if (state.edgeReachedGate !== "prepared" && state.edgeReachedGate !== (allowedEdge === "start" ? "consumed-end" : "consumed-start")) {
856
859
  return void 0;
857
860
  }
858
- const allowedEdge = scrollDelta < 0 ? "start" : "end";
859
- resetEdgeLatch(ctx, allowedEdge);
861
+ const snapshotKey = allowedEdge === "start" ? "startReachedSnapshot" : "endReachedSnapshot";
862
+ const snapshot = state[snapshotKey];
863
+ if ((snapshot == null ? void 0 : snapshot.didRearmForData) && snapshot.data === state.props.data) {
864
+ snapshot.didRearmForData = false;
865
+ state.edgeReachedGate = state.edgeReachedGate === "prepared" ? `consumed-${allowedEdge}` : "closed";
866
+ return void 0;
867
+ }
868
+ state[allowedEdge === "start" ? "isStartReached" : "isEndReached"] = false;
869
+ state[snapshotKey] = void 0;
860
870
  return allowedEdge;
861
871
  }
862
872
 
@@ -867,7 +877,6 @@ function hasActiveInitialScroll(state) {
867
877
 
868
878
  // src/utils/checkAtBottom.ts
869
879
  function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
870
- var _a3;
871
880
  const state = ctx.state;
872
881
  if (!state) {
873
882
  return;
@@ -907,19 +916,14 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
907
916
  onEndReachedThreshold * scrollLength,
908
917
  state.isEndReached,
909
918
  state.endReachedSnapshot,
910
- {
911
- contentSize,
912
- dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
913
- scrollPosition: scroll
914
- },
919
+ { contentSize, data: state.props.data, dataLength: state.props.data.length, scroll },
915
920
  (distance) => {
916
- let dispatched = false;
917
921
  if (state.props.onEndReached && canDispatchReachedEdge(ctx, "end", allowedEdge, allowGateCreatedInCurrentCheck)) {
918
- markReachedEdge(ctx);
922
+ markReachedEdge(ctx, "end");
919
923
  state.props.onEndReached({ distanceFromEnd: distance });
920
- dispatched = true;
924
+ return true;
921
925
  }
922
- return dispatched;
926
+ return false;
923
927
  },
924
928
  (snapshot) => {
925
929
  state.endReachedSnapshot = snapshot;
@@ -936,43 +940,30 @@ function checkAtTop(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
936
940
  return;
937
941
  }
938
942
  const {
939
- isStartReached,
940
943
  props: { data, onStartReachedThreshold },
941
- scroll,
942
- scrollLength,
943
- startReachedSnapshot,
944
- totalSize
944
+ scrollLength
945
945
  } = state;
946
- const dataLength = data.length;
947
946
  const threshold = onStartReachedThreshold * scrollLength;
947
+ const distanceFromStart = getDistanceFromStart(ctx);
948
948
  resetSharedEdgeGateIfOutsideHysteresis(ctx);
949
- if (isStartReached && threshold > 0 && scroll > threshold && startReachedSnapshot && (startReachedSnapshot.contentSize !== totalSize || startReachedSnapshot.dataLength !== dataLength)) {
950
- state.isStartReached = false;
951
- state.startReachedSnapshot = void 0;
952
- }
953
- set$(ctx, "isAtStart", scroll <= EDGE_POSITION_EPSILON);
954
- set$(ctx, "isNearStart", scroll <= threshold);
949
+ set$(ctx, "isAtStart", distanceFromStart <= EDGE_POSITION_EPSILON);
950
+ set$(ctx, "isNearStart", distanceFromStart <= threshold);
955
951
  const shouldSkipThresholdChecks = !state.queuedInitialLayout || hasActiveInitialScroll(state) || !!state.scrollingTo;
956
952
  if (!shouldSkipThresholdChecks) {
957
953
  state.isStartReached = checkThreshold(
958
- scroll,
954
+ distanceFromStart,
959
955
  false,
960
956
  threshold,
961
957
  state.isStartReached,
962
- startReachedSnapshot,
963
- {
964
- contentSize: totalSize,
965
- dataLength,
966
- scrollPosition: scroll
967
- },
958
+ state.startReachedSnapshot,
959
+ { contentSize: getContentSize(ctx), data, dataLength: data.length, scroll: state.scroll },
968
960
  (distance) => {
969
- let dispatched = false;
970
961
  if (state.props.onStartReached && canDispatchReachedEdge(ctx, "start", allowedEdge, allowGateCreatedInCurrentCheck)) {
971
- markReachedEdge(ctx);
962
+ markReachedEdge(ctx, "start");
972
963
  state.props.onStartReached({ distanceFromStart: distance });
973
- dispatched = true;
964
+ return true;
974
965
  }
975
- return dispatched;
966
+ return false;
976
967
  },
977
968
  (snapshot) => {
978
969
  state.startReachedSnapshot = snapshot;
@@ -1442,11 +1433,9 @@ function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
1442
1433
  if (viewOffset) {
1443
1434
  offset -= viewOffset;
1444
1435
  }
1436
+ const leadingInset = index !== void 0 ? getContentInsetTop(ctx) : 0;
1445
1437
  if (index !== void 0) {
1446
- const startOffsetAdjustment = getStartOffsetAdjustment(ctx);
1447
- if (startOffsetAdjustment) {
1448
- offset += startOffsetAdjustment;
1449
- }
1438
+ offset += getStartOffsetAdjustment(ctx) - leadingInset;
1450
1439
  }
1451
1440
  if (viewPosition !== void 0 && index !== void 0) {
1452
1441
  const dataLength = state.props.data.length;
@@ -1458,9 +1447,12 @@ function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
1458
1447
  const measuredItemSize = isOutOfBounds ? fallbackEstimatedSize : getItemSize(ctx, getId(state, index), index, state.props.data[index]);
1459
1448
  const itemSize = Math.max(0, measuredItemSize - (isOutOfBounds ? 0 : ctx.scrollAxisGap));
1460
1449
  const trailingInset = getContentInsetEnd(ctx);
1461
- const availableSpace = state.scrollLength - trailingInset - itemSize;
1450
+ const availableSpace = state.scrollLength - leadingInset - trailingInset - itemSize;
1462
1451
  offset += getViewPositionOffset(availableSpace, viewPosition, viewPositionFallback);
1463
1452
  }
1453
+ if (index !== void 0 && params.clampToContentContainerMinSize) {
1454
+ offset += getContentSize(ctx) - getContentSize(ctx, false);
1455
+ }
1464
1456
  return offset;
1465
1457
  }
1466
1458
 
@@ -1513,11 +1505,12 @@ function shouldQueueNativeMVCPAdjust(dataChanged, state, positionDiff, prevTotal
1513
1505
  return false;
1514
1506
  }
1515
1507
  }
1516
- function getPredictedNativeClamp(state, unresolvedAmount, totalSize) {
1508
+ function getPredictedNativeClamp(ctx, unresolvedAmount, totalSize) {
1517
1509
  if (Math.abs(unresolvedAmount) <= MVCP_POSITION_EPSILON) {
1518
1510
  return 0;
1519
1511
  }
1520
- const maxScroll = Math.max(0, totalSize - state.scrollLength);
1512
+ const state = ctx.state;
1513
+ const maxScroll = getScrollRangeEnd(ctx, totalSize);
1521
1514
  const clampDelta = maxScroll - state.scroll;
1522
1515
  if (unresolvedAmount < 0) {
1523
1516
  return Math.max(unresolvedAmount, Math.min(0, clampDelta));
@@ -1545,7 +1538,7 @@ function maybeApplyPredictedNativeMVCPAdjust(ctx) {
1545
1538
  return;
1546
1539
  }
1547
1540
  const totalSize = getContentSize(ctx);
1548
- const predictedNativeClamp = getPredictedNativeClamp(state, pending.amount, totalSize);
1541
+ const predictedNativeClamp = getPredictedNativeClamp(ctx, pending.amount, totalSize);
1549
1542
  if (Math.abs(predictedNativeClamp) <= MVCP_POSITION_EPSILON) {
1550
1543
  return;
1551
1544
  }
@@ -1579,7 +1572,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
1579
1572
  settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
1580
1573
  return true;
1581
1574
  }
1582
- const expectedNativeClampScroll = Math.max(0, getContentSize(ctx) - state.scrollLength);
1575
+ const expectedNativeClampScroll = getScrollRangeEnd(ctx);
1583
1576
  const distanceToClamp = Math.abs(newScroll - expectedNativeClampScroll);
1584
1577
  const isAtExpectedNativeClamp = distanceToClamp <= NATIVE_END_CLAMP_EPSILON;
1585
1578
  if (isAtExpectedNativeClamp) {
@@ -1720,7 +1713,7 @@ function prepareMVCP(ctx, dataChanged, adjustmentSource) {
1720
1713
  if (diff > 0) {
1721
1714
  diff = Math.max(0, totalSize - state.scroll - state.scrollLength);
1722
1715
  } else {
1723
- const maxScroll = Math.max(0, totalSize - state.scrollLength);
1716
+ const maxScroll = getScrollRangeEnd(ctx, totalSize);
1724
1717
  state.scroll = maxScroll;
1725
1718
  state.scrollPending = maxScroll;
1726
1719
  diff = 0;
@@ -1737,7 +1730,7 @@ function prepareMVCP(ctx, dataChanged, adjustmentSource) {
1737
1730
  const prevSize = scrollingTo.itemSize;
1738
1731
  if (prevSize !== void 0 && newSize !== prevSize) {
1739
1732
  if (scrollingTo.viewPositionFallback) {
1740
- const viewport = state.scrollLength - getContentInsetEnd(ctx);
1733
+ const viewport = state.scrollLength - getContentInsetTop(ctx) - getContentInsetEnd(ctx);
1741
1734
  const previousSpace = viewport - Math.max(0, prevSize - ctx.scrollAxisGap);
1742
1735
  const nextSpace = viewport - Math.max(0, newSize - ctx.scrollAxisGap);
1743
1736
  positionDiff += getViewPositionOffset(
@@ -1944,27 +1937,31 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
1944
1937
  }
1945
1938
 
1946
1939
  // src/core/cancelScroll.ts
1947
- function cancelScroll(ctx, stopAnimation = true, commitAdjust = true) {
1940
+ function cancelScroll(ctx, stopAnimation = true, commitAdjust = true, inputDelta = 0) {
1948
1941
  var _a3, _b;
1949
1942
  const { state } = ctx;
1950
1943
  const observed = getObservedScrollOffset(ctx, peek$(ctx, "scrollAdjustPending") ? state.scrollPending : void 0);
1951
1944
  const wasAnimating = !!((_a3 = state.scrollingTo) == null ? void 0 : _a3.animated) || !!((_b = ctx.scrollRequestTracker) == null ? void 0 : _b.cancel());
1945
+ const stopped = wasAnimating && stopAnimation;
1946
+ const stopOffset = stopped && inputDelta ? clampScrollOffset(ctx, observed + inputDelta) : observed;
1952
1947
  releaseScrollOwners(ctx, true);
1953
- state.scrollPending = observed;
1948
+ state.scrollPending = stopOffset;
1954
1949
  const ignoreScrollFromMVCP = state.ignoreScrollFromMVCP;
1955
1950
  if (peek$(ctx, "scrollAdjustPending")) state.ignoreScrollFromMVCP = void 0;
1956
- updateScroll(ctx, observed, true, { markHasScrolled: false });
1951
+ updateScroll(ctx, stopOffset, true, { markHasScrolled: false });
1957
1952
  state.ignoreScrollFromMVCP = ignoreScrollFromMVCP;
1958
- if (wasAnimating && stopAnimation) stopScrollAnimation(ctx, observed);
1953
+ if (stopped) stopScrollAnimation(ctx, observed, inputDelta);
1959
1954
  if (commitAdjust) state.scrollAdjustHandler.commitPendingAdjust();
1960
1955
  else state.scrollAdjustHandler.supersedePendingAdjust();
1956
+ return stopped;
1961
1957
  }
1962
- function stopScrollAnimation(ctx, observed = getObservedScrollOffset(ctx)) {
1958
+ function stopScrollAnimation(ctx, observed = getObservedScrollOffset(ctx), inputDelta = 0) {
1963
1959
  var _a3, _b;
1964
1960
  const { state } = ctx;
1965
1961
  const scroller = state.refScroller.current;
1966
- const x = state.props.horizontal ? (_b = (_a3 = scroller == null ? void 0 : scroller.getCurrentScrollOffset) == null ? void 0 : _a3.call(scroller)) != null ? _b : getNativeScrollPoint(ctx, observed).x : 0;
1967
- scroller == null ? void 0 : scroller.scrollTo({ animated: false, x, y: state.props.horizontal ? 0 : observed });
1962
+ const offset = observed + inputDelta;
1963
+ const x = !state.props.horizontal ? 0 : inputDelta ? getNativeScrollPoint(ctx, offset).x : (_b = (_a3 = scroller == null ? void 0 : scroller.getCurrentScrollOffset) == null ? void 0 : _a3.call(scroller)) != null ? _b : getNativeScrollPoint(ctx, observed).x;
1964
+ scroller == null ? void 0 : scroller.scrollTo({ animated: false, x, y: state.props.horizontal ? 0 : offset });
1968
1965
  }
1969
1966
  function releaseScrollOwners(ctx, supersedeInitial) {
1970
1967
  var _a3;
@@ -1978,12 +1975,39 @@ function releaseScrollOwners(ctx, supersedeInitial) {
1978
1975
  clearPreservedInitialScrollTarget(state);
1979
1976
  syncScrollActive(ctx);
1980
1977
  }
1981
- function interruptUserScroll(ctx) {
1982
- if (ctx.state.scrollingTo || ctx.state.initialScroll && !ctx.state.didFinishInitialScroll) {
1983
- cancelScroll(ctx, Platform.OS === "web");
1984
- } else {
1985
- releaseScrollOwners(ctx, false);
1978
+ function interruptUserScroll(ctx, inputDelta = 0) {
1979
+ var _a3;
1980
+ if (ctx.state.scrollingTo || ((_a3 = ctx.scrollRequestTracker) == null ? void 0 : _a3.isWaitingToRun()) || ctx.state.initialScroll && !ctx.state.didFinishInitialScroll) {
1981
+ return cancelScroll(ctx, Platform.OS === "web", true, inputDelta) && inputDelta !== 0;
1982
+ }
1983
+ releaseScrollOwners(ctx, false);
1984
+ return false;
1985
+ }
1986
+
1987
+ // src/utils/clampScrollIndex.ts
1988
+ function clampScrollIndex(index, dataLength) {
1989
+ if (dataLength <= 0) {
1990
+ return -1;
1991
+ }
1992
+ if (index >= dataLength) {
1993
+ return dataLength - 1;
1986
1994
  }
1995
+ if (index < 0) {
1996
+ return 0;
1997
+ }
1998
+ return index;
1999
+ }
2000
+
2001
+ // src/core/getCurrentTargetOffset.ts
2002
+ function isEndAlignedLastItemTarget(ctx, scrollingTo) {
2003
+ return (scrollingTo.isScrollToEnd || scrollingTo.index === ctx.state.props.data.length - 1) && scrollingTo.viewPosition === 1;
2004
+ }
2005
+ function getCurrentTargetOffset(ctx, scrollingTo) {
2006
+ var _a3, _b;
2007
+ const index = scrollingTo.isScrollToEnd ? ctx.state.props.data.length - 1 : scrollingTo.index === void 0 ? void 0 : clampScrollIndex(scrollingTo.index, ctx.state.props.data.length);
2008
+ const isRetargetingWebScroll = (!scrollingTo.isInitialScroll || ((_a3 = ctx.state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap");
2009
+ const requestedTargetOffset = index !== void 0 && (isRetargetingWebScroll || isEndAlignedLastItemTarget(ctx, scrollingTo)) ? calculateOffsetWithOffsetPosition(ctx, calculateOffsetForIndex(ctx, index), { ...scrollingTo, index }) : isRetargetingWebScroll ? calculateOffsetWithOffsetPosition(ctx, scrollingTo.offset, scrollingTo) : (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset - (scrollingTo.viewOffset || 0);
2010
+ return clampScrollOffset(ctx, requestedTargetOffset, scrollingTo);
1987
2011
  }
1988
2012
 
1989
2013
  // src/core/scrollRequestTracker.ts
@@ -2027,7 +2051,7 @@ function getScrollRequestTracker(ctx) {
2027
2051
  state.scrollAdjustHandler.commitPendingAdjust();
2028
2052
  }
2029
2053
  }
2030
- if (didStartScroll === "unreachable") {
2054
+ if (didStartScroll === "unreachable" || !didStartScroll && state.scrollingTo) {
2031
2055
  cancelScroll(ctx);
2032
2056
  return;
2033
2057
  }
@@ -2068,6 +2092,18 @@ function getScrollRequestTracker(ctx) {
2068
2092
  }
2069
2093
 
2070
2094
  // src/core/doMaintainScrollAtEnd.ts
2095
+ function reissueClampedNativeEndScroll(ctx) {
2096
+ var _a3, _b, _c;
2097
+ const state = ctx.state;
2098
+ const target = state.scrollingTo;
2099
+ if ((target == null ? void 0 : target.isScrollToEnd) && !target.animated && !((_a3 = ctx.scrollRequestTracker) == null ? void 0 : _a3.isWaitingToRun())) {
2100
+ const targetOffset = getCurrentTargetOffset(ctx, target);
2101
+ const distanceToTarget = targetOffset - ((_b = state.lastNativeScroll) != null ? _b : state.scroll);
2102
+ if (distanceToTarget > 1 || state.lastNativeScroll === void 0 && distanceToTarget < -1) {
2103
+ (_c = state.refScroller.current) == null ? void 0 : _c.scrollTo({ animated: false, ...getNativeScrollPoint(ctx, targetOffset) });
2104
+ }
2105
+ }
2106
+ }
2071
2107
  function doMaintainScrollAtEnd(ctx, options) {
2072
2108
  var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2073
2109
  const state = ctx.state;
@@ -2116,7 +2152,7 @@ function doMaintainScrollAtEnd(ctx, options) {
2116
2152
  return false;
2117
2153
  }
2118
2154
  if (state.scrollingTo || state.pendingScrollResolve) {
2119
- if (immediate && ((_k = state.scrollingTo) == null ? void 0 : _k.isScrollToEnd) && !state.scrollingTo.animated) {
2155
+ if ((options == null ? void 0 : options.immediate) && !maintainScrollAtEnd.animated && ((_k = state.scrollingTo) == null ? void 0 : _k.isScrollToEnd) && !state.scrollingTo.animated) {
2120
2156
  state.pendingMaintainScrollAtEnd = false;
2121
2157
  ctx.scrollToEnd({ animated: false });
2122
2158
  return true;
@@ -2127,7 +2163,7 @@ function doMaintainScrollAtEnd(ctx, options) {
2127
2163
  state.pendingMaintainScrollAtEnd = false;
2128
2164
  const contentSize = getContentSize(ctx);
2129
2165
  if (contentSize < state.scrollLength) {
2130
- state.scroll = 0;
2166
+ state.scroll = clampScrollOffset(ctx, 0);
2131
2167
  }
2132
2168
  if (!state.maintainingScrollAtEnd || immediate && (state.maintainingScrollAtEnd === "pending-instant" || state.maintainingScrollAtEnd === "instant")) {
2133
2169
  const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
@@ -2220,20 +2256,6 @@ function finishScrollTo(ctx) {
2220
2256
  }
2221
2257
  }
2222
2258
 
2223
- // src/utils/clampScrollIndex.ts
2224
- function clampScrollIndex(index, dataLength) {
2225
- if (dataLength <= 0) {
2226
- return -1;
2227
- }
2228
- if (index >= dataLength) {
2229
- return dataLength - 1;
2230
- }
2231
- if (index < 0) {
2232
- return 0;
2233
- }
2234
- return index;
2235
- }
2236
-
2237
2259
  // src/core/checkFinishedScroll.ts
2238
2260
  var INITIAL_SCROLL_MAX_FALLBACK_CHECKS = 20;
2239
2261
  var INITIAL_SCROLL_COMPLETION_TARGET_EPSILON = 1;
@@ -2281,16 +2303,6 @@ function shouldFinishInitialZeroTargetScroll(ctx) {
2281
2303
  const { state } = ctx;
2282
2304
  return !!((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) && state.props.data.length > 0 && getContentSize(ctx) <= state.scrollLength && state.scrollPending <= INITIAL_SCROLL_ZERO_TARGET_EPSILON;
2283
2305
  }
2284
- function isEndAlignedLastItemTarget(ctx, scrollingTo) {
2285
- return (scrollingTo.isScrollToEnd || scrollingTo.index === ctx.state.props.data.length - 1) && scrollingTo.viewPosition === 1;
2286
- }
2287
- function getCurrentTargetOffset(ctx, scrollingTo) {
2288
- var _a3, _b;
2289
- const index = scrollingTo.isScrollToEnd ? ctx.state.props.data.length - 1 : scrollingTo.index === void 0 ? void 0 : clampScrollIndex(scrollingTo.index, ctx.state.props.data.length);
2290
- const isRetargetingWebScroll = (!scrollingTo.isInitialScroll || ((_a3 = ctx.state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap");
2291
- const requestedTargetOffset = index !== void 0 && (isRetargetingWebScroll || isEndAlignedLastItemTarget(ctx, scrollingTo)) ? calculateOffsetWithOffsetPosition(ctx, calculateOffsetForIndex(ctx, index), { ...scrollingTo, index }) : isRetargetingWebScroll ? calculateOffsetWithOffsetPosition(ctx, scrollingTo.offset, scrollingTo) : (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset - (scrollingTo.viewOffset || 0);
2292
- return clampScrollOffset(ctx, requestedTargetOffset, scrollingTo);
2293
- }
2294
2306
  function getResolvedScrollCompletionState(ctx, scrollingTo) {
2295
2307
  const { state } = ctx;
2296
2308
  const isWebInitialScroll = scrollingTo.isInitialScroll;
@@ -2302,9 +2314,10 @@ function getResolvedScrollCompletionState(ctx, scrollingTo) {
2302
2314
  const adjustedTargetOffset = clampedTargetOffset + adjust;
2303
2315
  const diff2 = Math.abs(scroll - adjustedTargetOffset);
2304
2316
  const canUseAdjustedCompletion = !isWebInitialScroll && (!scrollingTo.animated || Platform.OS === "ios");
2317
+ const isWaitingForNativeEnd = Platform.OS !== "web";
2305
2318
  return {
2306
2319
  clampedTargetOffset,
2307
- isAtResolvedTarget: Math.abs(scroll - maxOffset) < 1 && (diff1 < 1 || canUseAdjustedCompletion && diff2 < 1)
2320
+ isAtResolvedTarget: !isWaitingForNativeEnd && Math.abs(scroll - maxOffset) < 1 && (diff1 < 1 || canUseAdjustedCompletion && diff2 < 1)
2308
2321
  };
2309
2322
  }
2310
2323
  function checkFinishedScrollFrame(ctx) {
@@ -2688,18 +2701,20 @@ function scrollTo(ctx, params) {
2688
2701
  if (forceScroll || !isInitialScroll || Platform.OS === "android") {
2689
2702
  doScrollTo(ctx, { animated, horizontal, offset });
2690
2703
  } else {
2691
- state.scroll = offset;
2704
+ state.scroll = targetOffset;
2692
2705
  }
2693
2706
  }
2694
2707
 
2695
2708
  // src/core/initialScroll.ts
2696
2709
  function dispatchInitialScroll(ctx, params) {
2710
+ var _a3;
2697
2711
  const { forceScroll, resolvedOffset, target, waitForCompletionFrame } = params;
2698
2712
  const requestedIndex = target.index;
2699
2713
  const index = requestedIndex !== void 0 ? clampScrollIndex(requestedIndex, ctx.state.props.data.length) : void 0;
2700
2714
  const itemSize = getItemSizeAtIndex(ctx, index);
2701
2715
  scrollTo(ctx, {
2702
2716
  animated: false,
2717
+ clampToContentContainerMinSize: ((_a3 = ctx.state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || isEndOfContentTarget(target, ctx.state.props.data.length),
2703
2718
  forceScroll,
2704
2719
  index: index !== void 0 && index >= 0 ? index : void 0,
2705
2720
  isInitialScroll: true,
@@ -2732,8 +2747,12 @@ function resolveInitialScrollOffset(ctx, initialScroll) {
2732
2747
  return (_b = initialScroll.contentOffset) != null ? _b : 0;
2733
2748
  }
2734
2749
  const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
2735
- const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
2736
- return clampScrollOffset(ctx, resolvedOffset, initialScroll);
2750
+ const target = {
2751
+ ...initialScroll,
2752
+ clampToContentContainerMinSize: isEndOfContentTarget(initialScroll, state.props.data.length)
2753
+ };
2754
+ const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, target);
2755
+ return clampScrollOffset(ctx, resolvedOffset, target);
2737
2756
  }
2738
2757
  function getAdvanceableInitialScrollState(state, options) {
2739
2758
  const { didFinishInitialScroll, queuedInitialLayout, scrollingTo } = state;
@@ -3552,7 +3571,7 @@ function updateSnapToOffsets(ctx) {
3552
3571
  const {
3553
3572
  props: { snapToIndices }
3554
3573
  } = state;
3555
- const contentSize = state.props.horizontal ? getContentSize(ctx) : void 0;
3574
+ const contentSize = state.props.horizontal ? getContentSize(ctx, false) : void 0;
3556
3575
  const snapToOffsets = Array(snapToIndices.length);
3557
3576
  for (let i = 0; i < snapToIndices.length; i++) {
3558
3577
  const idx = snapToIndices[i];
@@ -4611,31 +4630,7 @@ function maybeEmitFirstVisibleItemChanged(state, index) {
4611
4630
  state.lastFirstVisibleItemCallback = { index, key };
4612
4631
  onFirstVisibleItemChanged({ index, item: state.props.data[index], key });
4613
4632
  }
4614
- function findFirstVisibleIndexInCachedRange(ctx, scroll) {
4615
- var _a3, _b;
4616
- const state = ctx.state;
4617
- const {
4618
- endBuffered,
4619
- idCache,
4620
- positions,
4621
- props: { data },
4622
- sizes,
4623
- startBuffered
4624
- } = state;
4625
- if (startBuffered === null || endBuffered === null || startBuffered < 0 || endBuffered < startBuffered) {
4626
- return null;
4627
- }
4628
- for (let i = startBuffered; i <= endBuffered && i < data.length; i++) {
4629
- const id = (_a3 = idCache[i]) != null ? _a3 : getId(state, i);
4630
- const size = (_b = sizes.get(id)) != null ? _b : getItemSize(ctx, id, i, data[i]);
4631
- const top = positions[i];
4632
- if (top + size > scroll) {
4633
- return i;
4634
- }
4635
- }
4636
- return null;
4637
- }
4638
- function updateViewabilityForCachedRange(ctx, viewabilityConfigCallbackPairs, scrollLength, scroll, scrollBottom) {
4633
+ function updateVisibleRangeForCachedRange(ctx, viewabilityConfigCallbackPairs, scrollLength, scroll, scrollBottom) {
4639
4634
  var _a3, _b, _c, _d;
4640
4635
  const state = ctx.state;
4641
4636
  const {
@@ -4663,14 +4658,11 @@ function updateViewabilityForCachedRange(ctx, viewabilityConfigCallbackPairs, sc
4663
4658
  break;
4664
4659
  }
4665
4660
  }
4666
- Object.assign(state, {
4667
- endNoBuffer: visibleRange.endNoBuffer,
4668
- firstFullyOnScreenIndex: visibleRange.firstFullyOnScreenIndex,
4669
- idsInView: getIdsInVisibleRange(state, visibleRange),
4670
- startNoBuffer: visibleRange.startNoBuffer
4661
+ Object.assign(state, visibleRange, {
4662
+ idsInView: getIdsInVisibleRange(state, visibleRange)
4671
4663
  });
4672
4664
  maybeEmitFirstVisibleItemChanged(state, visibleRange.startNoBuffer);
4673
- if (state.props.hasExternalScroll || visibleRange.startNoBuffer !== null && visibleRange.endNoBuffer !== null) {
4665
+ if (viewabilityConfigCallbackPairs && (state.props.hasExternalScroll || visibleRange.startNoBuffer !== null && visibleRange.endNoBuffer !== null)) {
4674
4666
  updateViewableItems(
4675
4667
  state,
4676
4668
  ctx,
@@ -4713,7 +4705,8 @@ function calculateItemsInView(ctx, params = {}) {
4713
4705
  if (!data || scrollLength === 0 || !prevNumContainers) {
4714
4706
  return;
4715
4707
  }
4716
- let totalSize = getContentSize(ctx);
4708
+ const includeContentContainerMinSize = Platform.OS === "web";
4709
+ let totalSize = getContentSize(ctx, includeContentContainerMinSize);
4717
4710
  let changedContainerIds;
4718
4711
  const topPad = getStartOffsetAdjustment(ctx);
4719
4712
  const numColumns = peek$(ctx, "numColumns");
@@ -4780,8 +4773,9 @@ function calculateItemsInView(ctx, params = {}) {
4780
4773
  const scrollStart = state.props.hasExternalScroll ? scroll : Math.max(0, scroll);
4781
4774
  const overscrollBeforeContent = state.props.hasExternalScroll ? 0 : Math.max(0, -nativeScrollState);
4782
4775
  scrollBottom = Math.max(scrollStart, scroll + scrollLength + overscrollBeforeContent);
4776
+ const unusedTopBuffer = state.props.hasExternalScroll ? 0 : Math.max(0, scrollBufferTop - scroll);
4783
4777
  scrollTopBuffered = scrollStart - scrollBufferTop + projectedBufferAdjustment;
4784
- scrollBottomBuffered = scrollBottom + scrollBufferBottom + projectedBufferAdjustment;
4778
+ scrollBottomBuffered = scrollBottom + scrollBufferBottom + unusedTopBuffer + projectedBufferAdjustment;
4785
4779
  };
4786
4780
  updateScrollRange();
4787
4781
  if (projectedBufferAdjustment !== 0) {
@@ -4793,17 +4787,13 @@ function calculateItemsInView(ctx, params = {}) {
4793
4787
  state.scrollForNextCalculateItemsInView = void 0;
4794
4788
  } else if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
4795
4789
  if (!isInMVCPActiveMode(state)) {
4796
- if (viewabilityConfigCallbackPairs) {
4797
- updateViewabilityForCachedRange(
4798
- ctx,
4799
- viewabilityConfigCallbackPairs,
4800
- scrollLength,
4801
- scroll,
4802
- scrollBottom
4803
- );
4804
- } else if (state.props.onFirstVisibleItemChanged) {
4805
- maybeEmitFirstVisibleItemChanged(state, findFirstVisibleIndexInCachedRange(ctx, scroll));
4806
- }
4790
+ updateVisibleRangeForCachedRange(
4791
+ ctx,
4792
+ viewabilityConfigCallbackPairs,
4793
+ scrollLength,
4794
+ scroll,
4795
+ scrollBottom
4796
+ );
4807
4797
  (_d = stickyState == null ? void 0 : stickyState.finishCalculateItemsInView) == null ? void 0 : _d.call(stickyState);
4808
4798
  return;
4809
4799
  }
@@ -4825,7 +4815,7 @@ function calculateItemsInView(ctx, params = {}) {
4825
4815
  scrollVelocity: speed,
4826
4816
  startIndex
4827
4817
  });
4828
- totalSize = getContentSize(ctx);
4818
+ totalSize = getContentSize(ctx, includeContentContainerMinSize);
4829
4819
  if (positionRecalculationStartIndex !== void 0) {
4830
4820
  state.positionRecalculationStartIndex = void 0;
4831
4821
  }
@@ -4923,14 +4913,11 @@ function calculateItemsInView(ctx, params = {}) {
4923
4913
  }
4924
4914
  }
4925
4915
  }
4926
- Object.assign(state, {
4916
+ Object.assign(state, visibleRange, {
4927
4917
  endBuffered,
4928
- endNoBuffer: visibleRange.endNoBuffer,
4929
- firstFullyOnScreenIndex: visibleRange.firstFullyOnScreenIndex,
4930
4918
  idsInView: getIdsInVisibleRange(state, visibleRange),
4931
4919
  startBuffered,
4932
- startBufferedId,
4933
- startNoBuffer: visibleRange.startNoBuffer
4920
+ startBufferedId
4934
4921
  });
4935
4922
  if (enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0) {
4936
4923
  state.scrollForNextCalculateItemsInView = isNullOrUndefined(nextTop) && isNullOrUndefined(nextBottom) ? void 0 : {
@@ -5193,7 +5180,11 @@ function maybeUpdateAnchoredEndSpace(ctx) {
5193
5180
  contentBelowAnchor = Math.max(0, contentBelowAnchor - ctx.scrollAxisGap);
5194
5181
  contentBelowAnchor += (ctx.values.get("footerSize") || 0) + getStylePaddingEnd(state.props);
5195
5182
  isReady = !hasUnknownTailSize;
5196
- const knownSizeBound = Math.max(0, state.scrollLength - contentBelowAnchor - anchorOffset);
5183
+ const externalEndInset = 0;
5184
+ const knownSizeBound = Math.max(
5185
+ 0,
5186
+ state.scrollLength - contentBelowAnchor - anchorOffset - externalEndInset
5187
+ );
5197
5188
  nextSize = hasUnknownTailSize ? Math.min(previousSize || 0, knownSizeBound) : knownSizeBound;
5198
5189
  } else if (anchorIndex >= 0) {
5199
5190
  isReady = false;
@@ -5310,13 +5301,27 @@ function updateItemSizes(ctx, measurement) {
5310
5301
  updateItemSizesBatch(ctx, [measurement]);
5311
5302
  }
5312
5303
  }
5304
+ function isContainerItemCurrent(ctx, containerId, itemKey) {
5305
+ if (peek$(ctx, `containerItemKey${containerId}`) !== itemKey) return false;
5306
+ const state = ctx.state;
5307
+ const index = state.indexByKey.get(itemKey);
5308
+ if (index !== void 0 && index < state.props.data.length && getId(state, index) === itemKey) return true;
5309
+ state.scheduledWork.microtask(
5310
+ () => {
5311
+ var _a3;
5312
+ return (_a3 = ctx.containerLayoutTriggers.get(containerId)) == null ? void 0 : _a3();
5313
+ },
5314
+ `containerMeasurementRetry${containerId}`
5315
+ );
5316
+ return false;
5317
+ }
5313
5318
  function updateItemSizesBatch(ctx, measurements) {
5314
5319
  var _a3;
5315
5320
  const state = ctx.state;
5316
5321
  const result = {};
5317
5322
  const previousTotalSize = state.totalSize;
5318
5323
  for (const measurement of measurements) {
5319
- const ownsMeasuredItem = measurement.containerId === void 0 || peek$(ctx, `containerItemKey${measurement.containerId}`) === measurement.itemKey;
5324
+ const ownsMeasuredItem = measurement.containerId === void 0 || isContainerItemCurrent(ctx, measurement.containerId, measurement.itemKey);
5320
5325
  if (ownsMeasuredItem) {
5321
5326
  const index = state.indexByKey.get(measurement.itemKey);
5322
5327
  const itemData = index === void 0 ? void 0 : (_a3 = state.props.data) == null ? void 0 : _a3[index];
@@ -5475,7 +5480,7 @@ function measureContainersInLayoutEffect(ctx, targetContainerIds = null) {
5475
5480
  const viewRef = ctx.viewRefs.get(containerId);
5476
5481
  const itemKey = peek$(ctx, `containerItemKey${containerId}`);
5477
5482
  const element = viewRef == null ? void 0 : viewRef.current;
5478
- if (itemKey !== void 0 && element) {
5483
+ if (itemKey !== void 0 && element && isContainerItemCurrent(ctx, containerId, itemKey)) {
5479
5484
  const generation = (_b = ctx.state.containerItemGenerations[containerId]) != null ? _b : 0;
5480
5485
  const rect = element.getBoundingClientRect();
5481
5486
  setContainerLayoutBaseline(element, rect);
@@ -5509,7 +5514,7 @@ function measureContainersInLayoutEffect(ctx, targetContainerIds = null) {
5509
5514
  return index === void 0 || index < state.startBuffered || index > state.endBuffered || measuredKeys.has(key);
5510
5515
  });
5511
5516
  const physicalMax = (_e = (_d = state.refScroller.current) == null ? void 0 : _d.getMaxScrollOffset) == null ? void 0 : _e.call(_d);
5512
- const layoutMax = Math.max(0, getContentSize(ctx) - state.scrollLength);
5517
+ const layoutMax = getScrollRangeEnd(ctx);
5513
5518
  if (isCurrentViewportMeasured && isCurrentBufferMeasured && physicalMax !== void 0 && Math.abs(physicalMax - layoutMax) <= 1) {
5514
5519
  evaluateBootstrapInitialScroll(ctx);
5515
5520
  }
@@ -6964,7 +6969,8 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
6964
6969
  if (isWheel && !wheelAccepted) wheelStartedNested = true;
6965
6970
  return false;
6966
6971
  }
6967
- if (explicit ? !keepsExplicitOwner : direction <= 0) interruptUserScroll(ctx);
6972
+ if ((explicit ? !keepsExplicitOwner : direction <= 0) && interruptUserScroll(ctx, isWheel && event.cancelable ? direction : 0) && event.cancelable)
6973
+ event.preventDefault();
6968
6974
  if (isNew) (_b2 = (_a4 = state.props).onUserScroll) == null ? void 0 : _b2.call(_a4);
6969
6975
  return true;
6970
6976
  }
@@ -6976,11 +6982,15 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
6976
6982
  const inputDirection = (delta) => isHorizontalRTL(ctx.state) && getNativeHorizontalRTLScrollType(ctx.state) !== "normal" ? -delta : delta;
6977
6983
  const onWheel = (nativeEvent) => {
6978
6984
  const event = nativeEvent;
6979
- const delta = horizontal ? event.deltaX || (event.shiftKey ? event.deltaY : 0) : event.deltaY;
6985
+ const delta = normalizeWheelDelta(
6986
+ horizontal ? event.deltaX || (event.shiftKey ? event.deltaY : 0) : event.deltaY,
6987
+ event.deltaMode,
6988
+ ctx.state.scrollLength
6989
+ );
6980
6990
  if (delta !== 0 && !event.ctrlKey && !event.defaultPrevented) {
6981
6991
  wheelGesture = getWheelGesture(
6982
6992
  wheelGesture,
6983
- normalizeWheelDelta(delta, event.deltaMode, ctx.state.scrollLength),
6993
+ delta,
6984
6994
  event.timeStamp,
6985
6995
  event.momentum
6986
6996
  );
@@ -7050,7 +7060,15 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
7050
7060
  scrollbarPressOffset = void 0;
7051
7061
  if (offset !== void 0 && getCurrentScrollOffset() === offset) rearmEndFollowIfSettled(ctx);
7052
7062
  };
7053
- target.addEventListener("wheel", onWheel, { passive: true });
7063
+ let wheelPassive;
7064
+ const setWheelPassive = (passive) => {
7065
+ if (passive === wheelPassive) return;
7066
+ if (wheelPassive !== void 0) target.removeEventListener("wheel", onWheel);
7067
+ target.addEventListener("wheel", onWheel, { passive });
7068
+ wheelPassive = passive;
7069
+ };
7070
+ setWheelPassive(!peek$(ctx, "isScrollActive"));
7071
+ const unlistenScrollActive = listen$(ctx, "isScrollActive", (active) => setWheelPassive(!active));
7054
7072
  target.addEventListener("touchstart", onTouchStart, { passive: true });
7055
7073
  target.addEventListener("touchmove", onTouchMove, { passive: true });
7056
7074
  target.addEventListener("keydown", onKeyDown);
@@ -7058,6 +7076,7 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
7058
7076
  target.addEventListener("pointerup", onPointerRelease);
7059
7077
  target.addEventListener("pointercancel", onPointerRelease);
7060
7078
  return () => {
7079
+ unlistenScrollActive();
7061
7080
  target.removeEventListener("wheel", onWheel);
7062
7081
  target.removeEventListener("touchstart", onTouchStart);
7063
7082
  target.removeEventListener("touchmove", onTouchMove);
@@ -7480,6 +7499,14 @@ var ListComponent = typedMemo(function ListComponent2({
7480
7499
  },
7481
7500
  [ctx, onScrollToTop]
7482
7501
  );
7502
+ const { onContentSizeChange } = rest;
7503
+ useCallback(
7504
+ (width, height) => {
7505
+ reissueClampedNativeEndScroll(ctx);
7506
+ onContentSizeChange == null ? void 0 : onContentSizeChange(width, height);
7507
+ },
7508
+ [ctx, onContentSizeChange]
7509
+ );
7483
7510
  const onLayoutHeader = useCallback(
7484
7511
  (rect) => {
7485
7512
  const size = rect[horizontal ? "width" : "height"];
@@ -7635,6 +7662,7 @@ function checkResetContainers(ctx, dataProp, { didColumnsChange = false } = {})
7635
7662
  state.positionRecalculationStartIndex = 0;
7636
7663
  state.scrollForNextCalculateItemsInView = void 0;
7637
7664
  }
7665
+ state.positionsAreCurrent = false;
7638
7666
  calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
7639
7667
  if ((_a3 = state.pendingEndMeasurements) == null ? void 0 : _a3.size) {
7640
7668
  const removedMeasurements = new Set(state.pendingEndMeasurements);
@@ -7657,9 +7685,6 @@ function checkResetContainers(ctx, dataProp, { didColumnsChange = false } = {})
7657
7685
  if (!didMaintainScrollAtEnd && !state.pendingMaintainScrollAtEnd) {
7658
7686
  state.pendingEndMeasurements = void 0;
7659
7687
  }
7660
- if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
7661
- state.isEndReached = false;
7662
- }
7663
7688
  if (!didMaintainScrollAtEnd) {
7664
7689
  checkThresholds(ctx);
7665
7690
  }
@@ -7782,6 +7807,7 @@ function scrollToIndex(ctx, {
7782
7807
  animated = true,
7783
7808
  forceScroll,
7784
7809
  isInitialScroll,
7810
+ clampToContentContainerMinSize,
7785
7811
  viewPosition,
7786
7812
  viewPositionFallback
7787
7813
  }) {
@@ -7797,6 +7823,7 @@ function scrollToIndex(ctx, {
7797
7823
  state.scrollForNextCalculateItemsInView = void 0;
7798
7824
  scrollTo(ctx, {
7799
7825
  animated,
7826
+ clampToContentContainerMinSize,
7800
7827
  forceScroll,
7801
7828
  index,
7802
7829
  isInitialScroll,
@@ -8085,7 +8112,7 @@ var ScrollAdjustHandler = class {
8085
8112
  targetScroll = clampScrollOffset(this.ctx, targetScroll, scrollTarget);
8086
8113
  } else {
8087
8114
  targetScroll = clampScrollOffset(this.ctx, state.scroll + pending - superseded, {
8088
- clampToContentContainerMinSize: scrollTarget == null ? void 0 : scrollTarget.clampToContentContainerMinSize
8115
+ clampToContentContainerMinSize: !scrollTarget || scrollTarget.clampToContentContainerMinSize
8089
8116
  });
8090
8117
  }
8091
8118
  const adjustment = targetScroll - state.scroll;
@@ -8114,6 +8141,7 @@ function scrollToEnd(ctx, options) {
8114
8141
  const footerSize = peek$(ctx, "footerSize") || 0;
8115
8142
  scrollToIndex(ctx, {
8116
8143
  ...options,
8144
+ clampToContentContainerMinSize: true,
8117
8145
  index,
8118
8146
  viewOffset: getEndAlignedViewOffset(paddingBottom, footerSize) + ((options == null ? void 0 : options.viewOffset) || 0),
8119
8147
  viewPosition: 1
@@ -8333,9 +8361,10 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
8333
8361
  const observed = getObservedScrollOffset(ctx);
8334
8362
  const position = calculateOffsetForIndex(ctx, index) + getStartOffsetAdjustment(ctx) + (itemOffset != null ? itemOffset : 0);
8335
8363
  const size = hasRegion ? itemLength != null ? itemLength : 0 : ((_a3 = getItemSizeAtIndex(ctx, index)) != null ? _a3 : 0) - ctx.scrollAxisGap;
8336
- const viewportLength = state.scrollLength - getContentInsetEnd(ctx);
8337
- const viewportStart = observed + ((_b = viewportMargin == null ? void 0 : viewportMargin.start) != null ? _b : 0);
8338
- const viewportEnd = observed + viewportLength - ((_c = viewportMargin == null ? void 0 : viewportMargin.end) != null ? _c : 0);
8364
+ const insetTop = getContentInsetTop(ctx);
8365
+ const viewportLength = state.scrollLength - insetTop - getContentInsetEnd(ctx);
8366
+ const viewportStart = observed + insetTop + ((_b = viewportMargin == null ? void 0 : viewportMargin.start) != null ? _b : 0);
8367
+ const viewportEnd = observed + insetTop + viewportLength - ((_c = viewportMargin == null ? void 0 : viewportMargin.end) != null ? _c : 0);
8339
8368
  if (!hasRegion && position <= viewportStart && position + size >= viewportEnd) return false;
8340
8369
  const above = position < viewportStart;
8341
8370
  const below = position + size > viewportEnd;
@@ -8770,7 +8799,7 @@ var LegendList = typedMemo(
8770
8799
  })
8771
8800
  );
8772
8801
  var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
8773
- var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
8802
+ var _a3, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
8774
8803
  useEffect(subscribeScreenReader, []);
8775
8804
  const noopOnScroll = useCallback((_event) => {
8776
8805
  }, []);
@@ -8895,7 +8924,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8895
8924
  const hasInitialScrollIndex = initialScrollIndexProp !== void 0 && initialScrollIndexProp !== null;
8896
8925
  const hasInitialScrollOffset = initialScrollOffsetProp !== void 0 && initialScrollOffsetProp !== null;
8897
8926
  const shouldInitializeHorizontalRTL = !initialScrollAtEnd && !hasInitialScrollIndex && !hasInitialScrollOffset && isHorizontalRTLProps({ horizontal, rtl });
8898
- const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && (hasInitialScrollOffset || shouldInitializeHorizontalRTL);
8927
+ const initialInsetTop = 0;
8928
+ const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && (hasInitialScrollOffset || shouldInitializeHorizontalRTL || initialInsetTop > 0);
8899
8929
  const usesBootstrapInitialScroll = initialScrollAtEnd || hasInitialScrollIndex;
8900
8930
  const shouldBottomAlignNumericInitialScrollIndex = typeof initialScrollIndexProp === "number" && !hasInitialScrollOffset && dataProp.length > 1 && initialScrollIndexProp >= dataProp.length - 1;
8901
8931
  const initialScrollProp = initialScrollAtEnd ? {
@@ -8904,10 +8934,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8904
8934
  viewOffset: getEndAlignedViewOffset(stylePaddingEndState),
8905
8935
  viewPosition: 1
8906
8936
  } : hasInitialScrollIndex ? typeof initialScrollIndexProp === "object" ? {
8907
- index: (_b = initialScrollIndexProp.index) != null ? _b : 0,
8937
+ index: (_c = initialScrollIndexProp.index) != null ? _c : 0,
8908
8938
  preserveForBottomPadding: initialScrollIndexProp.viewOffset === void 0 && initialScrollIndexProp.viewPosition === 1 && initialScrollIndexProp.viewPositionFallback === void 0 ? true : void 0,
8909
- viewOffset: (_c = initialScrollIndexProp.viewOffset) != null ? _c : initialScrollIndexProp.viewPosition === 1 && initialScrollIndexProp.viewPositionFallback === void 0 ? getEndAlignedViewOffset(stylePaddingEndState) : 0,
8910
- viewPosition: (_d = initialScrollIndexProp.viewPosition) != null ? _d : 0,
8939
+ viewOffset: (_d = initialScrollIndexProp.viewOffset) != null ? _d : initialScrollIndexProp.viewPosition === 1 && initialScrollIndexProp.viewPositionFallback === void 0 ? getEndAlignedViewOffset(stylePaddingEndState) : 0,
8940
+ viewPosition: (_e = initialScrollIndexProp.viewPosition) != null ? _e : 0,
8911
8941
  viewPositionFallback: initialScrollIndexProp.viewPositionFallback
8912
8942
  } : {
8913
8943
  index: initialScrollIndexProp != null ? initialScrollIndexProp : 0,
@@ -8915,7 +8945,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8915
8945
  viewOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : shouldBottomAlignNumericInitialScrollIndex ? getEndAlignedViewOffset(stylePaddingEndState) : 0,
8916
8946
  viewPosition: shouldBottomAlignNumericInitialScrollIndex ? 1 : void 0
8917
8947
  } : initialScrollUsesOffsetOnly ? {
8918
- contentOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : 0,
8948
+ contentOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : -initialInsetTop,
8919
8949
  index: 0,
8920
8950
  viewOffset: 0
8921
8951
  } : void 0;
@@ -8923,7 +8953,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8923
8953
  const [, scheduleImperativeScrollCommit] = React3.useReducer((value) => value + 1, 0);
8924
8954
  const ctx = useStateContext();
8925
8955
  ctx.columnWrapperStyle = columnWrapperStyle || (contentContainerStyle ? createColumnWrapperStyle(contentContainerStyle) : void 0);
8926
- const scrollAxisGap = horizontal ? (_g = (_e = ctx.columnWrapperStyle) == null ? void 0 : _e.columnGap) != null ? _g : (_f = ctx.columnWrapperStyle) == null ? void 0 : _f.gap : (_j = (_h = ctx.columnWrapperStyle) == null ? void 0 : _h.rowGap) != null ? _j : (_i = ctx.columnWrapperStyle) == null ? void 0 : _i.gap;
8956
+ const scrollAxisGap = horizontal ? (_h = (_f = ctx.columnWrapperStyle) == null ? void 0 : _f.columnGap) != null ? _h : (_g = ctx.columnWrapperStyle) == null ? void 0 : _g.gap : (_k = (_i = ctx.columnWrapperStyle) == null ? void 0 : _i.rowGap) != null ? _k : (_j = ctx.columnWrapperStyle) == null ? void 0 : _j.gap;
8927
8957
  const nextScrollAxisGap = typeof scrollAxisGap === "number" && Number.isFinite(scrollAxisGap) ? scrollAxisGap : 0;
8928
8958
  const refScroller = useRef(null);
8929
8959
  const combinedRef = useCombinedRef(refScroller, refScrollView);
@@ -8938,8 +8968,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8938
8968
  anchoredEndSpace == null ? void 0 : anchoredEndSpace.anchorIndex,
8939
8969
  alwaysRender == null ? void 0 : alwaysRender.top,
8940
8970
  alwaysRender == null ? void 0 : alwaysRender.bottom,
8941
- (_k = alwaysRender == null ? void 0 : alwaysRender.indices) == null ? void 0 : _k.join(","),
8942
- (_l = alwaysRender == null ? void 0 : alwaysRender.keys) == null ? void 0 : _l.join(","),
8971
+ (_l = alwaysRender == null ? void 0 : alwaysRender.indices) == null ? void 0 : _l.join(","),
8972
+ (_m = alwaysRender == null ? void 0 : alwaysRender.keys) == null ? void 0 : _m.join(","),
8943
8973
  dataProp,
8944
8974
  dataKey,
8945
8975
  dataVersion,
@@ -8954,7 +8984,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8954
8984
  if (!refState.current) {
8955
8985
  if (!ctx.state) {
8956
8986
  const initialScrollLength = (estimatedListSize != null ? estimatedListSize : { height: 0, width: 0 } )[horizontal ? "width" : "height"];
8957
- ctx.values.set("adaptiveRender", (_m = experimental_adaptiveRender == null ? void 0 : experimental_adaptiveRender.initialMode) != null ? _m : "normal");
8987
+ ctx.values.set("adaptiveRender", (_n = experimental_adaptiveRender == null ? void 0 : experimental_adaptiveRender.initialMode) != null ? _n : "normal");
8958
8988
  ctx.state = {
8959
8989
  averageSizes: {},
8960
8990
  columnSpans: [],
@@ -9046,13 +9076,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
9046
9076
  const didScrollAxisGapChange = !isFirstLocal && ctx.scrollAxisGap !== nextScrollAxisGap;
9047
9077
  ctx.scrollAxisGap = nextScrollAxisGap;
9048
9078
  state.didColumnsChange = numColumnsProp !== previousNumColumnsProp || didScrollAxisGapChange;
9049
- const previousDataLength = (_o = (_n = state.props.data) == null ? void 0 : _n.length) != null ? _o : 0;
9079
+ const previousDataLength = (_p = (_o = state.props.data) == null ? void 0 : _o.length) != null ? _p : 0;
9050
9080
  const didDataReferenceChangeLocal = state.props.data !== dataProp;
9051
9081
  const didDataKeyChangeLocal = state.props.dataKey !== dataKey;
9052
9082
  const didDataVersionChangeLocal = state.props.dataVersion !== dataVersion;
9053
9083
  const didDataChangeLocal = didDataKeyChangeLocal || didDataVersionChangeLocal || didDataReferenceChangeLocal && checkStructuralDataChange(state, dataProp, state.props.data);
9054
9084
  const shouldResetFreshDataLayout = !isFirstLocal && didDataChangeLocal && state.hasHadNonEmptyData && (didDataKeyChangeLocal || previousDataLength === 0) && dataProp.length > 0;
9055
- if (didDataChangeLocal && !initialScrollAtEnd && state.didFinishInitialScroll && ((_p = state.initialScroll) == null ? void 0 : _p.viewPosition) === 1 && state.props.data.length > 0) {
9085
+ if (didDataChangeLocal && !initialScrollAtEnd && state.didFinishInitialScroll && ((_q = state.initialScroll) == null ? void 0 : _q.viewPosition) === 1 && state.props.data.length > 0) {
9056
9086
  clearPreservedInitialScrollTarget(state);
9057
9087
  }
9058
9088
  if (didDataChangeLocal) {
@@ -9068,7 +9098,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
9068
9098
  const freshDataTransitionEpoch = state.freshDataTransitionEpoch;
9069
9099
  const throttledOnScroll = useThrottledOnScroll(onScrollProp != null ? onScrollProp : noopOnScroll, scrollEventThrottle != null ? scrollEventThrottle : 0);
9070
9100
  const throttleScrollFn = scrollEventThrottle && onScrollProp ? throttledOnScroll : onScrollProp;
9071
- const didAnchoredEndSpaceAnchorIndexChange = !isFirstLocal && !didDataChangeLocal && ((_q = state.props.anchoredEndSpace) == null ? void 0 : _q.anchorIndex) !== (anchoredEndSpace == null ? void 0 : anchoredEndSpace.anchorIndex);
9101
+ const didAnchoredEndSpaceAnchorIndexChange = !isFirstLocal && !didDataChangeLocal && ((_r = state.props.anchoredEndSpace) == null ? void 0 : _r.anchorIndex) !== (anchoredEndSpace == null ? void 0 : anchoredEndSpace.anchorIndex);
9072
9102
  state.props = {
9073
9103
  adaptiveRender: experimental_adaptiveRender,
9074
9104
  alignItemsAtEnd,
@@ -9251,6 +9281,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
9251
9281
  anchoredEndSpace == null ? void 0 : anchoredEndSpace.anchorIndex,
9252
9282
  anchoredEndSpace == null ? void 0 : anchoredEndSpace.anchorMaxSize,
9253
9283
  anchoredEndSpace == null ? void 0 : anchoredEndSpace.anchorOffset,
9284
+ anchoredEndSpaceOwner,
9285
+ contentInset == null ? void 0 : contentInset.bottom,
9286
+ contentInset == null ? void 0 : contentInset.left,
9287
+ contentInset == null ? void 0 : contentInset.right,
9254
9288
  didAnchoredEndSpaceAnchorIndexChange,
9255
9289
  horizontal,
9256
9290
  numColumnsProp,
@@ -9310,6 +9344,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
9310
9344
  useLayoutEffect(
9311
9345
  () => initializeStateVars(true),
9312
9346
  [
9347
+ contentInset == null ? void 0 : contentInset.bottom,
9348
+ contentInset == null ? void 0 : contentInset.top,
9313
9349
  dataKey,
9314
9350
  dataVersion,
9315
9351
  memoizedLastItemKeys.join(","),
@@ -9320,6 +9356,16 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
9320
9356
  useAlignItemsAtEndPadding
9321
9357
  ]
9322
9358
  );
9359
+ const previousContentInsetTop = useRef(contentInset == null ? void 0 : contentInset.top);
9360
+ useLayoutEffect(() => {
9361
+ var _a4;
9362
+ Math.max(0, (_a4 = previousContentInsetTop.current) != null ? _a4 : 0);
9363
+ previousContentInsetTop.current !== (contentInset == null ? void 0 : contentInset.top);
9364
+ previousContentInsetTop.current = contentInset == null ? void 0 : contentInset.top;
9365
+ }, [contentInset == null ? void 0 : contentInset.top]);
9366
+ useLayoutEffect(() => {
9367
+ checkThresholds(ctx);
9368
+ }, [maintainScrollAtEndThreshold]);
9323
9369
  useLayoutEffect(() => {
9324
9370
  if (!maintainScrollAtEndConfig) {
9325
9371
  finishMaintainScrollAtEnd(ctx);
@@ -9495,7 +9541,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
9495
9541
  onScroll: onScrollHandler,
9496
9542
  recycleItems,
9497
9543
  refreshControl: refreshControlElement ? stylePaddingTopState > 0 ? React3.cloneElement(refreshControlElement, {
9498
- progressViewOffset: ((_r = refreshControlElement.props.progressViewOffset) != null ? _r : 0) + stylePaddingTopState
9544
+ progressViewOffset: ((_s = refreshControlElement.props.progressViewOffset) != null ? _s : 0) + stylePaddingTopState
9499
9545
  }) : refreshControlElement : onRefresh && /* @__PURE__ */ React3.createElement(
9500
9546
  RefreshControl,
9501
9547
  {
@@ -9506,7 +9552,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
9506
9552
  ),
9507
9553
  refScrollView: combinedRef,
9508
9554
  renderScrollComponent,
9509
- scrollAdjustHandler: (_s = refState.current) == null ? void 0 : _s.scrollAdjustHandler,
9555
+ scrollAdjustHandler: (_t = refState.current) == null ? void 0 : _t.scrollAdjustHandler,
9510
9556
  scrollElement: scrollElementResolved,
9511
9557
  scrollEventThrottle: 0,
9512
9558
  snapToIndices,