@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.
package/index.js CHANGED
@@ -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
  });
@@ -664,12 +799,6 @@ function toLayout(rect) {
664
799
  };
665
800
  }
666
801
 
667
- // src/platform/Platform.ts
668
- var Platform = {
669
- // Widen the type to avoid unreachable-branch lints in cross-platform code that compares against other OSes
670
- OS: "web"
671
- };
672
-
673
802
  // src/utils/hasActiveMVCPAnchorLock.ts
674
803
  function hasActiveMVCPAnchorLock(state) {
675
804
  const lock = state.mvcpAnchorLock;
@@ -693,6 +822,7 @@ function getContainerPositionStyle({
693
822
  columnWrapperStyle,
694
823
  horizontal,
695
824
  hasItemSeparator,
825
+ isHorizontalRTLList,
696
826
  numColumns,
697
827
  otherAxisPos,
698
828
  otherAxisSize
@@ -716,6 +846,7 @@ function getContainerPositionStyle({
716
846
  }
717
847
  return horizontal ? {
718
848
  boxSizing: paddingStyles ? "border-box" : void 0,
849
+ direction: isHorizontalRTLList && Platform.OS === "web" ? "ltr" : void 0,
719
850
  flexDirection: hasItemSeparator ? "row" : void 0,
720
851
  height: otherAxisSize,
721
852
  left: 0,
@@ -744,6 +875,7 @@ var Container = typedMemo(function Container2({
744
875
  }) {
745
876
  const ctx = useStateContext();
746
877
  const { columnWrapperStyle, animatedScrollY } = ctx;
878
+ const isHorizontalRTLList = isHorizontalRTL(ctx.state);
747
879
  const positionComponentInternal = ctx.state.props.positionComponentInternal;
748
880
  const stickyPositionComponentInternal = ctx.state.props.stickyPositionComponentInternal;
749
881
  const [column = 0, span = 1, data, numColumns = 1, extraData, isSticky] = useArr$([
@@ -775,11 +907,20 @@ var Container = typedMemo(function Container2({
775
907
  columnWrapperStyle,
776
908
  hasItemSeparator: !!ItemSeparatorComponent,
777
909
  horizontal,
910
+ isHorizontalRTLList,
778
911
  numColumns,
779
912
  otherAxisPos,
780
913
  otherAxisSize
781
914
  }),
782
- [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns, ItemSeparatorComponent]
915
+ [
916
+ horizontal,
917
+ isHorizontalRTLList,
918
+ otherAxisPos,
919
+ otherAxisSize,
920
+ columnWrapperStyle,
921
+ numColumns,
922
+ ItemSeparatorComponent
923
+ ]
783
924
  );
784
925
  const renderedItemInfo = React3.useMemo(
785
926
  () => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
@@ -1019,9 +1160,16 @@ var ContainersInner = typedMemo(function ContainersInner2({ horizontal, numColum
1019
1160
  const ref = React3.useRef(null);
1020
1161
  const ctx = useStateContext();
1021
1162
  const columnWrapperStyle = ctx.columnWrapperStyle;
1163
+ const isHorizontalRTLList = isHorizontalRTL(ctx.state);
1022
1164
  const [otherAxisSize, readyToRender, totalSize] = useArr$(["otherAxisSize", "readyToRender", "totalSize"]);
1023
1165
  useDOMOrder(ref);
1024
- const style = horizontal ? { minHeight: otherAxisSize, opacity: readyToRender ? 1 : 0, position: "relative", width: totalSize } : { height: totalSize, minWidth: otherAxisSize, opacity: readyToRender ? 1 : 0, position: "relative" };
1166
+ const style = horizontal ? {
1167
+ direction: isHorizontalRTLList ? "ltr" : void 0,
1168
+ minHeight: otherAxisSize,
1169
+ opacity: readyToRender ? 1 : 0,
1170
+ position: "relative",
1171
+ width: totalSize
1172
+ } : { height: totalSize, minWidth: otherAxisSize, opacity: readyToRender ? 1 : 0, position: "relative" };
1025
1173
  if (!readyToRender) {
1026
1174
  style.pointerEvents = "none";
1027
1175
  }
@@ -1085,10 +1233,16 @@ var StyleSheet = {
1085
1233
  create: (styles) => styles,
1086
1234
  flatten: (style) => flattenStyles(style)
1087
1235
  };
1236
+ function useLatestRef(value) {
1237
+ const ref = React3__namespace.useRef(value);
1238
+ ref.current = value;
1239
+ return ref;
1240
+ }
1241
+
1242
+ // src/utils/useRafCoalescer.ts
1088
1243
  function useRafCoalescer(callback) {
1089
- const callbackRef = React3.useRef(callback);
1244
+ const callbackRef = useLatestRef(callback);
1090
1245
  const rafIdRef = React3.useRef(void 0);
1091
- callbackRef.current = callback;
1092
1246
  const coalescer = React3.useMemo(
1093
1247
  () => ({
1094
1248
  cancel() {
@@ -1232,6 +1386,31 @@ function getContentInsetEndAdjustmentEnd2(ctx) {
1232
1386
  const adjustment = (_b = (_a3 = ctx.state) == null ? void 0 : _a3.props) == null ? void 0 : _b.contentInsetEndAdjustment;
1233
1387
  return Math.max(0, adjustment != null ? adjustment : 0);
1234
1388
  }
1389
+ function getFiniteSnapOffsets(snapToOffsets) {
1390
+ if (!(snapToOffsets == null ? void 0 : snapToOffsets.length)) {
1391
+ return [];
1392
+ }
1393
+ const snapOffsets = [];
1394
+ const seen = /* @__PURE__ */ new Set();
1395
+ for (const offset of snapToOffsets) {
1396
+ if (Number.isFinite(offset) && !seen.has(offset)) {
1397
+ seen.add(offset);
1398
+ snapOffsets.push(offset);
1399
+ }
1400
+ }
1401
+ return snapOffsets;
1402
+ }
1403
+ function getSnapAnchorStyle(offset, horizontal) {
1404
+ return {
1405
+ height: horizontal ? "100%" : 1,
1406
+ left: horizontal ? offset : 0,
1407
+ pointerEvents: "none",
1408
+ position: "absolute",
1409
+ scrollSnapAlign: "start",
1410
+ top: horizontal ? 0 : offset,
1411
+ width: horizontal ? 1 : "100%"
1412
+ };
1413
+ }
1235
1414
  var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView2({
1236
1415
  children,
1237
1416
  style,
@@ -1249,7 +1428,7 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
1249
1428
  onLayout,
1250
1429
  ...props
1251
1430
  }, ref) {
1252
- var _a3, _b, _c;
1431
+ var _a3, _b, _c, _d;
1253
1432
  const ctx = useStateContext();
1254
1433
  const [anchoredEndSpaceSize] = useArr$(["anchoredEndSpaceSize"]);
1255
1434
  const scrollRef = React3.useRef(null);
@@ -1464,10 +1643,16 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
1464
1643
  contentInset: _contentInset,
1465
1644
  scrollEventThrottle: _scrollEventThrottle,
1466
1645
  ScrollComponent: _ScrollComponent,
1646
+ snapToOffsets,
1467
1647
  useWindowScroll: _useWindowScroll,
1468
1648
  className: scrollViewClassNameProp,
1469
1649
  ...webProps
1470
1650
  } = props;
1651
+ const snapOffsets = !isWindowScroll ? getFiniteSnapOffsets(snapToOffsets) : [];
1652
+ if (snapOffsets.length > 0) {
1653
+ scrollViewStyle.scrollSnapType = horizontal ? "x mandatory" : "y mandatory";
1654
+ contentStyle.position = (_d = contentStyle.position) != null ? _d : "relative";
1655
+ }
1471
1656
  const scrollViewClassName = hiddenScrollIndicatorClassName ? scrollViewClassNameProp ? `${scrollViewClassNameProp} ${hiddenScrollIndicatorClassName}` : hiddenScrollIndicatorClassName : scrollViewClassNameProp;
1472
1657
  if (IS_DEV) {
1473
1658
  if (/(?:^|\s)(?:[a-z0-9_-]+:)*gap(?:-[xy])?-(?:\[[^\]]+\]|[^\s]+)/.test(
@@ -1488,9 +1673,29 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
1488
1673
  style: scrollViewStyle
1489
1674
  },
1490
1675
  refreshControl,
1491
- /* @__PURE__ */ React3__namespace.createElement("div", { className, ref: contentRef, style: contentStyle }, children, contentInsetEndAdjustmentSpacerStyle ? /* @__PURE__ */ React3__namespace.createElement("div", { "aria-hidden": true, style: contentInsetEndAdjustmentSpacerStyle }) : null)
1676
+ /* @__PURE__ */ React3__namespace.createElement("div", { className, ref: contentRef, style: contentStyle }, snapOffsets.map((offset) => /* @__PURE__ */ React3__namespace.createElement(
1677
+ "div",
1678
+ {
1679
+ "aria-hidden": true,
1680
+ "data-legend-list-snap-anchor": offset,
1681
+ key: `snap-${offset}`,
1682
+ style: getSnapAnchorStyle(offset, horizontal)
1683
+ }
1684
+ )), children, contentInsetEndAdjustmentSpacerStyle ? /* @__PURE__ */ React3__namespace.createElement("div", { "aria-hidden": true, style: contentInsetEndAdjustmentSpacerStyle }) : null)
1492
1685
  );
1493
1686
  });
1687
+
1688
+ // src/components/listComponentStyles.ts
1689
+ function getAutoOtherAxisStyle({
1690
+ horizontal,
1691
+ needsOtherAxisSize,
1692
+ otherAxisSize
1693
+ }) {
1694
+ if (!needsOtherAxisSize || !otherAxisSize || otherAxisSize <= 0) {
1695
+ return void 0;
1696
+ }
1697
+ return horizontal ? { height: otherAxisSize } : { width: otherAxisSize };
1698
+ }
1494
1699
  function useValueListener$(key, callback) {
1495
1700
  const ctx = useStateContext();
1496
1701
  React3.useLayoutEffect(() => {
@@ -1585,10 +1790,10 @@ function ScrollAdjust() {
1585
1790
  useValueListener$("scrollAdjustUserOffset", callback);
1586
1791
  return null;
1587
1792
  }
1588
- function SnapWrapper({ ScrollComponent, ...props }) {
1793
+ var SnapWrapper = React3__namespace.forwardRef(function SnapWrapperInner({ ScrollComponent, ...props }, ref) {
1589
1794
  const [snapToOffsets] = useArr$(["snapToOffsets"]);
1590
- return /* @__PURE__ */ React3__namespace.createElement(ScrollComponent, { ...props, snapToOffsets });
1591
- }
1795
+ return /* @__PURE__ */ React3__namespace.createElement(ScrollComponent, { ...props, ref, snapToOffsets });
1796
+ });
1592
1797
  function WebAnchoredEndSpace({ horizontal }) {
1593
1798
  const ctx = useStateContext();
1594
1799
  const [anchoredEndSpaceSize] = useArr$(["anchoredEndSpaceSize"]);
@@ -1599,21 +1804,25 @@ function WebAnchoredEndSpace({ horizontal }) {
1599
1804
  const style = horizontal ? { height: "100%", width: anchoredEndSpaceSize || 0 } : { height: anchoredEndSpaceSize || 0 };
1600
1805
  return /* @__PURE__ */ React3__namespace.createElement("div", { style }, null);
1601
1806
  }
1807
+ function useStableRenderComponent(renderComponent, mapProps) {
1808
+ const renderComponentRef = useLatestRef(renderComponent);
1809
+ const mapPropsRef = useLatestRef(mapProps);
1810
+ return React3__namespace.useMemo(
1811
+ () => React3__namespace.forwardRef(
1812
+ (props, ref) => {
1813
+ var _a3, _b;
1814
+ return (_b = (_a3 = renderComponentRef.current) == null ? void 0 : _a3.call(renderComponentRef, mapPropsRef.current(props, ref))) != null ? _b : null;
1815
+ }
1816
+ ),
1817
+ [mapPropsRef, renderComponentRef]
1818
+ );
1819
+ }
1602
1820
  var LayoutView = ({ onLayoutChange, refView, children, ...rest }) => {
1603
1821
  const localRef = React3.useRef(null);
1604
1822
  const ref = refView != null ? refView : localRef;
1605
1823
  useOnLayoutSync({ onLayoutChange, ref });
1606
1824
  return /* @__PURE__ */ React3__namespace.createElement("div", { ...rest, ref }, children);
1607
1825
  };
1608
- var getComponent = (Component) => {
1609
- if (React3__namespace.isValidElement(Component)) {
1610
- return Component;
1611
- }
1612
- if (Component) {
1613
- return /* @__PURE__ */ React3__namespace.createElement(Component, null);
1614
- }
1615
- return null;
1616
- };
1617
1826
 
1618
1827
  // src/components/ListComponent.tsx
1619
1828
  var ListComponent = typedMemo(function ListComponent2({
@@ -1646,14 +1855,17 @@ var ListComponent = typedMemo(function ListComponent2({
1646
1855
  }) {
1647
1856
  const ctx = useStateContext();
1648
1857
  const maintainVisibleContentPosition = ctx.state.props.maintainVisibleContentPosition;
1649
- const ScrollComponent = React3.useMemo(() => {
1650
- if (!renderScrollComponent) {
1651
- return ListComponentScrollView;
1652
- }
1653
- return React3__namespace.forwardRef(
1654
- (props, ref) => renderScrollComponent({ ...props, ref })
1655
- );
1656
- }, [renderScrollComponent]);
1858
+ const [otherAxisSize = 0] = useArr$(["otherAxisSize"]);
1859
+ const autoOtherAxisStyle = getAutoOtherAxisStyle({
1860
+ horizontal,
1861
+ needsOtherAxisSize: ctx.state.needsOtherAxisSize,
1862
+ otherAxisSize
1863
+ });
1864
+ const CustomScrollComponent = useStableRenderComponent(
1865
+ renderScrollComponent,
1866
+ (props, ref) => ({ ...props, ref })
1867
+ );
1868
+ const ScrollComponent = renderScrollComponent ? CustomScrollComponent : ListComponentScrollView;
1657
1869
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
1658
1870
  React3.useLayoutEffect(() => {
1659
1871
  if (!ListHeaderComponent) {
@@ -1684,10 +1896,10 @@ var ListComponent = typedMemo(function ListComponent2({
1684
1896
  ...rest,
1685
1897
  ...ScrollComponent === ListComponentScrollView ? { useWindowScroll } : {},
1686
1898
  contentContainerStyle: [
1687
- contentContainerStyle,
1688
1899
  horizontal ? {
1689
1900
  height: "100%"
1690
- } : {}
1901
+ } : {},
1902
+ contentContainerStyle
1691
1903
  ],
1692
1904
  contentOffset: initialContentOffset !== void 0 ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
1693
1905
  horizontal,
@@ -1696,7 +1908,7 @@ var ListComponent = typedMemo(function ListComponent2({
1696
1908
  onScroll: onScroll2,
1697
1909
  ref: refScrollView,
1698
1910
  ScrollComponent: snapToIndices ? ScrollComponent : void 0,
1699
- style
1911
+ style: autoOtherAxisStyle ? [autoOtherAxisStyle, style] : style
1700
1912
  },
1701
1913
  /* @__PURE__ */ React3__namespace.createElement(ScrollAdjust, null),
1702
1914
  ListHeaderComponent && /* @__PURE__ */ React3__namespace.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
@@ -2413,7 +2625,8 @@ function doScrollTo(ctx, params) {
2413
2625
  }
2414
2626
  const isAnimated = !!animated;
2415
2627
  const isHorizontal = !!horizontal;
2416
- const left = isHorizontal ? offset : 0;
2628
+ const contentSize = isHorizontal ? getContentSize(ctx) : void 0;
2629
+ const left = isHorizontal ? toNativeHorizontalOffset(state, offset, contentSize) : 0;
2417
2630
  const top = isHorizontal ? 0 : offset;
2418
2631
  scroller.scrollTo({ animated: isAnimated, x: left, y: top });
2419
2632
  if (isAnimated) {
@@ -3012,11 +3225,51 @@ function getObservedBootstrapInitialScrollOffset(state) {
3012
3225
  const observedOffset = (_b = (_a3 = state.refScroller.current) == null ? void 0 : _a3.getCurrentScrollOffset) == null ? void 0 : _b.call(_a3);
3013
3226
  return typeof observedOffset === "number" && Number.isFinite(observedOffset) ? observedOffset : (_d = (_c = state.scrollPending) != null ? _c : state.scroll) != null ? _d : 0;
3014
3227
  }
3228
+ function getPreservedEndAnchorOffsetDiff(ctx) {
3229
+ var _a3;
3230
+ const state = ctx.state;
3231
+ const initialScroll = state.initialScroll;
3232
+ if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || !initialScroll || initialScroll.viewPosition !== 1 || state.props.data.length === 0 || isOffsetInitialScrollSession(state)) {
3233
+ return;
3234
+ }
3235
+ const currentOffset = typeof state.lastNativeScroll === "number" && Number.isFinite(state.lastNativeScroll) ? state.lastNativeScroll : getObservedBootstrapInitialScrollOffset(state);
3236
+ return resolveInitialScrollOffset(ctx, initialScroll) - currentOffset;
3237
+ }
3238
+ function schedulePreservedEndAnchorCorrection(ctx) {
3239
+ if (getPreservedEndAnchorOffsetDiff(ctx) === void 0) {
3240
+ return false;
3241
+ }
3242
+ const correction = {};
3243
+ schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
3244
+ return true;
3245
+ }
3246
+ function schedulePreservedEndAnchorCorrectionFrame(ctx, correction) {
3247
+ const state = ctx.state;
3248
+ state.preservedEndAnchorCorrection = correction;
3249
+ requestAnimationFrame(() => {
3250
+ var _a3;
3251
+ const activeCorrection = state.preservedEndAnchorCorrection;
3252
+ if (activeCorrection !== correction) {
3253
+ return;
3254
+ }
3255
+ const offsetDiff = getPreservedEndAnchorOffsetDiff(ctx);
3256
+ if (offsetDiff === void 0 || Math.abs(offsetDiff) <= DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
3257
+ state.preservedEndAnchorCorrection = void 0;
3258
+ return;
3259
+ }
3260
+ const hasObservedNativeScrollAfterRequest = !activeCorrection.lastRequestTime || ((_a3 = state.lastNativeScrollTime) != null ? _a3 : 0) > activeCorrection.lastRequestTime;
3261
+ if (hasObservedNativeScrollAfterRequest) {
3262
+ activeCorrection.lastRequestTime = Date.now();
3263
+ requestAdjust(ctx, offsetDiff);
3264
+ }
3265
+ schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
3266
+ });
3267
+ }
3015
3268
  function clearFinishedBootstrapInitialScrollTargetIfMovedAway(ctx) {
3016
3269
  var _a3, _b;
3017
3270
  const state = ctx.state;
3018
3271
  const initialScroll = state.initialScroll;
3019
- if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1) {
3272
+ if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1 || state.preservedEndAnchorCorrection) {
3020
3273
  return;
3021
3274
  }
3022
3275
  if (didFinishedInitialScrollMoveAwayFromTarget(ctx, initialScroll)) {
@@ -3173,7 +3426,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
3173
3426
  }
3174
3427
  }
3175
3428
  function handleBootstrapInitialScrollLayoutChange(ctx) {
3176
- var _a3, _b, _c, _d;
3429
+ var _a3, _b, _c;
3177
3430
  const state = ctx.state;
3178
3431
  const initialScroll = state.initialScroll;
3179
3432
  const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
@@ -3184,7 +3437,9 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
3184
3437
  const currentOffset = scrollingTo ? (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset : getObservedBootstrapInitialScrollOffset(state);
3185
3438
  const offsetDiff = resolvedOffset - currentOffset;
3186
3439
  if (Math.abs(offsetDiff) > DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
3187
- if (scrollingTo) {
3440
+ if (state.didFinishInitialScroll) {
3441
+ schedulePreservedEndAnchorCorrection(ctx);
3442
+ } else if (scrollingTo) {
3188
3443
  const existingWatchdog = initialScrollWatchdog.get(state);
3189
3444
  scrollingTo.offset = resolvedOffset;
3190
3445
  scrollingTo.targetOffset = resolvedOffset;
@@ -3197,15 +3452,9 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
3197
3452
  startScroll: (_c = existingWatchdog == null ? void 0 : existingWatchdog.startScroll) != null ? _c : state.scroll,
3198
3453
  targetOffset: resolvedOffset
3199
3454
  });
3200
- }
3201
- requestAdjust(ctx, offsetDiff);
3202
- if (state.didFinishInitialScroll) {
3203
- (_d = state.triggerCalculateItemsInView) == null ? void 0 : _d.call(state, { forceFullItemPositions: true });
3455
+ requestAdjust(ctx, offsetDiff);
3204
3456
  }
3205
3457
  }
3206
- if (state.didFinishInitialScroll) {
3207
- clearFinishedViewportRetargetableInitialScroll(state);
3208
- }
3209
3458
  } else {
3210
3459
  rearmBootstrapInitialScroll(ctx, {
3211
3460
  scroll: resolvedOffset,
@@ -3455,7 +3704,10 @@ function retargetActiveInitialScrollAtEnd(ctx) {
3455
3704
  var _a3;
3456
3705
  const state = ctx.state;
3457
3706
  const initialScroll = state.initialScroll;
3458
- if (!initialScroll || state.didFinishInitialScroll || ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || initialScroll.viewPosition !== 1 || state.props.data.length === 0) {
3707
+ if (state.didFinishInitialScroll) {
3708
+ return schedulePreservedEndAnchorCorrection(ctx);
3709
+ }
3710
+ if (!initialScroll || ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || initialScroll.viewPosition !== 1 || state.props.data.length === 0) {
3459
3711
  return false;
3460
3712
  }
3461
3713
  return advanceCurrentInitialScrollSession(ctx, { forceScroll: true });
@@ -3474,7 +3726,14 @@ function handleInitialScrollLayoutReady(ctx) {
3474
3726
  }
3475
3727
  function initializeInitialScrollOnMount(ctx, options) {
3476
3728
  var _a3, _b;
3477
- const { dataLength, hasFooterComponent, initialContentOffset, initialScrollAtEnd, useBootstrapInitialScroll } = options;
3729
+ const {
3730
+ alwaysDispatchInitialScroll,
3731
+ dataLength,
3732
+ hasFooterComponent,
3733
+ initialContentOffset,
3734
+ initialScrollAtEnd,
3735
+ useBootstrapInitialScroll
3736
+ } = options;
3478
3737
  const state = ctx.state;
3479
3738
  const initialScroll = state.initialScroll;
3480
3739
  const resolvedInitialContentOffset = initialContentOffset != null ? initialContentOffset : 0;
@@ -3494,7 +3753,7 @@ function initializeInitialScrollOnMount(ctx, options) {
3494
3753
  return;
3495
3754
  }
3496
3755
  const hasPendingDataDependentInitialScroll = !!initialScroll && dataLength === 0 && !(resolvedInitialContentOffset === 0 && !initialScrollAtEnd);
3497
- if (!resolvedInitialContentOffset && !hasPendingDataDependentInitialScroll) {
3756
+ if (!alwaysDispatchInitialScroll && !resolvedInitialContentOffset && !hasPendingDataDependentInitialScroll) {
3498
3757
  if (initialScroll && !initialScrollAtEnd) {
3499
3758
  finishInitialScroll(ctx, {
3500
3759
  resolvedOffset: resolvedInitialContentOffset
@@ -3815,9 +4074,18 @@ function prepareMVCP(ctx, dataChanged) {
3815
4074
  }
3816
4075
  }
3817
4076
 
4077
+ // src/core/resetLayoutCachesForDataChange.ts
4078
+ function resetLayoutCachesForDataChange(state) {
4079
+ state.indexByKey.clear();
4080
+ state.idCache.length = 0;
4081
+ state.positions.length = 0;
4082
+ state.columns.length = 0;
4083
+ state.columnSpans.length = 0;
4084
+ }
4085
+
3818
4086
  // src/core/syncMountedContainer.ts
3819
4087
  function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3820
- var _a3, _b, _c, _d, _e, _f, _g, _h;
4088
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i;
3821
4089
  const state = ctx.state;
3822
4090
  const {
3823
4091
  columns,
@@ -3829,7 +4097,8 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3829
4097
  if (item === void 0) {
3830
4098
  return { didChangePosition: false, didRefreshData: false };
3831
4099
  }
3832
- const updateLayout = (_a3 = options == null ? void 0 : options.updateLayout) != null ? _a3 : true;
4100
+ const itemKey = (_a3 = state.idCache[itemIndex]) != null ? _a3 : getId(state, itemIndex);
4101
+ const updateLayout = (_b = options == null ? void 0 : options.updateLayout) != null ? _b : true;
3833
4102
  let didChangePosition = false;
3834
4103
  let didRefreshData = false;
3835
4104
  if (updateLayout) {
@@ -3838,7 +4107,9 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3838
4107
  set$(ctx, `containerPosition${containerIndex}`, POSITION_OUT_OF_VIEW);
3839
4108
  return { didChangePosition: false, didRefreshData: false };
3840
4109
  }
3841
- const position = (positionValue || 0) - ((_b = options == null ? void 0 : options.scrollAdjustPending) != null ? _b : 0);
4110
+ const logicalPosition = (positionValue || 0) - ((_c = options == null ? void 0 : options.scrollAdjustPending) != null ? _c : 0);
4111
+ const itemSize = (_d = state.sizes.get(itemKey)) != null ? _d : getItemSize(ctx, itemKey, itemIndex, item);
4112
+ const position = toPhysicalHorizontalItemPosition(state, logicalPosition, itemSize, peek$(ctx, "totalSize"));
3842
4113
  const column = columns[itemIndex] || 1;
3843
4114
  const span = columnSpans[itemIndex] || 1;
3844
4115
  const prevPos = peek$(ctx, `containerPosition${containerIndex}`);
@@ -3857,15 +4128,15 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3857
4128
  }
3858
4129
  const prevData = peek$(ctx, `containerItemData${containerIndex}`);
3859
4130
  if (prevData !== item) {
3860
- 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;
3861
- const cachedComparison = (_e = pendingDataComparison == null ? void 0 : pendingDataComparison.byIndex[itemIndex]) != null ? _e : 0;
4131
+ 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;
4132
+ const cachedComparison = (_g = pendingDataComparison == null ? void 0 : pendingDataComparison.byIndex[itemIndex]) != null ? _g : 0;
3862
4133
  if (cachedComparison === 2) {
3863
4134
  set$(ctx, `containerItemData${containerIndex}`, item);
3864
4135
  didRefreshData = true;
3865
4136
  } else if (cachedComparison !== 1) {
3866
- const itemKey = (_g = (_f = peek$(ctx, `containerItemKey${containerIndex}`)) != null ? _f : state.idCache[itemIndex]) != null ? _g : getId(state, itemIndex);
4137
+ const nextItemKey = (_h = peek$(ctx, `containerItemKey${containerIndex}`)) != null ? _h : itemKey;
3867
4138
  const prevKey = keyExtractor == null ? void 0 : keyExtractor(prevData, itemIndex);
3868
- if (prevData === void 0 || !keyExtractor || prevKey !== itemKey) {
4139
+ if (prevData === void 0 || !keyExtractor || prevKey !== nextItemKey) {
3869
4140
  set$(ctx, `containerItemData${containerIndex}`, item);
3870
4141
  didRefreshData = true;
3871
4142
  } else if (!itemsAreEqual) {
@@ -3882,7 +4153,7 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3882
4153
  };
3883
4154
  }
3884
4155
  }
3885
- if ((_h = state.pendingDataComparison) == null ? void 0 : _h.byIndex) {
4156
+ if ((_i = state.pendingDataComparison) == null ? void 0 : _i.byIndex) {
3886
4157
  state.pendingDataComparison.byIndex[itemIndex] = isEqual ? 1 : 2;
3887
4158
  }
3888
4159
  if (!isEqual) {
@@ -4047,11 +4318,13 @@ function updateSnapToOffsets(ctx) {
4047
4318
  const {
4048
4319
  props: { snapToIndices }
4049
4320
  } = state;
4321
+ const contentSize = state.props.horizontal ? getContentSize(ctx) : void 0;
4050
4322
  const snapToOffsets = Array(snapToIndices.length);
4051
4323
  for (let i = 0; i < snapToIndices.length; i++) {
4052
4324
  const idx = snapToIndices[i];
4053
4325
  getId(state, idx);
4054
- snapToOffsets[i] = state.positions[idx];
4326
+ const logicalOffset = state.positions[idx];
4327
+ snapToOffsets[i] = toNativeHorizontalOffset(state, logicalOffset, contentSize);
4055
4328
  }
4056
4329
  set$(ctx, "snapToOffsets", snapToOffsets);
4057
4330
  }
@@ -4660,7 +4933,6 @@ function calculateItemsInView(ctx, params = {}) {
4660
4933
  var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
4661
4934
  const {
4662
4935
  columns,
4663
- columnSpans,
4664
4936
  containerItemKeys,
4665
4937
  enableScrollForNextCalculateItemsInView,
4666
4938
  idCache,
@@ -4710,8 +4982,10 @@ function calculateItemsInView(ctx, params = {}) {
4710
4982
  let scrollTopBuffered = 0;
4711
4983
  let scrollBottom = 0;
4712
4984
  let scrollBottomBuffered = 0;
4985
+ let nativeScrollState = scrollState;
4713
4986
  const updateScroll2 = (nextScrollState) => {
4714
4987
  var _a4;
4988
+ nativeScrollState = nextScrollState;
4715
4989
  scrollAdjustPending = (_a4 = peek$(ctx, "scrollAdjustPending")) != null ? _a4 : 0;
4716
4990
  scrollAdjustPad = scrollAdjustPending - topPad;
4717
4991
  scroll = Math.round(nextScrollState + scrollExtra + scrollAdjustPad);
@@ -4723,9 +4997,17 @@ function calculateItemsInView(ctx, params = {}) {
4723
4997
  const previousStickyIndex = peek$(ctx, "activeStickyIndex");
4724
4998
  const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
4725
4999
  const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : -1;
5000
+ const stickyIndexDidChange = previousStickyIndex !== nextActiveStickyIndex;
4726
5001
  if (currentStickyIdx >= 0 || previousStickyIndex >= 0) {
4727
5002
  set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
4728
5003
  }
5004
+ const shouldNotifyStickyHeaderChange = !!onStickyHeaderChange && stickyIndicesArr.length > 0 && stickyIndexDidChange;
5005
+ const finishCalculateItemsInView = shouldNotifyStickyHeaderChange ? () => {
5006
+ const item = data[nextActiveStickyIndex];
5007
+ if (item !== void 0) {
5008
+ onStickyHeaderChange == null ? void 0 : onStickyHeaderChange({ index: nextActiveStickyIndex, item });
5009
+ }
5010
+ } : void 0;
4729
5011
  let scrollBufferTop = drawDistance;
4730
5012
  let scrollBufferBottom = drawDistance;
4731
5013
  if (speed > 0 || speed === 0 && scroll < Math.max(50, drawDistance)) {
@@ -4736,8 +5018,10 @@ function calculateItemsInView(ctx, params = {}) {
4736
5018
  scrollBufferBottom = drawDistance * 0.5;
4737
5019
  }
4738
5020
  const updateScrollRange = () => {
4739
- scrollTopBuffered = scroll - scrollBufferTop;
4740
- scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
5021
+ const scrollStart = Math.max(0, scroll);
5022
+ const overscrollBeforeContent = Math.max(0, -nativeScrollState);
5023
+ scrollTopBuffered = scrollStart - scrollBufferTop;
5024
+ scrollBottom = Math.max(scrollStart, scroll + scrollLength + overscrollBeforeContent);
4741
5025
  scrollBottomBuffered = scrollBottom + scrollBufferBottom;
4742
5026
  };
4743
5027
  updateScrollRange();
@@ -4747,17 +5031,14 @@ function calculateItemsInView(ctx, params = {}) {
4747
5031
  state.scrollForNextCalculateItemsInView = void 0;
4748
5032
  } else if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
4749
5033
  if (!isInMVCPActiveMode(state)) {
5034
+ finishCalculateItemsInView == null ? void 0 : finishCalculateItemsInView();
4750
5035
  return;
4751
5036
  }
4752
5037
  }
4753
5038
  }
4754
5039
  const checkMVCP = doMVCP && !suppressInitialScrollSideEffects ? prepareMVCP(ctx, dataChanged) : void 0;
4755
5040
  if (dataChanged) {
4756
- indexByKey.clear();
4757
- idCache.length = 0;
4758
- positions.length = 0;
4759
- columns.length = 0;
4760
- columnSpans.length = 0;
5041
+ resetLayoutCachesForDataChange(state);
4761
5042
  }
4762
5043
  const startIndex = forceFullItemPositions || dataChanged ? 0 : (_c = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _c : 0;
4763
5044
  const optimizeForVisibleWindow = !forceFullItemPositions && !dataChanged && numColumns > 1 && minIndexSizeChanged !== void 0;
@@ -5071,12 +5352,7 @@ function calculateItemsInView(ctx, params = {}) {
5071
5352
  );
5072
5353
  }
5073
5354
  }
5074
- if (onStickyHeaderChange && stickyIndicesArr.length > 0 && nextActiveStickyIndex !== void 0 && nextActiveStickyIndex !== previousStickyIndex) {
5075
- const item = data[nextActiveStickyIndex];
5076
- if (item !== void 0) {
5077
- onStickyHeaderChange({ index: nextActiveStickyIndex, item });
5078
- }
5079
- }
5355
+ finishCalculateItemsInView == null ? void 0 : finishCalculateItemsInView();
5080
5356
  });
5081
5357
  }
5082
5358
 
@@ -5104,11 +5380,22 @@ function doMaintainScrollAtEnd(ctx) {
5104
5380
  if (!state.maintainingScrollAtEnd) {
5105
5381
  state.maintainingScrollAtEnd = true;
5106
5382
  requestAnimationFrame(() => {
5107
- var _a3;
5108
5383
  if (peek$(ctx, "isWithinMaintainScrollAtEndThreshold")) {
5109
- (_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
5110
- animated: maintainScrollAtEnd.animated
5111
- });
5384
+ const scroller = refScroller.current;
5385
+ if (state.props.horizontal && isHorizontalRTL(state)) {
5386
+ const currentContentSize = getContentSize(ctx);
5387
+ const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
5388
+ const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
5389
+ scroller == null ? void 0 : scroller.scrollTo({
5390
+ animated: maintainScrollAtEnd.animated,
5391
+ x: nativeOffset,
5392
+ y: 0
5393
+ });
5394
+ } else {
5395
+ scroller == null ? void 0 : scroller.scrollToEnd({
5396
+ animated: maintainScrollAtEnd.animated
5397
+ });
5398
+ }
5112
5399
  setTimeout(
5113
5400
  () => {
5114
5401
  state.maintainingScrollAtEnd = false;
@@ -5308,7 +5595,8 @@ function handleLayout(ctx, layoutParam, setCanRender) {
5308
5595
  }
5309
5596
  checkThresholds(ctx);
5310
5597
  if (state) {
5311
- state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
5598
+ const crossAxisPadding = state.props.horizontal ? (state.props.stylePaddingTop || 0) + (state.props.stylePaddingBottom || 0) : (state.props.stylePaddingLeft || 0) + (state.props.stylePaddingRight || 0);
5599
+ state.needsOtherAxisSize = otherAxisSize - crossAxisPadding < 10;
5312
5600
  }
5313
5601
  if (IS_DEV && measuredLength === 0) {
5314
5602
  warnDevOnce(
@@ -5422,7 +5710,7 @@ function cloneScrollEvent(event) {
5422
5710
  };
5423
5711
  }
5424
5712
  function onScroll(ctx, event) {
5425
- var _a3, _b, _c, _d;
5713
+ var _a3, _b, _c, _d, _e, _f;
5426
5714
  const state = ctx.state;
5427
5715
  const { scrollProcessingEnabled } = state;
5428
5716
  if (scrollProcessingEnabled === false) {
@@ -5441,6 +5729,12 @@ function onScroll(ctx, event) {
5441
5729
  }
5442
5730
  }
5443
5731
  let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
5732
+ if (state.props.horizontal) {
5733
+ newScroll = toLogicalHorizontalOffset(state, newScroll, (_e = event.nativeEvent.contentSize) == null ? void 0 : _e.width);
5734
+ }
5735
+ state.didFinishInitialScroll && ((_f = state.initialScroll) == null ? void 0 : _f.viewPosition) === 1 && state.scroll > state.scrollLength;
5736
+ state.lastNativeScroll = newScroll;
5737
+ state.lastNativeScrollTime = Date.now();
5444
5738
  if (state.scrollingTo && state.scrollingTo.offset >= newScroll) {
5445
5739
  const maxOffset = clampScrollOffset(ctx, newScroll, state.scrollingTo);
5446
5740
  if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
@@ -5612,6 +5906,16 @@ function runOrScheduleMVCPRecalculate(ctx) {
5612
5906
  });
5613
5907
  }
5614
5908
  }
5909
+ function updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal) {
5910
+ const state = ctx.state;
5911
+ if (state.needsOtherAxisSize) {
5912
+ const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
5913
+ const currentOtherAxisSize = peek$(ctx, "otherAxisSize");
5914
+ if (!currentOtherAxisSize || otherAxisSize > currentOtherAxisSize) {
5915
+ set$(ctx, "otherAxisSize", otherAxisSize);
5916
+ }
5917
+ }
5918
+ }
5615
5919
  function updateItemSize(ctx, itemKey, sizeObj) {
5616
5920
  var _a3;
5617
5921
  const state = ctx.state;
@@ -5635,13 +5939,13 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5635
5939
  const type = getItemType ? (_a3 = getItemType(itemData, index)) != null ? _a3 : "" : "";
5636
5940
  const size2 = getFixedItemSize(itemData, index, type);
5637
5941
  if (size2 !== void 0 && size2 === sizesKnown.get(itemKey)) {
5942
+ updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal);
5638
5943
  return;
5639
5944
  }
5640
5945
  }
5641
5946
  let needsRecalculate = !didContainersLayout;
5642
5947
  let shouldMaintainScrollAtEnd = false;
5643
5948
  let minIndexSizeChanged;
5644
- let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
5645
5949
  const prevSizeKnown = state.sizesKnown.get(itemKey);
5646
5950
  const diff = updateOneItemSize(ctx, itemKey, sizeObj);
5647
5951
  const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
@@ -5652,10 +5956,6 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5652
5956
  if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
5653
5957
  needsRecalculate = true;
5654
5958
  }
5655
- if (state.needsOtherAxisSize) {
5656
- const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
5657
- maxOtherAxisSize = Math.max(maxOtherAxisSize, otherAxisSize);
5658
- }
5659
5959
  if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
5660
5960
  shouldMaintainScrollAtEnd = true;
5661
5961
  }
@@ -5671,10 +5971,7 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5671
5971
  if (minIndexSizeChanged !== void 0) {
5672
5972
  state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, minIndexSizeChanged) : minIndexSizeChanged;
5673
5973
  }
5674
- const cur = peek$(ctx, "otherAxisSize");
5675
- if (!cur || maxOtherAxisSize > cur) {
5676
- set$(ctx, "otherAxisSize", maxOtherAxisSize);
5677
- }
5974
+ updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal);
5678
5975
  if (didContainersLayout || checkAllSizesKnown(state, getMountedBufferedIndices(state))) {
5679
5976
  if (needsRecalculate) {
5680
5977
  state.scrollForNextCalculateItemsInView = void 0;
@@ -6063,6 +6360,8 @@ function getAlwaysRenderIndices(config, data, keyExtractor, anchoredEndSpaceAnch
6063
6360
  indices.sort(sortAsc);
6064
6361
  return indices;
6065
6362
  }
6363
+
6364
+ // src/utils/getRenderedItem.ts
6066
6365
  function getRenderedItem(ctx, key) {
6067
6366
  var _a3;
6068
6367
  const state = ctx.state;
@@ -6088,7 +6387,7 @@ function getRenderedItem(ctx, key) {
6088
6387
  item,
6089
6388
  type: getItemType ? (_a3 = getItemType(item, index)) != null ? _a3 : "" : ""
6090
6389
  };
6091
- renderedItem = React3__namespace.default.createElement(renderItem, itemProps);
6390
+ renderedItem = renderItem(itemProps);
6092
6391
  }
6093
6392
  return { index, item: data[index], renderedItem };
6094
6393
  }
@@ -6249,7 +6548,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6249
6548
  getFixedItemSize,
6250
6549
  getItemType,
6251
6550
  horizontal,
6551
+ rtl,
6252
6552
  initialContainerPoolRatio = 3,
6553
+ estimatedHeaderSize,
6253
6554
  initialScrollAtEnd = false,
6254
6555
  initialScrollIndex: initialScrollIndexProp,
6255
6556
  initialScrollOffset: initialScrollOffsetProp,
@@ -6317,13 +6618,16 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6317
6618
  const style = { ...StyleSheet.flatten(styleProp) };
6318
6619
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
6319
6620
  const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
6621
+ const stylePaddingLeftState = extractPadding(style, contentContainerStyle, "Left");
6622
+ const stylePaddingRightState = extractPadding(style, contentContainerStyle, "Right");
6320
6623
  const maintainScrollAtEndConfig = normalizeMaintainScrollAtEnd(maintainScrollAtEnd);
6321
6624
  const maintainVisibleContentPositionConfig = normalizeMaintainVisibleContentPosition(
6322
6625
  maintainVisibleContentPositionProp
6323
6626
  );
6324
6627
  const hasInitialScrollIndex = initialScrollIndexProp !== void 0 && initialScrollIndexProp !== null;
6325
6628
  const hasInitialScrollOffset = initialScrollOffsetProp !== void 0 && initialScrollOffsetProp !== null;
6326
- const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && hasInitialScrollOffset;
6629
+ const shouldInitializeHorizontalRTL = !initialScrollAtEnd && !hasInitialScrollIndex && !hasInitialScrollOffset && isHorizontalRTLProps({ horizontal, rtl });
6630
+ const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && (hasInitialScrollOffset || shouldInitializeHorizontalRTL);
6327
6631
  const usesBootstrapInitialScroll = initialScrollAtEnd || hasInitialScrollIndex;
6328
6632
  const initialScrollProp = initialScrollAtEnd ? {
6329
6633
  index: Math.max(0, dataProp.length - 1),
@@ -6439,6 +6743,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6439
6743
  internalState.reprocessCurrentScroll = () => updateScroll(ctx, internalState.scroll, true);
6440
6744
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
6441
6745
  set$(ctx, "extraData", extraData);
6746
+ if (estimatedHeaderSize !== void 0) {
6747
+ set$(ctx, "headerSize", estimatedHeaderSize);
6748
+ }
6442
6749
  }
6443
6750
  refState.current = ctx.state;
6444
6751
  }
@@ -6498,11 +6805,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6498
6805
  positionComponentInternal,
6499
6806
  recycleItems: !!recycleItems,
6500
6807
  renderItem,
6808
+ rtl,
6501
6809
  snapToIndices,
6502
6810
  stickyIndicesArr: stickyHeaderIndices != null ? stickyHeaderIndices : [],
6503
6811
  stickyIndicesSet: React3.useMemo(() => new Set(stickyHeaderIndices != null ? stickyHeaderIndices : []), [stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.join(",")]),
6504
6812
  stickyPositionComponentInternal,
6505
6813
  stylePaddingBottom: stylePaddingBottomState,
6814
+ stylePaddingLeft: stylePaddingLeftState,
6815
+ stylePaddingRight: stylePaddingRightState,
6506
6816
  stylePaddingTop: stylePaddingTopState,
6507
6817
  useWindowScroll: useWindowScrollResolved
6508
6818
  };
@@ -6525,6 +6835,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6525
6835
  };
6526
6836
  if (isFirstLocal) {
6527
6837
  initializeStateVars(false);
6838
+ resetLayoutCachesForDataChange(state);
6528
6839
  updateItemPositions(
6529
6840
  ctx,
6530
6841
  /*dataChanged*/
@@ -6542,6 +6853,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6542
6853
  }, [usesBootstrapInitialScroll]);
6543
6854
  React3.useLayoutEffect(() => {
6544
6855
  initializeInitialScrollOnMount(ctx, {
6856
+ alwaysDispatchInitialScroll: shouldInitializeHorizontalRTL,
6545
6857
  dataLength: dataProp.length,
6546
6858
  hasFooterComponent: !!ListFooterComponent,
6547
6859
  initialContentOffset,