@legendapp/list 3.1.0 → 3.1.1

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/react.mjs CHANGED
@@ -1834,6 +1834,67 @@ function WebAnchoredEndSpace({ horizontal }) {
1834
1834
  return /* @__PURE__ */ React3.createElement("div", { style }, null);
1835
1835
  }
1836
1836
 
1837
+ // src/core/doMaintainScrollAtEnd.ts
1838
+ function doMaintainScrollAtEnd(ctx) {
1839
+ const state = ctx.state;
1840
+ const {
1841
+ didContainersLayout,
1842
+ pendingNativeMVCPAdjust,
1843
+ refScroller,
1844
+ props: { maintainScrollAtEnd }
1845
+ } = state;
1846
+ const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
1847
+ const shouldMaintainScrollAtEnd = !!(isWithinMaintainScrollAtEndThreshold && maintainScrollAtEnd && didContainersLayout);
1848
+ if (pendingNativeMVCPAdjust) {
1849
+ state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
1850
+ return false;
1851
+ }
1852
+ state.pendingMaintainScrollAtEnd = false;
1853
+ if (shouldMaintainScrollAtEnd) {
1854
+ const contentSize = getContentSize(ctx);
1855
+ if (contentSize < state.scrollLength) {
1856
+ state.scroll = 0;
1857
+ }
1858
+ if (!state.maintainingScrollAtEnd) {
1859
+ const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
1860
+ const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
1861
+ state.maintainingScrollAtEnd = pendingState;
1862
+ requestAnimationFrame(() => {
1863
+ if (peek$(ctx, "isWithinMaintainScrollAtEndThreshold")) {
1864
+ state.maintainingScrollAtEnd = activeState;
1865
+ const scroller = refScroller.current;
1866
+ if (state.props.horizontal && isHorizontalRTL(state)) {
1867
+ const currentContentSize = getContentSize(ctx);
1868
+ const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
1869
+ const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
1870
+ scroller == null ? void 0 : scroller.scrollTo({
1871
+ animated: maintainScrollAtEnd.animated,
1872
+ x: nativeOffset,
1873
+ y: 0
1874
+ });
1875
+ } else {
1876
+ scroller == null ? void 0 : scroller.scrollToEnd({
1877
+ animated: maintainScrollAtEnd.animated
1878
+ });
1879
+ }
1880
+ setTimeout(
1881
+ () => {
1882
+ if (state.maintainingScrollAtEnd === activeState) {
1883
+ state.maintainingScrollAtEnd = void 0;
1884
+ }
1885
+ },
1886
+ maintainScrollAtEnd.animated ? 500 : 0
1887
+ );
1888
+ } else if (state.maintainingScrollAtEnd === pendingState) {
1889
+ state.maintainingScrollAtEnd = void 0;
1890
+ }
1891
+ });
1892
+ }
1893
+ return true;
1894
+ }
1895
+ return false;
1896
+ }
1897
+
1837
1898
  // src/core/updateContentMetricsState.ts
