@legendapp/list 3.0.0-beta.54 → 3.0.0-beta.56

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.
@@ -34,6 +34,115 @@ var View = React3.forwardRef(function View2(props, ref) {
34
34
  });
35
35
  var Text = View;
36
36
 
37
+ // src/platform/Platform.ts
38
+ var Platform = {
39
+ // Widen the type to avoid unreachable-branch lints in cross-platform code that compares against other OSes
40
+ OS: "web"
41
+ };
42
+
43
+ // src/utils/rtl.ts
44
+ function clampHorizontalOffset(offset, maxOffset) {
45
+ if (maxOffset === void 0) {
46
+ return offset;
47
+ }
48
+ return Math.max(0, Math.min(maxOffset, offset));
49
+ }
50
+ function getHorizontalMaxOffset(state, contentWidth) {
51
+ if (contentWidth === void 0 || !Number.isFinite(contentWidth) || !Number.isFinite(state.scrollLength) || contentWidth <= state.scrollLength) {
52
+ return contentWidth !== void 0 && Number.isFinite(contentWidth) && Number.isFinite(state.scrollLength) ? 0 : void 0;
53
+ }
54
+ return Math.max(0, contentWidth - state.scrollLength);
55
+ }
56
+ function getDefaultHorizontalRTLScrollType() {
57
+ return "normal" ;
58
+ }
59
+ function getNativeHorizontalRTLScrollType(state) {
60
+ var _a3;
61
+ return (_a3 = state == null ? void 0 : state.horizontalRTLScrollType) != null ? _a3 : getDefaultHorizontalRTLScrollType();
62
+ }
63
+ function isRTLProps(props) {
64
+ var _a3;
65
+ return (_a3 = props == null ? void 0 : props.rtl) != null ? _a3 : false;
66
+ }
67
+ function isHorizontalRTL(state) {
68
+ return isHorizontalRTLProps(state == null ? void 0 : state.props);
69
+ }
70
+ function isHorizontalRTLProps(props) {
71
+ return !!(props == null ? void 0 : props.horizontal) && isRTLProps(props);
72
+ }
73
+ function getLogicalHorizontalMaxOffset(state, contentWidth) {
74
+ var _a3;
75
+ return (_a3 = getHorizontalMaxOffset(state, contentWidth)) != null ? _a3 : 0;
76
+ }
77
+ function getHorizontalInsetEnd(state, inset) {
78
+ if (!inset) {
79
+ return 0;
80
+ }
81
+ return (isHorizontalRTL(state) ? inset.left : inset.right) || 0;
82
+ }
83
+ function toPhysicalHorizontalItemPosition(state, logicalPosition, itemSize, listSize) {
84
+ if (!isHorizontalRTL(state) || listSize === void 0 || !Number.isFinite(listSize)) {
85
+ return logicalPosition;
86
+ }
87
+ return Math.max(0, listSize - logicalPosition - itemSize);
88
+ }
89
+ function toNativeHorizontalOffset(state, logicalOffset, contentWidth) {
90
+ if (!state || !isHorizontalRTL(state)) {
91
+ return logicalOffset;
92
+ }
93
+ const maxOffset = getHorizontalMaxOffset(state, contentWidth);
94
+ const clampedLogicalOffset = clampHorizontalOffset(logicalOffset, maxOffset);
95
+ const mode = getNativeHorizontalRTLScrollType(state);
96
+ if (mode === "negative") {
97
+ return clampedLogicalOffset === 0 ? 0 : -clampedLogicalOffset;
98
+ }
99
+ if (mode === "inverted") {
100
+ if (maxOffset === void 0) {
101
+ return clampedLogicalOffset;
102
+ }
103
+ return clampHorizontalOffset(maxOffset - clampedLogicalOffset, maxOffset);
104
+ }
105
+ return clampedLogicalOffset;
106
+ }
107
+ function toLogicalHorizontalOffset(state, rawOffset, contentWidth) {
108
+ if (!isHorizontalRTL(state)) {
109
+ state.horizontalRTLScrollType = void 0;
110
+ return rawOffset;
111
+ }
112
+ const maxOffset = getHorizontalMaxOffset(state, contentWidth);
113
+ if (rawOffset < 0) {
114
+ state.horizontalRTLScrollType = "negative";
115
+ return clampHorizontalOffset(-rawOffset, maxOffset);
116
+ }
117
+ if (maxOffset === void 0) {
118
+ return rawOffset;
119
+ }
120
+ const normalOffset = rawOffset;
121
+ const invertedOffset = maxOffset - rawOffset;
122
+ if (!Number.isFinite(invertedOffset)) {
123
+ state.horizontalRTLScrollType = "normal";
124
+ return normalOffset;
125
+ }
126
+ const previousMode = state.horizontalRTLScrollType;
127
+ if (previousMode === "inverted") {
128
+ return clampHorizontalOffset(invertedOffset, maxOffset);
129
+ }
130
+ if (previousMode === "normal") {
131
+ return clampHorizontalOffset(normalOffset, maxOffset);
132
+ }
133
+ if (!state.hasScrolled) {
134
+ const defaultMode = getDefaultHorizontalRTLScrollType();
135
+ state.horizontalRTLScrollType = defaultMode;
136
+ return clampHorizontalOffset(normalOffset, maxOffset);
137
+ }
138
+ const referenceScroll = state.scroll;
139
+ const distanceNormal = Math.abs(normalOffset - referenceScroll);
140
+ const distanceInverted = Math.abs(invertedOffset - referenceScroll);
141
+ const useInverted = distanceInverted + 0.5 < distanceNormal;
142
+ state.horizontalRTLScrollType = useInverted ? "inverted" : "normal";
143
+ return clampHorizontalOffset(useInverted ? invertedOffset : normalOffset, maxOffset);
144
+ }
145
+
37
146
  // src/platform/Animated.tsx
38
147
  var createAnimatedValue = (value) => value;
39
148
 
