@legendapp/list 3.0.0-beta.41 → 3.0.0-beta.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -576,8 +576,7 @@ interface InternalState$1 {
576
576
  otherAxisSize?: number;
577
577
  pendingNativeMVCPAdjust?: {
578
578
  amount: number;
579
- closestDistanceToClamp: number;
580
- hasApproachedClamp: boolean;
579
+ furthestProgressTowardAmount: number;
581
580
  manualApplied: number;
582
581
  startScroll: number;
583
582
  };
package/index.js CHANGED
@@ -2117,6 +2117,17 @@ function getPredictedNativeClamp(state, unresolvedAmount, totalSize) {
2117
2117
  }
2118
2118
  return 0;
2119
2119
  }
2120
+ function getProgressTowardAmount(targetDelta, nativeDelta) {
2121
+ return targetDelta < 0 ? -nativeDelta : nativeDelta;
2122
+ }
2123
+ function settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta) {
2124
+ const state = ctx.state;
2125
+ state.pendingNativeMVCPAdjust = void 0;
2126
+ const remaining = remainingAfterManual - nativeDelta;
2127
+ if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
2128
+ requestAdjust(ctx, remaining);
2129
+ }
2130
+ }
2120
2131
  function maybeApplyPredictedNativeMVCPAdjust(ctx) {
2121
2132
  const state = ctx.state;
2122
2133
  const pending = state.pendingNativeMVCPAdjust;
@@ -2134,6 +2145,7 @@ function maybeApplyPredictedNativeMVCPAdjust(ctx) {
2134
2145
  }
2135
2146
  pending.manualApplied = manualDesired;
2136
2147
  requestAdjust(ctx, manualDesired);
2148
+ pending.furthestProgressTowardAmount = 0;
2137
2149
  }
2138
2150
  function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2139
2151
  const state = ctx.state;
@@ -2144,6 +2156,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2144
2156
  const remainingAfterManual = pending.amount - pending.manualApplied;
2145
2157
  const nativeDelta = newScroll - (pending.startScroll + pending.manualApplied);
2146
2158
  const isWrongDirection = remainingAfterManual < 0 && nativeDelta > MVCP_POSITION_EPSILON || remainingAfterManual > 0 && nativeDelta < -MVCP_POSITION_EPSILON;
2159
+ const progressTowardAmount = getProgressTowardAmount(remainingAfterManual, nativeDelta);
2147
2160
  if (Math.abs(remainingAfterManual) <= MVCP_POSITION_EPSILON) {
2148
2161
  state.pendingNativeMVCPAdjust = void 0;
2149
2162
  return true;
@@ -2152,27 +2165,30 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2152
2165
  state.pendingNativeMVCPAdjust = void 0;
2153
2166
  return false;
2154
2167
  }
2168
+ if (progressTowardAmount + MVCP_POSITION_EPSILON >= Math.abs(remainingAfterManual)) {
2169
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2170
+ return true;
2171
+ }
2155
2172
  const expectedNativeClampScroll = Math.max(0, getContentSize(ctx) - state.scrollLength);
2156
2173
  const distanceToClamp = Math.abs(newScroll - expectedNativeClampScroll);
2157
- const didApproachClamp = distanceToClamp < pending.closestDistanceToClamp - MVCP_POSITION_EPSILON;
2158
- const didMoveAwayAfterApproach = pending.hasApproachedClamp && distanceToClamp > pending.closestDistanceToClamp + MVCP_POSITION_EPSILON;
2159
- if (didApproachClamp) {
2160
- pending.closestDistanceToClamp = distanceToClamp;
2161
- pending.hasApproachedClamp = true;
2162
- } else if (didMoveAwayAfterApproach) {
2163
- state.pendingNativeMVCPAdjust = void 0;
2164
- return false;
2165
- }
2166
2174
  const isAtExpectedNativeClamp = distanceToClamp <= NATIVE_END_CLAMP_EPSILON;
2167
- if (!isAtExpectedNativeClamp) {
2175
+ if (isAtExpectedNativeClamp) {
2176
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2177
+ return true;
2178
+ }
2179
+ if (state.pendingMaintainScrollAtEnd && state.isAtEnd && progressTowardAmount > MVCP_POSITION_EPSILON) {
2180
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2181
+ return true;
2182
+ }
2183
+ if (progressTowardAmount > pending.furthestProgressTowardAmount + MVCP_POSITION_EPSILON) {
2184
+ pending.furthestProgressTowardAmount = progressTowardAmount;
2168
2185
  return false;
2169
2186
  }
2170
- state.pendingNativeMVCPAdjust = void 0;
2171
- const remaining = remainingAfterManual - nativeDelta;
2172
- if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
2173
- requestAdjust(ctx, remaining);
2187
+ if (pending.furthestProgressTowardAmount > MVCP_POSITION_EPSILON && progressTowardAmount < pending.furthestProgressTowardAmount - MVCP_POSITION_EPSILON) {
2188
+ state.pendingNativeMVCPAdjust = void 0;
2189
+ return false;
2174
2190
  }
2175
- return true;
2191
+ return false;
2176
2192
  }
2177
2193
  function prepareMVCP(ctx, dataChanged) {
2178
2194
  const state = ctx.state;
@@ -2303,10 +2319,7 @@ function prepareMVCP(ctx, dataChanged) {
2303
2319
  if (shouldQueueNativeMVCPAdjust()) {
2304
2320
  state.pendingNativeMVCPAdjust = {
2305
2321
  amount: positionDiff,
2306
- closestDistanceToClamp: Math.abs(
2307
- prevScroll - Math.max(0, getContentSize(ctx) - state.scrollLength)
2308
- ),
2309
- hasApproachedClamp: false,
2322
+ furthestProgressTowardAmount: 0,
2310
2323
  manualApplied: 0,
2311
2324
  startScroll: prevScroll
2312
2325
  };
package/index.mjs CHANGED
@@ -2096,6 +2096,17 @@ function getPredictedNativeClamp(state, unresolvedAmount, totalSize) {
2096
2096
  }
2097
2097
  return 0;
2098
2098
  }
2099
+ function getProgressTowardAmount(targetDelta, nativeDelta) {
2100
+ return targetDelta < 0 ? -nativeDelta : nativeDelta;
2101
+ }
2102
+ function settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta) {
2103
+ const state = ctx.state;
2104
+ state.pendingNativeMVCPAdjust = void 0;
2105
+ const remaining = remainingAfterManual - nativeDelta;
2106
+ if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
2107
+ requestAdjust(ctx, remaining);
2108
+ }
2109
+ }
2099
2110
  function maybeApplyPredictedNativeMVCPAdjust(ctx) {
2100
2111
  const state = ctx.state;
2101
2112
  const pending = state.pendingNativeMVCPAdjust;
@@ -2113,6 +2124,7 @@ function maybeApplyPredictedNativeMVCPAdjust(ctx) {
2113
2124
  }
2114
2125
  pending.manualApplied = manualDesired;
2115
2126
  requestAdjust(ctx, manualDesired);
2127
+ pending.furthestProgressTowardAmount = 0;
2116
2128
  }