1838
1899
  function getRawContentLength(ctx) {
1839
1900
  var _a3, _b, _c;
@@ -2501,10 +2562,12 @@ function requestAdjust(ctx, positionDiff, dataChanged) {
2501
2562
  // src/core/updateContentMetrics.ts
2502
2563
  var SCROLL_ADJUST_EPSILON = 0.1;
2503
2564
  function setContentLengthSignal(ctx, signalName, size) {
2504
- if (peek$(ctx, signalName) !== size) {
2565
+ const didChange = peek$(ctx, signalName) !== size;
2566
+ if (didChange) {
2505
2567
  set$(ctx, signalName, size);
2506
2568
  updateContentMetricsState(ctx);
2507
2569
  }
2570
+ return didChange;
2508
2571
  }
2509
2572
  function shouldAdjustForHeaderSizeChange(ctx, previousHeaderSize, nextHeaderSize) {
2510
2573
  const { didContainersLayout, didFinishInitialScroll, props, scroll, scrollingTo } = ctx.state;
@@ -2528,7 +2591,7 @@ function setHeaderSize(ctx, size) {
2528
2591
  state.didMeasureHeader = true;
2529
2592
  }
2530
2593
  function setFooterSize(ctx, size) {
2531
- setContentLengthSignal(ctx, "footerSize", size);
2594
+ return setContentLengthSignal(ctx, "footerSize", size);
2532
2595
  }
2533
2596
  function areInsetsEqual(left, right) {
2534
2597
  var _a3, _b, _c, _d, _e, _f, _g, _h;
@@ -2622,14 +2685,25 @@ var ListComponent = typedMemo(function ListComponent2({
2622
2685
  );
2623
2686
  const ScrollComponent = renderScrollComponent ? CustomScrollComponent : ListComponentScrollView;
2624
2687
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
2688
+ const updateFooterSize = useCallback(
2689
+ (size, afterSizeUpdate) => {
2690
+ var _a3;
2691
+ const didFooterSizeChange = setFooterSize(ctx, size);
2692
+ afterSizeUpdate == null ? void 0 : afterSizeUpdate();
2693
+ if (didFooterSizeChange && ((_a3 = ctx.state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onFooterLayout)) {
2694
+ doMaintainScrollAtEnd(ctx);
2695
+ }
2696
+ },
2697
+ [ctx]
2698
+ );
2625
2699
  useLayoutEffect(() => {
2626
2700
  if (!ListHeaderComponent) {
2627
2701
  setHeaderSize(ctx, 0);
2628
2702
  }
2629
2703
  if (!ListFooterComponent) {
2630
- setFooterSize(ctx, 0);
2704
+ updateFooterSize(0);
2631
2705
  }
2632
- }, [ListHeaderComponent, ListFooterComponent, ctx]);
2706
+ }, [ListHeaderComponent, ListFooterComponent, ctx, updateFooterSize]);
2633
2707
  const onLayoutHeader = useCallback(
2634
2708
  (rect) => {
2635
2709
  const size = rect[horizontal ? "width" : "height"];
@@ -2640,10 +2714,11 @@ var ListComponent = typedMemo(function ListComponent2({
2640
2714
  const onLayoutFooterInternal = useCallback(
2641
2715
  (rect, fromLayoutEffect) => {
2642
2716
  const size = rect[horizontal ? "width" : "height"];
2643
- setFooterSize(ctx, size);
2644
- onLayoutFooter == null ? void 0 : onLayoutFooter(rect, fromLayoutEffect);
2717
+ updateFooterSize(size, () => {
2718
+ onLayoutFooter == null ? void 0 : onLayoutFooter(rect, fromLayoutEffect);
2719
+ });
2645
2720
  },
2646
- [ctx, horizontal, onLayoutFooter]
2721
+ [horizontal, onLayoutFooter, updateFooterSize]
2647
2722
  );
2648
2723
  return /* @__PURE__ */ React3.createElement(
2649
2724
  SnapOrScroll,
@@ -2915,67 +2990,6 @@ function clampScrollOffset(ctx, offset, scrollTarget) {
2915
2990
  return clampedOffset;
2916
2991
  }
2917
2992
 
2918
- // src/core/doMaintainScrollAtEnd.ts
2919
- function doMaintainScrollAtEnd(ctx) {
2920
- const state = ctx.state;
2921
- const {
2922
- didContainersLayout,
2923
- pendingNativeMVCPAdjust,
2924
- refScroller,
2925
- props: { maintainScrollAtEnd }
2926
- } = state;
2927
- const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
2928
- const shouldMaintainScrollAtEnd = !!(isWithinMaintainScrollAtEndThreshold && maintainScrollAtEnd && didContainersLayout);
2929
- if (pendingNativeMVCPAdjust) {
2930
- state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
2931
- return false;
2932
- }
2933
- state.pendingMaintainScrollAtEnd = false;
2934
- if (shouldMaintainScrollAtEnd) {
2935
- const contentSize = getContentSize(ctx);
2936
- if (contentSize < state.scrollLength) {
2937
- state.scroll = 0;
2938
- }
2939
- if (!state.maintainingScrollAtEnd) {
2940
- const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
2941
- const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
2942
- state.maintainingScrollAtEnd = pendingState;
2943
- requestAnimationFrame(() => {
2944
- if (peek$(ctx, "isWithinMaintainScrollAtEndThreshold")) {
2945
- state.maintainingScrollAtEnd = activeState;
2946
- const scroller = refScroller.current;
2947
- if (state.props.horizontal && isHorizontalRTL(state)) {
2948
- const currentContentSize = getContentSize(ctx);
2949
- const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
2950
- const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
2951
- scroller == null ? void 0 : scroller.scrollTo({
2952
- animated: maintainScrollAtEnd.animated,
2953
- x: nativeOffset,
2954
- y: 0
2955
- });
2956
- } else {
2957
- scroller == null ? void 0 : scroller.scrollToEnd({
2958
- animated: maintainScrollAtEnd.animated
2959
- });
2960
- }
2961
- setTimeout(
2962
- () => {
2963
- if (state.maintainingScrollAtEnd === activeState) {
2964
- state.maintainingScrollAtEnd = void 0;
2965
- }
2966
- },
2967
- maintainScrollAtEnd.animated ? 500 : 0
2968
- );
2969
- } else if (state.maintainingScrollAtEnd === pendingState) {
2970
- state.maintainingScrollAtEnd = void 0;
2971
- }
2972
- });
2973
- }
2974
- return true;
2975
- }
2976
- return false;
2977
- }
2978
-
2979
2993
  // src/core/mvcp.ts
2980
2994
  var MVCP_POSITION_EPSILON = 0.1;
2981
2995
  var MVCP_ANCHOR_LOCK_TTL_MS = 300;
@@ -6799,12 +6813,13 @@ function getRenderedItem(ctx, key) {
6799
6813
 
6800
6814
  // src/utils/normalizeMaintainScrollAtEnd.ts
6801
6815
  function normalizeMaintainScrollAtEndOn(on, hasExplicitOn) {
6802
- var _a3, _b, _c;
6816
+ var _a3, _b, _c, _d;
6803
6817
  return {
6804
6818
  animated: false,
6805
6819
  onDataChange: hasExplicitOn ? (_a3 = on == null ? void 0 : on.dataChange) != null ? _a3 : false : true,
6806
- onItemLayout: hasExplicitOn ? (_b = on == null ? void 0 : on.itemLayout) != null ? _b : false : true,
6807
- onLayout: hasExplicitOn ? (_c = on == null ? void 0 : on.layout) != null ? _c : false : true
6820
+ onFooterLayout: hasExplicitOn ? (_b = on == null ? void 0 : on.footerLayout) != null ? _b : false : true,
6821
+ onItemLayout: hasExplicitOn ? (_c = on == null ? void 0 : on.itemLayout) != null ? _c : false : true,
6822
+ onLayout: hasExplicitOn ? (_d = on == null ? void 0 : on.layout) != null ? _d : false : true
6808
6823
  };
6809
6824
  }
6810
6825
  function normalizeMaintainScrollAtEnd(value) {
package/reanimated.d.ts CHANGED
@@ -461,6 +461,7 @@ interface AlwaysRenderConfig {
461
461
  }
462
462
  interface MaintainScrollAtEndOnOptions {
463
463
  dataChange?: boolean;
464
+ footerLayout?: boolean;
464
465
  itemLayout?: boolean;
465
466
  layout?: boolean;
466
467
  }
package/section-list.d.ts CHANGED
@@ -517,6 +517,7 @@ interface AlwaysRenderConfig {
517
517
  }
518
518
  interface MaintainScrollAtEndOnOptions {
519
519
  dataChange?: boolean;
520
+ footerLayout?: boolean;
520
521
  itemLayout?: boolean;
521
522
  layout?: boolean;
522
523
  }