@legendapp/list 3.0.0-beta.52 → 3.0.0-beta.53

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.
@@ -145,7 +145,10 @@ function useSelector$(signalName, selector) {
145
145
  }
146
146
 
147
147
  // src/state/getContentInsetEnd.ts
148
- function getContentInsetEnd(ctx) {
148
+ function getContentInsetEndAdjustmentEnd(adjustment) {
149
+ return Math.max(0, adjustment != null ? adjustment : 0);
150
+ }
151
+ function getContentInsetEnd(ctx, contentInsetEndAdjustmentOverride) {
149
152
  var _a3, _b;
150
153
  const state = ctx.state;
151
154
  const { props } = state;
@@ -153,14 +156,21 @@ function getContentInsetEnd(ctx) {
153
156
  const contentInset = props.contentInset;
154
157
  const baseInset = contentInset != null ? contentInset : state.nativeContentInset;
155
158
  const baseEndInset = (horizontal ? baseInset == null ? void 0 : baseInset.right : baseInset == null ? void 0 : baseInset.bottom) || 0;
159
+ const contentInsetEndAdjustment = getContentInsetEndAdjustmentEnd(
160
+ contentInsetEndAdjustmentOverride != null ? contentInsetEndAdjustmentOverride : props.contentInsetEndAdjustment
161
+ );
156
162
  const anchoredEndSpaceSize = peek$(ctx, "anchoredEndSpaceSize");
157
163
  const anchoredEndInset = ((_a3 = props.anchoredEndSpace) == null ? void 0 : _a3.includeInEndInset) && anchoredEndSpaceSize ? anchoredEndSpaceSize : 0;
158
164
  const overrideInset = (_b = state.contentInsetOverride) != null ? _b : void 0;
165
+ const adjustedBaseEndInset = baseEndInset + contentInsetEndAdjustment;
159
166
  if (overrideInset) {
160
167
  const mergedInset = { bottom: 0, right: 0, ...baseInset, ...overrideInset };
161
- return Math.max((horizontal ? mergedInset.right : mergedInset.bottom) || 0, anchoredEndInset);
168
+ return Math.max(
169
+ ((horizontal ? mergedInset.right : mergedInset.bottom) || 0) + contentInsetEndAdjustment,
170
+ anchoredEndInset
171
+ );
162
172
  }
163
- return Math.max(baseEndInset, anchoredEndInset);
173
+ return Math.max(adjustedBaseEndInset, anchoredEndInset);
164
174
  }
165
175
 
166
176
  // src/state/getContentSize.ts
@@ -661,6 +671,49 @@ function isInMVCPActiveMode(state) {
661
671
  }
662
672
 
663
673
  // src/components/Container.tsx
674
+ function getContainerPositionStyle({
675
+ columnWrapperStyle,
676
+ horizontal,
677
+ hasItemSeparator,
678
+ numColumns,
679
+ otherAxisPos,
680
+ otherAxisSize
681
+ }) {
682
+ let paddingStyles;
683
+ if (columnWrapperStyle) {
684
+ const { columnGap, rowGap, gap } = columnWrapperStyle;
685
+ if (horizontal) {
686
+ paddingStyles = {
687
+ paddingBottom: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0,
688
+ paddingRight: columnGap || gap || void 0,
689
+ paddingTop: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
690
+ };
691
+ } else {
692
+ paddingStyles = {
693
+ paddingBottom: rowGap || gap || void 0,
694
+ paddingLeft: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0,
695
+ paddingRight: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
696
+ };
697
+ }
698
+ }
699
+ return horizontal ? {
700
+ boxSizing: paddingStyles ? "border-box" : void 0,
701
+ flexDirection: hasItemSeparator ? "row" : void 0,
702
+ height: otherAxisSize,
703
+ left: 0,
704
+ position: "absolute",
705
+ top: otherAxisPos,
706
+ ...paddingStyles || {}
707
+ } : {
708
+ boxSizing: paddingStyles ? "border-box" : void 0,
709
+ left: otherAxisPos,
710
+ position: "absolute",
711
+ right: numColumns > 1 ? null : 0,
712
+ top: 0,
713
+ width: otherAxisSize,
714
+ ...paddingStyles || {}
715
+ };
716
+ }
664
717
  var Container = typedMemo(function Container2({
665
718
  id,
666
719
  recycleItems,
@@ -699,42 +752,17 @@ var Container = typedMemo(function Container2({
699
752
  const resolvedSpan = Math.min(Math.max(span || 1, 1), numColumns);
700
753
  const otherAxisPos = numColumns > 1 ? `${(resolvedColumn - 1) / numColumns * 100}%` : 0;
701
754
  const otherAxisSize = numColumns > 1 ? `${resolvedSpan / numColumns * 100}%` : void 0;
702
- const style = useMemo(() => {
703
- let paddingStyles;
704
- if (columnWrapperStyle) {
705
- const { columnGap, rowGap, gap } = columnWrapperStyle;
706
- if (horizontal) {
707
- paddingStyles = {
708
- paddingBottom: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0,
709
- paddingRight: columnGap || gap || void 0,
710
- paddingTop: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
711
- };
712
- } else {
713
- paddingStyles = {
714
- paddingBottom: rowGap || gap || void 0,
715
- paddingLeft: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0,
716
- paddingRight: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
717
- };
718
- }
719
- }
720
- return horizontal ? {
721
- boxSizing: paddingStyles ? "border-box" : void 0,
722
- flexDirection: ItemSeparatorComponent ? "row" : void 0,
723
- height: otherAxisSize,
724
- left: 0,
725
- position: "absolute",
726
- top: otherAxisPos,
727
- ...paddingStyles || {}
728
- } : {
729
- boxSizing: paddingStyles ? "border-box" : void 0,
730
- left: otherAxisPos,
731
- position: "absolute",
732
- right: numColumns > 1 ? null : 0,
733
- top: 0,
734
- width: otherAxisSize,
735
- ...paddingStyles || {}
736
- };
737
- }, [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns]);
755
+ const style = useMemo(
756
+ () => getContainerPositionStyle({
757
+ columnWrapperStyle,
758
+ hasItemSeparator: !!ItemSeparatorComponent,
759
+ horizontal,
760
+ numColumns,
761
+ otherAxisPos,
762
+ otherAxisSize
763
+ }),
764
+ [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns, ItemSeparatorComponent]
765
+ );
738
766
  const renderedItemInfo = useMemo(
739
767
  () => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
740
768
  [itemKey, data, extraData]
@@ -1045,6 +1073,9 @@ function useRafCoalescer(callback) {
1045
1073
  return coalescer;
1046
1074
  }
1047
1075
 
1076
+ // src/components/webConstants.ts
1077
+ var LEGEND_LIST_CONTENT_CONTAINER_CLASS = "legend-list-content-container";
1078
+
1048
1079
  // src/components/webScrollUtils.ts
1049
1080
  function getDocumentScrollerNode() {
1050
1081
  if (typeof document === "undefined") {
@@ -1129,6 +1160,11 @@ function resolveWindowScrollTarget({ clampedOffset, horizontal, listPos, scroll
1129
1160
  }
1130
1161
 
1131
1162
  // src/components/ListComponentScrollView.tsx
1163
+ function getContentInsetEndAdjustmentEnd2(ctx) {
1164
+ var _a3, _b;
1165
+ const adjustment = (_b = (_a3 = ctx.state) == null ? void 0 : _a3.props) == null ? void 0 : _b.contentInsetEndAdjustment;
1166
+ return Math.max(0, adjustment != null ? adjustment : 0);
1167
+ }
1132
1168
  var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
1133
1169
  children,
1134
1170
  style,
@@ -1146,7 +1182,9 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
1146
1182
  onLayout,
1147
1183
  ...props
1148
1184
  }, ref) {
1185
+ var _a3, _b, _c;
1149
1186
  const ctx = useStateContext();
1187
+ const [anchoredEndSpaceSize] = useArr$(["anchoredEndSpaceSize"]);
1150
1188
  const scrollRef = useRef(null);
1151
1189
  const contentRef = useRef(null);
1152
1190
  const isWindowScroll = useWindowScroll;
@@ -1208,10 +1246,9 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
1208
1246
  useImperativeHandle(ref, () => {
1209
1247
  const api = {
1210
1248
  getBoundingClientRect: () => {
1211
- var _a3;
1212
- return (_a3 = scrollRef.current) == null ? void 0 : _a3.getBoundingClientRect();
1249
+ var _a4;
1250
+ return (_a4 = scrollRef.current) == null ? void 0 : _a4.getBoundingClientRect();
1213
1251
  },
1214
- getContentNode: () => contentRef.current,
1215
1252
  getCurrentScrollOffset,
1216
1253
  getScrollableNode: () => resolveScrollableNode(scrollRef.current, isWindowScroll),
1217
1254
  getScrollEventTarget: () => getScrollTarget(),
@@ -1337,6 +1374,10 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
1337
1374
  },
1338
1375
  ...StyleSheet.flatten(style)
1339
1376
  };
1377
+ const contentInsetEndAdjustment = getContentInsetEndAdjustmentEnd2(ctx);
1378
+ const anchoredEndInset = ((_c = (_b = (_a3 = ctx.state) == null ? void 0 : _a3.props) == null ? void 0 : _b.anchoredEndSpace) == null ? void 0 : _c.includeInEndInset) && anchoredEndSpaceSize ? anchoredEndSpaceSize : 0;
1379
+ const renderedContentInsetEndAdjustment = Math.max(0, contentInsetEndAdjustment - anchoredEndInset);
1380
+ const contentInsetEndAdjustmentSpacerStyle = renderedContentInsetEndAdjustment ? horizontal ? { flexShrink: 0, width: renderedContentInsetEndAdjustment } : { height: renderedContentInsetEndAdjustment } : void 0;
1340
1381
  const contentStyle = {
1341
1382
  display: horizontal ? "flex" : "block",
1342
1383
  flexDirection: horizontal ? "row" : void 0,
@@ -1344,6 +1385,7 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
1344
1385
  minWidth: horizontal ? "100%" : void 0,
1345
1386
  ...StyleSheet.flatten(contentContainerStyle)
1346
1387
  };
1388
+ const className = contentContainerClassName ? `${LEGEND_LIST_CONTENT_CONTAINER_CLASS} ${contentContainerClassName}` : LEGEND_LIST_CONTENT_CONTAINER_CLASS;
1347
1389
  const {
1348
1390
  contentContainerClassName: _contentContainerClassName,
1349
1391
  contentInset: _contentInset,
@@ -1352,7 +1394,7 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
1352
1394
  useWindowScroll: _useWindowScroll,
1353
1395
  ...webProps
1354
1396
  } = props;
1355
- return /* @__PURE__ */ React3.createElement("div", { ref: scrollRef, ...webProps, style: scrollViewStyle }, refreshControl, /* @__PURE__ */ React3.createElement("div", { className: contentContainerClassName, ref: contentRef, style: contentStyle }, children));
1397
+ return /* @__PURE__ */ React3.createElement("div", { ref: scrollRef, ...webProps, style: scrollViewStyle }, refreshControl, /* @__PURE__ */ React3.createElement("div", { className, ref: contentRef, style: contentStyle }, children, contentInsetEndAdjustmentSpacerStyle ? /* @__PURE__ */ React3.createElement("div", { "aria-hidden": true, style: contentInsetEndAdjustmentSpacerStyle }) : null));
1356
1398
  });
1357
1399
  function useValueListener$(key, callback) {
1358
1400
  const ctx = useStateContext();
@@ -1380,11 +1422,18 @@ function getScrollAdjustAxis(horizontal) {
1380
1422
  y: 1
1381
1423
  };
1382
1424
  }
1425
+ function resolveScrollAdjustContentNode(el, contentNode) {
1426
+ if ((contentNode == null ? void 0 : contentNode.isConnected) && contentNode.parentElement === el) {
1427
+ return contentNode;
1428
+ }
1429
+ return el.querySelector(`:scope > .${LEGEND_LIST_CONTENT_CONTAINER_CLASS}`);
1430
+ }
1383
1431
  function ScrollAdjust() {
1384
1432
  const ctx = useStateContext();
1385
1433
  const lastScrollOffsetRef = React3.useRef(0);
1386
1434
  const resetPaddingRafRef = React3.useRef(void 0);
1387
1435
  const resetPaddingBaselineRef = React3.useRef(void 0);
1436
+ const contentNodeRef = React3.useRef(null);
1388
1437
  const callback = React3.useCallback(() => {
1389
1438
  var _a3, _b;
1390
1439
  const scrollAdjust = peek$(ctx, "scrollAdjust");
@@ -1395,9 +1444,10 @@ function ScrollAdjust() {
1395
1444
  const scrollDelta = scrollOffset - lastScrollOffsetRef.current;
1396
1445
  if (scrollDelta !== 0) {
1397
1446
  const axis = getScrollAdjustAxis(!!ctx.state.props.horizontal);
1398
- const contentNode = scrollView.getContentNode();
1399
1447
  const prevScroll = scrollView.getCurrentScrollOffset();
1400
1448
  const el = scrollView.getScrollableNode();
1449
+ const contentNode = resolveScrollAdjustContentNode(el, contentNodeRef.current);
1450
+ contentNodeRef.current = contentNode;
1401
1451
  const scrollBy = () => scrollView.scrollBy(axis.x * scrollDelta, axis.y * scrollDelta);
1402
1452
  if (!contentNode) {
1403
1453
  scrollBy();
@@ -3252,6 +3302,15 @@ function checkFinishedScrollFallback(ctx) {
3252
3302
  }
3253
3303
 
3254
3304
  // src/core/initialScrollLifecycle.ts
3305
+ function retargetActiveInitialScrollAtEnd(ctx) {
3306
+ var _a3;
3307
+ const state = ctx.state;
3308
+ const initialScroll = state.initialScroll;
3309
+ if (!initialScroll || state.didFinishInitialScroll || ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || initialScroll.viewPosition !== 1 || state.props.data.length === 0) {
3310
+ return false;
3311
+ }
3312
+ return advanceCurrentInitialScrollSession(ctx, { forceScroll: true });
3313
+ }
3255
3314
  function handleInitialScrollLayoutReady(ctx) {
3256
3315
  var _a3;
3257
3316
  if (!ctx.state.initialScroll) {
@@ -5318,6 +5377,22 @@ function maybeUpdateAnchoredEndSpace(ctx) {
5318
5377
  return nextSize;
5319
5378
  }
5320
5379
 
5380
+ // src/core/updateContentInsetEndAdjustment.ts
5381
+ function updateContentInsetEndAdjustment(ctx, previousContentInsetEndAdjustment) {
5382
+ const state = ctx.state;
5383
+ const previousContentInsetEnd = getContentInsetEnd(ctx, previousContentInsetEndAdjustment);
5384
+ const nextContentInsetEnd = getContentInsetEnd(ctx);
5385
+ const insetDiff = nextContentInsetEnd - previousContentInsetEnd;
5386
+ if (insetDiff !== 0) {
5387
+ const wasWithinEndThreshold = !!peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
5388
+ updateScroll(ctx, state.scroll, true, { markHasScrolled: false });
5389
+ const didRetargetInitialScroll = retargetActiveInitialScrollAtEnd(ctx);
5390
+ if (!didRetargetInitialScroll && wasWithinEndThreshold && (insetDiff > 0)) {
5391
+ requestAdjust(ctx, insetDiff);
5392
+ }
5393
+ }
5394
+ }
5395
+
5321
5396
  // src/core/updateItemSize.ts
5322
5397
  function runOrScheduleMVCPRecalculate(ctx) {
5323
5398
  const state = ctx.state;
@@ -5665,8 +5740,14 @@ function createImperativeHandle(ctx) {
5665
5740
  startBuffered: state.startBuffered
5666
5741
  }),
5667
5742
  reportContentInset: (inset) => {
5743
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
5744
+ const previousInset = state.contentInsetOverride;
5668
5745
  state.contentInsetOverride = inset != null ? inset : void 0;
5746
+ const didChange = ((_a3 = previousInset == null ? void 0 : previousInset.top) != null ? _a3 : 0) !== ((_c = (_b = state.contentInsetOverride) == null ? void 0 : _b.top) != null ? _c : 0) || ((_d = previousInset == null ? void 0 : previousInset.bottom) != null ? _d : 0) !== ((_f = (_e = state.contentInsetOverride) == null ? void 0 : _e.bottom) != null ? _f : 0) || ((_g = previousInset == null ? void 0 : previousInset.left) != null ? _g : 0) !== ((_i = (_h = state.contentInsetOverride) == null ? void 0 : _h.left) != null ? _i : 0) || ((_j = previousInset == null ? void 0 : previousInset.right) != null ? _j : 0) !== ((_l = (_k = state.contentInsetOverride) == null ? void 0 : _k.right) != null ? _l : 0);
5669
5747
  updateScroll(ctx, state.scroll, true, { markHasScrolled: false });
5748
+ if (didChange) {
5749
+ retargetActiveInitialScrollAtEnd(ctx);
5750
+ }
5670
5751
  },
5671
5752
  scrollIndexIntoView: (options) => runScrollWithPromise(() => scrollIndexIntoView(options)),
5672
5753
  scrollItemIntoView: ({ item, ...props }) => runScrollWithPromise(() => {
@@ -5967,6 +6048,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
5967
6048
  data: dataProp = [],
5968
6049
  dataVersion,
5969
6050
  drawDistance = 250,
6051
+ contentInsetEndAdjustment,
5970
6052
  estimatedItemSize = 100,
5971
6053
  estimatedListSize,
5972
6054
  extraData,
@@ -6076,6 +6158,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6076
6158
  const combinedRef = useCombinedRef(refScroller, refScrollView);
6077
6159
  const keyExtractor = keyExtractorProp != null ? keyExtractorProp : ((_item, index) => index.toString());
6078
6160
  const stickyHeaderIndices = stickyHeaderIndicesProp != null ? stickyHeaderIndicesProp : stickyIndicesDeprecated;
6161
+ const contentInsetEndAdjustmentResolved = contentInsetEndAdjustment ;
6162
+ const previousContentInsetEndAdjustmentRef = useRef(contentInsetEndAdjustmentResolved);
6079
6163
  const alwaysRenderIndices = useMemo(() => {
6080
6164
  const indices = getAlwaysRenderIndices(alwaysRender, dataProp, keyExtractor, anchoredEndSpace == null ? void 0 : anchoredEndSpace.anchorIndex);
6081
6165
  return { arr: indices, set: new Set(indices) };
@@ -6195,6 +6279,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6195
6279
  anchoredEndSpace: anchoredEndSpaceResolved,
6196
6280
  animatedProps: animatedPropsInternal,
6197
6281
  contentInset,
6282
+ contentInsetEndAdjustment: contentInsetEndAdjustmentResolved,
6198
6283
  data: dataProp,
6199
6284
  dataVersion,
6200
6285
  drawDistance,
@@ -6312,6 +6397,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6312
6397
  didAnchoredEndSpaceAnchorIndexChange,
6313
6398
  numColumnsProp
6314
6399
  ]);
6400
+ useLayoutEffect(() => {
6401
+ const previousContentInsetEndAdjustment = previousContentInsetEndAdjustmentRef.current;
6402
+ previousContentInsetEndAdjustmentRef.current = contentInsetEndAdjustmentResolved;
6403
+ updateContentInsetEndAdjustment(ctx, previousContentInsetEndAdjustment);
6404
+ }, [ctx, contentInsetEndAdjustmentResolved]);
6315
6405
  const onLayoutFooter = useCallback(
6316
6406
  (layout) => {
6317
6407
  if (!usesBootstrapInitialScroll) {
package/react.d.ts CHANGED
@@ -5,7 +5,6 @@ type ScrollEventTarget = Window | HTMLElement;
5
5
 
6
6
  interface ScrollViewMethods {
7
7
  getBoundingClientRect(): DOMRect | null | undefined;
8
- getContentNode(): HTMLElement | null;
9
8
  getCurrentScrollOffset(): number;
10
9
  getScrollableNode(): HTMLElement;
11
10
  getScrollEventTarget(): ScrollEventTarget | null;
@@ -278,6 +277,11 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
278
277
  * Keeps an item visually anchored to the start by adding trailing space when the content below it underflows.
279
278
  */
280
279
  anchoredEndSpace?: AnchoredEndSpaceConfig$1;
280
+ /**
281
+ * Adjusts the effective end content inset for web lists without replacing the base contentInset.
282
+ * The adjustment is also rendered as real content padding so the browser scroll range includes it.
283
+ */
284
+ contentInsetEndAdjustment?: number;
281
285
  /**
282
286
  * Number of columns to render items in.
283
287
  * @default 1
package/react.js CHANGED
@@ -166,7 +166,10 @@ function useSelector$(signalName, selector) {
166
166
  }
167
167
 
168
168
  // src/state/getContentInsetEnd.ts
169
- function getContentInsetEnd(ctx) {
169
+ function getContentInsetEndAdjustmentEnd(adjustment) {
170
+ return Math.max(0, adjustment != null ? adjustment : 0);
171
+ }
172
+ function getContentInsetEnd(ctx, contentInsetEndAdjustmentOverride) {
170
173
  var _a3, _b;
171
174
  const state = ctx.state;
172
175
  const { props } = state;
@@ -174,14 +177,21 @@ function getContentInsetEnd(ctx) {
174
177
  const contentInset = props.contentInset;
175
178
  const baseInset = contentInset != null ? contentInset : state.nativeContentInset;
176
179
  const baseEndInset = (horizontal ? baseInset == null ? void 0 : baseInset.right : baseInset == null ? void 0 : baseInset.bottom) || 0;
180
+ const contentInsetEndAdjustment = getContentInsetEndAdjustmentEnd(
181
+ contentInsetEndAdjustmentOverride != null ? contentInsetEndAdjustmentOverride : props.contentInsetEndAdjustment
182
+ );
177
183
  const anchoredEndSpaceSize = peek$(ctx, "anchoredEndSpaceSize");
178
184
  const anchoredEndInset = ((_a3 = props.anchoredEndSpace) == null ? void 0 : _a3.includeInEndInset) && anchoredEndSpaceSize ? anchoredEndSpaceSize : 0;
179
185
  const overrideInset = (_b = state.contentInsetOverride) != null ? _b : void 0;
186
+ const adjustedBaseEndInset = baseEndInset + contentInsetEndAdjustment;
180
187
  if (overrideInset) {
181
188
  const mergedInset = { bottom: 0, right: 0, ...baseInset, ...overrideInset };
182
- return Math.max((horizontal ? mergedInset.right : mergedInset.bottom) || 0, anchoredEndInset);
189
+ return Math.max(
190
+ ((horizontal ? mergedInset.right : mergedInset.bottom) || 0) + contentInsetEndAdjustment,
191
+ anchoredEndInset
192
+ );
183
193
  }
184
- return Math.max(baseEndInset, anchoredEndInset);
194
+ return Math.max(adjustedBaseEndInset, anchoredEndInset);
185
195
  }
186
196
 
187
197
  // src/state/getContentSize.ts
@@ -682,6 +692,49 @@ function isInMVCPActiveMode(state) {
682
692
  }
683
693
 
684
694
  // src/components/Container.tsx
695
+ function getContainerPositionStyle({
696
+ columnWrapperStyle,
697
+ horizontal,
698
+ hasItemSeparator,
699
+ numColumns,
700
+ otherAxisPos,
701
+ otherAxisSize
702
+ }) {
703
+ let paddingStyles;
704
+ if (columnWrapperStyle) {
705
+ const { columnGap, rowGap, gap } = columnWrapperStyle;
706
+ if (horizontal) {
707
+ paddingStyles = {
708
+ paddingBottom: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0,
709
+ paddingRight: columnGap || gap || void 0,
710
+ paddingTop: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
711
+ };
712
+ } else {
713
+ paddingStyles = {
714
+ paddingBottom: rowGap || gap || void 0,
715
+ paddingLeft: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0,
716
+ paddingRight: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
717
+ };
718
+ }
719
+ }
720
+ return horizontal ? {
721
+ boxSizing: paddingStyles ? "border-box" : void 0,
722
+ flexDirection: hasItemSeparator ? "row" : void 0,
723
+ height: otherAxisSize,
724
+ left: 0,
725
+ position: "absolute",
726
+ top: otherAxisPos,
727
+ ...paddingStyles || {}
728
+ } : {
729
+ boxSizing: paddingStyles ? "border-box" : void 0,
730
+ left: otherAxisPos,
731
+ position: "absolute",
732
+ right: numColumns > 1 ? null : 0,
733
+ top: 0,
734
+ width: otherAxisSize,
735
+ ...paddingStyles || {}
736
+ };
737
+ }
685
738
  var Container = typedMemo(function Container2({
686
739
  id,
687
740
  recycleItems,
@@ -720,42 +773,17 @@ var Container = typedMemo(function Container2({
720
773
  const resolvedSpan = Math.min(Math.max(span || 1, 1), numColumns);
721
774
  const otherAxisPos = numColumns > 1 ? `${(resolvedColumn - 1) / numColumns * 100}%` : 0;
722
775
  const otherAxisSize = numColumns > 1 ? `${resolvedSpan / numColumns * 100}%` : void 0;
723
- const style = React3.useMemo(() => {
724
- let paddingStyles;
725
- if (columnWrapperStyle) {
726
- const { columnGap, rowGap, gap } = columnWrapperStyle;
727
- if (horizontal) {
728
- paddingStyles = {
729
- paddingBottom: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0,
730
- paddingRight: columnGap || gap || void 0,
731
- paddingTop: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
732
- };
733
- } else {
734
- paddingStyles = {
735
- paddingBottom: rowGap || gap || void 0,
736
- paddingLeft: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0,
737
- paddingRight: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
738
- };
739
- }
740
- }
741
- return horizontal ? {
742
- boxSizing: paddingStyles ? "border-box" : void 0,
743
- flexDirection: ItemSeparatorComponent ? "row" : void 0,
744
- height: otherAxisSize,
745
- left: 0,
746
- position: "absolute",
747
- top: otherAxisPos,
748
- ...paddingStyles || {}
749
- } : {
750
- boxSizing: paddingStyles ? "border-box" : void 0,
751
- left: otherAxisPos,
752
- position: "absolute",
753
- right: numColumns > 1 ? null : 0,
754
- top: 0,
755
- width: otherAxisSize,
756
- ...paddingStyles || {}
757
- };
758
- }, [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns]);
776
+ const style = React3.useMemo(
777
+ () => getContainerPositionStyle({
778
+ columnWrapperStyle,
779
+ hasItemSeparator: !!ItemSeparatorComponent,
780
+ horizontal,
781
+ numColumns,
782
+ otherAxisPos,
783
+ otherAxisSize
784
+ }),
785
+ [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns, ItemSeparatorComponent]
786
+ );
759
787
  const renderedItemInfo = React3.useMemo(
760
788
  () => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
761
789
  [itemKey, data, extraData]
@@ -1066,6 +1094,9 @@ function useRafCoalescer(callback) {
1066
1094
  return coalescer;
1067
1095
  }
1068
1096
 
1097
+ // src/components/webConstants.ts
1098
+ var LEGEND_LIST_CONTENT_CONTAINER_CLASS = "legend-list-content-container";
1099
+
1069
1100
  // src/components/webScrollUtils.ts
1070
1101
  function getDocumentScrollerNode() {
1071
1102
  if (typeof document === "undefined") {
@@ -1150,6 +1181,11 @@ function resolveWindowScrollTarget({ clampedOffset, horizontal, listPos, scroll
1150
1181
  }
1151
1182
 
1152
1183
  // src/components/ListComponentScrollView.tsx
1184
+ function getContentInsetEndAdjustmentEnd2(ctx) {
1185
+ var _a3, _b;
1186
+ const adjustment = (_b = (_a3 = ctx.state) == null ? void 0 : _a3.props) == null ? void 0 : _b.contentInsetEndAdjustment;
1187
+ return Math.max(0, adjustment != null ? adjustment : 0);
1188
+ }
1153
1189
  var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView2({
1154
1190
  children,
1155
1191
  style,
@@ -1167,7 +1203,9 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
1167
1203
  onLayout,
1168
1204
  ...props
1169
1205
  }, ref) {
1206
+ var _a3, _b, _c;
1170
1207
  const ctx = useStateContext();
1208
+ const [anchoredEndSpaceSize] = useArr$(["anchoredEndSpaceSize"]);
1171
1209
  const scrollRef = React3.useRef(null);
1172
1210
  const contentRef = React3.useRef(null);
1173
1211
  const isWindowScroll = useWindowScroll;
@@ -1229,10 +1267,9 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
1229
1267
  React3.useImperativeHandle(ref, () => {
1230
1268
  const api = {
1231
1269
  getBoundingClientRect: () => {
1232
- var _a3;
1233
- return (_a3 = scrollRef.current) == null ? void 0 : _a3.getBoundingClientRect();
1270
+ var _a4;
1271
+ return (_a4 = scrollRef.current) == null ? void 0 : _a4.getBoundingClientRect();
1234
1272
  },
1235
- getContentNode: () => contentRef.current,
1236
1273
  getCurrentScrollOffset,
1237
1274
  getScrollableNode: () => resolveScrollableNode(scrollRef.current, isWindowScroll),
1238
1275
  getScrollEventTarget: () => getScrollTarget(),
@@ -1358,6 +1395,10 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
1358
1395
  },
1359
1396
  ...StyleSheet.flatten(style)
1360
1397
  };
1398
+ const contentInsetEndAdjustment = getContentInsetEndAdjustmentEnd2(ctx);
1399
+ const anchoredEndInset = ((_c = (_b = (_a3 = ctx.state) == null ? void 0 : _a3.props) == null ? void 0 : _b.anchoredEndSpace) == null ? void 0 : _c.includeInEndInset) && anchoredEndSpaceSize ? anchoredEndSpaceSize : 0;
1400
+ const renderedContentInsetEndAdjustment = Math.max(0, contentInsetEndAdjustment - anchoredEndInset);
1401
+ const contentInsetEndAdjustmentSpacerStyle = renderedContentInsetEndAdjustment ? horizontal ? { flexShrink: 0, width: renderedContentInsetEndAdjustment } : { height: renderedContentInsetEndAdjustment } : void 0;
1361
1402
  const contentStyle = {
1362
1403
  display: horizontal ? "flex" : "block",
1363
1404
  flexDirection: horizontal ? "row" : void 0,
@@ -1365,6 +1406,7 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
1365
1406
  minWidth: horizontal ? "100%" : void 0,
1366
1407
  ...StyleSheet.flatten(contentContainerStyle)
1367
1408
  };
1409
+ const className = contentContainerClassName ? `${LEGEND_LIST_CONTENT_CONTAINER_CLASS} ${contentContainerClassName}` : LEGEND_LIST_CONTENT_CONTAINER_CLASS;
1368
1410
  const {
1369
1411
  contentContainerClassName: _contentContainerClassName,
1370
1412
  contentInset: _contentInset,
@@ -1373,7 +1415,7 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
1373
1415
  useWindowScroll: _useWindowScroll,
1374
1416
  ...webProps
1375
1417
  } = props;
1376
- return /* @__PURE__ */ React3__namespace.createElement("div", { ref: scrollRef, ...webProps, style: scrollViewStyle }, refreshControl, /* @__PURE__ */ React3__namespace.createElement("div", { className: contentContainerClassName, ref: contentRef, style: contentStyle }, children));
1418
+ return /* @__PURE__ */ React3__namespace.createElement("div", { ref: scrollRef, ...webProps, style: scrollViewStyle }, refreshControl, /* @__PURE__ */ React3__namespace.createElement("div", { className, ref: contentRef, style: contentStyle }, children, contentInsetEndAdjustmentSpacerStyle ? /* @__PURE__ */ React3__namespace.createElement("div", { "aria-hidden": true, style: contentInsetEndAdjustmentSpacerStyle }) : null));
1377
1419
  });
1378
1420
  function useValueListener$(key, callback) {
1379
1421
  const ctx = useStateContext();
@@ -1401,11 +1443,18 @@ function getScrollAdjustAxis(horizontal) {
1401
1443
  y: 1
1402
1444
  };
1403
1445
  }
1446
+ function resolveScrollAdjustContentNode(el, contentNode) {
1447
+ if ((contentNode == null ? void 0 : contentNode.isConnected) && contentNode.parentElement === el) {
1448
+ return contentNode;
1449
+ }
1450
+ return el.querySelector(`:scope > .${LEGEND_LIST_CONTENT_CONTAINER_CLASS}`);
1451
+ }
1404
1452
  function ScrollAdjust() {
1405
1453
  const ctx = useStateContext();
1406
1454
  const lastScrollOffsetRef = React3__namespace.useRef(0);
1407
1455
  const resetPaddingRafRef = React3__namespace.useRef(void 0);
1408
1456
  const resetPaddingBaselineRef = React3__namespace.useRef(void 0);
1457
+ const contentNodeRef = React3__namespace.useRef(null);
1409
1458
  const callback = React3__namespace.useCallback(() => {
1410
1459
  var _a3, _b;
1411
1460
  const scrollAdjust = peek$(ctx, "scrollAdjust");
@@ -1416,9 +1465,10 @@ function ScrollAdjust() {
1416
1465
  const scrollDelta = scrollOffset - lastScrollOffsetRef.current;
1417
1466
  if (scrollDelta !== 0) {
1418
1467
  const axis = getScrollAdjustAxis(!!ctx.state.props.horizontal);
1419
- const contentNode = scrollView.getContentNode();
1420
1468
  const prevScroll = scrollView.getCurrentScrollOffset();
1421
1469
  const el = scrollView.getScrollableNode();
1470
+ const contentNode = resolveScrollAdjustContentNode(el, contentNodeRef.current);
1471
+ contentNodeRef.current = contentNode;
1422
1472
  const scrollBy = () => scrollView.scrollBy(axis.x * scrollDelta, axis.y * scrollDelta);
1423
1473
  if (!contentNode) {
1424
1474
  scrollBy();
@@ -3273,6 +3323,15 @@ function checkFinishedScrollFallback(ctx) {
3273
3323
  }
3274
3324
 
3275
3325
  // src/core/initialScrollLifecycle.ts
3326
+ function retargetActiveInitialScrollAtEnd(ctx) {
3327
+ var _a3;
3328
+ const state = ctx.state;
3329
+ const initialScroll = state.initialScroll;
3330
+ if (!initialScroll || state.didFinishInitialScroll || ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || initialScroll.viewPosition !== 1 || state.props.data.length === 0) {
3331
+ return false;
3332
+ }
3333
+ return advanceCurrentInitialScrollSession(ctx, { forceScroll: true });
3334
+ }
3276
3335
  function handleInitialScrollLayoutReady(ctx) {
3277
3336
  var _a3;
3278
3337
  if (!ctx.state.initialScroll) {
@@ -5339,6 +5398,22 @@ function maybeUpdateAnchoredEndSpace(ctx) {
5339
5398
  return nextSize;
5340
5399
  }
5341
5400
 
5401
+ // src/core/updateContentInsetEndAdjustment.ts
5402
+ function updateContentInsetEndAdjustment(ctx, previousContentInsetEndAdjustment) {
5403
+ const state = ctx.state;
5404
+ const previousContentInsetEnd = getContentInsetEnd(ctx, previousContentInsetEndAdjustment);
5405
+ const nextContentInsetEnd = getContentInsetEnd(ctx);
5406
+ const insetDiff = nextContentInsetEnd - previousContentInsetEnd;
5407
+ if (insetDiff !== 0) {
5408
+ const wasWithinEndThreshold = !!peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
5409
+ updateScroll(ctx, state.scroll, true, { markHasScrolled: false });
5410
+ const didRetargetInitialScroll = retargetActiveInitialScrollAtEnd(ctx);
5411
+ if (!didRetargetInitialScroll && wasWithinEndThreshold && (insetDiff > 0)) {
5412
+ requestAdjust(ctx, insetDiff);
5413
+ }
5414
+ }
5415
+ }
5416
+
5342
5417
  // src/core/updateItemSize.ts
5343
5418
  function runOrScheduleMVCPRecalculate(ctx) {
5344
5419
  const state = ctx.state;
@@ -5686,8 +5761,14 @@ function createImperativeHandle(ctx) {
5686
5761
  startBuffered: state.startBuffered
5687
5762
  }),
5688
5763
  reportContentInset: (inset) => {
5764
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
5765
+ const previousInset = state.contentInsetOverride;
5689
5766
  state.contentInsetOverride = inset != null ? inset : void 0;
5767
+ const didChange = ((_a3 = previousInset == null ? void 0 : previousInset.top) != null ? _a3 : 0) !== ((_c = (_b = state.contentInsetOverride) == null ? void 0 : _b.top) != null ? _c : 0) || ((_d = previousInset == null ? void 0 : previousInset.bottom) != null ? _d : 0) !== ((_f = (_e = state.contentInsetOverride) == null ? void 0 : _e.bottom) != null ? _f : 0) || ((_g = previousInset == null ? void 0 : previousInset.left) != null ? _g : 0) !== ((_i = (_h = state.contentInsetOverride) == null ? void 0 : _h.left) != null ? _i : 0) || ((_j = previousInset == null ? void 0 : previousInset.right) != null ? _j : 0) !== ((_l = (_k = state.contentInsetOverride) == null ? void 0 : _k.right) != null ? _l : 0);
5690
5768
  updateScroll(ctx, state.scroll, true, { markHasScrolled: false });
5769
+ if (didChange) {
5770
+ retargetActiveInitialScrollAtEnd(ctx);
5771
+ }
5691
5772
  },
5692
5773
  scrollIndexIntoView: (options) => runScrollWithPromise(() => scrollIndexIntoView(options)),
5693
5774
  scrollItemIntoView: ({ item, ...props }) => runScrollWithPromise(() => {
@@ -5988,6 +6069,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
5988
6069
  data: dataProp = [],
5989
6070
  dataVersion,
5990
6071
  drawDistance = 250,
6072
+ contentInsetEndAdjustment,
5991
6073
  estimatedItemSize = 100,
5992
6074
  estimatedListSize,
5993
6075
  extraData,
@@ -6097,6 +6179,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6097
6179
  const combinedRef = useCombinedRef(refScroller, refScrollView);
6098
6180
  const keyExtractor = keyExtractorProp != null ? keyExtractorProp : ((_item, index) => index.toString());
6099
6181
  const stickyHeaderIndices = stickyHeaderIndicesProp != null ? stickyHeaderIndicesProp : stickyIndicesDeprecated;
6182
+ const contentInsetEndAdjustmentResolved = contentInsetEndAdjustment ;
6183
+ const previousContentInsetEndAdjustmentRef = React3.useRef(contentInsetEndAdjustmentResolved);
6100
6184
  const alwaysRenderIndices = React3.useMemo(() => {
6101
6185
  const indices = getAlwaysRenderIndices(alwaysRender, dataProp, keyExtractor, anchoredEndSpace == null ? void 0 : anchoredEndSpace.anchorIndex);
6102
6186
  return { arr: indices, set: new Set(indices) };
@@ -6216,6 +6300,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6216
6300
  anchoredEndSpace: anchoredEndSpaceResolved,
6217
6301
  animatedProps: animatedPropsInternal,
6218
6302
  contentInset,
6303
+ contentInsetEndAdjustment: contentInsetEndAdjustmentResolved,
6219
6304
  data: dataProp,
6220
6305
  dataVersion,
6221
6306
  drawDistance,
@@ -6333,6 +6418,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6333
6418
  didAnchoredEndSpaceAnchorIndexChange,
6334
6419
  numColumnsProp
6335
6420
  ]);
6421
+ React3.useLayoutEffect(() => {
6422
+ const previousContentInsetEndAdjustment = previousContentInsetEndAdjustmentRef.current;
6423
+ previousContentInsetEndAdjustmentRef.current = contentInsetEndAdjustmentResolved;
6424
+ updateContentInsetEndAdjustment(ctx, previousContentInsetEndAdjustment);
6425
+ }, [ctx, contentInsetEndAdjustmentResolved]);
6336
6426
  const onLayoutFooter = React3.useCallback(
6337
6427
  (layout) => {
6338
6428
  if (!usesBootstrapInitialScroll) {