@legendapp/list 3.4.0 → 3.5.0
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/CHANGELOG.md +6 -0
- package/README.md +33 -0
- package/package.json +1 -1
- package/react-native.js +102 -51
- package/react-native.mjs +102 -51
- package/react-native.web.d.ts +12 -2
- package/react-native.web.js +277 -178
- package/react-native.web.mjs +277 -178
- package/react.d.ts +12 -2
- package/react.js +277 -178
- package/react.mjs +277 -178
package/react-native.mjs
CHANGED
|
@@ -914,8 +914,14 @@ function scheduleFullDrawDistancePrewarm(ctx) {
|
|
|
914
914
|
return;
|
|
915
915
|
}
|
|
916
916
|
state.scheduledWork.frame(() => {
|
|
917
|
-
var _a3;
|
|
918
|
-
|
|
917
|
+
var _a3, _b, _c;
|
|
918
|
+
if (state.props.hasExternalScroll && !hasActiveInitialScroll(state) && !state.scrollingTo && !state.pendingNativeMVCPAdjust) {
|
|
919
|
+
const offset = (_b = (_a3 = state.refScroller.current) == null ? void 0 : _a3.getRawScrollOffset) == null ? void 0 : _b.call(_a3);
|
|
920
|
+
if (offset !== void 0) {
|
|
921
|
+
state.scroll = state.scrollPending = state.props.horizontal ? toLogicalHorizontalOffset(state, offset, state.totalSize) : offset;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
(_c = state.triggerCalculateItemsInView) == null ? void 0 : _c.call(state);
|
|
919
925
|
}, "fullDrawDistancePrewarm");
|
|
920
926
|
}
|
|
921
927
|
|
|
@@ -928,6 +934,9 @@ function resetInitialRenderState(ctx, {
|
|
|
928
934
|
if (resetLayout) {
|
|
929
935
|
state.didContainersLayout = false;
|
|
930
936
|
state.queuedInitialLayout = false;
|
|
937
|
+
state.scrollBufferDirection = void 0;
|
|
938
|
+
state.scrollHistory.length = 0;
|
|
939
|
+
state.scheduledWork.cancel("renderRangeProjection");
|
|
931
940
|
state.edgeReachedGate = void 0;
|
|
932
941
|
state.isStartReached = null;
|
|
933
942
|
state.isEndReached = null;
|
|
@@ -1156,6 +1165,7 @@ function setSize(ctx, itemKey, size, notifyTotalSize = true) {
|
|
|
1156
1165
|
const previousSize = sizes.get(itemKey);
|
|
1157
1166
|
const diff = previousSize !== void 0 ? size - previousSize : size;
|
|
1158
1167
|
if (diff !== 0) {
|
|
1168
|
+
state.positionsAreCurrent = false;
|
|
1159
1169
|
addTotalSize(ctx, itemKey, diff, notifyTotalSize);
|
|
1160
1170
|
}
|
|
1161
1171
|
sizes.set(itemKey, size);
|
|
@@ -1216,6 +1226,7 @@ function getKnownOrFixedSize(ctx, key, index, data, resolved) {
|
|
|
1216
1226
|
const fixedSize = (resolved == null ? void 0 : resolved.didResolveFixedItemSize) ? resolved.fixedItemSize : getFixedItemSize(data, index, itemType);
|
|
1217
1227
|
if (fixedSize !== void 0) {
|
|
1218
1228
|
size = fixedSize + ctx.scrollAxisGap;
|
|
1229
|
+
state.positionsAreCurrent = false;
|
|
1219
1230
|
state.sizesKnown.set(key, size);
|
|
1220
1231
|
}
|
|
1221
1232
|
}
|
|
@@ -1829,6 +1840,9 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
|
1829
1840
|
state.scrollTime = currentTime;
|
|
1830
1841
|
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
1831
1842
|
const isUserScrollEvent = !!(options == null ? void 0 : options.fromNativeScrollEvent) && scrollDelta > 0.1 && !adjustChanged && scrollingTo === void 0 && !state.pendingNativeMVCPAdjust;
|
|
1843
|
+
if (isUserScrollEvent) {
|
|
1844
|
+
state.scrollBufferDirection = newScroll > prevScroll ? 1 : -1;
|
|
1845
|
+
}
|
|
1832
1846
|
const didCancelMaintainScrollAtEnd = Platform.OS === "web" && isUserScrollEvent && newScroll < prevScroll && !!(state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd);
|
|
1833
1847
|
if (didCancelMaintainScrollAtEnd) {
|
|
1834
1848
|
finishMaintainScrollAtEnd(ctx);
|
|
@@ -1908,10 +1922,10 @@ function finishMaintainScrollAtEnd(ctx) {
|
|
|
1908
1922
|
}
|
|
1909
1923
|
}
|
|
1910
1924
|
function doMaintainScrollAtEnd(ctx, options) {
|
|
1911
|
-
var _a3, _b, _c, _d, _e, _f;
|
|
1925
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h;
|
|
1912
1926
|
const state = ctx.state;
|
|
1913
1927
|
let didMaintain = false;
|
|
1914
|
-
if (state.isDragging) {
|
|
1928
|
+
if (state.isDragging || ((_b = (_a3 = state.refScroller.current) == null ? void 0 : _a3.isScrollInRange) == null ? void 0 : _b.call(_a3)) === false) {
|
|
1915
1929
|
finishMaintainScrollAtEnd(ctx);
|
|
1916
1930
|
} else {
|
|
1917
1931
|
const {
|
|
@@ -1923,11 +1937,11 @@ function doMaintainScrollAtEnd(ctx, options) {
|
|
|
1923
1937
|
const immediate = (options == null ? void 0 : options.immediate) && Platform.OS === "web" && !(maintainScrollAtEnd == null ? void 0 : maintainScrollAtEnd.animated);
|
|
1924
1938
|
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1925
1939
|
const isReplayingPendingMaintain = !!state.pendingMaintainScrollAtEnd;
|
|
1926
|
-
const shouldMaintainScrollAtEnd = !!(!((
|
|
1940
|
+
const shouldMaintainScrollAtEnd = !!(!((_c = ctx.scrollRequestTracker) == null ? void 0 : _c.isWaitingToRun()) && (!state.scrollingTo || state.scrollingTo.isScrollToEnd) && (isWithinMaintainScrollAtEndThreshold || isReplayingPendingMaintain || ((_d = state.scrollingTo) == null ? void 0 : _d.isScrollToEnd)) && maintainScrollAtEnd && didFinishInitialScroll);
|
|
1927
1941
|
if (shouldMaintainScrollAtEnd && !state.scrollingTo) {
|
|
1928
1942
|
const scroller = state.refScroller.current;
|
|
1929
|
-
const nativeMax = (
|
|
1930
|
-
const observed = (
|
|
1943
|
+
const nativeMax = (_e = scroller == null ? void 0 : scroller.getMaxScrollOffset) == null ? void 0 : _e.call(scroller);
|
|
1944
|
+
const observed = (_f = scroller == null ? void 0 : scroller.getCurrentScrollOffset) == null ? void 0 : _f.call(scroller);
|
|
1931
1945
|
if (nativeMax !== void 0 && observed !== void 0 && nativeMax < state.scroll - 1 && Math.abs(observed - nativeMax) <= 1) {
|
|
1932
1946
|
state.pendingMaintainScrollAtEnd = true;
|
|
1933
1947
|
state.scrollPending = observed;
|
|
@@ -1939,13 +1953,13 @@ function doMaintainScrollAtEnd(ctx, options) {
|
|
|
1939
1953
|
} else if (pendingNativeMVCPAdjust) {
|
|
1940
1954
|
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
1941
1955
|
} else if (shouldMaintainScrollAtEnd && (state.scrollingTo || state.pendingScrollResolve)) {
|
|
1942
|
-
if (immediate && ((
|
|
1956
|
+
if (immediate && ((_g = state.scrollingTo) == null ? void 0 : _g.isScrollToEnd) && !state.scrollingTo.animated) {
|
|
1943
1957
|
state.pendingMaintainScrollAtEnd = false;
|
|
1944
1958
|
ctx.scrollToEnd({ animated: false });
|
|
1945
1959
|
didMaintain = true;
|
|
1946
1960
|
} else {
|
|
1947
1961
|
state.pendingMaintainScrollAtEnd = true;
|
|
1948
|
-
(
|
|
1962
|
+
(_h = state.maintainingScrollAtEnd) != null ? _h : state.maintainingScrollAtEnd = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
1949
1963
|
}
|
|
1950
1964
|
} else if (shouldMaintainScrollAtEnd && didContainersLayout) {
|
|
1951
1965
|
state.pendingMaintainScrollAtEnd = false;
|
|
@@ -1959,8 +1973,9 @@ function doMaintainScrollAtEnd(ctx, options) {
|
|
|
1959
1973
|
const scrollAtRequest = state.scroll;
|
|
1960
1974
|
state.maintainingScrollAtEnd = pendingState;
|
|
1961
1975
|
const run = () => {
|
|
1976
|
+
var _a4, _b2;
|
|
1962
1977
|
if (state.maintainingScrollAtEnd === pendingState) {
|
|
1963
|
-
if (state.isDragging) {
|
|
1978
|
+
if (state.isDragging || ((_b2 = (_a4 = state.refScroller.current) == null ? void 0 : _a4.isScrollInRange) == null ? void 0 : _b2.call(_a4)) === false) {
|
|
1964
1979
|
finishMaintainScrollAtEnd(ctx);
|
|
1965
1980
|
} else {
|
|
1966
1981
|
const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
@@ -3298,6 +3313,7 @@ function handleInitialScrollDataChange(ctx, options) {
|
|
|
3298
3313
|
|
|
3299
3314
|
// src/core/resetLayoutCachesForDataChange.ts
|
|
3300
3315
|
function resetLayoutCachesForDataChange(state) {
|
|
3316
|
+
state.positionsAreCurrent = false;
|
|
3301
3317
|
state.indexByKey.clear();
|
|
3302
3318
|
state.idCache.length = 0;
|
|
3303
3319
|
state.positions.length = 0;
|
|
@@ -3578,7 +3594,7 @@ function updateItemPositions(ctx, dataChanged, {
|
|
|
3578
3594
|
scrollBottomBuffered: -1,
|
|
3579
3595
|
startIndex: 0
|
|
3580
3596
|
}) {
|
|
3581
|
-
var _a3, _b, _c, _d, _e;
|
|
3597
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3582
3598
|
const state = ctx.state;
|
|
3583
3599
|
const hasPositionListeners = ctx.positionListeners.size > 0;
|
|
3584
3600
|
const {
|
|
@@ -3594,6 +3610,11 @@ function updateItemPositions(ctx, dataChanged, {
|
|
|
3594
3610
|
const dataLength = data.length;
|
|
3595
3611
|
const numColumns = (_a3 = peek$(ctx, "numColumns")) != null ? _a3 : 1;
|
|
3596
3612
|
const hasColumns = numColumns > 1;
|
|
3613
|
+
const canReuseEstimates = !doMVCP || !state.didContainersLayout && Object.keys(state.averageSizes).length === 0;
|
|
3614
|
+
if (state.positionsAreCurrent && !dataChanged && !forceFullUpdate && state.positionRecalculationStartIndex === void 0 && !scrollingTo && !hasColumns && !snapToIndices && positions.length === dataLength && canReuseEstimates) {
|
|
3615
|
+
return;
|
|
3616
|
+
}
|
|
3617
|
+
state.positionsAreCurrent = false;
|
|
3597
3618
|
const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
|
|
3598
3619
|
const extraData = peek$(ctx, "extraData");
|
|
3599
3620
|
const layoutConfig = overrideItemLayout ? { span: 1 } : void 0;
|
|
@@ -3708,6 +3729,10 @@ function updateItemPositions(ctx, dataChanged, {
|
|
|
3708
3729
|
}
|
|
3709
3730
|
if (!didBreakEarly) {
|
|
3710
3731
|
updateTotalSize(ctx);
|
|
3732
|
+
state.positionsAreCurrent = !hasColumns;
|
|
3733
|
+
if (startIndex <= ((_f = state.positionRecalculationStartIndex) != null ? _f : -1)) {
|
|
3734
|
+
state.positionRecalculationStartIndex = void 0;
|
|
3735
|
+
}
|
|
3711
3736
|
}
|
|
3712
3737
|
if (snapToIndices) {
|
|
3713
3738
|
updateSnapToOffsets(ctx);
|
|
@@ -4270,7 +4295,7 @@ function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentSt
|
|
|
4270
4295
|
}
|
|
4271
4296
|
function trackVisibleRange(range, i, top, size, scroll, scrollBottom) {
|
|
4272
4297
|
let didPassVisibleEnd = false;
|
|
4273
|
-
if (range.startNoBuffer === null && top + size > scroll) {
|
|
4298
|
+
if (range.startNoBuffer === null && top + size > scroll && top <= scrollBottom) {
|
|
4274
4299
|
range.startNoBuffer = i;
|
|
4275
4300
|
}
|
|
4276
4301
|
if (range.firstFullyOnScreenIndex === void 0 && top >= scroll - 10 && top <= scrollBottom) {
|
|
@@ -4336,7 +4361,7 @@ function findFirstVisibleIndexInCachedRange(ctx, scroll) {
|
|
|
4336
4361
|
return null;
|
|
4337
4362
|
}
|
|
4338
4363
|
function updateViewabilityForCachedRange(ctx, viewabilityConfigCallbackPairs, scrollLength, scroll, scrollBottom) {
|
|
4339
|
-
var _a3, _b;
|
|
4364
|
+
var _a3, _b, _c, _d;
|
|
4340
4365
|
const state = ctx.state;
|
|
4341
4366
|
const {
|
|
4342
4367
|
endBuffered,
|
|
@@ -4370,14 +4395,14 @@ function updateViewabilityForCachedRange(ctx, viewabilityConfigCallbackPairs, sc
|
|
|
4370
4395
|
startNoBuffer: visibleRange.startNoBuffer
|
|
4371
4396
|
});
|
|
4372
4397
|
maybeEmitFirstVisibleItemChanged(state, visibleRange.startNoBuffer);
|
|
4373
|
-
if (visibleRange.startNoBuffer !== null && visibleRange.endNoBuffer !== null) {
|
|
4398
|
+
if (state.props.hasExternalScroll || visibleRange.startNoBuffer !== null && visibleRange.endNoBuffer !== null) {
|
|
4374
4399
|
updateViewableItems(
|
|
4375
4400
|
state,
|
|
4376
4401
|
ctx,
|
|
4377
4402
|
viewabilityConfigCallbackPairs,
|
|
4378
4403
|
scrollLength,
|
|
4379
|
-
visibleRange.startNoBuffer,
|
|
4380
|
-
visibleRange.endNoBuffer,
|
|
4404
|
+
(_c = visibleRange.startNoBuffer) != null ? _c : 0,
|
|
4405
|
+
(_d = visibleRange.endNoBuffer) != null ? _d : -1,
|
|
4381
4406
|
startBuffered,
|
|
4382
4407
|
endBuffered
|
|
4383
4408
|
);
|
|
@@ -4386,7 +4411,7 @@ function updateViewabilityForCachedRange(ctx, viewabilityConfigCallbackPairs, sc
|
|
|
4386
4411
|
function calculateItemsInView(ctx, params = {}) {
|
|
4387
4412
|
const state = ctx.state;
|
|
4388
4413
|
batchedUpdates(() => {
|
|
4389
|
-
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
|
|
4414
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
|
|
4390
4415
|
const {
|
|
4391
4416
|
columns,
|
|
4392
4417
|
containerItemKeys,
|
|
@@ -4438,7 +4463,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4438
4463
|
scrollAdjustPending = (_a4 = peek$(ctx, "scrollAdjustPending")) != null ? _a4 : 0;
|
|
4439
4464
|
scrollAdjustPad = scrollAdjustPending - topPad;
|
|
4440
4465
|
scroll = Math.round(nextScrollState + scrollExtra + scrollAdjustPad);
|
|
4441
|
-
if (scroll + scrollLength > totalSize) {
|
|
4466
|
+
if (!state.props.hasExternalScroll && scroll + scrollLength > totalSize) {
|
|
4442
4467
|
scroll = Math.max(0, totalSize - scrollLength);
|
|
4443
4468
|
}
|
|
4444
4469
|
};
|
|
@@ -4465,7 +4490,11 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4465
4490
|
let stickyState = dataChanged ? void 0 : resolveStickyState();
|
|
4466
4491
|
let scrollBufferTop = drawDistance;
|
|
4467
4492
|
let scrollBufferBottom = drawDistance;
|
|
4468
|
-
if (speed
|
|
4493
|
+
if (speed !== 0) {
|
|
4494
|
+
state.scrollBufferDirection = speed > 0 ? 1 : -1;
|
|
4495
|
+
}
|
|
4496
|
+
const bufferForward = state.scrollBufferDirection === 1 || state.scrollBufferDirection === void 0 && scroll < Math.max(50, drawDistance);
|
|
4497
|
+
if (bufferForward) {
|
|
4469
4498
|
scrollBufferTop = drawDistance * 0.5;
|
|
4470
4499
|
scrollBufferBottom = drawDistance * 1.5;
|
|
4471
4500
|
} else {
|
|
@@ -4475,8 +4504,8 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4475
4504
|
const shouldProjectRenderRange = !dataChanged && !forceFullItemPositions && !suppressInitialScrollSideEffects && !hasActiveInitialScroll(state) && !state.scrollingTo && !state.pendingNativeMVCPAdjust && !!peek$(ctx, "readyToRender");
|
|
4476
4505
|
const projectedBufferAdjustment = shouldProjectRenderRange ? getProjectedBufferAdjustment(speed, Math.min(scrollBufferTop, scrollBufferBottom)) : 0;
|
|
4477
4506
|
const updateScrollRange = () => {
|
|
4478
|
-
const scrollStart = Math.max(0, scroll);
|
|
4479
|
-
const overscrollBeforeContent = Math.max(0, -nativeScrollState);
|
|
4507
|
+
const scrollStart = state.props.hasExternalScroll ? scroll : Math.max(0, scroll);
|
|
4508
|
+
const overscrollBeforeContent = state.props.hasExternalScroll ? 0 : Math.max(0, -nativeScrollState);
|
|
4480
4509
|
scrollBottom = Math.max(scrollStart, scroll + scrollLength + overscrollBeforeContent);
|
|
4481
4510
|
scrollTopBuffered = scrollStart - scrollBufferTop + projectedBufferAdjustment;
|
|
4482
4511
|
scrollBottomBuffered = scrollBottom + scrollBufferBottom + projectedBufferAdjustment;
|
|
@@ -4605,7 +4634,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4605
4634
|
nextTop = top;
|
|
4606
4635
|
}
|
|
4607
4636
|
}
|
|
4608
|
-
if (
|
|
4637
|
+
if (startBuffered !== null) {
|
|
4609
4638
|
if (top <= scrollBottomBuffered) {
|
|
4610
4639
|
endBuffered = i;
|
|
4611
4640
|
if (scrollBottomBuffered > totalSize) {
|
|
@@ -4616,6 +4645,8 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4616
4645
|
} else {
|
|
4617
4646
|
foundEnd = true;
|
|
4618
4647
|
}
|
|
4648
|
+
} else if (top > scrollBottomBuffered) {
|
|
4649
|
+
foundEnd = true;
|
|
4619
4650
|
}
|
|
4620
4651
|
}
|
|
4621
4652
|
}
|
|
@@ -4633,6 +4664,12 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4633
4664
|
bottom: nextBottom,
|
|
4634
4665
|
top: nextTop
|
|
4635
4666
|
};
|
|
4667
|
+
} else if (enableScrollForNextCalculateItemsInView && state.props.hasExternalScroll) {
|
|
4668
|
+
if (scrollBottomBuffered < 0) {
|
|
4669
|
+
state.scrollForNextCalculateItemsInView = { bottom: 0, top: null };
|
|
4670
|
+
} else if (scrollTopBuffered > totalSize) {
|
|
4671
|
+
state.scrollForNextCalculateItemsInView = { bottom: null, top: totalSize };
|
|
4672
|
+
}
|
|
4636
4673
|
}
|
|
4637
4674
|
let numContainers = prevNumContainers;
|
|
4638
4675
|
const pendingRemoval = [];
|
|
@@ -4656,7 +4693,9 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4656
4693
|
}
|
|
4657
4694
|
const hasScrollTargetPinnedRange = scrollTargetPinnedStart <= scrollTargetPinnedEnd;
|
|
4658
4695
|
const isPinnedRenderIndex = (index) => alwaysRenderIndicesSet.has(index) || hasScrollTargetPinnedRange && index >= scrollTargetPinnedStart && index <= scrollTargetPinnedEnd;
|
|
4659
|
-
if (startBuffered !== null && endBuffered !== null) {
|
|
4696
|
+
if (startBuffered !== null && endBuffered !== null || alwaysRenderIndicesArr.length || hasScrollTargetPinnedRange) {
|
|
4697
|
+
const allocationStart = startBuffered != null ? startBuffered : 0;
|
|
4698
|
+
const allocationEnd = endBuffered != null ? endBuffered : -1;
|
|
4660
4699
|
const needNewContainers = [];
|
|
4661
4700
|
const needNewContainersSet = /* @__PURE__ */ new Set();
|
|
4662
4701
|
const addPinnedIndex = (index) => {
|
|
@@ -4672,7 +4711,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4672
4711
|
}
|
|
4673
4712
|
}
|
|
4674
4713
|
};
|
|
4675
|
-
for (let i =
|
|
4714
|
+
for (let i = allocationStart; i <= allocationEnd; i++) {
|
|
4676
4715
|
const id = (_m = idCache[i]) != null ? _m : getId(state, i);
|
|
4677
4716
|
if (!containerItemKeys.has(id)) {
|
|
4678
4717
|
needNewContainersSet.add(i);
|
|
@@ -4694,8 +4733,8 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4694
4733
|
(_n = stickyState == null ? void 0 : stickyState.currentStickyIdx) != null ? _n : -1,
|
|
4695
4734
|
needNewContainers,
|
|
4696
4735
|
needNewContainersSet,
|
|
4697
|
-
|
|
4698
|
-
|
|
4736
|
+
allocationStart,
|
|
4737
|
+
allocationEnd
|
|
4699
4738
|
);
|
|
4700
4739
|
} else if (previousStickyIndex !== -1) {
|
|
4701
4740
|
set$(ctx, "activeStickyIndex", -1);
|
|
@@ -4704,8 +4743,8 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4704
4743
|
const availableContainerAllocations = findAvailableContainers(
|
|
4705
4744
|
ctx,
|
|
4706
4745
|
needNewContainers,
|
|
4707
|
-
|
|
4708
|
-
|
|
4746
|
+
allocationStart,
|
|
4747
|
+
allocationEnd,
|
|
4709
4748
|
pendingRemoval,
|
|
4710
4749
|
protectedContainerKeys,
|
|
4711
4750
|
// Initial end alignment has no scroll velocity yet. Keep its
|
|
@@ -4832,19 +4871,19 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4832
4871
|
handleInitialScrollLayoutReady(ctx);
|
|
4833
4872
|
}
|
|
4834
4873
|
}
|
|
4835
|
-
if (viewabilityConfigCallbackPairs && visibleRange.startNoBuffer !== null && visibleRange.endNoBuffer !== null) {
|
|
4874
|
+
if (viewabilityConfigCallbackPairs && (state.props.hasExternalScroll || visibleRange.startNoBuffer !== null && visibleRange.endNoBuffer !== null)) {
|
|
4836
4875
|
updateViewableItems(
|
|
4837
4876
|
ctx.state,
|
|
4838
4877
|
ctx,
|
|
4839
4878
|
viewabilityConfigCallbackPairs,
|
|
4840
4879
|
scrollLength,
|
|
4841
|
-
visibleRange.startNoBuffer,
|
|
4842
|
-
visibleRange.endNoBuffer,
|
|
4843
|
-
startBuffered != null ? startBuffered : visibleRange.startNoBuffer,
|
|
4844
|
-
endBuffered != null ? endBuffered : visibleRange.endNoBuffer
|
|
4880
|
+
(_u = visibleRange.startNoBuffer) != null ? _u : 0,
|
|
4881
|
+
(_v = visibleRange.endNoBuffer) != null ? _v : -1,
|
|
4882
|
+
(_w = startBuffered != null ? startBuffered : visibleRange.startNoBuffer) != null ? _w : 0,
|
|
4883
|
+
(_x = endBuffered != null ? endBuffered : visibleRange.endNoBuffer) != null ? _x : -1
|
|
4845
4884
|
);
|
|
4846
4885
|
}
|
|
4847
|
-
(
|
|
4886
|
+
(_y = stickyState == null ? void 0 : stickyState.finishCalculateItemsInView) == null ? void 0 : _y.call(stickyState);
|
|
4848
4887
|
});
|
|
4849
4888
|
}
|
|
4850
4889
|
|
|
@@ -5139,6 +5178,7 @@ function updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem, notif
|
|
|
5139
5178
|
return 0;
|
|
5140
5179
|
}
|
|
5141
5180
|
const size = Platform.OS === "web" ? Math.round(rawSize) : roundSize(rawSize);
|
|
5181
|
+
if (prevSizeKnown !== size) state.positionsAreCurrent = false;
|
|
5142
5182
|
sizesKnown.set(itemKey, size);
|
|
5143
5183
|
if (fixedItemSize === void 0 && size > 0) {
|
|
5144
5184
|
itemType != null ? itemType : itemType = getItemType ? (_b = getItemType(itemData, index)) != null ? _b : "" : "";
|
|
@@ -6239,6 +6279,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
6239
6279
|
stickyHeaderConfig,
|
|
6240
6280
|
stickyHeaderIndices,
|
|
6241
6281
|
useWindowScroll = false,
|
|
6282
|
+
scrollElement,
|
|
6242
6283
|
...rest
|
|
6243
6284
|
}) {
|
|
6244
6285
|
const ctx = useStateContext();
|
|
@@ -6304,7 +6345,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
6304
6345
|
SnapOrScroll,
|
|
6305
6346
|
{
|
|
6306
6347
|
...rest,
|
|
6307
|
-
...Platform.OS === "web" ? ScrollComponent === ListComponentScrollView ? { onInternalScrollEnd, useWindowScroll } : {} : { onScrollBeginDrag: onInternalScrollBeginDrag, onScrollEndDrag: onInternalScrollEndDrag },
|
|
6348
|
+
...Platform.OS === "web" ? ScrollComponent === ListComponentScrollView ? { onInternalScrollEnd, scrollElement, useWindowScroll } : {} : { onScrollBeginDrag: onInternalScrollBeginDrag, onScrollEndDrag: onInternalScrollEndDrag },
|
|
6308
6349
|
contentContainerStyle: [
|
|
6309
6350
|
horizontal ? { height: "100%" } : {},
|
|
6310
6351
|
contentContainerStyle,
|
|
@@ -6344,7 +6385,15 @@ var WEB_UNBOUNDED_HEIGHT_CONTAINER_RATIO = 0.9;
|
|
|
6344
6385
|
var WEB_UNBOUNDED_HEIGHT_VIEWPORT_RATIO = 0.9;
|
|
6345
6386
|
function useDevChecksImpl(props) {
|
|
6346
6387
|
const ctx = useStateContext();
|
|
6347
|
-
const {
|
|
6388
|
+
const {
|
|
6389
|
+
anchoredEndSpace,
|
|
6390
|
+
childrenMode,
|
|
6391
|
+
keyExtractor,
|
|
6392
|
+
numColumns,
|
|
6393
|
+
renderScrollComponent,
|
|
6394
|
+
scrollElement,
|
|
6395
|
+
useWindowScroll
|
|
6396
|
+
} = props;
|
|
6348
6397
|
const hasAnchoredEndSpace = !!anchoredEndSpace;
|
|
6349
6398
|
useEffect(() => {
|
|
6350
6399
|
if (hasAnchoredEndSpace && (numColumns != null ? numColumns : 1) > 1) {
|
|
@@ -6355,13 +6404,13 @@ function useDevChecksImpl(props) {
|
|
|
6355
6404
|
}
|
|
6356
6405
|
}, [hasAnchoredEndSpace, numColumns]);
|
|
6357
6406
|
useEffect(() => {
|
|
6358
|
-
if (useWindowScroll && renderScrollComponent) {
|
|
6407
|
+
if ((useWindowScroll || scrollElement !== void 0) && renderScrollComponent) {
|
|
6359
6408
|
warnDevOnce(
|
|
6360
6409
|
"useWindowScrollRenderScrollComponent",
|
|
6361
|
-
"useWindowScroll
|
|
6410
|
+
"useWindowScroll and scrollElement are not supported when renderScrollComponent is provided."
|
|
6362
6411
|
);
|
|
6363
6412
|
}
|
|
6364
|
-
}, [renderScrollComponent, useWindowScroll]);
|
|
6413
|
+
}, [renderScrollComponent, scrollElement, useWindowScroll]);
|
|
6365
6414
|
useEffect(() => {
|
|
6366
6415
|
if (!keyExtractor && !ctx.state.isFirst && ctx.state.didDataChange && !childrenMode) {
|
|
6367
6416
|
warnDevOnce(
|
|
@@ -6373,8 +6422,8 @@ function useDevChecksImpl(props) {
|
|
|
6373
6422
|
useEffect(() => {
|
|
6374
6423
|
const state = ctx.state;
|
|
6375
6424
|
const dataLength = state.props.data.length;
|
|
6376
|
-
const
|
|
6377
|
-
if (Platform.OS !== "web" ||
|
|
6425
|
+
const usesExternalScroll = state.props.hasExternalScroll;
|
|
6426
|
+
if (Platform.OS !== "web" || usesExternalScroll || dataLength < WEB_UNBOUNDED_HEIGHT_MIN_DATA_LENGTH) {
|
|
6378
6427
|
return;
|
|
6379
6428
|
}
|
|
6380
6429
|
const warnIfUnboundedOuterSize = () => {
|
|
@@ -6538,7 +6587,8 @@ function doInitialAllocateContainers(ctx) {
|
|
|
6538
6587
|
calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
|
|
6539
6588
|
});
|
|
6540
6589
|
} else {
|
|
6541
|
-
|
|
6590
|
+
const reuseInitialPositions = !state.didLoad && state.positionsAreCurrent && !state.didDataChange && !state.didColumnsChange;
|
|
6591
|
+
calculateItemsInView(ctx, { dataChanged: !reuseInitialPositions, doMVCP: true });
|
|
6542
6592
|
}
|
|
6543
6593
|
}
|
|
6544
6594
|
return true;
|
|
@@ -6577,10 +6627,8 @@ function handleLayout(ctx, layoutParam, setCanRender) {
|
|
|
6577
6627
|
updateContentMetricsState(ctx);
|
|
6578
6628
|
state.lastBatchingAction = Date.now();
|
|
6579
6629
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
}
|
|
6583
|
-
if (needsCalculate) {
|
|
6630
|
+
const didAllocate = scrollLength > 0 && doInitialAllocateContainers(ctx);
|
|
6631
|
+
if (needsCalculate && (!didAllocate || state.initialScroll)) {
|
|
6584
6632
|
calculateItemsInView(ctx, { doMVCP: true });
|
|
6585
6633
|
}
|
|
6586
6634
|
if (didChange || otherAxisSize !== prevOtherAxisSize) {
|
|
@@ -6662,7 +6710,7 @@ function onScroll(ctx, event) {
|
|
|
6662
6710
|
}
|
|
6663
6711
|
state.lastNativeScroll = newScroll;
|
|
6664
6712
|
state.lastNativeScrollTime = Date.now();
|
|
6665
|
-
if (state.scrollingTo && state.scrollingTo.offset >= newScroll) {
|
|
6713
|
+
if (!state.props.hasExternalScroll && state.scrollingTo && state.scrollingTo.offset >= newScroll) {
|
|
6666
6714
|
const maxOffset = clampScrollOffset(ctx, newScroll, state.scrollingTo);
|
|
6667
6715
|
if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
|
|
6668
6716
|
newScroll = maxOffset;
|
|
@@ -7445,6 +7493,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7445
7493
|
stickyHeaderIndices: stickyHeaderIndicesProp,
|
|
7446
7494
|
style: styleProp,
|
|
7447
7495
|
useWindowScroll = false,
|
|
7496
|
+
scrollElement,
|
|
7448
7497
|
viewabilityConfig,
|
|
7449
7498
|
viewabilityConfigCallbackPairs,
|
|
7450
7499
|
...rest
|
|
@@ -7539,7 +7588,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7539
7588
|
dataVersion,
|
|
7540
7589
|
keyExtractor
|
|
7541
7590
|
]);
|
|
7542
|
-
const
|
|
7591
|
+
const scrollElementResolved = Platform.OS === "web" && !renderScrollComponent ? scrollElement : void 0;
|
|
7592
|
+
const useWindowScrollResolved = Platform.OS === "web" && !!useWindowScroll && scrollElementResolved === void 0 && !renderScrollComponent;
|
|
7593
|
+
const hasExternalScroll = useWindowScrollResolved || scrollElementResolved !== void 0;
|
|
7543
7594
|
const refState = useRef(void 0);
|
|
7544
7595
|
const hasOverrideItemLayout = !!overrideItemLayout;
|
|
7545
7596
|
const prevHasOverrideItemLayout = useRef(hasOverrideItemLayout);
|
|
@@ -7677,6 +7728,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7677
7728
|
estimatedItemSize,
|
|
7678
7729
|
getFixedItemSize: useWrapIfItem(getFixedItemSize),
|
|
7679
7730
|
getItemType: useWrapIfItem(getItemType),
|
|
7731
|
+
hasExternalScroll,
|
|
7680
7732
|
hideItemsUntilMeasured: experimental_hideItemsUntilMeasured,
|
|
7681
7733
|
horizontal: !!horizontal,
|
|
7682
7734
|
itemsAreEqual,
|
|
@@ -7873,9 +7925,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7873
7925
|
const { onLayout } = useOnLayoutSync({
|
|
7874
7926
|
onLayoutChange,
|
|
7875
7927
|
onLayoutProp,
|
|
7876
|
-
ref: refScroller
|
|
7877
|
-
// the type of ScrollView doesn't include measure?
|
|
7878
|
-
});
|
|
7928
|
+
ref: refScroller});
|
|
7879
7929
|
useLayoutEffect(() => {
|
|
7880
7930
|
if (snapToIndices) {
|
|
7881
7931
|
updateSnapToOffsets(ctx);
|
|
@@ -8043,6 +8093,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
8043
8093
|
refScrollView: combinedRef,
|
|
8044
8094
|
renderScrollComponent,
|
|
8045
8095
|
scrollAdjustHandler: (_s = refState.current) == null ? void 0 : _s.scrollAdjustHandler,
|
|
8096
|
+
scrollElement: scrollElementResolved,
|
|
8046
8097
|
scrollEventThrottle: 0,
|
|
8047
8098
|
snapToIndices,
|
|
8048
8099
|
stickyHeaderIndices,
|
package/react-native.web.d.ts
CHANGED
|
@@ -6,11 +6,14 @@ type ScrollEventTarget = Window | HTMLElement;
|
|
|
6
6
|
interface ScrollViewMethods {
|
|
7
7
|
getBoundingClientRect(): DOMRect | null | undefined;
|
|
8
8
|
getCurrentScrollOffset(): number;
|
|
9
|
+
getRawScrollOffset(): number;
|
|
9
10
|
getMaxScrollOffset(): number;
|
|
10
|
-
getScrollableNode(): HTMLElement;
|
|
11
|
+
getScrollableNode(): HTMLElement | null;
|
|
11
12
|
getScrollEventTarget(): ScrollEventTarget | null;
|
|
12
13
|
getScrollResponder(): HTMLElement | null;
|
|
13
14
|
isWindowScroll?(): boolean;
|
|
15
|
+
getContentNode?(): HTMLElement | null;
|
|
16
|
+
isScrollInRange?(): boolean;
|
|
14
17
|
scrollBy(x: number, y: number): void;
|
|
15
18
|
scrollTo(options: {
|
|
16
19
|
x?: number;
|
|
@@ -836,6 +839,13 @@ type ScrollViewPropsWeb = Omit<LooseScrollViewProps, "style" | "contentContainer
|
|
|
836
839
|
onLayout?: (event: LooseLayoutChangeEvent) => void;
|
|
837
840
|
};
|
|
838
841
|
type LegendListPropsOverrides<ItemT, TItemType extends string | undefined> = Omit<LegendListPropsBase<ItemT, ScrollViewPropsWeb, TItemType>, "anchoredEndSpace" | "refScrollView" | "renderScrollComponent" | "ListHeaderComponentStyle" | "ListFooterComponentStyle" | "onRefresh" | "progressViewOffset" | "refreshing"> & {
|
|
842
|
+
/**
|
|
843
|
+
* Web only: use an ancestor element's scrollbar instead of creating a scrollable list.
|
|
844
|
+
* Pass a state-backed callback ref value so changes to the element are observed.
|
|
845
|
+
* null waits for the element to mount; undefined uses the list's own scrollbar.
|
|
846
|
+
* Takes precedence over useWindowScroll. Not supported with renderScrollComponent.
|
|
847
|
+
*/
|
|
848
|
+
scrollElement?: HTMLElement | null;
|
|
839
849
|
anchoredEndSpace?: AnchoredEndSpaceConfig;
|
|
840
850
|
refScrollView?: Ref<HTMLElement | ScrollViewMethods>;
|
|
841
851
|
ListHeaderComponentStyle?: CSSProperties | undefined;
|
|
@@ -845,7 +855,7 @@ type LegendListProps<ItemT = any, TItemType extends string | undefined = string
|
|
|
845
855
|
type LegendListRef = Omit<LegendListRef$1, "getAnimatableRef" | "getNativeScrollRef" | "getScrollableNode" | "getScrollResponder"> & {
|
|
846
856
|
getAnimatableRef(): HTMLElement | ScrollViewMethods;
|
|
847
857
|
getNativeScrollRef(): HTMLElement | ScrollViewMethods;
|
|
848
|
-
getScrollableNode(): HTMLElement;
|
|
858
|
+
getScrollableNode(): HTMLElement | null;
|
|
849
859
|
getScrollResponder(): HTMLElement | null;
|
|
850
860
|
};
|
|
851
861
|
type LegendListState = Omit<LegendListState$1, "elementAtIndex"> & {
|