@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.mjs
CHANGED
|
@@ -117,6 +117,7 @@ var createAnimatedValue = (value) => new Animated.Value(value);
|
|
|
117
117
|
|
|
118
118
|
// src/state/state.tsx
|
|
119
119
|
var ContextState = React2.createContext(null);
|
|
120
|
+
var SIGNAL_NAMES_SEPARATOR = "\0";
|
|
120
121
|
var contextNum = 0;
|
|
121
122
|
function StateProvider({ children }) {
|
|
122
123
|
const [value] = React2.useState(() => ({
|
|
@@ -188,6 +189,12 @@ function createSelectorFunctionsArr(ctx, signalNames) {
|
|
|
188
189
|
}
|
|
189
190
|
};
|
|
190
191
|
}
|
|
192
|
+
function getSignalNamesKey(signalNames) {
|
|
193
|
+
return signalNames.length === 1 ? signalNames[0] : signalNames.join(SIGNAL_NAMES_SEPARATOR);
|
|
194
|
+
}
|
|
195
|
+
function getSignalNamesFromKey(signalNamesKey) {
|
|
196
|
+
return signalNamesKey.split(SIGNAL_NAMES_SEPARATOR);
|
|
197
|
+
}
|
|
191
198
|
function listen$(ctx, signalName, cb) {
|
|
192
199
|
const { listeners } = ctx;
|
|
193
200
|
let setListeners = listeners.get(signalName);
|
|
@@ -235,7 +242,11 @@ function notifyPosition$(ctx, key, value) {
|
|
|
235
242
|
}
|
|
236
243
|
function useArr$(signalNames) {
|
|
237
244
|
const ctx = React2.useContext(ContextState);
|
|
238
|
-
const
|
|
245
|
+
const signalNamesKey = getSignalNamesKey(signalNames);
|
|
246
|
+
const { subscribe, get } = React2.useMemo(
|
|
247
|
+
() => createSelectorFunctionsArr(ctx, getSignalNamesFromKey(signalNamesKey)),
|
|
248
|
+
[ctx, signalNamesKey]
|
|
249
|
+
);
|
|
239
250
|
const value = useSyncExternalStore(subscribe, get, get);
|
|
240
251
|
return value;
|
|
241
252
|
}
|
|
@@ -587,9 +598,22 @@ function findContainerId(ctx, key) {
|
|
|
587
598
|
|
|
588
599
|
// src/state/ContextContainer.ts
|
|
589
600
|
var ContextContainer = createContext(null);
|
|
601
|
+
var NO_CONTAINER_ID = -1;
|
|
590
602
|
function useContextContainer() {
|
|
591
603
|
return useContext(ContextContainer);
|
|
592
604
|
}
|
|
605
|
+
function useContainerItemInfo(containerContext) {
|
|
606
|
+
var _a3;
|
|
607
|
+
const containerId = (_a3 = containerContext == null ? void 0 : containerContext.containerId) != null ? _a3 : NO_CONTAINER_ID;
|
|
608
|
+
const [itemInfo] = useArr$([`containerItemInfo${containerId}`]);
|
|
609
|
+
return containerContext ? itemInfo : void 0;
|
|
610
|
+
}
|
|
611
|
+
function useContainerItemKey(containerContext) {
|
|
612
|
+
var _a3;
|
|
613
|
+
const containerId = (_a3 = containerContext == null ? void 0 : containerContext.containerId) != null ? _a3 : NO_CONTAINER_ID;
|
|
614
|
+
const [itemKey] = useArr$([`containerItemKey${containerId}`]);
|
|
615
|
+
return containerContext ? itemKey : void 0;
|
|
616
|
+
}
|
|
593
617
|
function useAdaptiveRender() {
|
|
594
618
|
const [mode] = useArr$(["adaptiveRender"]);
|
|
595
619
|
return mode;
|
|
@@ -660,40 +684,35 @@ function useViewabilityAmount(callback) {
|
|
|
660
684
|
}
|
|
661
685
|
function useRecyclingEffect(effect) {
|
|
662
686
|
const containerContext = useContextContainer();
|
|
663
|
-
const
|
|
664
|
-
|
|
665
|
-
prevItem: void 0
|
|
666
|
-
});
|
|
687
|
+
const itemInfo = useContainerItemInfo(containerContext);
|
|
688
|
+
const prevInfo = useRef(void 0);
|
|
667
689
|
useEffect(() => {
|
|
668
|
-
if (!
|
|
690
|
+
if (!itemInfo) {
|
|
669
691
|
return;
|
|
670
692
|
}
|
|
671
|
-
const { index, value } = containerContext;
|
|
672
693
|
let ret;
|
|
673
|
-
if (
|
|
694
|
+
if (prevInfo.current) {
|
|
674
695
|
ret = effect({
|
|
675
|
-
index,
|
|
676
|
-
item: value,
|
|
677
|
-
prevIndex:
|
|
678
|
-
prevItem:
|
|
696
|
+
index: itemInfo.index,
|
|
697
|
+
item: itemInfo.value,
|
|
698
|
+
prevIndex: prevInfo.current.index,
|
|
699
|
+
prevItem: prevInfo.current.value
|
|
679
700
|
});
|
|
680
701
|
}
|
|
681
|
-
|
|
682
|
-
prevIndex: index,
|
|
683
|
-
prevItem: value
|
|
684
|
-
};
|
|
702
|
+
prevInfo.current = itemInfo;
|
|
685
703
|
return ret;
|
|
686
|
-
}, [effect,
|
|
704
|
+
}, [effect, itemInfo]);
|
|
687
705
|
}
|
|
688
706
|
function useRecyclingState(valueOrFun) {
|
|
689
|
-
var _a3
|
|
707
|
+
var _a3;
|
|
690
708
|
const containerContext = useContextContainer();
|
|
691
|
-
const
|
|
709
|
+
const itemInfo = useContainerItemInfo(containerContext);
|
|
710
|
+
const computeValue = (info) => {
|
|
692
711
|
if (isFunction(valueOrFun)) {
|
|
693
712
|
const initializer = valueOrFun;
|
|
694
|
-
return
|
|
695
|
-
index:
|
|
696
|
-
item:
|
|
713
|
+
return info ? initializer({
|
|
714
|
+
index: info.index,
|
|
715
|
+
item: info.value,
|
|
697
716
|
prevIndex: void 0,
|
|
698
717
|
prevItem: void 0
|
|
699
718
|
}) : initializer();
|
|
@@ -701,13 +720,12 @@ function useRecyclingState(valueOrFun) {
|
|
|
701
720
|
return valueOrFun;
|
|
702
721
|
};
|
|
703
722
|
const [stateValue, setStateValue] = useState(() => {
|
|
704
|
-
return computeValue(
|
|
723
|
+
return computeValue(itemInfo);
|
|
705
724
|
});
|
|
706
|
-
const prevItemKeyRef = useRef((_a3 =
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
setStateValue(computeValue(containerContext));
|
|
725
|
+
const prevItemKeyRef = useRef((_a3 = itemInfo == null ? void 0 : itemInfo.itemKey) != null ? _a3 : null);
|
|
726
|
+
if (itemInfo && prevItemKeyRef.current !== itemInfo.itemKey) {
|
|
727
|
+
prevItemKeyRef.current = itemInfo.itemKey;
|
|
728
|
+
setStateValue(computeValue(itemInfo));
|
|
711
729
|
}
|
|
712
730
|
const triggerLayout = containerContext == null ? void 0 : containerContext.triggerLayout;
|
|
713
731
|
const setState = useCallback(
|
|
@@ -726,12 +744,10 @@ function useRecyclingState(valueOrFun) {
|
|
|
726
744
|
}
|
|
727
745
|
function useIsLastItem() {
|
|
728
746
|
const containerContext = useContextContainer();
|
|
747
|
+
const itemKey = useContainerItemKey(containerContext);
|
|
729
748
|
const isLast = useSelector$("lastItemKeys", (lastItemKeys) => {
|
|
730
|
-
if (containerContext) {
|
|
731
|
-
|
|
732
|
-
if (!isNullOrUndefined(itemKey)) {
|
|
733
|
-
return (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false;
|
|
734
|
-
}
|
|
749
|
+
if (containerContext && !isNullOrUndefined(itemKey)) {
|
|
750
|
+
return (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false;
|
|
735
751
|
}
|
|
736
752
|
return false;
|
|
737
753
|
});
|
|
@@ -745,12 +761,7 @@ var noop = () => {
|
|
|
745
761
|
};
|
|
746
762
|
function useSyncLayout() {
|
|
747
763
|
const containerContext = useContextContainer();
|
|
748
|
-
|
|
749
|
-
const { triggerLayout: syncLayout } = containerContext;
|
|
750
|
-
return syncLayout;
|
|
751
|
-
} else {
|
|
752
|
-
return noop;
|
|
753
|
-
}
|
|
764
|
+
return IsNewArchitecture && containerContext ? containerContext.triggerLayout : noop;
|
|
754
765
|
}
|
|
755
766
|
|
|
756
767
|
// src/components/Separator.tsx
|
|
@@ -1513,6 +1524,7 @@ function finishScrollTo(ctx) {
|
|
|
1513
1524
|
const scrollingTo = state.scrollingTo;
|
|
1514
1525
|
state.scrollHistory.length = 0;
|
|
1515
1526
|
state.scrollingTo = void 0;
|
|
1527
|
+
state.scrollTargetPinnedRange = void 0;
|
|
1516
1528
|
if (state.pendingTotalSize !== void 0) {
|
|
1517
1529
|
addTotalSize(ctx, null, state.pendingTotalSize);
|
|
1518
1530
|
}
|
|
@@ -2152,6 +2164,8 @@ var flushSync = (fn) => {
|
|
|
2152
2164
|
};
|
|
2153
2165
|
|
|
2154
2166
|
// src/utils/getScrollVelocity.ts
|
|
2167
|
+
var MAX_SCROLL_VELOCITY_WINDOW_MS = 1e3;
|
|
2168
|
+
var SCROLL_VELOCITY_HALF_LIFE_MS = 200;
|
|
2155
2169
|
var getScrollVelocity = (state) => {
|
|
2156
2170
|
const { scrollHistory } = state;
|
|
2157
2171
|
const newestIndex = scrollHistory.length - 1;
|
|
@@ -2159,35 +2173,37 @@ var getScrollVelocity = (state) => {
|
|
|
2159
2173
|
return 0;
|
|
2160
2174
|
}
|
|
2161
2175
|
const newest = scrollHistory[newestIndex];
|
|
2162
|
-
|
|
2163
|
-
let direction = 0;
|
|
2164
|
-
for (let i = newestIndex; i > 0; i--) {
|
|
2165
|
-
const delta = scrollHistory[i].scroll - scrollHistory[i - 1].scroll;
|
|
2166
|
-
if (delta !== 0) {
|
|
2167
|
-
direction = Math.sign(delta);
|
|
2168
|
-
break;
|
|
2169
|
-
}
|
|
2170
|
-
}
|
|
2171
|
-
if (direction === 0) {
|
|
2176
|
+
if (Date.now() - newest.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
|
|
2172
2177
|
return 0;
|
|
2173
2178
|
}
|
|
2174
|
-
let
|
|
2175
|
-
|
|
2179
|
+
let direction = 0;
|
|
2180
|
+
let weightedVelocity = 0;
|
|
2181
|
+
let totalWeight = 0;
|
|
2182
|
+
for (let i = newestIndex; i > 0; i--) {
|
|
2176
2183
|
const current = scrollHistory[i];
|
|
2177
|
-
const
|
|
2178
|
-
const
|
|
2179
|
-
const
|
|
2180
|
-
|
|
2181
|
-
|
|
2184
|
+
const previous = scrollHistory[i - 1];
|
|
2185
|
+
const scrollDiff = current.scroll - previous.scroll;
|
|
2186
|
+
const timeDiff = current.time - previous.time;
|
|
2187
|
+
const deltaSign = Math.sign(scrollDiff);
|
|
2188
|
+
if (deltaSign !== 0) {
|
|
2189
|
+
if (direction === 0) {
|
|
2190
|
+
direction = deltaSign;
|
|
2191
|
+
} else if (deltaSign !== direction) {
|
|
2192
|
+
break;
|
|
2193
|
+
}
|
|
2182
2194
|
}
|
|
2183
|
-
if (
|
|
2195
|
+
if (newest.time - previous.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
|
|
2184
2196
|
break;
|
|
2185
2197
|
}
|
|
2186
|
-
|
|
2198
|
+
if (scrollDiff === 0 || timeDiff <= 0) {
|
|
2199
|
+
continue;
|
|
2200
|
+
}
|
|
2201
|
+
const age = newest.time - current.time;
|
|
2202
|
+
const weight = Math.exp(-age / SCROLL_VELOCITY_HALF_LIFE_MS);
|
|
2203
|
+
weightedVelocity += scrollDiff / timeDiff * weight;
|
|
2204
|
+
totalWeight += weight;
|
|
2187
2205
|
}
|
|
2188
|
-
|
|
2189
|
-
const timeDiff = newest.time - oldest.time;
|
|
2190
|
-
return timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
2206
|
+
return totalWeight > 0 ? weightedVelocity / totalWeight : 0;
|
|
2191
2207
|
};
|
|
2192
2208
|
|
|
2193
2209
|
// src/core/updateScroll.ts
|
|
@@ -2304,8 +2320,93 @@ function syncInitialScrollNativeWatchdog(state, options) {
|
|
|
2304
2320
|
initialScrollWatchdog.clear(state);
|
|
2305
2321
|
}
|
|
2306
2322
|
}
|
|
2307
|
-
function
|
|
2323
|
+
function findPositionIndexAtOrBeforeOffset(ctx, offset) {
|
|
2324
|
+
const state = ctx.state;
|
|
2325
|
+
const dataLength = state.props.data.length;
|
|
2326
|
+
let low = 0;
|
|
2327
|
+
let high = dataLength - 1;
|
|
2328
|
+
let match;
|
|
2329
|
+
while (low <= high) {
|
|
2330
|
+
const mid = Math.floor((low + high) / 2);
|
|
2331
|
+
const top = state.positions[mid];
|
|
2332
|
+
if (top === void 0) {
|
|
2333
|
+
high = mid - 1;
|
|
2334
|
+
} else {
|
|
2335
|
+
if (top <= offset) {
|
|
2336
|
+
match = mid;
|
|
2337
|
+
low = mid + 1;
|
|
2338
|
+
} else {
|
|
2339
|
+
high = mid - 1;
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
return match;
|
|
2344
|
+
}
|
|
2345
|
+
function getItemBottom(ctx, index) {
|
|
2308
2346
|
var _a3;
|
|
2347
|
+
const top = ctx.state.positions[index];
|
|
2348
|
+
if (top === void 0) {
|
|
2349
|
+
return void 0;
|
|
2350
|
+
}
|
|
2351
|
+
const itemSize = (_a3 = getItemSizeAtIndex(ctx, index)) != null ? _a3 : 0;
|
|
2352
|
+
return top + (Number.isFinite(itemSize) ? itemSize : 0);
|
|
2353
|
+
}
|
|
2354
|
+
function getTargetViewportRenderRange(ctx, targetOffset, targetIndex) {
|
|
2355
|
+
const state = ctx.state;
|
|
2356
|
+
const dataLength = state.props.data.length;
|
|
2357
|
+
if (dataLength === 0) {
|
|
2358
|
+
return void 0;
|
|
2359
|
+
}
|
|
2360
|
+
const viewportStart = Math.max(0, targetOffset);
|
|
2361
|
+
const viewportEnd = Math.max(viewportStart, targetOffset + state.scrollLength);
|
|
2362
|
+
let start = targetIndex !== void 0 ? Math.max(0, Math.min(dataLength - 1, targetIndex)) : findPositionIndexAtOrBeforeOffset(ctx, viewportStart);
|
|
2363
|
+
if (start === void 0) {
|
|
2364
|
+
return void 0;
|
|
2365
|
+
}
|
|
2366
|
+
if (targetIndex !== void 0 && state.positions[start] === void 0) {
|
|
2367
|
+
return { end: start, start };
|
|
2368
|
+
}
|
|
2369
|
+
if (targetIndex === void 0) {
|
|
2370
|
+
const startBottom = getItemBottom(ctx, start);
|
|
2371
|
+
if (startBottom === void 0 || startBottom <= viewportStart) {
|
|
2372
|
+
return void 0;
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
while (start > 0) {
|
|
2376
|
+
const top = state.positions[start];
|
|
2377
|
+
if (top === void 0 || top <= viewportStart || state.positions[start - 1] === void 0) {
|
|
2378
|
+
break;
|
|
2379
|
+
}
|
|
2380
|
+
start--;
|
|
2381
|
+
}
|
|
2382
|
+
while (start > 0) {
|
|
2383
|
+
const previousBottom = getItemBottom(ctx, start - 1);
|
|
2384
|
+
if (previousBottom === void 0 || previousBottom <= viewportStart) {
|
|
2385
|
+
break;
|
|
2386
|
+
}
|
|
2387
|
+
start--;
|
|
2388
|
+
}
|
|
2389
|
+
let end = start;
|
|
2390
|
+
while (end + 1 < dataLength) {
|
|
2391
|
+
const nextTop = state.positions[end + 1];
|
|
2392
|
+
if (nextTop === void 0 || nextTop > viewportEnd) {
|
|
2393
|
+
break;
|
|
2394
|
+
}
|
|
2395
|
+
end++;
|
|
2396
|
+
}
|
|
2397
|
+
return { end, start };
|
|
2398
|
+
}
|
|
2399
|
+
function pinScrollTargetRenderRange(ctx, targetOffset, targetIndex) {
|
|
2400
|
+
const range = getTargetViewportRenderRange(ctx, targetOffset, targetIndex);
|
|
2401
|
+
if (range) {
|
|
2402
|
+
ctx.state.scrollTargetPinnedRange = range;
|
|
2403
|
+
ctx.state.scrollForNextCalculateItemsInView = void 0;
|
|
2404
|
+
} else {
|
|
2405
|
+
ctx.state.scrollTargetPinnedRange = void 0;
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
function scrollTo(ctx, params) {
|
|
2409
|
+
var _a3, _b;
|
|
2309
2410
|
const state = ctx.state;
|
|
2310
2411
|
const { noScrollingTo, forceScroll, ...scrollTarget } = params;
|
|
2311
2412
|
const {
|
|
@@ -2340,11 +2441,20 @@ function scrollTo(ctx, params) {
|
|
|
2340
2441
|
targetOffset,
|
|
2341
2442
|
waitForInitialScrollCompletionFrame
|
|
2342
2443
|
};
|
|
2444
|
+
if (!isInitialScroll) {
|
|
2445
|
+
pinScrollTargetRenderRange(ctx, targetOffset, scrollTarget.index);
|
|
2446
|
+
}
|
|
2343
2447
|
}
|
|
2344
2448
|
state.scrollPending = targetOffset;
|
|
2345
2449
|
syncInitialScrollNativeWatchdog(state, { isInitialScroll, requestedOffset: offset, targetOffset });
|
|
2346
|
-
if (!
|
|
2347
|
-
|
|
2450
|
+
if (!isInitialScroll && !noScrollingTo && Math.abs(state.scroll - targetOffset) > 1) {
|
|
2451
|
+
if (animated) {
|
|
2452
|
+
if (state.scrollTargetPinnedRange) {
|
|
2453
|
+
(_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state);
|
|
2454
|
+
}
|
|
2455
|
+
} else {
|
|
2456
|
+
updateScroll(ctx, targetOffset, true, { markHasScrolled: false });
|
|
2457
|
+
}
|
|
2348
2458
|
}
|
|
2349
2459
|
if (forceScroll || !isInitialScroll || Platform.OS === "android") {
|
|
2350
2460
|
doScrollTo(ctx, { animated, horizontal, isInitialScroll, offset });
|
|
@@ -3287,22 +3397,28 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
|
|
|
3287
3397
|
set$(ctx, `containerSpan${containerIndex}`, span);
|
|
3288
3398
|
}
|
|
3289
3399
|
}
|
|
3400
|
+
const prevItemInfo = peek$(ctx, `containerItemInfo${containerIndex}`);
|
|
3290
3401
|
const prevData = peek$(ctx, `containerItemData${containerIndex}`);
|
|
3402
|
+
let itemInfoValue = prevData;
|
|
3403
|
+
let didChangeItemInfo = (prevItemInfo == null ? void 0 : prevItemInfo.itemKey) !== itemKey || (prevItemInfo == null ? void 0 : prevItemInfo.index) !== itemIndex || (prevItemInfo == null ? void 0 : prevItemInfo.value) !== prevData;
|
|
3404
|
+
const updateData = () => {
|
|
3405
|
+
set$(ctx, `containerItemData${containerIndex}`, item);
|
|
3406
|
+
itemInfoValue = item;
|
|
3407
|
+
didChangeItemInfo = true;
|
|
3408
|
+
didRefreshData = true;
|
|
3409
|
+
};
|
|
3291
3410
|
if (prevData !== item) {
|
|
3292
3411
|
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;
|
|
3293
3412
|
const cachedComparison = (_g = pendingDataComparison == null ? void 0 : pendingDataComparison.byIndex[itemIndex]) != null ? _g : 0;
|
|
3294
3413
|
if (cachedComparison === 2) {
|
|
3295
|
-
|
|
3296
|
-
didRefreshData = true;
|
|
3414
|
+
updateData();
|
|
3297
3415
|
} else if (cachedComparison !== 1) {
|
|
3298
3416
|
const nextItemKey = (_h = peek$(ctx, `containerItemKey${containerIndex}`)) != null ? _h : itemKey;
|
|
3299
3417
|
const prevKey = keyExtractor == null ? void 0 : keyExtractor(prevData, itemIndex);
|
|
3300
3418
|
if (prevData === void 0 || !keyExtractor || prevKey !== nextItemKey) {
|
|
3301
|
-
|
|
3302
|
-
didRefreshData = true;
|
|
3419
|
+
updateData();
|
|
3303
3420
|
} else if (!itemsAreEqual) {
|
|
3304
|
-
|
|
3305
|
-
didRefreshData = true;
|
|
3421
|
+
updateData();
|
|
3306
3422
|
} else {
|
|
3307
3423
|
const isEqual = itemsAreEqual(prevData, item, itemIndex, data);
|
|
3308
3424
|
if (!state.pendingDataComparison || state.pendingDataComparison.previousData !== state.previousData || state.pendingDataComparison.nextData !== data) {
|
|
@@ -3318,12 +3434,18 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
|
|
|
3318
3434
|
state.pendingDataComparison.byIndex[itemIndex] = isEqual ? 1 : 2;
|
|
3319
3435
|
}
|
|
3320
3436
|
if (!isEqual) {
|
|
3321
|
-
|
|
3322
|
-
didRefreshData = true;
|
|
3437
|
+
updateData();
|
|
3323
3438
|
}
|
|
3324
3439
|
}
|
|
3325
3440
|
}
|
|
3326
3441
|
}
|
|
3442
|
+
if (didChangeItemInfo) {
|
|
3443
|
+
set$(ctx, `containerItemInfo${containerIndex}`, {
|
|
3444
|
+
index: itemIndex,
|
|
3445
|
+
itemKey,
|
|
3446
|
+
value: itemInfoValue
|
|
3447
|
+
});
|
|
3448
|
+
}
|
|
3327
3449
|
return { didChangePosition, didRefreshData };
|
|
3328
3450
|
}
|
|
3329
3451
|
|
|
@@ -4016,6 +4138,32 @@ function setDidLayout(ctx) {
|
|
|
4016
4138
|
}
|
|
4017
4139
|
|
|
4018
4140
|
// src/core/calculateItemsInView.ts
|
|
4141
|
+
var RENDER_RANGE_PROJECTION_FULL_VELOCITY = 4;
|
|
4142
|
+
var RENDER_RANGE_PROJECTION_SETTLE_DELAY = 100;
|
|
4143
|
+
function getProjectedBufferAdjustment(scrollVelocity, trailingBuffer) {
|
|
4144
|
+
if (trailingBuffer <= 0) {
|
|
4145
|
+
return 0;
|
|
4146
|
+
}
|
|
4147
|
+
const velocityProgress = Math.min(1, Math.abs(scrollVelocity) / RENDER_RANGE_PROJECTION_FULL_VELOCITY);
|
|
4148
|
+
return Math.sign(scrollVelocity) * trailingBuffer * velocityProgress;
|
|
4149
|
+
}
|
|
4150
|
+
function scheduleRenderRangeProjectionSettle(ctx) {
|
|
4151
|
+
const state = ctx.state;
|
|
4152
|
+
const previousTimeout = state.timeoutRenderRangeProjectionSettle;
|
|
4153
|
+
if (previousTimeout !== void 0) {
|
|
4154
|
+
clearTimeout(previousTimeout);
|
|
4155
|
+
state.timeouts.delete(previousTimeout);
|
|
4156
|
+
}
|
|
4157
|
+
const timeout = setTimeout(() => {
|
|
4158
|
+
var _a3;
|
|
4159
|
+
state.timeoutRenderRangeProjectionSettle = void 0;
|
|
4160
|
+
state.timeouts.delete(timeout);
|
|
4161
|
+
state.scrollHistory.length = 0;
|
|
4162
|
+
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state);
|
|
4163
|
+
}, RENDER_RANGE_PROJECTION_SETTLE_DELAY);
|
|
4164
|
+
state.timeoutRenderRangeProjectionSettle = timeout;
|
|
4165
|
+
state.timeouts.add(timeout);
|
|
4166
|
+
}
|
|
4019
4167
|
function findCurrentStickyIndex(stickyArray, scroll, state) {
|
|
4020
4168
|
const positions = state.positions;
|
|
4021
4169
|
for (let i = stickyArray.length - 1; i >= 0; i--) {
|
|
@@ -4056,14 +4204,14 @@ function handleStickyActivation(ctx, stickyArray, currentStickyIdx, needNewConta
|
|
|
4056
4204
|
}
|
|
4057
4205
|
}
|
|
4058
4206
|
}
|
|
4059
|
-
function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentStickyIdx, pendingRemoval,
|
|
4207
|
+
function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentStickyIdx, pendingRemoval, isPinnedRenderIndex) {
|
|
4060
4208
|
var _a3, _b;
|
|
4061
4209
|
const state = ctx.state;
|
|
4062
4210
|
for (const containerIndex of state.stickyContainerPool) {
|
|
4063
4211
|
const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
4064
4212
|
const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
|
|
4065
4213
|
if (itemIndex === void 0) continue;
|
|
4066
|
-
if (
|
|
4214
|
+
if (isPinnedRenderIndex(itemIndex)) continue;
|
|
4067
4215
|
const arrayIdx = stickyArray.indexOf(itemIndex);
|
|
4068
4216
|
if (arrayIdx === -1) {
|
|
4069
4217
|
state.stickyContainerPool.delete(containerIndex);
|
|
@@ -4227,8 +4375,6 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4227
4375
|
const { data } = state.props;
|
|
4228
4376
|
const stickyHeaderIndicesArr = state.props.stickyHeaderIndicesArr || [];
|
|
4229
4377
|
const stickyHeaderIndicesSet = state.props.stickyHeaderIndicesSet || /* @__PURE__ */ new Set();
|
|
4230
|
-
const alwaysRenderArr = alwaysRenderIndicesArr || [];
|
|
4231
|
-
const alwaysRenderSet = alwaysRenderIndicesSet || /* @__PURE__ */ new Set();
|
|
4232
4378
|
const drawDistance = getEffectiveDrawDistance(ctx, params.drawDistanceMode);
|
|
4233
4379
|
const { dataChanged, doMVCP, forceFullItemPositions } = params;
|
|
4234
4380
|
const bootstrapInitialScrollState = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
|
|
@@ -4295,14 +4441,19 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4295
4441
|
scrollBufferTop = drawDistance * 1.5;
|
|
4296
4442
|
scrollBufferBottom = drawDistance * 0.5;
|
|
4297
4443
|
}
|
|
4444
|
+
const shouldProjectRenderRange = !dataChanged && !forceFullItemPositions && !suppressInitialScrollSideEffects && !hasActiveInitialScroll(state) && !state.scrollingTo && !state.pendingNativeMVCPAdjust && !!peek$(ctx, "readyToRender");
|
|
4445
|
+
const projectedBufferAdjustment = shouldProjectRenderRange ? getProjectedBufferAdjustment(speed, Math.min(scrollBufferTop, scrollBufferBottom)) : 0;
|
|
4298
4446
|
const updateScrollRange = () => {
|
|
4299
4447
|
const scrollStart = Math.max(0, scroll);
|
|
4300
4448
|
const overscrollBeforeContent = Math.max(0, -nativeScrollState);
|
|
4301
|
-
scrollTopBuffered = scrollStart - scrollBufferTop;
|
|
4302
4449
|
scrollBottom = Math.max(scrollStart, scroll + scrollLength + overscrollBeforeContent);
|
|
4303
|
-
|
|
4450
|
+
scrollTopBuffered = scrollStart - scrollBufferTop + projectedBufferAdjustment;
|
|
4451
|
+
scrollBottomBuffered = scrollBottom + scrollBufferBottom + projectedBufferAdjustment;
|
|
4304
4452
|
};
|
|
4305
4453
|
updateScrollRange();
|
|
4454
|
+
if (projectedBufferAdjustment !== 0) {
|
|
4455
|
+
scheduleRenderRangeProjectionSettle(ctx);
|
|
4456
|
+
}
|
|
4306
4457
|
if (enableScrollForNextCalculateItemsInView && !suppressInitialScrollSideEffects && !dataChanged && !forceFullItemPositions && scrollForNextCalculateItemsInView) {
|
|
4307
4458
|
const { top, bottom } = scrollForNextCalculateItemsInView;
|
|
4308
4459
|
if (top === null && bottom === null) {
|
|
@@ -4460,9 +4611,34 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4460
4611
|
}
|
|
4461
4612
|
}
|
|
4462
4613
|
}
|
|
4614
|
+
const scrollTargetPinnedRange = state.scrollTargetPinnedRange;
|
|
4615
|
+
let scrollTargetPinnedStart = 0;
|
|
4616
|
+
let scrollTargetPinnedEnd = -1;
|
|
4617
|
+
if (scrollTargetPinnedRange) {
|
|
4618
|
+
scrollTargetPinnedStart = Math.max(0, Math.min(scrollTargetPinnedRange.start, scrollTargetPinnedRange.end));
|
|
4619
|
+
scrollTargetPinnedEnd = Math.min(
|
|
4620
|
+
dataLength - 1,
|
|
4621
|
+
Math.max(scrollTargetPinnedRange.start, scrollTargetPinnedRange.end)
|
|
4622
|
+
);
|
|
4623
|
+
}
|
|
4624
|
+
const hasScrollTargetPinnedRange = scrollTargetPinnedStart <= scrollTargetPinnedEnd;
|
|
4625
|
+
const isPinnedRenderIndex = (index) => alwaysRenderIndicesSet.has(index) || hasScrollTargetPinnedRange && index >= scrollTargetPinnedStart && index <= scrollTargetPinnedEnd;
|
|
4463
4626
|
if (startBuffered !== null && endBuffered !== null) {
|
|
4464
4627
|
const needNewContainers = [];
|
|
4465
4628
|
const needNewContainersSet = /* @__PURE__ */ new Set();
|
|
4629
|
+
const addPinnedIndex = (index) => {
|
|
4630
|
+
var _a4;
|
|
4631
|
+
if (index >= 0 && index < dataLength) {
|
|
4632
|
+
const id = (_a4 = idCache[index]) != null ? _a4 : getId(state, index);
|
|
4633
|
+
const containerIndex = containerItemKeys.get(id);
|
|
4634
|
+
if (containerIndex !== void 0) {
|
|
4635
|
+
state.stickyContainerPool.add(containerIndex);
|
|
4636
|
+
} else if (!isNullOrUndefined(id) && !needNewContainersSet.has(index)) {
|
|
4637
|
+
needNewContainersSet.add(index);
|
|
4638
|
+
needNewContainers.push(index);
|
|
4639
|
+
}
|
|
4640
|
+
}
|
|
4641
|
+
};
|
|
4466
4642
|
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
4467
4643
|
const id = (_m = idCache[i]) != null ? _m : getId(state, i);
|
|
4468
4644
|
if (!containerItemKeys.has(id)) {
|
|
@@ -4470,21 +4646,19 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4470
4646
|
needNewContainers.push(i);
|
|
4471
4647
|
}
|
|
4472
4648
|
}
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
needNewContainers.push(index);
|
|
4480
|
-
}
|
|
4649
|
+
for (const index of alwaysRenderIndicesArr) {
|
|
4650
|
+
addPinnedIndex(index);
|
|
4651
|
+
}
|
|
4652
|
+
if (hasScrollTargetPinnedRange) {
|
|
4653
|
+
for (let index = scrollTargetPinnedStart; index <= scrollTargetPinnedEnd; index++) {
|
|
4654
|
+
addPinnedIndex(index);
|
|
4481
4655
|
}
|
|
4482
4656
|
}
|
|
4483
4657
|
if (stickyHeaderIndicesArr.length > 0) {
|
|
4484
4658
|
handleStickyActivation(
|
|
4485
4659
|
ctx,
|
|
4486
4660
|
stickyHeaderIndicesArr,
|
|
4487
|
-
(
|
|
4661
|
+
(_n = stickyState == null ? void 0 : stickyState.currentStickyIdx) != null ? _n : -1,
|
|
4488
4662
|
needNewContainers,
|
|
4489
4663
|
needNewContainersSet,
|
|
4490
4664
|
startBuffered,
|
|
@@ -4510,21 +4684,30 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4510
4684
|
for (const allocation of availableContainerAllocations) {
|
|
4511
4685
|
const i = allocation.itemIndex;
|
|
4512
4686
|
const containerIndex = allocation.containerIndex;
|
|
4513
|
-
const id = (
|
|
4687
|
+
const id = (_o = idCache[i]) != null ? _o : getId(state, i);
|
|
4514
4688
|
const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
4515
4689
|
if (oldKey && oldKey !== id) {
|
|
4516
4690
|
containerItemKeys.delete(oldKey);
|
|
4517
4691
|
}
|
|
4518
4692
|
set$(ctx, `containerItemKey${containerIndex}`, id);
|
|
4519
4693
|
set$(ctx, `containerItemData${containerIndex}`, data[i]);
|
|
4694
|
+
set$(ctx, `containerItemInfo${containerIndex}`, {
|
|
4695
|
+
index: i,
|
|
4696
|
+
itemKey: id,
|
|
4697
|
+
value: data[i]
|
|
4698
|
+
});
|
|
4520
4699
|
if (allocation.itemType !== void 0) {
|
|
4521
4700
|
state.containerItemTypes.set(containerIndex, allocation.itemType);
|
|
4522
4701
|
}
|
|
4523
4702
|
containerItemKeys.set(id, containerIndex);
|
|
4524
|
-
(
|
|
4703
|
+
(_p = state.userScrollAnchorReset) == null ? void 0 : _p.keys.add(id);
|
|
4704
|
+
if (IsNewArchitecture) {
|
|
4705
|
+
(_q = state.pendingLayoutEffectMeasurements) != null ? _q : state.pendingLayoutEffectMeasurements = /* @__PURE__ */ new Set();
|
|
4706
|
+
state.pendingLayoutEffectMeasurements.add(id);
|
|
4707
|
+
}
|
|
4525
4708
|
const containerSticky = `containerSticky${containerIndex}`;
|
|
4526
4709
|
const isSticky = stickyHeaderIndicesSet.has(i);
|
|
4527
|
-
const
|
|
4710
|
+
const isPinnedRender = isPinnedRenderIndex(i);
|
|
4528
4711
|
if (isSticky) {
|
|
4529
4712
|
set$(ctx, containerSticky, true);
|
|
4530
4713
|
state.stickyContainerPool.add(containerIndex);
|
|
@@ -4532,9 +4715,9 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4532
4715
|
if (peek$(ctx, containerSticky)) {
|
|
4533
4716
|
set$(ctx, containerSticky, false);
|
|
4534
4717
|
}
|
|
4535
|
-
if (
|
|
4718
|
+
if (isPinnedRender) {
|
|
4536
4719
|
state.stickyContainerPool.add(containerIndex);
|
|
4537
|
-
} else
|
|
4720
|
+
} else {
|
|
4538
4721
|
state.stickyContainerPool.delete(containerIndex);
|
|
4539
4722
|
}
|
|
4540
4723
|
}
|
|
@@ -4549,20 +4732,8 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4549
4732
|
}
|
|
4550
4733
|
}
|
|
4551
4734
|
}
|
|
4552
|
-
if (state.userScrollAnchorReset) {
|
|
4553
|
-
|
|
4554
|
-
state.userScrollAnchorReset = void 0;
|
|
4555
|
-
}
|
|
4556
|
-
}
|
|
4557
|
-
if (alwaysRenderArr.length > 0) {
|
|
4558
|
-
for (const index of alwaysRenderArr) {
|
|
4559
|
-
if (index < 0 || index >= dataLength) continue;
|
|
4560
|
-
const id = (_r = idCache[index]) != null ? _r : getId(state, index);
|
|
4561
|
-
const containerIndex = containerItemKeys.get(id);
|
|
4562
|
-
if (containerIndex !== void 0) {
|
|
4563
|
-
state.stickyContainerPool.add(containerIndex);
|
|
4564
|
-
}
|
|
4565
|
-
}
|
|
4735
|
+
if (((_r = state.userScrollAnchorReset) == null ? void 0 : _r.keys.size) === 0) {
|
|
4736
|
+
state.userScrollAnchorReset = void 0;
|
|
4566
4737
|
}
|
|
4567
4738
|
}
|
|
4568
4739
|
if (state.stickyContainerPool.size > 0) {
|
|
@@ -4573,7 +4744,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4573
4744
|
drawDistance,
|
|
4574
4745
|
(_s = stickyState == null ? void 0 : stickyState.currentStickyIdx) != null ? _s : -1,
|
|
4575
4746
|
pendingRemoval,
|
|
4576
|
-
|
|
4747
|
+
isPinnedRenderIndex
|
|
4577
4748
|
);
|
|
4578
4749
|
}
|
|
4579
4750
|
const pendingRemovalSet = pendingRemoval.length > 0 ? new Set(pendingRemoval) : void 0;
|
|
@@ -4591,6 +4762,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4591
4762
|
}
|
|
4592
4763
|
set$(ctx, `containerItemKey${i}`, void 0);
|
|
4593
4764
|
set$(ctx, `containerItemData${i}`, void 0);
|
|
4765
|
+
set$(ctx, `containerItemInfo${i}`, void 0);
|
|
4594
4766
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
4595
4767
|
set$(ctx, `containerColumn${i}`, -1);
|
|
4596
4768
|
set$(ctx, `containerSpan${i}`, 1);
|
|
@@ -4745,6 +4917,36 @@ function mergeItemSizeUpdateResult(result, next) {
|
|
|
4745
4917
|
result.needsRecalculate || (result.needsRecalculate = next.needsRecalculate);
|
|
4746
4918
|
result.shouldMaintainScrollAtEnd || (result.shouldMaintainScrollAtEnd = next.shouldMaintainScrollAtEnd);
|
|
4747
4919
|
}
|
|
4920
|
+
var batchedItemSizeRecalculates = /* @__PURE__ */ new WeakMap();
|
|
4921
|
+
function flushBatchedItemSizeRecalculate(ctx, didFallback = false, expectedResult) {
|
|
4922
|
+
const result = batchedItemSizeRecalculates.get(ctx);
|
|
4923
|
+
if (!result || expectedResult && result !== expectedResult) {
|
|
4924
|
+
return;
|
|
4925
|
+
}
|
|
4926
|
+
batchedItemSizeRecalculates.delete(ctx);
|
|
4927
|
+
if (didFallback) {
|
|
4928
|
+
ctx.state.pendingLayoutEffectMeasurements = void 0;
|
|
4929
|
+
}
|
|
4930
|
+
flushItemSizeUpdates(ctx, result);
|
|
4931
|
+
}
|
|
4932
|
+
function queueItemSizeRecalculate(ctx, result) {
|
|
4933
|
+
var _a3, _b;
|
|
4934
|
+
const batch = batchedItemSizeRecalculates.get(ctx);
|
|
4935
|
+
if (batch) {
|
|
4936
|
+
mergeItemSizeUpdateResult(batch, result);
|
|
4937
|
+
} else {
|
|
4938
|
+
const nextBatch = { ...result };
|
|
4939
|
+
batchedItemSizeRecalculates.set(ctx, nextBatch);
|
|
4940
|
+
if ((_a3 = ctx.state.pendingLayoutEffectMeasurements) == null ? void 0 : _a3.size) {
|
|
4941
|
+
requestAnimationFrame(() => {
|
|
4942
|
+
flushBatchedItemSizeRecalculate(ctx, true, nextBatch);
|
|
4943
|
+
});
|
|
4944
|
+
}
|
|
4945
|
+
}
|
|
4946
|
+
if (!((_b = ctx.state.pendingLayoutEffectMeasurements) == null ? void 0 : _b.size)) {
|
|
4947
|
+
flushBatchedItemSizeRecalculate(ctx);
|
|
4948
|
+
}
|
|
4949
|
+
}
|
|
4748
4950
|
function flushItemSizeUpdates(ctx, result) {
|
|
4749
4951
|
var _a3;
|
|
4750
4952
|
const state = ctx.state;
|
|
@@ -4761,12 +4963,22 @@ function flushItemSizeUpdates(ctx, result) {
|
|
|
4761
4963
|
function updateItemSizes(ctx, measurement) {
|
|
4762
4964
|
var _a3, _b, _c, _d;
|
|
4763
4965
|
const state = ctx.state;
|
|
4966
|
+
let didDrainLayoutEffectMeasurements = false;
|
|
4967
|
+
if (IsNewArchitecture && measurement.fromLayoutEffect) {
|
|
4968
|
+
const pendingLayoutEffectMeasurements = state.pendingLayoutEffectMeasurements;
|
|
4969
|
+
if ((pendingLayoutEffectMeasurements == null ? void 0 : pendingLayoutEffectMeasurements.delete(measurement.itemKey)) && pendingLayoutEffectMeasurements.size === 0) {
|
|
4970
|
+
state.pendingLayoutEffectMeasurements = void 0;
|
|
4971
|
+
didDrainLayoutEffectMeasurements = true;
|
|
4972
|
+
}
|
|
4973
|
+
}
|
|
4764
4974
|
const pendingKeys = (_a3 = state.userScrollAnchorReset) == null ? void 0 : _a3.keys;
|
|
4765
4975
|
const shouldBatchPendingMeasurements = IsNewArchitecture && measurement.fromLayoutEffect && !!(pendingKeys == null ? void 0 : pendingKeys.size);
|
|
4976
|
+
const shouldQueueRecalculate = IsNewArchitecture && !!measurement.fromLayoutEffect;
|
|
4977
|
+
let result;
|
|
4766
4978
|
if (!shouldBatchPendingMeasurements) {
|
|
4767
|
-
|
|
4979
|
+
result = applyItemSize(ctx, measurement.itemKey, measurement.size);
|
|
4768
4980
|
} else {
|
|
4769
|
-
|
|
4981
|
+
result = {};
|
|
4770
4982
|
const updateContainerItemSize = (itemKey, containerId, size) => {
|
|
4771
4983
|
if (containerId !== void 0 && peek$(ctx, `containerItemKey${containerId}`) === itemKey) {
|
|
4772
4984
|
mergeItemSizeUpdateResult(result, applyItemSize(ctx, itemKey, size));
|
|
@@ -4784,8 +4996,15 @@ function updateItemSizes(ctx, measurement) {
|
|
|
4784
4996
|
});
|
|
4785
4997
|
}
|
|
4786
4998
|
}
|
|
4999
|
+
}
|
|
5000
|
+
if (shouldQueueRecalculate && result.needsRecalculate) {
|
|
5001
|
+
queueItemSizeRecalculate(ctx, result);
|
|
5002
|
+
} else {
|
|
4787
5003
|
flushItemSizeUpdates(ctx, result);
|
|
4788
5004
|
}
|
|
5005
|
+
if (didDrainLayoutEffectMeasurements) {
|
|
5006
|
+
flushBatchedItemSizeRecalculate(ctx);
|
|
5007
|
+
}
|
|
4789
5008
|
}
|
|
4790
5009
|
function applyItemSize(ctx, itemKey, sizeObj) {
|
|
4791
5010
|
var _a3;
|
|
@@ -5113,12 +5332,9 @@ var Container = typedMemo(function Container2({
|
|
|
5113
5332
|
ctx.viewRefs.set(id, ref);
|
|
5114
5333
|
return {
|
|
5115
5334
|
containerId: id,
|
|
5116
|
-
|
|
5117
|
-
itemKey,
|
|
5118
|
-
triggerLayout,
|
|
5119
|
-
value: data
|
|
5335
|
+
triggerLayout
|
|
5120
5336
|
};
|
|
5121
|
-
}, [id,
|
|
5337
|
+
}, [id, triggerLayout]);
|
|
5122
5338
|
useLayoutEffect(() => {
|
|
5123
5339
|
ctx.containerLayoutTriggers.set(id, triggerLayout);
|
|
5124
5340
|
return () => {
|