@@ -176,7 +285,7 @@ function getContentInsetEnd(ctx, contentInsetEndAdjustmentOverride) {
176
285
  const horizontal = props.horizontal;
177
286
  const contentInset = props.contentInset;
178
287
  const baseInset = contentInset != null ? contentInset : state.nativeContentInset;
179
- const baseEndInset = (horizontal ? baseInset == null ? void 0 : baseInset.right : baseInset == null ? void 0 : baseInset.bottom) || 0;
288
+ const baseEndInset = (horizontal ? getHorizontalInsetEnd(state, baseInset) : baseInset == null ? void 0 : baseInset.bottom) || 0;
180
289
  const contentInsetEndAdjustment = getContentInsetEndAdjustmentEnd(
181
290
  contentInsetEndAdjustmentOverride != null ? contentInsetEndAdjustmentOverride : props.contentInsetEndAdjustment
182
291
  );
@@ -185,9 +294,9 @@ function getContentInsetEnd(ctx, contentInsetEndAdjustmentOverride) {
185
294
  const overrideInset = (_b = state.contentInsetOverride) != null ? _b : void 0;
186
295
  const adjustedBaseEndInset = baseEndInset + contentInsetEndAdjustment;
187
296
  if (overrideInset) {
188
- const mergedInset = { bottom: 0, right: 0, ...baseInset, ...overrideInset };
297
+ const mergedInset = { bottom: 0, left: 0, right: 0, ...baseInset, ...overrideInset };
189
298
  return Math.max(
190
- ((horizontal ? mergedInset.right : mergedInset.bottom) || 0) + contentInsetEndAdjustment,
299
+ ((horizontal ? getHorizontalInsetEnd(state, mergedInset) : mergedInset.bottom) || 0) + contentInsetEndAdjustment,
191
300
  anchoredEndInset
192
301
  );
193
302
  }
@@ -281,6 +390,15 @@ var ENABLE_DEVMODE = IS_DEV && false;
281
390
  var ENABLE_DEBUG_VIEW = IS_DEV && false;
282
391
  var typedForwardRef = React3__namespace.forwardRef;
283
392
  var typedMemo = React3__namespace.memo;
393
+ var getComponent = (Component) => {
394
+ if (React3__namespace.isValidElement(Component)) {
395
+ return Component;
396
+ }
397
+ if (Component) {
398
+ return /* @__PURE__ */ React3__namespace.createElement(Component, null);
399
+ }
400
+ return null;
401
+ };
284
402
 
285
403
  // src/utils/helpers.ts
286
404
  function isFunction(obj) {
@@ -307,7 +425,8 @@ function comparatorDefault(a, b) {
307
425
  }
308
426
  function getPadding(s, type) {
309
427
  var _a3, _b, _c;
310
- return (_c = (_b = (_a3 = s[`padding${type}`]) != null ? _a3 : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
428
+ const axisPadding = type === "Left" || type === "Right" ? s.paddingHorizontal : s.paddingVertical;
429
+ return (_c = (_b = (_a3 = s[`padding${type}`]) != null ? _a3 : axisPadding) != null ? _b : s.padding) != null ? _c : 0;
311
430
  }
312
431
  function extractPadding(style, contentContainerStyle, type) {
313
432
  return getPadding(style, type) + getPadding(contentContainerStyle, type);
@@ -329,6 +448,14 @@ function findContainerId(ctx, key) {
329
448
  }
330
449
 
331
450
  // src/components/PositionView.tsx
451
+ var isRNWeb = typeof document !== "undefined" && !!document.getElementById("react-native-stylesheet");
452
+ var baseCss = {
453
+ contain: "paint layout style",
454
+ ...isRNWeb ? {
455
+ display: "flex",
456
+ flexDirection: "column"
457
+ } : {}
458
+ };
332
459
  var PositionViewState = typedMemo(function PositionViewState2({
333
460
  id,
334
461
  horizontal,
@@ -337,11 +464,8 @@ var PositionViewState = typedMemo(function PositionViewState2({
337
464
  ...props
338
465
  }) {
339
466
  const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
340
- const base = {
341
- contain: "paint layout style"
342
- };
343
467
  const composed = isArray(style) ? Object.assign({}, ...style) : style;
344
- const combinedStyle = horizontal ? { ...base, ...composed, left: position } : { ...base, ...composed, top: position };
468
+ const combinedStyle = horizontal ? { ...baseCss, ...composed, left: position } : { ...baseCss, ...composed, top: position };
345
469
  const {
346
470
  animatedScrollY: _animatedScrollY,
347
471
  index,
@@ -369,9 +493,6 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
369
493
  `containerPosition${id}`,
370
494
  "activeStickyIndex"
371
495
  ]);
372
- const base = {
373
- contain: "paint layout style"
374
- };
375
496
  const composed = React3__namespace.useMemo(
376
497
  () => {
377
498
  var _a3;
@@ -381,10 +502,9 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
381
502
  );
382
503
  const viewStyle = React3__namespace.useMemo(() => {
383
504
  var _a3;
384
- const styleBase = { ...base, ...composed };
505
+ const styleBase = { ...baseCss, ...composed };
385
506
  delete styleBase.transform;
386
- const stickyConfigOffset = (_a3 = stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.offset) != null ? _a3 : 0;
387
- const offset = stickyConfigOffset != null ? stickyConfigOffset : 0;
507
+ const offset = (_a3 = stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.offset) != null ? _a3 : 0;
388
508
  const isActive = activeStickyIndex === index;
389
509
  styleBase.position = isActive ? "sticky" : "absolute";
390
510
  styleBase.zIndex = index + 1e3;
@@ -395,6 +515,20 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
395
515
  }
396
516
  return styleBase;
397
517
  }, [composed, horizontal, position, index, activeStickyIndex, stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.offset]);
518
+ const renderStickyHeaderBackdrop = React3__namespace.useMemo(
519
+ () => (stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.backdropComponent) ? /* @__PURE__ */ React3__namespace.createElement(
520
+ "div",
521
+ {
522
+ style: {
523
+ inset: 0,
524
+ pointerEvents: "none",
525
+ position: "absolute"
526
+ }
527
+ },
528
+ getComponent(stickyHeaderConfig.backdropComponent)
529
+ ) : null,
530
+ [stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.backdropComponent]
531
+ );
398
532
  return /* @__PURE__ */ React3__namespace.createElement(
399
533
  "div",
400
534
  {
@@ -403,6 +537,7 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
403
537
  style: viewStyle,
404
538
  ...webProps
405
539
  },
540
+ renderStickyHeaderBackdrop,
406
541
  children
407
542
  );
408
543
  });
@@ -667,12 +802,6 @@ function toLayout(rect) {
667
802
  };
668
803
  }
669
804
 
670
- // src/platform/Platform.ts
671
- var Platform = {
672
- // Widen the type to avoid unreachable-branch lints in cross-platform code that compares against other OSes
673
- OS: "web"
674
- };
675
-
676
805
  // src/utils/hasActiveMVCPAnchorLock.ts
677
806
  function hasActiveMVCPAnchorLock(state) {
678
807
  const lock = state.mvcpAnchorLock;
@@ -696,6 +825,7 @@ function getContainerPositionStyle({
696
825
  columnWrapperStyle,
697
826
  horizontal,
698
827
  hasItemSeparator,
828
+ isHorizontalRTLList,
699
829
  numColumns,
700
830
  otherAxisPos,
701
831
  otherAxisSize
@@ -719,6 +849,7 @@ function getContainerPositionStyle({
719
849
  }
720
850
  return horizontal ? {
721
851
  boxSizing: paddingStyles ? "border-box" : void 0,
852
+ direction: isHorizontalRTLList && Platform.OS === "web" ? "ltr" : void 0,
722
853
  flexDirection: hasItemSeparator ? "row" : void 0,
723
854
  height: otherAxisSize,
724
855
  left: 0,
@@ -747,6 +878,7 @@ var Container = typedMemo(function Container2({
747
878
  }) {
748
879
  const ctx = useStateContext();
749
880
  const { columnWrapperStyle, animatedScrollY } = ctx;
881
+ const isHorizontalRTLList = isHorizontalRTL(ctx.state);
750
882
  const positionComponentInternal = ctx.state.props.positionComponentInternal;
751
883
  const stickyPositionComponentInternal = ctx.state.props.stickyPositionComponentInternal;
752
884
  const [column = 0, span = 1, data, numColumns = 1, extraData, isSticky] = useArr$([
@@ -778,11 +910,20 @@ var Container = typedMemo(function Container2({
778
910
  columnWrapperStyle,
779
911
  hasItemSeparator: !!ItemSeparatorComponent,
780
912
  horizontal,
913
+ isHorizontalRTLList,
781
914
  numColumns,
782
915
  otherAxisPos,
783
916
  otherAxisSize
784
917
  }),
785
- [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns, ItemSeparatorComponent]
918
+ [
919
+ horizontal,
920
+ isHorizontalRTLList,
921
+ otherAxisPos,
922
+ otherAxisSize,
923
+ columnWrapperStyle,
924
+ numColumns,
925
+ ItemSeparatorComponent
926
+ ]
786
927
  );
787
928
  const renderedItemInfo = React3.useMemo(
788
929
  () => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
@@ -1022,9 +1163,16 @@ var ContainersInner = typedMemo(function ContainersInner2({ horizontal, numColum
1022
1163
  const ref = React3.useRef(null);
1023
1164
  const ctx = useStateContext();
1024
1165
  const columnWrapperStyle = ctx.columnWrapperStyle;
1166
+ const isHorizontalRTLList = isHorizontalRTL(ctx.state);
1025
1167
  const [otherAxisSize, readyToRender, totalSize] = useArr$(["otherAxisSize", "readyToRender", "totalSize"]);
1026
1168
  useDOMOrder(ref);
1027
- const style = horizontal ? { minHeight: otherAxisSize, opacity: readyToRender ? 1 : 0, position: "relative", width: totalSize } : { height: totalSize, minWidth: otherAxisSize, opacity: readyToRender ? 1 : 0, position: "relative" };
1169
+ const style = horizontal ? {
1170
+ direction: isHorizontalRTLList ? "ltr" : void 0,
1171
+ minHeight: otherAxisSize,
1172
+ opacity: readyToRender ? 1 : 0,
1173
+ position: "relative",
1174
+ width: totalSize
1175
+ } : { height: totalSize, minWidth: otherAxisSize, opacity: readyToRender ? 1 : 0, position: "relative" };
1028
1176
  if (!readyToRender) {
1029
1177
  style.pointerEvents = "none";
1030
1178
  }
@@ -1088,10 +1236,16 @@ var StyleSheet = {
1088
1236
  create: (styles) => styles,
1089
1237
  flatten: (style) => flattenStyles(style)
1090
1238
  };
1239
+ function useLatestRef(value) {
1240
+ const ref = React3__namespace.useRef(value);
1241
+ ref.current = value;
1242
+ return ref;
1243
+ }
1244
+
1245
+ // src/utils/useRafCoalescer.ts
1091
1246
  function useRafCoalescer(callback) {
1092
- const callbackRef = React3.useRef(callback);
1247
+ const callbackRef = useLatestRef(callback);
1093
1248
  const rafIdRef = React3.useRef(void 0);
1094
- callbackRef.current = callback;
1095
1249
  const coalescer = React3.useMemo(
1096
1250
  () => ({
1097
1251
  cancel() {
@@ -1235,6 +1389,31 @@ function getContentInsetEndAdjustmentEnd2(ctx) {
1235
1389
  const adjustment = (_b = (_a3 = ctx.state) == null ? void 0 : _a3.props) == null ? void 0 : _b.contentInsetEndAdjustment;
1236
1390
  return Math.max(0, adjustment != null ? adjustment : 0);
1237
1391
  }
1392
+ function getFiniteSnapOffsets(snapToOffsets) {
1393
+ if (!(snapToOffsets == null ? void 0 : snapToOffsets.length)) {
1394
+ return [];
1395
+ }
1396
+ const snapOffsets = [];
1397
+ const seen = /* @__PURE__ */ new Set();
1398
+ for (const offset of snapToOffsets) {
1399
+ if (Number.isFinite(offset) && !seen.has(offset)) {
1400
+ seen.add(offset);
1401
+ snapOffsets.push(offset);
1402
+ }
1403
+ }
1404
+ return snapOffsets;
1405
+ }
1406
+ function getSnapAnchorStyle(offset, horizontal) {
1407
+ return {
1408
+ height: horizontal ? "100%" : 1,
1409
+ left: horizontal ? offset : 0,
1410
+ pointerEvents: "none",
1411
+ position: "absolute",
1412
+ scrollSnapAlign: "start",
1413
+ top: horizontal ? 0 : offset,
1414
+ width: horizontal ? 1 : "100%"
1415
+ };
1416
+ }
1238
1417
  var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView2({
1239
1418
  children,
1240
1419
  style,
@@ -1252,7 +1431,7 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
1252
1431
  onLayout,
1253
1432
  ...props
1254
1433
  }, ref) {
1255
- var _a3, _b, _c;
1434
+ var _a3, _b, _c, _d;
1256
1435
  const ctx = useStateContext();
1257
1436
  const [anchoredEndSpaceSize] = useArr$(["anchoredEndSpaceSize"]);
1258
1437
  const scrollRef = React3.useRef(null);
@@ -1467,10 +1646,16 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
1467
1646
  contentInset: _contentInset,
1468
1647
  scrollEventThrottle: _scrollEventThrottle,
1469
1648
  ScrollComponent: _ScrollComponent,
1649
+ snapToOffsets,
1470
1650
  useWindowScroll: _useWindowScroll,
1471
1651
  className: scrollViewClassNameProp,
1472
1652
  ...webProps
1473
1653
  } = props;
1654
+ const snapOffsets = !isWindowScroll ? getFiniteSnapOffsets(snapToOffsets) : [];
1655
+ if (snapOffsets.length > 0) {
1656
+ scrollViewStyle.scrollSnapType = horizontal ? "x mandatory" : "y mandatory";
1657
+ contentStyle.position = (_d = contentStyle.position) != null ? _d : "relative";
1658
+ }
1474
1659
  const scrollViewClassName = hiddenScrollIndicatorClassName ? scrollViewClassNameProp ? `${scrollViewClassNameProp} ${hiddenScrollIndicatorClassName}` : hiddenScrollIndicatorClassName : scrollViewClassNameProp;
1475
1660
  if (IS_DEV) {
1476
1661
  if (/(?:^|\s)(?:[a-z0-9_-]+:)*gap(?:-[xy])?-(?:\[[^\]]+\]|[^\s]+)/.test(
@@ -1491,9 +1676,29 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
1491
1676
  style: scrollViewStyle
1492
1677
  },
1493
1678
  refreshControl,
1494
- /* @__PURE__ */ React3__namespace.createElement("div", { className, ref: contentRef, style: contentStyle }, children, contentInsetEndAdjustmentSpacerStyle ? /* @__PURE__ */ React3__namespace.createElement("div", { "aria-hidden": true, style: contentInsetEndAdjustmentSpacerStyle }) : null)
1679
+ /* @__PURE__ */ React3__namespace.createElement("div", { className, ref: contentRef, style: contentStyle }, snapOffsets.map((offset) => /* @__PURE__ */ React3__namespace.createElement(
1680
+ "div",
1681
+ {
1682
+ "aria-hidden": true,
1683
+ "data-legend-list-snap-anchor": offset,
1684
+ key: `snap-${offset}`,
1685
+ style: getSnapAnchorStyle(offset, horizontal)
1686
+ }
1687
+ )), children, contentInsetEndAdjustmentSpacerStyle ? /* @__PURE__ */ React3__namespace.createElement("div", { "aria-hidden": true, style: contentInsetEndAdjustmentSpacerStyle }) : null)
1495
1688
  );
1496
1689
  });
1690
+
1691
+ // src/components/listComponentStyles.ts
1692
+ function getAutoOtherAxisStyle({
1693
+ horizontal,
1694
+ needsOtherAxisSize,
1695
+ otherAxisSize
1696
+ }) {
1697
+ if (!needsOtherAxisSize || !otherAxisSize || otherAxisSize <= 0) {
1698
+ return void 0;
1699
+ }
1700
+ return horizontal ? { height: otherAxisSize } : { width: otherAxisSize };
1701
+ }
1497
1702
  function useValueListener$(key, callback) {
1498
1703
  const ctx = useStateContext();
1499
1704
  React3.useLayoutEffect(() => {
@@ -1588,10 +1793,10 @@ function ScrollAdjust() {
1588
1793
  useValueListener$("scrollAdjustUserOffset", callback);
1589
1794
  return null;
1590
1795
  }
1591
- function SnapWrapper({ ScrollComponent, ...props }) {
1796
+ var SnapWrapper = React3__namespace.forwardRef(function SnapWrapperInner({ ScrollComponent, ...props }, ref) {
1592
1797
  const [snapToOffsets] = useArr$(["snapToOffsets"]);
1593
- return /* @__PURE__ */ React3__namespace.createElement(ScrollComponent, { ...props, snapToOffsets });
1594
- }
1798
+ return /* @__PURE__ */ React3__namespace.createElement(ScrollComponent, { ...props, ref, snapToOffsets });
1799
+ });
1595
1800
  function WebAnchoredEndSpace({ horizontal }) {
1596
1801
  const ctx = useStateContext();
1597
1802
  const [anchoredEndSpaceSize] = useArr$(["anchoredEndSpaceSize"]);
@@ -1602,21 +1807,25 @@ function WebAnchoredEndSpace({ horizontal }) {
1602
1807
  const style = horizontal ? { height: "100%", width: anchoredEndSpaceSize || 0 } : { height: anchoredEndSpaceSize || 0 };
1603
1808
  return /* @__PURE__ */ React3__namespace.createElement("div", { style }, null);
1604
1809
  }
1810
+ function useStableRenderComponent(renderComponent, mapProps) {
1811
+ const renderComponentRef = useLatestRef(renderComponent);
1812
+ const mapPropsRef = useLatestRef(mapProps);
1813
+ return React3__namespace.useMemo(
1814
+ () => React3__namespace.forwardRef(
1815
+ (props, ref) => {
1816
+ var _a3, _b;
1817
+ return (_b = (_a3 = renderComponentRef.current) == null ? void 0 : _a3.call(renderComponentRef, mapPropsRef.current(props, ref))) != null ? _b : null;
1818
+ }
1819
+ ),
1820
+ [mapPropsRef, renderComponentRef]
1821
+ );
1822
+ }
1605
1823
  var LayoutView = ({ onLayoutChange, refView, children, ...rest }) => {
1606
1824
  const localRef = React3.useRef(null);
1607
1825
  const ref = refView != null ? refView : localRef;
1608
1826
  useOnLayoutSync({ onLayoutChange, ref });
1609
1827
  return /* @__PURE__ */ React3__namespace.createElement("div", { ...rest, ref }, children);
1610
1828
  };
1611
- var getComponent = (Component) => {
1612
- if (React3__namespace.isValidElement(Component)) {
1613
- return Component;
1614
- }
1615
- if (Component) {
1616
- return /* @__PURE__ */ React3__namespace.createElement(Component, null);
1617
- }
1618
- return null;
1619
- };
1620
1829
 
1621
1830
  // src/components/ListComponent.tsx
1622
1831
  var ListComponent = typedMemo(function ListComponent2({
@@ -1649,14 +1858,17 @@ var ListComponent = typedMemo(function ListComponent2({
1649
1858
  }) {
1650
1859
  const ctx = useStateContext();
1651
1860
  const maintainVisibleContentPosition = ctx.state.props.maintainVisibleContentPosition;
1652
- const ScrollComponent = React3.useMemo(() => {
1653
- if (!renderScrollComponent) {
1654
- return ListComponentScrollView;
1655
- }
1656
- return React3__namespace.forwardRef(
1657
- (props, ref) => renderScrollComponent({ ...props, ref })
1658
- );
1659
- }, [renderScrollComponent]);
1861
+ const [otherAxisSize = 0] = useArr$(["otherAxisSize"]);
1862
+ const autoOtherAxisStyle = getAutoOtherAxisStyle({
1863
+ horizontal,
1864
+ needsOtherAxisSize: ctx.state.needsOtherAxisSize,
1865
+ otherAxisSize
1866
+ });
1867
+ const CustomScrollComponent = useStableRenderComponent(
1868
+ renderScrollComponent,
1869
+ (props, ref) => ({ ...props, ref })
1870
+ );
1871
+ const ScrollComponent = renderScrollComponent ? CustomScrollComponent : ListComponentScrollView;
1660
1872
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
1661
1873
  React3.useLayoutEffect(() => {
1662
1874
  if (!ListHeaderComponent) {
@@ -1687,10 +1899,10 @@ var ListComponent = typedMemo(function ListComponent2({
1687
1899
  ...rest,
1688
1900
  ...ScrollComponent === ListComponentScrollView ? { useWindowScroll } : {},
1689
1901
  contentContainerStyle: [
1690
- contentContainerStyle,
1691
1902
  horizontal ? {
1692
1903
  height: "100%"
1693
- } : {}
1904
+ } : {},
1905
+ contentContainerStyle
1694
1906
  ],
1695
1907
  contentOffset: initialContentOffset !== void 0 ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
1696
1908
  horizontal,
@@ -1699,7 +1911,7 @@ var ListComponent = typedMemo(function ListComponent2({
1699
1911
  onScroll: onScroll2,
1700
1912
  ref: refScrollView,
1701
1913
  ScrollComponent: snapToIndices ? ScrollComponent : void 0,
1702
- style
1914
+ style: autoOtherAxisStyle ? [autoOtherAxisStyle, style] : style
1703
1915
  },
1704
1916
  /* @__PURE__ */ React3__namespace.createElement(ScrollAdjust, null),
1705
1917
  ListHeaderComponent && /* @__PURE__ */ React3__namespace.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
@@ -2416,7 +2628,8 @@ function doScrollTo(ctx, params) {
2416
2628
  }
2417
2629
  const isAnimated = !!animated;
2418
2630
  const isHorizontal = !!horizontal;
2419
- const left = isHorizontal ? offset : 0;
2631
+ const contentSize = isHorizontal ? getContentSize(ctx) : void 0;
2632
+ const left = isHorizontal ? toNativeHorizontalOffset(state, offset, contentSize) : 0;
2420
2633
  const top = isHorizontal ? 0 : offset;
2421
2634
  scroller.scrollTo({ animated: isAnimated, x: left, y: top });
2422
2635
  if (isAnimated) {
@@ -3015,11 +3228,51 @@ function getObservedBootstrapInitialScrollOffset(state) {
3015
3228
  const observedOffset = (_b = (_a3 = state.refScroller.current) == null ? void 0 : _a3.getCurrentScrollOffset) == null ? void 0 : _b.call(_a3);
3016
3229
  return typeof observedOffset === "number" && Number.isFinite(observedOffset) ? observedOffset : (_d = (_c = state.scrollPending) != null ? _c : state.scroll) != null ? _d : 0;
3017
3230
  }
3231
+ function getPreservedEndAnchorOffsetDiff(ctx) {
3232
+ var _a3;
3233
+ const state = ctx.state;
3234
+ const initialScroll = state.initialScroll;
3235
+ if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || !initialScroll || initialScroll.viewPosition !== 1 || state.props.data.length === 0 || isOffsetInitialScrollSession(state)) {
3236
+ return;
3237
+ }
3238
+ const currentOffset = typeof state.lastNativeScroll === "number" && Number.isFinite(state.lastNativeScroll) ? state.lastNativeScroll : getObservedBootstrapInitialScrollOffset(state);
3239
+ return resolveInitialScrollOffset(ctx, initialScroll) - currentOffset;
3240
+ }
3241
+ function schedulePreservedEndAnchorCorrection(ctx) {
3242
+ if (getPreservedEndAnchorOffsetDiff(ctx) === void 0) {
3243
+ return false;
3244
+ }
3245
+ const correction = {};
3246
+ schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
3247
+ return true;
3248
+ }
3249
+ function schedulePreservedEndAnchorCorrectionFrame(ctx, correction) {
3250
+ const state = ctx.state;
3251
+ state.preservedEndAnchorCorrection = correction;
3252
+ requestAnimationFrame(() => {
3253
+ var _a3;
3254
+ const activeCorrection = state.preservedEndAnchorCorrection;
3255
+ if (activeCorrection !== correction) {
3256
+ return;
3257
+ }
3258
+ const offsetDiff = getPreservedEndAnchorOffsetDiff(ctx);
3259
+ if (offsetDiff === void 0 || Math.abs(offsetDiff) <= DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
3260
+ state.preservedEndAnchorCorrection = void 0;
3261
+ return;
3262
+ }
3263
+ const hasObservedNativeScrollAfterRequest = !activeCorrection.lastRequestTime || ((_a3 = state.lastNativeScrollTime) != null ? _a3 : 0) > activeCorrection.lastRequestTime;
3264
+ if (hasObservedNativeScrollAfterRequest) {
3265
+ activeCorrection.lastRequestTime = Date.now();
3266
+ requestAdjust(ctx, offsetDiff);
3267
+ }
3268
+ schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
3269
+ });
3270
+ }
3018
3271
  function clearFinishedBootstrapInitialScrollTargetIfMovedAway(ctx) {
3019
3272
  var _a3, _b;
3020
3273
  const state = ctx.state;
3021
3274
  const initialScroll = state.initialScroll;
3022
- if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1) {
3275
+ if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1 || state.preservedEndAnchorCorrection) {
3023
3276
  return;
3024
3277
  }
3025
3278
  if (didFinishedInitialScrollMoveAwayFromTarget(ctx, initialScroll)) {
@@ -3176,7 +3429,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
3176
3429
  }
3177
3430
  }
3178
3431
  function handleBootstrapInitialScrollLayoutChange(ctx) {
3179
- var _a3, _b, _c, _d;
3432
+ var _a3, _b, _c;
3180
3433
  const state = ctx.state;
3181
3434
  const initialScroll = state.initialScroll;
3182
3435
  const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
@@ -3187,7 +3440,9 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
3187
3440
  const currentOffset = scrollingTo ? (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset : getObservedBootstrapInitialScrollOffset(state);
3188
3441
  const offsetDiff = resolvedOffset - currentOffset;
3189
3442
  if (Math.abs(offsetDiff) > DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
3190
- if (scrollingTo) {
3443
+ if (state.didFinishInitialScroll) {
3444
+ schedulePreservedEndAnchorCorrection(ctx);
3445
+ } else if (scrollingTo) {
3191
3446
  const existingWatchdog = initialScrollWatchdog.get(state);
3192
3447
  scrollingTo.offset = resolvedOffset;
3193
3448
  scrollingTo.targetOffset = resolvedOffset;
@@ -3200,15 +3455,9 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
3200
3455
  startScroll: (_c = existingWatchdog == null ? void 0 : existingWatchdog.startScroll) != null ? _c : state.scroll,
3201
3456
  targetOffset: resolvedOffset
3202
3457
  });
3203
- }
3204
- requestAdjust(ctx, offsetDiff);
3205
- if (state.didFinishInitialScroll) {
3206
- (_d = state.triggerCalculateItemsInView) == null ? void 0 : _d.call(state, { forceFullItemPositions: true });
3458
+ requestAdjust(ctx, offsetDiff);
3207
3459
  }
3208
3460
  }
3209
- if (state.didFinishInitialScroll) {
3210
- clearFinishedViewportRetargetableInitialScroll(state);
3211
- }
3212
3461
  } else {
3213
3462
  rearmBootstrapInitialScroll(ctx, {
3214
3463
  scroll: resolvedOffset,
@@ -3458,7 +3707,10 @@ function retargetActiveInitialScrollAtEnd(ctx) {
3458
3707
  var _a3;
3459
3708
  const state = ctx.state;
3460
3709
  const initialScroll = state.initialScroll;
3461
- if (!initialScroll || state.didFinishInitialScroll || ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || initialScroll.viewPosition !== 1 || state.props.data.length === 0) {
3710
+ if (state.didFinishInitialScroll) {
3711
+ return schedulePreservedEndAnchorCorrection(ctx);
3712
+ }
3713
+ if (!initialScroll || ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || initialScroll.viewPosition !== 1 || state.props.data.length === 0) {
3462
3714
  return false;
3463
3715
  }
3464
3716
  return advanceCurrentInitialScrollSession(ctx, { forceScroll: true });
@@ -3477,7 +3729,14 @@ function handleInitialScrollLayoutReady(ctx) {
3477
3729
  }
3478
3730
  function initializeInitialScrollOnMount(ctx, options) {
3479
3731
  var _a3, _b;
3480
- const { dataLength, hasFooterComponent, initialContentOffset, initialScrollAtEnd, useBootstrapInitialScroll } = options;
3732
+ const {
3733
+ alwaysDispatchInitialScroll,
3734
+ dataLength,
3735
+ hasFooterComponent,
3736
+ initialContentOffset,
3737
+ initialScrollAtEnd,
3738
+ useBootstrapInitialScroll
3739
+ } = options;
3481
3740
  const state = ctx.state;
3482
3741
  const initialScroll = state.initialScroll;
3483
3742
  const resolvedInitialContentOffset = initialContentOffset != null ? initialContentOffset : 0;
@@ -3497,7 +3756,7 @@ function initializeInitialScrollOnMount(ctx, options) {
3497
3756
  return;
3498
3757
  }
3499
3758
  const hasPendingDataDependentInitialScroll = !!initialScroll && dataLength === 0 && !(resolvedInitialContentOffset === 0 && !initialScrollAtEnd);
3500
- if (!resolvedInitialContentOffset && !hasPendingDataDependentInitialScroll) {
3759
+ if (!alwaysDispatchInitialScroll && !resolvedInitialContentOffset && !hasPendingDataDependentInitialScroll) {
3501
3760
  if (initialScroll && !initialScrollAtEnd) {
3502
3761
  finishInitialScroll(ctx, {
3503
3762
  resolvedOffset: resolvedInitialContentOffset
@@ -3818,9 +4077,18 @@ function prepareMVCP(ctx, dataChanged) {
3818
4077
  }
3819
4078
  }
3820
4079
 
4080
+ // src/core/resetLayoutCachesForDataChange.ts
4081
+ function resetLayoutCachesForDataChange(state) {
4082
+ state.indexByKey.clear();
4083
+ state.idCache.length = 0;
4084
+ state.positions.length = 0;
4085
+ state.columns.length = 0;
4086
+ state.columnSpans.length = 0;
4087
+ }
4088
+
3821
4089
  // src/core/syncMountedContainer.ts
3822
4090
  function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3823
- var _a3, _b, _c, _d, _e, _f, _g, _h;
4091
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i;
3824
4092
  const state = ctx.state;
3825
4093
  const {
3826
4094
  columns,
@@ -3832,7 +4100,8 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3832
4100
  if (item === void 0) {
3833
4101
  return { didChangePosition: false, didRefreshData: false };
3834
4102
  }
3835
- const updateLayout = (_a3 = options == null ? void 0 : options.updateLayout) != null ? _a3 : true;
4103
+ const itemKey = (_a3 = state.idCache[itemIndex]) != null ? _a3 : getId(state, itemIndex);
4104
+ const updateLayout = (_b = options == null ? void 0 : options.updateLayout) != null ? _b : true;
3836
4105
  let didChangePosition = false;
3837
4106
  let didRefreshData = false;
3838
4107
  if (updateLayout) {
@@ -3841,7 +4110,9 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3841
4110
  set$(ctx, `containerPosition${containerIndex}`, POSITION_OUT_OF_VIEW);
3842
4111
  return { didChangePosition: false, didRefreshData: false };
3843
4112
  }
3844
- const position = (positionValue || 0) - ((_b = options == null ? void 0 : options.scrollAdjustPending) != null ? _b : 0);
4113
+ const logicalPosition = (positionValue || 0) - ((_c = options == null ? void 0 : options.scrollAdjustPending) != null ? _c : 0);
4114
+ const itemSize = (_d = state.sizes.get(itemKey)) != null ? _d : getItemSize(ctx, itemKey, itemIndex, item);
4115
+ const position = toPhysicalHorizontalItemPosition(state, logicalPosition, itemSize, peek$(ctx, "totalSize"));
3845
4116
  const column = columns[itemIndex] || 1;
3846
4117
  const span = columnSpans[itemIndex] || 1;
3847
4118
  const prevPos = peek$(ctx, `containerPosition${containerIndex}`);
@@ -3860,15 +4131,15 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3860
4131
  }
3861
4132
  const prevData = peek$(ctx, `containerItemData${containerIndex}`);
3862
4133
  if (prevData !== item) {
3863
- const pendingDataComparison = ((_c = state.pendingDataComparison) == null ? void 0 : _c.previousData) === state.previousData && ((_d = state.pendingDataComparison) == null ? void 0 : _d.nextData) === data ? state.pendingDataComparison : void 0;
3864
- const cachedComparison = (_e = pendingDataComparison == null ? void 0 : pendingDataComparison.byIndex[itemIndex]) != null ? _e : 0;
4134
+ const pendingDataComparison = ((_e = state.pendingDataComparison) == null ? void 0 : _e.previousData) === state.previousData && ((_f = state.pendingDataComparison) == null ? void 0 : _f.nextData) === data ? state.pendingDataComparison : void 0;
4135
+ const cachedComparison = (_g = pendingDataComparison == null ? void 0 : pendingDataComparison.byIndex[itemIndex]) != null ? _g : 0;
3865
4136
  if (cachedComparison === 2) {
3866
4137
  set$(ctx, `containerItemData${containerIndex}`, item);
3867
4138
  didRefreshData = true;
3868
4139
  } else if (cachedComparison !== 1) {
3869
- const itemKey = (_g = (_f = peek$(ctx, `containerItemKey${containerIndex}`)) != null ? _f : state.idCache[itemIndex]) != null ? _g : getId(state, itemIndex);
4140
+ const nextItemKey = (_h = peek$(ctx, `containerItemKey${containerIndex}`)) != null ? _h : itemKey;
3870
4141
  const prevKey = keyExtractor == null ? void 0 : keyExtractor(prevData, itemIndex);
3871
- if (prevData === void 0 || !keyExtractor || prevKey !== itemKey) {
4142
+ if (prevData === void 0 || !keyExtractor || prevKey !== nextItemKey) {
3872
4143
  set$(ctx, `containerItemData${containerIndex}`, item);
3873
4144
  didRefreshData = true;
3874
4145
  } else if (!itemsAreEqual) {
@@ -3885,7 +4156,7 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3885
4156
  };
3886
4157
  }
3887
4158
  }
3888
- if ((_h = state.pendingDataComparison) == null ? void 0 : _h.byIndex) {
4159
+ if ((_i = state.pendingDataComparison) == null ? void 0 : _i.byIndex) {
3889
4160
  state.pendingDataComparison.byIndex[itemIndex] = isEqual ? 1 : 2;
3890
4161
  }
3891
4162
  if (!isEqual) {
@@ -4050,11 +4321,13 @@ function updateSnapToOffsets(ctx) {
4050
4321
  const {
4051
4322
  props: { snapToIndices }
4052
4323
  } = state;
4324
+ const contentSize = state.props.horizontal ? getContentSize(ctx) : void 0;
4053
4325
  const snapToOffsets = Array(snapToIndices.length);
4054
4326
  for (let i = 0; i < snapToIndices.length; i++) {
4055
4327
  const idx = snapToIndices[i];
4056
4328
  getId(state, idx);
4057
- snapToOffsets[i] = state.positions[idx];
4329
+ const logicalOffset = state.positions[idx];
4330
+ snapToOffsets[i] = toNativeHorizontalOffset(state, logicalOffset, contentSize);
4058
4331
  }
4059
4332
  set$(ctx, "snapToOffsets", snapToOffsets);
4060
4333
  }
@@ -4663,7 +4936,6 @@ function calculateItemsInView(ctx, params = {}) {
4663
4936
  var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
4664
4937
  const {
4665
4938
  columns,
4666
- columnSpans,
4667
4939
  containerItemKeys,
4668
4940
  enableScrollForNextCalculateItemsInView,
4669
4941
  idCache,
@@ -4713,8 +4985,10 @@ function calculateItemsInView(ctx, params = {}) {
4713
4985
  let scrollTopBuffered = 0;
4714
4986
  let scrollBottom = 0;
4715
4987
  let scrollBottomBuffered = 0;
4988
+ let nativeScrollState = scrollState;
4716
4989
  const updateScroll2 = (nextScrollState) => {
4717
4990
  var _a4;
4991
+ nativeScrollState = nextScrollState;
4718
4992
  scrollAdjustPending = (_a4 = peek$(ctx, "scrollAdjustPending")) != null ? _a4 : 0;
4719
4993
  scrollAdjustPad = scrollAdjustPending - topPad;
4720
4994
  scroll = Math.round(nextScrollState + scrollExtra + scrollAdjustPad);
@@ -4726,9 +5000,17 @@ function calculateItemsInView(ctx, params = {}) {
4726
5000
  const previousStickyIndex = peek$(ctx, "activeStickyIndex");
4727
5001
  const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
4728
5002
  const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : -1;
5003
+ const stickyIndexDidChange = previousStickyIndex !== nextActiveStickyIndex;
4729
5004
  if (currentStickyIdx >= 0 || previousStickyIndex >= 0) {
4730
5005
  set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
4731
5006
  }
5007
+ const shouldNotifyStickyHeaderChange = !!onStickyHeaderChange && stickyIndicesArr.length > 0 && stickyIndexDidChange;
5008
+ const finishCalculateItemsInView = shouldNotifyStickyHeaderChange ? () => {
5009
+ const item = data[nextActiveStickyIndex];
5010
+ if (item !== void 0) {
5011
+ onStickyHeaderChange == null ? void 0 : onStickyHeaderChange({ index: nextActiveStickyIndex, item });
5012
+ }
5013
+ } : void 0;
4732
5014
  let scrollBufferTop = drawDistance;
4733
5015
  let scrollBufferBottom = drawDistance;
4734
5016
  if (speed > 0 || speed === 0 && scroll < Math.max(50, drawDistance)) {
@@ -4739,8 +5021,10 @@ function calculateItemsInView(ctx, params = {}) {
4739
5021
  scrollBufferBottom = drawDistance * 0.5;
4740
5022
  }
4741
5023
  const updateScrollRange = () => {
4742
- scrollTopBuffered = scroll - scrollBufferTop;
4743
- scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
5024
+ const scrollStart = Math.max(0, scroll);
5025
+ const overscrollBeforeContent = Math.max(0, -nativeScrollState);
5026
+ scrollTopBuffered = scrollStart - scrollBufferTop;
5027
+ scrollBottom = Math.max(scrollStart, scroll + scrollLength + overscrollBeforeContent);
4744
5028
  scrollBottomBuffered = scrollBottom + scrollBufferBottom;
4745
5029
  };
4746
5030
  updateScrollRange();
@@ -4750,17 +5034,14 @@ function calculateItemsInView(ctx, params = {}) {
4750
5034
  state.scrollForNextCalculateItemsInView = void 0;
4751
5035
  } else if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
4752
5036
  if (!isInMVCPActiveMode(state)) {
5037
+ finishCalculateItemsInView == null ? void 0 : finishCalculateItemsInView();
4753
5038
  return;
4754
5039
  }
4755
5040
  }
4756
5041
  }
4757
5042
  const checkMVCP = doMVCP && !suppressInitialScrollSideEffects ? prepareMVCP(ctx, dataChanged) : void 0;
4758
5043
  if (dataChanged) {
4759
- indexByKey.clear();
4760
- idCache.length = 0;
4761
- positions.length = 0;
4762
- columns.length = 0;
4763
- columnSpans.length = 0;
5044
+ resetLayoutCachesForDataChange(state);
4764
5045
  }
4765
5046
  const startIndex = forceFullItemPositions || dataChanged ? 0 : (_c = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _c : 0;
4766
5047
  const optimizeForVisibleWindow = !forceFullItemPositions && !dataChanged && numColumns > 1 && minIndexSizeChanged !== void 0;
@@ -5074,12 +5355,7 @@ function calculateItemsInView(ctx, params = {}) {
5074
5355
  );
5075
5356
  }
5076
5357
  }
5077
- if (onStickyHeaderChange && stickyIndicesArr.length > 0 && nextActiveStickyIndex !== void 0 && nextActiveStickyIndex !== previousStickyIndex) {
5078
- const item = data[nextActiveStickyIndex];
5079
- if (item !== void 0) {
5080
- onStickyHeaderChange({ index: nextActiveStickyIndex, item });
5081
- }
5082
- }
5358
+ finishCalculateItemsInView == null ? void 0 : finishCalculateItemsInView();
5083
5359
  });
5084
5360
  }
5085
5361
 
@@ -5107,11 +5383,22 @@ function doMaintainScrollAtEnd(ctx) {
5107
5383
  if (!state.maintainingScrollAtEnd) {
5108
5384
  state.maintainingScrollAtEnd = true;
5109
5385
  requestAnimationFrame(() => {
5110
- var _a3;
5111
5386
  if (peek$(ctx, "isWithinMaintainScrollAtEndThreshold")) {
5112
- (_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
5113
- animated: maintainScrollAtEnd.animated
5114
- });
5387
+ const scroller = refScroller.current;
5388
+ if (state.props.horizontal && isHorizontalRTL(state)) {
5389
+ const currentContentSize = getContentSize(ctx);
5390
+ const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
5391
+ const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
5392
+ scroller == null ? void 0 : scroller.scrollTo({
5393
+ animated: maintainScrollAtEnd.animated,
5394
+ x: nativeOffset,
5395
+ y: 0
5396
+ });
5397
+ } else {
5398
+ scroller == null ? void 0 : scroller.scrollToEnd({
5399
+ animated: maintainScrollAtEnd.animated
5400
+ });
5401
+ }
5115
5402
  setTimeout(
5116
5403
  () => {
5117
5404
  state.maintainingScrollAtEnd = false;
@@ -5311,7 +5598,8 @@ function handleLayout(ctx, layoutParam, setCanRender) {
5311
5598
  }
5312
5599
  checkThresholds(ctx);
5313
5600
  if (state) {
5314
- state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
5601
+ const crossAxisPadding = state.props.horizontal ? (state.props.stylePaddingTop || 0) + (state.props.stylePaddingBottom || 0) : (state.props.stylePaddingLeft || 0) + (state.props.stylePaddingRight || 0);
5602
+ state.needsOtherAxisSize = otherAxisSize - crossAxisPadding < 10;
5315
5603
  }
5316
5604
  if (IS_DEV && measuredLength === 0) {
5317
5605
  warnDevOnce(
@@ -5425,7 +5713,7 @@ function cloneScrollEvent(event) {
5425
5713
  };
5426
5714
  }
5427
5715
  function onScroll(ctx, event) {
5428
- var _a3, _b, _c, _d;
5716
+ var _a3, _b, _c, _d, _e, _f;
5429
5717
  const state = ctx.state;
5430
5718
  const { scrollProcessingEnabled } = state;
5431
5719
  if (scrollProcessingEnabled === false) {
@@ -5444,6 +5732,12 @@ function onScroll(ctx, event) {
5444
5732
  }
5445
5733
  }
5446
5734
  let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
5735
+ if (state.props.horizontal) {
5736
+ newScroll = toLogicalHorizontalOffset(state, newScroll, (_e = event.nativeEvent.contentSize) == null ? void 0 : _e.width);
5737
+ }
5738
+ state.didFinishInitialScroll && ((_f = state.initialScroll) == null ? void 0 : _f.viewPosition) === 1 && state.scroll > state.scrollLength;
5739
+ state.lastNativeScroll = newScroll;
5740
+ state.lastNativeScrollTime = Date.now();
5447
5741
  if (state.scrollingTo && state.scrollingTo.offset >= newScroll) {
5448
5742
  const maxOffset = clampScrollOffset(ctx, newScroll, state.scrollingTo);
5449
5743
  if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
@@ -5615,6 +5909,16 @@ function runOrScheduleMVCPRecalculate(ctx) {
5615
5909
  });
5616
5910
  }
5617
5911
  }
5912
+ function updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal) {
5913
+ const state = ctx.state;
5914
+ if (state.needsOtherAxisSize) {
5915
+ const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
5916
+ const currentOtherAxisSize = peek$(ctx, "otherAxisSize");
5917
+ if (!currentOtherAxisSize || otherAxisSize > currentOtherAxisSize) {
5918
+ set$(ctx, "otherAxisSize", otherAxisSize);
5919
+ }
5920
+ }
5921
+ }
5618
5922
  function updateItemSize(ctx, itemKey, sizeObj) {
5619
5923
  var _a3;
5620
5924
  const state = ctx.state;
@@ -5638,13 +5942,13 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5638
5942
  const type = getItemType ? (_a3 = getItemType(itemData, index)) != null ? _a3 : "" : "";
5639
5943
  const size2 = getFixedItemSize(itemData, index, type);
5640
5944
  if (size2 !== void 0 && size2 === sizesKnown.get(itemKey)) {
5945
+ updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal);
5641
5946
  return;
5642
5947
  }
5643
5948
  }
5644
5949
  let needsRecalculate = !didContainersLayout;
5645
5950
  let shouldMaintainScrollAtEnd = false;
5646
5951
  let minIndexSizeChanged;
5647
- let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
5648
5952
  const prevSizeKnown = state.sizesKnown.get(itemKey);
5649
5953
  const diff = updateOneItemSize(ctx, itemKey, sizeObj);
5650
5954
  const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
@@ -5655,10 +5959,6 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5655
5959
  if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
5656
5960
  needsRecalculate = true;
5657
5961
  }
5658
- if (state.needsOtherAxisSize) {
5659
- const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
5660
- maxOtherAxisSize = Math.max(maxOtherAxisSize, otherAxisSize);
5661
- }
5662
5962
  if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
5663
5963
  shouldMaintainScrollAtEnd = true;
5664
5964
  }
@@ -5674,10 +5974,7 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5674
5974
  if (minIndexSizeChanged !== void 0) {
5675
5975
  state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, minIndexSizeChanged) : minIndexSizeChanged;
5676
5976
  }
5677
- const cur = peek$(ctx, "otherAxisSize");
5678
- if (!cur || maxOtherAxisSize > cur) {
5679
- set$(ctx, "otherAxisSize", maxOtherAxisSize);
5680
- }
5977
+ updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal);
5681
5978
  if (didContainersLayout || checkAllSizesKnown(state, getMountedBufferedIndices(state))) {
5682
5979
  if (needsRecalculate) {
5683
5980
  state.scrollForNextCalculateItemsInView = void 0;
@@ -6066,6 +6363,8 @@ function getAlwaysRenderIndices(config, data, keyExtractor, anchoredEndSpaceAnch
6066
6363
  indices.sort(sortAsc);
6067
6364
  return indices;
6068
6365
  }
6366
+
6367
+ // src/utils/getRenderedItem.ts
6069
6368
  function getRenderedItem(ctx, key) {
6070
6369
  var _a3;
6071
6370
  const state = ctx.state;
@@ -6091,7 +6390,7 @@ function getRenderedItem(ctx, key) {
6091
6390
  item,
6092
6391
  type: getItemType ? (_a3 = getItemType(item, index)) != null ? _a3 : "" : ""
6093
6392
  };
6094
- renderedItem = React3__namespace.default.createElement(renderItem, itemProps);
6393
+ renderedItem = renderItem(itemProps);
6095
6394
  }
6096
6395
  return { index, item: data[index], renderedItem };
6097
6396
  }
@@ -6252,7 +6551,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6252
6551
  getFixedItemSize,
6253
6552
  getItemType,
6254
6553
  horizontal,
6554
+ rtl,
6255
6555
  initialContainerPoolRatio = 3,
6556
+ estimatedHeaderSize,
6256
6557
  initialScrollAtEnd = false,
6257
6558
  initialScrollIndex: initialScrollIndexProp,
6258
6559
  initialScrollOffset: initialScrollOffsetProp,
@@ -6320,13 +6621,16 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6320
6621
  const style = { ...StyleSheet.flatten(styleProp) };
6321
6622
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
6322
6623
  const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
6624
+ const stylePaddingLeftState = extractPadding(style, contentContainerStyle, "Left");
6625
+ const stylePaddingRightState = extractPadding(style, contentContainerStyle, "Right");
6323
6626
  const maintainScrollAtEndConfig = normalizeMaintainScrollAtEnd(maintainScrollAtEnd);
6324
6627
  const maintainVisibleContentPositionConfig = normalizeMaintainVisibleContentPosition(
6325
6628
  maintainVisibleContentPositionProp
6326
6629
  );
6327
6630
  const hasInitialScrollIndex = initialScrollIndexProp !== void 0 && initialScrollIndexProp !== null;
6328
6631
  const hasInitialScrollOffset = initialScrollOffsetProp !== void 0 && initialScrollOffsetProp !== null;
6329
- const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && hasInitialScrollOffset;
6632
+ const shouldInitializeHorizontalRTL = !initialScrollAtEnd && !hasInitialScrollIndex && !hasInitialScrollOffset && isHorizontalRTLProps({ horizontal, rtl });
6633
+ const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && (hasInitialScrollOffset || shouldInitializeHorizontalRTL);
6330
6634
  const usesBootstrapInitialScroll = initialScrollAtEnd || hasInitialScrollIndex;
6331
6635
  const initialScrollProp = initialScrollAtEnd ? {
6332
6636
  index: Math.max(0, dataProp.length - 1),
@@ -6442,6 +6746,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6442
6746
  internalState.reprocessCurrentScroll = () => updateScroll(ctx, internalState.scroll, true);
6443
6747
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
6444
6748
  set$(ctx, "extraData", extraData);
6749
+ if (estimatedHeaderSize !== void 0) {
6750
+ set$(ctx, "headerSize", estimatedHeaderSize);
6751
+ }
6445
6752
  }
6446
6753
  refState.current = ctx.state;
6447
6754
  }
@@ -6501,11 +6808,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6501
6808
  positionComponentInternal,
6502
6809
  recycleItems: !!recycleItems,
6503
6810
  renderItem,
6811
+ rtl,
6504
6812
  snapToIndices,
6505
6813
  stickyIndicesArr: stickyHeaderIndices != null ? stickyHeaderIndices : [],
6506
6814
  stickyIndicesSet: React3.useMemo(() => new Set(stickyHeaderIndices != null ? stickyHeaderIndices : []), [stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.join(",")]),
6507
6815
  stickyPositionComponentInternal,
6508
6816
  stylePaddingBottom: stylePaddingBottomState,
6817
+ stylePaddingLeft: stylePaddingLeftState,
6818
+ stylePaddingRight: stylePaddingRightState,
6509
6819
  stylePaddingTop: stylePaddingTopState,
6510
6820
  useWindowScroll: useWindowScrollResolved
6511
6821
  };
@@ -6528,6 +6838,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6528
6838
  };
6529
6839
  if (isFirstLocal) {
6530
6840
  initializeStateVars(false);
6841
+ resetLayoutCachesForDataChange(state);
6531
6842
  updateItemPositions(
6532
6843
  ctx,
6533
6844
  /*dataChanged*/
@@ -6545,6 +6856,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6545
6856
  }, [usesBootstrapInitialScroll]);
6546
6857
  React3.useLayoutEffect(() => {
6547
6858
  initializeInitialScrollOnMount(ctx, {
6859
+ alwaysDispatchInitialScroll: shouldInitializeHorizontalRTL,
6548
6860
  dataLength: dataProp.length,
6549
6861
  hasFooterComponent: !!ListFooterComponent,
6550
6862
  initialContentOffset,
@@ -6804,6 +7116,8 @@ var internal = {
6804
7116
  typedMemo,
6805
7117
  useArr$,
6806
7118
  useCombinedRef,
7119
+ useLatestRef,
7120
+ useStableRenderComponent,
6807
7121
  useStateContext
6808
7122
  };
6809
7123