@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.
@@ -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
  });
@@ -646,12 +781,6 @@ function toLayout(rect) {
646
781
  };
647
782
  }
648
783
 
649
- // src/platform/Platform.ts
650
- var Platform = {
651
- // Widen the type to avoid unreachable-branch lints in cross-platform code that compares against other OSes
652
- OS: "web"
653
- };
654
-
655
784
  // src/utils/hasActiveMVCPAnchorLock.ts
656
785
  function hasActiveMVCPAnchorLock(state) {
657
786
  const lock = state.mvcpAnchorLock;
@@ -675,6 +804,7 @@ function getContainerPositionStyle({
675
804
  columnWrapperStyle,
676
805
  horizontal,
677
806
  hasItemSeparator,
807
+ isHorizontalRTLList,
678
808
  numColumns,
679
809
  otherAxisPos,
680
810
  otherAxisSize
@@ -698,6 +828,7 @@ function getContainerPositionStyle({
698
828
  }
699
829
  return horizontal ? {
700
830
  boxSizing: paddingStyles ? "border-box" : void 0,
831
+ direction: isHorizontalRTLList && Platform.OS === "web" ? "ltr" : void 0,
701
832
  flexDirection: hasItemSeparator ? "row" : void 0,
702
833
  height: otherAxisSize,
703
834
  left: 0,
@@ -726,6 +857,7 @@ var Container = typedMemo(function Container2({
726
857
  }) {
727
858
  const ctx = useStateContext();
728
859
  const { columnWrapperStyle, animatedScrollY } = ctx;
860
+ const isHorizontalRTLList = isHorizontalRTL(ctx.state);
729
861
  const positionComponentInternal = ctx.state.props.positionComponentInternal;
730
862
  const stickyPositionComponentInternal = ctx.state.props.stickyPositionComponentInternal;
731
863
  const [column = 0, span = 1, data, numColumns = 1, extraData, isSticky] = useArr$([
@@ -757,11 +889,20 @@ var Container = typedMemo(function Container2({
757
889
  columnWrapperStyle,
758
890
  hasItemSeparator: !!ItemSeparatorComponent,
759
891
  horizontal,
892
+ isHorizontalRTLList,
760
893
  numColumns,
761
894
  otherAxisPos,
762
895
  otherAxisSize
763
896
  }),
764
- [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns, ItemSeparatorComponent]
897
+ [
898
+ horizontal,
899
+ isHorizontalRTLList,
900
+ otherAxisPos,
901
+ otherAxisSize,
902
+ columnWrapperStyle,
903
+ numColumns,
904
+ ItemSeparatorComponent
905
+ ]
765
906
  );
766
907
  const renderedItemInfo = useMemo(
767
908
  () => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
@@ -1001,9 +1142,16 @@ var ContainersInner = typedMemo(function ContainersInner2({ horizontal, numColum
1001
1142
  const ref = useRef(null);
1002
1143
  const ctx = useStateContext();
1003
1144
  const columnWrapperStyle = ctx.columnWrapperStyle;
1145
+ const isHorizontalRTLList = isHorizontalRTL(ctx.state);
1004
1146
  const [otherAxisSize, readyToRender, totalSize] = useArr$(["otherAxisSize", "readyToRender", "totalSize"]);
1005
1147
  useDOMOrder(ref);
1006
- const style = horizontal ? { minHeight: otherAxisSize, opacity: readyToRender ? 1 : 0, position: "relative", width: totalSize } : { height: totalSize, minWidth: otherAxisSize, opacity: readyToRender ? 1 : 0, position: "relative" };
1148
+ const style = horizontal ? {
1149
+ direction: isHorizontalRTLList ? "ltr" : void 0,
1150
+ minHeight: otherAxisSize,
1151
+ opacity: readyToRender ? 1 : 0,
1152
+ position: "relative",
1153
+ width: totalSize
1154
+ } : { height: totalSize, minWidth: otherAxisSize, opacity: readyToRender ? 1 : 0, position: "relative" };
1007
1155
  if (!readyToRender) {
1008
1156
  style.pointerEvents = "none";
1009
1157
  }
@@ -1067,10 +1215,16 @@ var StyleSheet = {
1067
1215
  create: (styles) => styles,
1068
1216
  flatten: (style) => flattenStyles(style)
1069
1217
  };
1218
+ function useLatestRef(value) {
1219
+ const ref = React3.useRef(value);
1220
+ ref.current = value;
1221
+ return ref;
1222
+ }
1223
+
1224
+ // src/utils/useRafCoalescer.ts
1070
1225
  function useRafCoalescer(callback) {
1071
- const callbackRef = useRef(callback);
1226
+ const callbackRef = useLatestRef(callback);
1072
1227
  const rafIdRef = useRef(void 0);
1073
- callbackRef.current = callback;
1074
1228
  const coalescer = useMemo(
1075
1229
  () => ({
1076
1230
  cancel() {
@@ -1214,6 +1368,31 @@ function getContentInsetEndAdjustmentEnd2(ctx) {
1214
1368
  const adjustment = (_b = (_a3 = ctx.state) == null ? void 0 : _a3.props) == null ? void 0 : _b.contentInsetEndAdjustment;
1215
1369
  return Math.max(0, adjustment != null ? adjustment : 0);
1216
1370
  }
1371
+ function getFiniteSnapOffsets(snapToOffsets) {
1372
+ if (!(snapToOffsets == null ? void 0 : snapToOffsets.length)) {
1373
+ return [];
1374
+ }
1375
+ const snapOffsets = [];
1376
+ const seen = /* @__PURE__ */ new Set();
1377
+ for (const offset of snapToOffsets) {
1378
+ if (Number.isFinite(offset) && !seen.has(offset)) {
1379
+ seen.add(offset);
1380
+ snapOffsets.push(offset);
1381
+ }
1382
+ }
1383
+ return snapOffsets;
1384
+ }
1385
+ function getSnapAnchorStyle(offset, horizontal) {
1386
+ return {
1387
+ height: horizontal ? "100%" : 1,
1388
+ left: horizontal ? offset : 0,
1389
+ pointerEvents: "none",
1390
+ position: "absolute",
1391
+ scrollSnapAlign: "start",
1392
+ top: horizontal ? 0 : offset,
1393
+ width: horizontal ? 1 : "100%"
1394
+ };
1395
+ }
1217
1396
  var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
1218
1397
  children,
1219
1398
  style,
@@ -1231,7 +1410,7 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
1231
1410
  onLayout,
1232
1411
  ...props
1233
1412
  }, ref) {
1234
- var _a3, _b, _c;
1413
+ var _a3, _b, _c, _d;
1235
1414
  const ctx = useStateContext();
1236
1415
  const [anchoredEndSpaceSize] = useArr$(["anchoredEndSpaceSize"]);
1237
1416
  const scrollRef = useRef(null);
@@ -1446,10 +1625,16 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
1446
1625
  contentInset: _contentInset,
1447
1626
  scrollEventThrottle: _scrollEventThrottle,
1448
1627
  ScrollComponent: _ScrollComponent,
1628
+ snapToOffsets,
1449
1629
  useWindowScroll: _useWindowScroll,
1450
1630
  className: scrollViewClassNameProp,
1451
1631
  ...webProps
1452
1632
  } = props;
1633
+ const snapOffsets = !isWindowScroll ? getFiniteSnapOffsets(snapToOffsets) : [];
1634
+ if (snapOffsets.length > 0) {
1635
+ scrollViewStyle.scrollSnapType = horizontal ? "x mandatory" : "y mandatory";
1636
+ contentStyle.position = (_d = contentStyle.position) != null ? _d : "relative";
1637
+ }
1453
1638
  const scrollViewClassName = hiddenScrollIndicatorClassName ? scrollViewClassNameProp ? `${scrollViewClassNameProp} ${hiddenScrollIndicatorClassName}` : hiddenScrollIndicatorClassName : scrollViewClassNameProp;
1454
1639
  if (IS_DEV) {
1455
1640
  if (/(?:^|\s)(?:[a-z0-9_-]+:)*gap(?:-[xy])?-(?:\[[^\]]+\]|[^\s]+)/.test(
@@ -1470,9 +1655,29 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
1470
1655
  style: scrollViewStyle
1471
1656
  },
1472
1657
  refreshControl,
1473
- /* @__PURE__ */ React3.createElement("div", { className, ref: contentRef, style: contentStyle }, children, contentInsetEndAdjustmentSpacerStyle ? /* @__PURE__ */ React3.createElement("div", { "aria-hidden": true, style: contentInsetEndAdjustmentSpacerStyle }) : null)
1658
+ /* @__PURE__ */ React3.createElement("div", { className, ref: contentRef, style: contentStyle }, snapOffsets.map((offset) => /* @__PURE__ */ React3.createElement(
1659
+ "div",
1660
+ {
1661
+ "aria-hidden": true,
1662
+ "data-legend-list-snap-anchor": offset,
1663
+ key: `snap-${offset}`,
1664
+ style: getSnapAnchorStyle(offset, horizontal)
1665
+ }
1666
+ )), children, contentInsetEndAdjustmentSpacerStyle ? /* @__PURE__ */ React3.createElement("div", { "aria-hidden": true, style: contentInsetEndAdjustmentSpacerStyle }) : null)
1474
1667
  );
1475
1668
  });
1669
+
1670
+ // src/components/listComponentStyles.ts
1671
+ function getAutoOtherAxisStyle({
1672
+ horizontal,
1673
+ needsOtherAxisSize,
1674
+ otherAxisSize
1675
+ }) {
1676
+ if (!needsOtherAxisSize || !otherAxisSize || otherAxisSize <= 0) {
1677
+ return void 0;
1678
+ }
1679
+ return horizontal ? { height: otherAxisSize } : { width: otherAxisSize };
1680
+ }
1476
1681
  function useValueListener$(key, callback) {
1477
1682
  const ctx = useStateContext();
1478
1683
  useLayoutEffect(() => {
@@ -1567,10 +1772,10 @@ function ScrollAdjust() {
1567
1772
  useValueListener$("scrollAdjustUserOffset", callback);
1568
1773
  return null;
1569
1774
  }
1570
- function SnapWrapper({ ScrollComponent, ...props }) {
1775
+ var SnapWrapper = React3.forwardRef(function SnapWrapperInner({ ScrollComponent, ...props }, ref) {
1571
1776
  const [snapToOffsets] = useArr$(["snapToOffsets"]);
1572
- return /* @__PURE__ */ React3.createElement(ScrollComponent, { ...props, snapToOffsets });
1573
- }
1777
+ return /* @__PURE__ */ React3.createElement(ScrollComponent, { ...props, ref, snapToOffsets });
1778
+ });
1574
1779
  function WebAnchoredEndSpace({ horizontal }) {
1575
1780
  const ctx = useStateContext();
1576
1781
  const [anchoredEndSpaceSize] = useArr$(["anchoredEndSpaceSize"]);
@@ -1581,21 +1786,25 @@ function WebAnchoredEndSpace({ horizontal }) {
1581
1786
  const style = horizontal ? { height: "100%", width: anchoredEndSpaceSize || 0 } : { height: anchoredEndSpaceSize || 0 };
1582
1787
  return /* @__PURE__ */ React3.createElement("div", { style }, null);
1583
1788
  }
1789
+ function useStableRenderComponent(renderComponent, mapProps) {
1790
+ const renderComponentRef = useLatestRef(renderComponent);
1791
+ const mapPropsRef = useLatestRef(mapProps);
1792
+ return React3.useMemo(
1793
+ () => React3.forwardRef(
1794
+ (props, ref) => {
1795
+ var _a3, _b;
1796
+ return (_b = (_a3 = renderComponentRef.current) == null ? void 0 : _a3.call(renderComponentRef, mapPropsRef.current(props, ref))) != null ? _b : null;
1797
+ }
1798
+ ),
1799
+ [mapPropsRef, renderComponentRef]
1800
+ );
1801
+ }
1584
1802
  var LayoutView = ({ onLayoutChange, refView, children, ...rest }) => {
1585
1803
  const localRef = useRef(null);
1586
1804
  const ref = refView != null ? refView : localRef;
1587
1805
  useOnLayoutSync({ onLayoutChange, ref });
1588
1806
  return /* @__PURE__ */ React3.createElement("div", { ...rest, ref }, children);
1589
1807
  };
1590
- var getComponent = (Component) => {
1591
- if (React3.isValidElement(Component)) {
1592
- return Component;
1593
- }
1594
- if (Component) {
1595
- return /* @__PURE__ */ React3.createElement(Component, null);
1596
- }
1597
- return null;
1598
- };
1599
1808
 
1600
1809
  // src/components/ListComponent.tsx
1601
1810
  var ListComponent = typedMemo(function ListComponent2({
@@ -1628,14 +1837,17 @@ var ListComponent = typedMemo(function ListComponent2({
1628
1837
  }) {
1629
1838
  const ctx = useStateContext();
1630
1839
  const maintainVisibleContentPosition = ctx.state.props.maintainVisibleContentPosition;
1631
- const ScrollComponent = useMemo(() => {
1632
- if (!renderScrollComponent) {
1633
- return ListComponentScrollView;
1634
- }
1635
- return React3.forwardRef(
1636
- (props, ref) => renderScrollComponent({ ...props, ref })
1637
- );
1638
- }, [renderScrollComponent]);
1840
+ const [otherAxisSize = 0] = useArr$(["otherAxisSize"]);
1841
+ const autoOtherAxisStyle = getAutoOtherAxisStyle({
1842
+ horizontal,
1843
+ needsOtherAxisSize: ctx.state.needsOtherAxisSize,
1844
+ otherAxisSize
1845
+ });
1846
+ const CustomScrollComponent = useStableRenderComponent(
1847
+ renderScrollComponent,
1848
+ (props, ref) => ({ ...props, ref })
1849
+ );
1850
+ const ScrollComponent = renderScrollComponent ? CustomScrollComponent : ListComponentScrollView;
1639
1851
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
1640
1852
  useLayoutEffect(() => {
1641
1853
  if (!ListHeaderComponent) {
@@ -1666,10 +1878,10 @@ var ListComponent = typedMemo(function ListComponent2({
1666
1878
  ...rest,
1667
1879
  ...ScrollComponent === ListComponentScrollView ? { useWindowScroll } : {},
1668
1880
  contentContainerStyle: [
1669
- contentContainerStyle,
1670
1881
  horizontal ? {
1671
1882
  height: "100%"
1672
- } : {}
1883
+ } : {},
1884
+ contentContainerStyle
1673
1885
  ],
1674
1886
  contentOffset: initialContentOffset !== void 0 ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
1675
1887
  horizontal,
@@ -1678,7 +1890,7 @@ var ListComponent = typedMemo(function ListComponent2({
1678
1890
  onScroll: onScroll2,
1679
1891
  ref: refScrollView,
1680
1892
  ScrollComponent: snapToIndices ? ScrollComponent : void 0,
1681
- style
1893
+ style: autoOtherAxisStyle ? [autoOtherAxisStyle, style] : style
1682
1894
  },
1683
1895
  /* @__PURE__ */ React3.createElement(ScrollAdjust, null),
1684
1896
  ListHeaderComponent && /* @__PURE__ */ React3.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
@@ -2395,7 +2607,8 @@ function doScrollTo(ctx, params) {
2395
2607
  }
2396
2608
  const isAnimated = !!animated;
2397
2609
  const isHorizontal = !!horizontal;
2398
- const left = isHorizontal ? offset : 0;
2610
+ const contentSize = isHorizontal ? getContentSize(ctx) : void 0;
2611
+ const left = isHorizontal ? toNativeHorizontalOffset(state, offset, contentSize) : 0;
2399
2612
  const top = isHorizontal ? 0 : offset;
2400
2613
  scroller.scrollTo({ animated: isAnimated, x: left, y: top });
2401
2614
  if (isAnimated) {
@@ -2994,11 +3207,51 @@ function getObservedBootstrapInitialScrollOffset(state) {
2994
3207
  const observedOffset = (_b = (_a3 = state.refScroller.current) == null ? void 0 : _a3.getCurrentScrollOffset) == null ? void 0 : _b.call(_a3);
2995
3208
  return typeof observedOffset === "number" && Number.isFinite(observedOffset) ? observedOffset : (_d = (_c = state.scrollPending) != null ? _c : state.scroll) != null ? _d : 0;
2996
3209
  }
3210
+ function getPreservedEndAnchorOffsetDiff(ctx) {
3211
+ var _a3;
3212
+ const state = ctx.state;
3213
+ const initialScroll = state.initialScroll;
3214
+ if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || !initialScroll || initialScroll.viewPosition !== 1 || state.props.data.length === 0 || isOffsetInitialScrollSession(state)) {
3215
+ return;
3216
+ }
3217
+ const currentOffset = typeof state.lastNativeScroll === "number" && Number.isFinite(state.lastNativeScroll) ? state.lastNativeScroll : getObservedBootstrapInitialScrollOffset(state);
3218
+ return resolveInitialScrollOffset(ctx, initialScroll) - currentOffset;
3219
+ }
3220
+ function schedulePreservedEndAnchorCorrection(ctx) {
3221
+ if (getPreservedEndAnchorOffsetDiff(ctx) === void 0) {
3222
+ return false;
3223
+ }
3224
+ const correction = {};
3225
+ schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
3226
+ return true;
3227
+ }
3228
+ function schedulePreservedEndAnchorCorrectionFrame(ctx, correction) {
3229
+ const state = ctx.state;
3230
+ state.preservedEndAnchorCorrection = correction;
3231
+ requestAnimationFrame(() => {
3232
+ var _a3;
3233
+ const activeCorrection = state.preservedEndAnchorCorrection;
3234
+ if (activeCorrection !== correction) {
3235
+ return;
3236
+ }
3237
+ const offsetDiff = getPreservedEndAnchorOffsetDiff(ctx);
3238
+ if (offsetDiff === void 0 || Math.abs(offsetDiff) <= DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
3239
+ state.preservedEndAnchorCorrection = void 0;
3240
+ return;
3241
+ }
3242
+ const hasObservedNativeScrollAfterRequest = !activeCorrection.lastRequestTime || ((_a3 = state.lastNativeScrollTime) != null ? _a3 : 0) > activeCorrection.lastRequestTime;
3243
+ if (hasObservedNativeScrollAfterRequest) {
3244
+ activeCorrection.lastRequestTime = Date.now();
3245
+ requestAdjust(ctx, offsetDiff);
3246
+ }
3247
+ schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
3248
+ });
3249
+ }
2997
3250
  function clearFinishedBootstrapInitialScrollTargetIfMovedAway(ctx) {
2998
3251
  var _a3, _b;
2999
3252
  const state = ctx.state;
3000
3253
  const initialScroll = state.initialScroll;
3001
- if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1) {
3254
+ if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1 || state.preservedEndAnchorCorrection) {
3002
3255
  return;
3003
3256
  }
3004
3257
  if (didFinishedInitialScrollMoveAwayFromTarget(ctx, initialScroll)) {
@@ -3155,7 +3408,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
3155
3408
  }
3156
3409
  }
3157
3410
  function handleBootstrapInitialScrollLayoutChange(ctx) {
3158
- var _a3, _b, _c, _d;
3411
+ var _a3, _b, _c;
3159
3412
  const state = ctx.state;
3160
3413
  const initialScroll = state.initialScroll;
3161
3414
  const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
@@ -3166,7 +3419,9 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
3166
3419
  const currentOffset = scrollingTo ? (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset : getObservedBootstrapInitialScrollOffset(state);
3167
3420
  const offsetDiff = resolvedOffset - currentOffset;
3168
3421
  if (Math.abs(offsetDiff) > DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
3169
- if (scrollingTo) {
3422
+ if (state.didFinishInitialScroll) {
3423
+ schedulePreservedEndAnchorCorrection(ctx);
3424
+ } else if (scrollingTo) {
3170
3425
  const existingWatchdog = initialScrollWatchdog.get(state);
3171
3426
  scrollingTo.offset = resolvedOffset;
3172
3427
  scrollingTo.targetOffset = resolvedOffset;
@@ -3179,15 +3434,9 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
3179
3434
  startScroll: (_c = existingWatchdog == null ? void 0 : existingWatchdog.startScroll) != null ? _c : state.scroll,
3180
3435
  targetOffset: resolvedOffset
3181
3436
  });
3182
- }
3183
- requestAdjust(ctx, offsetDiff);
3184
- if (state.didFinishInitialScroll) {
3185
- (_d = state.triggerCalculateItemsInView) == null ? void 0 : _d.call(state, { forceFullItemPositions: true });
3437
+ requestAdjust(ctx, offsetDiff);
3186
3438
  }
3187
3439
  }
3188
- if (state.didFinishInitialScroll) {
3189
- clearFinishedViewportRetargetableInitialScroll(state);
3190
- }
3191
3440
  } else {
3192
3441
  rearmBootstrapInitialScroll(ctx, {
3193
3442
  scroll: resolvedOffset,
@@ -3437,7 +3686,10 @@ function retargetActiveInitialScrollAtEnd(ctx) {
3437
3686
  var _a3;
3438
3687
  const state = ctx.state;
3439
3688
  const initialScroll = state.initialScroll;
3440
- if (!initialScroll || state.didFinishInitialScroll || ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || initialScroll.viewPosition !== 1 || state.props.data.length === 0) {
3689
+ if (state.didFinishInitialScroll) {
3690
+ return schedulePreservedEndAnchorCorrection(ctx);
3691
+ }
3692
+ if (!initialScroll || ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || initialScroll.viewPosition !== 1 || state.props.data.length === 0) {
3441
3693
  return false;
3442
3694
  }
3443
3695
  return advanceCurrentInitialScrollSession(ctx, { forceScroll: true });
@@ -3456,7 +3708,14 @@ function handleInitialScrollLayoutReady(ctx) {
3456
3708
  }
3457
3709
  function initializeInitialScrollOnMount(ctx, options) {
3458
3710
  var _a3, _b;
3459
- const { dataLength, hasFooterComponent, initialContentOffset, initialScrollAtEnd, useBootstrapInitialScroll } = options;
3711
+ const {
3712
+ alwaysDispatchInitialScroll,
3713
+ dataLength,
3714
+ hasFooterComponent,
3715
+ initialContentOffset,
3716
+ initialScrollAtEnd,
3717
+ useBootstrapInitialScroll
3718
+ } = options;
3460
3719
  const state = ctx.state;
3461
3720
  const initialScroll = state.initialScroll;
3462
3721
  const resolvedInitialContentOffset = initialContentOffset != null ? initialContentOffset : 0;
@@ -3476,7 +3735,7 @@ function initializeInitialScrollOnMount(ctx, options) {
3476
3735
  return;
3477
3736
  }
3478
3737
  const hasPendingDataDependentInitialScroll = !!initialScroll && dataLength === 0 && !(resolvedInitialContentOffset === 0 && !initialScrollAtEnd);
3479
- if (!resolvedInitialContentOffset && !hasPendingDataDependentInitialScroll) {
3738
+ if (!alwaysDispatchInitialScroll && !resolvedInitialContentOffset && !hasPendingDataDependentInitialScroll) {
3480
3739
  if (initialScroll && !initialScrollAtEnd) {
3481
3740
  finishInitialScroll(ctx, {
3482
3741
  resolvedOffset: resolvedInitialContentOffset
@@ -3797,9 +4056,18 @@ function prepareMVCP(ctx, dataChanged) {
3797
4056
  }
3798
4057
  }
3799
4058
 
4059
+ // src/core/resetLayoutCachesForDataChange.ts
4060
+ function resetLayoutCachesForDataChange(state) {
4061
+ state.indexByKey.clear();
4062
+ state.idCache.length = 0;
4063
+ state.positions.length = 0;
4064
+ state.columns.length = 0;
4065
+ state.columnSpans.length = 0;
4066
+ }
4067
+
3800
4068
  // src/core/syncMountedContainer.ts
3801
4069
  function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3802
- var _a3, _b, _c, _d, _e, _f, _g, _h;
4070
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i;
3803
4071
  const state = ctx.state;
3804
4072
  const {
3805
4073
  columns,
@@ -3811,7 +4079,8 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3811
4079
  if (item === void 0) {
3812
4080
  return { didChangePosition: false, didRefreshData: false };
3813
4081
  }
3814
- const updateLayout = (_a3 = options == null ? void 0 : options.updateLayout) != null ? _a3 : true;
4082
+ const itemKey = (_a3 = state.idCache[itemIndex]) != null ? _a3 : getId(state, itemIndex);
4083
+ const updateLayout = (_b = options == null ? void 0 : options.updateLayout) != null ? _b : true;
3815
4084
  let didChangePosition = false;
3816
4085
  let didRefreshData = false;
3817
4086
  if (updateLayout) {
@@ -3820,7 +4089,9 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3820
4089
  set$(ctx, `containerPosition${containerIndex}`, POSITION_OUT_OF_VIEW);
3821
4090
  return { didChangePosition: false, didRefreshData: false };
3822
4091
  }
3823
- const position = (positionValue || 0) - ((_b = options == null ? void 0 : options.scrollAdjustPending) != null ? _b : 0);
4092
+ const logicalPosition = (positionValue || 0) - ((_c = options == null ? void 0 : options.scrollAdjustPending) != null ? _c : 0);
4093
+ const itemSize = (_d = state.sizes.get(itemKey)) != null ? _d : getItemSize(ctx, itemKey, itemIndex, item);
4094
+ const position = toPhysicalHorizontalItemPosition(state, logicalPosition, itemSize, peek$(ctx, "totalSize"));
3824
4095
  const column = columns[itemIndex] || 1;
3825
4096
  const span = columnSpans[itemIndex] || 1;
3826
4097
  const prevPos = peek$(ctx, `containerPosition${containerIndex}`);
@@ -3839,15 +4110,15 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3839
4110
  }
3840
4111
  const prevData = peek$(ctx, `containerItemData${containerIndex}`);
3841
4112
  if (prevData !== item) {
3842
- 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;
3843
- const cachedComparison = (_e = pendingDataComparison == null ? void 0 : pendingDataComparison.byIndex[itemIndex]) != null ? _e : 0;
4113
+ 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;
4114
+ const cachedComparison = (_g = pendingDataComparison == null ? void 0 : pendingDataComparison.byIndex[itemIndex]) != null ? _g : 0;
3844
4115
  if (cachedComparison === 2) {
3845
4116
  set$(ctx, `containerItemData${containerIndex}`, item);
3846
4117
  didRefreshData = true;
3847
4118
  } else if (cachedComparison !== 1) {
3848
- const itemKey = (_g = (_f = peek$(ctx, `containerItemKey${containerIndex}`)) != null ? _f : state.idCache[itemIndex]) != null ? _g : getId(state, itemIndex);
4119
+ const nextItemKey = (_h = peek$(ctx, `containerItemKey${containerIndex}`)) != null ? _h : itemKey;
3849
4120
  const prevKey = keyExtractor == null ? void 0 : keyExtractor(prevData, itemIndex);
3850
- if (prevData === void 0 || !keyExtractor || prevKey !== itemKey) {
4121
+ if (prevData === void 0 || !keyExtractor || prevKey !== nextItemKey) {
3851
4122
  set$(ctx, `containerItemData${containerIndex}`, item);
3852
4123
  didRefreshData = true;
3853
4124
  } else if (!itemsAreEqual) {
@@ -3864,7 +4135,7 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3864
4135
  };
3865
4136
  }
3866
4137
  }
3867
- if ((_h = state.pendingDataComparison) == null ? void 0 : _h.byIndex) {
4138
+ if ((_i = state.pendingDataComparison) == null ? void 0 : _i.byIndex) {
3868
4139
  state.pendingDataComparison.byIndex[itemIndex] = isEqual ? 1 : 2;
3869
4140
  }
3870
4141
  if (!isEqual) {
@@ -4029,11 +4300,13 @@ function updateSnapToOffsets(ctx) {
4029
4300
  const {
4030
4301
  props: { snapToIndices }
4031
4302
  } = state;
4303
+ const contentSize = state.props.horizontal ? getContentSize(ctx) : void 0;
4032
4304
  const snapToOffsets = Array(snapToIndices.length);
4033
4305
  for (let i = 0; i < snapToIndices.length; i++) {
4034
4306
  const idx = snapToIndices[i];
4035
4307
  getId(state, idx);
4036
- snapToOffsets[i] = state.positions[idx];
4308
+ const logicalOffset = state.positions[idx];
4309
+ snapToOffsets[i] = toNativeHorizontalOffset(state, logicalOffset, contentSize);
4037
4310
  }
4038
4311
  set$(ctx, "snapToOffsets", snapToOffsets);
4039
4312
  }
@@ -4642,7 +4915,6 @@ function calculateItemsInView(ctx, params = {}) {
4642
4915
  var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
4643
4916
  const {
4644
4917
  columns,
4645
- columnSpans,
4646
4918
  containerItemKeys,
4647
4919
  enableScrollForNextCalculateItemsInView,
4648
4920
  idCache,
@@ -4692,8 +4964,10 @@ function calculateItemsInView(ctx, params = {}) {
4692
4964
  let scrollTopBuffered = 0;
4693
4965
  let scrollBottom = 0;
4694
4966
  let scrollBottomBuffered = 0;
4967
+ let nativeScrollState = scrollState;
4695
4968
  const updateScroll2 = (nextScrollState) => {
4696
4969
  var _a4;
4970
+ nativeScrollState = nextScrollState;
4697
4971
  scrollAdjustPending = (_a4 = peek$(ctx, "scrollAdjustPending")) != null ? _a4 : 0;
4698
4972
  scrollAdjustPad = scrollAdjustPending - topPad;
4699
4973
  scroll = Math.round(nextScrollState + scrollExtra + scrollAdjustPad);
@@ -4705,9 +4979,17 @@ function calculateItemsInView(ctx, params = {}) {
4705
4979
  const previousStickyIndex = peek$(ctx, "activeStickyIndex");
4706
4980
  const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
4707
4981
  const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : -1;
4982
+ const stickyIndexDidChange = previousStickyIndex !== nextActiveStickyIndex;
4708
4983
  if (currentStickyIdx >= 0 || previousStickyIndex >= 0) {
4709
4984
  set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
4710
4985
  }
4986
+ const shouldNotifyStickyHeaderChange = !!onStickyHeaderChange && stickyIndicesArr.length > 0 && stickyIndexDidChange;
4987
+ const finishCalculateItemsInView = shouldNotifyStickyHeaderChange ? () => {
4988
+ const item = data[nextActiveStickyIndex];
4989
+ if (item !== void 0) {
4990
+ onStickyHeaderChange == null ? void 0 : onStickyHeaderChange({ index: nextActiveStickyIndex, item });
4991
+ }
4992
+ } : void 0;
4711
4993
  let scrollBufferTop = drawDistance;
4712
4994
  let scrollBufferBottom = drawDistance;
4713
4995
  if (speed > 0 || speed === 0 && scroll < Math.max(50, drawDistance)) {
@@ -4718,8 +5000,10 @@ function calculateItemsInView(ctx, params = {}) {
4718
5000
  scrollBufferBottom = drawDistance * 0.5;
4719
5001
  }
4720
5002
  const updateScrollRange = () => {
4721
- scrollTopBuffered = scroll - scrollBufferTop;
4722
- scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
5003
+ const scrollStart = Math.max(0, scroll);
5004
+ const overscrollBeforeContent = Math.max(0, -nativeScrollState);
5005
+ scrollTopBuffered = scrollStart - scrollBufferTop;
5006
+ scrollBottom = Math.max(scrollStart, scroll + scrollLength + overscrollBeforeContent);
4723
5007
  scrollBottomBuffered = scrollBottom + scrollBufferBottom;
4724
5008
  };
4725
5009
  updateScrollRange();
@@ -4729,17 +5013,14 @@ function calculateItemsInView(ctx, params = {}) {
4729
5013
  state.scrollForNextCalculateItemsInView = void 0;
4730
5014
  } else if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
4731
5015
  if (!isInMVCPActiveMode(state)) {
5016
+ finishCalculateItemsInView == null ? void 0 : finishCalculateItemsInView();
4732
5017
  return;
4733
5018
  }
4734
5019
  }
4735
5020
  }
4736
5021
  const checkMVCP = doMVCP && !suppressInitialScrollSideEffects ? prepareMVCP(ctx, dataChanged) : void 0;
4737
5022
  if (dataChanged) {
4738
- indexByKey.clear();
4739
- idCache.length = 0;
4740
- positions.length = 0;
4741
- columns.length = 0;
4742
- columnSpans.length = 0;
5023
+ resetLayoutCachesForDataChange(state);
4743
5024
  }
4744
5025
  const startIndex = forceFullItemPositions || dataChanged ? 0 : (_c = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _c : 0;
4745
5026
  const optimizeForVisibleWindow = !forceFullItemPositions && !dataChanged && numColumns > 1 && minIndexSizeChanged !== void 0;
@@ -5053,12 +5334,7 @@ function calculateItemsInView(ctx, params = {}) {
5053
5334
  );
5054
5335
  }
5055
5336
  }
5056
- if (onStickyHeaderChange && stickyIndicesArr.length > 0 && nextActiveStickyIndex !== void 0 && nextActiveStickyIndex !== previousStickyIndex) {
5057
- const item = data[nextActiveStickyIndex];
5058
- if (item !== void 0) {
5059
- onStickyHeaderChange({ index: nextActiveStickyIndex, item });
5060
- }
5061
- }
5337
+ finishCalculateItemsInView == null ? void 0 : finishCalculateItemsInView();
5062
5338
  });
5063
5339
  }
5064
5340
 
@@ -5086,11 +5362,22 @@ function doMaintainScrollAtEnd(ctx) {
5086
5362
  if (!state.maintainingScrollAtEnd) {
5087
5363
  state.maintainingScrollAtEnd = true;
5088
5364
  requestAnimationFrame(() => {
5089
- var _a3;
5090
5365
  if (peek$(ctx, "isWithinMaintainScrollAtEndThreshold")) {
5091
- (_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
5092
- animated: maintainScrollAtEnd.animated
5093
- });
5366
+ const scroller = refScroller.current;
5367
+ if (state.props.horizontal && isHorizontalRTL(state)) {
5368
+ const currentContentSize = getContentSize(ctx);
5369
+ const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
5370
+ const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
5371
+ scroller == null ? void 0 : scroller.scrollTo({
5372
+ animated: maintainScrollAtEnd.animated,
5373
+ x: nativeOffset,
5374
+ y: 0
5375
+ });
5376
+ } else {
5377
+ scroller == null ? void 0 : scroller.scrollToEnd({
5378
+ animated: maintainScrollAtEnd.animated
5379
+ });
5380
+ }
5094
5381
  setTimeout(
5095
5382
  () => {
5096
5383
  state.maintainingScrollAtEnd = false;
@@ -5290,7 +5577,8 @@ function handleLayout(ctx, layoutParam, setCanRender) {
5290
5577
  }
5291
5578
  checkThresholds(ctx);
5292
5579
  if (state) {
5293
- state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
5580
+ const crossAxisPadding = state.props.horizontal ? (state.props.stylePaddingTop || 0) + (state.props.stylePaddingBottom || 0) : (state.props.stylePaddingLeft || 0) + (state.props.stylePaddingRight || 0);
5581
+ state.needsOtherAxisSize = otherAxisSize - crossAxisPadding < 10;
5294
5582
  }
5295
5583
  if (IS_DEV && measuredLength === 0) {
5296
5584
  warnDevOnce(
@@ -5404,7 +5692,7 @@ function cloneScrollEvent(event) {
5404
5692
  };
5405
5693
  }
5406
5694
  function onScroll(ctx, event) {
5407
- var _a3, _b, _c, _d;
5695
+ var _a3, _b, _c, _d, _e, _f;
5408
5696
  const state = ctx.state;
5409
5697
  const { scrollProcessingEnabled } = state;
5410
5698
  if (scrollProcessingEnabled === false) {
@@ -5423,6 +5711,12 @@ function onScroll(ctx, event) {
5423
5711
  }
5424
5712
  }
5425
5713
  let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
5714
+ if (state.props.horizontal) {
5715
+ newScroll = toLogicalHorizontalOffset(state, newScroll, (_e = event.nativeEvent.contentSize) == null ? void 0 : _e.width);
5716
+ }
5717
+ state.didFinishInitialScroll && ((_f = state.initialScroll) == null ? void 0 : _f.viewPosition) === 1 && state.scroll > state.scrollLength;
5718
+ state.lastNativeScroll = newScroll;
5719
+ state.lastNativeScrollTime = Date.now();
5426
5720
  if (state.scrollingTo && state.scrollingTo.offset >= newScroll) {
5427
5721
  const maxOffset = clampScrollOffset(ctx, newScroll, state.scrollingTo);
5428
5722
  if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
@@ -5594,6 +5888,16 @@ function runOrScheduleMVCPRecalculate(ctx) {
5594
5888
  });
5595
5889
  }
5596
5890
  }
5891
+ function updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal) {
5892
+ const state = ctx.state;
5893
+ if (state.needsOtherAxisSize) {
5894
+ const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
5895
+ const currentOtherAxisSize = peek$(ctx, "otherAxisSize");
5896
+ if (!currentOtherAxisSize || otherAxisSize > currentOtherAxisSize) {
5897
+ set$(ctx, "otherAxisSize", otherAxisSize);
5898
+ }
5899
+ }
5900
+ }
5597
5901
  function updateItemSize(ctx, itemKey, sizeObj) {
5598
5902
  var _a3;
5599
5903
  const state = ctx.state;
@@ -5617,13 +5921,13 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5617
5921
  const type = getItemType ? (_a3 = getItemType(itemData, index)) != null ? _a3 : "" : "";
5618
5922
  const size2 = getFixedItemSize(itemData, index, type);
5619
5923
  if (size2 !== void 0 && size2 === sizesKnown.get(itemKey)) {
5924
+ updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal);
5620
5925
  return;
5621
5926
  }
5622
5927
  }
5623
5928
  let needsRecalculate = !didContainersLayout;
5624
5929
  let shouldMaintainScrollAtEnd = false;
5625
5930
  let minIndexSizeChanged;
5626
- let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
5627
5931
  const prevSizeKnown = state.sizesKnown.get(itemKey);
5628
5932
  const diff = updateOneItemSize(ctx, itemKey, sizeObj);
5629
5933
  const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
@@ -5634,10 +5938,6 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5634
5938
  if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
5635
5939
  needsRecalculate = true;
5636
5940
  }
5637
- if (state.needsOtherAxisSize) {
5638
- const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
5639
- maxOtherAxisSize = Math.max(maxOtherAxisSize, otherAxisSize);
5640
- }
5641
5941
  if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
5642
5942
  shouldMaintainScrollAtEnd = true;
5643
5943
  }
@@ -5653,10 +5953,7 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5653
5953
  if (minIndexSizeChanged !== void 0) {
5654
5954
  state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, minIndexSizeChanged) : minIndexSizeChanged;
5655
5955
  }
5656
- const cur = peek$(ctx, "otherAxisSize");
5657
- if (!cur || maxOtherAxisSize > cur) {
5658
- set$(ctx, "otherAxisSize", maxOtherAxisSize);
5659
- }
5956
+ updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal);
5660
5957
  if (didContainersLayout || checkAllSizesKnown(state, getMountedBufferedIndices(state))) {
5661
5958
  if (needsRecalculate) {
5662
5959
  state.scrollForNextCalculateItemsInView = void 0;
@@ -6045,6 +6342,8 @@ function getAlwaysRenderIndices(config, data, keyExtractor, anchoredEndSpaceAnch
6045
6342
  indices.sort(sortAsc);
6046
6343
  return indices;
6047
6344
  }
6345
+
6346
+ // src/utils/getRenderedItem.ts
6048
6347
  function getRenderedItem(ctx, key) {
6049
6348
  var _a3;
6050
6349
  const state = ctx.state;
@@ -6070,7 +6369,7 @@ function getRenderedItem(ctx, key) {
6070
6369
  item,
6071
6370
  type: getItemType ? (_a3 = getItemType(item, index)) != null ? _a3 : "" : ""
6072
6371
  };
6073
- renderedItem = React3__default.createElement(renderItem, itemProps);
6372
+ renderedItem = renderItem(itemProps);
6074
6373
  }
6075
6374
  return { index, item: data[index], renderedItem };
6076
6375
  }
@@ -6231,7 +6530,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6231
6530
  getFixedItemSize,
6232
6531
  getItemType,
6233
6532
  horizontal,
6533
+ rtl,
6234
6534
  initialContainerPoolRatio = 3,
6535
+ estimatedHeaderSize,
6235
6536
  initialScrollAtEnd = false,
6236
6537
  initialScrollIndex: initialScrollIndexProp,
6237
6538
  initialScrollOffset: initialScrollOffsetProp,
@@ -6299,13 +6600,16 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6299
6600
  const style = { ...StyleSheet.flatten(styleProp) };
6300
6601
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
6301
6602
  const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
6603
+ const stylePaddingLeftState = extractPadding(style, contentContainerStyle, "Left");
6604
+ const stylePaddingRightState = extractPadding(style, contentContainerStyle, "Right");
6302
6605
  const maintainScrollAtEndConfig = normalizeMaintainScrollAtEnd(maintainScrollAtEnd);
6303
6606
  const maintainVisibleContentPositionConfig = normalizeMaintainVisibleContentPosition(
6304
6607
  maintainVisibleContentPositionProp
6305
6608
  );
6306
6609
  const hasInitialScrollIndex = initialScrollIndexProp !== void 0 && initialScrollIndexProp !== null;
6307
6610
  const hasInitialScrollOffset = initialScrollOffsetProp !== void 0 && initialScrollOffsetProp !== null;
6308
- const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && hasInitialScrollOffset;
6611
+ const shouldInitializeHorizontalRTL = !initialScrollAtEnd && !hasInitialScrollIndex && !hasInitialScrollOffset && isHorizontalRTLProps({ horizontal, rtl });
6612
+ const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && (hasInitialScrollOffset || shouldInitializeHorizontalRTL);
6309
6613
  const usesBootstrapInitialScroll = initialScrollAtEnd || hasInitialScrollIndex;
6310
6614
  const initialScrollProp = initialScrollAtEnd ? {
6311
6615
  index: Math.max(0, dataProp.length - 1),
@@ -6421,6 +6725,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6421
6725
  internalState.reprocessCurrentScroll = () => updateScroll(ctx, internalState.scroll, true);
6422
6726
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
6423
6727
  set$(ctx, "extraData", extraData);
6728
+ if (estimatedHeaderSize !== void 0) {
6729
+ set$(ctx, "headerSize", estimatedHeaderSize);
6730
+ }
6424
6731
  }
6425
6732
  refState.current = ctx.state;
6426
6733
  }
@@ -6480,11 +6787,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6480
6787
  positionComponentInternal,
6481
6788
  recycleItems: !!recycleItems,
6482
6789
  renderItem,
6790
+ rtl,
6483
6791
  snapToIndices,
6484
6792
  stickyIndicesArr: stickyHeaderIndices != null ? stickyHeaderIndices : [],
6485
6793
  stickyIndicesSet: useMemo(() => new Set(stickyHeaderIndices != null ? stickyHeaderIndices : []), [stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.join(",")]),
6486
6794
  stickyPositionComponentInternal,
6487
6795
  stylePaddingBottom: stylePaddingBottomState,
6796
+ stylePaddingLeft: stylePaddingLeftState,
6797
+ stylePaddingRight: stylePaddingRightState,
6488
6798
  stylePaddingTop: stylePaddingTopState,
6489
6799
  useWindowScroll: useWindowScrollResolved
6490
6800
  };
@@ -6507,6 +6817,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6507
6817
  };
6508
6818
  if (isFirstLocal) {
6509
6819
  initializeStateVars(false);
6820
+ resetLayoutCachesForDataChange(state);
6510
6821
  updateItemPositions(
6511
6822
  ctx,
6512
6823
  /*dataChanged*/
@@ -6524,6 +6835,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6524
6835
  }, [usesBootstrapInitialScroll]);
6525
6836
  useLayoutEffect(() => {
6526
6837
  initializeInitialScrollOnMount(ctx, {
6838
+ alwaysDispatchInitialScroll: shouldInitializeHorizontalRTL,
6527
6839
  dataLength: dataProp.length,
6528
6840
  hasFooterComponent: !!ListFooterComponent,
6529
6841
  initialContentOffset,
@@ -6783,6 +7095,8 @@ var internal = {
6783
7095
  typedMemo,
6784
7096
  useArr$,
6785
7097
  useCombinedRef,
7098
+ useLatestRef,
7099
+ useStableRenderComponent,
6786
7100
  useStateContext
6787
7101
  };
6788
7102