2117
2129
  function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2118
2130
  const state = ctx.state;
@@ -2123,6 +2135,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2123
2135
  const remainingAfterManual = pending.amount - pending.manualApplied;
2124
2136
  const nativeDelta = newScroll - (pending.startScroll + pending.manualApplied);
2125
2137
  const isWrongDirection = remainingAfterManual < 0 && nativeDelta > MVCP_POSITION_EPSILON || remainingAfterManual > 0 && nativeDelta < -MVCP_POSITION_EPSILON;
2138
+ const progressTowardAmount = getProgressTowardAmount(remainingAfterManual, nativeDelta);
2126
2139
  if (Math.abs(remainingAfterManual) <= MVCP_POSITION_EPSILON) {
2127
2140
  state.pendingNativeMVCPAdjust = void 0;
2128
2141
  return true;
@@ -2131,27 +2144,30 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2131
2144
  state.pendingNativeMVCPAdjust = void 0;
2132
2145
  return false;
2133
2146
  }
2147
+ if (progressTowardAmount + MVCP_POSITION_EPSILON >= Math.abs(remainingAfterManual)) {
2148
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2149
+ return true;
2150
+ }
2134
2151
  const expectedNativeClampScroll = Math.max(0, getContentSize(ctx) - state.scrollLength);
2135
2152
  const distanceToClamp = Math.abs(newScroll - expectedNativeClampScroll);
2136
- const didApproachClamp = distanceToClamp < pending.closestDistanceToClamp - MVCP_POSITION_EPSILON;
2137
- const didMoveAwayAfterApproach = pending.hasApproachedClamp && distanceToClamp > pending.closestDistanceToClamp + MVCP_POSITION_EPSILON;
2138
- if (didApproachClamp) {
2139
- pending.closestDistanceToClamp = distanceToClamp;
2140
- pending.hasApproachedClamp = true;
2141
- } else if (didMoveAwayAfterApproach) {
2142
- state.pendingNativeMVCPAdjust = void 0;
2143
- return false;
2144
- }
2145
2153
  const isAtExpectedNativeClamp = distanceToClamp <= NATIVE_END_CLAMP_EPSILON;
2146
- if (!isAtExpectedNativeClamp) {
2154
+ if (isAtExpectedNativeClamp) {
2155
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2156
+ return true;
2157
+ }
2158
+ if (state.pendingMaintainScrollAtEnd && state.isAtEnd && progressTowardAmount > MVCP_POSITION_EPSILON) {
2159
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2160
+ return true;
2161
+ }
2162
+ if (progressTowardAmount > pending.furthestProgressTowardAmount + MVCP_POSITION_EPSILON) {
2163
+ pending.furthestProgressTowardAmount = progressTowardAmount;
2147
2164
  return false;
2148
2165
  }
2149
- state.pendingNativeMVCPAdjust = void 0;
2150
- const remaining = remainingAfterManual - nativeDelta;
2151
- if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
2152
- requestAdjust(ctx, remaining);
2166
+ if (pending.furthestProgressTowardAmount > MVCP_POSITION_EPSILON && progressTowardAmount < pending.furthestProgressTowardAmount - MVCP_POSITION_EPSILON) {
2167
+ state.pendingNativeMVCPAdjust = void 0;
2168
+ return false;
2153
2169
  }
2154
- return true;
2170
+ return false;
2155
2171
  }
2156
2172
  function prepareMVCP(ctx, dataChanged) {
2157
2173
  const state = ctx.state;
@@ -2282,10 +2298,7 @@ function prepareMVCP(ctx, dataChanged) {
2282
2298
  if (shouldQueueNativeMVCPAdjust()) {
2283
2299
  state.pendingNativeMVCPAdjust = {
2284
2300
  amount: positionDiff,
2285
- closestDistanceToClamp: Math.abs(
2286
- prevScroll - Math.max(0, getContentSize(ctx) - state.scrollLength)
2287
- ),
2288
- hasApproachedClamp: false,
2301
+ furthestProgressTowardAmount: 0,
2289
2302
  manualApplied: 0,
2290
2303
  startScroll: prevScroll
2291
2304
  };
package/index.native.js CHANGED
@@ -1620,6 +1620,17 @@ function getPredictedNativeClamp(state, unresolvedAmount, totalSize) {
1620
1620
  }
1621
1621
  return 0;
1622
1622
  }
1623
+ function getProgressTowardAmount(targetDelta, nativeDelta) {
1624
+ return targetDelta < 0 ? -nativeDelta : nativeDelta;
1625
+ }
1626
+ function settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta) {
1627
+ const state = ctx.state;
1628
+ state.pendingNativeMVCPAdjust = void 0;
1629
+ const remaining = remainingAfterManual - nativeDelta;
1630
+ if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
1631
+ requestAdjust(ctx, remaining, true);
1632
+ }
1633
+ }
1623
1634
  function maybeApplyPredictedNativeMVCPAdjust(ctx) {
1624
1635
  const state = ctx.state;
1625
1636
  const pending = state.pendingNativeMVCPAdjust;
@@ -1637,6 +1648,7 @@ function maybeApplyPredictedNativeMVCPAdjust(ctx) {
1637
1648
  }
1638
1649
  pending.manualApplied = manualDesired;
1639
1650
  requestAdjust(ctx, manualDesired, true);
1651
+ pending.furthestProgressTowardAmount = 0;
1640
1652
  }
1641
1653
  function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
1642
1654
  const state = ctx.state;
@@ -1647,6 +1659,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
1647
1659
  const remainingAfterManual = pending.amount - pending.manualApplied;
1648
1660
  const nativeDelta = newScroll - (pending.startScroll + pending.manualApplied);
1649
1661
  const isWrongDirection = remainingAfterManual < 0 && nativeDelta > MVCP_POSITION_EPSILON || remainingAfterManual > 0 && nativeDelta < -MVCP_POSITION_EPSILON;
1662
+ const progressTowardAmount = getProgressTowardAmount(remainingAfterManual, nativeDelta);
1650
1663
  if (Math.abs(remainingAfterManual) <= MVCP_POSITION_EPSILON) {
1651
1664
  state.pendingNativeMVCPAdjust = void 0;
1652
1665
  return true;
@@ -1655,27 +1668,30 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
1655
1668
  state.pendingNativeMVCPAdjust = void 0;
1656
1669
  return false;
1657
1670
  }
1671
+ if (progressTowardAmount + MVCP_POSITION_EPSILON >= Math.abs(remainingAfterManual)) {
1672
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
1673
+ return true;
1674
+ }
1658
1675
  const expectedNativeClampScroll = Math.max(0, getContentSize(ctx) - state.scrollLength);
1659
1676
  const distanceToClamp = Math.abs(newScroll - expectedNativeClampScroll);
