@legendapp/list 3.3.0 → 3.3.2
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 +12 -0
- package/animated.d.ts +8 -1
- package/keyboard-legacy.d.ts +8 -1
- package/keyboard.d.ts +8 -1
- package/package.json +1 -1
- package/react-native.d.ts +8 -1
- package/react-native.js +330 -114
- package/react-native.mjs +330 -114
- package/react-native.web.d.ts +8 -1
- package/react-native.web.js +330 -114
- package/react-native.web.mjs +330 -114
- package/react.d.ts +8 -1
- package/react.js +330 -114
- package/react.mjs +330 -114
- package/reanimated.d.ts +8 -1
- package/section-list.d.ts +8 -1
package/react-native.js
CHANGED
|
@@ -138,6 +138,7 @@ var createAnimatedValue = (value) => new ReactNative.Animated.Value(value);
|
|
|
138
138
|
|
|
139
139
|
// src/state/state.tsx
|
|
140
140
|
var ContextState = React2__namespace.createContext(null);
|
|
141
|
+
var SIGNAL_NAMES_SEPARATOR = "\0";
|
|
141
142
|
var contextNum = 0;
|
|
142
143
|
function StateProvider({ children }) {
|
|
143
144
|
const [value] = React2__namespace.useState(() => ({
|
|
@@ -209,6 +210,12 @@ function createSelectorFunctionsArr(ctx, signalNames) {
|
|
|
209
210
|
}
|
|
210
211
|
};
|
|
211
212
|
}
|
|
213
|
+
function getSignalNamesKey(signalNames) {
|
|
214
|
+
return signalNames.length === 1 ? signalNames[0] : signalNames.join(SIGNAL_NAMES_SEPARATOR);
|
|
215
|
+
}
|
|
216
|
+
function getSignalNamesFromKey(signalNamesKey) {
|
|
217
|
+
return signalNamesKey.split(SIGNAL_NAMES_SEPARATOR);
|
|
218
|
+
}
|
|
212
219
|
function listen$(ctx, signalName, cb) {
|
|
213
220
|
const { listeners } = ctx;
|
|
214
221
|
let setListeners = listeners.get(signalName);
|
|
@@ -256,7 +263,11 @@ function notifyPosition$(ctx, key, value) {
|
|
|
256
263
|
}
|
|
257
264
|
function useArr$(signalNames) {
|
|
258
265
|
const ctx = React2__namespace.useContext(ContextState);
|
|
259
|
-
const
|
|
266
|
+
const signalNamesKey = getSignalNamesKey(signalNames);
|
|
267
|
+
const { subscribe, get } = React2__namespace.useMemo(
|
|
268
|
+
() => createSelectorFunctionsArr(ctx, getSignalNamesFromKey(signalNamesKey)),
|
|
269
|
+
[ctx, signalNamesKey]
|
|
270
|
+
);
|
|
260
271
|
const value = shim.useSyncExternalStore(subscribe, get, get);
|
|
261
272
|
return value;
|
|
262
273
|
}
|
|
@@ -608,9 +619,22 @@ function findContainerId(ctx, key) {
|
|
|
608
619
|
|
|
609
620
|
// src/state/ContextContainer.ts
|
|
610
621
|
var ContextContainer = React2.createContext(null);
|
|
622
|
+
var NO_CONTAINER_ID = -1;
|
|
611
623
|
function useContextContainer() {
|
|
612
624
|
return React2.useContext(ContextContainer);
|
|
613
625
|
}
|
|
626
|
+
function useContainerItemInfo(containerContext) {
|
|
627
|
+
var _a3;
|
|
628
|
+
const containerId = (_a3 = containerContext == null ? void 0 : containerContext.containerId) != null ? _a3 : NO_CONTAINER_ID;
|
|
629
|
+
const [itemInfo] = useArr$([`containerItemInfo${containerId}`]);
|
|
630
|
+
return containerContext ? itemInfo : void 0;
|
|
631
|
+
}
|
|
632
|
+
function useContainerItemKey(containerContext) {
|
|
633
|
+
var _a3;
|
|
634
|
+
const containerId = (_a3 = containerContext == null ? void 0 : containerContext.containerId) != null ? _a3 : NO_CONTAINER_ID;
|
|
635
|
+
const [itemKey] = useArr$([`containerItemKey${containerId}`]);
|
|
636
|
+
return containerContext ? itemKey : void 0;
|
|
637
|
+
}
|
|
614
638
|
function useAdaptiveRender() {
|
|
615
639
|
const [mode] = useArr$(["adaptiveRender"]);
|
|
616
640
|
return mode;
|
|
@@ -681,40 +705,35 @@ function useViewabilityAmount(callback) {
|
|
|
681
705
|
}
|
|
682
706
|
function useRecyclingEffect(effect) {
|
|
683
707
|
const containerContext = useContextContainer();
|
|
684
|
-
const
|
|
685
|
-
|
|
686
|
-
prevItem: void 0
|
|
687
|
-
});
|
|
708
|
+
const itemInfo = useContainerItemInfo(containerContext);
|
|
709
|
+
const prevInfo = React2.useRef(void 0);
|
|
688
710
|
React2.useEffect(() => {
|
|
689
|
-
if (!
|
|
711
|
+
if (!itemInfo) {
|
|
690
712
|
return;
|
|
691
713
|
}
|
|
692
|
-
const { index, value } = containerContext;
|
|
693
714
|
let ret;
|
|
694
|
-
if (
|
|
715
|
+
if (prevInfo.current) {
|
|
695
716
|
ret = effect({
|
|
696
|
-
index,
|
|
697
|
-
item: value,
|
|
698
|
-
prevIndex:
|
|
699
|
-
prevItem:
|
|
717
|
+
index: itemInfo.index,
|
|
718
|
+
item: itemInfo.value,
|
|
719
|
+
prevIndex: prevInfo.current.index,
|
|
720
|
+
prevItem: prevInfo.current.value
|
|
700
721
|
});
|
|
701
722
|
}
|
|
702
|
-
|
|
703
|
-
prevIndex: index,
|
|
704
|
-
prevItem: value
|
|
705
|
-
};
|
|
723
|
+
prevInfo.current = itemInfo;
|
|
706
724
|
return ret;
|
|
707
|
-
}, [effect,
|
|
725
|
+
}, [effect, itemInfo]);
|
|
708
726
|
}
|
|
709
727
|
function useRecyclingState(valueOrFun) {
|
|
710
|
-
var _a3
|
|
728
|
+
var _a3;
|
|
711
729
|
const containerContext = useContextContainer();
|
|
712
|
-
const
|
|
730
|
+
const itemInfo = useContainerItemInfo(containerContext);
|
|
731
|
+
const computeValue = (info) => {
|
|
713
732
|
if (isFunction(valueOrFun)) {
|
|
714
733
|
const initializer = valueOrFun;
|
|
715
|
-
return
|
|
716
|
-
index:
|
|
717
|
-
item:
|
|
734
|
+
return info ? initializer({
|
|
735
|
+
index: info.index,
|
|
736
|
+
item: info.value,
|
|
718
737
|
prevIndex: void 0,
|
|
719
738
|
prevItem: void 0
|
|
720
739
|
}) : initializer();
|
|
@@ -722,13 +741,12 @@ function useRecyclingState(valueOrFun) {
|
|
|
722
741
|
return valueOrFun;
|
|
723
742
|
};
|
|
724
743
|
const [stateValue, setStateValue] = React2.useState(() => {
|
|
725
|
-
return computeValue(
|
|
744
|
+
return computeValue(itemInfo);
|
|
726
745
|
});
|
|
727
|
-
const prevItemKeyRef = React2.useRef((_a3 =
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
setStateValue(computeValue(containerContext));
|
|
746
|
+
const prevItemKeyRef = React2.useRef((_a3 = itemInfo == null ? void 0 : itemInfo.itemKey) != null ? _a3 : null);
|
|
747
|
+
if (itemInfo && prevItemKeyRef.current !== itemInfo.itemKey) {
|
|
748
|
+
prevItemKeyRef.current = itemInfo.itemKey;
|
|
749
|
+
setStateValue(computeValue(itemInfo));
|
|
732
750
|
}
|
|
733
751
|
const triggerLayout = containerContext == null ? void 0 : containerContext.triggerLayout;
|
|
734
752
|
const setState = React2.useCallback(
|
|
@@ -747,12 +765,10 @@ function useRecyclingState(valueOrFun) {
|
|
|
747
765
|
}
|
|
748
766
|
function useIsLastItem() {
|
|
749
767
|
const containerContext = useContextContainer();
|
|
768
|
+
const itemKey = useContainerItemKey(containerContext);
|
|
750
769
|
const isLast = useSelector$("lastItemKeys", (lastItemKeys) => {
|
|
751
|
-
if (containerContext) {
|
|
752
|
-
|
|
753
|
-
if (!isNullOrUndefined(itemKey)) {
|
|
754
|
-
return (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false;
|
|
755
|
-
}
|
|
770
|
+
if (containerContext && !isNullOrUndefined(itemKey)) {
|
|
771
|
+
return (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false;
|
|
756
772
|
}
|
|
757
773
|
return false;
|
|
758
774
|
});
|
|
@@ -766,12 +782,7 @@ var noop = () => {
|
|
|
766
782
|
};
|
|
767
783
|
function useSyncLayout() {
|
|
768
784
|
const containerContext = useContextContainer();
|
|
769
|
-
|
|
770
|
-
const { triggerLayout: syncLayout } = containerContext;
|
|
771
|
-
return syncLayout;
|
|
772
|
-
} else {
|
|
773
|
-
return noop;
|
|
774
|
-
}
|
|
785
|
+
return IsNewArchitecture && containerContext ? containerContext.triggerLayout : noop;
|
|
775
786
|
}
|
|
776
787
|
|
|
777
788
|
// src/components/Separator.tsx
|
|
@@ -1534,6 +1545,7 @@ function finishScrollTo(ctx) {
|
|
|
1534
1545
|
const scrollingTo = state.scrollingTo;
|
|
1535
1546
|
state.scrollHistory.length = 0;
|
|
1536
1547
|
state.scrollingTo = void 0;
|
|
1548
|
+
state.scrollTargetPinnedRange = void 0;
|
|
1537
1549
|
if (state.pendingTotalSize !== void 0) {
|
|
1538
1550
|
addTotalSize(ctx, null, state.pendingTotalSize);
|
|
1539
1551
|
}
|
|
@@ -2173,6 +2185,8 @@ var flushSync = (fn) => {
|
|
|
2173
2185
|
};
|
|
2174
2186
|
|
|
2175
2187
|
// src/utils/getScrollVelocity.ts
|
|
2188
|
+
var MAX_SCROLL_VELOCITY_WINDOW_MS = 1e3;
|
|
2189
|
+
var SCROLL_VELOCITY_HALF_LIFE_MS = 200;
|
|
2176
2190
|
var getScrollVelocity = (state) => {
|
|
2177
2191
|
const { scrollHistory } = state;
|
|
2178
2192
|
const newestIndex = scrollHistory.length - 1;
|
|
@@ -2180,35 +2194,37 @@ var getScrollVelocity = (state) => {
|
|
|
2180
2194
|
return 0;
|
|
2181
2195
|
}
|
|
2182
2196
|
const newest = scrollHistory[newestIndex];
|
|
2183
|
-
|
|
2184
|
-
let direction = 0;
|
|
2185
|
-
for (let i = newestIndex; i > 0; i--) {
|
|
2186
|
-
const delta = scrollHistory[i].scroll - scrollHistory[i - 1].scroll;
|
|
2187
|
-
if (delta !== 0) {
|
|
2188
|
-
direction = Math.sign(delta);
|
|
2189
|
-
break;
|
|
2190
|
-
}
|
|
2191
|
-
}
|
|
2192
|
-
if (direction === 0) {
|
|
2197
|
+
if (Date.now() - newest.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
|
|
2193
2198
|
return 0;
|
|
2194
2199
|
}
|
|
2195
|
-
let
|
|
2196
|
-
|
|
2200
|
+
let direction = 0;
|
|
2201
|
+
let weightedVelocity = 0;
|
|
2202
|
+
let totalWeight = 0;
|
|
2203
|
+
for (let i = newestIndex; i > 0; i--) {
|
|
2197
2204
|
const current = scrollHistory[i];
|
|
2198
|
-
const
|
|
2199
|
-
const
|
|
2200
|
-
const
|
|
2201
|
-
|
|
2202
|
-
|
|
2205
|
+
const previous = scrollHistory[i - 1];
|
|
2206
|
+
const scrollDiff = current.scroll - previous.scroll;
|
|
2207
|
+
const timeDiff = current.time - previous.time;
|
|
2208
|
+
const deltaSign = Math.sign(scrollDiff);
|
|
2209
|
+
if (deltaSign !== 0) {
|
|
2210
|
+
if (direction === 0) {
|
|
2211
|
+
direction = deltaSign;
|
|
2212
|
+
} else if (deltaSign !== direction) {
|
|
2213
|
+
break;
|
|
2214
|
+
}
|
|
2203
2215
|
}
|
|
2204
|
-
if (
|
|
2216
|
+
if (newest.time - previous.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
|
|
2205
2217
|
break;
|
|
2206
2218
|
}
|
|
2207
|
-
|
|
2219
|
+
if (scrollDiff === 0 || timeDiff <= 0) {
|
|
2220
|
+
continue;
|
|
2221
|
+
}
|
|
2222
|
+
const age = newest.time - current.time;
|
|
2223
|
+
const weight = Math.exp(-age / SCROLL_VELOCITY_HALF_LIFE_MS);
|
|
2224
|
+
weightedVelocity += scrollDiff / timeDiff * weight;
|
|
2225
|
+
totalWeight += weight;
|
|
2208
2226
|
}
|
|
2209
|
-
|
|
2210
|
-
const timeDiff = newest.time - oldest.time;
|
|
2211
|
-
return timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
2227
|
+
return totalWeight > 0 ? weightedVelocity / totalWeight : 0;
|
|
2212
2228
|
};
|
|
2213
2229
|
|
|
2214
2230
|
// src/core/updateScroll.ts
|
|
@@ -2325,8 +2341,93 @@ function syncInitialScrollNativeWatchdog(state, options) {
|
|
|
2325
2341
|
initialScrollWatchdog.clear(state);
|
|
2326
2342
|
}
|
|
2327
2343
|
}
|
|
2328
|
-
function
|
|
2344
|
+
function findPositionIndexAtOrBeforeOffset(ctx, offset) {
|
|
2345
|
+
const state = ctx.state;
|
|
2346
|
+
const dataLength = state.props.data.length;
|
|
2347
|
+
let low = 0;
|
|
2348
|
+
let high = dataLength - 1;
|
|
2349
|
+
let match;
|
|
2350
|
+
while (low <= high) {
|
|
2351
|
+
const mid = Math.floor((low + high) / 2);
|
|
2352
|
+
const top = state.positions[mid];
|
|
2353
|
+
if (top === void 0) {
|
|
2354
|
+
high = mid - 1;
|
|
2355
|
+
} else {
|
|
2356
|
+
if (top <= offset) {
|
|
2357
|
+
match = mid;
|
|
2358
|
+
low = mid + 1;
|
|
2359
|
+
} else {
|
|
2360
|
+
high = mid - 1;
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
}
|
|
2364
|
+
return match;
|
|
2365
|
+
}
|
|
2366
|
+
function getItemBottom(ctx, index) {
|
|
2329
2367
|
var _a3;
|
|
2368
|
+
const top = ctx.state.positions[index];
|
|
2369
|
+
if (top === void 0) {
|
|
2370
|
+
return void 0;
|
|
2371
|
+
}
|
|
2372
|
+
const itemSize = (_a3 = getItemSizeAtIndex(ctx, index)) != null ? _a3 : 0;
|
|
2373
|
+
return top + (Number.isFinite(itemSize) ? itemSize : 0);
|
|
2374
|
+
}
|
|
2375
|
+
function getTargetViewportRenderRange(ctx, targetOffset, targetIndex) {
|
|
2376
|
+
const state = ctx.state;
|
|
2377
|
+
const dataLength = state.props.data.length;
|
|
2378
|
+
if (dataLength === 0) {
|
|
2379
|
+
return void 0;
|
|
2380
|
+
}
|
|
2381
|
+
const viewportStart = Math.max(0, targetOffset);
|
|
2382
|
+
const viewportEnd = Math.max(viewportStart, targetOffset + state.scrollLength);
|
|
2383
|
+
let start = targetIndex !== void 0 ? Math.max(0, Math.min(dataLength - 1, targetIndex)) : findPositionIndexAtOrBeforeOffset(ctx, viewportStart);
|
|
2384
|
+
if (start === void 0) {
|
|
2385
|
+
return void 0;
|
|
2386
|
+
}
|
|
2387
|
+
if (targetIndex !== void 0 && state.positions[start] === void 0) {
|
|
2388
|
+
return { end: start, start };
|
|
2389
|
+
}
|
|
2390
|
+
if (targetIndex === void 0) {
|
|
2391
|
+
const startBottom = getItemBottom(ctx, start);
|
|
2392
|
+
if (startBottom === void 0 || startBottom <= viewportStart) {
|
|
2393
|
+
return void 0;
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
while (start > 0) {
|
|
2397
|
+
const top = state.positions[start];
|
|
2398
|
+
if (top === void 0 || top <= viewportStart || state.positions[start - 1] === void 0) {
|
|
2399
|
+
break;
|
|
2400
|
+
}
|
|
2401
|
+
start--;
|
|
2402
|
+
}
|
|
2403
|
+
while (start > 0) {
|
|
2404
|
+
const previousBottom = getItemBottom(ctx, start - 1);
|
|
2405
|
+
if (previousBottom === void 0 || previousBottom <= viewportStart) {
|
|
2406
|
+
break;
|
|
2407
|
+
}
|
|
2408
|
+
start--;
|
|
2409
|
+
}
|
|
2410
|
+
let end = start;
|
|
2411
|
+
while (end + 1 < dataLength) {
|
|
2412
|
+
const nextTop = state.positions[end + 1];
|
|
2413
|
+
if (nextTop === void 0 || nextTop > viewportEnd) {
|
|
2414
|
+
break;
|
|
2415
|
+
}
|
|
2416
|
+
end++;
|
|
2417
|
+
}
|
|
2418
|
+
return { end, start };
|
|
2419
|
+
}
|
|
2420
|
+
function pinScrollTargetRenderRange(ctx, targetOffset, targetIndex) {
|
|
2421
|
+
const range = getTargetViewportRenderRange(ctx, targetOffset, targetIndex);
|
|
2422
|
+
if (range) {
|
|
2423
|
+
ctx.state.scrollTargetPinnedRange = range;
|
|
2424
|
+
ctx.state.scrollForNextCalculateItemsInView = void 0;
|
|
2425
|
+
} else {
|
|
2426
|
+
ctx.state.scrollTargetPinnedRange = void 0;
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2429
|
+
function scrollTo(ctx, params) {
|
|
2430
|
+
var _a3, _b;
|
|
2330
2431
|
const state = ctx.state;
|
|
2331
2432
|
const { noScrollingTo, forceScroll, ...scrollTarget } = params;
|
|
2332
2433
|
const {
|
|
@@ -2361,11 +2462,20 @@ function scrollTo(ctx, params) {
|
|
|
2361
2462
|
targetOffset,
|
|
2362
2463
|
waitForInitialScrollCompletionFrame
|
|
2363
2464
|
};
|
|
2465
|
+
if (!isInitialScroll) {
|
|
2466
|
+
pinScrollTargetRenderRange(ctx, targetOffset, scrollTarget.index);
|
|
2467
|
+
}
|
|
2364
2468
|
}
|
|
2365
2469
|
state.scrollPending = targetOffset;
|
|
2366
2470
|
syncInitialScrollNativeWatchdog(state, { isInitialScroll, requestedOffset: offset, targetOffset });
|
|
2367
|
-
if (!
|
|
2368
|
-
|
|
2471
|
+
if (!isInitialScroll && !noScrollingTo && Math.abs(state.scroll - targetOffset) > 1) {
|
|
2472
|
+
if (animated) {
|
|
2473
|
+
if (state.scrollTargetPinnedRange) {
|
|
2474
|
+
(_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state);
|
|
2475
|
+
}
|
|
2476
|
+
} else {
|
|
2477
|
+
updateScroll(ctx, targetOffset, true, { markHasScrolled: false });
|
|
2478
|
+
}
|
|
2369
2479
|
}
|
|
2370
2480
|
if (forceScroll || !isInitialScroll || Platform.OS === "android") {
|
|
2371
2481
|
doScrollTo(ctx, { animated, horizontal, isInitialScroll, offset });
|
|
@@ -3308,22 +3418,28 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
|
|
|
3308
3418
|
set$(ctx, `containerSpan${containerIndex}`, span);
|
|
3309
3419
|
}
|
|
3310
3420
|
}
|
|
3421
|
+
const prevItemInfo = peek$(ctx, `containerItemInfo${containerIndex}`);
|
|
3311
3422
|
const prevData = peek$(ctx, `containerItemData${containerIndex}`);
|
|
3423
|
+
let itemInfoValue = prevData;
|
|
3424
|
+
let didChangeItemInfo = (prevItemInfo == null ? void 0 : prevItemInfo.itemKey) !== itemKey || (prevItemInfo == null ? void 0 : prevItemInfo.index) !== itemIndex || (prevItemInfo == null ? void 0 : prevItemInfo.value) !== prevData;
|
|
3425
|
+
const updateData = () => {
|
|
3426
|
+
set$(ctx, `containerItemData${containerIndex}`, item);
|
|
3427
|
+
itemInfoValue = item;
|
|
3428
|
+
didChangeItemInfo = true;
|
|
3429
|
+
didRefreshData = true;
|
|
3430
|
+
};
|
|
3312
3431
|
if (prevData !== item) {
|
|
3313
3432
|
const pendingDataComparison = ((_e = state.pendingDataComparison) == null ? void 0 : _e.previousData) === state.previousData && ((_f = state.pendingDataComparison) == null ? void 0 : _f.nextData) === data ? state.pendingDataComparison : void 0;
|
|
3314
3433
|
const cachedComparison = (_g = pendingDataComparison == null ? void 0 : pendingDataComparison.byIndex[itemIndex]) != null ? _g : 0;
|
|
3315
3434
|
if (cachedComparison === 2) {
|
|
3316
|
-
|
|
3317
|
-
didRefreshData = true;
|
|
3435
|
+
updateData();
|
|
3318
3436
|
} else if (cachedComparison !== 1) {
|
|
3319
3437
|
const nextItemKey = (_h = peek$(ctx, `containerItemKey${containerIndex}`)) != null ? _h : itemKey;
|
|
3320
3438
|
const prevKey = keyExtractor == null ? void 0 : keyExtractor(prevData, itemIndex);
|
|
3321
3439
|
if (prevData === void 0 || !keyExtractor || prevKey !== nextItemKey) {
|
|
3322
|
-
|
|
3323
|
-
didRefreshData = true;
|
|
3440
|
+
updateData();
|
|
3324
3441
|
} else if (!itemsAreEqual) {
|
|
3325
|
-
|
|
3326
|
-
didRefreshData = true;
|
|
3442
|
+
updateData();
|
|
3327
3443
|
} else {
|
|
3328
3444
|
const isEqual = itemsAreEqual(prevData, item, itemIndex, data);
|
|
3329
3445
|
if (!state.pendingDataComparison || state.pendingDataComparison.previousData !== state.previousData || state.pendingDataComparison.nextData !== data) {
|
|
@@ -3339,12 +3455,18 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
|
|
|
3339
3455
|
state.pendingDataComparison.byIndex[itemIndex] = isEqual ? 1 : 2;
|
|
3340
3456
|
}
|
|
3341
3457
|
if (!isEqual) {
|
|
3342
|
-
|
|
3343
|
-
didRefreshData = true;
|
|
3458
|
+
updateData();
|
|
3344
3459
|
}
|
|
3345
3460
|
}
|
|
3346
3461
|
}
|
|
3347
3462
|
}
|
|
3463
|
+
if (didChangeItemInfo) {
|
|
3464
|
+
set$(ctx, `containerItemInfo${containerIndex}`, {
|
|
3465
|
+
index: itemIndex,
|
|
3466
|
+
itemKey,
|
|
3467
|
+
value: itemInfoValue
|
|
3468
|
+
});
|
|
3469
|
+
}
|
|
3348
3470
|
return { didChangePosition, didRefreshData };
|
|
3349
3471
|
}
|
|
3350
3472
|
|
|
@@ -4037,6 +4159,32 @@ function setDidLayout(ctx) {
|
|
|
4037
4159
|
}
|
|
4038
4160
|
|
|
4039
4161
|
// src/core/calculateItemsInView.ts
|
|
4162
|
+
var RENDER_RANGE_PROJECTION_FULL_VELOCITY = 4;
|
|
4163
|
+
var RENDER_RANGE_PROJECTION_SETTLE_DELAY = 100;
|
|
4164
|
+
function getProjectedBufferAdjustment(scrollVelocity, trailingBuffer) {
|
|
4165
|
+
if (trailingBuffer <= 0) {
|
|
4166
|
+
return 0;
|
|
4167
|
+
}
|
|
4168
|
+
const velocityProgress = Math.min(1, Math.abs(scrollVelocity) / RENDER_RANGE_PROJECTION_FULL_VELOCITY);
|
|
4169
|
+
return Math.sign(scrollVelocity) * trailingBuffer * velocityProgress;
|
|
4170
|
+
}
|
|
4171
|
+
function scheduleRenderRangeProjectionSettle(ctx) {
|
|
4172
|
+
const state = ctx.state;
|
|
4173
|
+
const previousTimeout = state.timeoutRenderRangeProjectionSettle;
|
|
4174
|
+
if (previousTimeout !== void 0) {
|
|
4175
|
+
clearTimeout(previousTimeout);
|
|
4176
|
+
state.timeouts.delete(previousTimeout);
|
|
4177
|
+
}
|
|
4178
|
+
const timeout = setTimeout(() => {
|
|
4179
|
+
var _a3;
|
|
4180
|
+
state.timeoutRenderRangeProjectionSettle = void 0;
|
|
4181
|
+
state.timeouts.delete(timeout);
|
|
4182
|
+
state.scrollHistory.length = 0;
|
|
4183
|
+
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state);
|
|
4184
|
+
}, RENDER_RANGE_PROJECTION_SETTLE_DELAY);
|
|
4185
|
+
state.timeoutRenderRangeProjectionSettle = timeout;
|
|
4186
|
+
state.timeouts.add(timeout);
|
|
4187
|
+
}
|
|
4040
4188
|
function findCurrentStickyIndex(stickyArray, scroll, state) {
|
|
4041
4189
|
const positions = state.positions;
|
|
4042
4190
|
for (let i = stickyArray.length - 1; i >= 0; i--) {
|
|
@@ -4077,14 +4225,14 @@ function handleStickyActivation(ctx, stickyArray, currentStickyIdx, needNewConta
|
|
|
4077
4225
|
}
|
|
4078
4226
|
}
|
|
4079
4227
|
}
|
|
4080
|
-
function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentStickyIdx, pendingRemoval,
|
|
4228
|
+
function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentStickyIdx, pendingRemoval, isPinnedRenderIndex) {
|
|
4081
4229
|
var _a3, _b;
|
|
4082
4230
|
const state = ctx.state;
|
|
4083
4231
|
for (const containerIndex of state.stickyContainerPool) {
|
|
4084
4232
|
const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
4085
4233
|
const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
|
|
4086
4234
|
if (itemIndex === void 0) continue;
|
|
4087
|
-
if (
|
|
4235
|
+
if (isPinnedRenderIndex(itemIndex)) continue;
|
|
4088
4236
|
const arrayIdx = stickyArray.indexOf(itemIndex);
|
|
4089
4237
|
if (arrayIdx === -1) {
|
|
4090
4238
|
state.stickyContainerPool.delete(containerIndex);
|
|
@@ -4248,8 +4396,6 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4248
4396
|
const { data } = state.props;
|
|
4249
4397
|
const stickyHeaderIndicesArr = state.props.stickyHeaderIndicesArr || [];
|
|
4250
4398
|
const stickyHeaderIndicesSet = state.props.stickyHeaderIndicesSet || /* @__PURE__ */ new Set();
|
|
4251
|
-
const alwaysRenderArr = alwaysRenderIndicesArr || [];
|
|
4252
|
-
const alwaysRenderSet = alwaysRenderIndicesSet || /* @__PURE__ */ new Set();
|
|
4253
4399
|
const drawDistance = getEffectiveDrawDistance(ctx, params.drawDistanceMode);
|
|
4254
4400
|
const { dataChanged, doMVCP, forceFullItemPositions } = params;
|
|
4255
4401
|
const bootstrapInitialScrollState = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
|
|
@@ -4316,14 +4462,19 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4316
4462
|
scrollBufferTop = drawDistance * 1.5;
|
|
4317
4463
|
scrollBufferBottom = drawDistance * 0.5;
|
|
4318
4464
|
}
|
|
4465
|
+
const shouldProjectRenderRange = !dataChanged && !forceFullItemPositions && !suppressInitialScrollSideEffects && !hasActiveInitialScroll(state) && !state.scrollingTo && !state.pendingNativeMVCPAdjust && !!peek$(ctx, "readyToRender");
|
|
4466
|
+
const projectedBufferAdjustment = shouldProjectRenderRange ? getProjectedBufferAdjustment(speed, Math.min(scrollBufferTop, scrollBufferBottom)) : 0;
|
|
4319
4467
|
const updateScrollRange = () => {
|
|
4320
4468
|
const scrollStart = Math.max(0, scroll);
|
|
4321
4469
|
const overscrollBeforeContent = Math.max(0, -nativeScrollState);
|
|
4322
|
-
scrollTopBuffered = scrollStart - scrollBufferTop;
|
|
4323
4470
|
scrollBottom = Math.max(scrollStart, scroll + scrollLength + overscrollBeforeContent);
|
|
4324
|
-
|
|
4471
|
+
scrollTopBuffered = scrollStart - scrollBufferTop + projectedBufferAdjustment;
|
|
4472
|
+
scrollBottomBuffered = scrollBottom + scrollBufferBottom + projectedBufferAdjustment;
|
|
4325
4473
|
};
|
|
4326
4474
|
updateScrollRange();
|
|
4475
|
+
if (projectedBufferAdjustment !== 0) {
|
|
4476
|
+
scheduleRenderRangeProjectionSettle(ctx);
|
|
4477
|
+
}
|
|
4327
4478
|
if (enableScrollForNextCalculateItemsInView && !suppressInitialScrollSideEffects && !dataChanged && !forceFullItemPositions && scrollForNextCalculateItemsInView) {
|
|
4328
4479
|
const { top, bottom } = scrollForNextCalculateItemsInView;
|
|
4329
4480
|
if (top === null && bottom === null) {
|
|
@@ -4481,9 +4632,34 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4481
4632
|
}
|
|
4482
4633
|
}
|
|
4483
4634
|
}
|
|
4635
|
+
const scrollTargetPinnedRange = state.scrollTargetPinnedRange;
|
|
4636
|
+
let scrollTargetPinnedStart = 0;
|
|
4637
|
+
let scrollTargetPinnedEnd = -1;
|
|
4638
|
+
if (scrollTargetPinnedRange) {
|
|
4639
|
+
scrollTargetPinnedStart = Math.max(0, Math.min(scrollTargetPinnedRange.start, scrollTargetPinnedRange.end));
|
|
4640
|
+
scrollTargetPinnedEnd = Math.min(
|
|
4641
|
+
dataLength - 1,
|
|
4642
|
+
Math.max(scrollTargetPinnedRange.start, scrollTargetPinnedRange.end)
|
|
4643
|
+
);
|
|
4644
|
+
}
|
|
4645
|
+
const hasScrollTargetPinnedRange = scrollTargetPinnedStart <= scrollTargetPinnedEnd;
|
|
4646
|
+
const isPinnedRenderIndex = (index) => alwaysRenderIndicesSet.has(index) || hasScrollTargetPinnedRange && index >= scrollTargetPinnedStart && index <= scrollTargetPinnedEnd;
|
|
4484
4647
|
if (startBuffered !== null && endBuffered !== null) {
|
|
4485
4648
|
const needNewContainers = [];
|
|
4486
4649
|
const needNewContainersSet = /* @__PURE__ */ new Set();
|
|
4650
|
+
const addPinnedIndex = (index) => {
|
|
4651
|
+
var _a4;
|
|
4652
|
+
if (index >= 0 && index < dataLength) {
|
|
4653
|
+
const id = (_a4 = idCache[index]) != null ? _a4 : getId(state, index);
|
|
4654
|
+
const containerIndex = containerItemKeys.get(id);
|
|
4655
|
+
if (containerIndex !== void 0) {
|
|
4656
|
+
state.stickyContainerPool.add(containerIndex);
|
|
4657
|
+
} else if (!isNullOrUndefined(id) && !needNewContainersSet.has(index)) {
|
|
4658
|
+
needNewContainersSet.add(index);
|
|
4659
|
+
needNewContainers.push(index);
|
|
4660
|
+
}
|
|
4661
|
+
}
|
|
4662
|
+
};
|
|
4487
4663
|
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
4488
4664
|
const id = (_m = idCache[i]) != null ? _m : getId(state, i);
|
|
4489
4665
|
if (!containerItemKeys.has(id)) {
|
|
@@ -4491,21 +4667,19 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4491
4667
|
needNewContainers.push(i);
|
|
4492
4668
|
}
|
|
4493
4669
|
}
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
needNewContainers.push(index);
|
|
4501
|
-
}
|
|
4670
|
+
for (const index of alwaysRenderIndicesArr) {
|
|
4671
|
+
addPinnedIndex(index);
|
|
4672
|
+
}
|
|
4673
|
+
if (hasScrollTargetPinnedRange) {
|
|
4674
|
+
for (let index = scrollTargetPinnedStart; index <= scrollTargetPinnedEnd; index++) {
|
|
4675
|
+
addPinnedIndex(index);
|
|
4502
4676
|
}
|
|
4503
4677
|
}
|
|
4504
4678
|
if (stickyHeaderIndicesArr.length > 0) {
|
|
4505
4679
|
handleStickyActivation(
|
|
4506
4680
|
ctx,
|
|
4507
4681
|
stickyHeaderIndicesArr,
|
|
4508
|
-
(
|
|
4682
|
+
(_n = stickyState == null ? void 0 : stickyState.currentStickyIdx) != null ? _n : -1,
|
|
4509
4683
|
needNewContainers,
|
|
4510
4684
|
needNewContainersSet,
|
|
4511
4685
|
startBuffered,
|
|
@@ -4531,21 +4705,30 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4531
4705
|
for (const allocation of availableContainerAllocations) {
|
|
4532
4706
|
const i = allocation.itemIndex;
|
|
4533
4707
|
const containerIndex = allocation.containerIndex;
|
|
4534
|
-
const id = (
|
|
4708
|
+
const id = (_o = idCache[i]) != null ? _o : getId(state, i);
|
|
4535
4709
|
const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
4536
4710
|
if (oldKey && oldKey !== id) {
|
|
4537
4711
|
containerItemKeys.delete(oldKey);
|
|
4538
4712
|
}
|
|
4539
4713
|
set$(ctx, `containerItemKey${containerIndex}`, id);
|
|
4540
4714
|
set$(ctx, `containerItemData${containerIndex}`, data[i]);
|
|
4715
|
+
set$(ctx, `containerItemInfo${containerIndex}`, {
|
|
4716
|
+
index: i,
|
|
4717
|
+
itemKey: id,
|
|
4718
|
+
value: data[i]
|
|
4719
|
+
});
|
|
4541
4720
|
if (allocation.itemType !== void 0) {
|
|
4542
4721
|
state.containerItemTypes.set(containerIndex, allocation.itemType);
|
|
4543
4722
|
}
|
|
4544
4723
|
containerItemKeys.set(id, containerIndex);
|
|
4545
|
-
(
|
|
4724
|
+
(_p = state.userScrollAnchorReset) == null ? void 0 : _p.keys.add(id);
|
|
4725
|
+
if (IsNewArchitecture) {
|
|
4726
|
+
(_q = state.pendingLayoutEffectMeasurements) != null ? _q : state.pendingLayoutEffectMeasurements = /* @__PURE__ */ new Set();
|
|
4727
|
+
state.pendingLayoutEffectMeasurements.add(id);
|
|
4728
|
+
}
|
|
4546
4729
|
const containerSticky = `containerSticky${containerIndex}`;
|
|
4547
4730
|
const isSticky = stickyHeaderIndicesSet.has(i);
|
|
4548
|
-
const
|
|
4731
|
+
const isPinnedRender = isPinnedRenderIndex(i);
|
|
4549
4732
|
if (isSticky) {
|
|
4550
4733
|
set$(ctx, containerSticky, true);
|
|
4551
4734
|
state.stickyContainerPool.add(containerIndex);
|
|
@@ -4553,9 +4736,9 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4553
4736
|
if (peek$(ctx, containerSticky)) {
|
|
4554
4737
|
set$(ctx, containerSticky, false);
|
|
4555
4738
|
}
|
|
4556
|
-
if (
|
|
4739
|
+
if (isPinnedRender) {
|
|
4557
4740
|
state.stickyContainerPool.add(containerIndex);
|
|
4558
|
-
} else
|
|
4741
|
+
} else {
|
|
4559
4742
|
state.stickyContainerPool.delete(containerIndex);
|
|
4560
4743
|
}
|
|
4561
4744
|
}
|
|
@@ -4570,20 +4753,8 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4570
4753
|
}
|
|
4571
4754
|
}
|
|
4572
4755
|
}
|
|
4573
|
-
if (state.userScrollAnchorReset) {
|
|
4574
|
-
|
|
4575
|
-
state.userScrollAnchorReset = void 0;
|
|
4576
|
-
}
|
|
4577
|
-
}
|
|
4578
|
-
if (alwaysRenderArr.length > 0) {
|
|
4579
|
-
for (const index of alwaysRenderArr) {
|
|
4580
|
-
if (index < 0 || index >= dataLength) continue;
|
|
4581
|
-
const id = (_r = idCache[index]) != null ? _r : getId(state, index);
|
|
4582
|
-
const containerIndex = containerItemKeys.get(id);
|
|
4583
|
-
if (containerIndex !== void 0) {
|
|
4584
|
-
state.stickyContainerPool.add(containerIndex);
|
|
4585
|
-
}
|
|
4586
|
-
}
|
|
4756
|
+
if (((_r = state.userScrollAnchorReset) == null ? void 0 : _r.keys.size) === 0) {
|
|
4757
|
+
state.userScrollAnchorReset = void 0;
|
|
4587
4758
|
}
|
|
4588
4759
|
}
|
|
4589
4760
|
if (state.stickyContainerPool.size > 0) {
|
|
@@ -4594,7 +4765,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4594
4765
|
drawDistance,
|
|
4595
4766
|
(_s = stickyState == null ? void 0 : stickyState.currentStickyIdx) != null ? _s : -1,
|
|
4596
4767
|
pendingRemoval,
|
|
4597
|
-
|
|
4768
|
+
isPinnedRenderIndex
|
|
4598
4769
|
);
|
|
4599
4770
|
}
|
|
4600
4771
|
const pendingRemovalSet = pendingRemoval.length > 0 ? new Set(pendingRemoval) : void 0;
|
|
@@ -4612,6 +4783,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4612
4783
|
}
|
|
4613
4784
|
set$(ctx, `containerItemKey${i}`, void 0);
|
|
4614
4785
|
set$(ctx, `containerItemData${i}`, void 0);
|
|
4786
|
+
set$(ctx, `containerItemInfo${i}`, void 0);
|
|
4615
4787
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
4616
4788
|
set$(ctx, `containerColumn${i}`, -1);
|
|
4617
4789
|
set$(ctx, `containerSpan${i}`, 1);
|
|
@@ -4766,6 +4938,36 @@ function mergeItemSizeUpdateResult(result, next) {
|
|
|
4766
4938
|
result.needsRecalculate || (result.needsRecalculate = next.needsRecalculate);
|
|
4767
4939
|
result.shouldMaintainScrollAtEnd || (result.shouldMaintainScrollAtEnd = next.shouldMaintainScrollAtEnd);
|
|
4768
4940
|
}
|
|
4941
|
+
var batchedItemSizeRecalculates = /* @__PURE__ */ new WeakMap();
|
|
4942
|
+
function flushBatchedItemSizeRecalculate(ctx, didFallback = false, expectedResult) {
|
|
4943
|
+
const result = batchedItemSizeRecalculates.get(ctx);
|
|
4944
|
+
if (!result || expectedResult && result !== expectedResult) {
|
|
4945
|
+
return;
|
|
4946
|
+
}
|
|
4947
|
+
batchedItemSizeRecalculates.delete(ctx);
|
|
4948
|
+
if (didFallback) {
|
|
4949
|
+
ctx.state.pendingLayoutEffectMeasurements = void 0;
|
|
4950
|
+
}
|
|
4951
|
+
flushItemSizeUpdates(ctx, result);
|
|
4952
|
+
}
|
|
4953
|
+
function queueItemSizeRecalculate(ctx, result) {
|
|
4954
|
+
var _a3, _b;
|
|
4955
|
+
const batch = batchedItemSizeRecalculates.get(ctx);
|
|
4956
|
+
if (batch) {
|
|
4957
|
+
mergeItemSizeUpdateResult(batch, result);
|
|
4958
|
+
} else {
|
|
4959
|
+
const nextBatch = { ...result };
|
|
4960
|
+
batchedItemSizeRecalculates.set(ctx, nextBatch);
|
|
4961
|
+
if ((_a3 = ctx.state.pendingLayoutEffectMeasurements) == null ? void 0 : _a3.size) {
|
|
4962
|
+
requestAnimationFrame(() => {
|
|
4963
|
+
flushBatchedItemSizeRecalculate(ctx, true, nextBatch);
|
|
4964
|
+
});
|
|
4965
|
+
}
|
|
4966
|
+
}
|
|
4967
|
+
if (!((_b = ctx.state.pendingLayoutEffectMeasurements) == null ? void 0 : _b.size)) {
|
|
4968
|
+
flushBatchedItemSizeRecalculate(ctx);
|
|
4969
|
+
}
|
|
4970
|
+
}
|
|
4769
4971
|
function flushItemSizeUpdates(ctx, result) {
|
|
4770
4972
|
var _a3;
|
|
4771
4973
|
const state = ctx.state;
|
|
@@ -4782,12 +4984,22 @@ function flushItemSizeUpdates(ctx, result) {
|
|
|
4782
4984
|
function updateItemSizes(ctx, measurement) {
|
|
4783
4985
|
var _a3, _b, _c, _d;
|
|
4784
4986
|
const state = ctx.state;
|
|
4987
|
+
let didDrainLayoutEffectMeasurements = false;
|
|
4988
|
+
if (IsNewArchitecture && measurement.fromLayoutEffect) {
|
|
4989
|
+
const pendingLayoutEffectMeasurements = state.pendingLayoutEffectMeasurements;
|
|
4990
|
+
if ((pendingLayoutEffectMeasurements == null ? void 0 : pendingLayoutEffectMeasurements.delete(measurement.itemKey)) && pendingLayoutEffectMeasurements.size === 0) {
|
|
4991
|
+
state.pendingLayoutEffectMeasurements = void 0;
|
|
4992
|
+
didDrainLayoutEffectMeasurements = true;
|
|
4993
|
+
}
|
|
4994
|
+
}
|
|
4785
4995
|
const pendingKeys = (_a3 = state.userScrollAnchorReset) == null ? void 0 : _a3.keys;
|
|
4786
4996
|
const shouldBatchPendingMeasurements = IsNewArchitecture && measurement.fromLayoutEffect && !!(pendingKeys == null ? void 0 : pendingKeys.size);
|
|
4997
|
+
const shouldQueueRecalculate = IsNewArchitecture && !!measurement.fromLayoutEffect;
|
|
4998
|
+
let result;
|
|
4787
4999
|
if (!shouldBatchPendingMeasurements) {
|
|
4788
|
-
|
|
5000
|
+
result = applyItemSize(ctx, measurement.itemKey, measurement.size);
|
|
4789
5001
|
} else {
|
|
4790
|
-
|
|
5002
|
+
result = {};
|
|
4791
5003
|
const updateContainerItemSize = (itemKey, containerId, size) => {
|
|
4792
5004
|
if (containerId !== void 0 && peek$(ctx, `containerItemKey${containerId}`) === itemKey) {
|
|
4793
5005
|
mergeItemSizeUpdateResult(result, applyItemSize(ctx, itemKey, size));
|
|
@@ -4805,8 +5017,15 @@ function updateItemSizes(ctx, measurement) {
|
|
|
4805
5017
|
});
|
|
4806
5018
|
}
|
|
4807
5019
|
}
|
|
5020
|
+
}
|
|
5021
|
+
if (shouldQueueRecalculate && result.needsRecalculate) {
|
|
5022
|
+
queueItemSizeRecalculate(ctx, result);
|
|
5023
|
+
} else {
|
|
4808
5024
|
flushItemSizeUpdates(ctx, result);
|
|
4809
5025
|
}
|
|
5026
|
+
if (didDrainLayoutEffectMeasurements) {
|
|
5027
|
+
flushBatchedItemSizeRecalculate(ctx);
|
|
5028
|
+
}
|
|
4810
5029
|
}
|
|
4811
5030
|
function applyItemSize(ctx, itemKey, sizeObj) {
|
|
4812
5031
|
var _a3;
|
|
@@ -5134,12 +5353,9 @@ var Container = typedMemo(function Container2({
|
|
|
5134
5353
|
ctx.viewRefs.set(id, ref);
|
|
5135
5354
|
return {
|
|
5136
5355
|
containerId: id,
|
|
5137
|
-
|
|
5138
|
-
itemKey,
|
|
5139
|
-
triggerLayout,
|
|
5140
|
-
value: data
|
|
5356
|
+
triggerLayout
|
|
5141
5357
|
};
|
|
5142
|
-
}, [id,
|
|
5358
|
+
}, [id, triggerLayout]);
|
|
5143
5359
|
React2.useLayoutEffect(() => {
|
|
5144
5360
|
ctx.containerLayoutTriggers.set(id, triggerLayout);
|
|
5145
5361
|
return () => {
|