@legendapp/list 3.0.0-beta.36 → 3.0.0-beta.38

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/index.native.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var React2 = require('react');
4
- var reactNative = require('react-native');
4
+ var ReactNative = require('react-native');
5
5
  var shim = require('use-sync-external-store/shim');
6
6
 
7
7
  function _interopNamespace(e) {
@@ -23,11 +23,12 @@ function _interopNamespace(e) {
23
23
  }
24
24
 
25
25
  var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
26
+ var ReactNative__namespace = /*#__PURE__*/_interopNamespace(ReactNative);
26
27
 
27
28
  // src/components/LegendList.tsx
28
- reactNative.Animated.View;
29
- var View = reactNative.View;
30
- var Text = reactNative.Text;
29
+ ReactNative.Animated.View;
30
+ var View = ReactNative.View;
31
+ var Text = ReactNative.Text;
31
32
 
32
33
  // src/state/getContentInsetEnd.ts
33
34
  function getContentInsetEnd(state) {
@@ -59,7 +60,7 @@ function getContentSize(ctx) {
59
60
  const totalSize = (_a3 = state.pendingTotalSize) != null ? _a3 : values.get("totalSize");
60
61
  return headerSize + footerSize + totalSize + stylePaddingTop + stylePaddingBottom + (contentInsetBottom || 0);
61
62
  }
62
- var createAnimatedValue = (value) => new reactNative.Animated.Value(value);
63
+ var createAnimatedValue = (value) => new ReactNative.Animated.Value(value);
63
64
 
64
65
  // src/state/state.tsx
65
66
  var ContextState = React2__namespace.createContext(null);
@@ -250,7 +251,7 @@ var ENABLE_DEBUG_VIEW = IS_DEV && false;
250
251
  var f = global.nativeFabricUIManager;
251
252
  var IsNewArchitecture = f !== void 0 && f != null;
252
253
  var useAnimatedValue = (initialValue) => {
253
- const [animAnimatedValue] = React2.useState(() => new reactNative.Animated.Value(initialValue));
254
+ const [animAnimatedValue] = React2.useState(() => new ReactNative.Animated.Value(initialValue));
254
255
  return animAnimatedValue;
255
256
  };
256
257
 
@@ -341,7 +342,7 @@ function useValue$(key, params) {
341
342
  }, []);
342
343
  return animValue;
343
344
  }