1660
- const didApproachClamp = distanceToClamp < pending.closestDistanceToClamp - MVCP_POSITION_EPSILON;
1661
- const didMoveAwayAfterApproach = pending.hasApproachedClamp && distanceToClamp > pending.closestDistanceToClamp + MVCP_POSITION_EPSILON;
1662
- if (didApproachClamp) {
1663
- pending.closestDistanceToClamp = distanceToClamp;
1664
- pending.hasApproachedClamp = true;
1665
- } else if (didMoveAwayAfterApproach) {
1666
- state.pendingNativeMVCPAdjust = void 0;
1667
- return false;
1668
- }
1669
1677
  const isAtExpectedNativeClamp = distanceToClamp <= NATIVE_END_CLAMP_EPSILON;
1670
- if (!isAtExpectedNativeClamp) {
1678
+ if (isAtExpectedNativeClamp) {
1679
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
1680
+ return true;
1681
+ }
1682
+ if (state.pendingMaintainScrollAtEnd && state.isAtEnd && progressTowardAmount > MVCP_POSITION_EPSILON) {
1683
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
1684
+ return true;
1685
+ }
1686
+ if (progressTowardAmount > pending.furthestProgressTowardAmount + MVCP_POSITION_EPSILON) {
1687
+ pending.furthestProgressTowardAmount = progressTowardAmount;
1671
1688
  return false;
1672
1689
  }
1673
- state.pendingNativeMVCPAdjust = void 0;
1674
- const remaining = remainingAfterManual - nativeDelta;
1675
- if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
1676
- requestAdjust(ctx, remaining, true);
1690
+ if (pending.furthestProgressTowardAmount > MVCP_POSITION_EPSILON && progressTowardAmount < pending.furthestProgressTowardAmount - MVCP_POSITION_EPSILON) {
1691
+ state.pendingNativeMVCPAdjust = void 0;
1692
+ return false;
1677
1693
  }
1678
- return true;
1694
+ return false;
1679
1695
  }
1680
1696
  function prepareMVCP(ctx, dataChanged) {
1681
1697
  const state = ctx.state;
@@ -1814,10 +1830,7 @@ function prepareMVCP(ctx, dataChanged) {
1814
1830
  if (shouldQueueNativeMVCPAdjust(dataChanged, state, positionDiff, prevTotalSize, prevScroll, scrollTarget)) {
1815
1831
  state.pendingNativeMVCPAdjust = {
1816
1832
  amount: positionDiff,
1817
- closestDistanceToClamp: Math.abs(
1818
- prevScroll - Math.max(0, getContentSize(ctx) - state.scrollLength)
1819
- ),
1820
- hasApproachedClamp: false,
1833
+ furthestProgressTowardAmount: 0,
1821
1834
  manualApplied: 0,
1822
1835
  startScroll: prevScroll
1823
1836
  };
package/index.native.mjs CHANGED
@@ -1599,6 +1599,17 @@ function getPredictedNativeClamp(state, unresolvedAmount, totalSize) {
1599
1599
  }
1600
1600
  return 0;
1601
1601
  }
1602
+ function getProgressTowardAmount(targetDelta, nativeDelta) {
1603
+ return targetDelta < 0 ? -nativeDelta : nativeDelta;
1604
+ }
1605
+ function settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta) {
1606
+ const state = ctx.state;
1607
+ state.pendingNativeMVCPAdjust = void 0;
1608
+ const remaining = remainingAfterManual - nativeDelta;
1609
+ if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
1610
+ requestAdjust(ctx, remaining, true);
1611
+ }
1612
+ }
1602
1613
  function maybeApplyPredictedNativeMVCPAdjust(ctx) {
1603
1614
  const state = ctx.state;
1604
1615
  const pending = state.pendingNativeMVCPAdjust;
@@ -1616,6 +1627,7 @@ function maybeApplyPredictedNativeMVCPAdjust(ctx) {
1616
1627
  }
1617
1628
  pending.manualApplied = manualDesired;
1618
1629
  requestAdjust(ctx, manualDesired, true);
1630
+ pending.furthestProgressTowardAmount = 0;
1619
1631
  }
1620
1632
  function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
1621
1633
  const state = ctx.state;
@@ -1626,6 +1638,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
1626
1638
  const remainingAfterManual = pending.amount - pending.manualApplied;
1627
1639
  const nativeDelta = newScroll - (pending.startScroll + pending.manualApplied);
1628
1640
  const isWrongDirection = remainingAfterManual < 0 && nativeDelta > MVCP_POSITION_EPSILON || remainingAfterManual > 0 && nativeDelta < -MVCP_POSITION_EPSILON;
1641
+ const progressTowardAmount = getProgressTowardAmount(remainingAfterManual, nativeDelta);
1629
1642
  if (Math.abs(remainingAfterManual) <= MVCP_POSITION_EPSILON) {
1630
1643
  state.pendingNativeMVCPAdjust = void 0;
1631
1644
  return true;
@@ -1634,27 +1647,30 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
1634
1647
  state.pendingNativeMVCPAdjust = void 0;
1635
1648
  return false;
1636
1649
  }
1650
+ if (progressTowardAmount + MVCP_POSITION_EPSILON >= Math.abs(remainingAfterManual)) {
1651
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
1652
+ return true;
1653
+ }
1637
1654
  const expectedNativeClampScroll = Math.max(0, getContentSize(ctx) - state.scrollLength);
1638
1655
  const distanceToClamp = Math.abs(newScroll - expectedNativeClampScroll);
1639
- const didApproachClamp = distanceToClamp < pending.closestDistanceToClamp - MVCP_POSITION_EPSILON;
1640
- const didMoveAwayAfterApproach = pending.hasApproachedClamp && distanceToClamp > pending.closestDistanceToClamp + MVCP_POSITION_EPSILON;
1641
- if (didApproachClamp) {
1642
- pending.closestDistanceToClamp = distanceToClamp;
1643
- pending.hasApproachedClamp = true;
1644
- } else if (didMoveAwayAfterApproach) {
1645
- state.pendingNativeMVCPAdjust = void 0;
1646
- return false;
1647
- }
1648
1656
  const isAtExpectedNativeClamp = distanceToClamp <= NATIVE_END_CLAMP_EPSILON;
1649
- if (!isAtExpectedNativeClamp) {
1657
+ if (isAtExpectedNativeClamp) {
1658
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
1659
+ return true;
1660
+ }
1661
+ if (state.pendingMaintainScrollAtEnd && state.isAtEnd && progressTowardAmount > MVCP_POSITION_EPSILON) {
1662
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
1663
+ return true;
1664
+ }
1665
+ if (progressTowardAmount > pending.furthestProgressTowardAmount + MVCP_POSITION_EPSILON) {
1666
+ pending.furthestProgressTowardAmount = progressTowardAmount;
1650
1667
  return false;
1651
1668
  }
1652
- state.pendingNativeMVCPAdjust = void 0;
1653
- const remaining = remainingAfterManual - nativeDelta;
1654
- if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
1655
- requestAdjust(ctx, remaining, true);
1669
+ if (pending.furthestProgressTowardAmount > MVCP_POSITION_EPSILON && progressTowardAmount < pending.furthestProgressTowardAmount - MVCP_POSITION_EPSILON) {
1670
+ state.pendingNativeMVCPAdjust = void 0;
1671
+ return false;
1656
1672
  }
1657
- return true;
1673
+ return false;
1658
1674
  }
