@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.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as React3 from 'react';
2
- import React3__default, { forwardRef, useReducer, useEffect, createContext, useRef, useState, useMemo, useCallback, useImperativeHandle, useLayoutEffect, useContext } from 'react';
2
+ import { forwardRef, useReducer, useEffect, createContext, useRef, useState, useMemo, useCallback, useImperativeHandle, useLayoutEffect, useContext } from 'react';
3
3
  import { useSyncExternalStore } from 'use-sync-external-store/shim';
4
4
  import * as ReactDOM from 'react-dom';
5
5
  import { flushSync } from 'react-dom';
@@ -13,6 +13,115 @@ var View = forwardRef(function View2(props, ref) {
13
13
  });
14
14
  var Text = View;
15
15
 
16
+ // src/platform/Platform.ts
17
+ var Platform = {
18
+ // Widen the type to avoid unreachable-branch lints in cross-platform code that compares against other OSes
19
+ OS: "web"
20
+ };
21
+
22
+ // src/utils/rtl.ts
23
+ function clampHorizontalOffset(offset, maxOffset) {
24
+ if (maxOffset === void 0) {
25
+ return offset;
26
+ }
27
+ return Math.max(0, Math.min(maxOffset, offset));
28
+ }
29
+ function getHorizontalMaxOffset(state, contentWidth) {
30
+ if (contentWidth === void 0 || !Number.isFinite(contentWidth) || !Number.isFinite(state.scrollLength) || contentWidth <= state.scrollLength) {
31
+ return contentWidth !== void 0 && Number.isFinite(contentWidth) && Number.isFinite(state.scrollLength) ? 0 : void 0;
32
+ }
33
+ return Math.max(0, contentWidth - state.scrollLength);
34
+ }
35
+ function getDefaultHorizontalRTLScrollType() {
36
+ return "normal" ;
37
+ }
38
+ function getNativeHorizontalRTLScrollType(state) {
39
+ var _a3;
40
+ return (_a3 = state == null ? void 0 : state.horizontalRTLScrollType) != null ? _a3 : getDefaultHorizontalRTLScrollType();
41
+ }
42
+ function isRTLProps(props) {
43
+ var _a3;
44
+ return (_a3 = props == null ? void 0 : props.rtl) != null ? _a3 : false;
45
+ }
46
+ function isHorizontalRTL(state) {
47
+ return isHorizontalRTLProps(state == null ? void 0 : state.props);
48
+ }
49
+ function isHorizontalRTLProps(props) {
50
+ return !!(props == null ? void 0 : props.horizontal) && isRTLProps(props);
51
+ }
52
+ function getLogicalHorizontalMaxOffset(state, contentWidth) {
53
+ var _a3;
54
+ return (_a3 = getHorizontalMaxOffset(state, contentWidth)) != null ? _a3 : 0;
55
+ }
56
+ function getHorizontalInsetEnd(state, inset) {
57
+ if (!inset) {
58
+ return 0;
59
+ }
60
+ return (isHorizontalRTL(state) ? inset.left : inset.right) || 0;
61
+ }
62
+ function toPhysicalHorizontalItemPosition(state, logicalPosition, itemSize, listSize) {
63
+ if (!isHorizontalRTL(state) || listSize === void 0 || !Number.isFinite(listSize)) {
64
+ return logicalPosition;
65
+ }
66
+ return Math.max(0, listSize - logicalPosition - itemSize);
67
+ }
68
+ function toNativeHorizontalOffset(state, logicalOffset, contentWidth) {
69
+ if (!state || !isHorizontalRTL(state)) {
70
+ return logicalOffset;
71
+ }
72
+ const maxOffset = getHorizontalMaxOffset(state, contentWidth);
73
+ const clampedLogicalOffset = clampHorizontalOffset(logicalOffset, maxOffset);
74
+ const mode = getNativeHorizontalRTLScrollType(state);
75
+ if (mode === "negative") {
76
+ return clampedLogicalOffset === 0 ? 0 : -clampedLogicalOffset;
77
+ }
78
+ if (mode === "inverted") {
79
+ if (maxOffset === void 0) {
80
+ return clampedLogicalOffset;
81
+ }
82
+ return clampHorizontalOffset(maxOffset - clampedLogicalOffset, maxOffset);
83
+ }
84
+ return clampedLogicalOffset;
85
+ }
86
+ function toLogicalHorizontalOffset(state, rawOffset, contentWidth) {
87
+ if (!isHorizontalRTL(state)) {
88
+ state.horizontalRTLScrollType = void 0;
89
+ return rawOffset;
90
+ }
91
+ const maxOffset = getHorizontalMaxOffset(state, contentWidth);
92
+ if (rawOffset < 0) {
93
+ state.horizontalRTLScrollType = "negative";
94
+ return clampHorizontalOffset(-rawOffset, maxOffset);
95
+ }
96
+ if (maxOffset === void 0) {
97
+ return rawOffset;
98
+ }
99
+ const normalOffset = rawOffset;
100
+ const invertedOffset = maxOffset - rawOffset;
101
+ if (!Number.isFinite(invertedOffset)) {
102
+ state.horizontalRTLScrollType = "normal";
103
+ return normalOffset;
104
+ }
105
+ const previousMode = state.horizontalRTLScrollType;
106
+ if (previousMode === "inverted") {
107
+ return clampHorizontalOffset(invertedOffset, maxOffset);
108
+ }
109
+ if (previousMode === "normal") {
110
+ return clampHorizontalOffset(normalOffset, maxOffset);
111
+ }
112
+ if (!state.hasScrolled) {
113
+ const defaultMode = getDefaultHorizontalRTLScrollType();
114
+ state.horizontalRTLScrollType = defaultMode;
115
+ return clampHorizontalOffset(normalOffset, maxOffset);
116
+ }
117
+ const referenceScroll = state.scroll;
118
+ const distanceNormal = Math.abs(normalOffset - referenceScroll);
119
+ const distanceInverted = Math.abs(invertedOffset - referenceScroll);
120
+ const useInverted = distanceInverted + 0.5 < distanceNormal;
121
+ state.horizontalRTLScrollType = useInverted ? "inverted" : "normal";
122
+ return clampHorizontalOffset(useInverted ? invertedOffset : normalOffset, maxOffset);
123
+ }
124
+
16
125
  // src/platform/Animated.tsx
17
126
  var createAnimatedValue = (value) => value;
18
127
 
