@legendapp/list 3.0.0-beta.40 → 3.0.0-beta.41
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/README.md +1 -1
- package/animated.d.ts +16 -3
- package/index.d.ts +40 -5
- package/index.js +732 -204
- package/index.mjs +732 -204
- package/index.native.js +782 -288
- package/index.native.mjs +782 -288
- package/package.json +14 -4
- package/react-native.d.ts +38 -5
- package/react-native.js +779 -281
- package/react-native.mjs +779 -281
- package/react-native.web.d.ts +1005 -0
- package/react-native.web.js +5357 -0
- package/react-native.web.mjs +5326 -0
- package/react.d.ts +38 -5
- package/react.js +751 -206
- package/react.mjs +751 -207
- package/reanimated.d.ts +16 -3
- package/section-list.d.ts +16 -3
package/index.js
CHANGED
|
@@ -1004,6 +1004,47 @@ var StyleSheet = {
|
|
|
1004
1004
|
create: (styles) => styles,
|
|
1005
1005
|
flatten: (style) => flattenStyles(style)
|
|
1006
1006
|
};
|
|
1007
|
+
function useRafCoalescer(callback) {
|
|
1008
|
+
const callbackRef = React3.useRef(callback);
|
|
1009
|
+
const rafIdRef = React3.useRef(void 0);
|
|
1010
|
+
callbackRef.current = callback;
|
|
1011
|
+
const coalescer = React3.useMemo(
|
|
1012
|
+
() => ({
|
|
1013
|
+
cancel() {
|
|
1014
|
+
if (rafIdRef.current !== void 0) {
|
|
1015
|
+
cancelAnimationFrame(rafIdRef.current);
|
|
1016
|
+
rafIdRef.current = void 0;
|
|
1017
|
+
}
|
|
1018
|
+
},
|
|
1019
|
+
flush() {
|
|
1020
|
+
coalescer.cancel();
|
|
1021
|
+
callbackRef.current();
|
|
1022
|
+
},
|
|
1023
|
+
schedule() {
|
|
1024
|
+
if (rafIdRef.current !== void 0) {
|
|
1025
|
+
return false;
|
|
1026
|
+
}
|
|
1027
|
+
const rafId = requestAnimationFrame(() => {
|
|
1028
|
+
if (rafIdRef.current !== rafId) {
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
rafIdRef.current = void 0;
|
|
1032
|
+
callbackRef.current();
|
|
1033
|
+
});
|
|
1034
|
+
rafIdRef.current = rafId;
|
|
1035
|
+
return true;
|
|
1036
|
+
}
|
|
1037
|
+
}),
|
|
1038
|
+
[]
|
|
1039
|
+
);
|
|
1040
|
+
React3.useEffect(
|
|
1041
|
+
() => () => {
|
|
1042
|
+
coalescer.cancel();
|
|
1043
|
+
},
|
|
1044
|
+
[coalescer]
|
|
1045
|
+
);
|
|
1046
|
+
return coalescer;
|
|
1047
|
+
}
|
|
1007
1048
|
|
|
1008
1049
|
// src/components/webScrollUtils.ts
|
|
1009
1050
|
function getDocumentScrollerNode() {
|
|
@@ -1105,6 +1146,7 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
|
|
|
1105
1146
|
onLayout,
|
|
1106
1147
|
...props
|
|
1107
1148
|
}, ref) {
|
|
1149
|
+
const ctx = useStateContext();
|
|
1108
1150
|
const scrollRef = React3.useRef(null);
|
|
1109
1151
|
const contentRef = React3.useRef(null);
|
|
1110
1152
|
const isWindowScroll = useWindowScroll;
|
|
@@ -1198,37 +1240,46 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
|
|
|
1198
1240
|
};
|
|
1199
1241
|
return api;
|
|
1200
1242
|
}, [getCurrentScrollOffset, getMaxScrollOffset, getScrollTarget, horizontal, isWindowScroll, scrollToLocalOffset]);
|
|
1243
|
+
const emitScroll = React3.useCallback(() => {
|
|
1244
|
+
if (!onScroll2 || !scrollRef.current) {
|
|
1245
|
+
return;
|
|
1246
|
+
}
|
|
1247
|
+
const contentSize = getContentSize2(contentRef.current);
|
|
1248
|
+
const layoutMeasurement = getLayoutMeasurement(scrollRef.current, isWindowScroll, horizontal);
|
|
1249
|
+
const offset = getCurrentScrollOffset();
|
|
1250
|
+
const scrollEvent = {
|
|
1251
|
+
nativeEvent: {
|
|
1252
|
+
contentOffset: {
|
|
1253
|
+
x: horizontal ? offset : 0,
|
|
1254
|
+
y: horizontal ? 0 : offset
|
|
1255
|
+
},
|
|
1256
|
+
contentSize: {
|
|
1257
|
+
height: contentSize.height,
|
|
1258
|
+
width: contentSize.width
|
|
1259
|
+
},
|
|
1260
|
+
layoutMeasurement: {
|
|
1261
|
+
height: layoutMeasurement.height,
|
|
1262
|
+
width: layoutMeasurement.width
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
};
|
|
1266
|
+
onScroll2(scrollEvent);
|
|
1267
|
+
}, [getCurrentScrollOffset, horizontal, isWindowScroll, onScroll2]);
|
|
1268
|
+
const scrollEventCoalescer = useRafCoalescer(emitScroll);
|
|
1201
1269
|
const handleScroll = React3.useCallback(
|
|
1202
1270
|
(_event) => {
|
|
1271
|
+
var _a3;
|
|
1203
1272
|
if (!onScroll2) {
|
|
1204
1273
|
return;
|
|
1205
1274
|
}
|
|
1206
|
-
const
|
|
1207
|
-
if (!
|
|
1208
|
-
|
|
1275
|
+
const scrollingTo = (_a3 = ctx.state) == null ? void 0 : _a3.scrollingTo;
|
|
1276
|
+
if (scrollingTo && !scrollingTo.animated) {
|
|
1277
|
+
scrollEventCoalescer.flush();
|
|
1278
|
+
} else {
|
|
1279
|
+
scrollEventCoalescer.schedule();
|
|
1209
1280
|
}
|
|
1210
|
-
const contentSize = getContentSize2(contentRef.current);
|
|
1211
|
-
const layoutMeasurement = getLayoutMeasurement(scrollRef.current, isWindowScroll, horizontal);
|
|
1212
|
-
const offset = getCurrentScrollOffset();
|
|
1213
|
-
const scrollEvent = {
|
|
1214
|
-
nativeEvent: {
|
|
1215
|
-
contentOffset: {
|
|
1216
|
-
x: horizontal ? offset : 0,
|
|
1217
|
-
y: horizontal ? 0 : offset
|
|
1218
|
-
},
|
|
1219
|
-
contentSize: {
|
|
1220
|
-
height: contentSize.height,
|
|
1221
|
-
width: contentSize.width
|
|
1222
|
-
},
|
|
1223
|
-
layoutMeasurement: {
|
|
1224
|
-
height: layoutMeasurement.height,
|
|
1225
|
-
width: layoutMeasurement.width
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
|
-
};
|
|
1229
|
-
onScroll2(scrollEvent);
|
|
1230
1281
|
},
|
|
1231
|
-
[
|
|
1282
|
+
[onScroll2, scrollEventCoalescer]
|
|
1232
1283
|
);
|
|
1233
1284
|
React3.useLayoutEffect(() => {
|
|
1234
1285
|
const target = getScrollTarget();
|
|
@@ -1236,8 +1287,9 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
|
|
|
1236
1287
|
target.addEventListener("scroll", handleScroll, { passive: true });
|
|
1237
1288
|
return () => {
|
|
1238
1289
|
target.removeEventListener("scroll", handleScroll);
|
|
1290
|
+
scrollEventCoalescer.cancel();
|
|
1239
1291
|
};
|
|
1240
|
-
}, [getScrollTarget, handleScroll]);
|
|
1292
|
+
}, [getScrollTarget, handleScroll, scrollEventCoalescer]);
|
|
1241
1293
|
React3.useEffect(() => {
|
|
1242
1294
|
const doScroll = () => {
|
|
1243
1295
|
if (contentOffset) {
|
|
@@ -1589,6 +1641,7 @@ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize) {
|
|
|
1589
1641
|
|
|
1590
1642
|
// src/core/calculateOffsetWithOffsetPosition.ts
|
|
1591
1643
|
function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
|
|
1644
|
+
var _a3;
|
|
1592
1645
|
const state = ctx.state;
|
|
1593
1646
|
const { index, viewOffset, viewPosition } = params;
|
|
1594
1647
|
let offset = offsetParam;
|
|
@@ -1602,10 +1655,16 @@ function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
|
|
|
1602
1655
|
}
|
|
1603
1656
|
}
|
|
1604
1657
|
if (viewPosition !== void 0 && index !== void 0) {
|
|
1605
|
-
const
|
|
1658
|
+
const dataLength = state.props.data.length;
|
|
1659
|
+
if (dataLength === 0) {
|
|
1660
|
+
return offset;
|
|
1661
|
+
}
|
|
1662
|
+
const isOutOfBounds = index < 0 || index >= dataLength;
|
|
1663
|
+
const fallbackEstimatedSize = (_a3 = state.props.estimatedItemSize) != null ? _a3 : 0;
|
|
1664
|
+
const itemSize = isOutOfBounds ? fallbackEstimatedSize : getItemSize(ctx, getId(state, index), index, state.props.data[index]);
|
|
1606
1665
|
const trailingInset = getContentInsetEnd(state);
|
|
1607
1666
|
offset -= viewPosition * (state.scrollLength - trailingInset - itemSize);
|
|
1608
|
-
if (index === state.props.data.length - 1) {
|
|
1667
|
+
if (!isOutOfBounds && index === state.props.data.length - 1) {
|
|
1609
1668
|
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
1610
1669
|
offset += footerSize;
|
|
1611
1670
|
}
|
|
@@ -1807,7 +1866,9 @@ function finishScrollTo(ctx) {
|
|
|
1807
1866
|
const scrollingTo = state.scrollingTo;
|
|
1808
1867
|
state.scrollHistory.length = 0;
|
|
1809
1868
|
state.initialScroll = void 0;
|
|
1869
|
+
state.initialScrollUsesOffset = false;
|
|
1810
1870
|
state.initialAnchor = void 0;
|
|
1871
|
+
state.initialNativeScrollWatchdog = void 0;
|
|
1811
1872
|
state.scrollingTo = void 0;
|
|
1812
1873
|
if (state.pendingTotalSize !== void 0) {
|
|
1813
1874
|
addTotalSize(ctx, null, state.pendingTotalSize);
|
|
@@ -1909,7 +1970,9 @@ function listenForScrollEnd(ctx, params) {
|
|
|
1909
1970
|
}
|
|
1910
1971
|
|
|
1911
1972
|
// src/core/scrollTo.ts
|
|
1973
|
+
var WATCHDOG_OFFSET_EPSILON = 1;
|
|
1912
1974
|
function scrollTo(ctx, params) {
|
|
1975
|
+
var _a3, _b;
|
|
1913
1976
|
const state = ctx.state;
|
|
1914
1977
|
const { noScrollingTo, forceScroll, ...scrollTarget } = params;
|
|
1915
1978
|
const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
|
|
@@ -1926,9 +1989,23 @@ function scrollTo(ctx, params) {
|
|
|
1926
1989
|
offset = clampScrollOffset(ctx, offset, scrollTarget);
|
|
1927
1990
|
state.scrollHistory.length = 0;
|
|
1928
1991
|
if (!noScrollingTo) {
|
|
1929
|
-
state.scrollingTo =
|
|
1992
|
+
state.scrollingTo = {
|
|
1993
|
+
...scrollTarget,
|
|
1994
|
+
targetOffset: offset
|
|
1995
|
+
};
|
|
1930
1996
|
}
|
|
1931
1997
|
state.scrollPending = offset;
|
|
1998
|
+
const shouldWatchInitialNativeScroll = !state.didFinishInitialScroll && (isInitialScroll || !!state.initialNativeScrollWatchdog) && offset > WATCHDOG_OFFSET_EPSILON;
|
|
1999
|
+
const shouldClearInitialNativeScrollWatchdog = !state.didFinishInitialScroll && !!state.initialNativeScrollWatchdog && offset <= WATCHDOG_OFFSET_EPSILON;
|
|
2000
|
+
if (shouldWatchInitialNativeScroll) {
|
|
2001
|
+
state.hasScrolled = false;
|
|
2002
|
+
state.initialNativeScrollWatchdog = {
|
|
2003
|
+
startScroll: (_b = (_a3 = state.initialNativeScrollWatchdog) == null ? void 0 : _a3.startScroll) != null ? _b : state.scroll,
|
|
2004
|
+
targetOffset: offset
|
|
2005
|
+
};
|
|
2006
|
+
} else if (shouldClearInitialNativeScrollWatchdog) {
|
|
2007
|
+
state.initialNativeScrollWatchdog = void 0;
|
|
2008
|
+
}
|
|
1932
2009
|
if (forceScroll || !isInitialScroll || Platform.OS === "android") {
|
|
1933
2010
|
doScrollTo(ctx, { animated, horizontal, offset });
|
|
1934
2011
|
} else {
|
|
@@ -1936,91 +2013,52 @@ function scrollTo(ctx, params) {
|
|
|
1936
2013
|
}
|
|
1937
2014
|
}
|
|
1938
2015
|
|
|
1939
|
-
// src/core/
|
|
1940
|
-
function
|
|
2016
|
+
// src/core/doMaintainScrollAtEnd.ts
|
|
2017
|
+
function doMaintainScrollAtEnd(ctx) {
|
|
1941
2018
|
const state = ctx.state;
|
|
1942
|
-
const {
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
if (scrollingTo === void 0 && !(scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
1954
|
-
if (!adjustChanged) {
|
|
1955
|
-
scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
1956
|
-
}
|
|
1957
|
-
}
|
|
1958
|
-
if (scrollHistory.length > 5) {
|
|
1959
|
-
scrollHistory.shift();
|
|
2019
|
+
const {
|
|
2020
|
+
didContainersLayout,
|
|
2021
|
+
isAtEnd,
|
|
2022
|
+
pendingNativeMVCPAdjust,
|
|
2023
|
+
refScroller,
|
|
2024
|
+
props: { maintainScrollAtEnd }
|
|
2025
|
+
} = state;
|
|
2026
|
+
const shouldMaintainScrollAtEnd = !!(isAtEnd && maintainScrollAtEnd && didContainersLayout);
|
|
2027
|
+
if (pendingNativeMVCPAdjust) {
|
|
2028
|
+
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
2029
|
+
return false;
|
|
1960
2030
|
}
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
2031
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
2032
|
+
if (shouldMaintainScrollAtEnd) {
|
|
2033
|
+
const contentSize = getContentSize(ctx);
|
|
2034
|
+
if (contentSize < state.scrollLength) {
|
|
2035
|
+
state.scroll = 0;
|
|
1966
2036
|
}
|
|
1967
|
-
|
|
1968
|
-
state.scrollPrev = prevScroll;
|
|
1969
|
-
state.scrollPrevTime = state.scrollTime;
|
|
1970
|
-
state.scroll = newScroll;
|
|
1971
|
-
state.scrollTime = currentTime;
|
|
1972
|
-
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
1973
|
-
const scrollLength = state.scrollLength;
|
|
1974
|
-
const lastCalculated = state.scrollLastCalculate;
|
|
1975
|
-
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
1976
|
-
const shouldUpdate = useAggressiveItemRecalculation || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
1977
|
-
if (shouldUpdate) {
|
|
1978
|
-
state.scrollLastCalculate = state.scroll;
|
|
1979
|
-
state.ignoreScrollFromMVCPIgnored = false;
|
|
1980
|
-
state.lastScrollDelta = scrollDelta;
|
|
1981
|
-
const runCalculateItems = () => {
|
|
2037
|
+
requestAnimationFrame(() => {
|
|
1982
2038
|
var _a3;
|
|
1983
|
-
(
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
}
|
|
1995
|
-
|
|
1996
|
-
// src/utils/requestAdjust.ts
|
|
1997
|
-
function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
1998
|
-
const state = ctx.state;
|
|
1999
|
-
if (Math.abs(positionDiff) > 0.1) {
|
|
2000
|
-
const doit = () => {
|
|
2001
|
-
{
|
|
2002
|
-
state.scrollAdjustHandler.requestAdjust(positionDiff);
|
|
2003
|
-
if (state.adjustingFromInitialMount) {
|
|
2004
|
-
state.adjustingFromInitialMount--;
|
|
2005
|
-
}
|
|
2039
|
+
if (state.isAtEnd) {
|
|
2040
|
+
state.maintainingScrollAtEnd = true;
|
|
2041
|
+
(_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
|
|
2042
|
+
animated: maintainScrollAtEnd.animated
|
|
2043
|
+
});
|
|
2044
|
+
setTimeout(
|
|
2045
|
+
() => {
|
|
2046
|
+
state.maintainingScrollAtEnd = false;
|
|
2047
|
+
},
|
|
2048
|
+
maintainScrollAtEnd.animated ? 500 : 0
|
|
2049
|
+
);
|
|
2006
2050
|
}
|
|
2007
|
-
};
|
|
2008
|
-
|
|
2009
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
2010
|
-
const readyToRender = peek$(ctx, "readyToRender");
|
|
2011
|
-
if (readyToRender) {
|
|
2012
|
-
doit();
|
|
2013
|
-
} else {
|
|
2014
|
-
state.adjustingFromInitialMount = (state.adjustingFromInitialMount || 0) + 1;
|
|
2015
|
-
requestAnimationFrame(doit);
|
|
2016
|
-
}
|
|
2051
|
+
});
|
|
2052
|
+
return true;
|
|
2017
2053
|
}
|
|
2054
|
+
return false;
|
|
2018
2055
|
}
|
|
2019
2056
|
|
|
2020
2057
|
// src/core/mvcp.ts
|
|
2021
2058
|
var MVCP_POSITION_EPSILON = 0.1;
|
|
2022
2059
|
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
2023
2060
|
var MVCP_ANCHOR_LOCK_QUIET_PASSES_TO_RELEASE = 2;
|
|
2061
|
+
var NATIVE_END_CLAMP_EPSILON = 1;
|
|
2024
2062
|
function resolveAnchorLock(state, enableMVCPAnchorLock, mvcpData, now) {
|
|
2025
2063
|
if (!enableMVCPAnchorLock) {
|
|
2026
2064
|
state.mvcpAnchorLock = void 0;
|
|
@@ -2060,6 +2098,82 @@ function updateAnchorLock(state, params) {
|
|
|
2060
2098
|
};
|
|
2061
2099
|
}
|
|
2062
2100
|
}
|
|
2101
|
+
function shouldQueueNativeMVCPAdjust(dataChanged, state, positionDiff, prevTotalSize, prevScroll, scrollTarget) {
|
|
2102
|
+
{
|
|
2103
|
+
return false;
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
function getPredictedNativeClamp(state, unresolvedAmount, totalSize) {
|
|
2107
|
+
if (Math.abs(unresolvedAmount) <= MVCP_POSITION_EPSILON) {
|
|
2108
|
+
return 0;
|
|
2109
|
+
}
|
|
2110
|
+
const maxScroll = Math.max(0, totalSize - state.scrollLength);
|
|
2111
|
+
const clampDelta = maxScroll - state.scroll;
|
|
2112
|
+
if (unresolvedAmount < 0) {
|
|
2113
|
+
return Math.max(unresolvedAmount, Math.min(0, clampDelta));
|
|
2114
|
+
}
|
|
2115
|
+
if (unresolvedAmount > 0) {
|
|
2116
|
+
return Math.min(unresolvedAmount, Math.max(0, clampDelta));
|
|
2117
|
+
}
|
|
2118
|
+
return 0;
|
|
2119
|
+
}
|
|
2120
|
+
function maybeApplyPredictedNativeMVCPAdjust(ctx) {
|
|
2121
|
+
const state = ctx.state;
|
|
2122
|
+
const pending = state.pendingNativeMVCPAdjust;
|
|
2123
|
+
if (!pending || Math.abs(pending.manualApplied) > MVCP_POSITION_EPSILON) {
|
|
2124
|
+
return;
|
|
2125
|
+
}
|
|
2126
|
+
const totalSize = getContentSize(ctx);
|
|
2127
|
+
const predictedNativeClamp = getPredictedNativeClamp(state, pending.amount, totalSize);
|
|
2128
|
+
if (Math.abs(predictedNativeClamp) <= MVCP_POSITION_EPSILON) {
|
|
2129
|
+
return;
|
|
2130
|
+
}
|
|
2131
|
+
const manualDesired = pending.amount - predictedNativeClamp;
|
|
2132
|
+
if (Math.abs(manualDesired) <= MVCP_POSITION_EPSILON) {
|
|
2133
|
+
return;
|
|
2134
|
+
}
|
|
2135
|
+
pending.manualApplied = manualDesired;
|
|
2136
|
+
requestAdjust(ctx, manualDesired);
|
|
2137
|
+
}
|
|
2138
|
+
function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
|
|
2139
|
+
const state = ctx.state;
|
|
2140
|
+
const pending = state.pendingNativeMVCPAdjust;
|
|
2141
|
+
if (!pending) {
|
|
2142
|
+
return false;
|
|
2143
|
+
}
|
|
2144
|
+
const remainingAfterManual = pending.amount - pending.manualApplied;
|
|
2145
|
+
const nativeDelta = newScroll - (pending.startScroll + pending.manualApplied);
|
|
2146
|
+
const isWrongDirection = remainingAfterManual < 0 && nativeDelta > MVCP_POSITION_EPSILON || remainingAfterManual > 0 && nativeDelta < -MVCP_POSITION_EPSILON;
|
|
2147
|
+
if (Math.abs(remainingAfterManual) <= MVCP_POSITION_EPSILON) {
|
|
2148
|
+
state.pendingNativeMVCPAdjust = void 0;
|
|
2149
|
+
return true;
|
|
2150
|
+
}
|
|
2151
|
+
if (isWrongDirection) {
|
|
2152
|
+
state.pendingNativeMVCPAdjust = void 0;
|
|
2153
|
+
return false;
|
|
2154
|
+
}
|
|
2155
|
+
const expectedNativeClampScroll = Math.max(0, getContentSize(ctx) - state.scrollLength);
|
|
2156
|
+
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
|
+
const isAtExpectedNativeClamp = distanceToClamp <= NATIVE_END_CLAMP_EPSILON;
|
|
2167
|
+
if (!isAtExpectedNativeClamp) {
|
|
2168
|
+
return false;
|
|
2169
|
+
}
|
|
2170
|
+
state.pendingNativeMVCPAdjust = void 0;
|
|
2171
|
+
const remaining = remainingAfterManual - nativeDelta;
|
|
2172
|
+
if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
|
|
2173
|
+
requestAdjust(ctx, remaining);
|
|
2174
|
+
}
|
|
2175
|
+
return true;
|
|
2176
|
+
}
|
|
2063
2177
|
function prepareMVCP(ctx, dataChanged) {
|
|
2064
2178
|
const state = ctx.state;
|
|
2065
2179
|
const { idsInView, positions, props } = state;
|
|
@@ -2078,6 +2192,8 @@ function prepareMVCP(ctx, dataChanged) {
|
|
|
2078
2192
|
const isEndAnchoredScrollTarget = scrollTarget !== void 0 && state.props.data.length > 0 && scrollTarget >= state.props.data.length - 1 && (scrollingToViewPosition != null ? scrollingToViewPosition : 0) > 0;
|
|
2079
2193
|
const shouldMVCP = dataChanged ? mvcpData : mvcpScroll;
|
|
2080
2194
|
const indexByKey = state.indexByKey;
|
|
2195
|
+
const prevScroll = state.scroll;
|
|
2196
|
+
getContentSize(ctx);
|
|
2081
2197
|
if (shouldMVCP) {
|
|
2082
2198
|
if (anchorLock && scrollTarget === void 0) {
|
|
2083
2199
|
targetId = anchorLock.id;
|
|
@@ -2184,6 +2300,19 @@ function prepareMVCP(ctx, dataChanged) {
|
|
|
2184
2300
|
now,
|
|
2185
2301
|
positionDiff
|
|
2186
2302
|
});
|
|
2303
|
+
if (shouldQueueNativeMVCPAdjust()) {
|
|
2304
|
+
state.pendingNativeMVCPAdjust = {
|
|
2305
|
+
amount: positionDiff,
|
|
2306
|
+
closestDistanceToClamp: Math.abs(
|
|
2307
|
+
prevScroll - Math.max(0, getContentSize(ctx) - state.scrollLength)
|
|
2308
|
+
),
|
|
2309
|
+
hasApproachedClamp: false,
|
|
2310
|
+
manualApplied: 0,
|
|
2311
|
+
startScroll: prevScroll
|
|
2312
|
+
};
|
|
2313
|
+
maybeApplyPredictedNativeMVCPAdjust(ctx);
|
|
2314
|
+
return;
|
|
2315
|
+
}
|
|
2187
2316
|
if (Math.abs(positionDiff) > MVCP_POSITION_EPSILON) {
|
|
2188
2317
|
requestAdjust(ctx, positionDiff);
|
|
2189
2318
|
}
|
|
@@ -2191,6 +2320,94 @@ function prepareMVCP(ctx, dataChanged) {
|
|
|
2191
2320
|
}
|
|
2192
2321
|
}
|
|
2193
2322
|
|
|
2323
|
+
// src/core/updateScroll.ts
|
|
2324
|
+
function updateScroll(ctx, newScroll, forceUpdate) {
|
|
2325
|
+
var _a3;
|
|
2326
|
+
const state = ctx.state;
|
|
2327
|
+
const { ignoreScrollFromMVCP, lastScrollAdjustForHistory, scrollAdjustHandler, scrollHistory, scrollingTo } = state;
|
|
2328
|
+
const prevScroll = state.scroll;
|
|
2329
|
+
state.hasScrolled = true;
|
|
2330
|
+
state.lastBatchingAction = Date.now();
|
|
2331
|
+
const currentTime = Date.now();
|
|
2332
|
+
const adjust = scrollAdjustHandler.getAdjust();
|
|
2333
|
+
const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
|
|
2334
|
+
if (adjustChanged) {
|
|
2335
|
+
scrollHistory.length = 0;
|
|
2336
|
+
}
|
|
2337
|
+
state.lastScrollAdjustForHistory = adjust;
|
|
2338
|
+
if (scrollingTo === void 0 && !(scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
2339
|
+
if (!adjustChanged) {
|
|
2340
|
+
scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
if (scrollHistory.length > 5) {
|
|
2344
|
+
scrollHistory.shift();
|
|
2345
|
+
}
|
|
2346
|
+
if (ignoreScrollFromMVCP && !scrollingTo) {
|
|
2347
|
+
const { lt, gt } = ignoreScrollFromMVCP;
|
|
2348
|
+
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
2349
|
+
state.ignoreScrollFromMVCPIgnored = true;
|
|
2350
|
+
return;
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
state.scrollPrev = prevScroll;
|
|
2354
|
+
state.scrollPrevTime = state.scrollTime;
|
|
2355
|
+
state.scroll = newScroll;
|
|
2356
|
+
state.scrollTime = currentTime;
|
|
2357
|
+
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
2358
|
+
const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
|
|
2359
|
+
const scrollLength = state.scrollLength;
|
|
2360
|
+
const lastCalculated = state.scrollLastCalculate;
|
|
2361
|
+
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
2362
|
+
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
2363
|
+
if (shouldUpdate) {
|
|
2364
|
+
state.scrollLastCalculate = state.scroll;
|
|
2365
|
+
state.ignoreScrollFromMVCPIgnored = false;
|
|
2366
|
+
state.lastScrollDelta = scrollDelta;
|
|
2367
|
+
const runCalculateItems = () => {
|
|
2368
|
+
var _a4;
|
|
2369
|
+
(_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, { doMVCP: scrollingTo !== void 0 });
|
|
2370
|
+
checkThresholds(ctx);
|
|
2371
|
+
};
|
|
2372
|
+
if (scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength) {
|
|
2373
|
+
ReactDOM.flushSync(runCalculateItems);
|
|
2374
|
+
} else {
|
|
2375
|
+
runCalculateItems();
|
|
2376
|
+
}
|
|
2377
|
+
const shouldMaintainScrollAtEndAfterPendingSettle = !!state.pendingMaintainScrollAtEnd || !!((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onDataChange);
|
|
2378
|
+
if (didResolvePendingNativeMVCPAdjust && shouldMaintainScrollAtEndAfterPendingSettle) {
|
|
2379
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
2380
|
+
doMaintainScrollAtEnd(ctx);
|
|
2381
|
+
}
|
|
2382
|
+
state.dataChangeNeedsScrollUpdate = false;
|
|
2383
|
+
state.lastScrollDelta = 0;
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
2386
|
+
|
|
2387
|
+
// src/utils/requestAdjust.ts
|
|
2388
|
+
function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
2389
|
+
const state = ctx.state;
|
|
2390
|
+
if (Math.abs(positionDiff) > 0.1) {
|
|
2391
|
+
const doit = () => {
|
|
2392
|
+
{
|
|
2393
|
+
state.scrollAdjustHandler.requestAdjust(positionDiff);
|
|
2394
|
+
if (state.adjustingFromInitialMount) {
|
|
2395
|
+
state.adjustingFromInitialMount--;
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
};
|
|
2399
|
+
state.scroll += positionDiff;
|
|
2400
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
2401
|
+
const readyToRender = peek$(ctx, "readyToRender");
|
|
2402
|
+
if (readyToRender) {
|
|
2403
|
+
doit();
|
|
2404
|
+
} else {
|
|
2405
|
+
state.adjustingFromInitialMount = (state.adjustingFromInitialMount || 0) + 1;
|
|
2406
|
+
requestAnimationFrame(doit);
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
|
|
2194
2411
|
// src/core/prepareColumnStartState.ts
|
|
2195
2412
|
function prepareColumnStartState(ctx, startIndex, useAverageSize) {
|
|
2196
2413
|
var _a3;
|
|
@@ -2844,7 +3061,14 @@ function comparatorByDistance(a, b) {
|
|
|
2844
3061
|
}
|
|
2845
3062
|
|
|
2846
3063
|
// src/core/scrollToIndex.ts
|
|
2847
|
-
function scrollToIndex(ctx, {
|
|
3064
|
+
function scrollToIndex(ctx, {
|
|
3065
|
+
index,
|
|
3066
|
+
viewOffset = 0,
|
|
3067
|
+
animated = true,
|
|
3068
|
+
forceScroll,
|
|
3069
|
+
isInitialScroll,
|
|
3070
|
+
viewPosition
|
|
3071
|
+
}) {
|
|
2848
3072
|
const state = ctx.state;
|
|
2849
3073
|
const { data } = state.props;
|
|
2850
3074
|
if (index >= data.length) {
|
|
@@ -2862,7 +3086,9 @@ function scrollToIndex(ctx, { index, viewOffset = 0, animated = true, viewPositi
|
|
|
2862
3086
|
const itemSize = getItemSize(ctx, targetId, index, state.props.data[index]);
|
|
2863
3087
|
scrollTo(ctx, {
|
|
2864
3088
|
animated,
|
|
3089
|
+
forceScroll,
|
|
2865
3090
|
index,
|
|
3091
|
+
isInitialScroll,
|
|
2866
3092
|
itemSize,
|
|
2867
3093
|
offset: firstIndexOffset,
|
|
2868
3094
|
viewOffset,
|
|
@@ -2870,15 +3096,58 @@ function scrollToIndex(ctx, { index, viewOffset = 0, animated = true, viewPositi
|
|
|
2870
3096
|
});
|
|
2871
3097
|
}
|
|
2872
3098
|
|
|
3099
|
+
// src/utils/performInitialScroll.ts
|
|
3100
|
+
function performInitialScroll(ctx, params) {
|
|
3101
|
+
var _a3;
|
|
3102
|
+
const { forceScroll, initialScrollUsesOffset, resolvedOffset, target } = params;
|
|
3103
|
+
if (initialScrollUsesOffset || resolvedOffset !== void 0) {
|
|
3104
|
+
scrollTo(ctx, {
|
|
3105
|
+
animated: false,
|
|
3106
|
+
forceScroll,
|
|
3107
|
+
index: initialScrollUsesOffset ? void 0 : target.index,
|
|
3108
|
+
isInitialScroll: true,
|
|
3109
|
+
offset: (_a3 = resolvedOffset != null ? resolvedOffset : target.contentOffset) != null ? _a3 : 0,
|
|
3110
|
+
precomputedWithViewOffset: resolvedOffset !== void 0
|
|
3111
|
+
});
|
|
3112
|
+
return;
|
|
3113
|
+
}
|
|
3114
|
+
if (target.index === void 0) {
|
|
3115
|
+
return;
|
|
3116
|
+
}
|
|
3117
|
+
scrollToIndex(ctx, {
|
|
3118
|
+
...target,
|
|
3119
|
+
animated: false,
|
|
3120
|
+
forceScroll,
|
|
3121
|
+
isInitialScroll: true
|
|
3122
|
+
});
|
|
3123
|
+
}
|
|
3124
|
+
|
|
2873
3125
|
// src/utils/setDidLayout.ts
|
|
2874
3126
|
function setDidLayout(ctx) {
|
|
2875
3127
|
const state = ctx.state;
|
|
2876
3128
|
const { initialScroll } = state;
|
|
2877
3129
|
state.queuedInitialLayout = true;
|
|
2878
3130
|
checkAtBottom(ctx);
|
|
2879
|
-
if (
|
|
2880
|
-
const
|
|
2881
|
-
|
|
3131
|
+
if (initialScroll) {
|
|
3132
|
+
const runScroll = () => {
|
|
3133
|
+
var _a3, _b;
|
|
3134
|
+
const target = state.initialScroll;
|
|
3135
|
+
if (!target) {
|
|
3136
|
+
return;
|
|
3137
|
+
}
|
|
3138
|
+
const activeInitialTargetOffset = ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) ? (_b = state.scrollingTo.targetOffset) != null ? _b : state.scrollingTo.offset : void 0;
|
|
3139
|
+
const desiredInitialTargetOffset = state.initialScrollUsesOffset ? target.contentOffset : activeInitialTargetOffset;
|
|
3140
|
+
const isAlreadyAtDesiredInitialTarget = desiredInitialTargetOffset !== void 0 && Math.abs(state.scroll - desiredInitialTargetOffset) <= 1 && Math.abs(state.scrollPending - desiredInitialTargetOffset) <= 1;
|
|
3141
|
+
if (!isAlreadyAtDesiredInitialTarget) {
|
|
3142
|
+
performInitialScroll(ctx, {
|
|
3143
|
+
forceScroll: true,
|
|
3144
|
+
initialScrollUsesOffset: state.initialScrollUsesOffset,
|
|
3145
|
+
// Offset-based initial scrolls do not need item lookup, so they can run even before data exists.
|
|
3146
|
+
// Re-run on the next frame to pick up measured viewport size without waiting for index resolution.
|
|
3147
|
+
target
|
|
3148
|
+
});
|
|
3149
|
+
}
|
|
3150
|
+
};
|
|
2882
3151
|
runScroll();
|
|
2883
3152
|
requestAnimationFrame(runScroll);
|
|
2884
3153
|
}
|
|
@@ -2956,7 +3225,7 @@ function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentSt
|
|
|
2956
3225
|
function calculateItemsInView(ctx, params = {}) {
|
|
2957
3226
|
const state = ctx.state;
|
|
2958
3227
|
batchedUpdates(() => {
|
|
2959
|
-
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
3228
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
2960
3229
|
const {
|
|
2961
3230
|
columns,
|
|
2962
3231
|
columnSpans,
|
|
@@ -2992,7 +3261,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
2992
3261
|
if (!data || scrollLength === 0 || !prevNumContainers) {
|
|
2993
3262
|
return;
|
|
2994
3263
|
}
|
|
2995
|
-
|
|
3264
|
+
let totalSize = getContentSize(ctx);
|
|
2996
3265
|
const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
|
|
2997
3266
|
const numColumns = peek$(ctx, "numColumns");
|
|
2998
3267
|
const speed = getScrollVelocity(state);
|
|
@@ -3000,14 +3269,14 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
3000
3269
|
const { queuedInitialLayout } = state;
|
|
3001
3270
|
let { scroll: scrollState } = state;
|
|
3002
3271
|
if (!queuedInitialLayout && initialScroll) {
|
|
3003
|
-
const updatedOffset = calculateOffsetWithOffsetPosition(
|
|
3272
|
+
const updatedOffset = state.initialScrollUsesOffset ? (_a3 = initialScroll.contentOffset) != null ? _a3 : 0 : calculateOffsetWithOffsetPosition(
|
|
3004
3273
|
ctx,
|
|
3005
3274
|
calculateOffsetForIndex(ctx, initialScroll.index),
|
|
3006
3275
|
initialScroll
|
|
3007
3276
|
);
|
|
3008
3277
|
scrollState = updatedOffset;
|
|
3009
3278
|
}
|
|
3010
|
-
const scrollAdjustPending = (
|
|
3279
|
+
const scrollAdjustPending = (_b = peek$(ctx, "scrollAdjustPending")) != null ? _b : 0;
|
|
3011
3280
|
const scrollAdjustPad = scrollAdjustPending - topPad;
|
|
3012
3281
|
let scroll = Math.round(scrollState + scrollExtra + scrollAdjustPad);
|
|
3013
3282
|
if (scroll + scrollLength > totalSize) {
|
|
@@ -3049,13 +3318,14 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
3049
3318
|
columns.length = 0;
|
|
3050
3319
|
columnSpans.length = 0;
|
|
3051
3320
|
}
|
|
3052
|
-
const startIndex = forceFullItemPositions || dataChanged ? 0 : (
|
|
3321
|
+
const startIndex = forceFullItemPositions || dataChanged ? 0 : (_c = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _c : 0;
|
|
3053
3322
|
updateItemPositions(ctx, dataChanged, {
|
|
3054
3323
|
doMVCP,
|
|
3055
3324
|
forceFullUpdate: !!forceFullItemPositions,
|
|
3056
3325
|
scrollBottomBuffered,
|
|
3057
3326
|
startIndex
|
|
3058
3327
|
});
|
|
3328
|
+
totalSize = getContentSize(ctx);
|
|
3059
3329
|
if (minIndexSizeChanged !== void 0) {
|
|
3060
3330
|
state.minIndexSizeChanged = void 0;
|
|
3061
3331
|
}
|
|
@@ -3067,9 +3337,9 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
3067
3337
|
let endBuffered = null;
|
|
3068
3338
|
let loopStart = !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
|
|
3069
3339
|
for (let i = loopStart; i >= 0; i--) {
|
|
3070
|
-
const id = (
|
|
3340
|
+
const id = (_d = idCache[i]) != null ? _d : getId(state, i);
|
|
3071
3341
|
const top = positions[i];
|
|
3072
|
-
const size = (
|
|
3342
|
+
const size = (_e = sizes.get(id)) != null ? _e : getItemSize(ctx, id, i, data[i]);
|
|
3073
3343
|
const bottom = top + size;
|
|
3074
3344
|
if (bottom > scroll - scrollBufferTop) {
|
|
3075
3345
|
loopStart = i;
|
|
@@ -3100,14 +3370,14 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
3100
3370
|
let firstFullyOnScreenIndex;
|
|
3101
3371
|
const dataLength = data.length;
|
|
3102
3372
|
for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
|
|
3103
|
-
const id = (
|
|
3104
|
-
const size = (
|
|
3373
|
+
const id = (_f = idCache[i]) != null ? _f : getId(state, i);
|
|
3374
|
+
const size = (_g = sizes.get(id)) != null ? _g : getItemSize(ctx, id, i, data[i]);
|
|
3105
3375
|
const top = positions[i];
|
|
3106
3376
|
if (!foundEnd) {
|
|
3107
3377
|
if (startNoBuffer === null && top + size > scroll) {
|
|
3108
3378
|
startNoBuffer = i;
|
|
3109
3379
|
}
|
|
3110
|
-
if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10) {
|
|
3380
|
+
if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10 && top <= scrollBottom) {
|
|
3111
3381
|
firstFullyOnScreenIndex = i;
|
|
3112
3382
|
}
|
|
3113
3383
|
if (startBuffered === null && top + size > scrollTopBuffered) {
|
|
@@ -3137,9 +3407,12 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
3137
3407
|
}
|
|
3138
3408
|
}
|
|
3139
3409
|
const idsInView = [];
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3410
|
+
const firstVisibleAnchorIndex = firstFullyOnScreenIndex != null ? firstFullyOnScreenIndex : startNoBuffer;
|
|
3411
|
+
if (firstVisibleAnchorIndex !== null && firstVisibleAnchorIndex !== void 0 && endNoBuffer !== null) {
|
|
3412
|
+
for (let i = firstVisibleAnchorIndex; i <= endNoBuffer; i++) {
|
|
3413
|
+
const id = (_h = idCache[i]) != null ? _h : getId(state, i);
|
|
3414
|
+
idsInView.push(id);
|
|
3415
|
+
}
|
|
3143
3416
|
}
|
|
3144
3417
|
Object.assign(state, {
|
|
3145
3418
|
endBuffered,
|
|
@@ -3170,7 +3443,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
3170
3443
|
const needNewContainers = [];
|
|
3171
3444
|
const needNewContainersSet = /* @__PURE__ */ new Set();
|
|
3172
3445
|
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
3173
|
-
const id = (
|
|
3446
|
+
const id = (_i = idCache[i]) != null ? _i : getId(state, i);
|
|
3174
3447
|
if (!containerItemKeys.has(id)) {
|
|
3175
3448
|
needNewContainersSet.add(i);
|
|
3176
3449
|
needNewContainers.push(i);
|
|
@@ -3179,7 +3452,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
3179
3452
|
if (alwaysRenderArr.length > 0) {
|
|
3180
3453
|
for (const index of alwaysRenderArr) {
|
|
3181
3454
|
if (index < 0 || index >= dataLength) continue;
|
|
3182
|
-
const id = (
|
|
3455
|
+
const id = (_j = idCache[index]) != null ? _j : getId(state, index);
|
|
3183
3456
|
if (id && !containerItemKeys.has(id) && !needNewContainersSet.has(index)) {
|
|
3184
3457
|
needNewContainersSet.add(index);
|
|
3185
3458
|
needNewContainers.push(index);
|
|
@@ -3217,7 +3490,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
3217
3490
|
for (let idx = 0; idx < needNewContainers.length; idx++) {
|
|
3218
3491
|
const i = needNewContainers[idx];
|
|
3219
3492
|
const containerIndex = availableContainers[idx];
|
|
3220
|
-
const id = (
|
|
3493
|
+
const id = (_k = idCache[i]) != null ? _k : getId(state, i);
|
|
3221
3494
|
const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
3222
3495
|
if (oldKey && oldKey !== id) {
|
|
3223
3496
|
containerItemKeys.delete(oldKey);
|
|
@@ -3258,7 +3531,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
3258
3531
|
if (alwaysRenderArr.length > 0) {
|
|
3259
3532
|
for (const index of alwaysRenderArr) {
|
|
3260
3533
|
if (index < 0 || index >= dataLength) continue;
|
|
3261
|
-
const id = (
|
|
3534
|
+
const id = (_l = idCache[index]) != null ? _l : getId(state, index);
|
|
3262
3535
|
const containerIndex = containerItemKeys.get(id);
|
|
3263
3536
|
if (containerIndex !== void 0) {
|
|
3264
3537
|
state.stickyContainerPool.add(containerIndex);
|
|
@@ -3367,21 +3640,21 @@ function checkActualChange(state, dataProp, previousData) {
|
|
|
3367
3640
|
}
|
|
3368
3641
|
|
|
3369
3642
|
// src/core/checkFinishedScroll.ts
|
|
3643
|
+
var INITIAL_SCROLL_MIN_TARGET_OFFSET = 1;
|
|
3644
|
+
var INITIAL_SCROLL_MAX_FALLBACK_CHECKS = 20;
|
|
3645
|
+
var INITIAL_SCROLL_ZERO_TARGET_EPSILON = 1;
|
|
3370
3646
|
function checkFinishedScroll(ctx) {
|
|
3371
3647
|
ctx.state.animFrameCheckFinishedScroll = requestAnimationFrame(() => checkFinishedScrollFrame(ctx));
|
|
3372
3648
|
}
|
|
3373
3649
|
function checkFinishedScrollFrame(ctx) {
|
|
3650
|
+
var _a3;
|
|
3374
3651
|
const scrollingTo = ctx.state.scrollingTo;
|
|
3375
3652
|
if (scrollingTo) {
|
|
3376
3653
|
const { state } = ctx;
|
|
3377
3654
|
state.animFrameCheckFinishedScroll = void 0;
|
|
3378
3655
|
const scroll = state.scrollPending;
|
|
3379
3656
|
const adjust = state.scrollAdjustHandler.getAdjust();
|
|
3380
|
-
const clampedTargetOffset = clampScrollOffset(
|
|
3381
|
-
ctx,
|
|
3382
|
-
scrollingTo.offset - (scrollingTo.viewOffset || 0),
|
|
3383
|
-
scrollingTo
|
|
3384
|
-
);
|
|
3657
|
+
const clampedTargetOffset = (_a3 = scrollingTo.targetOffset) != null ? _a3 : clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0), scrollingTo);
|
|
3385
3658
|
const maxOffset = clampScrollOffset(ctx, scroll, scrollingTo);
|
|
3386
3659
|
const diff1 = Math.abs(scroll - clampedTargetOffset);
|
|
3387
3660
|
const diff2 = Math.abs(diff1 - adjust);
|
|
@@ -3395,17 +3668,33 @@ function checkFinishedScrollFrame(ctx) {
|
|
|
3395
3668
|
function checkFinishedScrollFallback(ctx) {
|
|
3396
3669
|
const state = ctx.state;
|
|
3397
3670
|
const scrollingTo = state.scrollingTo;
|
|
3398
|
-
const
|
|
3671
|
+
const shouldFinishInitialZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
|
|
3672
|
+
const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && !shouldFinishInitialZeroTarget || !state.didContainersLayout;
|
|
3399
3673
|
state.timeoutCheckFinishedScrollFallback = setTimeout(
|
|
3400
3674
|
() => {
|
|
3401
3675
|
let numChecks = 0;
|
|
3402
3676
|
const checkHasScrolled = () => {
|
|
3677
|
+
var _a3, _b;
|
|
3403
3678
|
state.timeoutCheckFinishedScrollFallback = void 0;
|
|
3404
3679
|
const isStillScrollingTo = state.scrollingTo;
|
|
3405
3680
|
if (isStillScrollingTo) {
|
|
3406
3681
|
numChecks++;
|
|
3407
|
-
|
|
3682
|
+
const isNativeInitialPending = isNativeInitialNonZeroTarget(state) && !state.hasScrolled;
|
|
3683
|
+
const maxChecks = isNativeInitialPending ? INITIAL_SCROLL_MAX_FALLBACK_CHECKS : 5;
|
|
3684
|
+
const shouldFinishZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
|
|
3685
|
+
if (shouldFinishZeroTarget || state.hasScrolled || numChecks > maxChecks) {
|
|
3408
3686
|
finishScrollTo(ctx);
|
|
3687
|
+
} else if (isNativeInitialPending && numChecks <= maxChecks) {
|
|
3688
|
+
const targetOffset = (_b = (_a3 = state.initialNativeScrollWatchdog) == null ? void 0 : _a3.targetOffset) != null ? _b : state.scrollPending;
|
|
3689
|
+
const scroller = state.refScroller.current;
|
|
3690
|
+
if (scroller) {
|
|
3691
|
+
scroller.scrollTo({
|
|
3692
|
+
animated: false,
|
|
3693
|
+
x: state.props.horizontal ? targetOffset : 0,
|
|
3694
|
+
y: state.props.horizontal ? 0 : targetOffset
|
|
3695
|
+
});
|
|
3696
|
+
}
|
|
3697
|
+
state.timeoutCheckFinishedScrollFallback = setTimeout(checkHasScrolled, 100);
|
|
3409
3698
|
} else {
|
|
3410
3699
|
state.timeoutCheckFinishedScrollFallback = setTimeout(checkHasScrolled, 100);
|
|
3411
3700
|
}
|
|
@@ -3416,39 +3705,13 @@ function checkFinishedScrollFallback(ctx) {
|
|
|
3416
3705
|
slowTimeout ? 500 : 100
|
|
3417
3706
|
);
|
|
3418
3707
|
}
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
refScroller,
|
|
3427
|
-
props: { maintainScrollAtEnd }
|
|
3428
|
-
} = state;
|
|
3429
|
-
if (isAtEnd && maintainScrollAtEnd && didContainersLayout) {
|
|
3430
|
-
const contentSize = getContentSize(ctx);
|
|
3431
|
-
if (contentSize < state.scrollLength) {
|
|
3432
|
-
state.scroll = 0;
|
|
3433
|
-
}
|
|
3434
|
-
requestAnimationFrame(() => {
|
|
3435
|
-
var _a3;
|
|
3436
|
-
if (state.isAtEnd) {
|
|
3437
|
-
state.maintainingScrollAtEnd = true;
|
|
3438
|
-
(_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
|
|
3439
|
-
animated
|
|
3440
|
-
});
|
|
3441
|
-
setTimeout(
|
|
3442
|
-
() => {
|
|
3443
|
-
state.maintainingScrollAtEnd = false;
|
|
3444
|
-
},
|
|
3445
|
-
0
|
|
3446
|
-
);
|
|
3447
|
-
}
|
|
3448
|
-
});
|
|
3449
|
-
return true;
|
|
3450
|
-
}
|
|
3451
|
-
return false;
|
|
3708
|
+
function isNativeInitialNonZeroTarget(state) {
|
|
3709
|
+
return !state.didFinishInitialScroll && !!state.initialNativeScrollWatchdog && state.initialNativeScrollWatchdog.targetOffset > INITIAL_SCROLL_MIN_TARGET_OFFSET;
|
|
3710
|
+
}
|
|
3711
|
+
function shouldFinishInitialZeroTargetScroll(ctx) {
|
|
3712
|
+
var _a3;
|
|
3713
|
+
const { state } = ctx;
|
|
3714
|
+
return !!((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) && state.props.data.length > 0 && getContentSize(ctx) <= state.scrollLength && state.scrollPending <= INITIAL_SCROLL_ZERO_TARGET_EPSILON;
|
|
3452
3715
|
}
|
|
3453
3716
|
|
|
3454
3717
|
// src/utils/updateAveragesOnDataChange.ts
|
|
@@ -3512,8 +3775,8 @@ function checkResetContainers(ctx, dataProp) {
|
|
|
3512
3775
|
}
|
|
3513
3776
|
const { maintainScrollAtEnd } = state.props;
|
|
3514
3777
|
calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
|
|
3515
|
-
const shouldMaintainScrollAtEnd = maintainScrollAtEnd
|
|
3516
|
-
const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx
|
|
3778
|
+
const shouldMaintainScrollAtEnd = maintainScrollAtEnd == null ? void 0 : maintainScrollAtEnd.onDataChange;
|
|
3779
|
+
const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx);
|
|
3517
3780
|
if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
|
|
3518
3781
|
state.isEndReached = false;
|
|
3519
3782
|
}
|
|
@@ -3621,8 +3884,8 @@ function handleLayout(ctx, layoutParam, setCanRender) {
|
|
|
3621
3884
|
if (didChange || otherAxisSize !== prevOtherAxisSize) {
|
|
3622
3885
|
set$(ctx, "scrollSize", { height: layout.height, width: layout.width });
|
|
3623
3886
|
}
|
|
3624
|
-
if (maintainScrollAtEnd
|
|
3625
|
-
doMaintainScrollAtEnd(ctx
|
|
3887
|
+
if (maintainScrollAtEnd == null ? void 0 : maintainScrollAtEnd.onLayout) {
|
|
3888
|
+
doMaintainScrollAtEnd(ctx);
|
|
3626
3889
|
}
|
|
3627
3890
|
checkThresholds(ctx);
|
|
3628
3891
|
if (state) {
|
|
@@ -3639,6 +3902,12 @@ function handleLayout(ctx, layoutParam, setCanRender) {
|
|
|
3639
3902
|
}
|
|
3640
3903
|
|
|
3641
3904
|
// src/core/onScroll.ts
|
|
3905
|
+
var INITIAL_SCROLL_PROGRESS_EPSILON = 1;
|
|
3906
|
+
function didObserveInitialScrollProgress(newScroll, watchdog) {
|
|
3907
|
+
const previousDistance = Math.abs(watchdog.startScroll - watchdog.targetOffset);
|
|
3908
|
+
const nextDistance = Math.abs(newScroll - watchdog.targetOffset);
|
|
3909
|
+
return nextDistance <= INITIAL_SCROLL_PROGRESS_EPSILON || nextDistance + INITIAL_SCROLL_PROGRESS_EPSILON < previousDistance;
|
|
3910
|
+
}
|
|
3642
3911
|
function onScroll(ctx, event) {
|
|
3643
3912
|
var _a3, _b, _c, _d;
|
|
3644
3913
|
const state = ctx.state;
|
|
@@ -3676,7 +3945,16 @@ function onScroll(ctx, event) {
|
|
|
3676
3945
|
}
|
|
3677
3946
|
}
|
|
3678
3947
|
state.scrollPending = newScroll;
|
|
3948
|
+
const initialNativeScrollWatchdog = state.initialNativeScrollWatchdog;
|
|
3949
|
+
const didInitialScrollProgress = !!initialNativeScrollWatchdog && didObserveInitialScrollProgress(newScroll, initialNativeScrollWatchdog);
|
|
3950
|
+
if (didInitialScrollProgress) {
|
|
3951
|
+
state.initialNativeScrollWatchdog = void 0;
|
|
3952
|
+
}
|
|
3679
3953
|
updateScroll(ctx, newScroll, insetChanged);
|
|
3954
|
+
if (initialNativeScrollWatchdog && !didInitialScrollProgress) {
|
|
3955
|
+
state.hasScrolled = false;
|
|
3956
|
+
state.initialNativeScrollWatchdog = initialNativeScrollWatchdog;
|
|
3957
|
+
}
|
|
3680
3958
|
if (state.scrollingTo) {
|
|
3681
3959
|
checkFinishedScroll(ctx);
|
|
3682
3960
|
}
|
|
@@ -3841,8 +4119,8 @@ function updateItemSize(ctx, itemKey, sizeObj) {
|
|
|
3841
4119
|
runOrScheduleMVCPRecalculate(ctx);
|
|
3842
4120
|
}
|
|
3843
4121
|
if (shouldMaintainScrollAtEnd) {
|
|
3844
|
-
if (maintainScrollAtEnd
|
|
3845
|
-
doMaintainScrollAtEnd(ctx
|
|
4122
|
+
if (maintainScrollAtEnd == null ? void 0 : maintainScrollAtEnd.onItemLayout) {
|
|
4123
|
+
doMaintainScrollAtEnd(ctx);
|
|
3846
4124
|
}
|
|
3847
4125
|
}
|
|
3848
4126
|
}
|
|
@@ -4192,6 +4470,34 @@ function getRenderedItem(ctx, key) {
|
|
|
4192
4470
|
return { index, item: data[index], renderedItem };
|
|
4193
4471
|
}
|
|
4194
4472
|
|
|
4473
|
+
// src/utils/normalizeMaintainScrollAtEnd.ts
|
|
4474
|
+
function normalizeMaintainScrollAtEndOn(on, hasExplicitOn) {
|
|
4475
|
+
var _a3, _b, _c;
|
|
4476
|
+
return {
|
|
4477
|
+
animated: false,
|
|
4478
|
+
onDataChange: hasExplicitOn ? (_a3 = on == null ? void 0 : on.dataChange) != null ? _a3 : false : true,
|
|
4479
|
+
onItemLayout: hasExplicitOn ? (_b = on == null ? void 0 : on.itemLayout) != null ? _b : false : true,
|
|
4480
|
+
onLayout: hasExplicitOn ? (_c = on == null ? void 0 : on.layout) != null ? _c : false : true
|
|
4481
|
+
};
|
|
4482
|
+
}
|
|
4483
|
+
function normalizeMaintainScrollAtEnd(value) {
|
|
4484
|
+
var _a3;
|
|
4485
|
+
if (!value) {
|
|
4486
|
+
return void 0;
|
|
4487
|
+
}
|
|
4488
|
+
if (value === true) {
|
|
4489
|
+
return {
|
|
4490
|
+
...normalizeMaintainScrollAtEndOn(void 0, false),
|
|
4491
|
+
animated: false
|
|
4492
|
+
};
|
|
4493
|
+
}
|
|
4494
|
+
const normalizedTriggers = normalizeMaintainScrollAtEndOn(value.on, "on" in value);
|
|
4495
|
+
return {
|
|
4496
|
+
...normalizedTriggers,
|
|
4497
|
+
animated: (_a3 = value.animated) != null ? _a3 : false
|
|
4498
|
+
};
|
|
4499
|
+
}
|
|
4500
|
+
|
|
4195
4501
|
// src/utils/normalizeMaintainVisibleContentPosition.ts
|
|
4196
4502
|
function normalizeMaintainVisibleContentPosition(value) {
|
|
4197
4503
|
var _a3, _b;
|
|
@@ -4293,7 +4599,7 @@ var LegendList = typedMemo(
|
|
|
4293
4599
|
})
|
|
4294
4600
|
);
|
|
4295
4601
|
var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
|
|
4296
|
-
var _a3, _b, _c, _d, _e;
|
|
4602
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h;
|
|
4297
4603
|
const {
|
|
4298
4604
|
alignItemsAtEnd = false,
|
|
4299
4605
|
alwaysRender,
|
|
@@ -4379,16 +4685,24 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
4379
4685
|
const style = { ...StyleSheet.flatten(styleProp) };
|
|
4380
4686
|
const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
|
|
4381
4687
|
const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
|
|
4688
|
+
const maintainScrollAtEndConfig = normalizeMaintainScrollAtEnd(maintainScrollAtEnd);
|
|
4382
4689
|
const maintainVisibleContentPositionConfig = normalizeMaintainVisibleContentPosition(
|
|
4383
4690
|
maintainVisibleContentPositionProp
|
|
4384
4691
|
);
|
|
4385
|
-
const
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4692
|
+
const hasInitialScrollIndex = initialScrollIndexProp !== void 0 && initialScrollIndexProp !== null;
|
|
4693
|
+
const hasInitialScrollOffset = initialScrollOffsetProp !== void 0 && initialScrollOffsetProp !== null;
|
|
4694
|
+
const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && hasInitialScrollOffset;
|
|
4695
|
+
const initialScrollProp = initialScrollAtEnd ? { index: Math.max(0, dataProp.length - 1), viewOffset: -stylePaddingBottomState, viewPosition: 1 } : hasInitialScrollIndex ? typeof initialScrollIndexProp === "object" ? {
|
|
4696
|
+
index: (_a3 = initialScrollIndexProp.index) != null ? _a3 : 0,
|
|
4697
|
+
viewOffset: (_b = initialScrollIndexProp.viewOffset) != null ? _b : initialScrollIndexProp.viewPosition === 1 ? -stylePaddingBottomState : 0,
|
|
4698
|
+
viewPosition: (_c = initialScrollIndexProp.viewPosition) != null ? _c : 0
|
|
4389
4699
|
} : {
|
|
4390
|
-
index: initialScrollIndexProp
|
|
4391
|
-
viewOffset: initialScrollOffsetProp
|
|
4700
|
+
index: initialScrollIndexProp != null ? initialScrollIndexProp : 0,
|
|
4701
|
+
viewOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : 0
|
|
4702
|
+
} : initialScrollUsesOffsetOnly ? {
|
|
4703
|
+
contentOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : 0,
|
|
4704
|
+
index: 0,
|
|
4705
|
+
viewOffset: 0
|
|
4392
4706
|
} : void 0;
|
|
4393
4707
|
const [canRender, setCanRender] = React3__namespace.useState(false);
|
|
4394
4708
|
const ctx = useStateContext();
|
|
@@ -4403,8 +4717,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
4403
4717
|
}, [
|
|
4404
4718
|
alwaysRender == null ? void 0 : alwaysRender.top,
|
|
4405
4719
|
alwaysRender == null ? void 0 : alwaysRender.bottom,
|
|
4406
|
-
(
|
|
4407
|
-
(
|
|
4720
|
+
(_d = alwaysRender == null ? void 0 : alwaysRender.indices) == null ? void 0 : _d.join(","),
|
|
4721
|
+
(_e = alwaysRender == null ? void 0 : alwaysRender.keys) == null ? void 0 : _e.join(","),
|
|
4408
4722
|
dataProp,
|
|
4409
4723
|
dataVersion,
|
|
4410
4724
|
keyExtractor
|
|
@@ -4448,14 +4762,22 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
4448
4762
|
idCache: [],
|
|
4449
4763
|
idsInView: [],
|
|
4450
4764
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
4451
|
-
initialAnchor: (initialScrollProp == null ? void 0 : initialScrollProp.index) !== void 0 && (initialScrollProp == null ? void 0 : initialScrollProp.viewPosition) !== void 0 ? {
|
|
4765
|
+
initialAnchor: !initialScrollUsesOffsetOnly && (initialScrollProp == null ? void 0 : initialScrollProp.index) !== void 0 && (initialScrollProp == null ? void 0 : initialScrollProp.viewPosition) !== void 0 ? {
|
|
4452
4766
|
attempts: 0,
|
|
4453
4767
|
index: initialScrollProp.index,
|
|
4454
4768
|
settledTicks: 0,
|
|
4455
|
-
viewOffset: (
|
|
4769
|
+
viewOffset: (_f = initialScrollProp.viewOffset) != null ? _f : 0,
|
|
4456
4770
|
viewPosition: initialScrollProp.viewPosition
|
|
4457
4771
|
} : void 0,
|
|
4772
|
+
initialNativeScrollWatchdog: void 0,
|
|
4458
4773
|
initialScroll: initialScrollProp,
|
|
4774
|
+
initialScrollLastDidFinish: false,
|
|
4775
|
+
initialScrollLastTarget: initialScrollProp,
|
|
4776
|
+
initialScrollLastTargetUsesOffset: initialScrollUsesOffsetOnly,
|
|
4777
|
+
initialScrollPreviousDataLength: dataProp.length,
|
|
4778
|
+
initialScrollRetryLastLength: void 0,
|
|
4779
|
+
initialScrollRetryWindowUntil: 0,
|
|
4780
|
+
initialScrollUsesOffset: initialScrollUsesOffsetOnly,
|
|
4459
4781
|
isAtEnd: false,
|
|
4460
4782
|
isAtStart: false,
|
|
4461
4783
|
isEndReached: null,
|
|
@@ -4468,6 +4790,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
4468
4790
|
minIndexSizeChanged: 0,
|
|
4469
4791
|
nativeContentInset: void 0,
|
|
4470
4792
|
nativeMarginTop: 0,
|
|
4793
|
+
pendingNativeMVCPAdjust: void 0,
|
|
4471
4794
|
positions: [],
|
|
4472
4795
|
props: {},
|
|
4473
4796
|
queuedCalculateItemsInView: 0,
|
|
@@ -4505,7 +4828,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
4505
4828
|
const state = refState.current;
|
|
4506
4829
|
const isFirstLocal = state.isFirst;
|
|
4507
4830
|
state.didColumnsChange = numColumnsProp !== state.props.numColumns;
|
|
4508
|
-
const
|
|
4831
|
+
const didDataReferenceChangeLocal = state.props.data !== dataProp;
|
|
4832
|
+
const didDataVersionChangeLocal = state.props.dataVersion !== dataVersion;
|
|
4833
|
+
const didDataChangeLocal = didDataVersionChangeLocal || didDataReferenceChangeLocal && checkActualChange(state, dataProp, state.props.data);
|
|
4509
4834
|
if (didDataChangeLocal) {
|
|
4510
4835
|
state.dataChangeEpoch += 1;
|
|
4511
4836
|
state.dataChangeNeedsScrollUpdate = true;
|
|
@@ -4531,7 +4856,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
4531
4856
|
initialContainerPoolRatio,
|
|
4532
4857
|
itemsAreEqual,
|
|
4533
4858
|
keyExtractor: useWrapIfItem(keyExtractor),
|
|
4534
|
-
maintainScrollAtEnd,
|
|
4859
|
+
maintainScrollAtEnd: maintainScrollAtEndConfig,
|
|
4535
4860
|
maintainScrollAtEndThreshold,
|
|
4536
4861
|
maintainVisibleContentPosition: maintainVisibleContentPositionConfig,
|
|
4537
4862
|
numColumns: numColumnsProp,
|
|
@@ -4582,29 +4907,93 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
4582
4907
|
);
|
|
4583
4908
|
}
|
|
4584
4909
|
const resolveInitialScrollOffset = React3.useCallback((initialScroll) => {
|
|
4910
|
+
var _a4;
|
|
4911
|
+
if (state.initialScrollUsesOffset) {
|
|
4912
|
+
return clampScrollOffset(ctx, (_a4 = initialScroll.contentOffset) != null ? _a4 : 0);
|
|
4913
|
+
}
|
|
4585
4914
|
const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
|
|
4586
4915
|
const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
|
|
4587
4916
|
return clampScrollOffset(ctx, resolvedOffset, initialScroll);
|
|
4588
4917
|
}, []);
|
|
4918
|
+
const finishInitialScrollWithoutScroll = React3.useCallback(() => {
|
|
4919
|
+
refState.current.initialAnchor = void 0;
|
|
4920
|
+
refState.current.initialScroll = void 0;
|
|
4921
|
+
state.initialAnchor = void 0;
|
|
4922
|
+
state.initialScroll = void 0;
|
|
4923
|
+
state.initialScrollUsesOffset = false;
|
|
4924
|
+
state.initialScrollLastTarget = void 0;
|
|
4925
|
+
state.initialScrollLastTargetUsesOffset = false;
|
|
4926
|
+
setInitialRenderState(ctx, { didInitialScroll: true });
|
|
4927
|
+
}, []);
|
|
4928
|
+
const setActiveInitialScrollTarget = React3.useCallback(
|
|
4929
|
+
(target, options) => {
|
|
4930
|
+
const usesOffset = !!(options == null ? void 0 : options.usesOffset);
|
|
4931
|
+
state.initialScrollUsesOffset = usesOffset;
|
|
4932
|
+
state.initialScrollLastTarget = target;
|
|
4933
|
+
state.initialScrollLastTargetUsesOffset = usesOffset;
|
|
4934
|
+
refState.current.initialScroll = target;
|
|
4935
|
+
state.initialScroll = target;
|
|
4936
|
+
if ((options == null ? void 0 : options.resetDidFinish) && state.didFinishInitialScroll) {
|
|
4937
|
+
state.didFinishInitialScroll = false;
|
|
4938
|
+
}
|
|
4939
|
+
if (!(options == null ? void 0 : options.syncAnchor)) {
|
|
4940
|
+
return;
|
|
4941
|
+
}
|
|
4942
|
+
},
|
|
4943
|
+
[]
|
|
4944
|
+
);
|
|
4945
|
+
const shouldFinishInitialScrollAtOrigin = React3.useCallback(
|
|
4946
|
+
(initialScroll, offset) => {
|
|
4947
|
+
var _a4, _b2, _c2;
|
|
4948
|
+
if (offset !== 0 || initialScrollAtEnd) {
|
|
4949
|
+
return false;
|
|
4950
|
+
}
|
|
4951
|
+
if (state.initialScrollUsesOffset) {
|
|
4952
|
+
return Math.abs((_a4 = initialScroll.contentOffset) != null ? _a4 : 0) <= 1;
|
|
4953
|
+
}
|
|
4954
|
+
return initialScroll.index === 0 && ((_b2 = initialScroll.viewPosition) != null ? _b2 : 0) === 0 && Math.abs((_c2 = initialScroll.viewOffset) != null ? _c2 : 0) <= 1;
|
|
4955
|
+
},
|
|
4956
|
+
[initialScrollAtEnd]
|
|
4957
|
+
);
|
|
4958
|
+
const shouldFinishEmptyInitialScrollAtEnd = React3.useCallback(
|
|
4959
|
+
(initialScroll, offset) => {
|
|
4960
|
+
return dataProp.length === 0 && initialScrollAtEnd && offset === 0 && initialScroll.viewPosition === 1;
|
|
4961
|
+
},
|
|
4962
|
+
[dataProp.length, initialScrollAtEnd]
|
|
4963
|
+
);
|
|
4964
|
+
const shouldRearmFinishedEmptyInitialScrollAtEnd = React3.useCallback(
|
|
4965
|
+
(initialScroll) => {
|
|
4966
|
+
var _a4;
|
|
4967
|
+
return !!(state.didFinishInitialScroll && dataProp.length > 0 && initialScroll && !state.initialScrollUsesOffset && initialScroll.index === 0 && initialScroll.viewPosition === 1 && ((_a4 = initialScroll.contentOffset) != null ? _a4 : 0) === 0);
|
|
4968
|
+
},
|
|
4969
|
+
[dataProp.length]
|
|
4970
|
+
);
|
|
4589
4971
|
const initialContentOffset = React3.useMemo(() => {
|
|
4590
4972
|
let value;
|
|
4591
4973
|
const { initialScroll, initialAnchor } = refState.current;
|
|
4592
4974
|
if (initialScroll) {
|
|
4975
|
+
if (!state.initialScrollUsesOffset && false) ;
|
|
4593
4976
|
if (initialScroll.contentOffset !== void 0) {
|
|
4594
4977
|
value = initialScroll.contentOffset;
|
|
4595
4978
|
} else {
|
|
4596
4979
|
const clampedOffset = resolveInitialScrollOffset(initialScroll);
|
|
4597
4980
|
const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
|
|
4598
|
-
|
|
4599
|
-
|
|
4981
|
+
setActiveInitialScrollTarget(updatedInitialScroll, {
|
|
4982
|
+
usesOffset: state.initialScrollUsesOffset
|
|
4983
|
+
});
|
|
4600
4984
|
value = clampedOffset;
|
|
4601
4985
|
}
|
|
4602
4986
|
} else {
|
|
4603
4987
|
refState.current.initialAnchor = void 0;
|
|
4604
4988
|
value = 0;
|
|
4605
4989
|
}
|
|
4606
|
-
|
|
4607
|
-
|
|
4990
|
+
const hasPendingDataDependentInitialScroll = !!initialScroll && dataProp.length === 0 && !shouldFinishInitialScrollAtOrigin(initialScroll, value) && !shouldFinishEmptyInitialScrollAtEnd(initialScroll, value);
|
|
4991
|
+
if (!value && !hasPendingDataDependentInitialScroll) {
|
|
4992
|
+
if (initialScroll && shouldFinishInitialScrollAtOrigin(initialScroll, value)) {
|
|
4993
|
+
finishInitialScrollWithoutScroll();
|
|
4994
|
+
} else {
|
|
4995
|
+
setInitialRenderState(ctx, { didInitialScroll: true });
|
|
4996
|
+
}
|
|
4608
4997
|
}
|
|
4609
4998
|
return value;
|
|
4610
4999
|
}, []);
|
|
@@ -4621,24 +5010,131 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
4621
5010
|
set$(ctx, "totalSize", 0);
|
|
4622
5011
|
}
|
|
4623
5012
|
}
|
|
4624
|
-
const doInitialScroll = React3.useCallback(() => {
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
5013
|
+
const doInitialScroll = React3.useCallback((options) => {
|
|
5014
|
+
var _a4, _b2;
|
|
5015
|
+
const allowPostFinishRetry = !!(options == null ? void 0 : options.allowPostFinishRetry);
|
|
5016
|
+
const { didFinishInitialScroll, queuedInitialLayout, scrollingTo } = state;
|
|
5017
|
+
const initialScroll = (_a4 = state.initialScroll) != null ? _a4 : allowPostFinishRetry ? state.initialScrollLastTarget : void 0;
|
|
5018
|
+
const isInitialScrollInProgress = !!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll);
|
|
5019
|
+
const needsContainerLayoutForInitialScroll = !state.initialScrollUsesOffset;
|
|
5020
|
+
const shouldWaitForInitialLayout = waitForInitialLayout && needsContainerLayoutForInitialScroll && !queuedInitialLayout && !allowPostFinishRetry && !isInitialScrollInProgress;
|
|
5021
|
+
if (!initialScroll || shouldWaitForInitialLayout || didFinishInitialScroll && !allowPostFinishRetry || scrollingTo && !isInitialScrollInProgress) {
|
|
5022
|
+
return;
|
|
5023
|
+
}
|
|
5024
|
+
if (allowPostFinishRetry && state.initialScrollLastTargetUsesOffset) {
|
|
5025
|
+
return;
|
|
5026
|
+
}
|
|
5027
|
+
const didMoveAwayFromInitialTarget = allowPostFinishRetry && initialScroll.contentOffset !== void 0 && Math.abs(state.scroll - initialScroll.contentOffset) > 1;
|
|
5028
|
+
if (didMoveAwayFromInitialTarget) {
|
|
5029
|
+
state.initialScrollRetryWindowUntil = 0;
|
|
5030
|
+
return;
|
|
5031
|
+
}
|
|
5032
|
+
const offset = resolveInitialScrollOffset(initialScroll);
|
|
5033
|
+
const activeInitialTargetOffset = isInitialScrollInProgress ? (_b2 = scrollingTo.targetOffset) != null ? _b2 : scrollingTo.offset : void 0;
|
|
5034
|
+
const didOffsetChange = initialScroll.contentOffset === void 0 || Math.abs(initialScroll.contentOffset - offset) > 1;
|
|
5035
|
+
const didActiveInitialTargetChange = activeInitialTargetOffset !== void 0 && Math.abs(activeInitialTargetOffset - offset) > 1;
|
|
5036
|
+
if (!didOffsetChange && (allowPostFinishRetry || isInitialScrollInProgress && !didActiveInitialTargetChange)) {
|
|
5037
|
+
return;
|
|
5038
|
+
}
|
|
5039
|
+
if (didOffsetChange) {
|
|
4628
5040
|
const updatedInitialScroll = { ...initialScroll, contentOffset: offset };
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
});
|
|
5041
|
+
if (!state.initialScrollUsesOffset) {
|
|
5042
|
+
state.initialScrollLastTarget = updatedInitialScroll;
|
|
5043
|
+
state.initialScrollLastTargetUsesOffset = false;
|
|
5044
|
+
if (state.initialScroll) {
|
|
5045
|
+
refState.current.initialScroll = updatedInitialScroll;
|
|
5046
|
+
state.initialScroll = updatedInitialScroll;
|
|
5047
|
+
}
|
|
5048
|
+
}
|
|
4638
5049
|
}
|
|
5050
|
+
const hasMeasuredScrollLayout = !!state.lastLayout && state.scrollLength > 0;
|
|
5051
|
+
const shouldForceNativeInitialScroll = state.initialScrollUsesOffset && hasMeasuredScrollLayout || allowPostFinishRetry || !!queuedInitialLayout || isInitialScrollInProgress && didOffsetChange;
|
|
5052
|
+
performInitialScroll(ctx, {
|
|
5053
|
+
forceScroll: shouldForceNativeInitialScroll,
|
|
5054
|
+
initialScrollUsesOffset: state.initialScrollUsesOffset,
|
|
5055
|
+
resolvedOffset: offset,
|
|
5056
|
+
target: initialScroll
|
|
5057
|
+
});
|
|
4639
5058
|
}, []);
|
|
5059
|
+
React3.useLayoutEffect(() => {
|
|
5060
|
+
var _a4;
|
|
5061
|
+
const previousDataLength = state.initialScrollPreviousDataLength;
|
|
5062
|
+
state.initialScrollPreviousDataLength = dataProp.length;
|
|
5063
|
+
if (previousDataLength !== 0 || dataProp.length === 0 || !state.initialScroll || !state.queuedInitialLayout) {
|
|
5064
|
+
return;
|
|
5065
|
+
}
|
|
5066
|
+
if (initialScrollAtEnd) {
|
|
5067
|
+
const lastIndex = Math.max(0, dataProp.length - 1);
|
|
5068
|
+
const initialScroll = state.initialScroll;
|
|
5069
|
+
const shouldRearm = shouldRearmFinishedEmptyInitialScrollAtEnd(initialScroll);
|
|
5070
|
+
if (state.didFinishInitialScroll && !shouldRearm) {
|
|
5071
|
+
return;
|
|
5072
|
+
}
|
|
5073
|
+
if (initialScroll && !state.initialScrollUsesOffset && initialScroll.index === lastIndex && initialScroll.viewPosition === 1 && !shouldRearm) {
|
|
5074
|
+
return;
|
|
5075
|
+
}
|
|
5076
|
+
const updatedInitialScroll = {
|
|
5077
|
+
contentOffset: void 0,
|
|
5078
|
+
index: lastIndex,
|
|
5079
|
+
viewOffset: (_a4 = initialScroll == null ? void 0 : initialScroll.viewOffset) != null ? _a4 : -stylePaddingBottomState,
|
|
5080
|
+
viewPosition: 1
|
|
5081
|
+
};
|
|
5082
|
+
setActiveInitialScrollTarget(updatedInitialScroll, {
|
|
5083
|
+
resetDidFinish: shouldRearm,
|
|
5084
|
+
syncAnchor: true
|
|
5085
|
+
});
|
|
5086
|
+
doInitialScroll();
|
|
5087
|
+
return;
|
|
5088
|
+
}
|
|
5089
|
+
if (state.didFinishInitialScroll) {
|
|
5090
|
+
return;
|
|
5091
|
+
}
|
|
5092
|
+
doInitialScroll();
|
|
5093
|
+
}, [
|
|
5094
|
+
dataProp.length,
|
|
5095
|
+
doInitialScroll,
|
|
5096
|
+
initialScrollAtEnd,
|
|
5097
|
+
shouldRearmFinishedEmptyInitialScrollAtEnd,
|
|
5098
|
+
stylePaddingBottomState
|
|
5099
|
+
]);
|
|
5100
|
+
React3.useLayoutEffect(() => {
|
|
5101
|
+
var _a4;
|
|
5102
|
+
if (!initialScrollAtEnd) {
|
|
5103
|
+
return;
|
|
5104
|
+
}
|
|
5105
|
+
const lastIndex = Math.max(0, dataProp.length - 1);
|
|
5106
|
+
const initialScroll = state.initialScroll;
|
|
5107
|
+
const shouldRearm = shouldRearmFinishedEmptyInitialScrollAtEnd(initialScroll);
|
|
5108
|
+
if (state.didFinishInitialScroll && !shouldRearm) {
|
|
5109
|
+
return;
|
|
5110
|
+
}
|
|
5111
|
+
if (shouldRearm) {
|
|
5112
|
+
state.didFinishInitialScroll = false;
|
|
5113
|
+
}
|
|
5114
|
+
if (initialScroll && !state.initialScrollUsesOffset && initialScroll.index === lastIndex && initialScroll.viewPosition === 1 && !shouldRearm) {
|
|
5115
|
+
return;
|
|
5116
|
+
}
|
|
5117
|
+
const updatedInitialScroll = {
|
|
5118
|
+
contentOffset: void 0,
|
|
5119
|
+
index: lastIndex,
|
|
5120
|
+
viewOffset: (_a4 = initialScroll == null ? void 0 : initialScroll.viewOffset) != null ? _a4 : -stylePaddingBottomState,
|
|
5121
|
+
viewPosition: 1
|
|
5122
|
+
};
|
|
5123
|
+
setActiveInitialScrollTarget(updatedInitialScroll, {
|
|
5124
|
+
resetDidFinish: shouldRearm,
|
|
5125
|
+
syncAnchor: true
|
|
5126
|
+
});
|
|
5127
|
+
doInitialScroll();
|
|
5128
|
+
}, [
|
|
5129
|
+
dataProp.length,
|
|
5130
|
+
doInitialScroll,
|
|
5131
|
+
initialScrollAtEnd,
|
|
5132
|
+
shouldRearmFinishedEmptyInitialScrollAtEnd,
|
|
5133
|
+
stylePaddingBottomState
|
|
5134
|
+
]);
|
|
4640
5135
|
const onLayoutFooter = React3.useCallback(
|
|
4641
5136
|
(layout) => {
|
|
5137
|
+
var _a4;
|
|
4642
5138
|
if (!initialScrollAtEnd) {
|
|
4643
5139
|
return;
|
|
4644
5140
|
}
|
|
@@ -4653,16 +5149,48 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
4653
5149
|
const footerSize = layout[horizontal ? "width" : "height"];
|
|
4654
5150
|
const viewOffset = -stylePaddingBottomState - footerSize;
|
|
4655
5151
|
if (initialScroll.viewOffset !== viewOffset) {
|
|
5152
|
+
const previousTargetOffset = (_a4 = initialScroll.contentOffset) != null ? _a4 : resolveInitialScrollOffset(initialScroll);
|
|
5153
|
+
const didMoveAwayFromFinishedInitialTarget = state.didFinishInitialScroll && Math.abs(state.scroll - previousTargetOffset) > 1;
|
|
5154
|
+
if (didMoveAwayFromFinishedInitialTarget) {
|
|
5155
|
+
return;
|
|
5156
|
+
}
|
|
4656
5157
|
const updatedInitialScroll = { ...initialScroll, viewOffset };
|
|
4657
|
-
|
|
4658
|
-
|
|
5158
|
+
setActiveInitialScrollTarget(updatedInitialScroll, {
|
|
5159
|
+
resetDidFinish: true
|
|
5160
|
+
});
|
|
5161
|
+
doInitialScroll();
|
|
4659
5162
|
}
|
|
4660
5163
|
},
|
|
4661
|
-
[
|
|
5164
|
+
[
|
|
5165
|
+
dataProp.length,
|
|
5166
|
+
doInitialScroll,
|
|
5167
|
+
horizontal,
|
|
5168
|
+
initialScrollAtEnd,
|
|
5169
|
+
resolveInitialScrollOffset,
|
|
5170
|
+
stylePaddingBottomState
|
|
5171
|
+
]
|
|
4662
5172
|
);
|
|
4663
5173
|
const onLayoutChange = React3.useCallback((layout) => {
|
|
4664
|
-
|
|
5174
|
+
var _a4;
|
|
4665
5175
|
handleLayout(ctx, layout, setCanRender);
|
|
5176
|
+
const SCROLL_LENGTH_RETRY_WINDOW_MS = 600;
|
|
5177
|
+
const now = Date.now();
|
|
5178
|
+
const didFinishInitialScroll = !!state.didFinishInitialScroll;
|
|
5179
|
+
if (didFinishInitialScroll && !state.initialScrollLastDidFinish) {
|
|
5180
|
+
state.initialScrollRetryWindowUntil = now + SCROLL_LENGTH_RETRY_WINDOW_MS;
|
|
5181
|
+
}
|
|
5182
|
+
state.initialScrollLastDidFinish = didFinishInitialScroll;
|
|
5183
|
+
const previousScrollLength = state.initialScrollRetryLastLength;
|
|
5184
|
+
const currentScrollLength = state.scrollLength;
|
|
5185
|
+
const didScrollLengthChange = previousScrollLength === void 0 || Math.abs(currentScrollLength - previousScrollLength) > 1;
|
|
5186
|
+
if (didScrollLengthChange) {
|
|
5187
|
+
state.initialScrollRetryLastLength = currentScrollLength;
|
|
5188
|
+
}
|
|
5189
|
+
if (didFinishInitialScroll && didScrollLengthChange && now <= state.initialScrollRetryWindowUntil && !state.initialScrollLastTargetUsesOffset && ((_a4 = state.initialScrollLastTarget) == null ? void 0 : _a4.index) !== void 0) {
|
|
5190
|
+
doInitialScroll({ allowPostFinishRetry: true });
|
|
5191
|
+
return;
|
|
5192
|
+
}
|
|
5193
|
+
doInitialScroll();
|
|
4666
5194
|
}, []);
|
|
4667
5195
|
const { onLayout } = useOnLayoutSync({
|
|
4668
5196
|
onLayoutChange,
|
|
@@ -4774,7 +5302,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
4774
5302
|
onScroll: onScrollHandler,
|
|
4775
5303
|
recycleItems,
|
|
4776
5304
|
refreshControl: refreshControlElement ? stylePaddingTopState > 0 ? React3__namespace.cloneElement(refreshControlElement, {
|
|
4777
|
-
progressViewOffset: ((
|
|
5305
|
+
progressViewOffset: ((_g = refreshControlElement.props.progressViewOffset) != null ? _g : 0) + stylePaddingTopState
|
|
4778
5306
|
}) : refreshControlElement : onRefresh && /* @__PURE__ */ React3__namespace.createElement(
|
|
4779
5307
|
RefreshControl,
|
|
4780
5308
|
{
|
|
@@ -4785,7 +5313,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
4785
5313
|
),
|
|
4786
5314
|
refScrollView: combinedRef,
|
|
4787
5315
|
renderScrollComponent,
|
|
4788
|
-
scrollAdjustHandler: (
|
|
5316
|
+
scrollAdjustHandler: (_h = refState.current) == null ? void 0 : _h.scrollAdjustHandler,
|
|
4789
5317
|
scrollEventThrottle: 0,
|
|
4790
5318
|
snapToIndices,
|
|
4791
5319
|
stickyHeaderIndices,
|