@legendapp/list 2.1.0-beta.6 → 2.1.0-beta.7
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/index.d.mts +10 -0
- package/index.d.ts +10 -0
- package/index.js +85 -60
- package/index.mjs +85 -60
- package/index.native.d.mts +655 -0
- package/index.native.d.ts +655 -0
- package/index.native.js +3388 -0
- package/index.native.mjs +3360 -0
- package/package.json +2 -1
package/index.d.mts
CHANGED
|
@@ -125,6 +125,12 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
|
|
|
125
125
|
index: number;
|
|
126
126
|
viewOffset?: number | undefined;
|
|
127
127
|
};
|
|
128
|
+
/**
|
|
129
|
+
* When true, the list initializes scrolled to the last item.
|
|
130
|
+
* Overrides `initialScrollIndex` and `initialScrollOffset` when data is available.
|
|
131
|
+
* @default false
|
|
132
|
+
*/
|
|
133
|
+
initialScrollAtEnd?: boolean;
|
|
128
134
|
/**
|
|
129
135
|
* Component to render between items, receiving the leading item as prop.
|
|
130
136
|
*/
|
|
@@ -358,6 +364,10 @@ interface InternalState {
|
|
|
358
364
|
queuedInitialLayout?: boolean | undefined;
|
|
359
365
|
queuedCalculateItemsInView: number | undefined;
|
|
360
366
|
dataChangeNeedsScrollUpdate: boolean;
|
|
367
|
+
previousData?: readonly unknown[];
|
|
368
|
+
didColumnsChange?: boolean;
|
|
369
|
+
didDataChange?: boolean;
|
|
370
|
+
isFirst?: boolean;
|
|
361
371
|
lastBatchingAction: number;
|
|
362
372
|
ignoreScrollFromMVCP?: {
|
|
363
373
|
lt?: number;
|
package/index.d.ts
CHANGED
|
@@ -125,6 +125,12 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
|
|
|
125
125
|
index: number;
|
|
126
126
|
viewOffset?: number | undefined;
|
|
127
127
|
};
|
|
128
|
+
/**
|
|
129
|
+
* When true, the list initializes scrolled to the last item.
|
|
130
|
+
* Overrides `initialScrollIndex` and `initialScrollOffset` when data is available.
|
|
131
|
+
* @default false
|
|
132
|
+
*/
|
|
133
|
+
initialScrollAtEnd?: boolean;
|
|
128
134
|
/**
|
|
129
135
|
* Component to render between items, receiving the leading item as prop.
|
|
130
136
|
*/
|
|
@@ -358,6 +364,10 @@ interface InternalState {
|
|
|
358
364
|
queuedInitialLayout?: boolean | undefined;
|
|
359
365
|
queuedCalculateItemsInView: number | undefined;
|
|
360
366
|
dataChangeNeedsScrollUpdate: boolean;
|
|
367
|
+
previousData?: readonly unknown[];
|
|
368
|
+
didColumnsChange?: boolean;
|
|
369
|
+
didDataChange?: boolean;
|
|
370
|
+
isFirst?: boolean;
|
|
361
371
|
lastBatchingAction: number;
|
|
362
372
|
ignoreScrollFromMVCP?: {
|
|
363
373
|
lt?: number;
|
package/index.js
CHANGED
|
@@ -1196,6 +1196,26 @@ function calculateOffsetForIndex(ctx, state, index) {
|
|
|
1196
1196
|
return position;
|
|
1197
1197
|
}
|
|
1198
1198
|
|
|
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
|
+
|
|
1199
1219
|
// src/utils/setPaddingTop.ts
|
|
1200
1220
|
function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
|
|
1201
1221
|
if (stylePaddingTop !== void 0) {
|
|
@@ -1530,7 +1550,11 @@ function scrollTo(ctx, state, params) {
|
|
|
1530
1550
|
refScroller,
|
|
1531
1551
|
props: { horizontal }
|
|
1532
1552
|
} = state;
|
|
1533
|
-
|
|
1553
|
+
let offset = calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
|
|
1554
|
+
if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
|
|
1555
|
+
const maxOffset = Math.max(0, state.totalSize - state.scrollLength);
|
|
1556
|
+
offset = Math.min(offset, maxOffset);
|
|
1557
|
+
}
|
|
1534
1558
|
state.scrollHistory.length = 0;
|
|
1535
1559
|
if (!noScrollingTo) {
|
|
1536
1560
|
set$(ctx, "scrollingTo", scrollTarget);
|
|
@@ -2706,25 +2730,23 @@ function updateAveragesOnDataChange(state, oldData, newData) {
|
|
|
2706
2730
|
}
|
|
2707
2731
|
|
|
2708
2732
|
// src/core/checkResetContainers.ts
|
|
2709
|
-
function checkResetContainers(ctx, state,
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
}
|
|
2714
|
-
const { maintainScrollAtEnd } = state.props;
|
|
2715
|
-
if (!isFirst) {
|
|
2716
|
-
calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
|
|
2717
|
-
const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
|
|
2718
|
-
const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state, false);
|
|
2719
|
-
if (!didMaintainScrollAtEnd && dataProp.length > state.props.data.length) {
|
|
2720
|
-
state.isEndReached = false;
|
|
2721
|
-
}
|
|
2722
|
-
if (!didMaintainScrollAtEnd) {
|
|
2723
|
-
checkAtTop(state);
|
|
2724
|
-
checkAtBottom(ctx, state);
|
|
2725
|
-
}
|
|
2726
|
-
}
|
|
2733
|
+
function checkResetContainers(ctx, state, dataProp) {
|
|
2734
|
+
const { previousData } = state;
|
|
2735
|
+
if (previousData) {
|
|
2736
|
+
updateAveragesOnDataChange(state, previousData, dataProp);
|
|
2727
2737
|
}
|
|
2738
|
+
const { maintainScrollAtEnd } = state.props;
|
|
2739
|
+
calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
|
|
2740
|
+
const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
|
|
2741
|
+
const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state, false);
|
|
2742
|
+
if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
|
|
2743
|
+
state.isEndReached = false;
|
|
2744
|
+
}
|
|
2745
|
+
if (!didMaintainScrollAtEnd) {
|
|
2746
|
+
checkAtTop(state);
|
|
2747
|
+
checkAtBottom(ctx, state);
|
|
2748
|
+
}
|
|
2749
|
+
delete state.previousData;
|
|
2728
2750
|
}
|
|
2729
2751
|
|
|
2730
2752
|
// src/core/doInitialAllocateContainers.ts
|
|
@@ -3150,6 +3172,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3150
3172
|
getItemType,
|
|
3151
3173
|
horizontal,
|
|
3152
3174
|
initialContainerPoolRatio = 2,
|
|
3175
|
+
initialScrollAtEnd = false,
|
|
3153
3176
|
initialScrollIndex: initialScrollIndexProp,
|
|
3154
3177
|
initialScrollOffset: initialScrollOffsetProp,
|
|
3155
3178
|
itemsAreEqual,
|
|
@@ -3189,7 +3212,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3189
3212
|
...rest
|
|
3190
3213
|
} = props;
|
|
3191
3214
|
const [renderNum, setRenderNum] = React3.useState(0);
|
|
3192
|
-
const initialScrollProp = initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 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;
|
|
3193
3216
|
const [canRender, setCanRender] = React3__namespace.useState(!IsNewArchitecture);
|
|
3194
3217
|
const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
|
|
3195
3218
|
const style = { ...StyleSheet.flatten(styleProp) };
|
|
@@ -3213,6 +3236,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3213
3236
|
containerItemKeys: /* @__PURE__ */ new Set(),
|
|
3214
3237
|
containerItemTypes: /* @__PURE__ */ new Map(),
|
|
3215
3238
|
dataChangeNeedsScrollUpdate: false,
|
|
3239
|
+
didColumnsChange: false,
|
|
3240
|
+
didDataChange: false,
|
|
3216
3241
|
enableScrollForNextCalculateItemsInView: true,
|
|
3217
3242
|
endBuffered: -1,
|
|
3218
3243
|
endNoBuffer: -1,
|
|
@@ -3222,10 +3247,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3222
3247
|
idsInView: [],
|
|
3223
3248
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
3224
3249
|
initialScroll: initialScrollProp,
|
|
3225
|
-
isOptimizingItemPositions: false,
|
|
3226
3250
|
isAtEnd: false,
|
|
3227
3251
|
isAtStart: false,
|
|
3228
3252
|
isEndReached: false,
|
|
3253
|
+
isFirst: true,
|
|
3254
|
+
isOptimizingItemPositions: false,
|
|
3229
3255
|
isStartReached: false,
|
|
3230
3256
|
lastBatchingAction: Date.now(),
|
|
3231
3257
|
lastLayout: void 0,
|
|
@@ -3264,10 +3290,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3264
3290
|
refState.current = ctx.internalState;
|
|
3265
3291
|
}
|
|
3266
3292
|
const state = refState.current;
|
|
3267
|
-
const
|
|
3268
|
-
|
|
3269
|
-
|
|
3293
|
+
const isFirstLocal = state.isFirst;
|
|
3294
|
+
state.didColumnsChange = numColumnsProp !== state.props.numColumns;
|
|
3295
|
+
const didDataChangeLocal = state.props.data !== dataProp && checkActualChange(state, dataProp, state.props.data);
|
|
3296
|
+
if (didDataChangeLocal) {
|
|
3270
3297
|
state.dataChangeNeedsScrollUpdate = true;
|
|
3298
|
+
state.didDataChange = true;
|
|
3299
|
+
state.previousData = state.props.data;
|
|
3271
3300
|
}
|
|
3272
3301
|
const throttleScrollFn = scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp;
|
|
3273
3302
|
state.props = {
|
|
@@ -3326,7 +3355,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3326
3355
|
requestAdjust(ctx, state, paddingDiff);
|
|
3327
3356
|
}
|
|
3328
3357
|
};
|
|
3329
|
-
if (
|
|
3358
|
+
if (isFirstLocal) {
|
|
3330
3359
|
initializeStateVars();
|
|
3331
3360
|
updateItemPositions(
|
|
3332
3361
|
ctx,
|
|
@@ -3344,22 +3373,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3344
3373
|
initialContentOffset2 += calculateOffsetForIndex(ctx, state, index);
|
|
3345
3374
|
}
|
|
3346
3375
|
refState.current.isStartReached = initialContentOffset2 < refState.current.scrollLength * onStartReachedThreshold;
|
|
3347
|
-
if (initialContentOffset2 > 0) {
|
|
3348
|
-
scrollTo(ctx, state, {
|
|
3349
|
-
animated: false,
|
|
3350
|
-
index,
|
|
3351
|
-
isInitialScroll: true,
|
|
3352
|
-
offset: initialContentOffset2,
|
|
3353
|
-
viewPosition: index === dataProp.length - 1 ? 1 : 0
|
|
3354
|
-
});
|
|
3355
|
-
}
|
|
3356
3376
|
return initialContentOffset2;
|
|
3357
3377
|
}
|
|
3358
3378
|
return 0;
|
|
3359
3379
|
}, [renderNum]);
|
|
3360
|
-
if (
|
|
3380
|
+
if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
3361
3381
|
refState.current.lastBatchingAction = Date.now();
|
|
3362
|
-
if (!keyExtractorProp && !
|
|
3382
|
+
if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
|
|
3363
3383
|
IS_DEV && warnDevOnce(
|
|
3364
3384
|
"keyExtractor",
|
|
3365
3385
|
"Changing data without a keyExtractor can cause slow performance and resetting scroll. If your list data can change you should use a keyExtractor with a unique id for best performance and behavior."
|
|
@@ -3382,22 +3402,41 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3382
3402
|
}
|
|
3383
3403
|
}
|
|
3384
3404
|
}, []);
|
|
3405
|
+
const doInitialScroll = React3.useCallback(() => {
|
|
3406
|
+
const initialScroll = state.initialScroll;
|
|
3407
|
+
if (initialScroll) {
|
|
3408
|
+
scrollTo(ctx, state, { animated: false, offset: initialContentOffset, ...state.initialScroll || {} });
|
|
3409
|
+
}
|
|
3410
|
+
}, [initialContentOffset, state.initialScroll]);
|
|
3411
|
+
const onLayoutChange = React3.useCallback((layout) => {
|
|
3412
|
+
doInitialScroll();
|
|
3413
|
+
handleLayout(ctx, state, layout, setCanRender);
|
|
3414
|
+
}, []);
|
|
3415
|
+
const { onLayout } = useOnLayoutSync({
|
|
3416
|
+
onLayoutChange,
|
|
3417
|
+
onLayoutProp,
|
|
3418
|
+
ref: refScroller
|
|
3419
|
+
// the type of ScrollView doesn't include measure?
|
|
3420
|
+
});
|
|
3385
3421
|
React3.useLayoutEffect(() => {
|
|
3386
3422
|
if (snapToIndices) {
|
|
3387
3423
|
updateSnapToOffsets(ctx, state);
|
|
3388
3424
|
}
|
|
3389
3425
|
}, [snapToIndices]);
|
|
3390
3426
|
React3.useLayoutEffect(() => {
|
|
3391
|
-
const
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
);
|
|
3427
|
+
const {
|
|
3428
|
+
didColumnsChange,
|
|
3429
|
+
didDataChange,
|
|
3430
|
+
isFirst,
|
|
3431
|
+
props: { data }
|
|
3432
|
+
} = state;
|
|
3433
|
+
const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx, state);
|
|
3434
|
+
if (!didAllocateContainers && !isFirst && (didDataChange || didColumnsChange)) {
|
|
3435
|
+
checkResetContainers(ctx, state, data);
|
|
3400
3436
|
}
|
|
3437
|
+
state.didColumnsChange = false;
|
|
3438
|
+
state.didDataChange = false;
|
|
3439
|
+
state.isFirst = false;
|
|
3401
3440
|
}, [dataProp, numColumnsProp]);
|
|
3402
3441
|
React3.useLayoutEffect(() => {
|
|
3403
3442
|
set$(ctx, "extraData", extraData);
|
|
@@ -3417,15 +3456,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3417
3456
|
state.viewabilityConfigCallbackPairs = viewability;
|
|
3418
3457
|
state.enableScrollForNextCalculateItemsInView = !viewability;
|
|
3419
3458
|
}, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
|
|
3420
|
-
const onLayoutChange = React3.useCallback((layout) => {
|
|
3421
|
-
handleLayout(ctx, state, layout, setCanRender);
|
|
3422
|
-
}, []);
|
|
3423
|
-
const { onLayout } = useOnLayoutSync({
|
|
3424
|
-
onLayoutChange,
|
|
3425
|
-
onLayoutProp,
|
|
3426
|
-
ref: refScroller
|
|
3427
|
-
// the type of ScrollView doesn't include measure?
|
|
3428
|
-
});
|
|
3429
3459
|
React3.useImperativeHandle(forwardedRef, () => {
|
|
3430
3460
|
const scrollIndexIntoView = (options) => {
|
|
3431
3461
|
const state2 = refState.current;
|
|
@@ -3509,12 +3539,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3509
3539
|
};
|
|
3510
3540
|
}, []);
|
|
3511
3541
|
{
|
|
3512
|
-
React3.useEffect(
|
|
3513
|
-
const { initialScroll } = refState.current;
|
|
3514
|
-
if (initialContentOffset) {
|
|
3515
|
-
scrollTo(ctx, state, { animated: false, offset: initialContentOffset, ...initialScroll || {} });
|
|
3516
|
-
}
|
|
3517
|
-
}, []);
|
|
3542
|
+
React3.useEffect(doInitialScroll, []);
|
|
3518
3543
|
}
|
|
3519
3544
|
const fns = React3.useMemo(
|
|
3520
3545
|
() => ({
|
package/index.mjs
CHANGED
|
@@ -1175,6 +1175,26 @@ function calculateOffsetForIndex(ctx, state, index) {
|
|
|
1175
1175
|
return position;
|
|
1176
1176
|
}
|
|
1177
1177
|
|
|
1178
|
+
// src/core/checkActualChange.ts
|
|
1179
|
+
function checkActualChange(state, dataProp, previousData) {
|
|
1180
|
+
if (!previousData || !dataProp || dataProp.length !== previousData.length) {
|
|
1181
|
+
return true;
|
|
1182
|
+
}
|
|
1183
|
+
const {
|
|
1184
|
+
idCache,
|
|
1185
|
+
props: { keyExtractor }
|
|
1186
|
+
} = state;
|
|
1187
|
+
for (let i = 0; i < dataProp.length; i++) {
|
|
1188
|
+
if (dataProp[i] !== previousData[i]) {
|
|
1189
|
+
return true;
|
|
1190
|
+
}
|
|
1191
|
+
if (keyExtractor ? idCache[i] !== keyExtractor(previousData[i], i) : dataProp[i] !== previousData[i]) {
|
|
1192
|
+
return true;
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
return false;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1178
1198
|
// src/utils/setPaddingTop.ts
|
|
1179
1199
|
function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
|
|
1180
1200
|
if (stylePaddingTop !== void 0) {
|
|
@@ -1509,7 +1529,11 @@ function scrollTo(ctx, state, params) {
|
|
|
1509
1529
|
refScroller,
|
|
1510
1530
|
props: { horizontal }
|
|
1511
1531
|
} = state;
|
|
1512
|
-
|
|
1532
|
+
let offset = calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
|
|
1533
|
+
if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
|
|
1534
|
+
const maxOffset = Math.max(0, state.totalSize - state.scrollLength);
|
|
1535
|
+
offset = Math.min(offset, maxOffset);
|
|
1536
|
+
}
|
|
1513
1537
|
state.scrollHistory.length = 0;
|
|
1514
1538
|
if (!noScrollingTo) {
|
|
1515
1539
|
set$(ctx, "scrollingTo", scrollTarget);
|
|
@@ -2685,25 +2709,23 @@ function updateAveragesOnDataChange(state, oldData, newData) {
|
|
|
2685
2709
|
}
|
|
2686
2710
|
|
|
2687
2711
|
// src/core/checkResetContainers.ts
|
|
2688
|
-
function checkResetContainers(ctx, state,
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
}
|
|
2693
|
-
const { maintainScrollAtEnd } = state.props;
|
|
2694
|
-
if (!isFirst) {
|
|
2695
|
-
calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
|
|
2696
|
-
const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
|
|
2697
|
-
const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state, false);
|
|
2698
|
-
if (!didMaintainScrollAtEnd && dataProp.length > state.props.data.length) {
|
|
2699
|
-
state.isEndReached = false;
|
|
2700
|
-
}
|
|
2701
|
-
if (!didMaintainScrollAtEnd) {
|
|
2702
|
-
checkAtTop(state);
|
|
2703
|
-
checkAtBottom(ctx, state);
|
|
2704
|
-
}
|
|
2705
|
-
}
|
|
2712
|
+
function checkResetContainers(ctx, state, dataProp) {
|
|
2713
|
+
const { previousData } = state;
|
|
2714
|
+
if (previousData) {
|
|
2715
|
+
updateAveragesOnDataChange(state, previousData, dataProp);
|
|
2706
2716
|
}
|
|
2717
|
+
const { maintainScrollAtEnd } = state.props;
|
|
2718
|
+
calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
|
|
2719
|
+
const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
|
|
2720
|
+
const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state, false);
|
|
2721
|
+
if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
|
|
2722
|
+
state.isEndReached = false;
|
|
2723
|
+
}
|
|
2724
|
+
if (!didMaintainScrollAtEnd) {
|
|
2725
|
+
checkAtTop(state);
|
|
2726
|
+
checkAtBottom(ctx, state);
|
|
2727
|
+
}
|
|
2728
|
+
delete state.previousData;
|
|
2707
2729
|
}
|
|
2708
2730
|
|
|
2709
2731
|
// src/core/doInitialAllocateContainers.ts
|
|
@@ -3129,6 +3151,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3129
3151
|
getItemType,
|
|
3130
3152
|
horizontal,
|
|
3131
3153
|
initialContainerPoolRatio = 2,
|
|
3154
|
+
initialScrollAtEnd = false,
|
|
3132
3155
|
initialScrollIndex: initialScrollIndexProp,
|
|
3133
3156
|
initialScrollOffset: initialScrollOffsetProp,
|
|
3134
3157
|
itemsAreEqual,
|
|
@@ -3168,7 +3191,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3168
3191
|
...rest
|
|
3169
3192
|
} = props;
|
|
3170
3193
|
const [renderNum, setRenderNum] = useState(0);
|
|
3171
|
-
const initialScrollProp = initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
|
|
3194
|
+
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;
|
|
3172
3195
|
const [canRender, setCanRender] = React3.useState(!IsNewArchitecture);
|
|
3173
3196
|
const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
|
|
3174
3197
|
const style = { ...StyleSheet.flatten(styleProp) };
|
|
@@ -3192,6 +3215,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3192
3215
|
containerItemKeys: /* @__PURE__ */ new Set(),
|
|
3193
3216
|
containerItemTypes: /* @__PURE__ */ new Map(),
|
|
3194
3217
|
dataChangeNeedsScrollUpdate: false,
|
|
3218
|
+
didColumnsChange: false,
|
|
3219
|
+
didDataChange: false,
|
|
3195
3220
|
enableScrollForNextCalculateItemsInView: true,
|
|
3196
3221
|
endBuffered: -1,
|
|
3197
3222
|
endNoBuffer: -1,
|
|
@@ -3201,10 +3226,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3201
3226
|
idsInView: [],
|
|
3202
3227
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
3203
3228
|
initialScroll: initialScrollProp,
|
|
3204
|
-
isOptimizingItemPositions: false,
|
|
3205
3229
|
isAtEnd: false,
|
|
3206
3230
|
isAtStart: false,
|
|
3207
3231
|
isEndReached: false,
|
|
3232
|
+
isFirst: true,
|
|
3233
|
+
isOptimizingItemPositions: false,
|
|
3208
3234
|
isStartReached: false,
|
|
3209
3235
|
lastBatchingAction: Date.now(),
|
|
3210
3236
|
lastLayout: void 0,
|
|
@@ -3243,10 +3269,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3243
3269
|
refState.current = ctx.internalState;
|
|
3244
3270
|
}
|
|
3245
3271
|
const state = refState.current;
|
|
3246
|
-
const
|
|
3247
|
-
|
|
3248
|
-
|
|
3272
|
+
const isFirstLocal = state.isFirst;
|
|
3273
|
+
state.didColumnsChange = numColumnsProp !== state.props.numColumns;
|
|
3274
|
+
const didDataChangeLocal = state.props.data !== dataProp && checkActualChange(state, dataProp, state.props.data);
|
|
3275
|
+
if (didDataChangeLocal) {
|
|
3249
3276
|
state.dataChangeNeedsScrollUpdate = true;
|
|
3277
|
+
state.didDataChange = true;
|
|
3278
|
+
state.previousData = state.props.data;
|
|
3250
3279
|
}
|
|
3251
3280
|
const throttleScrollFn = scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp;
|
|
3252
3281
|
state.props = {
|
|
@@ -3305,7 +3334,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3305
3334
|
requestAdjust(ctx, state, paddingDiff);
|
|
3306
3335
|
}
|
|
3307
3336
|
};
|
|
3308
|
-
if (
|
|
3337
|
+
if (isFirstLocal) {
|
|
3309
3338
|
initializeStateVars();
|
|
3310
3339
|
updateItemPositions(
|
|
3311
3340
|
ctx,
|
|
@@ -3323,22 +3352,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3323
3352
|
initialContentOffset2 += calculateOffsetForIndex(ctx, state, index);
|
|
3324
3353
|
}
|
|
3325
3354
|
refState.current.isStartReached = initialContentOffset2 < refState.current.scrollLength * onStartReachedThreshold;
|
|
3326
|
-
if (initialContentOffset2 > 0) {
|
|
3327
|
-
scrollTo(ctx, state, {
|
|
3328
|
-
animated: false,
|
|
3329
|
-
index,
|
|
3330
|
-
isInitialScroll: true,
|
|
3331
|
-
offset: initialContentOffset2,
|
|
3332
|
-
viewPosition: index === dataProp.length - 1 ? 1 : 0
|
|
3333
|
-
});
|
|
3334
|
-
}
|
|
3335
3355
|
return initialContentOffset2;
|
|
3336
3356
|
}
|
|
3337
3357
|
return 0;
|
|
3338
3358
|
}, [renderNum]);
|
|
3339
|
-
if (
|
|
3359
|
+
if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
3340
3360
|
refState.current.lastBatchingAction = Date.now();
|
|
3341
|
-
if (!keyExtractorProp && !
|
|
3361
|
+
if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
|
|
3342
3362
|
IS_DEV && warnDevOnce(
|
|
3343
3363
|
"keyExtractor",
|
|
3344
3364
|
"Changing data without a keyExtractor can cause slow performance and resetting scroll. If your list data can change you should use a keyExtractor with a unique id for best performance and behavior."
|
|
@@ -3361,22 +3381,41 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3361
3381
|
}
|
|
3362
3382
|
}
|
|
3363
3383
|
}, []);
|
|
3384
|
+
const doInitialScroll = useCallback(() => {
|
|
3385
|
+
const initialScroll = state.initialScroll;
|
|
3386
|
+
if (initialScroll) {
|
|
3387
|
+
scrollTo(ctx, state, { animated: false, offset: initialContentOffset, ...state.initialScroll || {} });
|
|
3388
|
+
}
|
|
3389
|
+
}, [initialContentOffset, state.initialScroll]);
|
|
3390
|
+
const onLayoutChange = useCallback((layout) => {
|
|
3391
|
+
doInitialScroll();
|
|
3392
|
+
handleLayout(ctx, state, layout, setCanRender);
|
|
3393
|
+
}, []);
|
|
3394
|
+
const { onLayout } = useOnLayoutSync({
|
|
3395
|
+
onLayoutChange,
|
|
3396
|
+
onLayoutProp,
|
|
3397
|
+
ref: refScroller
|
|
3398
|
+
// the type of ScrollView doesn't include measure?
|
|
3399
|
+
});
|
|
3364
3400
|
useLayoutEffect(() => {
|
|
3365
3401
|
if (snapToIndices) {
|
|
3366
3402
|
updateSnapToOffsets(ctx, state);
|
|
3367
3403
|
}
|
|
3368
3404
|
}, [snapToIndices]);
|
|
3369
3405
|
useLayoutEffect(() => {
|
|
3370
|
-
const
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
);
|
|
3406
|
+
const {
|
|
3407
|
+
didColumnsChange,
|
|
3408
|
+
didDataChange,
|
|
3409
|
+
isFirst,
|
|
3410
|
+
props: { data }
|
|
3411
|
+
} = state;
|
|
3412
|
+
const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx, state);
|
|
3413
|
+
if (!didAllocateContainers && !isFirst && (didDataChange || didColumnsChange)) {
|
|
3414
|
+
checkResetContainers(ctx, state, data);
|
|
3379
3415
|
}
|
|
3416
|
+
state.didColumnsChange = false;
|
|
3417
|
+
state.didDataChange = false;
|
|
3418
|
+
state.isFirst = false;
|
|
3380
3419
|
}, [dataProp, numColumnsProp]);
|
|
3381
3420
|
useLayoutEffect(() => {
|
|
3382
3421
|
set$(ctx, "extraData", extraData);
|
|
@@ -3396,15 +3435,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3396
3435
|
state.viewabilityConfigCallbackPairs = viewability;
|
|
3397
3436
|
state.enableScrollForNextCalculateItemsInView = !viewability;
|
|
3398
3437
|
}, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
|
|
3399
|
-
const onLayoutChange = useCallback((layout) => {
|
|
3400
|
-
handleLayout(ctx, state, layout, setCanRender);
|
|
3401
|
-
}, []);
|
|
3402
|
-
const { onLayout } = useOnLayoutSync({
|
|
3403
|
-
onLayoutChange,
|
|
3404
|
-
onLayoutProp,
|
|
3405
|
-
ref: refScroller
|
|
3406
|
-
// the type of ScrollView doesn't include measure?
|
|
3407
|
-
});
|
|
3408
3438
|
useImperativeHandle(forwardedRef, () => {
|
|
3409
3439
|
const scrollIndexIntoView = (options) => {
|
|
3410
3440
|
const state2 = refState.current;
|
|
@@ -3488,12 +3518,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3488
3518
|
};
|
|
3489
3519
|
}, []);
|
|
3490
3520
|
{
|
|
3491
|
-
useEffect(
|
|
3492
|
-
const { initialScroll } = refState.current;
|
|
3493
|
-
if (initialContentOffset) {
|
|
3494
|
-
scrollTo(ctx, state, { animated: false, offset: initialContentOffset, ...initialScroll || {} });
|
|
3495
|
-
}
|
|
3496
|
-
}, []);
|
|
3521
|
+
useEffect(doInitialScroll, []);
|
|
3497
3522
|
}
|
|
3498
3523
|
const fns = useMemo(
|
|
3499
3524
|
() => ({
|