@@ -155,7 +264,7 @@ function getContentInsetEnd(ctx, contentInsetEndAdjustmentOverride) {
155
264
  const horizontal = props.horizontal;
156
265
  const contentInset = props.contentInset;
157
266
  const baseInset = contentInset != null ? contentInset : state.nativeContentInset;
158
- const baseEndInset = (horizontal ? baseInset == null ? void 0 : baseInset.right : baseInset == null ? void 0 : baseInset.bottom) || 0;
267
+ const baseEndInset = (horizontal ? getHorizontalInsetEnd(state, baseInset) : baseInset == null ? void 0 : baseInset.bottom) || 0;
159
268
  const contentInsetEndAdjustment = getContentInsetEndAdjustmentEnd(
160
269
  contentInsetEndAdjustmentOverride != null ? contentInsetEndAdjustmentOverride : props.contentInsetEndAdjustment
161
270
  );
@@ -164,9 +273,9 @@ function getContentInsetEnd(ctx, contentInsetEndAdjustmentOverride) {
164
273
  const overrideInset = (_b = state.contentInsetOverride) != null ? _b : void 0;
165
274
  const adjustedBaseEndInset = baseEndInset + contentInsetEndAdjustment;
166
275
  if (overrideInset) {
167
- const mergedInset = { bottom: 0, right: 0, ...baseInset, ...overrideInset };
276
+ const mergedInset = { bottom: 0, left: 0, right: 0, ...baseInset, ...overrideInset };
168
277
  return Math.max(
169
- ((horizontal ? mergedInset.right : mergedInset.bottom) || 0) + contentInsetEndAdjustment,
278
+ ((horizontal ? getHorizontalInsetEnd(state, mergedInset) : mergedInset.bottom) || 0) + contentInsetEndAdjustment,
170
279
  anchoredEndInset
171
280
  );
172
281
  }
@@ -260,6 +369,15 @@ var ENABLE_DEVMODE = IS_DEV && false;
260
369
  var ENABLE_DEBUG_VIEW = IS_DEV && false;
261
370
  var typedForwardRef = React3.forwardRef;
262
371
  var typedMemo = React3.memo;
372
+ var getComponent = (Component) => {
373
+ if (React3.isValidElement(Component)) {
374
+ return Component;
375
+ }
376
+ if (Component) {
377
+ return /* @__PURE__ */ React3.createElement(Component, null);
378
+ }
379
+ return null;
380
+ };
263
381
 
264
382
  // src/utils/helpers.ts
265
383
  function isFunction(obj) {
@@ -286,7 +404,8 @@ function comparatorDefault(a, b) {
286
404
  }
287
405
  function getPadding(s, type) {
288
406
  var _a3, _b, _c;
289
- return (_c = (_b = (_a3 = s[`padding${type}`]) != null ? _a3 : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
407
+ const axisPadding = type === "Left" || type === "Right" ? s.paddingHorizontal : s.paddingVertical;
408
+ return (_c = (_b = (_a3 = s[`padding${type}`]) != null ? _a3 : axisPadding) != null ? _b : s.padding) != null ? _c : 0;
290
409
  }
291
410
  function extractPadding(style, contentContainerStyle, type) {
292
411
  return getPadding(style, type) + getPadding(contentContainerStyle, type);
@@ -308,6 +427,14 @@ function findContainerId(ctx, key) {
308
427
  }
309
428
 
310
429
  // src/components/PositionView.tsx
430
+ var isRNWeb = typeof document !== "undefined" && !!document.getElementById("react-native-stylesheet");
431
+ var baseCss = {
432
+ contain: "paint layout style",
433
+ ...isRNWeb ? {
434
+ display: "flex",
435
+ flexDirection: "column"
436
+ } : {}
437
+ };
311
438
  var PositionViewState = typedMemo(function PositionViewState2({
312
439
  id,
313
440
  horizontal,
@@ -316,11 +443,8 @@ var PositionViewState = typedMemo(function PositionViewState2({
316
443
  ...props
317
444
  }) {
318
445
  const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
319
- const base = {
320
- contain: "paint layout style"
321
- };
322
446
  const composed = isArray(style) ? Object.assign({}, ...style) : style;
323
- const combinedStyle = horizontal ? { ...base, ...composed, left: position } : { ...base, ...composed, top: position };
447
+ const combinedStyle = horizontal ? { ...baseCss, ...composed, left: position } : { ...baseCss, ...composed, top: position };
324
448
  const {
325
449
  animatedScrollY: _animatedScrollY,
326
450
  index,
@@ -348,9 +472,6 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
348
472
  `containerPosition${id}`,
349
473
  "activeStickyIndex"
350
474
  ]);
351
- const base = {
352
- contain: "paint layout style"
353
- };
354
475
  const composed = React3.useMemo(
355
476
  () => {
356
477
  var _a3;
@@ -360,10 +481,9 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
360
481
  );
361
482
  const viewStyle = React3.useMemo(() => {
362
483
  var _a3;
363
- const styleBase = { ...base, ...composed };
484
+ const styleBase = { ...baseCss, ...composed };
364
485
  delete styleBase.transform;
365
- const stickyConfigOffset = (_a3 = stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.offset) != null ? _a3 : 0;
366
- const offset = stickyConfigOffset != null ? stickyConfigOffset : 0;
486
+ const offset = (_a3 = stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.offset) != null ? _a3 : 0;
367
487
  const isActive = activeStickyIndex === index;
368
488
  styleBase.position = isActive ? "sticky" : "absolute";
369
489
  styleBase.zIndex = index + 1e3;
@@ -374,6 +494,20 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
374
494
  }
375
495
  return styleBase;
376
496
  }, [composed, horizontal, position, index, activeStickyIndex, stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.offset]);
497
+ const renderStickyHeaderBackdrop = React3.useMemo(
498
+ () => (stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.backdropComponent) ? /* @__PURE__ */ React3.createElement(
499
+ "div",
500
+ {
501
+ style: {
502
+ inset: 0,
503
+ pointerEvents: "none",
504
+ position: "absolute"
505
+ }
506
+ },
507
+ getComponent(stickyHeaderConfig.backdropComponent)
508
+ ) : null,
509
+ [stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.backdropComponent]
510
+ );
377
511
  return /* @__PURE__ */ React3.createElement(
378
512
  "div",
379
513
  {
@@ -382,6 +516,7 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
382
516
  style: viewStyle,
383
517
  ...webProps
384
518
  },
519
+ renderStickyHeaderBackdrop,
385
520
  children
386
521
  );
387
522
  });
@@ -643,12 +778,6 @@ function toLayout(rect) {
643
778
  };
644
779
  }
645
780
 
646
- // src/platform/Platform.ts
647
- var Platform = {
648
- // Widen the type to avoid unreachable-branch lints in cross-platform code that compares against other OSes
649
- OS: "web"
650
- };
651
-
652
781
  // src/utils/hasActiveMVCPAnchorLock.ts
653
782
  function hasActiveMVCPAnchorLock(state) {
654
783
  const lock = state.mvcpAnchorLock;
@@ -672,6 +801,7 @@ function getContainerPositionStyle({
672
801
  columnWrapperStyle,
673
802
  horizontal,
674
803
  hasItemSeparator,
804
+ isHorizontalRTLList,
675
805
  numColumns,
676
806
  otherAxisPos,
677
807
  otherAxisSize
@@ -695,6 +825,7 @@ function getContainerPositionStyle({
695
825
  }
696
826
  return horizontal ? {
697
827
  boxSizing: paddingStyles ? "border-box" : void 0,
828
+ direction: isHorizontalRTLList && Platform.OS === "web" ? "ltr" : void 0,
698
829
  flexDirection: hasItemSeparator ? "row" : void 0,
699
830
  height: otherAxisSize,
700
831
  left: 0,
@@ -723,6 +854,7 @@ var Container = typedMemo(function Container2({
723
854
  }) {
724
855
  const ctx = useStateContext();
725
856
  const { columnWrapperStyle, animatedScrollY } = ctx;
857
+ const isHorizontalRTLList = isHorizontalRTL(ctx.state);
726
858
  const positionComponentInternal = ctx.state.props.positionComponentInternal;
727
859
  const stickyPositionComponentInternal = ctx.state.props.stickyPositionComponentInternal;
728
860
  const [column = 0, span = 1, data, numColumns = 1, extraData, isSticky] = useArr$([
@@ -754,11 +886,20 @@ var Container = typedMemo(function Container2({
754
886
  columnWrapperStyle,
755
887
  hasItemSeparator: !!ItemSeparatorComponent,
756
888
  horizontal,
889
+ isHorizontalRTLList,
757
890
  numColumns,
758
891
  otherAxisPos,
759
892
  otherAxisSize
760
893
  }),
761
- [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns, ItemSeparatorComponent]
894
+ [
895
+ horizontal,
896
+ isHorizontalRTLList,
897
+ otherAxisPos,
898
+ otherAxisSize,
899
+ columnWrapperStyle,
900
+ numColumns,
901
+ ItemSeparatorComponent
902
+ ]
762
903
  );
763
904
  const renderedItemInfo = useMemo(
764
905
  () => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
@@ -998,9 +1139,16 @@ var ContainersInner = typedMemo(function ContainersInner2({ horizontal, numColum
998
1139
  const ref = useRef(null);
999
1140
  const ctx = useStateContext();
1000
1141
  const columnWrapperStyle = ctx.columnWrapperStyle;
1142
+ const isHorizontalRTLList = isHorizontalRTL(ctx.state);
1001
1143
  const [otherAxisSize, readyToRender, totalSize] = useArr$(["otherAxisSize", "readyToRender", "totalSize"]);
1002
1144
  useDOMOrder(ref);
1003
- const style = horizontal ? { minHeight: otherAxisSize, opacity: readyToRender ? 1 : 0, position: "relative", width: totalSize } : { height: totalSize, minWidth: otherAxisSize, opacity: readyToRender ? 1 : 0, position: "relative" };
1145
+ const style = horizontal ? {
1146
+ direction: isHorizontalRTLList ? "ltr" : void 0,
1147
+ minHeight: otherAxisSize,
1148
+ opacity: readyToRender ? 1 : 0,
1149
+ position: "relative",
1150
+ width: totalSize
1151
+ } : { height: totalSize, minWidth: otherAxisSize, opacity: readyToRender ? 1 : 0, position: "relative" };
1004
1152
  if (!readyToRender) {
1005
1153
  style.pointerEvents = "none";
1006
1154
  }
@@ -1064,10 +1212,16 @@ var StyleSheet = {
1064
1212
  create: (styles) => styles,
1065
1213
  flatten: (style) => flattenStyles(style)
1066
1214
  };
1215
+ function useLatestRef(value) {
1216
+ const ref = React3.useRef(value);
1217
+ ref.current = value;
1218
+ return ref;
1219
+ }
1220
+
1221
+ // src/utils/useRafCoalescer.ts
1067
1222
  function useRafCoalescer(callback) {
1068
- const callbackRef = useRef(callback);
1223
+ const callbackRef = useLatestRef(callback);
1069
1224
  const rafIdRef = useRef(void 0);
1070
- callbackRef.current = callback;
1071
1225
  const coalescer = useMemo(
1072
1226
  () => ({
1073
1227
  cancel() {
@@ -1211,6 +1365,31 @@ function getContentInsetEndAdjustmentEnd2(ctx) {
1211
1365
  const adjustment = (_b = (_a3 = ctx.state) == null ? void 0 : _a3.props) == null ? void 0 : _b.contentInsetEndAdjustment;
1212
1366
  return Math.max(0, adjustment != null ? adjustment : 0);
1213
1367
  }
1368
+ function getFiniteSnapOffsets(snapToOffsets) {
1369
+ if (!(snapToOffsets == null ? void 0 : snapToOffsets.length)) {
1370
+ return [];
1371
+ }
1372
+ const snapOffsets = [];
1373
+ const seen = /* @__PURE__ */ new Set();
1374
+ for (const offset of snapToOffsets) {
1375
+ if (Number.isFinite(offset) && !seen.has(offset)) {
1376
+ seen.add(offset);
1377
+ snapOffsets.push(offset);
1378
+ }
1379
+ }
1380
+ return snapOffsets;
1381
+ }
1382
+ function getSnapAnchorStyle(offset, horizontal) {
1383
+ return {
1384
+ height: horizontal ? "100%" : 1,
1385
+ left: horizontal ? offset : 0,
1386
+ pointerEvents: "none",
1387
+ position: "absolute",
1388
+ scrollSnapAlign: "start",
1389
+ top: horizontal ? 0 : offset,
1390
+ width: horizontal ? 1 : "100%"
1391
+ };
1392
+ }
1214
1393
  var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
1215
1394
  children,
1216
1395
  style,
@@ -1228,7 +1407,7 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
1228
1407
  onLayout,
1229
1408
  ...props
1230
1409
  }, ref) {
1231
- var _a3, _b, _c;
1410
+ var _a3, _b, _c, _d;
1232
1411
  const ctx = useStateContext();
1233
1412
  const [anchoredEndSpaceSize] = useArr$(["anchoredEndSpaceSize"]);
1234
1413
  const scrollRef = useRef(null);
@@ -1443,10 +1622,16 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
1443
1622
  contentInset: _contentInset,
1444
1623
  scrollEventThrottle: _scrollEventThrottle,
1445
1624
  ScrollComponent: _ScrollComponent,
1625
+ snapToOffsets,
1446
1626
  useWindowScroll: _useWindowScroll,
1447
1627
  className: scrollViewClassNameProp,
1448
1628
  ...webProps
1449
1629
  } = props;
1630
+ const snapOffsets = !isWindowScroll ? getFiniteSnapOffsets(snapToOffsets) : [];
1631
+ if (snapOffsets.length > 0) {
1632
+ scrollViewStyle.scrollSnapType = horizontal ? "x mandatory" : "y mandatory";
1633
+ contentStyle.position = (_d = contentStyle.position) != null ? _d : "relative";
1634
+ }
1450
1635
  const scrollViewClassName = hiddenScrollIndicatorClassName ? scrollViewClassNameProp ? `${scrollViewClassNameProp} ${hiddenScrollIndicatorClassName}` : hiddenScrollIndicatorClassName : scrollViewClassNameProp;
1451
1636
  if (IS_DEV) {
1452
1637
  if (/(?:^|\s)(?:[a-z0-9_-]+:)*gap(?:-[xy])?-(?:\[[^\]]+\]|[^\s]+)/.test(
@@ -1467,9 +1652,29 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
1467
1652
  style: scrollViewStyle
1468
1653
  },
1469
1654
  refreshControl,
1470
- /* @__PURE__ */ React3.createElement("div", { className, ref: contentRef, style: contentStyle }, children, contentInsetEndAdjustmentSpacerStyle ? /* @__PURE__ */ React3.createElement("div", { "aria-hidden": true, style: contentInsetEndAdjustmentSpacerStyle }) : null)
1655
+ /* @__PURE__ */ React3.createElement("div", { className, ref: contentRef, style: contentStyle }, snapOffsets.map((offset) => /* @__PURE__ */ React3.createElement(
1656
+ "div",
1657
+ {
1658
+ "aria-hidden": true,
1659
+ "data-legend-list-snap-anchor": offset,
1660
+ key: `snap-${offset}`,
1661
+ style: getSnapAnchorStyle(offset, horizontal)
1662
+ }
1663
+ )), children, contentInsetEndAdjustmentSpacerStyle ? /* @__PURE__ */ React3.createElement("div", { "aria-hidden": true, style: contentInsetEndAdjustmentSpacerStyle }) : null)
1471
1664
  );
1472
1665
  });
1666
+
1667
+ // src/components/listComponentStyles.ts
1668
+ function getAutoOtherAxisStyle({
1669
+ horizontal,
1670
+ needsOtherAxisSize,
1671
+ otherAxisSize
1672
+ }) {
1673
+ if (!needsOtherAxisSize || !otherAxisSize || otherAxisSize <= 0) {
1674
+ return void 0;
1675
+ }
1676
+ return horizontal ? { height: otherAxisSize } : { width: otherAxisSize };
1677
+ }
1473
1678
  function useValueListener$(key, callback) {
1474
1679
  const ctx = useStateContext();
1475
1680
  useLayoutEffect(() => {
@@ -1564,10 +1769,10 @@ function ScrollAdjust() {
1564
1769
  useValueListener$("scrollAdjustUserOffset", callback);
1565
1770
  return null;
1566
1771
  }
1567
- function SnapWrapper({ ScrollComponent, ...props }) {
1772
+ var SnapWrapper = React3.forwardRef(function SnapWrapperInner({ ScrollComponent, ...props }, ref) {
1568
1773
  const [snapToOffsets] = useArr$(["snapToOffsets"]);
1569
- return /* @__PURE__ */ React3.createElement(ScrollComponent, { ...props, snapToOffsets });
1570
- }
1774
+ return /* @__PURE__ */ React3.createElement(ScrollComponent, { ...props, ref, snapToOffsets });
1775
+ });
1571
1776
  function WebAnchoredEndSpace({ horizontal }) {
1572
1777
  const ctx = useStateContext();
1573
1778
  const [anchoredEndSpaceSize] = useArr$(["anchoredEndSpaceSize"]);
@@ -1578,21 +1783,25 @@ function WebAnchoredEndSpace({ horizontal }) {
1578
1783
  const style = horizontal ? { height: "100%", width: anchoredEndSpaceSize || 0 } : { height: anchoredEndSpaceSize || 0 };
1579
1784
  return /* @__PURE__ */ React3.createElement("div", { style }, null);
1580
1785
  }
1786
+ function useStableRenderComponent(renderComponent, mapProps) {
1787
+ const renderComponentRef = useLatestRef(renderComponent);
1788
+ const mapPropsRef = useLatestRef(mapProps);
1789
+ return React3.useMemo(
1790
+ () => React3.forwardRef(
1791
+ (props, ref) => {
1792
+ var _a3, _b;
1793
+ return (_b = (_a3 = renderComponentRef.current) == null ? void 0 : _a3.call(renderComponentRef, mapPropsRef.current(props, ref))) != null ? _b : null;
1794
+ }
1795
+ ),
1796
+ [mapPropsRef, renderComponentRef]
1797
+ );
1798
+ }
1581
1799
  var LayoutView = ({ onLayoutChange, refView, children, ...rest }) => {
1582
1800
  const localRef = useRef(null);
1583
1801
  const ref = refView != null ? refView : localRef;
1584
1802
  useOnLayoutSync({ onLayoutChange, ref });
1585
1803
  return /* @__PURE__ */ React3.createElement("div", { ...rest, ref }, children);
1586
1804
  };
1587
- var getComponent = (Component) => {
1588
- if (React3.isValidElement(Component)) {
1589
- return Component;
1590
- }
1591
- if (Component) {
1592
- return /* @__PURE__ */ React3.createElement(Component, null);
1593
- }
1594
- return null;
1595
- };
1596
1805
 
1597
1806
  // src/components/ListComponent.tsx
1598
1807
  var ListComponent = typedMemo(function ListComponent2({
@@ -1625,14 +1834,17 @@ var ListComponent = typedMemo(function ListComponent2({
1625
1834
  }) {
1626
1835
  const ctx = useStateContext();
1627
1836
  const maintainVisibleContentPosition = ctx.state.props.maintainVisibleContentPosition;
1628
- const ScrollComponent = useMemo(() => {
1629
- if (!renderScrollComponent) {
1630
- return ListComponentScrollView;
1631
- }
1632
- return React3.forwardRef(
1633
- (props, ref) => renderScrollComponent({ ...props, ref })
1634
- );
1635
- }, [renderScrollComponent]);
1837
+ const [otherAxisSize = 0] = useArr$(["otherAxisSize"]);
1838
+ const autoOtherAxisStyle = getAutoOtherAxisStyle({
1839
+ horizontal,
1840
+ needsOtherAxisSize: ctx.state.needsOtherAxisSize,
1841
+ otherAxisSize
1842
+ });
1843
+ const CustomScrollComponent = useStableRenderComponent(
1844
+ renderScrollComponent,
1845
+ (props, ref) => ({ ...props, ref })
1846
+ );
1847
+ const ScrollComponent = renderScrollComponent ? CustomScrollComponent : ListComponentScrollView;
1636
1848
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
1637
1849
  useLayoutEffect(() => {
1638
1850
  if (!ListHeaderComponent) {
@@ -1663,10 +1875,10 @@ var ListComponent = typedMemo(function ListComponent2({
1663
1875
  ...rest,
1664
1876
  ...ScrollComponent === ListComponentScrollView ? { useWindowScroll } : {},
1665
1877
  contentContainerStyle: [
1666
- contentContainerStyle,
1667
1878
  horizontal ? {
1668
1879
  height: "100%"
1669
- } : {}
1880
+ } : {},
1881
+ contentContainerStyle
1670
1882
  ],
1671
1883
  contentOffset: initialContentOffset !== void 0 ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
1672
1884
  horizontal,
@@ -1675,7 +1887,7 @@ var ListComponent = typedMemo(function ListComponent2({
1675
1887
  onScroll: onScroll2,
1676
1888
  ref: refScrollView,
1677
1889
  ScrollComponent: snapToIndices ? ScrollComponent : void 0,
1678
- style
1890
+ style: autoOtherAxisStyle ? [autoOtherAxisStyle, style] : style
1679
1891
  },
1680
1892
  /* @__PURE__ */ React3.createElement(ScrollAdjust, null),
1681
1893
  ListHeaderComponent && /* @__PURE__ */ React3.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
@@ -2392,7 +2604,8 @@ function doScrollTo(ctx, params) {
2392
2604
  }
2393
2605
  const isAnimated = !!animated;
2394
2606
  const isHorizontal = !!horizontal;
2395
- const left = isHorizontal ? offset : 0;
2607
+ const contentSize = isHorizontal ? getContentSize(ctx) : void 0;
2608
+ const left = isHorizontal ? toNativeHorizontalOffset(state, offset, contentSize) : 0;
2396
2609
  const top = isHorizontal ? 0 : offset;
2397
2610
  scroller.scrollTo({ animated: isAnimated, x: left, y: top });
2398
2611
  if (isAnimated) {
@@ -2991,11 +3204,51 @@ function getObservedBootstrapInitialScrollOffset(state) {
2991
3204
  const observedOffset = (_b = (_a3 = state.refScroller.current) == null ? void 0 : _a3.getCurrentScrollOffset) == null ? void 0 : _b.call(_a3);
2992
3205
  return typeof observedOffset === "number" && Number.isFinite(observedOffset) ? observedOffset : (_d = (_c = state.scrollPending) != null ? _c : state.scroll) != null ? _d : 0;
2993
3206
  }
3207
+ function getPreservedEndAnchorOffsetDiff(ctx) {
3208
+ var _a3;
3209
+ const state = ctx.state;
3210
+ const initialScroll = state.initialScroll;
3211
+ if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || !initialScroll || initialScroll.viewPosition !== 1 || state.props.data.length === 0 || isOffsetInitialScrollSession(state)) {
3212
+ return;
3213
+ }
3214
+ const currentOffset = typeof state.lastNativeScroll === "number" && Number.isFinite(state.lastNativeScroll) ? state.lastNativeScroll : getObservedBootstrapInitialScrollOffset(state);
3215
+ return resolveInitialScrollOffset(ctx, initialScroll) - currentOffset;
3216
+ }
3217
+ function schedulePreservedEndAnchorCorrection(ctx) {
3218
+ if (getPreservedEndAnchorOffsetDiff(ctx) === void 0) {
3219
+ return false;
3220
+ }
3221
+ const correction = {};
3222
+ schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
3223
+ return true;
3224
+ }
3225
+ function schedulePreservedEndAnchorCorrectionFrame(ctx, correction) {
3226
+ const state = ctx.state;
3227
+ state.preservedEndAnchorCorrection = correction;
3228
+ requestAnimationFrame(() => {
3229
+ var _a3;
3230
+ const activeCorrection = state.preservedEndAnchorCorrection;
3231
+ if (activeCorrection !== correction) {
3232
+ return;
3233
+ }
3234
+ const offsetDiff = getPreservedEndAnchorOffsetDiff(ctx);
3235
+ if (offsetDiff === void 0 || Math.abs(offsetDiff) <= DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
3236
+ state.preservedEndAnchorCorrection = void 0;
3237
+ return;
3238
+ }
3239
+ const hasObservedNativeScrollAfterRequest = !activeCorrection.lastRequestTime || ((_a3 = state.lastNativeScrollTime) != null ? _a3 : 0) > activeCorrection.lastRequestTime;
3240
+ if (hasObservedNativeScrollAfterRequest) {
3241
+ activeCorrection.lastRequestTime = Date.now();
3242
+ requestAdjust(ctx, offsetDiff);
3243
+ }
3244
+ schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
3245
+ });
3246
+ }
2994
3247
  function clearFinishedBootstrapInitialScrollTargetIfMovedAway(ctx) {
2995
3248
  var _a3, _b;
2996
3249
  const state = ctx.state;
2997
3250
  const initialScroll = state.initialScroll;
2998
- if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1) {
3251
+ if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1 || state.preservedEndAnchorCorrection) {
2999
3252
  return;
3000
3253
  }
3001
3254
  if (didFinishedInitialScrollMoveAwayFromTarget(ctx, initialScroll)) {
@@ -3152,7 +3405,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
3152
3405
  }
3153
3406
  }
3154
3407
  function handleBootstrapInitialScrollLayoutChange(ctx) {
3155
- var _a3, _b, _c, _d;
3408
+ var _a3, _b, _c;
3156
3409
  const state = ctx.state;
3157
3410
  const initialScroll = state.initialScroll;
3158
3411
  const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
@@ -3163,7 +3416,9 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
3163
3416
  const currentOffset = scrollingTo ? (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset : getObservedBootstrapInitialScrollOffset(state);
3164
3417
  const offsetDiff = resolvedOffset - currentOffset;
3165
3418
  if (Math.abs(offsetDiff) > DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
3166
- if (scrollingTo) {
3419
+ if (state.didFinishInitialScroll) {
3420
+ schedulePreservedEndAnchorCorrection(ctx);
3421
+ } else if (scrollingTo) {
3167
3422
  const existingWatchdog = initialScrollWatchdog.get(state);
3168
3423
  scrollingTo.offset = resolvedOffset;
3169
3424
  scrollingTo.targetOffset = resolvedOffset;
@@ -3176,15 +3431,9 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
3176
3431
  startScroll: (_c = existingWatchdog == null ? void 0 : existingWatchdog.startScroll) != null ? _c : state.scroll,
3177
3432
  targetOffset: resolvedOffset
3178
3433
  });
3179
- }
3180
- requestAdjust(ctx, offsetDiff);
3181
- if (state.didFinishInitialScroll) {
3182
- (_d = state.triggerCalculateItemsInView) == null ? void 0 : _d.call(state, { forceFullItemPositions: true });
3434
+ requestAdjust(ctx, offsetDiff);
3183
3435
  }
3184
3436
  }
3185
- if (state.didFinishInitialScroll) {
3186
- clearFinishedViewportRetargetableInitialScroll(state);
3187
- }
3188
3437
  } else {
3189
3438
  rearmBootstrapInitialScroll(ctx, {
3190
3439
  scroll: resolvedOffset,
@@ -3434,7 +3683,10 @@ function retargetActiveInitialScrollAtEnd(ctx) {
3434
3683
  var _a3;
3435
3684
  const state = ctx.state;
3436
3685
  const initialScroll = state.initialScroll;
3437
- if (!initialScroll || state.didFinishInitialScroll || ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || initialScroll.viewPosition !== 1 || state.props.data.length === 0) {
3686
+ if (state.didFinishInitialScroll) {
3687
+ return schedulePreservedEndAnchorCorrection(ctx);
3688
+ }
3689
+ if (!initialScroll || ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || initialScroll.viewPosition !== 1 || state.props.data.length === 0) {
3438
3690
  return false;
3439
3691
  }
3440
3692
  return advanceCurrentInitialScrollSession(ctx, { forceScroll: true });
@@ -3453,7 +3705,14 @@ function handleInitialScrollLayoutReady(ctx) {
3453
3705
  }
3454
3706
  function initializeInitialScrollOnMount(ctx, options) {
3455
3707
  var _a3, _b;
3456
- const { dataLength, hasFooterComponent, initialContentOffset, initialScrollAtEnd, useBootstrapInitialScroll } = options;
3708
+ const {
3709
+ alwaysDispatchInitialScroll,
3710
+ dataLength,
3711
+ hasFooterComponent,
3712
+ initialContentOffset,
3713
+ initialScrollAtEnd,
3714
+ useBootstrapInitialScroll
3715
+ } = options;
3457
3716
  const state = ctx.state;
3458
3717
  const initialScroll = state.initialScroll;
3459
3718
  const resolvedInitialContentOffset = initialContentOffset != null ? initialContentOffset : 0;
@@ -3473,7 +3732,7 @@ function initializeInitialScrollOnMount(ctx, options) {
3473
3732
  return;
3474
3733
  }
3475
3734
  const hasPendingDataDependentInitialScroll = !!initialScroll && dataLength === 0 && !(resolvedInitialContentOffset === 0 && !initialScrollAtEnd);
3476
- if (!resolvedInitialContentOffset && !hasPendingDataDependentInitialScroll) {
3735
+ if (!alwaysDispatchInitialScroll && !resolvedInitialContentOffset && !hasPendingDataDependentInitialScroll) {
3477
3736
  if (initialScroll && !initialScrollAtEnd) {
3478
3737
  finishInitialScroll(ctx, {
3479
3738
  resolvedOffset: resolvedInitialContentOffset
@@ -3794,9 +4053,18 @@ function prepareMVCP(ctx, dataChanged) {
3794
4053
  }
3795
4054
  }
3796
4055
 
4056
+ // src/core/resetLayoutCachesForDataChange.ts
4057
+ function resetLayoutCachesForDataChange(state) {
4058
+ state.indexByKey.clear();
4059
+ state.idCache.length = 0;
4060
+ state.positions.length = 0;
4061
+ state.columns.length = 0;
4062
+ state.columnSpans.length = 0;
4063
+ }
4064
+
3797
4065
  // src/core/syncMountedContainer.ts
3798
4066
  function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3799
- var _a3, _b, _c, _d, _e, _f, _g, _h;
4067
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i;
3800
4068
  const state = ctx.state;
3801
4069
  const {
3802
4070
  columns,
@@ -3808,7 +4076,8 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3808
4076
  if (item === void 0) {
3809
4077
  return { didChangePosition: false, didRefreshData: false };
3810
4078
  }
3811
- const updateLayout = (_a3 = options == null ? void 0 : options.updateLayout) != null ? _a3 : true;
4079
+ const itemKey = (_a3 = state.idCache[itemIndex]) != null ? _a3 : getId(state, itemIndex);
4080
+ const updateLayout = (_b = options == null ? void 0 : options.updateLayout) != null ? _b : true;
3812
4081
  let didChangePosition = false;
3813
4082
  let didRefreshData = false;
3814
4083
  if (updateLayout) {
@@ -3817,7 +4086,9 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3817
4086
  set$(ctx, `containerPosition${containerIndex}`, POSITION_OUT_OF_VIEW);
3818
4087
  return { didChangePosition: false, didRefreshData: false };
3819
4088
  }
3820
- const position = (positionValue || 0) - ((_b = options == null ? void 0 : options.scrollAdjustPending) != null ? _b : 0);
4089
+ const logicalPosition = (positionValue || 0) - ((_c = options == null ? void 0 : options.scrollAdjustPending) != null ? _c : 0);
4090
+ const itemSize = (_d = state.sizes.get(itemKey)) != null ? _d : getItemSize(ctx, itemKey, itemIndex, item);
4091
+ const position = toPhysicalHorizontalItemPosition(state, logicalPosition, itemSize, peek$(ctx, "totalSize"));
3821
4092
  const column = columns[itemIndex] || 1;
3822
4093
  const span = columnSpans[itemIndex] || 1;
3823
4094
  const prevPos = peek$(ctx, `containerPosition${containerIndex}`);
@@ -3836,15 +4107,15 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3836
4107
  }
3837
4108
  const prevData = peek$(ctx, `containerItemData${containerIndex}`);
3838
4109
  if (prevData !== item) {
3839
- 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;
3840
- const cachedComparison = (_e = pendingDataComparison == null ? void 0 : pendingDataComparison.byIndex[itemIndex]) != null ? _e : 0;
4110
+ 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;
4111
+ const cachedComparison = (_g = pendingDataComparison == null ? void 0 : pendingDataComparison.byIndex[itemIndex]) != null ? _g : 0;
3841
4112
  if (cachedComparison === 2) {
3842
4113
  set$(ctx, `containerItemData${containerIndex}`, item);
3843
4114
  didRefreshData = true;
3844
4115
  } else if (cachedComparison !== 1) {
3845
- const itemKey = (_g = (_f = peek$(ctx, `containerItemKey${containerIndex}`)) != null ? _f : state.idCache[itemIndex]) != null ? _g : getId(state, itemIndex);
4116
+ const nextItemKey = (_h = peek$(ctx, `containerItemKey${containerIndex}`)) != null ? _h : itemKey;
3846
4117
  const prevKey = keyExtractor == null ? void 0 : keyExtractor(prevData, itemIndex);
3847
- if (prevData === void 0 || !keyExtractor || prevKey !== itemKey) {
4118
+ if (prevData === void 0 || !keyExtractor || prevKey !== nextItemKey) {
3848
4119
  set$(ctx, `containerItemData${containerIndex}`, item);
3849
4120
  didRefreshData = true;
3850
4121
  } else if (!itemsAreEqual) {
@@ -3861,7 +4132,7 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3861
4132
  };
3862
4133
  }
3863
4134
  }
3864
- if ((_h = state.pendingDataComparison) == null ? void 0 : _h.byIndex) {
4135
+ if ((_i = state.pendingDataComparison) == null ? void 0 : _i.byIndex) {
3865
4136
  state.pendingDataComparison.byIndex[itemIndex] = isEqual ? 1 : 2;
3866
4137
  }
3867
4138
  if (!isEqual) {
@@ -4026,11 +4297,13 @@ function updateSnapToOffsets(ctx) {
4026
4297
  const {
4027
4298
  props: { snapToIndices }
4028
4299
  } = state;
4300
+ const contentSize = state.props.horizontal ? getContentSize(ctx) : void 0;
4029
4301
  const snapToOffsets = Array(snapToIndices.length);
4030
4302
  for (let i = 0; i < snapToIndices.length; i++) {
4031
4303
  const idx = snapToIndices[i];
4032
4304
  getId(state, idx);
4033
- snapToOffsets[i] = state.positions[idx];
4305
+ const logicalOffset = state.positions[idx];
4306
+ snapToOffsets[i] = toNativeHorizontalOffset(state, logicalOffset, contentSize);
4034
4307
  }
4035
4308
  set$(ctx, "snapToOffsets", snapToOffsets);
4036
4309
  }
@@ -4639,7 +4912,6 @@ function calculateItemsInView(ctx, params = {}) {
4639
4912
  var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
4640
4913
  const {
4641
4914
  columns,
4642
- columnSpans,
4643
4915
  containerItemKeys,
4644
4916
  enableScrollForNextCalculateItemsInView,
4645
4917
  idCache,
@@ -4689,8 +4961,10 @@ function calculateItemsInView(ctx, params = {}) {
4689
4961
  let scrollTopBuffered = 0;
4690
4962
  let scrollBottom = 0;
4691
4963
  let scrollBottomBuffered = 0;
4964
+ let nativeScrollState = scrollState;
4692
4965
  const updateScroll2 = (nextScrollState) => {
4693
4966
  var _a4;
4967
+ nativeScrollState = nextScrollState;
4694
4968
  scrollAdjustPending = (_a4 = peek$(ctx, "scrollAdjustPending")) != null ? _a4 : 0;
4695
4969
  scrollAdjustPad = scrollAdjustPending - topPad;
4696
4970
  scroll = Math.round(nextScrollState + scrollExtra + scrollAdjustPad);
@@ -4702,9 +4976,17 @@ function calculateItemsInView(ctx, params = {}) {
4702
4976
  const previousStickyIndex = peek$(ctx, "activeStickyIndex");
4703
4977
  const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
4704
4978
  const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : -1;
4979
+ const stickyIndexDidChange = previousStickyIndex !== nextActiveStickyIndex;
4705
4980
  if (currentStickyIdx >= 0 || previousStickyIndex >= 0) {
4706
4981
  set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
4707
4982
  }
4983
+ const shouldNotifyStickyHeaderChange = !!onStickyHeaderChange && stickyIndicesArr.length > 0 && stickyIndexDidChange;
4984
+ const finishCalculateItemsInView = shouldNotifyStickyHeaderChange ? () => {
4985
+ const item = data[nextActiveStickyIndex];
4986
+ if (item !== void 0) {
4987
+ onStickyHeaderChange == null ? void 0 : onStickyHeaderChange({ index: nextActiveStickyIndex, item });
4988
+ }
4989
+ } : void 0;
4708
4990
  let scrollBufferTop = drawDistance;
4709
4991
  let scrollBufferBottom = drawDistance;
4710
4992
  if (speed > 0 || speed === 0 && scroll < Math.max(50, drawDistance)) {
@@ -4715,8 +4997,10 @@ function calculateItemsInView(ctx, params = {}) {
4715
4997
  scrollBufferBottom = drawDistance * 0.5;
4716
4998
  }
4717
4999
  const updateScrollRange = () => {
4718
- scrollTopBuffered = scroll - scrollBufferTop;
4719
- scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
5000
+ const scrollStart = Math.max(0, scroll);
5001
+ const overscrollBeforeContent = Math.max(0, -nativeScrollState);
5002
+ scrollTopBuffered = scrollStart - scrollBufferTop;
5003
+ scrollBottom = Math.max(scrollStart, scroll + scrollLength + overscrollBeforeContent);
4720
5004
  scrollBottomBuffered = scrollBottom + scrollBufferBottom;
4721
5005
  };
4722
5006
  updateScrollRange();
@@ -4726,17 +5010,14 @@ function calculateItemsInView(ctx, params = {}) {
4726
5010
  state.scrollForNextCalculateItemsInView = void 0;
4727
5011
  } else if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
4728
5012
  if (!isInMVCPActiveMode(state)) {
5013
+ finishCalculateItemsInView == null ? void 0 : finishCalculateItemsInView();
4729
5014
  return;
4730
5015
  }
4731
5016
  }
4732
5017
  }
4733
5018
  const checkMVCP = doMVCP && !suppressInitialScrollSideEffects ? prepareMVCP(ctx, dataChanged) : void 0;
4734
5019
  if (dataChanged) {
4735
- indexByKey.clear();
4736
- idCache.length = 0;
4737
- positions.length = 0;
4738
- columns.length = 0;
4739
- columnSpans.length = 0;
5020
+ resetLayoutCachesForDataChange(state);
4740
5021
  }
4741
5022
  const startIndex = forceFullItemPositions || dataChanged ? 0 : (_c = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _c : 0;
4742
5023
  const optimizeForVisibleWindow = !forceFullItemPositions && !dataChanged && numColumns > 1 && minIndexSizeChanged !== void 0;
@@ -5050,12 +5331,7 @@ function calculateItemsInView(ctx, params = {}) {
5050
5331
  );
5051
5332
  }
5052
5333
  }
5053
- if (onStickyHeaderChange && stickyIndicesArr.length > 0 && nextActiveStickyIndex !== void 0 && nextActiveStickyIndex !== previousStickyIndex) {
5054
- const item = data[nextActiveStickyIndex];
5055
- if (item !== void 0) {
5056
- onStickyHeaderChange({ index: nextActiveStickyIndex, item });
5057
- }
5058
- }
5334
+ finishCalculateItemsInView == null ? void 0 : finishCalculateItemsInView();
5059
5335
  });
5060
5336
  }
5061
5337
 
@@ -5083,11 +5359,22 @@ function doMaintainScrollAtEnd(ctx) {
5083
5359
  if (!state.maintainingScrollAtEnd) {
5084
5360
  state.maintainingScrollAtEnd = true;
5085
5361
  requestAnimationFrame(() => {
5086
- var _a3;
5087
5362
  if (peek$(ctx, "isWithinMaintainScrollAtEndThreshold")) {
5088
- (_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
5089
- animated: maintainScrollAtEnd.animated
5090
- });
5363
+ const scroller = refScroller.current;
5364
+ if (state.props.horizontal && isHorizontalRTL(state)) {
5365
+ const currentContentSize = getContentSize(ctx);
5366
+ const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
5367
+ const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
5368
+ scroller == null ? void 0 : scroller.scrollTo({
5369
+ animated: maintainScrollAtEnd.animated,
5370
+ x: nativeOffset,
5371
+ y: 0
5372
+ });
5373
+ } else {
5374
+ scroller == null ? void 0 : scroller.scrollToEnd({
5375
+ animated: maintainScrollAtEnd.animated
5376
+ });
5377
+ }
5091
5378
  setTimeout(
5092
5379
  () => {
5093
5380
  state.maintainingScrollAtEnd = false;
@@ -5287,7 +5574,8 @@ function handleLayout(ctx, layoutParam, setCanRender) {
5287
5574
  }
5288
5575
  checkThresholds(ctx);
5289
5576
  if (state) {
5290
- state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
5577
+ const crossAxisPadding = state.props.horizontal ? (state.props.stylePaddingTop || 0) + (state.props.stylePaddingBottom || 0) : (state.props.stylePaddingLeft || 0) + (state.props.stylePaddingRight || 0);
5578
+ state.needsOtherAxisSize = otherAxisSize - crossAxisPadding < 10;
5291
5579
  }
5292
5580
  if (IS_DEV && measuredLength === 0) {
5293
5581
  warnDevOnce(
@@ -5401,7 +5689,7 @@ function cloneScrollEvent(event) {
5401
5689
  };
5402
5690
  }
5403
5691
  function onScroll(ctx, event) {
5404
- var _a3, _b, _c, _d;
5692
+ var _a3, _b, _c, _d, _e, _f;
5405
5693
  const state = ctx.state;
5406
5694
  const { scrollProcessingEnabled } = state;
5407
5695
  if (scrollProcessingEnabled === false) {
@@ -5420,6 +5708,12 @@ function onScroll(ctx, event) {
5420
5708
  }
5421
5709
  }
5422
5710
  let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
5711
+ if (state.props.horizontal) {
5712
+ newScroll = toLogicalHorizontalOffset(state, newScroll, (_e = event.nativeEvent.contentSize) == null ? void 0 : _e.width);
5713
+ }
5714
+ state.didFinishInitialScroll && ((_f = state.initialScroll) == null ? void 0 : _f.viewPosition) === 1 && state.scroll > state.scrollLength;
5715
+ state.lastNativeScroll = newScroll;
5716
+ state.lastNativeScrollTime = Date.now();
5423
5717
  if (state.scrollingTo && state.scrollingTo.offset >= newScroll) {
5424
5718
  const maxOffset = clampScrollOffset(ctx, newScroll, state.scrollingTo);
5425
5719
  if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
@@ -5591,6 +5885,16 @@ function runOrScheduleMVCPRecalculate(ctx) {
5591
5885
  });
5592
5886
  }
5593
5887
  }
5888
+ function updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal) {
5889
+ const state = ctx.state;
5890
+ if (state.needsOtherAxisSize) {
5891
+ const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
5892
+ const currentOtherAxisSize = peek$(ctx, "otherAxisSize");
5893
+ if (!currentOtherAxisSize || otherAxisSize > currentOtherAxisSize) {
5894
+ set$(ctx, "otherAxisSize", otherAxisSize);
5895
+ }
5896
+ }
5897
+ }
5594
5898
  function updateItemSize(ctx, itemKey, sizeObj) {
5595
5899
  var _a3;
5596
5900
  const state = ctx.state;
@@ -5614,13 +5918,13 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5614
5918
  const type = getItemType ? (_a3 = getItemType(itemData, index)) != null ? _a3 : "" : "";
5615
5919
  const size2 = getFixedItemSize(itemData, index, type);
5616
5920
  if (size2 !== void 0 && size2 === sizesKnown.get(itemKey)) {
5921
+ updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal);
5617
5922
  return;
5618
5923
  }
5619
5924
  }
5620
5925
  let needsRecalculate = !didContainersLayout;
5621
5926
  let shouldMaintainScrollAtEnd = false;
5622
5927
  let minIndexSizeChanged;
5623
- let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
5624
5928
  const prevSizeKnown = state.sizesKnown.get(itemKey);
5625
5929
  const diff = updateOneItemSize(ctx, itemKey, sizeObj);
5626
5930
  const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
@@ -5631,10 +5935,6 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5631
5935
  if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
5632
5936
  needsRecalculate = true;
5633
5937
  }
5634
- if (state.needsOtherAxisSize) {
5635
- const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
5636
- maxOtherAxisSize = Math.max(maxOtherAxisSize, otherAxisSize);
5637
- }
5638
5938
  if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
5639
5939
  shouldMaintainScrollAtEnd = true;
5640
5940
  }
@@ -5650,10 +5950,7 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5650
5950
  if (minIndexSizeChanged !== void 0) {
5651
5951
  state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, minIndexSizeChanged) : minIndexSizeChanged;
5652
5952
  }
5653
- const cur = peek$(ctx, "otherAxisSize");
5654
- if (!cur || maxOtherAxisSize > cur) {
5655
- set$(ctx, "otherAxisSize", maxOtherAxisSize);
5656
- }
5953
+ updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal);
5657
5954
  if (didContainersLayout || checkAllSizesKnown(state, getMountedBufferedIndices(state))) {
5658
5955
  if (needsRecalculate) {
5659
5956
  state.scrollForNextCalculateItemsInView = void 0;
@@ -6042,6 +6339,8 @@ function getAlwaysRenderIndices(config, data, keyExtractor, anchoredEndSpaceAnch
6042
6339
  indices.sort(sortAsc);
6043
6340
  return indices;
6044
6341
  }
6342
+
6343
+ // src/utils/getRenderedItem.ts
6045
6344
  function getRenderedItem(ctx, key) {
6046
6345
  var _a3;
6047
6346
  const state = ctx.state;
@@ -6067,7 +6366,7 @@ function getRenderedItem(ctx, key) {
6067
6366
  item,
6068
6367
  type: getItemType ? (_a3 = getItemType(item, index)) != null ? _a3 : "" : ""
6069
6368
  };
6070
- renderedItem = React3__default.createElement(renderItem, itemProps);
6369
+ renderedItem = renderItem(itemProps);
6071
6370
  }
6072
6371
  return { index, item: data[index], renderedItem };
6073
6372
  }
@@ -6228,7 +6527,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6228
6527
  getFixedItemSize,
6229
6528
  getItemType,
6230
6529
  horizontal,
6530
+ rtl,
6231
6531
  initialContainerPoolRatio = 3,
6532
+ estimatedHeaderSize,
6232
6533
  initialScrollAtEnd = false,
6233
6534
  initialScrollIndex: initialScrollIndexProp,
6234
6535
  initialScrollOffset: initialScrollOffsetProp,
@@ -6296,13 +6597,16 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6296
6597
  const style = { ...StyleSheet.flatten(styleProp) };
6297
6598
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
6298
6599
  const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
6600
+ const stylePaddingLeftState = extractPadding(style, contentContainerStyle, "Left");
6601
+ const stylePaddingRightState = extractPadding(style, contentContainerStyle, "Right");
6299
6602
  const maintainScrollAtEndConfig = normalizeMaintainScrollAtEnd(maintainScrollAtEnd);
6300
6603
  const maintainVisibleContentPositionConfig = normalizeMaintainVisibleContentPosition(
6301
6604
  maintainVisibleContentPositionProp
6302
6605
  );
6303
6606
  const hasInitialScrollIndex = initialScrollIndexProp !== void 0 && initialScrollIndexProp !== null;
6304
6607
  const hasInitialScrollOffset = initialScrollOffsetProp !== void 0 && initialScrollOffsetProp !== null;
6305
- const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && hasInitialScrollOffset;
6608
+ const shouldInitializeHorizontalRTL = !initialScrollAtEnd && !hasInitialScrollIndex && !hasInitialScrollOffset && isHorizontalRTLProps({ horizontal, rtl });
6609
+ const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && (hasInitialScrollOffset || shouldInitializeHorizontalRTL);
6306
6610
  const usesBootstrapInitialScroll = initialScrollAtEnd || hasInitialScrollIndex;
6307
6611
  const initialScrollProp = initialScrollAtEnd ? {
6308
6612
  index: Math.max(0, dataProp.length - 1),
@@ -6418,6 +6722,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6418
6722
  internalState.reprocessCurrentScroll = () => updateScroll(ctx, internalState.scroll, true);
6419
6723
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
6420
6724
  set$(ctx, "extraData", extraData);
6725
+ if (estimatedHeaderSize !== void 0) {
6726
+ set$(ctx, "headerSize", estimatedHeaderSize);
6727
+ }
6421
6728
  }
6422
6729
  refState.current = ctx.state;
6423
6730
  }
@@ -6477,11 +6784,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6477
6784
  positionComponentInternal,
6478
6785
  recycleItems: !!recycleItems,
6479
6786
  renderItem,
6787
+ rtl,
6480
6788
  snapToIndices,
6481
6789
  stickyIndicesArr: stickyHeaderIndices != null ? stickyHeaderIndices : [],
6482
6790
  stickyIndicesSet: useMemo(() => new Set(stickyHeaderIndices != null ? stickyHeaderIndices : []), [stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.join(",")]),
6483
6791
  stickyPositionComponentInternal,
6484
6792
  stylePaddingBottom: stylePaddingBottomState,
6793
+ stylePaddingLeft: stylePaddingLeftState,
6794
+ stylePaddingRight: stylePaddingRightState,
6485
6795
  stylePaddingTop: stylePaddingTopState,
6486
6796
  useWindowScroll: useWindowScrollResolved
6487
6797
  };
@@ -6504,6 +6814,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6504
6814
  };
6505
6815
  if (isFirstLocal) {
6506
6816
  initializeStateVars(false);
6817
+ resetLayoutCachesForDataChange(state);
6507
6818
  updateItemPositions(
6508
6819
  ctx,
6509
6820
  /*dataChanged*/
@@ -6521,6 +6832,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6521
6832
  }, [usesBootstrapInitialScroll]);
6522
6833
  useLayoutEffect(() => {
6523
6834
  initializeInitialScrollOnMount(ctx, {
6835
+ alwaysDispatchInitialScroll: shouldInitializeHorizontalRTL,
6524
6836
  dataLength: dataProp.length,
6525
6837
  hasFooterComponent: !!ListFooterComponent,
6526
6838
  initialContentOffset,