@legendapp/list 2.1.0-beta.7 → 2.1.0-beta.9
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 +3 -0
- package/index.d.mts +20 -4
- package/index.d.ts +20 -4
- package/index.js +94 -66
- package/index.mjs +94 -66
- package/index.native.d.mts +20 -4
- package/index.native.d.ts +20 -4
- package/index.native.js +96 -67
- package/index.native.mjs +96 -67
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
## 2.0.14
|
|
2
|
+
- Feat: Add dataVersion prop to trigger re-render when mutating the data array in place
|
|
3
|
+
|
|
1
4
|
## 2.0.13
|
|
2
5
|
- Feat: Allow returning undefined in getFixedItemSize to fall back to estimated size
|
|
3
6
|
- Fix: scrollToIndex viewOffset was being subtracted twice, causing incorrect scroll positioning
|
package/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React$1 from 'react';
|
|
2
|
-
import { ComponentProps, ReactNode, Dispatch, SetStateAction } from 'react';
|
|
2
|
+
import { ComponentProps, Key, ReactNode, Dispatch, SetStateAction } from 'react';
|
|
3
3
|
import { View, ScrollView, Animated, LayoutRectangle, ScrollViewComponent, ScrollResponderMixin, StyleProp, ViewStyle, NativeSyntheticEvent, NativeScrollEvent, ScrollViewProps } from 'react-native';
|
|
4
4
|
import Animated$1 from 'react-native-reanimated';
|
|
5
5
|
|
|
@@ -102,6 +102,11 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
|
|
|
102
102
|
* Extra data to trigger re-rendering when changed.
|
|
103
103
|
*/
|
|
104
104
|
extraData?: any;
|
|
105
|
+
/**
|
|
106
|
+
* Version token that forces the list to treat data as updated even when the array reference is stable.
|
|
107
|
+
* Increment or change this when mutating the data array in place.
|
|
108
|
+
*/
|
|
109
|
+
dataVersion?: Key;
|
|
105
110
|
/**
|
|
106
111
|
* In case you have distinct item sizes, you can provide a function to get the size of an item.
|
|
107
112
|
* Use instead of FlatList's getItemLayout or FlashList overrideItemLayout if you want to have accurate initialScrollOffset, you should provide this function
|
|
@@ -250,6 +255,7 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
|
|
|
250
255
|
refreshing?: boolean;
|
|
251
256
|
/**
|
|
252
257
|
* Render custom ScrollView component.
|
|
258
|
+
* Note: When using `stickyHeaderIndices`, you must provide an Animated ScrollView component.
|
|
253
259
|
* @default (props) => <ScrollView {...props} />
|
|
254
260
|
*/
|
|
255
261
|
renderScrollComponent?: (props: ScrollViewProps) => React.ReactElement<ScrollViewProps>;
|
|
@@ -312,6 +318,7 @@ interface ScrollTarget {
|
|
|
312
318
|
viewPosition?: number;
|
|
313
319
|
animated?: boolean;
|
|
314
320
|
isInitialScroll?: boolean;
|
|
321
|
+
precomputedWithViewOffset?: boolean;
|
|
315
322
|
}
|
|
316
323
|
interface InternalState {
|
|
317
324
|
positions: Map<string, number>;
|
|
@@ -339,6 +346,11 @@ interface InternalState {
|
|
|
339
346
|
scrollPrev: number;
|
|
340
347
|
scrollPrevTime: number;
|
|
341
348
|
scrollAdjustHandler: ScrollAdjustHandler;
|
|
349
|
+
triggerCalculateItemsInView?: (params?: {
|
|
350
|
+
doMVCP?: boolean;
|
|
351
|
+
dataChanged?: boolean;
|
|
352
|
+
forceFullItemPositions?: boolean;
|
|
353
|
+
}) => void;
|
|
342
354
|
maintainingScrollAtEnd?: boolean;
|
|
343
355
|
totalSize: number;
|
|
344
356
|
otherAxisSize?: number;
|
|
@@ -382,17 +394,17 @@ interface InternalState {
|
|
|
382
394
|
}>;
|
|
383
395
|
refScroller: React.RefObject<ScrollView>;
|
|
384
396
|
loadStartTime: number;
|
|
385
|
-
initialScroll:
|
|
397
|
+
initialScroll: ScrollIndexWithOffsetAndContentOffset | undefined;
|
|
386
398
|
lastLayout: LayoutRectangle | undefined;
|
|
387
399
|
timeoutSetPaddingTop?: any;
|
|
388
400
|
activeStickyIndex: number | undefined;
|
|
389
401
|
stickyContainers: Map<number, number>;
|
|
390
402
|
stickyContainerPool: Set<number>;
|
|
391
403
|
scrollProcessingEnabled: boolean;
|
|
392
|
-
isOptimizingItemPositions: boolean;
|
|
393
404
|
props: {
|
|
394
405
|
alignItemsAtEnd: boolean;
|
|
395
406
|
data: readonly any[];
|
|
407
|
+
dataVersion: Key | undefined;
|
|
396
408
|
estimatedItemSize: number | undefined;
|
|
397
409
|
getEstimatedItemSize: LegendListProps["getEstimatedItemSize"];
|
|
398
410
|
getFixedItemSize: LegendListProps["getFixedItemSize"];
|
|
@@ -443,6 +455,7 @@ type ScrollState = {
|
|
|
443
455
|
activeStickyIndex: number | undefined;
|
|
444
456
|
contentLength: number;
|
|
445
457
|
data: readonly any[];
|
|
458
|
+
elementAtIndex: (index: number) => View | null | undefined;
|
|
446
459
|
end: number;
|
|
447
460
|
endBuffered: number;
|
|
448
461
|
isAtEnd: boolean;
|
|
@@ -630,6 +643,9 @@ interface ScrollIndexWithOffset {
|
|
|
630
643
|
interface ScrollIndexWithOffsetPosition extends ScrollIndexWithOffset {
|
|
631
644
|
viewPosition: number;
|
|
632
645
|
}
|
|
646
|
+
interface ScrollIndexWithOffsetAndContentOffset extends ScrollIndexWithOffset {
|
|
647
|
+
contentOffset?: number;
|
|
648
|
+
}
|
|
633
649
|
type GetRenderedItemResult<ItemT> = {
|
|
634
650
|
index: number;
|
|
635
651
|
item: ItemT;
|
|
@@ -652,4 +668,4 @@ declare function useListScrollSize(): {
|
|
|
652
668
|
};
|
|
653
669
|
declare function useSyncLayout(): () => void;
|
|
654
670
|
|
|
655
|
-
export { type ColumnWrapperStyle, type GetRenderedItem, type GetRenderedItemResult, type InternalState, LegendList, type LegendListProps, type LegendListPropsBase, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type MaintainScrollAtEndOptions, type OnViewableItemsChanged, type ScrollIndexWithOffset, type ScrollIndexWithOffsetPosition, type ScrollState, type ScrollTarget, type ThresholdSnapshot, type TypedForwardRef, type TypedMemo, type ViewAmountToken, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange, typedForwardRef, typedMemo, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useSyncLayout, useViewability, useViewabilityAmount };
|
|
671
|
+
export { type ColumnWrapperStyle, type GetRenderedItem, type GetRenderedItemResult, type InternalState, LegendList, type LegendListProps, type LegendListPropsBase, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type MaintainScrollAtEndOptions, type OnViewableItemsChanged, type ScrollIndexWithOffset, type ScrollIndexWithOffsetAndContentOffset, type ScrollIndexWithOffsetPosition, type ScrollState, type ScrollTarget, type ThresholdSnapshot, type TypedForwardRef, type TypedMemo, type ViewAmountToken, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange, typedForwardRef, typedMemo, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useSyncLayout, useViewability, useViewabilityAmount };
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React$1 from 'react';
|
|
2
|
-
import { ComponentProps, ReactNode, Dispatch, SetStateAction } from 'react';
|
|
2
|
+
import { ComponentProps, Key, ReactNode, Dispatch, SetStateAction } from 'react';
|
|
3
3
|
import { View, ScrollView, Animated, LayoutRectangle, ScrollViewComponent, ScrollResponderMixin, StyleProp, ViewStyle, NativeSyntheticEvent, NativeScrollEvent, ScrollViewProps } from 'react-native';
|
|
4
4
|
import Animated$1 from 'react-native-reanimated';
|
|
5
5
|
|
|
@@ -102,6 +102,11 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
|
|
|
102
102
|
* Extra data to trigger re-rendering when changed.
|
|
103
103
|
*/
|
|
104
104
|
extraData?: any;
|
|
105
|
+
/**
|
|
106
|
+
* Version token that forces the list to treat data as updated even when the array reference is stable.
|
|
107
|
+
* Increment or change this when mutating the data array in place.
|
|
108
|
+
*/
|
|
109
|
+
dataVersion?: Key;
|
|
105
110
|
/**
|
|
106
111
|
* In case you have distinct item sizes, you can provide a function to get the size of an item.
|
|
107
112
|
* Use instead of FlatList's getItemLayout or FlashList overrideItemLayout if you want to have accurate initialScrollOffset, you should provide this function
|
|
@@ -250,6 +255,7 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
|
|
|
250
255
|
refreshing?: boolean;
|
|
251
256
|
/**
|
|
252
257
|
* Render custom ScrollView component.
|
|
258
|
+
* Note: When using `stickyHeaderIndices`, you must provide an Animated ScrollView component.
|
|
253
259
|
* @default (props) => <ScrollView {...props} />
|
|
254
260
|
*/
|
|
255
261
|
renderScrollComponent?: (props: ScrollViewProps) => React.ReactElement<ScrollViewProps>;
|
|
@@ -312,6 +318,7 @@ interface ScrollTarget {
|
|
|
312
318
|
viewPosition?: number;
|
|
313
319
|
animated?: boolean;
|
|
314
320
|
isInitialScroll?: boolean;
|
|
321
|
+
precomputedWithViewOffset?: boolean;
|
|
315
322
|
}
|
|
316
323
|
interface InternalState {
|
|
317
324
|
positions: Map<string, number>;
|
|
@@ -339,6 +346,11 @@ interface InternalState {
|
|
|
339
346
|
scrollPrev: number;
|
|
340
347
|
scrollPrevTime: number;
|
|
341
348
|
scrollAdjustHandler: ScrollAdjustHandler;
|
|
349
|
+
triggerCalculateItemsInView?: (params?: {
|
|
350
|
+
doMVCP?: boolean;
|
|
351
|
+
dataChanged?: boolean;
|
|
352
|
+
forceFullItemPositions?: boolean;
|
|
353
|
+
}) => void;
|
|
342
354
|
maintainingScrollAtEnd?: boolean;
|
|
343
355
|
totalSize: number;
|
|
344
356
|
otherAxisSize?: number;
|
|
@@ -382,17 +394,17 @@ interface InternalState {
|
|
|
382
394
|
}>;
|
|
383
395
|
refScroller: React.RefObject<ScrollView>;
|
|
384
396
|
loadStartTime: number;
|
|
385
|
-
initialScroll:
|
|
397
|
+
initialScroll: ScrollIndexWithOffsetAndContentOffset | undefined;
|
|
386
398
|
lastLayout: LayoutRectangle | undefined;
|
|
387
399
|
timeoutSetPaddingTop?: any;
|
|
388
400
|
activeStickyIndex: number | undefined;
|
|
389
401
|
stickyContainers: Map<number, number>;
|
|
390
402
|
stickyContainerPool: Set<number>;
|
|
391
403
|
scrollProcessingEnabled: boolean;
|
|
392
|
-
isOptimizingItemPositions: boolean;
|
|
393
404
|
props: {
|
|
394
405
|
alignItemsAtEnd: boolean;
|
|
395
406
|
data: readonly any[];
|
|
407
|
+
dataVersion: Key | undefined;
|
|
396
408
|
estimatedItemSize: number | undefined;
|
|
397
409
|
getEstimatedItemSize: LegendListProps["getEstimatedItemSize"];
|
|
398
410
|
getFixedItemSize: LegendListProps["getFixedItemSize"];
|
|
@@ -443,6 +455,7 @@ type ScrollState = {
|
|
|
443
455
|
activeStickyIndex: number | undefined;
|
|
444
456
|
contentLength: number;
|
|
445
457
|
data: readonly any[];
|
|
458
|
+
elementAtIndex: (index: number) => View | null | undefined;
|
|
446
459
|
end: number;
|
|
447
460
|
endBuffered: number;
|
|
448
461
|
isAtEnd: boolean;
|
|
@@ -630,6 +643,9 @@ interface ScrollIndexWithOffset {
|
|
|
630
643
|
interface ScrollIndexWithOffsetPosition extends ScrollIndexWithOffset {
|
|
631
644
|
viewPosition: number;
|
|
632
645
|
}
|
|
646
|
+
interface ScrollIndexWithOffsetAndContentOffset extends ScrollIndexWithOffset {
|
|
647
|
+
contentOffset?: number;
|
|
648
|
+
}
|
|
633
649
|
type GetRenderedItemResult<ItemT> = {
|
|
634
650
|
index: number;
|
|
635
651
|
item: ItemT;
|
|
@@ -652,4 +668,4 @@ declare function useListScrollSize(): {
|
|
|
652
668
|
};
|
|
653
669
|
declare function useSyncLayout(): () => void;
|
|
654
670
|
|
|
655
|
-
export { type ColumnWrapperStyle, type GetRenderedItem, type GetRenderedItemResult, type InternalState, LegendList, type LegendListProps, type LegendListPropsBase, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type MaintainScrollAtEndOptions, type OnViewableItemsChanged, type ScrollIndexWithOffset, type ScrollIndexWithOffsetPosition, type ScrollState, type ScrollTarget, type ThresholdSnapshot, type TypedForwardRef, type TypedMemo, type ViewAmountToken, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange, typedForwardRef, typedMemo, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useSyncLayout, useViewability, useViewabilityAmount };
|
|
671
|
+
export { type ColumnWrapperStyle, type GetRenderedItem, type GetRenderedItemResult, type InternalState, LegendList, type LegendListProps, type LegendListPropsBase, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type MaintainScrollAtEndOptions, type OnViewableItemsChanged, type ScrollIndexWithOffset, type ScrollIndexWithOffsetAndContentOffset, type ScrollIndexWithOffsetPosition, type ScrollState, type ScrollTarget, type ThresholdSnapshot, type TypedForwardRef, type TypedMemo, type ViewAmountToken, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange, typedForwardRef, typedMemo, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useSyncLayout, useViewability, useViewabilityAmount };
|
package/index.js
CHANGED
|
@@ -313,6 +313,16 @@ function getPadding(s, type) {
|
|
|
313
313
|
function extractPadding(style, contentContainerStyle, type) {
|
|
314
314
|
return getPadding(style, type) + getPadding(contentContainerStyle, type);
|
|
315
315
|
}
|
|
316
|
+
function findContainerId(ctx, key) {
|
|
317
|
+
const numContainers = peek$(ctx, "numContainers");
|
|
318
|
+
for (let i = 0; i < numContainers; i++) {
|
|
319
|
+
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
320
|
+
if (itemKey === key) {
|
|
321
|
+
return i;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return -1;
|
|
325
|
+
}
|
|
316
326
|
|
|
317
327
|
// src/state/ContextContainer.ts
|
|
318
328
|
var ContextContainer = React3.createContext(null);
|
|
@@ -1196,26 +1206,6 @@ function calculateOffsetForIndex(ctx, state, index) {
|
|
|
1196
1206
|
return position;
|
|
1197
1207
|
}
|
|
1198
1208
|
|
|
1199
|
-
// src/core/checkActualChange.ts
|
|
1200
|
-
function checkActualChange(state, dataProp, previousData) {
|
|
1201
|
-
if (!previousData || !dataProp || dataProp.length !== previousData.length) {
|
|
1202
|
-
return true;
|
|
1203
|
-
}
|
|
1204
|
-
const {
|
|
1205
|
-
idCache,
|
|
1206
|
-
props: { keyExtractor }
|
|
1207
|
-
} = state;
|
|
1208
|
-
for (let i = 0; i < dataProp.length; i++) {
|
|
1209
|
-
if (dataProp[i] !== previousData[i]) {
|
|
1210
|
-
return true;
|
|
1211
|
-
}
|
|
1212
|
-
if (keyExtractor ? idCache[i] !== keyExtractor(previousData[i], i) : dataProp[i] !== previousData[i]) {
|
|
1213
|
-
return true;
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1216
|
-
return false;
|
|
1217
|
-
}
|
|
1218
|
-
|
|
1219
1209
|
// src/utils/setPaddingTop.ts
|
|
1220
1210
|
function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
|
|
1221
1211
|
if (stylePaddingTop !== void 0) {
|
|
@@ -1305,7 +1295,7 @@ function setSize(ctx, state, itemKey, size) {
|
|
|
1305
1295
|
}
|
|
1306
1296
|
|
|
1307
1297
|
// src/utils/getItemSize.ts
|
|
1308
|
-
function getItemSize(ctx, state, key, index, data, useAverageSize) {
|
|
1298
|
+
function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedSize) {
|
|
1309
1299
|
var _a3, _b;
|
|
1310
1300
|
const {
|
|
1311
1301
|
sizesKnown,
|
|
@@ -1320,6 +1310,12 @@ function getItemSize(ctx, state, key, index, data, useAverageSize) {
|
|
|
1320
1310
|
let size;
|
|
1321
1311
|
const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
|
|
1322
1312
|
const scrollingTo = peek$(ctx, "scrollingTo");
|
|
1313
|
+
if (preferCachedSize) {
|
|
1314
|
+
const cachedSize = sizes.get(key);
|
|
1315
|
+
if (cachedSize !== void 0) {
|
|
1316
|
+
return cachedSize;
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1323
1319
|
if (getFixedItemSize) {
|
|
1324
1320
|
size = getFixedItemSize(index, data, itemType);
|
|
1325
1321
|
if (size !== void 0) {
|
|
@@ -1529,14 +1525,13 @@ function updateScroll(ctx, state, newScroll, forceUpdate) {
|
|
|
1529
1525
|
|
|
1530
1526
|
// src/core/finishScrollTo.ts
|
|
1531
1527
|
function finishScrollTo(ctx, state) {
|
|
1532
|
-
var _a3;
|
|
1528
|
+
var _a3, _b;
|
|
1533
1529
|
if (state) {
|
|
1534
1530
|
state.scrollHistory.length = 0;
|
|
1535
1531
|
state.initialScroll = void 0;
|
|
1536
|
-
state.isOptimizingItemPositions = false;
|
|
1537
1532
|
set$(ctx, "scrollingTo", void 0);
|
|
1538
1533
|
if ((_a3 = state.props) == null ? void 0 : _a3.data) {
|
|
1539
|
-
|
|
1534
|
+
(_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
|
|
1540
1535
|
}
|
|
1541
1536
|
}
|
|
1542
1537
|
}
|
|
@@ -1545,14 +1540,14 @@ function finishScrollTo(ctx, state) {
|
|
|
1545
1540
|
function scrollTo(ctx, state, params) {
|
|
1546
1541
|
var _a3;
|
|
1547
1542
|
const { noScrollingTo, ...scrollTarget } = params;
|
|
1548
|
-
const { animated, isInitialScroll, offset: scrollTargetOffset } = scrollTarget;
|
|
1543
|
+
const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
|
|
1549
1544
|
const {
|
|
1550
1545
|
refScroller,
|
|
1551
1546
|
props: { horizontal }
|
|
1552
1547
|
} = state;
|
|
1553
|
-
let offset = calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
|
|
1548
|
+
let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
|
|
1554
1549
|
if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
|
|
1555
|
-
const maxOffset = Math.max(0,
|
|
1550
|
+
const maxOffset = Math.max(0, getContentSize(ctx) - state.scrollLength);
|
|
1556
1551
|
offset = Math.min(offset, maxOffset);
|
|
1557
1552
|
}
|
|
1558
1553
|
state.scrollHistory.length = 0;
|
|
@@ -1784,14 +1779,14 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1784
1779
|
scrollBottomBuffered: -1,
|
|
1785
1780
|
startIndex: 0
|
|
1786
1781
|
}) {
|
|
1787
|
-
var _a3, _b, _c, _d;
|
|
1782
|
+
var _a3, _b, _c, _d, _e;
|
|
1788
1783
|
const {
|
|
1789
1784
|
columns,
|
|
1790
1785
|
indexByKey,
|
|
1791
1786
|
positions,
|
|
1792
1787
|
idCache,
|
|
1793
1788
|
sizesKnown,
|
|
1794
|
-
props: { getEstimatedItemSize, snapToIndices, enableAverages }
|
|
1789
|
+
props: { getEstimatedItemSize, snapToIndices, enableAverages, maintainVisibleContentPosition }
|
|
1795
1790
|
} = state;
|
|
1796
1791
|
const data = state.props.data;
|
|
1797
1792
|
const dataLength = data.length;
|
|
@@ -1800,9 +1795,9 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1800
1795
|
const hasColumns = numColumns > 1;
|
|
1801
1796
|
const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
|
|
1802
1797
|
const shouldOptimize = !forceFullUpdate && !dataChanged && Math.abs(getScrollVelocity(state)) > 0;
|
|
1803
|
-
state.isOptimizingItemPositions = shouldOptimize;
|
|
1804
1798
|
const maxVisibleArea = scrollBottomBuffered + 1e3;
|
|
1805
1799
|
const useAverageSize = enableAverages && !getEstimatedItemSize;
|
|
1800
|
+
const preferCachedSize = maintainVisibleContentPosition && (dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0) !== 0);
|
|
1806
1801
|
let currentRowTop = 0;
|
|
1807
1802
|
let column = 1;
|
|
1808
1803
|
let maxSizeInRow = 0;
|
|
@@ -1819,8 +1814,8 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1819
1814
|
} else if (startIndex < dataLength) {
|
|
1820
1815
|
const prevIndex = startIndex - 1;
|
|
1821
1816
|
const prevId = getId(state, prevIndex);
|
|
1822
|
-
const prevPosition = (
|
|
1823
|
-
const prevSize = (
|
|
1817
|
+
const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
|
|
1818
|
+
const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, state, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
|
|
1824
1819
|
currentRowTop = prevPosition + prevSize;
|
|
1825
1820
|
}
|
|
1826
1821
|
}
|
|
@@ -1836,8 +1831,8 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1836
1831
|
const itemsPerRow = hasColumns ? numColumns : 1;
|
|
1837
1832
|
breakAt = i + itemsPerRow + 10;
|
|
1838
1833
|
}
|
|
1839
|
-
const id = (
|
|
1840
|
-
const size = (
|
|
1834
|
+
const id = (_d = idCache[i]) != null ? _d : getId(state, i);
|
|
1835
|
+
const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, state, id, i, data[i], useAverageSize, preferCachedSize);
|
|
1841
1836
|
if (IS_DEV && needsIndexByKey) {
|
|
1842
1837
|
if (indexByKeyForChecking.has(id)) {
|
|
1843
1838
|
console.error(
|
|
@@ -2055,16 +2050,6 @@ function isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize,
|
|
|
2055
2050
|
const value = ctx.mapViewabilityAmountValues.get(containerId) || computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
|
|
2056
2051
|
return value.isViewable;
|
|
2057
2052
|
}
|
|
2058
|
-
function findContainerId(ctx, key) {
|
|
2059
|
-
const numContainers = peek$(ctx, "numContainers");
|
|
2060
|
-
for (let i = 0; i < numContainers; i++) {
|
|
2061
|
-
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
2062
|
-
if (itemKey === key) {
|
|
2063
|
-
return i;
|
|
2064
|
-
}
|
|
2065
|
-
}
|
|
2066
|
-
return -1;
|
|
2067
|
-
}
|
|
2068
2053
|
function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
|
|
2069
2054
|
const key = containerId + configId;
|
|
2070
2055
|
ctx.mapViewabilityValues.set(key, viewToken);
|
|
@@ -2586,7 +2571,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2586
2571
|
for (let i = 0; i < numContainers; i++) {
|
|
2587
2572
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
2588
2573
|
if (pendingRemoval.includes(i)) {
|
|
2589
|
-
if (itemKey) {
|
|
2574
|
+
if (itemKey !== void 0) {
|
|
2590
2575
|
containerItemKeys.delete(itemKey);
|
|
2591
2576
|
}
|
|
2592
2577
|
state.containerItemTypes.delete(i);
|
|
@@ -2647,6 +2632,26 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2647
2632
|
});
|
|
2648
2633
|
}
|
|
2649
2634
|
|
|
2635
|
+
// src/core/checkActualChange.ts
|
|
2636
|
+
function checkActualChange(state, dataProp, previousData) {
|
|
2637
|
+
if (!previousData || !dataProp || dataProp.length !== previousData.length) {
|
|
2638
|
+
return true;
|
|
2639
|
+
}
|
|
2640
|
+
const {
|
|
2641
|
+
idCache,
|
|
2642
|
+
props: { keyExtractor }
|
|
2643
|
+
} = state;
|
|
2644
|
+
for (let i = 0; i < dataProp.length; i++) {
|
|
2645
|
+
if (dataProp[i] !== previousData[i]) {
|
|
2646
|
+
return true;
|
|
2647
|
+
}
|
|
2648
|
+
if (keyExtractor ? idCache[i] !== keyExtractor(previousData[i], i) : dataProp[i] !== previousData[i]) {
|
|
2649
|
+
return true;
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2652
|
+
return false;
|
|
2653
|
+
}
|
|
2654
|
+
|
|
2650
2655
|
// src/core/doMaintainScrollAtEnd.ts
|
|
2651
2656
|
function doMaintainScrollAtEnd(ctx, state, animated) {
|
|
2652
2657
|
const {
|
|
@@ -3162,6 +3167,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3162
3167
|
columnWrapperStyle,
|
|
3163
3168
|
contentContainerStyle: contentContainerStyleProp,
|
|
3164
3169
|
data: dataProp = [],
|
|
3170
|
+
dataVersion,
|
|
3165
3171
|
drawDistance = 250,
|
|
3166
3172
|
enableAverages = true,
|
|
3167
3173
|
estimatedItemSize: estimatedItemSizeProp,
|
|
@@ -3211,13 +3217,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3211
3217
|
waitForInitialLayout = true,
|
|
3212
3218
|
...rest
|
|
3213
3219
|
} = props;
|
|
3214
|
-
const [renderNum, setRenderNum] = React3.useState(0);
|
|
3215
|
-
const initialScrollProp = initialScrollAtEnd ? { index: dataProp.length - 1, viewOffset: 0 } : initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
|
|
3216
|
-
const [canRender, setCanRender] = React3__namespace.useState(!IsNewArchitecture);
|
|
3217
3220
|
const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
|
|
3218
3221
|
const style = { ...StyleSheet.flatten(styleProp) };
|
|
3219
3222
|
const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
|
|
3220
3223
|
const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
|
|
3224
|
+
const [renderNum, setRenderNum] = React3.useState(0);
|
|
3225
|
+
const initialScrollProp = initialScrollAtEnd ? { index: Math.max(0, dataProp.length - 1), viewOffset: -stylePaddingBottomState } : initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
|
|
3226
|
+
const [canRender, setCanRender] = React3__namespace.useState(!IsNewArchitecture);
|
|
3221
3227
|
const ctx = useStateContext();
|
|
3222
3228
|
ctx.columnWrapperStyle = columnWrapperStyle || (contentContainerStyle ? createColumnWrapperStyle(contentContainerStyle) : void 0);
|
|
3223
3229
|
const refScroller = React3.useRef(null);
|
|
@@ -3251,7 +3257,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3251
3257
|
isAtStart: false,
|
|
3252
3258
|
isEndReached: false,
|
|
3253
3259
|
isFirst: true,
|
|
3254
|
-
isOptimizingItemPositions: false,
|
|
3255
3260
|
isStartReached: false,
|
|
3256
3261
|
lastBatchingAction: Date.now(),
|
|
3257
3262
|
lastLayout: void 0,
|
|
@@ -3284,6 +3289,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3284
3289
|
totalSize: 0,
|
|
3285
3290
|
viewabilityConfigCallbackPairs: void 0
|
|
3286
3291
|
};
|
|
3292
|
+
const internalState = ctx.internalState;
|
|
3293
|
+
internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, internalState, params);
|
|
3287
3294
|
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
|
|
3288
3295
|
set$(ctx, "extraData", extraData);
|
|
3289
3296
|
}
|
|
@@ -3292,7 +3299,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3292
3299
|
const state = refState.current;
|
|
3293
3300
|
const isFirstLocal = state.isFirst;
|
|
3294
3301
|
state.didColumnsChange = numColumnsProp !== state.props.numColumns;
|
|
3295
|
-
const didDataChangeLocal = state.props.data !== dataProp && checkActualChange(state, dataProp, state.props.data);
|
|
3302
|
+
const didDataChangeLocal = state.props.dataVersion !== dataVersion || state.props.data !== dataProp && checkActualChange(state, dataProp, state.props.data);
|
|
3296
3303
|
if (didDataChangeLocal) {
|
|
3297
3304
|
state.dataChangeNeedsScrollUpdate = true;
|
|
3298
3305
|
state.didDataChange = true;
|
|
@@ -3302,6 +3309,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3302
3309
|
state.props = {
|
|
3303
3310
|
alignItemsAtEnd,
|
|
3304
3311
|
data: dataProp,
|
|
3312
|
+
dataVersion,
|
|
3305
3313
|
enableAverages,
|
|
3306
3314
|
estimatedItemSize,
|
|
3307
3315
|
getEstimatedItemSize,
|
|
@@ -3340,7 +3348,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3340
3348
|
{ length: Math.min(numColumnsProp, dataProp.length) },
|
|
3341
3349
|
(_, i) => getId(state, dataProp.length - 1 - i)
|
|
3342
3350
|
);
|
|
3343
|
-
}, [dataProp, numColumnsProp]);
|
|
3351
|
+
}, [dataProp, dataVersion, numColumnsProp]);
|
|
3344
3352
|
const initializeStateVars = () => {
|
|
3345
3353
|
set$(ctx, "lastItemKeys", memoizedLastItemKeys);
|
|
3346
3354
|
set$(ctx, "numColumns", numColumnsProp);
|
|
@@ -3366,17 +3374,26 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3366
3374
|
}
|
|
3367
3375
|
const initialContentOffset = React3.useMemo(() => {
|
|
3368
3376
|
const { initialScroll } = refState.current;
|
|
3369
|
-
if (initialScroll) {
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3377
|
+
if (!initialScroll) {
|
|
3378
|
+
return 0;
|
|
3379
|
+
}
|
|
3380
|
+
if (initialScroll.contentOffset !== void 0) {
|
|
3381
|
+
return initialScroll.contentOffset;
|
|
3382
|
+
}
|
|
3383
|
+
const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, state, initialScroll.index) : 0;
|
|
3384
|
+
const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, state, baseOffset, initialScroll);
|
|
3385
|
+
let clampedOffset = resolvedOffset;
|
|
3386
|
+
if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
|
|
3387
|
+
const maxOffset = Math.max(0, state.totalSize - state.scrollLength);
|
|
3388
|
+
clampedOffset = Math.min(clampedOffset, maxOffset);
|
|
3389
|
+
}
|
|
3390
|
+
clampedOffset = Math.max(0, clampedOffset);
|
|
3391
|
+
const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
|
|
3392
|
+
refState.current.initialScroll = updatedInitialScroll;
|
|
3393
|
+
state.initialScroll = updatedInitialScroll;
|
|
3394
|
+
refState.current.isStartReached = clampedOffset < refState.current.scrollLength * onStartReachedThreshold;
|
|
3395
|
+
return clampedOffset;
|
|
3396
|
+
}, [renderNum, state.initialScroll]);
|
|
3380
3397
|
if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
3381
3398
|
refState.current.lastBatchingAction = Date.now();
|
|
3382
3399
|
if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
|
|
@@ -3403,9 +3420,15 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3403
3420
|
}
|
|
3404
3421
|
}, []);
|
|
3405
3422
|
const doInitialScroll = React3.useCallback(() => {
|
|
3423
|
+
var _a4;
|
|
3406
3424
|
const initialScroll = state.initialScroll;
|
|
3407
3425
|
if (initialScroll) {
|
|
3408
|
-
scrollTo(ctx, state, {
|
|
3426
|
+
scrollTo(ctx, state, {
|
|
3427
|
+
animated: false,
|
|
3428
|
+
index: (_a4 = state.initialScroll) == null ? void 0 : _a4.index,
|
|
3429
|
+
offset: initialContentOffset,
|
|
3430
|
+
precomputedWithViewOffset: true
|
|
3431
|
+
});
|
|
3409
3432
|
}
|
|
3410
3433
|
}, [initialContentOffset, state.initialScroll]);
|
|
3411
3434
|
const onLayoutChange = React3.useCallback((layout) => {
|
|
@@ -3437,15 +3460,16 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3437
3460
|
state.didColumnsChange = false;
|
|
3438
3461
|
state.didDataChange = false;
|
|
3439
3462
|
state.isFirst = false;
|
|
3440
|
-
}, [dataProp, numColumnsProp]);
|
|
3463
|
+
}, [dataProp, dataVersion, numColumnsProp]);
|
|
3441
3464
|
React3.useLayoutEffect(() => {
|
|
3442
3465
|
set$(ctx, "extraData", extraData);
|
|
3443
3466
|
}, [extraData]);
|
|
3444
3467
|
React3.useLayoutEffect(initializeStateVars, [
|
|
3468
|
+
dataVersion,
|
|
3445
3469
|
memoizedLastItemKeys.join(","),
|
|
3446
3470
|
numColumnsProp,
|
|
3447
|
-
|
|
3448
|
-
|
|
3471
|
+
stylePaddingBottomState,
|
|
3472
|
+
stylePaddingTopState
|
|
3449
3473
|
]);
|
|
3450
3474
|
React3.useEffect(() => {
|
|
3451
3475
|
const viewability = setupViewability({
|
|
@@ -3483,6 +3507,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3483
3507
|
activeStickyIndex: state2.activeStickyIndex,
|
|
3484
3508
|
contentLength: state2.totalSize,
|
|
3485
3509
|
data: state2.props.data,
|
|
3510
|
+
elementAtIndex: (index) => {
|
|
3511
|
+
var _a4;
|
|
3512
|
+
return (_a4 = ctx.viewRefs.get(findContainerId(ctx, getId(state2, index)))) == null ? void 0 : _a4.current;
|
|
3513
|
+
},
|
|
3486
3514
|
end: state2.endNoBuffer,
|
|
3487
3515
|
endBuffered: state2.endBuffered,
|
|
3488
3516
|
isAtEnd: state2.isAtEnd,
|