1659
1675
  function prepareMVCP(ctx, dataChanged) {
1660
1676
  const state = ctx.state;
@@ -1793,10 +1809,7 @@ function prepareMVCP(ctx, dataChanged) {
1793
1809
  if (shouldQueueNativeMVCPAdjust(dataChanged, state, positionDiff, prevTotalSize, prevScroll, scrollTarget)) {
1794
1810
  state.pendingNativeMVCPAdjust = {
1795
1811
  amount: positionDiff,
1796
- closestDistanceToClamp: Math.abs(
1797
- prevScroll - Math.max(0, getContentSize(ctx) - state.scrollLength)
1798
- ),
1799
- hasApproachedClamp: false,
1812
+ furthestProgressTowardAmount: 0,
1800
1813
  manualApplied: 0,
1801
1814
  startScroll: prevScroll
1802
1815
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/list",
3
- "version": "3.0.0-beta.41",
3
+ "version": "3.0.0-beta.42",
4
4
  "description": "Legend List is a drop-in replacement for FlatList with much better performance and supporting dynamically sized items.",
5
5
  "sideEffects": false,
6
6
  "private": false,
package/react-native.d.ts CHANGED
@@ -577,8 +577,7 @@ interface InternalState {
577
577
  otherAxisSize?: number;
578
578
  pendingNativeMVCPAdjust?: {
579
579
  amount: number;
580
- closestDistanceToClamp: number;
581
- hasApproachedClamp: boolean;
580
+ furthestProgressTowardAmount: number;
582
581
  manualApplied: number;
583
582
  startScroll: number;
584
583
  };
package/react-native.js CHANGED
@@ -1620,6 +1620,17 @@ function getPredictedNativeClamp(state, unresolvedAmount, totalSize) {
1620
1620
  }
1621
1621
  return 0;
1622
1622
  }
1623
+ function getProgressTowardAmount(targetDelta, nativeDelta) {
1624
+ return targetDelta < 0 ? -nativeDelta : nativeDelta;
1625
+ }
1626
+ function settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta) {
1627
+ const state = ctx.state;
1628
+ state.pendingNativeMVCPAdjust = void 0;
1629
+ const remaining = remainingAfterManual - nativeDelta;
1630
+ if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
1631
+ requestAdjust(ctx, remaining, true);
1632
+ }
1633
+ }
1623
1634
  function maybeApplyPredictedNativeMVCPAdjust(ctx) {
1624
1635
  const state = ctx.state;
1625
1636
  const pending = state.pendingNativeMVCPAdjust;
@@ -1637,6 +1648,7 @@ function maybeApplyPredictedNativeMVCPAdjust(ctx) {
1637
1648
  }
1638
1649
  pending.manualApplied = manualDesired;
1639
1650
  requestAdjust(ctx, manualDesired, true);
1651
+ pending.furthestProgressTowardAmount = 0;
1640
1652
  }
1641
1653
  function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
1642
1654
  const state = ctx.state;
@@ -1647,6 +1659,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
1647
1659
  const remainingAfterManual = pending.amount - pending.manualApplied;
1648
1660
  const nativeDelta = newScroll - (pending.startScroll + pending.manualApplied);
1649
1661
  const isWrongDirection = remainingAfterManual < 0 && nativeDelta > MVCP_POSITION_EPSILON || remainingAfterManual > 0 && nativeDelta < -MVCP_POSITION_EPSILON;
1662
+ const progressTowardAmount = getProgressTowardAmount(remainingAfterManual, nativeDelta);
1650
1663
  if (Math.abs(remainingAfterManual) <= MVCP_POSITION_EPSILON) {
1651
1664
  state.pendingNativeMVCPAdjust = void 0;
1652
1665
  return true;
@@ -1655,27 +1668,30 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
1655
1668
  state.pendingNativeMVCPAdjust = void 0;
1656
1669
  return false;
1657
1670
  }
1671
+ if (progressTowardAmount + MVCP_POSITION_EPSILON >= Math.abs(remainingAfterManual)) {
1672
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
1673
+ return true;
1674
+ }
1658
1675
  const expectedNativeClampScroll = Math.max(0, getContentSize(ctx) - state.scrollLength);
1659
1676
  const distanceToClamp = Math.abs(newScroll - expectedNativeClampScroll);
1660
- const didApproachClamp = distanceToClamp < pending.closestDistanceToClamp - MVCP_POSITION_EPSILON;
1661
- const didMoveAwayAfterApproach = pending.hasApproachedClamp && distanceToClamp > pending.closestDistanceToClamp + MVCP_POSITION_EPSILON;
1662
- if (didApproachClamp) {
1663
- pending.closestDistanceToClamp = distanceToClamp;
1664
- pending.hasApproachedClamp = true;
1665
- } else if (didMoveAwayAfterApproach) {
1666
- state.pendingNativeMVCPAdjust = void 0;
1667
- return false;
1668
- }
1669
1677
  const isAtExpectedNativeClamp = distanceToClamp <= NATIVE_END_CLAMP_EPSILON;
1670
- if (!isAtExpectedNativeClamp) {
1678
+ if (isAtExpectedNativeClamp) {
1679
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
1680
+ return true;
1681
+ }
1682
+ if (state.pendingMaintainScrollAtEnd && state.isAtEnd && progressTowardAmount > MVCP_POSITION_EPSILON) {
1683
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
1684
+ return true;
1685
+ }
1686
+ if (progressTowardAmount > pending.furthestProgressTowardAmount + MVCP_POSITION_EPSILON) {
1687
+ pending.furthestProgressTowardAmount = progressTowardAmount;
1671
1688
  return false;
1672
1689
  }
1673
- state.pendingNativeMVCPAdjust = void 0;
1674
- const remaining = remainingAfterManual - nativeDelta;
1675
- if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
1676
- requestAdjust(ctx, remaining, true);
1690
+ if (pending.furthestProgressTowardAmount > MVCP_POSITION_EPSILON && progressTowardAmount < pending.furthestProgressTowardAmount - MVCP_POSITION_EPSILON) {
1691
+ state.pendingNativeMVCPAdjust = void 0;
1692
+ return false;
1677
1693
  }
1678
- return true;
1694
+ return false;
1679
1695
  }
1680
1696
  function prepareMVCP(ctx, dataChanged) {
1681
1697
  const state = ctx.state;
@@ -1814,10 +1830,7 @@ function prepareMVCP(ctx, dataChanged) {
1814
1830
  if (shouldQueueNativeMVCPAdjust(dataChanged, state, positionDiff, prevTotalSize, prevScroll, scrollTarget)) {
1815
1831
  state.pendingNativeMVCPAdjust = {
1816
1832
  amount: positionDiff,
1817
- closestDistanceToClamp: Math.abs(
1818
- prevScroll - Math.max(0, getContentSize(ctx) - state.scrollLength)
1819
- ),
1820
- hasApproachedClamp: false,
1833
+ furthestProgressTowardAmount: 0,
1821
1834
  manualApplied: 0,
1822
1835
  startScroll: prevScroll
1823
1836
  };
package/react-native.mjs CHANGED
@@ -1599,6 +1599,17 @@ function getPredictedNativeClamp(state, unresolvedAmount, totalSize) {
1599
1599
  }
1600
1600
  return 0;
1601
1601
  }
1602
+ function getProgressTowardAmount(targetDelta, nativeDelta) {
1603
+ return targetDelta < 0 ? -nativeDelta : nativeDelta;
1604
+ }
1605
+ function settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta) {
1606
+ const state = ctx.state;
1607
+ state.pendingNativeMVCPAdjust = void 0;
1608
+ const remaining = remainingAfterManual - nativeDelta;
1609
+ if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
1610
+ requestAdjust(ctx, remaining, true);
1611
+ }
1612
+ }
1602
1613
  function maybeApplyPredictedNativeMVCPAdjust(ctx) {
1603
1614
  const state = ctx.state;
1604
1615
  const pending = state.pendingNativeMVCPAdjust;
@@ -1616,6 +1627,7 @@ function maybeApplyPredictedNativeMVCPAdjust(ctx) {
1616
1627
  }
1617
1628
  pending.manualApplied = manualDesired;
1618
1629
  requestAdjust(ctx, manualDesired, true);
1630
+ pending.furthestProgressTowardAmount = 0;
1619
1631
  }
1620
1632
  function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
1621
1633
  const state = ctx.state;
@@ -1626,6 +1638,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
1626
1638
  const remainingAfterManual = pending.amount - pending.manualApplied;
1627
1639
  const nativeDelta = newScroll - (pending.startScroll + pending.manualApplied);
1628
1640
  const isWrongDirection = remainingAfterManual < 0 && nativeDelta > MVCP_POSITION_EPSILON || remainingAfterManual > 0 && nativeDelta < -MVCP_POSITION_EPSILON;
1641
+ const progressTowardAmount = getProgressTowardAmount(remainingAfterManual, nativeDelta);
1629
1642
  if (Math.abs(remainingAfterManual) <= MVCP_POSITION_EPSILON) {
1630
1643
  state.pendingNativeMVCPAdjust = void 0;
1631
1644
  return true;
@@ -1634,27 +1647,30 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
1634
1647
  state.pendingNativeMVCPAdjust = void 0;
1635
1648
  return false;
1636
1649
  }
1650
+ if (progressTowardAmount + MVCP_POSITION_EPSILON >= Math.abs(remainingAfterManual)) {
1651
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
1652
+ return true;
1653
+ }
1637
1654
  const expectedNativeClampScroll = Math.max(0, getContentSize(ctx) - state.scrollLength);
1638
1655
  const distanceToClamp = Math.abs(newScroll - expectedNativeClampScroll);
1639
- const didApproachClamp = distanceToClamp < pending.closestDistanceToClamp - MVCP_POSITION_EPSILON;
1640
- const didMoveAwayAfterApproach = pending.hasApproachedClamp && distanceToClamp > pending.closestDistanceToClamp + MVCP_POSITION_EPSILON;
1641
- if (didApproachClamp) {
1642
- pending.closestDistanceToClamp = distanceToClamp;
1643
- pending.hasApproachedClamp = true;
1644
- } else if (didMoveAwayAfterApproach) {
1645
- state.pendingNativeMVCPAdjust = void 0;
1646
- return false;
1647
- }
1648
1656
  const isAtExpectedNativeClamp = distanceToClamp <= NATIVE_END_CLAMP_EPSILON;
1649
- if (!isAtExpectedNativeClamp) {
1657
+ if (isAtExpectedNativeClamp) {
1658
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
1659
+ return true;
1660
+ }
1661
+ if (state.pendingMaintainScrollAtEnd && state.isAtEnd && progressTowardAmount > MVCP_POSITION_EPSILON) {
1662
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
1663
+ return true;
1664
+ }
1665
+ if (progressTowardAmount > pending.furthestProgressTowardAmount + MVCP_POSITION_EPSILON) {
1666
+ pending.furthestProgressTowardAmount = progressTowardAmount;
1650
1667
  return false;
1651
1668
  }
1652
- state.pendingNativeMVCPAdjust = void 0;
1653
- const remaining = remainingAfterManual - nativeDelta;
1654
- if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
1655
- requestAdjust(ctx, remaining, true);
1669
+ if (pending.furthestProgressTowardAmount > MVCP_POSITION_EPSILON && progressTowardAmount < pending.furthestProgressTowardAmount - MVCP_POSITION_EPSILON) {
1670
+ state.pendingNativeMVCPAdjust = void 0;
1671
+ return false;
1656
1672
  }
1657
- return true;
1673
+ return false;
1658
1674
  }
1659
1675
  function prepareMVCP(ctx, dataChanged) {
1660
1676
  const state = ctx.state;
@@ -1793,10 +1809,7 @@ function prepareMVCP(ctx, dataChanged) {
1793
1809
  if (shouldQueueNativeMVCPAdjust(dataChanged, state, positionDiff, prevTotalSize, prevScroll, scrollTarget)) {
1794
1810
  state.pendingNativeMVCPAdjust = {
1795
1811
  amount: positionDiff,
1796
- closestDistanceToClamp: Math.abs(
1797
- prevScroll - Math.max(0, getContentSize(ctx) - state.scrollLength)
1798
- ),
1799
- hasApproachedClamp: false,
1812
+ furthestProgressTowardAmount: 0,
1800
1813
  manualApplied: 0,
1801
1814
  startScroll: prevScroll
1802
1815
  };
@@ -596,8 +596,7 @@ interface InternalState {
596
596
  otherAxisSize?: number;
597
597
  pendingNativeMVCPAdjust?: {
598
598
  amount: number;
599
- closestDistanceToClamp: number;
600
- hasApproachedClamp: boolean;
599
+ furthestProgressTowardAmount: number;
601
600
  manualApplied: number;
602
601
  startScroll: number;
603
602
  };
@@ -2120,6 +2120,17 @@ function getPredictedNativeClamp(state, unresolvedAmount, totalSize) {
2120
2120
  }
2121
2121
  return 0;
2122
2122
  }
2123
+ function getProgressTowardAmount(targetDelta, nativeDelta) {
2124
+ return targetDelta < 0 ? -nativeDelta : nativeDelta;
2125
+ }
2126
+ function settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta) {
2127
+ const state = ctx.state;
2128
+ state.pendingNativeMVCPAdjust = void 0;
2129
+ const remaining = remainingAfterManual - nativeDelta;
2130
+ if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
2131
+ requestAdjust(ctx, remaining);
2132
+ }
2133
+ }
2123
2134
  function maybeApplyPredictedNativeMVCPAdjust(ctx) {
2124
2135
  const state = ctx.state;
2125
2136
  const pending = state.pendingNativeMVCPAdjust;
@@ -2137,6 +2148,7 @@ function maybeApplyPredictedNativeMVCPAdjust(ctx) {
2137
2148
  }
2138
2149
  pending.manualApplied = manualDesired;
2139
2150
  requestAdjust(ctx, manualDesired);
2151
+ pending.furthestProgressTowardAmount = 0;
2140
2152
  }
2141
2153
  function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2142
2154
  const state = ctx.state;
@@ -2147,6 +2159,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2147
2159
  const remainingAfterManual = pending.amount - pending.manualApplied;
2148
2160
  const nativeDelta = newScroll - (pending.startScroll + pending.manualApplied);
2149
2161
  const isWrongDirection = remainingAfterManual < 0 && nativeDelta > MVCP_POSITION_EPSILON || remainingAfterManual > 0 && nativeDelta < -MVCP_POSITION_EPSILON;
2162
+ const progressTowardAmount = getProgressTowardAmount(remainingAfterManual, nativeDelta);
2150
2163
  if (Math.abs(remainingAfterManual) <= MVCP_POSITION_EPSILON) {
2151
2164
  state.pendingNativeMVCPAdjust = void 0;
2152
2165
  return true;
@@ -2155,27 +2168,30 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2155
2168
  state.pendingNativeMVCPAdjust = void 0;
2156
2169
  return false;
2157
2170
  }
2171
+ if (progressTowardAmount + MVCP_POSITION_EPSILON >= Math.abs(remainingAfterManual)) {
2172
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2173
+ return true;
2174
+ }
2158
2175
  const expectedNativeClampScroll = Math.max(0, getContentSize(ctx) - state.scrollLength);
2159
2176
  const distanceToClamp = Math.abs(newScroll - expectedNativeClampScroll);
2160
- const didApproachClamp = distanceToClamp < pending.closestDistanceToClamp - MVCP_POSITION_EPSILON;
2161
- const didMoveAwayAfterApproach = pending.hasApproachedClamp && distanceToClamp > pending.closestDistanceToClamp + MVCP_POSITION_EPSILON;
2162
- if (didApproachClamp) {
2163
- pending.closestDistanceToClamp = distanceToClamp;
2164
- pending.hasApproachedClamp = true;
2165
- } else if (didMoveAwayAfterApproach) {
2166
- state.pendingNativeMVCPAdjust = void 0;
2167
- return false;
2168
- }
2169
2177
  const isAtExpectedNativeClamp = distanceToClamp <= NATIVE_END_CLAMP_EPSILON;
2170
- if (!isAtExpectedNativeClamp) {
2178
+ if (isAtExpectedNativeClamp) {
2179
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2180
+ return true;
2181
+ }
2182
+ if (state.pendingMaintainScrollAtEnd && state.isAtEnd && progressTowardAmount > MVCP_POSITION_EPSILON) {
2183
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2184
+ return true;
2185
+ }
2186
+ if (progressTowardAmount > pending.furthestProgressTowardAmount + MVCP_POSITION_EPSILON) {
2187
+ pending.furthestProgressTowardAmount = progressTowardAmount;
2171
2188
  return false;
2172
2189
  }
2173
- state.pendingNativeMVCPAdjust = void 0;
2174
- const remaining = remainingAfterManual - nativeDelta;
2175
- if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
2176
- requestAdjust(ctx, remaining);
2190
+ if (pending.furthestProgressTowardAmount > MVCP_POSITION_EPSILON && progressTowardAmount < pending.furthestProgressTowardAmount - MVCP_POSITION_EPSILON) {
2191
+ state.pendingNativeMVCPAdjust = void 0;
2192
+ return false;
2177
2193
  }
2178
- return true;
2194
+ return false;
2179
2195
  }
2180
2196
  function prepareMVCP(ctx, dataChanged) {
2181
2197
  const state = ctx.state;
@@ -2306,10 +2322,7 @@ function prepareMVCP(ctx, dataChanged) {
2306
2322
  if (shouldQueueNativeMVCPAdjust()) {
2307
2323
  state.pendingNativeMVCPAdjust = {
2308
2324
  amount: positionDiff,
2309
- closestDistanceToClamp: Math.abs(
2310
- prevScroll - Math.max(0, getContentSize(ctx) - state.scrollLength)
2311
- ),
2312
- hasApproachedClamp: false,
2325
+ furthestProgressTowardAmount: 0,
2313
2326
  manualApplied: 0,
2314
2327
  startScroll: prevScroll
2315
2328
  };
@@ -2099,6 +2099,17 @@ function getPredictedNativeClamp(state, unresolvedAmount, totalSize) {
2099
2099
  }
2100
2100
  return 0;
2101
2101
  }
2102
+ function getProgressTowardAmount(targetDelta, nativeDelta) {
2103
+ return targetDelta < 0 ? -nativeDelta : nativeDelta;
2104
+ }
2105
+ function settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta) {
2106
+ const state = ctx.state;
2107
+ state.pendingNativeMVCPAdjust = void 0;
2108
+ const remaining = remainingAfterManual - nativeDelta;
2109
+ if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
2110
+ requestAdjust(ctx, remaining);
2111
+ }
2112
+ }
2102
2113
  function maybeApplyPredictedNativeMVCPAdjust(ctx) {
2103
2114
  const state = ctx.state;
2104
2115
  const pending = state.pendingNativeMVCPAdjust;
@@ -2116,6 +2127,7 @@ function maybeApplyPredictedNativeMVCPAdjust(ctx) {
2116
2127
  }
2117
2128
  pending.manualApplied = manualDesired;
2118
2129
  requestAdjust(ctx, manualDesired);
2130
+ pending.furthestProgressTowardAmount = 0;
2119
2131
  }
2120
2132
  function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2121
2133
  const state = ctx.state;
@@ -2126,6 +2138,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2126
2138
  const remainingAfterManual = pending.amount - pending.manualApplied;
2127
2139
  const nativeDelta = newScroll - (pending.startScroll + pending.manualApplied);
2128
2140
  const isWrongDirection = remainingAfterManual < 0 && nativeDelta > MVCP_POSITION_EPSILON || remainingAfterManual > 0 && nativeDelta < -MVCP_POSITION_EPSILON;
2141
+ const progressTowardAmount = getProgressTowardAmount(remainingAfterManual, nativeDelta);
2129
2142
  if (Math.abs(remainingAfterManual) <= MVCP_POSITION_EPSILON) {
2130
2143
  state.pendingNativeMVCPAdjust = void 0;
2131
2144
  return true;
@@ -2134,27 +2147,30 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2134
2147
  state.pendingNativeMVCPAdjust = void 0;
2135
2148
  return false;
2136
2149
  }
2150
+ if (progressTowardAmount + MVCP_POSITION_EPSILON >= Math.abs(remainingAfterManual)) {
2151
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2152
+ return true;
2153
+ }
2137
2154
  const expectedNativeClampScroll = Math.max(0, getContentSize(ctx) - state.scrollLength);
2138
2155
  const distanceToClamp = Math.abs(newScroll - expectedNativeClampScroll);
2139
- const didApproachClamp = distanceToClamp < pending.closestDistanceToClamp - MVCP_POSITION_EPSILON;
2140
- const didMoveAwayAfterApproach = pending.hasApproachedClamp && distanceToClamp > pending.closestDistanceToClamp + MVCP_POSITION_EPSILON;
2141
- if (didApproachClamp) {
2142
- pending.closestDistanceToClamp = distanceToClamp;
2143
- pending.hasApproachedClamp = true;
2144
- } else if (didMoveAwayAfterApproach) {
2145
- state.pendingNativeMVCPAdjust = void 0;
2146
- return false;
2147
- }
2148
2156
  const isAtExpectedNativeClamp = distanceToClamp <= NATIVE_END_CLAMP_EPSILON;
2149
- if (!isAtExpectedNativeClamp) {
2157
+ if (isAtExpectedNativeClamp) {
2158
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2159
+ return true;
2160
+ }
2161
+ if (state.pendingMaintainScrollAtEnd && state.isAtEnd && progressTowardAmount > MVCP_POSITION_EPSILON) {
2162
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2163
+ return true;
2164
+ }
2165
+ if (progressTowardAmount > pending.furthestProgressTowardAmount + MVCP_POSITION_EPSILON) {
2166
+ pending.furthestProgressTowardAmount = progressTowardAmount;
2150
2167
  return false;
2151
2168
  }
2152
- state.pendingNativeMVCPAdjust = void 0;
2153
- const remaining = remainingAfterManual - nativeDelta;
2154
- if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
2155
- requestAdjust(ctx, remaining);
2169
+ if (pending.furthestProgressTowardAmount > MVCP_POSITION_EPSILON && progressTowardAmount < pending.furthestProgressTowardAmount - MVCP_POSITION_EPSILON) {
2170
+ state.pendingNativeMVCPAdjust = void 0;
2171
+ return false;
2156
2172
  }
2157
- return true;
2173
+ return false;
2158
2174
  }
2159
2175
  function prepareMVCP(ctx, dataChanged) {
2160
2176
  const state = ctx.state;
@@ -2285,10 +2301,7 @@ function prepareMVCP(ctx, dataChanged) {
2285
2301
  if (shouldQueueNativeMVCPAdjust()) {
2286
2302
  state.pendingNativeMVCPAdjust = {
2287
2303
  amount: positionDiff,
2288
- closestDistanceToClamp: Math.abs(
2289
- prevScroll - Math.max(0, getContentSize(ctx) - state.scrollLength)
2290
- ),
2291
- hasApproachedClamp: false,
2304
+ furthestProgressTowardAmount: 0,
2292
2305
  manualApplied: 0,
2293
2306
  startScroll: prevScroll
2294
2307
  };
package/react.d.ts CHANGED
@@ -596,8 +596,7 @@ interface InternalState {
596
596
  otherAxisSize?: number;
597
597
  pendingNativeMVCPAdjust?: {
598
598
  amount: number;
599
- closestDistanceToClamp: number;
600
- hasApproachedClamp: boolean;
599
+ furthestProgressTowardAmount: number;
601
600
  manualApplied: number;
602
601
  startScroll: number;
603
602
  };
package/react.js CHANGED
@@ -2120,6 +2120,17 @@ function getPredictedNativeClamp(state, unresolvedAmount, totalSize) {
2120
2120
  }
2121
2121
  return 0;
2122
2122
  }
2123
+ function getProgressTowardAmount(targetDelta, nativeDelta) {
2124
+ return targetDelta < 0 ? -nativeDelta : nativeDelta;
2125
+ }
2126
+ function settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta) {
2127
+ const state = ctx.state;
2128
+ state.pendingNativeMVCPAdjust = void 0;
2129
+ const remaining = remainingAfterManual - nativeDelta;
2130
+ if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
2131
+ requestAdjust(ctx, remaining);
2132
+ }
2133
+ }
2123
2134
  function maybeApplyPredictedNativeMVCPAdjust(ctx) {
2124
2135
  const state = ctx.state;
2125
2136
  const pending = state.pendingNativeMVCPAdjust;
@@ -2137,6 +2148,7 @@ function maybeApplyPredictedNativeMVCPAdjust(ctx) {
2137
2148
  }
2138
2149
  pending.manualApplied = manualDesired;
2139
2150
  requestAdjust(ctx, manualDesired);
2151
+ pending.furthestProgressTowardAmount = 0;
2140
2152
  }
2141
2153
  function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2142
2154
  const state = ctx.state;
@@ -2147,6 +2159,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2147
2159
  const remainingAfterManual = pending.amount - pending.manualApplied;
2148
2160
  const nativeDelta = newScroll - (pending.startScroll + pending.manualApplied);
2149
2161
  const isWrongDirection = remainingAfterManual < 0 && nativeDelta > MVCP_POSITION_EPSILON || remainingAfterManual > 0 && nativeDelta < -MVCP_POSITION_EPSILON;
2162
+ const progressTowardAmount = getProgressTowardAmount(remainingAfterManual, nativeDelta);
2150
2163
  if (Math.abs(remainingAfterManual) <= MVCP_POSITION_EPSILON) {
2151
2164
  state.pendingNativeMVCPAdjust = void 0;
2152
2165
  return true;
@@ -2155,27 +2168,30 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2155
2168
  state.pendingNativeMVCPAdjust = void 0;
2156
2169
  return false;
2157
2170
  }
2171
+ if (progressTowardAmount + MVCP_POSITION_EPSILON >= Math.abs(remainingAfterManual)) {
2172
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2173
+ return true;
2174
+ }
2158
2175
  const expectedNativeClampScroll = Math.max(0, getContentSize(ctx) - state.scrollLength);
2159
2176
  const distanceToClamp = Math.abs(newScroll - expectedNativeClampScroll);
2160
- const didApproachClamp = distanceToClamp < pending.closestDistanceToClamp - MVCP_POSITION_EPSILON;
2161
- const didMoveAwayAfterApproach = pending.hasApproachedClamp && distanceToClamp > pending.closestDistanceToClamp + MVCP_POSITION_EPSILON;
2162
- if (didApproachClamp) {
2163
- pending.closestDistanceToClamp = distanceToClamp;
2164
- pending.hasApproachedClamp = true;
2165
- } else if (didMoveAwayAfterApproach) {
2166
- state.pendingNativeMVCPAdjust = void 0;
2167
- return false;
2168
- }
2169
2177
  const isAtExpectedNativeClamp = distanceToClamp <= NATIVE_END_CLAMP_EPSILON;
2170
- if (!isAtExpectedNativeClamp) {
2178
+ if (isAtExpectedNativeClamp) {
2179
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2180
+ return true;
2181
+ }
2182
+ if (state.pendingMaintainScrollAtEnd && state.isAtEnd && progressTowardAmount > MVCP_POSITION_EPSILON) {
2183
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2184
+ return true;
2185
+ }
2186
+ if (progressTowardAmount > pending.furthestProgressTowardAmount + MVCP_POSITION_EPSILON) {
2187
+ pending.furthestProgressTowardAmount = progressTowardAmount;
2171
2188
  return false;
2172
2189
  }
2173
- state.pendingNativeMVCPAdjust = void 0;
2174
- const remaining = remainingAfterManual - nativeDelta;
2175
- if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
2176
- requestAdjust(ctx, remaining);
2190
+ if (pending.furthestProgressTowardAmount > MVCP_POSITION_EPSILON && progressTowardAmount < pending.furthestProgressTowardAmount - MVCP_POSITION_EPSILON) {
2191
+ state.pendingNativeMVCPAdjust = void 0;
2192
+ return false;
2177
2193
  }
2178
- return true;
2194
+ return false;
2179
2195
  }
2180
2196
  function prepareMVCP(ctx, dataChanged) {
2181
2197
  const state = ctx.state;
@@ -2306,10 +2322,7 @@ function prepareMVCP(ctx, dataChanged) {
2306
2322
  if (shouldQueueNativeMVCPAdjust()) {
2307
2323
  state.pendingNativeMVCPAdjust = {
2308
2324
  amount: positionDiff,
2309
- closestDistanceToClamp: Math.abs(
2310
- prevScroll - Math.max(0, getContentSize(ctx) - state.scrollLength)
2311
- ),
2312
- hasApproachedClamp: false,
2325
+ furthestProgressTowardAmount: 0,
2313
2326
  manualApplied: 0,
2314
2327
  startScroll: prevScroll
2315
2328
  };
package/react.mjs CHANGED
@@ -2099,6 +2099,17 @@ function getPredictedNativeClamp(state, unresolvedAmount, totalSize) {
2099
2099
  }
2100
2100
  return 0;
2101
2101
  }
2102
+ function getProgressTowardAmount(targetDelta, nativeDelta) {
2103
+ return targetDelta < 0 ? -nativeDelta : nativeDelta;
2104
+ }
2105
+ function settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta) {
2106
+ const state = ctx.state;
2107
+ state.pendingNativeMVCPAdjust = void 0;
2108
+ const remaining = remainingAfterManual - nativeDelta;
2109
+ if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
2110
+ requestAdjust(ctx, remaining);
2111
+ }
2112
+ }
2102
2113
  function maybeApplyPredictedNativeMVCPAdjust(ctx) {
2103
2114
  const state = ctx.state;
2104
2115
  const pending = state.pendingNativeMVCPAdjust;
@@ -2116,6 +2127,7 @@ function maybeApplyPredictedNativeMVCPAdjust(ctx) {
2116
2127
  }
2117
2128
  pending.manualApplied = manualDesired;
2118
2129
  requestAdjust(ctx, manualDesired);
2130
+ pending.furthestProgressTowardAmount = 0;
2119
2131
  }
2120
2132
  function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2121
2133
  const state = ctx.state;
@@ -2126,6 +2138,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2126
2138
  const remainingAfterManual = pending.amount - pending.manualApplied;
2127
2139
  const nativeDelta = newScroll - (pending.startScroll + pending.manualApplied);
2128
2140
  const isWrongDirection = remainingAfterManual < 0 && nativeDelta > MVCP_POSITION_EPSILON || remainingAfterManual > 0 && nativeDelta < -MVCP_POSITION_EPSILON;
2141
+ const progressTowardAmount = getProgressTowardAmount(remainingAfterManual, nativeDelta);
2129
2142
  if (Math.abs(remainingAfterManual) <= MVCP_POSITION_EPSILON) {
2130
2143
  state.pendingNativeMVCPAdjust = void 0;
2131
2144
  return true;
@@ -2134,27 +2147,30 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
2134
2147
  state.pendingNativeMVCPAdjust = void 0;
2135
2148
  return false;
2136
2149
  }
2150
+ if (progressTowardAmount + MVCP_POSITION_EPSILON >= Math.abs(remainingAfterManual)) {
2151
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2152
+ return true;
2153
+ }
2137
2154
  const expectedNativeClampScroll = Math.max(0, getContentSize(ctx) - state.scrollLength);
2138
2155
  const distanceToClamp = Math.abs(newScroll - expectedNativeClampScroll);
2139
- const didApproachClamp = distanceToClamp < pending.closestDistanceToClamp - MVCP_POSITION_EPSILON;
2140
- const didMoveAwayAfterApproach = pending.hasApproachedClamp && distanceToClamp > pending.closestDistanceToClamp + MVCP_POSITION_EPSILON;
2141
- if (didApproachClamp) {
2142
- pending.closestDistanceToClamp = distanceToClamp;
2143
- pending.hasApproachedClamp = true;
2144
- } else if (didMoveAwayAfterApproach) {
2145
- state.pendingNativeMVCPAdjust = void 0;
2146
- return false;
2147
- }
2148
2156
  const isAtExpectedNativeClamp = distanceToClamp <= NATIVE_END_CLAMP_EPSILON;
2149
- if (!isAtExpectedNativeClamp) {
2157
+ if (isAtExpectedNativeClamp) {
2158
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2159
+ return true;
2160
+ }
2161
+ if (state.pendingMaintainScrollAtEnd && state.isAtEnd && progressTowardAmount > MVCP_POSITION_EPSILON) {
2162
+ settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
2163
+ return true;
2164
+ }
2165
+ if (progressTowardAmount > pending.furthestProgressTowardAmount + MVCP_POSITION_EPSILON) {
2166
+ pending.furthestProgressTowardAmount = progressTowardAmount;
2150
2167
  return false;
2151
2168
  }
2152
- state.pendingNativeMVCPAdjust = void 0;
2153
- const remaining = remainingAfterManual - nativeDelta;
2154
- if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
2155
- requestAdjust(ctx, remaining);
2169
+ if (pending.furthestProgressTowardAmount > MVCP_POSITION_EPSILON && progressTowardAmount < pending.furthestProgressTowardAmount - MVCP_POSITION_EPSILON) {
2170
+ state.pendingNativeMVCPAdjust = void 0;
2171
+ return false;
2156
2172
  }
2157
- return true;
2173
+ return false;
2158
2174
  }
2159
2175
  function prepareMVCP(ctx, dataChanged) {
2160
2176
  const state = ctx.state;
@@ -2285,10 +2301,7 @@ function prepareMVCP(ctx, dataChanged) {
2285
2301
  if (shouldQueueNativeMVCPAdjust()) {
2286
2302
  state.pendingNativeMVCPAdjust = {
2287
2303
  amount: positionDiff,
2288
- closestDistanceToClamp: Math.abs(
2289
- prevScroll - Math.max(0, getContentSize(ctx) - state.scrollLength)
2290
- ),
2291
- hasApproachedClamp: false,
2304
+ furthestProgressTowardAmount: 0,
2292
2305
  manualApplied: 0,
2293
2306
  startScroll: prevScroll
2294
2307
  };