@legendapp/list 3.4.0 → 3.6.0

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/react.js CHANGED
@@ -901,8 +901,14 @@ function scheduleFullDrawDistancePrewarm(ctx) {
901
901
  return;
902
902
  }
903
903
  state.scheduledWork.frame(() => {
904
- var _a3;
905
- return (_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state);
904
+ var _a3, _b, _c;
905
+ if (state.props.hasExternalScroll && !hasActiveInitialScroll(state) && !state.scrollingTo && !state.pendingNativeMVCPAdjust) {
906
+ const offset = (_b = (_a3 = state.refScroller.current) == null ? void 0 : _a3.getRawScrollOffset) == null ? void 0 : _b.call(_a3);
907
+ if (offset !== void 0) {
908
+ state.scroll = state.scrollPending = state.props.horizontal ? toLogicalHorizontalOffset(state, offset, state.totalSize) : offset;
909
+ }
910
+ }
911
+ (_c = state.triggerCalculateItemsInView) == null ? void 0 : _c.call(state);
906
912
  }, "fullDrawDistancePrewarm");
907
913
  }
908
914
 
@@ -915,6 +921,9 @@ function resetInitialRenderState(ctx, {
915
921
  if (resetLayout) {
916
922
  state.didContainersLayout = false;
917
923
  state.queuedInitialLayout = false;
924
+ state.scrollBufferDirection = void 0;
925
+ state.scrollHistory.length = 0;
926
+ state.scheduledWork.cancel("renderRangeProjection");
918
927
  state.edgeReachedGate = void 0;
919
928
  state.isStartReached = null;
920
929
  state.isEndReached = null;
@@ -1141,6 +1150,7 @@ function setSize(ctx, itemKey, size, notifyTotalSize = true) {
1141
1150
  const previousSize = sizes.get(itemKey);
1142
1151
  const diff = previousSize !== void 0 ? size - previousSize : size;
1143
1152
  if (diff !== 0) {
1153
+ state.positionsAreCurrent = false;
1144
1154
  addTotalSize(ctx, itemKey, diff, notifyTotalSize);
1145
1155
  }
1146
1156
  sizes.set(itemKey, size);
@@ -1201,6 +1211,7 @@ function getKnownOrFixedSize(ctx, key, index, data, resolved) {
1201
1211
  const fixedSize = (resolved == null ? void 0 : resolved.didResolveFixedItemSize) ? resolved.fixedItemSize : getFixedItemSize(data, index, itemType);
1202
1212
  if (fixedSize !== void 0) {
1203
1213
  size = fixedSize + ctx.scrollAxisGap;
1214
+ state.positionsAreCurrent = false;
1204
1215
  state.sizesKnown.set(key, size);
1205
1216
  }
1206
1217
  }
@@ -1274,10 +1285,17 @@ function getItemSizeAtIndex(ctx, index) {
1274
1285
  }
1275
1286
 
1276
1287
  // src/core/calculateOffsetWithOffsetPosition.ts
1288
+ function getViewPositionOffset(availableSpace, viewPosition, viewPositionFallback) {
1289
+ let alignment = viewPosition;
1290
+ if (availableSpace < 0 && viewPositionFallback !== void 0) {
1291
+ alignment = viewPositionFallback === "start" ? 0 : 1;
1292
+ }
1293
+ return -alignment * availableSpace;
1294
+ }
1277
1295
  function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
1278
1296
  var _a3;
1279
1297
  const state = ctx.state;
1280
- const { index, viewOffset, viewPosition } = params;
1298
+ const { index, viewOffset, viewPosition, viewPositionFallback } = params;
1281
1299
  let offset = offsetParam;
1282
1300
  if (viewOffset) {
1283
1301
  offset -= viewOffset;
@@ -1298,7 +1316,8 @@ function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
1298
1316
  const measuredItemSize = isOutOfBounds ? fallbackEstimatedSize : getItemSize(ctx, getId(state, index), index, state.props.data[index]);
1299
1317
  const itemSize = Math.max(0, measuredItemSize - (isOutOfBounds ? 0 : ctx.scrollAxisGap));
1300
1318
  const trailingInset = getContentInsetEnd(ctx);
1301
- offset -= viewPosition * (state.scrollLength - trailingInset - itemSize);
1319
+ const availableSpace = state.scrollLength - trailingInset - itemSize;
1320
+ offset += getViewPositionOffset(availableSpace, viewPosition, viewPositionFallback);
1302
1321
  }
1303
1322
  return offset;
1304
1323
  }
@@ -1645,15 +1664,27 @@ function prepareMVCP(ctx, dataChanged, adjustmentSource) {
1645
1664
  anchorPositionForLock = newPosition;
1646
1665
  }
1647
1666
  }
1648
- if (scrollingToViewPosition && scrollingToViewPosition > 0) {
1667
+ if (scrollingTo && scrollingToViewPosition !== void 0 && (scrollingToViewPosition > 0 || scrollingTo.viewPositionFallback)) {
1649
1668
  const newSize = getItemSize(ctx, targetId, scrollTarget, state.props.data[scrollTarget]);
1650
- const prevSize = scrollingTo == null ? void 0 : scrollingTo.itemSize;
1669
+ const prevSize = scrollingTo.itemSize;
1651
1670
  if (newSize !== void 0 && prevSize !== void 0 && newSize !== prevSize) {
1652
- const diff = newSize - prevSize;
1653
- if (diff !== 0) {
1654
- positionDiff += diff * scrollingToViewPosition;
1655
- scrollingTo.itemSize = newSize;
1671
+ if (scrollingTo.viewPositionFallback) {
1672
+ const viewport = state.scrollLength - getContentInsetEnd(ctx);
1673
+ const previousSpace = viewport - Math.max(0, prevSize - ctx.scrollAxisGap);
1674
+ const nextSpace = viewport - Math.max(0, newSize - ctx.scrollAxisGap);
1675
+ positionDiff += getViewPositionOffset(
1676
+ nextSpace,
1677
+ scrollingToViewPosition,
1678
+ scrollingTo.viewPositionFallback
1679
+ ) - getViewPositionOffset(
1680
+ previousSpace,
1681
+ scrollingToViewPosition,
1682
+ scrollingTo.viewPositionFallback
1683
+ );
1684
+ } else {
1685
+ positionDiff += (newSize - prevSize) * scrollingToViewPosition;
1656
1686
  }
1687
+ scrollingTo.itemSize = newSize;
1657
1688
  }
1658
1689
  }
1659
1690
  updateAnchorLock(state, {
@@ -1782,6 +1813,9 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
1782
1813
  state.scrollTime = currentTime;
1783
1814
  const scrollDelta = Math.abs(newScroll - prevScroll);
1784
1815
  const isUserScrollEvent = !!(options == null ? void 0 : options.fromNativeScrollEvent) && scrollDelta > 0.1 && !adjustChanged && scrollingTo === void 0 && !state.pendingNativeMVCPAdjust;
1816
+ if (isUserScrollEvent) {
1817
+ state.scrollBufferDirection = newScroll > prevScroll ? 1 : -1;
1818
+ }
1785
1819
  const didCancelMaintainScrollAtEnd = isUserScrollEvent && newScroll < prevScroll && !!(state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd);
1786
1820
  if (didCancelMaintainScrollAtEnd) {
1787
1821
  finishMaintainScrollAtEnd(ctx);
@@ -1861,10 +1895,10 @@ function finishMaintainScrollAtEnd(ctx) {
1861
1895
  }
1862
1896
  }
1863
1897
  function doMaintainScrollAtEnd(ctx, options) {
1864
- var _a3, _b, _c, _d, _e, _f;
1898
+ var _a3, _b, _c, _d, _e, _f, _g, _h;
1865
1899
  const state = ctx.state;
1866
1900
  let didMaintain = false;
1867
- if (state.isDragging) {
1901
+ if (state.isDragging || ((_b = (_a3 = state.refScroller.current) == null ? void 0 : _a3.isScrollInRange) == null ? void 0 : _b.call(_a3)) === false) {
1868
1902
  finishMaintainScrollAtEnd(ctx);
1869
1903
  } else {
1870
1904
  const {
@@ -1876,11 +1910,11 @@ function doMaintainScrollAtEnd(ctx, options) {
1876
1910
  const immediate = (options == null ? void 0 : options.immediate) && Platform.OS === "web" && !(maintainScrollAtEnd == null ? void 0 : maintainScrollAtEnd.animated);
1877
1911
  const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
1878
1912
  const isReplayingPendingMaintain = !!state.pendingMaintainScrollAtEnd;
1879
- const shouldMaintainScrollAtEnd = !!(!((_a3 = ctx.scrollRequestTracker) == null ? void 0 : _a3.isWaitingToRun()) && (!state.scrollingTo || state.scrollingTo.isScrollToEnd) && (isWithinMaintainScrollAtEndThreshold || isReplayingPendingMaintain || ((_b = state.scrollingTo) == null ? void 0 : _b.isScrollToEnd)) && maintainScrollAtEnd && didFinishInitialScroll);
1913
+ const shouldMaintainScrollAtEnd = !!(!((_c = ctx.scrollRequestTracker) == null ? void 0 : _c.isWaitingToRun()) && (!state.scrollingTo || state.scrollingTo.isScrollToEnd) && (isWithinMaintainScrollAtEndThreshold || isReplayingPendingMaintain || ((_d = state.scrollingTo) == null ? void 0 : _d.isScrollToEnd)) && maintainScrollAtEnd && didFinishInitialScroll);
1880
1914
  if (shouldMaintainScrollAtEnd && !state.scrollingTo) {
1881
1915
  const scroller = state.refScroller.current;
1882
- const nativeMax = (_c = scroller == null ? void 0 : scroller.getMaxScrollOffset) == null ? void 0 : _c.call(scroller);
1883
- const observed = (_d = scroller == null ? void 0 : scroller.getCurrentScrollOffset) == null ? void 0 : _d.call(scroller);
1916
+ const nativeMax = (_e = scroller == null ? void 0 : scroller.getMaxScrollOffset) == null ? void 0 : _e.call(scroller);
1917
+ const observed = (_f = scroller == null ? void 0 : scroller.getCurrentScrollOffset) == null ? void 0 : _f.call(scroller);
1884
1918
  if (nativeMax !== void 0 && observed !== void 0 && nativeMax < state.scroll - 1 && Math.abs(observed - nativeMax) <= 1) {
1885
1919
  state.pendingMaintainScrollAtEnd = true;
1886
1920
  state.scrollPending = observed;
@@ -1892,13 +1926,13 @@ function doMaintainScrollAtEnd(ctx, options) {
1892
1926
  } else if (pendingNativeMVCPAdjust) {
1893
1927
  state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
1894
1928
  } else if (shouldMaintainScrollAtEnd && (state.scrollingTo || state.pendingScrollResolve)) {
1895
- if (immediate && ((_e = state.scrollingTo) == null ? void 0 : _e.isScrollToEnd) && !state.scrollingTo.animated) {
1929
+ if (immediate && ((_g = state.scrollingTo) == null ? void 0 : _g.isScrollToEnd) && !state.scrollingTo.animated) {
1896
1930
  state.pendingMaintainScrollAtEnd = false;
1897
1931
  ctx.scrollToEnd({ animated: false });
1898
1932
  didMaintain = true;
1899
1933
  } else {
1900
1934
  state.pendingMaintainScrollAtEnd = true;
1901
- (_f = state.maintainingScrollAtEnd) != null ? _f : state.maintainingScrollAtEnd = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
1935
+ (_h = state.maintainingScrollAtEnd) != null ? _h : state.maintainingScrollAtEnd = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
1902
1936
  }
1903
1937
  } else if (shouldMaintainScrollAtEnd && didContainersLayout) {
1904
1938
  state.pendingMaintainScrollAtEnd = false;
@@ -1912,8 +1946,9 @@ function doMaintainScrollAtEnd(ctx, options) {
1912
1946
  const scrollAtRequest = state.scroll;
1913
1947
  state.maintainingScrollAtEnd = pendingState;
1914
1948
  const run = () => {
1949
+ var _a4, _b2;
1915
1950
  if (state.maintainingScrollAtEnd === pendingState) {
1916
- if (state.isDragging) {
1951
+ if (state.isDragging || ((_b2 = (_a4 = state.refScroller.current) == null ? void 0 : _a4.isScrollInRange) == null ? void 0 : _b2.call(_a4)) === false) {
1917
1952
  finishMaintainScrollAtEnd(ctx);
1918
1953
  } else {
1919
1954
  const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
@@ -2299,7 +2334,8 @@ function scrollToIndex(ctx, {
2299
2334
  animated = true,
2300
2335
  forceScroll,
2301
2336
  isInitialScroll,
2302
- viewPosition
2337
+ viewPosition,
2338
+ viewPositionFallback
2303
2339
  }) {
2304
2340
  const state = ctx.state;
2305
2341
  const { data } = state.props;
@@ -2319,7 +2355,8 @@ function scrollToIndex(ctx, {
2319
2355
  itemSize,
2320
2356
  offset: firstIndexOffset,
2321
2357
  viewOffset,
2322
- viewPosition: viewPosition != null ? viewPosition : 0
2358
+ viewPosition: viewPosition != null ? viewPosition : 0,
2359
+ viewPositionFallback
2323
2360
  });
2324
2361
  }
2325
2362
 
@@ -2339,6 +2376,7 @@ function dispatchInitialScroll(ctx, params) {
2339
2376
  precomputedWithViewOffset: true,
2340
2377
  viewOffset: target.viewOffset,
2341
2378
  viewPosition: target.viewPosition,
2379
+ viewPositionFallback: target.viewPositionFallback,
2342
2380
  waitForInitialScrollCompletionFrame: waitForCompletionFrame
2343
2381
  });
2344
2382
  }
@@ -2673,7 +2711,7 @@ function createRetargetedBottomAlignedInitialScroll(options) {
2673
2711
  };
2674
2712
  }
2675
2713
  function areEquivalentBootstrapInitialScrollTargets(current, next) {
2676
- return current.index === next.index && current.preserveForBottomPadding === next.preserveForBottomPadding && current.preserveForFooterLayout === next.preserveForFooterLayout && current.viewOffset === next.viewOffset && current.viewPosition === next.viewPosition;
2714
+ return current.index === next.index && current.preserveForBottomPadding === next.preserveForBottomPadding && current.preserveForFooterLayout === next.preserveForFooterLayout && current.viewOffset === next.viewOffset && current.viewPosition === next.viewPosition && current.viewPositionFallback === next.viewPositionFallback;
2677
2715
  }
2678
2716
  function clearPendingInitialScrollFooterLayout(ctx, options) {
2679
2717
  const { dataLength, stylePaddingEnd, target } = options;
@@ -2888,7 +2926,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
2888
2926
  preserveForFooterLayout: shouldPreserveInitialScrollForFooterLayout(initialScroll),
2889
2927
  stylePaddingEnd
2890
2928
  });
2891
- const didTargetChange = initialScroll.index !== updatedInitialScroll.index || initialScroll.viewPosition !== updatedInitialScroll.viewPosition || initialScroll.viewOffset !== updatedInitialScroll.viewOffset;
2929
+ const didTargetChange = initialScroll.index !== updatedInitialScroll.index || initialScroll.viewPosition !== updatedInitialScroll.viewPosition || initialScroll.viewPositionFallback !== updatedInitialScroll.viewPositionFallback || initialScroll.viewOffset !== updatedInitialScroll.viewOffset;
2892
2930
  if (!didTargetChange) {
2893
2931
  clearPendingInitialScrollFooterLayout(ctx, {
2894
2932
  dataLength,
@@ -3356,6 +3394,7 @@ function handleInitialScrollDataChange(ctx, options) {
3356
3394
 
3357
3395
  // src/core/resetLayoutCachesForDataChange.ts
3358
3396
  function resetLayoutCachesForDataChange(state) {
3397
+ state.positionsAreCurrent = false;
3359
3398
  state.indexByKey.clear();
3360
3399
  state.idCache.length = 0;
3361
3400
  state.positions.length = 0;
@@ -3636,7 +3675,7 @@ function updateItemPositions(ctx, dataChanged, {
3636
3675
  scrollBottomBuffered: -1,
3637
3676
  startIndex: 0
3638
3677
  }) {
3639
- var _a3, _b, _c, _d, _e;
3678
+ var _a3, _b, _c, _d, _e, _f;
3640
3679
  const state = ctx.state;
3641
3680
  const hasPositionListeners = ctx.positionListeners.size > 0;
3642
3681
  const {
@@ -3652,6 +3691,11 @@ function updateItemPositions(ctx, dataChanged, {
3652
3691
  const dataLength = data.length;
3653
3692
  const numColumns = (_a3 = peek$(ctx, "numColumns")) != null ? _a3 : 1;
3654
3693
  const hasColumns = numColumns > 1;
3694
+ const canReuseEstimates = !doMVCP || !state.didContainersLayout && Object.keys(state.averageSizes).length === 0;
3695
+ if (state.positionsAreCurrent && !dataChanged && !forceFullUpdate && state.positionRecalculationStartIndex === void 0 && !scrollingTo && !hasColumns && !snapToIndices && positions.length === dataLength && canReuseEstimates) {
3696
+ return;
3697
+ }
3698
+ state.positionsAreCurrent = false;
3655
3699
  const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
3656
3700
  const extraData = peek$(ctx, "extraData");
3657
3701
  const layoutConfig = overrideItemLayout ? { span: 1 } : void 0;
@@ -3766,6 +3810,10 @@ function updateItemPositions(ctx, dataChanged, {
3766
3810
  }
3767
3811
  if (!didBreakEarly) {
3768
3812
  updateTotalSize(ctx);
3813
+ state.positionsAreCurrent = !hasColumns;
3814
+ if (startIndex <= ((_f = state.positionRecalculationStartIndex) != null ? _f : -1)) {
3815
+ state.positionRecalculationStartIndex = void 0;
3816
+ }
3769
3817
  }
3770
3818
  if (snapToIndices) {
3771
3819
  updateSnapToOffsets(ctx);
@@ -4328,7 +4376,7 @@ function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentSt
4328
4376
  }
4329
4377
  function trackVisibleRange(range, i, top, size, scroll, scrollBottom) {
4330
4378
  let didPassVisibleEnd = false;
4331
- if (range.startNoBuffer === null && top + size > scroll) {
4379
+ if (range.startNoBuffer === null && top + size > scroll && top <= scrollBottom) {
4332
4380
  range.startNoBuffer = i;
4333
4381
  }
4334
4382
  if (range.firstFullyOnScreenIndex === void 0 && top >= scroll - 10 && top <= scrollBottom) {
@@ -4394,7 +4442,7 @@ function findFirstVisibleIndexInCachedRange(ctx, scroll) {
4394
4442
  return null;
4395
4443
  }
4396
4444
  function updateViewabilityForCachedRange(ctx, viewabilityConfigCallbackPairs, scrollLength, scroll, scrollBottom) {
4397
- var _a3, _b;
4445
+ var _a3, _b, _c, _d;
4398
4446
  const state = ctx.state;
4399
4447
  const {
4400
4448
  endBuffered,
@@ -4428,14 +4476,14 @@ function updateViewabilityForCachedRange(ctx, viewabilityConfigCallbackPairs, sc
4428
4476
  startNoBuffer: visibleRange.startNoBuffer
4429
4477
  });
4430
4478
  maybeEmitFirstVisibleItemChanged(state, visibleRange.startNoBuffer);
4431
- if (visibleRange.startNoBuffer !== null && visibleRange.endNoBuffer !== null) {
4479
+ if (state.props.hasExternalScroll || visibleRange.startNoBuffer !== null && visibleRange.endNoBuffer !== null) {
4432
4480
  updateViewableItems(
4433
4481
  state,
4434
4482
  ctx,
4435
4483
  viewabilityConfigCallbackPairs,
4436
4484
  scrollLength,
4437
- visibleRange.startNoBuffer,
4438
- visibleRange.endNoBuffer,
4485
+ (_c = visibleRange.startNoBuffer) != null ? _c : 0,
4486
+ (_d = visibleRange.endNoBuffer) != null ? _d : -1,
4439
4487
  startBuffered,
4440
4488
  endBuffered
4441
4489
  );
@@ -4444,7 +4492,7 @@ function updateViewabilityForCachedRange(ctx, viewabilityConfigCallbackPairs, sc
4444
4492
  function calculateItemsInView(ctx, params = {}) {
4445
4493
  const state = ctx.state;
4446
4494
  batchedUpdates(() => {
4447
- var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
4495
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
4448
4496
  const {
4449
4497
  columns,
4450
4498
  containerItemKeys,
@@ -4496,7 +4544,7 @@ function calculateItemsInView(ctx, params = {}) {
4496
4544
  scrollAdjustPending = (_a4 = peek$(ctx, "scrollAdjustPending")) != null ? _a4 : 0;
4497
4545
  scrollAdjustPad = scrollAdjustPending - topPad;
4498
4546
  scroll = Math.round(nextScrollState + scrollExtra + scrollAdjustPad);
4499
- if (scroll + scrollLength > totalSize) {
4547
+ if (!state.props.hasExternalScroll && scroll + scrollLength > totalSize) {
4500
4548
  scroll = Math.max(0, totalSize - scrollLength);
4501
4549
  }
4502
4550
  };
@@ -4523,7 +4571,11 @@ function calculateItemsInView(ctx, params = {}) {
4523
4571
  let stickyState = dataChanged ? void 0 : resolveStickyState();
4524
4572
  let scrollBufferTop = drawDistance;
4525
4573
  let scrollBufferBottom = drawDistance;
4526
- if (speed > 0 || speed === 0 && scroll < Math.max(50, drawDistance)) {
4574
+ if (speed !== 0) {
4575
+ state.scrollBufferDirection = speed > 0 ? 1 : -1;
4576
+ }
4577
+ const bufferForward = state.scrollBufferDirection === 1 || state.scrollBufferDirection === void 0 && scroll < Math.max(50, drawDistance);
4578
+ if (bufferForward) {
4527
4579
  scrollBufferTop = drawDistance * 0.5;
4528
4580
  scrollBufferBottom = drawDistance * 1.5;
4529
4581
  } else {
@@ -4533,8 +4585,8 @@ function calculateItemsInView(ctx, params = {}) {
4533
4585
  const shouldProjectRenderRange = !dataChanged && !forceFullItemPositions && !suppressInitialScrollSideEffects && !hasActiveInitialScroll(state) && !state.scrollingTo && !state.pendingNativeMVCPAdjust && !!peek$(ctx, "readyToRender");
4534
4586
  const projectedBufferAdjustment = shouldProjectRenderRange ? getProjectedBufferAdjustment(speed, Math.min(scrollBufferTop, scrollBufferBottom)) : 0;
4535
4587
  const updateScrollRange = () => {
4536
- const scrollStart = Math.max(0, scroll);
4537
- const overscrollBeforeContent = Math.max(0, -nativeScrollState);
4588
+ const scrollStart = state.props.hasExternalScroll ? scroll : Math.max(0, scroll);
4589
+ const overscrollBeforeContent = state.props.hasExternalScroll ? 0 : Math.max(0, -nativeScrollState);
4538
4590
  scrollBottom = Math.max(scrollStart, scroll + scrollLength + overscrollBeforeContent);
4539
4591
  scrollTopBuffered = scrollStart - scrollBufferTop + projectedBufferAdjustment;
4540
4592
  scrollBottomBuffered = scrollBottom + scrollBufferBottom + projectedBufferAdjustment;
@@ -4663,7 +4715,7 @@ function calculateItemsInView(ctx, params = {}) {
4663
4715
  nextTop = top;
4664
4716
  }
4665
4717
  }
4666
- if (visibleRange.startNoBuffer !== null) {
4718
+ if (startBuffered !== null) {
4667
4719
  if (top <= scrollBottomBuffered) {
4668
4720
  endBuffered = i;
4669
4721
  if (scrollBottomBuffered > totalSize) {
@@ -4674,6 +4726,8 @@ function calculateItemsInView(ctx, params = {}) {
4674
4726
  } else {
4675
4727
  foundEnd = true;
4676
4728
  }
4729
+ } else if (top > scrollBottomBuffered) {
4730
+ foundEnd = true;
4677
4731
  }
4678
4732
  }
4679
4733
  }
@@ -4691,6 +4745,12 @@ function calculateItemsInView(ctx, params = {}) {
4691
4745
  bottom: nextBottom,
4692
4746
  top: nextTop
4693
4747
  };
4748
+ } else if (enableScrollForNextCalculateItemsInView && state.props.hasExternalScroll) {
4749
+ if (scrollBottomBuffered < 0) {
4750
+ state.scrollForNextCalculateItemsInView = { bottom: 0, top: null };
4751
+ } else if (scrollTopBuffered > totalSize) {
4752
+ state.scrollForNextCalculateItemsInView = { bottom: null, top: totalSize };
4753
+ }
4694
4754
  }
4695
4755
  let numContainers = prevNumContainers;
4696
4756
  const pendingRemoval = [];
@@ -4714,7 +4774,9 @@ function calculateItemsInView(ctx, params = {}) {
4714
4774
  }
4715
4775
  const hasScrollTargetPinnedRange = scrollTargetPinnedStart <= scrollTargetPinnedEnd;
4716
4776
  const isPinnedRenderIndex = (index) => alwaysRenderIndicesSet.has(index) || hasScrollTargetPinnedRange && index >= scrollTargetPinnedStart && index <= scrollTargetPinnedEnd;
4717
- if (startBuffered !== null && endBuffered !== null) {
4777
+ if (startBuffered !== null && endBuffered !== null || alwaysRenderIndicesArr.length || hasScrollTargetPinnedRange) {
4778
+ const allocationStart = startBuffered != null ? startBuffered : 0;
4779
+ const allocationEnd = endBuffered != null ? endBuffered : -1;
4718
4780
  const needNewContainers = [];
4719
4781
  const needNewContainersSet = /* @__PURE__ */ new Set();
4720
4782
  const addPinnedIndex = (index) => {
@@ -4730,7 +4792,7 @@ function calculateItemsInView(ctx, params = {}) {
4730
4792
  }
4731
4793
  }
4732
4794
  };
4733
- for (let i = startBuffered; i <= endBuffered; i++) {
4795
+ for (let i = allocationStart; i <= allocationEnd; i++) {
4734
4796
  const id = (_m = idCache[i]) != null ? _m : getId(state, i);
4735
4797
  if (!containerItemKeys.has(id)) {
4736
4798
  needNewContainersSet.add(i);
@@ -4752,8 +4814,8 @@ function calculateItemsInView(ctx, params = {}) {
4752
4814
  (_n = stickyState == null ? void 0 : stickyState.currentStickyIdx) != null ? _n : -1,
4753
4815
  needNewContainers,
4754
4816
  needNewContainersSet,
4755
- startBuffered,
4756
- endBuffered
4817
+ allocationStart,
4818
+ allocationEnd
4757
4819
  );
4758
4820
  } else if (previousStickyIndex !== -1) {
4759
4821
  set$(ctx, "activeStickyIndex", -1);
@@ -4762,8 +4824,8 @@ function calculateItemsInView(ctx, params = {}) {
4762
4824
  const availableContainerAllocations = findAvailableContainers(
4763
4825
  ctx,
4764
4826
  needNewContainers,
4765
- startBuffered,
4766
- endBuffered,
4827
+ allocationStart,
4828
+ allocationEnd,
4767
4829
  pendingRemoval,
4768
4830
  protectedContainerKeys,
4769
4831
  // Initial end alignment has no scroll velocity yet. Keep its
@@ -4890,19 +4952,19 @@ function calculateItemsInView(ctx, params = {}) {
4890
4952
  handleInitialScrollLayoutReady(ctx);
4891
4953
  }
4892
4954
  }
4893
- if (viewabilityConfigCallbackPairs && visibleRange.startNoBuffer !== null && visibleRange.endNoBuffer !== null) {
4955
+ if (viewabilityConfigCallbackPairs && (state.props.hasExternalScroll || visibleRange.startNoBuffer !== null && visibleRange.endNoBuffer !== null)) {
4894
4956
  updateViewableItems(
4895
4957
  ctx.state,
4896
4958
  ctx,
4897
4959
  viewabilityConfigCallbackPairs,
4898
4960
  scrollLength,
4899
- visibleRange.startNoBuffer,
4900
- visibleRange.endNoBuffer,
4901
- startBuffered != null ? startBuffered : visibleRange.startNoBuffer,
4902
- endBuffered != null ? endBuffered : visibleRange.endNoBuffer
4961
+ (_u = visibleRange.startNoBuffer) != null ? _u : 0,
4962
+ (_v = visibleRange.endNoBuffer) != null ? _v : -1,
4963
+ (_w = startBuffered != null ? startBuffered : visibleRange.startNoBuffer) != null ? _w : 0,
4964
+ (_x = endBuffered != null ? endBuffered : visibleRange.endNoBuffer) != null ? _x : -1
4903
4965
  );
4904
4966
  }
4905
- (_u = stickyState == null ? void 0 : stickyState.finishCalculateItemsInView) == null ? void 0 : _u.call(stickyState);
4967
+ (_y = stickyState == null ? void 0 : stickyState.finishCalculateItemsInView) == null ? void 0 : _y.call(stickyState);
4906
4968
  });
4907
4969
  }
4908
4970
 
@@ -5181,6 +5243,7 @@ function updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem, notif
5181
5243
  const rawSize = horizontal ? sizeObj.width : sizeObj.height;
5182
5244
  const prevSizeKnown = sizesKnown.get(itemKey);
5183
5245
  const size = Math.round(rawSize) ;
5246
+ if (prevSizeKnown !== size) state.positionsAreCurrent = false;
5184
5247
  sizesKnown.set(itemKey, size);
5185
5248
  if (fixedItemSize === void 0 && size > 0) {
5186
5249
  itemType != null ? itemType : itemType = getItemType ? (_b = getItemType(itemData, index)) != null ? _b : "" : "";
@@ -5601,10 +5664,19 @@ function useOnLayoutSync({
5601
5664
  measureInLayoutEffect = true,
5602
5665
  onLayoutProp,
5603
5666
  onLayoutChange,
5604
- webLayoutResync
5667
+ webLayoutResync,
5668
+ webExternalScroll = false
5605
5669
  }, deps) {
5670
+ const onExternalLayout = React3.useCallback(
5671
+ (event) => {
5672
+ onLayoutChange(event.nativeEvent.layout, false);
5673
+ onLayoutProp == null ? void 0 : onLayoutProp(event);
5674
+ },
5675
+ [onLayoutChange, onLayoutProp]
5676
+ );
5606
5677
  React3.useLayoutEffect(() => {
5607
5678
  var _a3, _b;
5679
+ if (webExternalScroll) return;
5608
5680
  const current = ref.current;
5609
5681
  const scrollableNode = (_b = (_a3 = current == null ? void 0 : current.getScrollableNode) == null ? void 0 : _a3.call(current)) != null ? _b : null;
5610
5682
  const element = scrollableNode || current;
@@ -5642,8 +5714,8 @@ function useOnLayoutSync({
5642
5714
  emit(toLayout(rectObserved), false);
5643
5715
  }
5644
5716
  });
5645
- }, [measureInLayoutEffect, ...deps || []]);
5646
- return {};
5717
+ }, [measureInLayoutEffect, webExternalScroll, ...deps || []]);
5718
+ return webExternalScroll ? { onLayout: onExternalLayout } : {};
5647
5719
  }
5648
5720
  function toLayout(rect) {
5649
5721
  if (!rect) {
@@ -6205,94 +6277,121 @@ function useRafCoalescer(callback) {
6205
6277
  return coalescer;
6206
6278
  }
6207
6279
 
6208
- // src/components/webConstants.ts
6209
- var LEGEND_LIST_CONTENT_CONTAINER_CLASS = "legend-list-content-container";
6210
- var LEGEND_LIST_SCROLLBAR_X_HIDDEN_CLASS = "legend-list-scrollbar-x-hidden";
6211
- var LEGEND_LIST_SCROLLBAR_Y_HIDDEN_CLASS = "legend-list-scrollbar-y-hidden";
6212
-
6213
6280
  // src/components/webScrollUtils.ts
6214
- function getDocumentScrollerNode() {
6215
- if (typeof document === "undefined") {
6216
- return null;
6217
- }
6218
- return document.scrollingElement || document.documentElement || document.body;
6281
+ function isWindowTarget(target) {
6282
+ return typeof window !== "undefined" && target === window;
6219
6283
  }
6220
- function getWindowScrollPosition() {
6221
- var _a3, _b, _c, _d;
6222
- if (typeof window === "undefined") {
6223
- return { x: 0, y: 0 };
6284
+ function getScrollPosition(target) {
6285
+ var _a3, _b, _c, _d, _e, _f;
6286
+ if (isWindowTarget(target)) {
6287
+ return { x: (_b = (_a3 = target.scrollX) != null ? _a3 : target.pageXOffset) != null ? _b : 0, y: (_d = (_c = target.scrollY) != null ? _c : target.pageYOffset) != null ? _d : 0 };
6224
6288
  }
6225
- return {
6226
- x: (_b = (_a3 = window.scrollX) != null ? _a3 : window.pageXOffset) != null ? _b : 0,
6227
- y: (_d = (_c = window.scrollY) != null ? _c : window.pageYOffset) != null ? _d : 0
6228
- };
6289
+ return { x: (_e = target == null ? void 0 : target.scrollLeft) != null ? _e : 0, y: (_f = target == null ? void 0 : target.scrollTop) != null ? _f : 0 };
6229
6290
  }
6230
- function getElementDocumentPosition(element, scroll) {
6231
- var _a3, _b;
6291
+ function getElementScrollPosition(element, target) {
6292
+ var _a3, _b, _c, _d, _e, _f;
6232
6293
  const rect = element == null ? void 0 : element.getBoundingClientRect();
6294
+ const scroll = getScrollPosition(target);
6295
+ const parent = target && !isWindowTarget(target) ? target : null;
6296
+ const parentRect = parent == null ? void 0 : parent.getBoundingClientRect();
6233
6297
  return {
6234
- left: ((_a3 = rect == null ? void 0 : rect.left) != null ? _a3 : 0) + scroll.x,
6235
- top: ((_b = rect == null ? void 0 : rect.top) != null ? _b : 0) + scroll.y
6298
+ left: ((_a3 = rect == null ? void 0 : rect.left) != null ? _a3 : 0) - ((_b = parentRect == null ? void 0 : parentRect.left) != null ? _b : 0) - ((_c = parent == null ? void 0 : parent.clientLeft) != null ? _c : 0) + scroll.x,
6299
+ top: ((_d = rect == null ? void 0 : rect.top) != null ? _d : 0) - ((_e = parentRect == null ? void 0 : parentRect.top) != null ? _e : 0) - ((_f = parent == null ? void 0 : parent.clientTop) != null ? _f : 0) + scroll.y
6236
6300
  };
6237
6301
  }
6238
6302
  function getContentSize2(content) {
6239
6303
  var _a3, _b;
6240
- return {
6241
- height: (_a3 = content == null ? void 0 : content.scrollHeight) != null ? _a3 : 0,
6242
- width: (_b = content == null ? void 0 : content.scrollWidth) != null ? _b : 0
6243
- };
6304
+ return { height: (_a3 = content == null ? void 0 : content.scrollHeight) != null ? _a3 : 0, width: (_b = content == null ? void 0 : content.scrollWidth) != null ? _b : 0 };
6244
6305
  }
6245
- function getScrollContentSize(scrollElement, contentElement, isWindowScroll) {
6246
- return getContentSize2(isWindowScroll ? contentElement : scrollElement);
6306
+ function getScrollContentSize(scrollElement, contentElement, externalTarget) {
6307
+ return getContentSize2(externalTarget !== void 0 ? contentElement : scrollElement);
6247
6308
  }
6248
- function getLayoutMeasurement(scrollElement, isWindowScroll, horizontal) {
6249
- var _a3, _b, _c, _d, _e, _f;
6250
- if (isWindowScroll && typeof window !== "undefined") {
6309
+ function getLayoutMeasurement(scrollElement, externalTarget, horizontal) {
6310
+ var _a3, _b, _c, _d, _e, _f, _g, _h;
6311
+ if (externalTarget !== void 0) {
6251
6312
  const rect = scrollElement == null ? void 0 : scrollElement.getBoundingClientRect();
6313
+ const viewport = isWindowTarget(externalTarget) ? { height: externalTarget.innerHeight, width: externalTarget.innerWidth } : { height: (_a3 = externalTarget == null ? void 0 : externalTarget.clientHeight) != null ? _a3 : 0, width: (_b = externalTarget == null ? void 0 : externalTarget.clientWidth) != null ? _b : 0 };
6252
6314
  return {
6253
- // In window-scroll mode, use viewport size on the scroll axis.
6254
- height: horizontal ? (_b = (_a3 = rect == null ? void 0 : rect.height) != null ? _a3 : scrollElement == null ? void 0 : scrollElement.clientHeight) != null ? _b : window.innerHeight : window.innerHeight,
6255
- // Keep the cross-axis size list-relative to avoid inflating container measurements.
6256
- width: horizontal ? window.innerWidth : (_d = (_c = rect == null ? void 0 : rect.width) != null ? _c : scrollElement == null ? void 0 : scrollElement.clientWidth) != null ? _d : window.innerWidth
6315
+ height: horizontal ? (_d = (_c = rect == null ? void 0 : rect.height) != null ? _c : scrollElement == null ? void 0 : scrollElement.clientHeight) != null ? _d : 0 : viewport.height,
6316
+ width: horizontal ? viewport.width : (_f = (_e = rect == null ? void 0 : rect.width) != null ? _e : scrollElement == null ? void 0 : scrollElement.clientWidth) != null ? _f : 0
6257
6317
  };
6258
6318
  }
6259
- return {
6260
- height: (_e = scrollElement == null ? void 0 : scrollElement.clientHeight) != null ? _e : 0,
6261
- width: (_f = scrollElement == null ? void 0 : scrollElement.clientWidth) != null ? _f : 0
6262
- };
6319
+ return { height: (_g = scrollElement == null ? void 0 : scrollElement.clientHeight) != null ? _g : 0, width: (_h = scrollElement == null ? void 0 : scrollElement.clientWidth) != null ? _h : 0 };
6263
6320
  }
6264
6321
  function clampOffset(offset, maxOffset) {
6265
6322
  return Math.max(0, Math.min(offset, maxOffset));
6266
6323
  }
6267
- function getAxisSize(size, horizontal) {
6268
- return horizontal ? size.width : size.height;
6269
- }
6270
6324
  function getMaxOffset(contentSize, layoutMeasurement, horizontal) {
6271
- return Math.max(0, getAxisSize(contentSize, horizontal) - getAxisSize(layoutMeasurement, horizontal));
6325
+ const axis = horizontal ? "width" : "height";
6326
+ return Math.max(0, contentSize[axis] - layoutMeasurement[axis]);
6272
6327
  }
6273
- function resolveScrollableNode(scrollElement, isWindowScroll) {
6274
- return isWindowScroll ? getDocumentScrollerNode() || scrollElement : scrollElement;
6328
+ function resolveScrollableNode(scrollElement, externalTarget) {
6329
+ if (isWindowTarget(externalTarget)) {
6330
+ return document.scrollingElement || document.documentElement || document.body;
6331
+ }
6332
+ return externalTarget === void 0 ? scrollElement : externalTarget;
6275
6333
  }
6276
- function resolveScrollEventTarget(scrollElement, isWindowScroll) {
6277
- return isWindowScroll && typeof window !== "undefined" ? window : scrollElement;
6334
+ function resolveScrollEventTarget(scrollElement, externalTarget) {
6335
+ return externalTarget === void 0 ? scrollElement : externalTarget;
6278
6336
  }
6279
- function getLayoutRectangle(element, isWindowScroll, horizontal) {
6280
- const rect = element.getBoundingClientRect();
6281
- const scroll = getWindowScrollPosition();
6282
- return {
6283
- height: isWindowScroll && typeof window !== "undefined" && !horizontal ? window.innerHeight : rect.height,
6284
- width: isWindowScroll && typeof window !== "undefined" && horizontal ? window.innerWidth : rect.width,
6285
- x: isWindowScroll ? rect.left + scroll.x : rect.left,
6286
- y: isWindowScroll ? rect.top + scroll.y : rect.top
6287
- };
6337
+ function getLayoutRectangle(element, externalTarget, horizontal) {
6338
+ if (externalTarget === void 0) {
6339
+ const rect = element.getBoundingClientRect();
6340
+ return { height: rect.height, width: rect.width, x: rect.left, y: rect.top };
6341
+ }
6342
+ const { left, top } = getElementScrollPosition(element, externalTarget);
6343
+ const { height, width } = getLayoutMeasurement(element, externalTarget, horizontal);
6344
+ return { height, width, x: left, y: top };
6288
6345
  }
6289
- function resolveWindowScrollTarget({ clampedOffset, horizontal, listPos, scroll }) {
6346
+ function resolveExternalScrollOffset({
6347
+ clampedOffset,
6348
+ horizontal,
6349
+ listPos,
6350
+ scroll
6351
+ }) {
6290
6352
  return {
6291
6353
  left: horizontal ? listPos.left + clampedOffset : scroll.x,
6292
6354
  top: horizontal ? scroll.y : listPos.top + clampedOffset
6293
6355
  };
6294
6356
  }
6295
6357
 
6358
+ // src/components/observeScrollLayout.ts
6359
+ function observeScrollLayout(element, owner, onLayout) {
6360
+ if (owner === null) return;
6361
+ const resizeObserver = new ResizeObserver(onLayout);
6362
+ const mutationObserver = owner === void 0 ? void 0 : new MutationObserver(observe);
6363
+ function observe() {
6364
+ resizeObserver.disconnect();
6365
+ mutationObserver == null ? void 0 : mutationObserver.disconnect();
6366
+ resizeObserver.observe(element);
6367
+ if (owner !== void 0) {
6368
+ for (let node = element; node && node !== owner; node = node.parentElement) {
6369
+ const parent = node.parentElement;
6370
+ if (parent) {
6371
+ resizeObserver.observe(parent);
6372
+ mutationObserver == null ? void 0 : mutationObserver.observe(parent, { childList: true });
6373
+ }
6374
+ for (let sibling = node.previousElementSibling; sibling; sibling = sibling.previousElementSibling) {
6375
+ resizeObserver.observe(sibling);
6376
+ }
6377
+ }
6378
+ }
6379
+ onLayout();
6380
+ }
6381
+ observe();
6382
+ if (isWindowTarget(owner)) owner.addEventListener("resize", onLayout);
6383
+ return () => {
6384
+ resizeObserver.disconnect();
6385
+ mutationObserver == null ? void 0 : mutationObserver.disconnect();
6386
+ if (isWindowTarget(owner)) owner.removeEventListener("resize", onLayout);
6387
+ };
6388
+ }
6389
+
6390
+ // src/components/webConstants.ts
6391
+ var LEGEND_LIST_CONTENT_CONTAINER_CLASS = "legend-list-content-container";
6392
+ var LEGEND_LIST_SCROLLBAR_X_HIDDEN_CLASS = "legend-list-scrollbar-x-hidden";
6393
+ var LEGEND_LIST_SCROLLBAR_Y_HIDDEN_CLASS = "legend-list-scrollbar-y-hidden";
6394
+
6296
6395
  // src/components/ListComponentScrollView.tsx
6297
6396
  var SCROLLBAR_HIDDEN_STYLE_ID = "legend-list-scrollbar-axis-hidden-style";
6298
6397
  var SCROLL_END_FALLBACK_MS = 200;
@@ -6351,6 +6450,7 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
6351
6450
  showsVerticalScrollIndicator = true,
6352
6451
  refreshControl,
6353
6452
  useWindowScroll = false,
6453
+ scrollElement: externalScrollElement,
6354
6454
  onLayout,
6355
6455
  ...props
6356
6456
  }, ref) {
@@ -6359,31 +6459,38 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
6359
6459
  const [anchoredEndSpaceSize] = useArr$(["anchoredEndSpaceSize"]);
6360
6460
  const scrollRef = React3.useRef(null);
6361
6461
  const contentRef = React3.useRef(null);
6362
- const isWindowScroll = useWindowScroll;
6462
+ const externalTarget = externalScrollElement === void 0 && useWindowScroll ? typeof window === "undefined" ? null : window : externalScrollElement;
6463
+ const isWindowScroll = isWindowTarget(externalTarget);
6464
+ const isExternalScroll = externalTarget !== void 0;
6363
6465
  const getScrollTarget = React3.useCallback(
6364
- () => resolveScrollEventTarget(scrollRef.current, isWindowScroll),
6365
- [isWindowScroll]
6466
+ () => resolveScrollEventTarget(scrollRef.current, externalTarget),
6467
+ [externalTarget]
6366
6468
  );
6367
6469
  const getMaxScrollOffset = React3.useCallback(() => {
6368
6470
  const scrollElement = scrollRef.current;
6369
- const contentSize = getScrollContentSize(scrollElement, contentRef.current, isWindowScroll);
6370
- const layoutMeasurement = getLayoutMeasurement(scrollElement, isWindowScroll, horizontal);
6471
+ const contentSize = getScrollContentSize(scrollElement, contentRef.current, externalTarget);
6472
+ const layoutMeasurement = getLayoutMeasurement(scrollElement, externalTarget, horizontal);
6371
6473
  return getMaxOffset(contentSize, layoutMeasurement, horizontal);
6372
- }, [horizontal, isWindowScroll]);
6474
+ }, [externalTarget, horizontal]);
6475
+ const getRawScrollOffset = React3.useCallback(() => {
6476
+ var _a4;
6477
+ const element = scrollRef.current;
6478
+ if (isExternalScroll) {
6479
+ const scroll = getScrollPosition(externalTarget);
6480
+ const listPos = getElementScrollPosition(element, externalTarget);
6481
+ return horizontal ? scroll.x - listPos.left : scroll.y - listPos.top;
6482
+ }
6483
+ return (_a4 = horizontal ? element == null ? void 0 : element.scrollLeft : element == null ? void 0 : element.scrollTop) != null ? _a4 : 0;
6484
+ }, [externalTarget, horizontal, isExternalScroll]);
6485
+ const isScrollInRange = React3.useCallback(() => {
6486
+ if (!isExternalScroll) return true;
6487
+ const offset = getRawScrollOffset();
6488
+ return offset >= -1 && offset <= getMaxScrollOffset() + 1;
6489
+ }, [getMaxScrollOffset, getRawScrollOffset, isExternalScroll]);
6373
6490
  const getCurrentScrollOffset = React3.useCallback(() => {
6374
- const scrollElement = scrollRef.current;
6375
- if (isWindowScroll) {
6376
- const maxOffset = getMaxScrollOffset();
6377
- const scroll = getWindowScrollPosition();
6378
- const listPos = getElementDocumentPosition(scrollElement, scroll);
6379
- const rawOffset = horizontal ? scroll.x - listPos.left : scroll.y - listPos.top;
6380
- return clampOffset(rawOffset, maxOffset);
6381
- }
6382
- if (!scrollElement) {
6383
- return 0;
6384
- }
6385
- return horizontal ? scrollElement.scrollLeft : scrollElement.scrollTop;
6386
- }, [getMaxScrollOffset, horizontal, isWindowScroll]);
6491
+ const offset = getRawScrollOffset();
6492
+ return isExternalScroll ? clampOffset(offset, getMaxScrollOffset()) : offset;
6493
+ }, [getMaxScrollOffset, getRawScrollOffset, isExternalScroll]);
6387
6494
  const scrollToLocalOffset = React3.useCallback(
6388
6495
  (offset, animated) => {
6389
6496
  const scrollElement = scrollRef.current;
@@ -6395,10 +6502,10 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
6395
6502
  const clampedOffset = clampOffset(offset, maxOffset);
6396
6503
  const behavior = animated ? "smooth" : "auto";
6397
6504
  const options = { behavior };
6398
- if (isWindowScroll) {
6399
- const scroll = getWindowScrollPosition();
6400
- const listPos = getElementDocumentPosition(scrollElement, scroll);
6401
- const { left, top } = resolveWindowScrollTarget({
6505
+ if (isExternalScroll) {
6506
+ const scroll = getScrollPosition(externalTarget);
6507
+ const listPos = getElementScrollPosition(scrollElement, externalTarget);
6508
+ const { left, top } = resolveExternalScrollOffset({
6402
6509
  clampedOffset,
6403
6510
  horizontal,
6404
6511
  listPos,
@@ -6413,7 +6520,7 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
6413
6520
  }
6414
6521
  target.scrollTo(options);
6415
6522
  },
6416
- [getMaxScrollOffset, getScrollTarget, horizontal, isWindowScroll]
6523
+ [externalTarget, getMaxScrollOffset, getScrollTarget, horizontal, isExternalScroll]
6417
6524
  );
6418
6525
  React3.useImperativeHandle(ref, () => {
6419
6526
  const api = {
@@ -6421,11 +6528,14 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
6421
6528
  var _a4;
6422
6529
  return (_a4 = scrollRef.current) == null ? void 0 : _a4.getBoundingClientRect();
6423
6530
  },
6531
+ getContentNode: () => contentRef.current,
6424
6532
  getCurrentScrollOffset,
6425
6533
  getMaxScrollOffset,
6426
- getScrollableNode: () => resolveScrollableNode(scrollRef.current, isWindowScroll),
6427
- getScrollEventTarget: () => getScrollTarget(),
6428
- getScrollResponder: () => resolveScrollableNode(scrollRef.current, isWindowScroll),
6534
+ getRawScrollOffset,
6535
+ getScrollableNode: () => resolveScrollableNode(scrollRef.current, externalTarget),
6536
+ getScrollEventTarget: getScrollTarget,
6537
+ getScrollResponder: () => resolveScrollableNode(scrollRef.current, externalTarget),
6538
+ isScrollInRange,
6429
6539
  isWindowScroll: () => isWindowScroll,
6430
6540
  scrollBy: (x, y) => {
6431
6541
  const target = getScrollTarget();
@@ -6449,14 +6559,24 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
6449
6559
  }
6450
6560
  };
6451
6561
  return api;
6452
- }, [getCurrentScrollOffset, getMaxScrollOffset, getScrollTarget, horizontal, isWindowScroll, scrollToLocalOffset]);
6562
+ }, [
6563
+ externalTarget,
6564
+ getCurrentScrollOffset,
6565
+ getRawScrollOffset,
6566
+ getMaxScrollOffset,
6567
+ isScrollInRange,
6568
+ getScrollTarget,
6569
+ horizontal,
6570
+ isWindowScroll,
6571
+ scrollToLocalOffset
6572
+ ]);
6453
6573
  const emitScroll = React3.useCallback(() => {
6454
6574
  if (!onScroll2 || !scrollRef.current) {
6455
6575
  return;
6456
6576
  }
6457
6577
  const contentSize = getContentSize2(contentRef.current);
6458
- const layoutMeasurement = getLayoutMeasurement(scrollRef.current, isWindowScroll, horizontal);
6459
- const offset = getCurrentScrollOffset();
6578
+ const layoutMeasurement = getLayoutMeasurement(scrollRef.current, externalTarget, horizontal);
6579
+ const offset = getRawScrollOffset();
6460
6580
  const scrollEvent = {
6461
6581
  nativeEvent: {
6462
6582
  contentOffset: {
@@ -6474,7 +6594,7 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
6474
6594
  }
6475
6595
  };
6476
6596
  onScroll2(scrollEvent);
6477
- }, [getCurrentScrollOffset, horizontal, isWindowScroll, onScroll2]);
6597
+ }, [externalTarget, getRawScrollOffset, horizontal, onScroll2]);
6478
6598
  const scrollEventCoalescer = useRafCoalescer(emitScroll);
6479
6599
  const scrollEndFallbackRef = React3.useRef(void 0);
6480
6600
  const emitScrollEnd = React3.useCallback(() => {
@@ -6536,14 +6656,14 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
6536
6656
  const delta = horizontal ? event.deltaX || (event.shiftKey ? event.deltaY : 0) : event.deltaY;
6537
6657
  if (delta < 0 && !event.ctrlKey && !event.defaultPrevented && (ctx.state.maintainingScrollAtEnd || ctx.state.pendingMaintainScrollAtEnd)) {
6538
6658
  const offset = getCurrentScrollOffset();
6539
- if (interruptMaintainScrollAtEnd(ctx)) {
6659
+ if (interruptMaintainScrollAtEnd(ctx) && isScrollInRange()) {
6540
6660
  scrollToLocalOffset(offset, false);
6541
6661
  }
6542
6662
  }
6543
6663
  };
6544
6664
  target.addEventListener("wheel", onWheel, { passive: true });
6545
6665
  return () => target.removeEventListener("wheel", onWheel);
6546
- }, [ctx, getCurrentScrollOffset, getScrollTarget, horizontal, scrollToLocalOffset]);
6666
+ }, [ctx, getCurrentScrollOffset, getScrollTarget, horizontal, isScrollInRange, scrollToLocalOffset]);
6547
6667
  React3.useEffect(() => {
6548
6668
  const doScroll = () => {
6549
6669
  if (contentOffset) {
@@ -6551,44 +6671,28 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
6551
6671
  }
6552
6672
  };
6553
6673
  doScroll();
6554
- requestAnimationFrame(doScroll);
6674
+ const frame = requestAnimationFrame(doScroll);
6675
+ return () => cancelAnimationFrame(frame);
6555
6676
  }, [contentOffset == null ? void 0 : contentOffset.x, contentOffset == null ? void 0 : contentOffset.y, horizontal, scrollToLocalOffset]);
6556
6677
  React3.useLayoutEffect(() => {
6557
- if (!onLayout || !scrollRef.current) return;
6558
6678
  const element = scrollRef.current;
6559
- const fireLayout = () => {
6560
- onLayout({
6561
- nativeEvent: {
6562
- layout: getLayoutRectangle(element, isWindowScroll, horizontal)
6563
- }
6564
- });
6565
- };
6566
- fireLayout();
6567
- const resizeObserver = new ResizeObserver(() => {
6568
- fireLayout();
6569
- });
6570
- resizeObserver.observe(element);
6571
- const onWindowResize = () => {
6572
- fireLayout();
6573
- };
6574
- if (isWindowScroll && typeof window !== "undefined" && typeof window.addEventListener === "function") {
6575
- window.addEventListener("resize", onWindowResize);
6576
- }
6577
- return () => {
6578
- resizeObserver.disconnect();
6579
- if (isWindowScroll && typeof window !== "undefined" && typeof window.removeEventListener === "function") {
6580
- window.removeEventListener("resize", onWindowResize);
6679
+ if (!onLayout || !element) return;
6680
+ return observeScrollLayout(element, externalTarget, () => {
6681
+ if (isExternalScroll && !ctx.state.lastLayout && !ctx.state.initialScroll) {
6682
+ ctx.state.scroll = ctx.state.scrollPending = getRawScrollOffset();
6581
6683
  }
6582
- };
6583
- }, [isWindowScroll, onLayout]);
6584
- const hiddenScrollIndicatorClassName = !isWindowScroll && (horizontal ? !showsHorizontalScrollIndicator && LEGEND_LIST_SCROLLBAR_X_HIDDEN_CLASS : !showsVerticalScrollIndicator && LEGEND_LIST_SCROLLBAR_Y_HIDDEN_CLASS);
6684
+ onLayout({ nativeEvent: { layout: getLayoutRectangle(element, externalTarget, horizontal) } });
6685
+ if (isExternalScroll) emitScroll();
6686
+ });
6687
+ }, [ctx, emitScroll, externalTarget, getRawScrollOffset, horizontal, isExternalScroll, onLayout]);
6688
+ const hiddenScrollIndicatorClassName = !isExternalScroll && (horizontal ? !showsHorizontalScrollIndicator && LEGEND_LIST_SCROLLBAR_X_HIDDEN_CLASS : !showsVerticalScrollIndicator && LEGEND_LIST_SCROLLBAR_Y_HIDDEN_CLASS);
6585
6689
  React3.useLayoutEffect(() => {
6586
6690
  if (hiddenScrollIndicatorClassName) {
6587
6691
  ensureScrollbarHiddenStyle();
6588
6692
  }
6589
6693
  }, [hiddenScrollIndicatorClassName]);
6590
6694
  const scrollViewStyle = {
6591
- ...isWindowScroll ? {} : {
6695
+ ...isExternalScroll ? {} : {
6592
6696
  overflow: "auto",
6593
6697
  overflowX: horizontal ? "auto" : showsHorizontalScrollIndicator ? "auto" : "hidden",
6594
6698
  overflowY: horizontal ? showsVerticalScrollIndicator ? "auto" : "hidden" : "auto",
@@ -6623,11 +6727,10 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
6623
6727
  scrollEventThrottle: _scrollEventThrottle,
6624
6728
  ScrollComponent: _ScrollComponent,
6625
6729
  snapToOffsets,
6626
- useWindowScroll: _useWindowScroll,
6627
6730
  className: scrollViewClassNameProp,
6628
6731
  ...webProps
6629
6732
  } = props;
6630
- const snapOffsets = !isWindowScroll ? getFiniteSnapOffsets(snapToOffsets) : [];
6733
+ const snapOffsets = !isExternalScroll ? getFiniteSnapOffsets(snapToOffsets) : [];
6631
6734
  if (snapOffsets.length > 0) {
6632
6735
  scrollViewStyle.scrollSnapType = horizontal ? "x mandatory" : "y mandatory";
6633
6736
  contentStyle.position = (_c = contentStyle.position) != null ? _c : "relative";
@@ -6702,12 +6805,12 @@ function getScrollAdjustAxis(horizontal) {
6702
6805
  };
6703
6806
  }
6704
6807
  function getScrollAdjustTarget(ctx, contentNode) {
6705
- var _a3, _b, _c;
6808
+ var _a3, _b, _c, _d, _e;
6706
6809
  const scrollView = (_a3 = ctx.state) == null ? void 0 : _a3.refScroller.current;
6707
6810
  const scrollElement = (_c = (_b = scrollView == null ? void 0 : scrollView.getScrollableNode) == null ? void 0 : _b.call(scrollView)) != null ? _c : null;
6708
6811
  let resolvedContentNode = null;
6709
6812
  if (scrollElement) {
6710
- resolvedContentNode = (contentNode == null ? void 0 : contentNode.isConnected) && contentNode.parentElement === scrollElement ? contentNode : scrollElement.querySelector(`:scope > .${LEGEND_LIST_CONTENT_CONTAINER_CLASS}`);
6813
+ resolvedContentNode = (_e = (_d = scrollView == null ? void 0 : scrollView.getContentNode) == null ? void 0 : _d.call(scrollView)) != null ? _e : (contentNode == null ? void 0 : contentNode.isConnected) && contentNode.parentElement === scrollElement ? contentNode : scrollElement.querySelector(`:scope > .${LEGEND_LIST_CONTENT_CONTAINER_CLASS}`);
6711
6814
  }
6712
6815
  return scrollElement ? { contentNode: resolvedContentNode, scrollElement } : null;
6713
6816
  }
@@ -6722,6 +6825,7 @@ function ScrollAdjust() {
6722
6825
  const temporaryPaddingRef = React3__namespace.useRef(void 0);
6723
6826
  const contentNodeRef = React3__namespace.useRef(null);
6724
6827
  const callback = React3__namespace.useCallback(() => {
6828
+ var _a3, _b, _c;
6725
6829
  const scrollAdjust = peek$(ctx, "scrollAdjust");
6726
6830
  const scrollAdjustUserOffset = peek$(ctx, "scrollAdjustUserOffset");
6727
6831
  const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0);
@@ -6732,17 +6836,21 @@ function ScrollAdjust() {
6732
6836
  const horizontal = !!ctx.state.props.horizontal;
6733
6837
  const axis = getScrollAdjustAxis(horizontal);
6734
6838
  const { contentNode, scrollElement: el } = target;
6735
- const currentScroll = horizontal ? el.scrollLeft : el.scrollTop;
6839
+ const scroller = ctx.state.refScroller.current;
6840
+ const parentScroll = horizontal ? el.scrollLeft : el.scrollTop;
6841
+ const isExternal = ctx.state.props.hasExternalScroll;
6842
+ const currentScroll = (_b = isExternal ? (_a3 = scroller == null ? void 0 : scroller.getCurrentScrollOffset) == null ? void 0 : _a3.call(scroller) : void 0) != null ? _b : parentScroll;
6843
+ const isOutsideList = ((_c = scroller == null ? void 0 : scroller.isScrollInRange) == null ? void 0 : _c.call(scroller)) === false;
6736
6844
  const userOffsetDelta = (scrollAdjustUserOffset || 0) - lastScrollAdjustUserOffsetRef.current;
6737
6845
  const intendedScroll = userOffsetDelta !== 0 ? currentScroll + userOffsetDelta : ctx.state.scroll;
6738
6846
  const scrollDelta = intendedScroll - currentScroll;
6739
- const shouldScroll = Math.abs(scrollDelta) > 0.01;
6847
+ const shouldScroll = !isOutsideList && Math.abs(scrollDelta) > 0.01;
6740
6848
  const scrollBy = () => scrollAdjustBy(el, axis.x * scrollDelta, axis.y * scrollDelta);
6741
6849
  contentNodeRef.current = contentNode;
6742
6850
  if (shouldScroll && contentNode) {
6743
- const totalSize = contentNode[axis.contentSizeKey];
6851
+ const totalSize = isExternal ? el[axis.contentSizeKey] : contentNode[axis.contentSizeKey];
6744
6852
  const viewportSize = el[axis.viewportSizeKey];
6745
- const nextScroll = currentScroll + scrollDelta;
6853
+ const nextScroll = parentScroll + scrollDelta;
6746
6854
  const needsTemporaryPadding = scrollDelta > 0 && !ctx.state.adjustingFromInitialMount && totalSize < nextScroll + viewportSize;
6747
6855
  if (needsTemporaryPadding) {
6748
6856
  const currentInlinePaddingEnd = contentNode.style[axis.paddingEndProp];
@@ -6907,6 +7015,7 @@ var ListComponent = typedMemo(function ListComponent2({
6907
7015
  stickyHeaderConfig,
6908
7016
  stickyHeaderIndices,
6909
7017
  useWindowScroll = false,
7018
+ scrollElement,
6910
7019
  ...rest
6911
7020
  }) {
6912
7021
  const ctx = useStateContext();
@@ -6972,7 +7081,7 @@ var ListComponent = typedMemo(function ListComponent2({
6972
7081
  SnapOrScroll,
6973
7082
  {
6974
7083
  ...rest,
6975
- ...ScrollComponent === ListComponentScrollView ? { onInternalScrollEnd, useWindowScroll } : {} ,
7084
+ ...ScrollComponent === ListComponentScrollView ? { onInternalScrollEnd, scrollElement, useWindowScroll } : {} ,
6976
7085
  contentContainerStyle: [
6977
7086
  horizontal ? { height: "100%" } : {},
6978
7087
  contentContainerStyle,
@@ -7012,7 +7121,15 @@ var WEB_UNBOUNDED_HEIGHT_CONTAINER_RATIO = 0.9;
7012
7121
  var WEB_UNBOUNDED_HEIGHT_VIEWPORT_RATIO = 0.9;
7013
7122
  function useDevChecksImpl(props) {
7014
7123
  const ctx = useStateContext();
7015
- const { anchoredEndSpace, childrenMode, keyExtractor, numColumns, renderScrollComponent, useWindowScroll } = props;
7124
+ const {
7125
+ anchoredEndSpace,
7126
+ childrenMode,
7127
+ keyExtractor,
7128
+ numColumns,
7129
+ renderScrollComponent,
7130
+ scrollElement,
7131
+ useWindowScroll
7132
+ } = props;
7016
7133
  const hasAnchoredEndSpace = !!anchoredEndSpace;
7017
7134
  React3.useEffect(() => {
7018
7135
  if (hasAnchoredEndSpace && (numColumns != null ? numColumns : 1) > 1) {
@@ -7023,13 +7140,13 @@ function useDevChecksImpl(props) {
7023
7140
  }
7024
7141
  }, [hasAnchoredEndSpace, numColumns]);
7025
7142
  React3.useEffect(() => {
7026
- if (useWindowScroll && renderScrollComponent) {
7143
+ if ((useWindowScroll || scrollElement !== void 0) && renderScrollComponent) {
7027
7144
  warnDevOnce(
7028
7145
  "useWindowScrollRenderScrollComponent",
7029
- "useWindowScroll is not supported when renderScrollComponent is provided."
7146
+ "useWindowScroll and scrollElement are not supported when renderScrollComponent is provided."
7030
7147
  );
7031
7148
  }
7032
- }, [renderScrollComponent, useWindowScroll]);
7149
+ }, [renderScrollComponent, scrollElement, useWindowScroll]);
7033
7150
  React3.useEffect(() => {
7034
7151
  if (!keyExtractor && !ctx.state.isFirst && ctx.state.didDataChange && !childrenMode) {
7035
7152
  warnDevOnce(
@@ -7041,8 +7158,8 @@ function useDevChecksImpl(props) {
7041
7158
  React3.useEffect(() => {
7042
7159
  const state = ctx.state;
7043
7160
  const dataLength = state.props.data.length;
7044
- const useWindowScrollResolved = state.props.useWindowScroll;
7045
- if (useWindowScrollResolved || dataLength < WEB_UNBOUNDED_HEIGHT_MIN_DATA_LENGTH) {
7161
+ const usesExternalScroll = state.props.hasExternalScroll;
7162
+ if (usesExternalScroll || dataLength < WEB_UNBOUNDED_HEIGHT_MIN_DATA_LENGTH) {
7046
7163
  return;
7047
7164
  }
7048
7165
  const warnIfUnboundedOuterSize = () => {
@@ -7206,7 +7323,8 @@ function doInitialAllocateContainers(ctx) {
7206
7323
  calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
7207
7324
  });
7208
7325
  } else {
7209
- calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
7326
+ const reuseInitialPositions = !state.didLoad && state.positionsAreCurrent && !state.didDataChange && !state.didColumnsChange;
7327
+ calculateItemsInView(ctx, { dataChanged: !reuseInitialPositions, doMVCP: true });
7210
7328
  }
7211
7329
  }
7212
7330
  return true;
@@ -7249,12 +7367,14 @@ function handleLayout(ctx, layoutParam, setCanRender) {
7249
7367
  updateContentMetricsState(ctx);
7250
7368
  state.lastBatchingAction = Date.now();
7251
7369
  state.scrollForNextCalculateItemsInView = void 0;
7252
- if (scrollLength > 0) {
7253
- doInitialAllocateContainers(ctx);
7254
- }
7255
- if (needsCalculate) {
7370
+ const didAllocate = scrollLength > 0 && doInitialAllocateContainers(ctx);
7371
+ if (needsCalculate && (!didAllocate || state.initialScroll)) {
7256
7372
  calculateItemsInView(ctx, { doMVCP: true });
7257
7373
  }
7374
+ const scrollTarget = state.scrollingTo;
7375
+ if (scrollLength !== previousLength && (scrollTarget == null ? void 0 : scrollTarget.viewPositionFallback) && !scrollTarget.isInitialScroll && scrollTarget.index !== void 0) {
7376
+ scrollToIndex(ctx, { ...scrollTarget, forceScroll: true, index: scrollTarget.index });
7377
+ }
7258
7378
  if (didChange || otherAxisSize !== prevOtherAxisSize) {
7259
7379
  set$(ctx, "scrollSize", { height: layout.height, width: layout.width });
7260
7380
  }
@@ -7330,7 +7450,7 @@ function onScroll(ctx, event) {
7330
7450
  state.didFinishInitialScroll && ((_f = state.initialScroll) == null ? void 0 : _f.viewPosition) === 1 && state.scroll > state.scrollLength;
7331
7451
  state.lastNativeScroll = newScroll;
7332
7452
  state.lastNativeScrollTime = Date.now();
7333
- if (state.scrollingTo && state.scrollingTo.offset >= newScroll) {
7453
+ if (!state.props.hasExternalScroll && state.scrollingTo && state.scrollingTo.offset >= newScroll) {
7334
7454
  const maxOffset = clampScrollOffset(ctx, newScroll, state.scrollingTo);
7335
7455
  if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
7336
7456
  newScroll = maxOffset;
@@ -8097,6 +8217,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8097
8217
  stickyHeaderIndices: stickyHeaderIndicesProp,
8098
8218
  style: styleProp,
8099
8219
  useWindowScroll = false,
8220
+ scrollElement,
8100
8221
  viewabilityConfig,
8101
8222
  viewabilityConfigCallbackPairs,
8102
8223
  ...rest
@@ -8152,9 +8273,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8152
8273
  viewPosition: 1
8153
8274
  } : hasInitialScrollIndex ? typeof initialScrollIndexProp === "object" ? {
8154
8275
  index: (_b = initialScrollIndexProp.index) != null ? _b : 0,
8155
- preserveForBottomPadding: initialScrollIndexProp.viewOffset === void 0 && initialScrollIndexProp.viewPosition === 1 ? true : void 0,
8156
- viewOffset: (_c = initialScrollIndexProp.viewOffset) != null ? _c : initialScrollIndexProp.viewPosition === 1 ? getEndAlignedViewOffset(stylePaddingEndState) : 0,
8157
- viewPosition: (_d = initialScrollIndexProp.viewPosition) != null ? _d : 0
8276
+ preserveForBottomPadding: initialScrollIndexProp.viewOffset === void 0 && initialScrollIndexProp.viewPosition === 1 && initialScrollIndexProp.viewPositionFallback === void 0 ? true : void 0,
8277
+ viewOffset: (_c = initialScrollIndexProp.viewOffset) != null ? _c : initialScrollIndexProp.viewPosition === 1 && initialScrollIndexProp.viewPositionFallback === void 0 ? getEndAlignedViewOffset(stylePaddingEndState) : 0,
8278
+ viewPosition: (_d = initialScrollIndexProp.viewPosition) != null ? _d : 0,
8279
+ viewPositionFallback: initialScrollIndexProp.viewPositionFallback
8158
8280
  } : {
8159
8281
  index: initialScrollIndexProp != null ? initialScrollIndexProp : 0,
8160
8282
  preserveForBottomPadding: shouldBottomAlignNumericInitialScrollIndex ? true : void 0,
@@ -8191,7 +8313,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8191
8313
  dataVersion,
8192
8314
  keyExtractor
8193
8315
  ]);
8194
- const useWindowScrollResolved = !!useWindowScroll && !renderScrollComponent;
8316
+ const scrollElementResolved = !renderScrollComponent ? scrollElement : void 0;
8317
+ const useWindowScrollResolved = !!useWindowScroll && scrollElementResolved === void 0 && !renderScrollComponent;
8318
+ const hasExternalScroll = useWindowScrollResolved || scrollElementResolved !== void 0;
8195
8319
  const refState = React3.useRef(void 0);
8196
8320
  const hasOverrideItemLayout = !!overrideItemLayout;
8197
8321
  const prevHasOverrideItemLayout = React3.useRef(hasOverrideItemLayout);
@@ -8329,6 +8453,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8329
8453
  estimatedItemSize,
8330
8454
  getFixedItemSize: useWrapIfItem(getFixedItemSize),
8331
8455
  getItemType: useWrapIfItem(getItemType),
8456
+ hasExternalScroll,
8332
8457
  hideItemsUntilMeasured: experimental_hideItemsUntilMeasured,
8333
8458
  horizontal: !!horizontal,
8334
8459
  itemsAreEqual,
@@ -8520,8 +8645,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8520
8645
  const { onLayout } = useOnLayoutSync({
8521
8646
  onLayoutChange,
8522
8647
  onLayoutProp,
8523
- ref: refScroller
8648
+ ref: refScroller,
8524
8649
  // the type of ScrollView doesn't include measure?
8650
+ webExternalScroll: hasExternalScroll
8525
8651
  });
8526
8652
  React3.useLayoutEffect(() => {
8527
8653
  if (snapToIndices) {
@@ -8687,6 +8813,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8687
8813
  refScrollView: combinedRef,
8688
8814
  renderScrollComponent,
8689
8815
  scrollAdjustHandler: (_s = refState.current) == null ? void 0 : _s.scrollAdjustHandler,
8816
+ scrollElement: scrollElementResolved,
8690
8817
  scrollEventThrottle: 0,
8691
8818
  snapToIndices,
8692
8819
  stickyHeaderIndices,