344
- var typedMemo = React2.memo;
345
+ var typedMemo = React2__namespace.memo;
345
346
  var getComponent = (Component) => {
346
347
  if (React2__namespace.isValidElement(Component)) {
347
348
  return Component;
@@ -362,7 +363,7 @@ var PositionViewState = typedMemo(function PositionViewState2({
362
363
  }) {
363
364
  const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
364
365
  return /* @__PURE__ */ React2__namespace.createElement(
365
- reactNative.View,
366
+ ReactNative.View,
366
367
  {
367
368
  ref: refView,
368
369
  style: [
@@ -384,12 +385,12 @@ var PositionViewAnimated = typedMemo(function PositionViewAnimated2({
384
385
  getValue: (v) => v != null ? v : POSITION_OUT_OF_VIEW
385
386
  });
386
387
  let position;
387
- if (reactNative.Platform.OS === "ios" || reactNative.Platform.OS === "android") {
388
+ if (ReactNative.Platform.OS === "ios" || ReactNative.Platform.OS === "android") {
388
389
  position = horizontal ? { transform: [{ translateX: position$ }] } : { transform: [{ translateY: position$ }] };
389
390
  } else {
390
391
  position = horizontal ? { left: position$ } : { top: position$ };
391
392
  }
392
- return /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { ref: refView, style: [style, position], ...rest });
393
+ return /* @__PURE__ */ React2__namespace.createElement(ReactNative.Animated.View, { ref: refView, style: [style, position], ...rest });
393
394
  });
394
395
  var PositionViewSticky = typedMemo(function PositionViewSticky2({
395
396
  id,
@@ -427,7 +428,7 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
427
428
  return null;
428
429
  }
429
430
  return /* @__PURE__ */ React2__namespace.createElement(
430
- reactNative.View,
431
+ ReactNative.View,
431
432
  {
432
433
  style: {
433
434
  inset: 0,
@@ -438,7 +439,7 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
438
439
  getComponent(stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.backdropComponent)
439
440
  );
440
441
  }, [stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.backdropComponent]);
441
- return /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { ref: refView, style: viewStyle, ...rest }, renderStickyHeaderBackdrop, children);
442
+ return /* @__PURE__ */ React2__namespace.createElement(ReactNative.Animated.View, { ref: refView, style: viewStyle, ...rest }, renderStickyHeaderBackdrop, children);
442
443
  });
443
444
  var PositionView = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
444
445
  function useInit(cb) {
@@ -631,10 +632,10 @@ function useOnLayoutSync({
631
632
  }
632
633
  return { onLayout };
633
634
  }
634
- var Platform2 = reactNative.Platform;
635
+ var Platform2 = ReactNative.Platform;
635
636
  var PlatformAdjustBreaksScroll = Platform2.OS === "android";
636
- var typedForwardRef = React2.forwardRef;
637
- var typedMemo2 = React2.memo;
637
+ var typedForwardRef = React2__namespace.forwardRef;
638
+ var typedMemo2 = React2__namespace.memo;
638
639
 
639
640
  // src/utils/isInMVCPActiveMode.native.ts
640
641
  function isInMVCPActiveMode(state) {
@@ -887,15 +888,15 @@ var Containers = typedMemo(function Containers2({
887
888
  }
888
889
  }
889
890
  }
890
- return /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { style }, containers);
891
+ return /* @__PURE__ */ React2__namespace.createElement(ReactNative.Animated.View, { style }, containers);
891
892
  });
892
- var ListComponentScrollView = reactNative.Animated.ScrollView;
893
+ var ListComponentScrollView = ReactNative.Animated.ScrollView;
893
894
  function ScrollAdjust() {
894
895
  const bias = 1e7;
895
896
  const [scrollAdjust, scrollAdjustUserOffset] = useArr$(["scrollAdjust", "scrollAdjustUserOffset"]);
896
897
  const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0) + bias;
897
898
  return /* @__PURE__ */ React2__namespace.createElement(
898
- reactNative.View,
899
+ ReactNative.View,
899
900
  {
900
901
  style: {
901
902
  height: 0,
@@ -912,9 +913,9 @@ function SnapWrapper({ ScrollComponent, ...props }) {
912
913
  return /* @__PURE__ */ React2__namespace.createElement(ScrollComponent, { ...props, snapToOffsets });
913
914
  }
914
915
  var LayoutView = ({ onLayoutChange, refView, ...rest }) => {
915
- const ref = refView != null ? refView : React2.useRef();
916
+ const ref = refView != null ? refView : React2.useRef(null);
916
917
  const { onLayout } = useOnLayoutSync({ onLayoutChange, ref });
917
- return /* @__PURE__ */ React2__namespace.createElement(reactNative.View, { ...rest, onLayout, ref });
918
+ return /* @__PURE__ */ React2__namespace.createElement(ReactNative.View, { ...rest, onLayout, ref });
918
919
  };
919
920
 
920
921
  // src/components/ListComponent.tsx
@@ -939,8 +940,8 @@ var ListComponent = typedMemo2(function ListComponent2({
939
940
  updateItemSize: updateItemSize2,
940
941
  refScrollView,
941
942
  renderScrollComponent,
943
+ onLayoutFooter,
942
944
  scrollAdjustHandler,
943
- onLayoutHeader,
944
945
  snapToIndices,
945
946
  stickyHeaderConfig,
946
947
  stickyHeaderIndices,
@@ -964,6 +965,21 @@ var ListComponent = typedMemo2(function ListComponent2({
964
965
  set$(ctx, "footerSize", 0);
965
966
  }
966
967
  }, [ListHeaderComponent, ListFooterComponent, ctx]);
968
+ const onLayoutHeader = React2.useCallback(
969
+ (rect) => {
970
+ const size = rect[horizontal ? "width" : "height"];
971
+ set$(ctx, "headerSize", size);
972
+ },
973
+ [ctx, horizontal]
974
+ );
975
+ const onLayoutFooterInternal = React2.useCallback(
976
+ (rect, fromLayoutEffect) => {
977
+ const size = rect[horizontal ? "width" : "height"];
978
+ set$(ctx, "footerSize", size);
979
+ onLayoutFooter == null ? void 0 : onLayoutFooter(rect, fromLayoutEffect);
980
+ },
981
+ [ctx, horizontal, onLayoutFooter]
982
+ );
967
983
  return /* @__PURE__ */ React2__namespace.createElement(
968
984
  SnapOrScroll,
969
985
  {
@@ -999,17 +1015,7 @@ var ListComponent = typedMemo2(function ListComponent2({
999
1015
  waitForInitialLayout
1000
1016
  }
1001
1017
  ),
1002
- ListFooterComponent && /* @__PURE__ */ React2__namespace.createElement(
1003
- LayoutView,
1004
- {
1005
- onLayoutChange: (layout) => {
1006
- const size = layout[horizontal ? "width" : "height"];
1007
- set$(ctx, "footerSize", size);
1008
- },
1009
- style: ListFooterComponentStyle
1010
- },
1011
- getComponent(ListFooterComponent)
1012
- ),
1018
+ ListFooterComponent && /* @__PURE__ */ React2__namespace.createElement(LayoutView, { onLayoutChange: onLayoutFooterInternal, style: ListFooterComponentStyle }, getComponent(ListFooterComponent)),
1013
1019
  IS_DEV && ENABLE_DEVMODE
1014
1020
  );
1015
1021
  });
@@ -1017,19 +1023,12 @@ var ListComponent = typedMemo2(function ListComponent2({
1017
1023
  // src/core/calculateOffsetForIndex.ts
1018
1024
  function calculateOffsetForIndex(ctx, index) {
1019
1025
  const state = ctx.state;
1020
- let position = 0;
1021
- if (index !== void 0) {
1022
- position = state.positions[index] || 0;
1023
- const paddingTop = peek$(ctx, "stylePaddingTop");
1024
- if (paddingTop) {
1025
- position += paddingTop;
1026
- }
1027
- const headerSize = peek$(ctx, "headerSize");
1028
- if (headerSize) {
1029
- position += headerSize;
1030
- }
1031
- }
1032
- return position;
1026
+ return index !== void 0 ? state.positions[index] || 0 : 0;
1027
+ }
1028
+
1029
+ // src/core/getTopOffsetAdjustment.ts
1030
+ function getTopOffsetAdjustment(ctx) {
1031
+ return (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
1033
1032
  }
1034
1033
 
1035
1034
  // src/utils/getId.ts
@@ -1137,10 +1136,20 @@ function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
1137
1136
  if (viewOffset) {
1138
1137
  offset -= viewOffset;
1139
1138
  }
1139
+ if (index !== void 0) {
1140
+ const topOffsetAdjustment = getTopOffsetAdjustment(ctx);
1141
+ if (topOffsetAdjustment) {
1142
+ offset += topOffsetAdjustment;
1143
+ }
1144
+ }
1140
1145
  if (viewPosition !== void 0 && index !== void 0) {
1141
1146
  const itemSize = getItemSize(ctx, getId(state, index), index, state.props.data[index]);
1142
1147
  const trailingInset = getContentInsetEnd(state);
1143
1148
  offset -= viewPosition * (state.scrollLength - trailingInset - itemSize);
1149
+ if (index === state.props.data.length - 1) {
1150
+ const footerSize = peek$(ctx, "footerSize") || 0;
1151
+ offset += footerSize;
1152
+ }
1144
1153
  }
1145
1154
  return offset;
1146
1155
  }
@@ -1594,7 +1603,8 @@ function ensureInitialAnchor(ctx) {
1594
1603
  return;
1595
1604
  }
1596
1605
  const availableSpace = Math.max(0, scrollLength - size);
1597
- const desiredOffset = calculateOffsetForIndex(ctx, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1606
+ const topOffsetAdjustment = getTopOffsetAdjustment(ctx);
1607
+ const desiredOffset = calculateOffsetForIndex(ctx, anchor.index) + topOffsetAdjustment - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1598
1608
  const clampedDesiredOffset = clampScrollOffset(ctx, desiredOffset, anchor);
1599
1609
  const delta = clampedDesiredOffset - scroll;
1600
1610
  if (Math.abs(delta) <= INITIAL_ANCHOR_TOLERANCE) {
@@ -2311,6 +2321,8 @@ function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
2311
2321
  const cb = ctx.mapViewabilityCallbacks.get(key);
2312
2322
  cb == null ? void 0 : cb(viewToken);
2313
2323
  }
2324
+ var unstableBatchedUpdates = ReactNative__namespace.unstable_batchedUpdates;
2325
+ var batchedUpdates = typeof unstableBatchedUpdates === "function" ? unstableBatchedUpdates : (fn) => fn();
2314
2326
 
2315
2327
  // src/utils/checkAllSizesKnown.ts
2316
2328
  function isNullOrUndefined2(value) {
@@ -2563,7 +2575,7 @@ function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentSt
2563
2575
  }
2564
2576
  function calculateItemsInView(ctx, params = {}) {
2565
2577
  const state = ctx.state;
2566
- reactNative.unstable_batchedUpdates(() => {
2578
+ batchedUpdates(() => {
2567
2579
  var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2568
2580
  const {
2569
2581
  columns,
@@ -3457,19 +3469,19 @@ var useCombinedRef = (...refs) => {
3457
3469
  return callback;
3458
3470
  };
3459
3471
  function getWindowSize() {
3460
- const screenSize = reactNative.Dimensions.get("window");
3472
+ const screenSize = ReactNative.Dimensions.get("window");
3461
3473
  return {
3462
3474
  height: screenSize.height,
3463
3475
  width: screenSize.width
3464
3476
  };
3465
3477
  }
3466
- var StyleSheet = reactNative.StyleSheet;
3478
+ var StyleSheet = ReactNative.StyleSheet;
3467
3479
  function useStickyScrollHandler(stickyHeaderIndices, horizontal, ctx, onScroll2) {
3468
3480
  const shouldUseRnAnimatedEngine = !ctx.state.props.stickyPositionComponentInternal;
3469
3481
  return React2.useMemo(() => {
3470
3482
  if ((stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.length) && shouldUseRnAnimatedEngine) {
3471
3483
  const { animatedScrollY } = ctx;
3472
- return reactNative.Animated.event(
3484
+ return ReactNative.Animated.event(
3473
3485
  [
3474
3486
  {
3475
3487
  nativeEvent: {
@@ -3502,20 +3514,69 @@ function createColumnWrapperStyle(contentContainerStyle) {
3502
3514
  }
3503
3515
  }
3504
3516
 
3517
+ // src/utils/hasActiveMVCPAnchorLock.ts
3518
+ function hasActiveMVCPAnchorLock(state) {
3519
+ const lock = state.mvcpAnchorLock;
3520
+ if (!lock) {
3521
+ return false;
3522
+ }
3523
+ if (Date.now() > lock.expiresAt) {
3524
+ state.mvcpAnchorLock = void 0;
3525
+ return false;
3526
+ }
3527
+ return true;
3528
+ }
3529
+
3505
3530
  // src/utils/createImperativeHandle.ts
3506
3531
  function createImperativeHandle(ctx) {
3507
3532
  const state = ctx.state;
3533
+ const IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS = 800;
3534
+ const IMPERATIVE_SCROLL_SETTLE_STABLE_FRAMES = 2;
3535
+ let imperativeScrollToken = 0;
3536
+ const isSettlingAfterDataChange = () => !!state.didDataChange || !!state.didColumnsChange || state.queuedMVCPRecalculate !== void 0 || state.ignoreScrollFromMVCP !== void 0 || hasActiveMVCPAnchorLock(state);
3537
+ const runWhenSettled = (token, run) => {
3538
+ const startedAt = Date.now();
3539
+ let stableFrames = 0;
3540
+ const check = () => {
3541
+ if (token !== imperativeScrollToken) {
3542
+ return;
3543
+ }
3544
+ if (isSettlingAfterDataChange()) {
3545
+ stableFrames = 0;
3546
+ } else {
3547
+ stableFrames += 1;
3548
+ }
3549
+ const timedOut = Date.now() - startedAt >= IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS;
3550
+ if (stableFrames >= IMPERATIVE_SCROLL_SETTLE_STABLE_FRAMES || timedOut) {
3551
+ run();
3552
+ return;
3553
+ }
3554
+ requestAnimationFrame(check);
3555
+ };
3556
+ requestAnimationFrame(check);
3557
+ };
3508
3558
  const runScrollWithPromise = (run) => new Promise((resolve) => {
3509
3559
  var _a3;
3560
+ const token = ++imperativeScrollToken;
3510
3561
  (_a3 = state.pendingScrollResolve) == null ? void 0 : _a3.call(state);
3511
3562
  state.pendingScrollResolve = resolve;
3512
- const didStartScroll = run();
3513
- if (!didStartScroll || !state.scrollingTo) {
3514
- if (state.pendingScrollResolve === resolve) {
3515
- state.pendingScrollResolve = void 0;
3563
+ const runNow = () => {
3564
+ if (token !== imperativeScrollToken) {
3565
+ return;
3566
+ }
3567
+ const didStartScroll = run();
3568
+ if (!didStartScroll || !state.scrollingTo) {
3569
+ if (state.pendingScrollResolve === resolve) {
3570
+ state.pendingScrollResolve = void 0;
3571
+ }
3572
+ resolve();
3516
3573
  }
3517
- resolve();
3574
+ };
3575
+ if (isSettlingAfterDataChange()) {
3576
+ runWhenSettled(token, runNow);
3577
+ return;
3518
3578
  }
3579
+ runNow();
3519
3580
  });
3520
3581
  const scrollIndexIntoView = (options) => {
3521
3582
  if (state) {
@@ -3825,7 +3886,7 @@ var LegendList = typedMemo2(
3825
3886
  })
3826
3887
  );
3827
3888
  var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
3828
- var _a3, _b, _c, _d;
3889
+ var _a3, _b, _c, _d, _e;
3829
3890
  const {
3830
3891
  alignItemsAtEnd = false,
3831
3892
  alwaysRender,
@@ -3914,7 +3975,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3914
3975
  const maintainVisibleContentPositionConfig = normalizeMaintainVisibleContentPosition(
3915
3976
  maintainVisibleContentPositionProp
3916
3977
  );
3917
- const [renderNum, setRenderNum] = React2.useState(0);
3918
3978
  const initialScrollProp = initialScrollAtEnd ? { index: Math.max(0, dataProp.length - 1), viewOffset: -stylePaddingBottomState, viewPosition: 1 } : initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? {
3919
3979
  index: initialScrollIndexProp.index || 0,
3920
3980
  viewOffset: initialScrollIndexProp.viewOffset || (initialScrollIndexProp.viewPosition === 1 ? -stylePaddingBottomState : 0),
@@ -3955,7 +4015,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3955
4015
  );
3956
4016
  }
3957
4017
  const useWindowScrollResolved = Platform2.OS === "web" && !!useWindowScroll && !renderScrollComponent;
3958
- const refState = React2.useRef();
4018
+ const refState = React2.useRef(void 0);
3959
4019
  const hasOverrideItemLayout = !!overrideItemLayout;
3960
4020
  const prevHasOverrideItemLayout = React2.useRef(hasOverrideItemLayout);
3961
4021
  if (!refState.current) {
@@ -4119,6 +4179,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4119
4179
  true
4120
4180
  );
4121
4181
  }
4182
+ const resolveInitialScrollOffset = React2.useCallback((initialScroll) => {
4183
+ const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
4184
+ const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
4185
+ return clampScrollOffset(ctx, resolvedOffset, initialScroll);
4186
+ }, []);
4122
4187
  const initialContentOffset = React2.useMemo(() => {
4123
4188
  var _a4;
4124
4189
  let value;
@@ -4136,9 +4201,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4136
4201
  if (initialScroll.contentOffset !== void 0) {
4137
4202
  value = initialScroll.contentOffset;
4138
4203
  } else {
4139
- const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
4140
- const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
4141
- const clampedOffset = clampScrollOffset(ctx, resolvedOffset, initialScroll);
4204
+ const clampedOffset = resolveInitialScrollOffset(initialScroll);
4142
4205
  const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
4143
4206
  refState.current.initialScroll = updatedInitialScroll;
4144
4207
  state.initialScroll = updatedInitialScroll;
@@ -4152,7 +4215,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4152
4215
  setInitialRenderState(ctx, { didInitialScroll: true });
4153
4216
  }
4154
4217
  return value;
4155
- }, [renderNum]);
4218
+ }, []);
4156
4219
  if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
4157
4220
  refState.current.lastBatchingAction = Date.now();
4158
4221
  if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
@@ -4166,32 +4229,45 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4166
4229
  set$(ctx, "totalSize", 0);
4167
4230
  }
4168
4231
  }
4169
- const onLayoutHeader = React2.useCallback((rect, fromLayoutEffect) => {
4170
- const { initialScroll } = refState.current;
4171
- const size = rect[horizontal ? "width" : "height"];
4172
- set$(ctx, "headerSize", size);
4173
- if ((initialScroll == null ? void 0 : initialScroll.index) !== void 0) {
4174
- if (IsNewArchitecture && Platform2.OS !== "android") {
4175
- if (fromLayoutEffect) {
4176
- setRenderNum((v) => v + 1);
4177
- }
4178
- } else {
4179
- setTimeout(doInitialScroll, 17);
4180
- }
4181
- }
4182
- }, []);
4183
4232
  const doInitialScroll = React2.useCallback(() => {
4184
4233
  const { initialScroll, didFinishInitialScroll, queuedInitialLayout, scrollingTo } = state;
4185
4234
  if (initialScroll && !queuedInitialLayout && !didFinishInitialScroll && !scrollingTo) {
4235
+ const offset = resolveInitialScrollOffset(initialScroll);
4236
+ const updatedInitialScroll = { ...initialScroll, contentOffset: offset };
4237
+ refState.current.initialScroll = updatedInitialScroll;
4238
+ state.initialScroll = updatedInitialScroll;
4186
4239
  scrollTo(ctx, {
4187
4240
  animated: false,
4188
- index: initialScroll == null ? void 0 : initialScroll.index,
4241
+ index: initialScroll.index,
4189
4242
  isInitialScroll: true,
4190
- offset: initialContentOffset,
4243
+ offset,
4191
4244
  precomputedWithViewOffset: true
4192
4245
  });
4193
4246
  }
4194
- }, [initialContentOffset]);
4247
+ }, []);
4248
+ const onLayoutFooter = React2.useCallback(
4249
+ (layout) => {
4250
+ if (!initialScrollAtEnd) {
4251
+ return;
4252
+ }
4253
+ const { initialScroll } = state;
4254
+ if (!initialScroll) {
4255
+ return;
4256
+ }
4257
+ const lastIndex = Math.max(0, dataProp.length - 1);
4258
+ if (initialScroll.index !== lastIndex || initialScroll.viewPosition !== 1) {
4259
+ return;
4260
+ }
4261
+ const footerSize = layout[horizontal ? "width" : "height"];
4262
+ const viewOffset = -stylePaddingBottomState - footerSize;
4263
+ if (initialScroll.viewOffset !== viewOffset) {
4264
+ const updatedInitialScroll = { ...initialScroll, viewOffset };
4265
+ refState.current.initialScroll = updatedInitialScroll;
4266
+ state.initialScroll = updatedInitialScroll;
4267
+ }
4268
+ },
4269
+ [dataProp.length, horizontal, initialScrollAtEnd, stylePaddingBottomState]
4270
+ );
4195
4271
  const onLayoutChange = React2.useCallback((layout) => {
4196
4272
  doInitialScroll();
4197
4273
  handleLayout(ctx, layout, setCanRender);
@@ -4291,6 +4367,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4291
4367
  []
4292
4368
  );
4293
4369
  const onScrollHandler = useStickyScrollHandler(stickyHeaderIndices, horizontal, ctx, fns.onScroll);
4370
+ const refreshControlElement = refreshControl;
4294
4371
  return /* @__PURE__ */ React2__namespace.createElement(React2__namespace.Fragment, null, /* @__PURE__ */ React2__namespace.createElement(
4295
4372
  ListComponent,
4296
4373
  {
@@ -4305,14 +4382,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4305
4382
  ListEmptyComponent: dataProp.length === 0 ? ListEmptyComponent : void 0,
4306
4383
  ListHeaderComponent,
4307
4384
  onLayout,
4308
- onLayoutHeader,
4385
+ onLayoutFooter,
4309
4386
  onMomentumScrollEnd: fns.onMomentumScrollEnd,
4310
4387
  onScroll: onScrollHandler,
4311
4388
  recycleItems,
4312
- refreshControl: refreshControl ? stylePaddingTopState > 0 ? React2__namespace.cloneElement(refreshControl, {
4313
- progressViewOffset: (refreshControl.props.progressViewOffset || 0) + stylePaddingTopState
4314
- }) : refreshControl : onRefresh && /* @__PURE__ */ React2__namespace.createElement(
4315
- reactNative.RefreshControl,
4389
+ refreshControl: refreshControlElement ? stylePaddingTopState > 0 ? React2__namespace.cloneElement(refreshControlElement, {
4390
+ progressViewOffset: ((_d = refreshControlElement.props.progressViewOffset) != null ? _d : 0) + stylePaddingTopState
4391
+ }) : refreshControlElement : onRefresh && /* @__PURE__ */ React2__namespace.createElement(
4392
+ ReactNative.RefreshControl,
4316
4393
  {
4317
4394
  onRefresh,
4318
4395
  progressViewOffset: (progressViewOffset || 0) + stylePaddingTopState,
@@ -4321,7 +4398,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4321
4398
  ),
4322
4399
  refScrollView: combinedRef,
4323
4400
  renderScrollComponent,
4324
- scrollAdjustHandler: (_d = refState.current) == null ? void 0 : _d.scrollAdjustHandler,
4401
+ scrollAdjustHandler: (_e = refState.current) == null ? void 0 : _e.scrollAdjustHandler,
4325
4402
  scrollEventThrottle: 0,
4326
4403
  snapToIndices,
4327
4404
  stickyHeaderIndices,