@legendapp/list 2.1.0-beta.1 → 2.1.0-beta.10
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 +43 -15
- package/index.d.ts +43 -15
- package/index.js +753 -614
- package/index.mjs +753 -614
- package/index.native.d.mts +671 -0
- package/index.native.d.ts +671 -0
- package/index.native.js +3417 -0
- package/index.native.mjs +3389 -0
- package/package.json +9 -4
package/index.mjs
CHANGED
|
@@ -33,7 +33,10 @@ function StateProvider({ children }) {
|
|
|
33
33
|
["stylePaddingTop", 0],
|
|
34
34
|
["headerSize", 0],
|
|
35
35
|
["numContainers", 0],
|
|
36
|
-
["
|
|
36
|
+
["activeStickyIndex", void 0],
|
|
37
|
+
["totalSize", 0],
|
|
38
|
+
["scrollAdjustPending", 0],
|
|
39
|
+
["scrollingTo", void 0]
|
|
37
40
|
]),
|
|
38
41
|
viewRefs: /* @__PURE__ */ new Map()
|
|
39
42
|
}));
|
|
@@ -187,6 +190,47 @@ var ENABLE_DEBUG_VIEW = IS_DEV && false;
|
|
|
187
190
|
var typedForwardRef = forwardRef;
|
|
188
191
|
var typedMemo = memo;
|
|
189
192
|
|
|
193
|
+
// src/utils/helpers.ts
|
|
194
|
+
function isFunction(obj) {
|
|
195
|
+
return typeof obj === "function";
|
|
196
|
+
}
|
|
197
|
+
function isArray(obj) {
|
|
198
|
+
return Array.isArray(obj);
|
|
199
|
+
}
|
|
200
|
+
var warned = /* @__PURE__ */ new Set();
|
|
201
|
+
function warnDevOnce(id, text) {
|
|
202
|
+
if (IS_DEV && !warned.has(id)) {
|
|
203
|
+
warned.add(id);
|
|
204
|
+
console.warn(`[legend-list] ${text}`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function roundSize(size) {
|
|
208
|
+
return Math.floor(size * 8) / 8;
|
|
209
|
+
}
|
|
210
|
+
function isNullOrUndefined(value) {
|
|
211
|
+
return value === null || value === void 0;
|
|
212
|
+
}
|
|
213
|
+
function comparatorDefault(a, b) {
|
|
214
|
+
return a - b;
|
|
215
|
+
}
|
|
216
|
+
function getPadding(s, type) {
|
|
217
|
+
var _a3, _b, _c;
|
|
218
|
+
return (_c = (_b = (_a3 = s[`padding${type}`]) != null ? _a3 : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
|
|
219
|
+
}
|
|
220
|
+
function extractPadding(style, contentContainerStyle, type) {
|
|
221
|
+
return getPadding(style, type) + getPadding(contentContainerStyle, type);
|
|
222
|
+
}
|
|
223
|
+
function findContainerId(ctx, key) {
|
|
224
|
+
const numContainers = peek$(ctx, "numContainers");
|
|
225
|
+
for (let i = 0; i < numContainers; i++) {
|
|
226
|
+
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
227
|
+
if (itemKey === key) {
|
|
228
|
+
return i;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return -1;
|
|
232
|
+
}
|
|
233
|
+
|
|
190
234
|
// src/components/PositionView.tsx
|
|
191
235
|
var PositionViewState = typedMemo(function PositionView({
|
|
192
236
|
id,
|
|
@@ -196,8 +240,11 @@ var PositionViewState = typedMemo(function PositionView({
|
|
|
196
240
|
...rest
|
|
197
241
|
}) {
|
|
198
242
|
const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
|
|
199
|
-
const base =
|
|
200
|
-
|
|
243
|
+
const base = {
|
|
244
|
+
contain: "paint layout style"
|
|
245
|
+
};
|
|
246
|
+
const composed = isArray(style) ? Object.assign({}, ...style) : style;
|
|
247
|
+
const combinedStyle = horizontal ? { ...base, ...composed, left: position } : { ...base, ...composed, top: position };
|
|
201
248
|
return /* @__PURE__ */ React3.createElement("div", { ref: refView, style: combinedStyle, ...rest });
|
|
202
249
|
});
|
|
203
250
|
var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
@@ -206,19 +253,42 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
|
206
253
|
style,
|
|
207
254
|
refView,
|
|
208
255
|
index,
|
|
256
|
+
stickyOffset,
|
|
257
|
+
animatedScrollY: _animatedScrollY,
|
|
258
|
+
children,
|
|
209
259
|
...rest
|
|
210
260
|
}) {
|
|
211
|
-
const [position = POSITION_OUT_OF_VIEW,
|
|
261
|
+
const [position = POSITION_OUT_OF_VIEW, headerSize = 0, activeStickyIndex] = useArr$([
|
|
262
|
+
`containerPosition${id}`,
|
|
263
|
+
"headerSize",
|
|
264
|
+
"activeStickyIndex"
|
|
265
|
+
]);
|
|
266
|
+
const base = {
|
|
267
|
+
contain: "paint layout style"
|
|
268
|
+
};
|
|
269
|
+
const composed = React3.useMemo(
|
|
270
|
+
() => {
|
|
271
|
+
var _a3;
|
|
272
|
+
return (_a3 = isArray(style) ? Object.assign({}, ...style) : style) != null ? _a3 : {};
|
|
273
|
+
},
|
|
274
|
+
[style]
|
|
275
|
+
);
|
|
212
276
|
const viewStyle = React3.useMemo(() => {
|
|
213
|
-
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
277
|
+
var _a3;
|
|
278
|
+
const styleBase = { ...base, ...composed };
|
|
279
|
+
delete styleBase.transform;
|
|
280
|
+
const offset = (_a3 = stickyOffset != null ? stickyOffset : headerSize) != null ? _a3 : 0;
|
|
281
|
+
const isActive = activeStickyIndex === index;
|
|
282
|
+
styleBase.position = isActive ? "sticky" : "absolute";
|
|
283
|
+
styleBase.zIndex = index + 1e3;
|
|
284
|
+
if (horizontal) {
|
|
285
|
+
styleBase.left = isActive ? offset : position;
|
|
286
|
+
} else {
|
|
287
|
+
styleBase.top = isActive ? offset : position;
|
|
288
|
+
}
|
|
289
|
+
return styleBase;
|
|
290
|
+
}, [composed, horizontal, position, index, stickyOffset, headerSize, activeStickyIndex]);
|
|
291
|
+
return /* @__PURE__ */ React3.createElement("div", { ref: refView, style: viewStyle, ...rest }, children);
|
|
222
292
|
});
|
|
223
293
|
var PositionView2 = PositionViewState;
|
|
224
294
|
|
|
@@ -233,37 +303,6 @@ function useInit(cb) {
|
|
|
233
303
|
return refValue.current;
|
|
234
304
|
}
|
|
235
305
|
|
|
236
|
-
// src/utils/helpers.ts
|
|
237
|
-
function isFunction(obj) {
|
|
238
|
-
return typeof obj === "function";
|
|
239
|
-
}
|
|
240
|
-
function isArray(obj) {
|
|
241
|
-
return Array.isArray(obj);
|
|
242
|
-
}
|
|
243
|
-
var warned = /* @__PURE__ */ new Set();
|
|
244
|
-
function warnDevOnce(id, text) {
|
|
245
|
-
if (IS_DEV && !warned.has(id)) {
|
|
246
|
-
warned.add(id);
|
|
247
|
-
console.warn(`[legend-list] ${text}`);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
function roundSize(size) {
|
|
251
|
-
return Math.floor(size * 8) / 8;
|
|
252
|
-
}
|
|
253
|
-
function isNullOrUndefined(value) {
|
|
254
|
-
return value === null || value === void 0;
|
|
255
|
-
}
|
|
256
|
-
function comparatorDefault(a, b) {
|
|
257
|
-
return a - b;
|
|
258
|
-
}
|
|
259
|
-
function getPadding(s, type) {
|
|
260
|
-
var _a3, _b, _c;
|
|
261
|
-
return (_c = (_b = (_a3 = s[`padding${type}`]) != null ? _a3 : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
|
|
262
|
-
}
|
|
263
|
-
function extractPadding(style, contentContainerStyle, type) {
|
|
264
|
-
return getPadding(style, type) + getPadding(contentContainerStyle, type);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
306
|
// src/state/ContextContainer.ts
|
|
268
307
|
var ContextContainer = createContext(null);
|
|
269
308
|
function useViewability(callback, configId) {
|
|
@@ -392,6 +431,10 @@ function getGlobalResizeObserver() {
|
|
|
392
431
|
}
|
|
393
432
|
var callbackMap = /* @__PURE__ */ new WeakMap();
|
|
394
433
|
function createResizeObserver(element, callback) {
|
|
434
|
+
if (typeof ResizeObserver === "undefined") {
|
|
435
|
+
return () => {
|
|
436
|
+
};
|
|
437
|
+
}
|
|
395
438
|
if (!element) {
|
|
396
439
|
return () => {
|
|
397
440
|
};
|
|
@@ -427,7 +470,7 @@ function useOnLayoutSync({
|
|
|
427
470
|
const current = ref.current;
|
|
428
471
|
const scrollableNode = (_b = (_a3 = current == null ? void 0 : current.getScrollableNode) == null ? void 0 : _a3.call(current)) != null ? _b : null;
|
|
429
472
|
const element = scrollableNode || current;
|
|
430
|
-
if (!element
|
|
473
|
+
if (!element) {
|
|
431
474
|
return;
|
|
432
475
|
}
|
|
433
476
|
const emit = (layout, fromLayoutEffect) => {
|
|
@@ -449,6 +492,9 @@ function useOnLayoutSync({
|
|
|
449
492
|
return {};
|
|
450
493
|
}
|
|
451
494
|
function toLayout(rect) {
|
|
495
|
+
if (!rect) {
|
|
496
|
+
return { height: 0, width: 0, x: 0, y: 0 };
|
|
497
|
+
}
|
|
452
498
|
return {
|
|
453
499
|
height: rect.height,
|
|
454
500
|
width: rect.width,
|
|
@@ -550,7 +596,7 @@ var Container = typedMemo(function Container2({
|
|
|
550
596
|
}
|
|
551
597
|
didLayoutRef.current = true;
|
|
552
598
|
let layout = rectangle;
|
|
553
|
-
|
|
599
|
+
roundSize(rectangle[currentHorizontal ? "width" : "height"]);
|
|
554
600
|
const doUpdate = () => {
|
|
555
601
|
itemLayoutRef.current.lastSize = { height: layout.height, width: layout.width };
|
|
556
602
|
updateItemSizeFn(currentItemKey, layout);
|
|
@@ -708,7 +754,7 @@ var ContainersInner = typedMemo(function ContainersInner2({ horizontal, numColum
|
|
|
708
754
|
const columnWrapperStyle = ctx.columnWrapperStyle;
|
|
709
755
|
const [totalSize, otherAxisSize] = useArr$(["totalSize", "otherAxisSize"]);
|
|
710
756
|
useDOMOrder(ref);
|
|
711
|
-
const style = horizontal ? { minHeight: otherAxisSize, width: totalSize } : { height: totalSize, minWidth: otherAxisSize };
|
|
757
|
+
const style = horizontal ? { minHeight: otherAxisSize, position: "relative", width: totalSize } : { height: totalSize, minWidth: otherAxisSize, position: "relative" };
|
|
712
758
|
if (columnWrapperStyle && numColumns > 1) {
|
|
713
759
|
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
714
760
|
const gapX = columnGap || gap || 0;
|
|
@@ -780,7 +826,7 @@ function DevNumbers() {
|
|
|
780
826
|
|
|
781
827
|
// src/platform/StyleSheet.tsx
|
|
782
828
|
function flattenStyles(styles) {
|
|
783
|
-
if (
|
|
829
|
+
if (isArray(styles)) {
|
|
784
830
|
return Object.assign({}, ...styles.filter(Boolean));
|
|
785
831
|
}
|
|
786
832
|
return styles;
|
|
@@ -970,10 +1016,11 @@ function PaddingDevMode() {
|
|
|
970
1016
|
function useValueListener$(key, callback) {
|
|
971
1017
|
const ctx = useStateContext();
|
|
972
1018
|
useLayoutEffect(() => {
|
|
973
|
-
listen$(ctx, key, (value) => {
|
|
1019
|
+
const unsubscribe = listen$(ctx, key, (value) => {
|
|
974
1020
|
callback(value);
|
|
975
1021
|
});
|
|
976
|
-
|
|
1022
|
+
return unsubscribe;
|
|
1023
|
+
}, [callback, ctx, key]);
|
|
977
1024
|
}
|
|
978
1025
|
|
|
979
1026
|
// src/components/ScrollAdjust.tsx
|
|
@@ -1138,13 +1185,100 @@ function calculateOffsetForIndex(ctx, state, index) {
|
|
|
1138
1185
|
return position;
|
|
1139
1186
|
}
|
|
1140
1187
|
|
|
1188
|
+
// src/utils/setPaddingTop.ts
|
|
1189
|
+
function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
|
|
1190
|
+
if (stylePaddingTop !== void 0) {
|
|
1191
|
+
const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
|
|
1192
|
+
if (stylePaddingTop < prevStylePaddingTop) {
|
|
1193
|
+
let prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
1194
|
+
set$(ctx, "totalSize", prevTotalSize + prevStylePaddingTop);
|
|
1195
|
+
state.timeoutSetPaddingTop = setTimeout(() => {
|
|
1196
|
+
prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
1197
|
+
set$(ctx, "totalSize", prevTotalSize - prevStylePaddingTop);
|
|
1198
|
+
}, 16);
|
|
1199
|
+
}
|
|
1200
|
+
set$(ctx, "stylePaddingTop", stylePaddingTop);
|
|
1201
|
+
}
|
|
1202
|
+
if (alignItemsPaddingTop !== void 0) {
|
|
1203
|
+
set$(ctx, "alignItemsPaddingTop", alignItemsPaddingTop);
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
// src/utils/updateAlignItemsPaddingTop.ts
|
|
1208
|
+
function updateAlignItemsPaddingTop(ctx, state) {
|
|
1209
|
+
const {
|
|
1210
|
+
scrollLength,
|
|
1211
|
+
props: { alignItemsAtEnd, data }
|
|
1212
|
+
} = state;
|
|
1213
|
+
if (alignItemsAtEnd) {
|
|
1214
|
+
let alignItemsPaddingTop = 0;
|
|
1215
|
+
if ((data == null ? void 0 : data.length) > 0) {
|
|
1216
|
+
const contentSize = getContentSize(ctx);
|
|
1217
|
+
alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
|
|
1218
|
+
}
|
|
1219
|
+
setPaddingTop(ctx, state, { alignItemsPaddingTop });
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
// src/core/updateTotalSize.ts
|
|
1224
|
+
function updateTotalSize(ctx, state) {
|
|
1225
|
+
const {
|
|
1226
|
+
positions,
|
|
1227
|
+
props: { data }
|
|
1228
|
+
} = state;
|
|
1229
|
+
if (data.length === 0) {
|
|
1230
|
+
addTotalSize(ctx, state, null, 0);
|
|
1231
|
+
} else {
|
|
1232
|
+
const lastId = getId(state, data.length - 1);
|
|
1233
|
+
if (lastId !== void 0) {
|
|
1234
|
+
const lastPosition = positions.get(lastId);
|
|
1235
|
+
if (lastPosition !== void 0) {
|
|
1236
|
+
const lastSize = getItemSize(ctx, state, lastId, data.length - 1, data[data.length - 1]);
|
|
1237
|
+
if (lastSize !== void 0) {
|
|
1238
|
+
const totalSize = lastPosition + lastSize;
|
|
1239
|
+
addTotalSize(ctx, state, null, totalSize);
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
function addTotalSize(ctx, state, key, add) {
|
|
1246
|
+
const { alignItemsAtEnd } = state.props;
|
|
1247
|
+
const prevTotalSize = state.totalSize;
|
|
1248
|
+
if (key === null) {
|
|
1249
|
+
state.totalSize = add;
|
|
1250
|
+
if (state.timeoutSetPaddingTop) {
|
|
1251
|
+
clearTimeout(state.timeoutSetPaddingTop);
|
|
1252
|
+
state.timeoutSetPaddingTop = void 0;
|
|
1253
|
+
}
|
|
1254
|
+
} else {
|
|
1255
|
+
state.totalSize += add;
|
|
1256
|
+
}
|
|
1257
|
+
if (prevTotalSize !== state.totalSize) {
|
|
1258
|
+
set$(ctx, "totalSize", state.totalSize);
|
|
1259
|
+
if (alignItemsAtEnd) {
|
|
1260
|
+
updateAlignItemsPaddingTop(ctx, state);
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
// src/core/setSize.ts
|
|
1266
|
+
function setSize(ctx, state, itemKey, size) {
|
|
1267
|
+
const { sizes } = state;
|
|
1268
|
+
const previousSize = sizes.get(itemKey);
|
|
1269
|
+
const diff = previousSize !== void 0 ? size - previousSize : size;
|
|
1270
|
+
if (diff !== 0) {
|
|
1271
|
+
addTotalSize(ctx, state, itemKey, diff);
|
|
1272
|
+
}
|
|
1273
|
+
sizes.set(itemKey, size);
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1141
1276
|
// src/utils/getItemSize.ts
|
|
1142
|
-
function getItemSize(state, key, index, data, useAverageSize) {
|
|
1277
|
+
function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedSize) {
|
|
1143
1278
|
var _a3, _b;
|
|
1144
1279
|
const {
|
|
1145
1280
|
sizesKnown,
|
|
1146
1281
|
sizes,
|
|
1147
|
-
scrollingTo,
|
|
1148
1282
|
averageSizes,
|
|
1149
1283
|
props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
|
|
1150
1284
|
} = state;
|
|
@@ -1154,6 +1288,13 @@ function getItemSize(state, key, index, data, useAverageSize) {
|
|
|
1154
1288
|
}
|
|
1155
1289
|
let size;
|
|
1156
1290
|
const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
|
|
1291
|
+
const scrollingTo = peek$(ctx, "scrollingTo");
|
|
1292
|
+
if (preferCachedSize) {
|
|
1293
|
+
const cachedSize = sizes.get(key);
|
|
1294
|
+
if (cachedSize !== void 0) {
|
|
1295
|
+
return cachedSize;
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1157
1298
|
if (getFixedItemSize) {
|
|
1158
1299
|
size = getFixedItemSize(index, data, itemType);
|
|
1159
1300
|
if (size !== void 0) {
|
|
@@ -1175,56 +1316,235 @@ function getItemSize(state, key, index, data, useAverageSize) {
|
|
|
1175
1316
|
if (size === void 0) {
|
|
1176
1317
|
size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
|
|
1177
1318
|
}
|
|
1178
|
-
|
|
1319
|
+
setSize(ctx, state, key, size);
|
|
1179
1320
|
return size;
|
|
1180
1321
|
}
|
|
1181
1322
|
|
|
1182
1323
|
// src/core/calculateOffsetWithOffsetPosition.ts
|
|
1183
|
-
function calculateOffsetWithOffsetPosition(state, offsetParam, params) {
|
|
1324
|
+
function calculateOffsetWithOffsetPosition(ctx, state, offsetParam, params) {
|
|
1184
1325
|
const { index, viewOffset, viewPosition } = params;
|
|
1185
1326
|
let offset = offsetParam;
|
|
1186
1327
|
if (viewOffset) {
|
|
1187
1328
|
offset -= viewOffset;
|
|
1188
1329
|
}
|
|
1189
1330
|
if (viewPosition !== void 0 && index !== void 0) {
|
|
1190
|
-
offset -= viewPosition * (state.scrollLength - getItemSize(state, getId(state, index), index, state.props.data[index]));
|
|
1331
|
+
offset -= viewPosition * (state.scrollLength - getItemSize(ctx, state, getId(state, index), index, state.props.data[index]));
|
|
1191
1332
|
}
|
|
1192
1333
|
return offset;
|
|
1193
1334
|
}
|
|
1194
1335
|
|
|
1195
|
-
// src/
|
|
1196
|
-
var
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1336
|
+
// src/utils/checkThreshold.ts
|
|
1337
|
+
var HYSTERESIS_MULTIPLIER = 1.3;
|
|
1338
|
+
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
|
|
1339
|
+
const absDistance = Math.abs(distance);
|
|
1340
|
+
const within = atThreshold || threshold > 0 && absDistance <= threshold;
|
|
1341
|
+
const updateSnapshot = () => {
|
|
1342
|
+
setSnapshot == null ? void 0 : setSnapshot({
|
|
1343
|
+
atThreshold,
|
|
1344
|
+
contentSize: context.contentSize,
|
|
1345
|
+
dataLength: context.dataLength,
|
|
1346
|
+
scrollPosition: context.scrollPosition
|
|
1347
|
+
});
|
|
1348
|
+
};
|
|
1349
|
+
if (!wasReached) {
|
|
1350
|
+
if (!within) {
|
|
1351
|
+
return false;
|
|
1352
|
+
}
|
|
1353
|
+
onReached == null ? void 0 : onReached(distance);
|
|
1354
|
+
updateSnapshot();
|
|
1355
|
+
return true;
|
|
1356
|
+
}
|
|
1357
|
+
const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
|
|
1358
|
+
if (reset) {
|
|
1359
|
+
setSnapshot == null ? void 0 : setSnapshot(void 0);
|
|
1360
|
+
return false;
|
|
1361
|
+
}
|
|
1362
|
+
if (within) {
|
|
1363
|
+
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
1364
|
+
if (changed) {
|
|
1365
|
+
onReached == null ? void 0 : onReached(distance);
|
|
1366
|
+
updateSnapshot();
|
|
1367
|
+
}
|
|
1200
1368
|
}
|
|
1369
|
+
return true;
|
|
1201
1370
|
};
|
|
1202
1371
|
|
|
1203
|
-
// src/
|
|
1204
|
-
function
|
|
1372
|
+
// src/utils/checkAtBottom.ts
|
|
1373
|
+
function checkAtBottom(ctx, state) {
|
|
1205
1374
|
var _a3;
|
|
1206
|
-
|
|
1375
|
+
if (!state) {
|
|
1376
|
+
return;
|
|
1377
|
+
}
|
|
1207
1378
|
const {
|
|
1208
|
-
|
|
1209
|
-
|
|
1379
|
+
queuedInitialLayout,
|
|
1380
|
+
scrollLength,
|
|
1381
|
+
scroll,
|
|
1382
|
+
maintainingScrollAtEnd,
|
|
1383
|
+
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
1210
1384
|
} = state;
|
|
1211
|
-
const
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1385
|
+
const contentSize = getContentSize(ctx);
|
|
1386
|
+
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1387
|
+
const distanceFromEnd = contentSize - scroll - scrollLength;
|
|
1388
|
+
const isContentLess = contentSize < scrollLength;
|
|
1389
|
+
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
1390
|
+
state.isEndReached = checkThreshold(
|
|
1391
|
+
distanceFromEnd,
|
|
1392
|
+
isContentLess,
|
|
1393
|
+
onEndReachedThreshold * scrollLength,
|
|
1394
|
+
state.isEndReached,
|
|
1395
|
+
state.endReachedSnapshot,
|
|
1396
|
+
{
|
|
1397
|
+
contentSize,
|
|
1398
|
+
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1399
|
+
scrollPosition: scroll
|
|
1400
|
+
},
|
|
1401
|
+
(distance) => {
|
|
1402
|
+
var _a4, _b;
|
|
1403
|
+
return (_b = (_a4 = state.props).onEndReached) == null ? void 0 : _b.call(_a4, { distanceFromEnd: distance });
|
|
1404
|
+
},
|
|
1405
|
+
(snapshot) => {
|
|
1406
|
+
state.endReachedSnapshot = snapshot;
|
|
1407
|
+
}
|
|
1408
|
+
);
|
|
1223
1409
|
}
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
// src/utils/checkAtTop.ts
|
|
1413
|
+
function checkAtTop(state) {
|
|
1414
|
+
var _a3;
|
|
1415
|
+
if (!state) {
|
|
1416
|
+
return;
|
|
1417
|
+
}
|
|
1418
|
+
const {
|
|
1419
|
+
scrollLength,
|
|
1420
|
+
scroll,
|
|
1421
|
+
props: { onStartReachedThreshold }
|
|
1422
|
+
} = state;
|
|
1423
|
+
const distanceFromTop = scroll;
|
|
1424
|
+
state.isAtStart = distanceFromTop <= 0;
|
|
1425
|
+
state.isStartReached = checkThreshold(
|
|
1426
|
+
distanceFromTop,
|
|
1427
|
+
false,
|
|
1428
|
+
onStartReachedThreshold * scrollLength,
|
|
1429
|
+
state.isStartReached,
|
|
1430
|
+
state.startReachedSnapshot,
|
|
1431
|
+
{
|
|
1432
|
+
contentSize: state.totalSize,
|
|
1433
|
+
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1434
|
+
scrollPosition: scroll
|
|
1435
|
+
},
|
|
1436
|
+
(distance) => {
|
|
1437
|
+
var _a4, _b;
|
|
1438
|
+
return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
|
|
1439
|
+
},
|
|
1440
|
+
(snapshot) => {
|
|
1441
|
+
state.startReachedSnapshot = snapshot;
|
|
1442
|
+
}
|
|
1443
|
+
);
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
// src/core/onScroll.ts
|
|
1447
|
+
function onScroll(ctx, state, event) {
|
|
1448
|
+
var _a3, _b, _c;
|
|
1449
|
+
const {
|
|
1450
|
+
scrollProcessingEnabled,
|
|
1451
|
+
props: { onScroll: onScrollProp }
|
|
1452
|
+
} = state;
|
|
1453
|
+
if (scrollProcessingEnabled === false) {
|
|
1454
|
+
return;
|
|
1455
|
+
}
|
|
1456
|
+
if (((_b = (_a3 = event.nativeEvent) == null ? void 0 : _a3.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
|
|
1457
|
+
return;
|
|
1458
|
+
}
|
|
1459
|
+
const newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
|
|
1460
|
+
state.scrollPending = newScroll;
|
|
1461
|
+
updateScroll(ctx, state, newScroll);
|
|
1462
|
+
onScrollProp == null ? void 0 : onScrollProp(event);
|
|
1463
|
+
}
|
|
1464
|
+
function updateScroll(ctx, state, newScroll, forceUpdate) {
|
|
1465
|
+
const scrollingTo = peek$(ctx, "scrollingTo");
|
|
1466
|
+
state.hasScrolled = true;
|
|
1467
|
+
state.lastBatchingAction = Date.now();
|
|
1468
|
+
const currentTime = Date.now();
|
|
1469
|
+
const adjust = state.scrollAdjustHandler.getAdjust();
|
|
1470
|
+
const lastHistoryAdjust = state.lastScrollAdjustForHistory;
|
|
1471
|
+
const adjustChanged = lastHistoryAdjust !== void 0 && Math.abs(adjust - lastHistoryAdjust) > 0.1;
|
|
1472
|
+
if (adjustChanged) {
|
|
1473
|
+
state.scrollHistory.length = 0;
|
|
1474
|
+
}
|
|
1475
|
+
state.lastScrollAdjustForHistory = adjust;
|
|
1476
|
+
if (scrollingTo === void 0 && !(state.scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
1477
|
+
if (!adjustChanged) {
|
|
1478
|
+
state.scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
if (state.scrollHistory.length > 5) {
|
|
1482
|
+
state.scrollHistory.shift();
|
|
1483
|
+
}
|
|
1484
|
+
state.scrollPrev = state.scroll;
|
|
1485
|
+
state.scrollPrevTime = state.scrollTime;
|
|
1486
|
+
state.scroll = newScroll;
|
|
1487
|
+
state.scrollTime = currentTime;
|
|
1488
|
+
const ignoreScrollFromMVCP = state.ignoreScrollFromMVCP;
|
|
1489
|
+
if (ignoreScrollFromMVCP && !scrollingTo) {
|
|
1490
|
+
const { lt, gt } = ignoreScrollFromMVCP;
|
|
1491
|
+
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
1492
|
+
state.ignoreScrollFromMVCPIgnored = true;
|
|
1493
|
+
return;
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
if (state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollPrev) > 2) {
|
|
1497
|
+
state.ignoreScrollFromMVCPIgnored = false;
|
|
1498
|
+
calculateItemsInView(ctx, state, { doMVCP: scrollingTo !== void 0 });
|
|
1499
|
+
checkAtBottom(ctx, state);
|
|
1500
|
+
checkAtTop(state);
|
|
1501
|
+
state.dataChangeNeedsScrollUpdate = false;
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
// src/core/finishScrollTo.ts
|
|
1506
|
+
function finishScrollTo(ctx, state) {
|
|
1507
|
+
var _a3, _b;
|
|
1508
|
+
if (state) {
|
|
1509
|
+
state.scrollHistory.length = 0;
|
|
1510
|
+
state.initialScroll = void 0;
|
|
1511
|
+
set$(ctx, "scrollingTo", void 0);
|
|
1512
|
+
if ((_a3 = state.props) == null ? void 0 : _a3.data) {
|
|
1513
|
+
(_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
// src/core/scrollTo.ts
|
|
1519
|
+
function scrollTo(ctx, state, params) {
|
|
1520
|
+
var _a3;
|
|
1521
|
+
const { noScrollingTo, ...scrollTarget } = params;
|
|
1522
|
+
const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
|
|
1523
|
+
const {
|
|
1524
|
+
refScroller,
|
|
1525
|
+
props: { horizontal }
|
|
1526
|
+
} = state;
|
|
1527
|
+
let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
|
|
1528
|
+
if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
|
|
1529
|
+
const maxOffset = Math.max(0, getContentSize(ctx) - state.scrollLength);
|
|
1530
|
+
offset = Math.min(offset, maxOffset);
|
|
1531
|
+
}
|
|
1532
|
+
state.scrollHistory.length = 0;
|
|
1533
|
+
if (!noScrollingTo) {
|
|
1534
|
+
set$(ctx, "scrollingTo", scrollTarget);
|
|
1535
|
+
}
|
|
1536
|
+
state.scrollPending = offset;
|
|
1537
|
+
if (!isInitialScroll || Platform.OS === "android") {
|
|
1538
|
+
(_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
|
|
1539
|
+
animated: !!animated,
|
|
1540
|
+
x: horizontal ? offset : 0,
|
|
1541
|
+
y: horizontal ? 0 : offset
|
|
1542
|
+
});
|
|
1543
|
+
}
|
|
1544
|
+
if (!animated) {
|
|
1545
|
+
state.scroll = offset;
|
|
1546
|
+
setTimeout(() => finishScrollTo(ctx, state), 100);
|
|
1547
|
+
if (isInitialScroll) {
|
|
1228
1548
|
setTimeout(() => {
|
|
1229
1549
|
state.initialScroll = void 0;
|
|
1230
1550
|
}, 500);
|
|
@@ -1245,24 +1565,6 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
|
|
|
1245
1565
|
const didLayout = peek$(ctx, "containersDidLayout");
|
|
1246
1566
|
if (didLayout) {
|
|
1247
1567
|
doit();
|
|
1248
|
-
const threshold = state.scroll - positionDiff / 2;
|
|
1249
|
-
if (!state.ignoreScrollFromMVCP) {
|
|
1250
|
-
state.ignoreScrollFromMVCP = {};
|
|
1251
|
-
}
|
|
1252
|
-
if (positionDiff > 0) {
|
|
1253
|
-
state.ignoreScrollFromMVCP.lt = threshold;
|
|
1254
|
-
} else {
|
|
1255
|
-
state.ignoreScrollFromMVCP.gt = threshold;
|
|
1256
|
-
}
|
|
1257
|
-
if (state.ignoreScrollFromMVCPTimeout) {
|
|
1258
|
-
clearTimeout(state.ignoreScrollFromMVCPTimeout);
|
|
1259
|
-
}
|
|
1260
|
-
state.ignoreScrollFromMVCPTimeout = setTimeout(
|
|
1261
|
-
() => {
|
|
1262
|
-
state.ignoreScrollFromMVCP = void 0;
|
|
1263
|
-
},
|
|
1264
|
-
100
|
|
1265
|
-
);
|
|
1266
1568
|
} else {
|
|
1267
1569
|
requestAnimationFrame(doit);
|
|
1268
1570
|
}
|
|
@@ -1274,9 +1576,9 @@ function prepareMVCP(ctx, state, dataChanged) {
|
|
|
1274
1576
|
const {
|
|
1275
1577
|
idsInView,
|
|
1276
1578
|
positions,
|
|
1277
|
-
scrollingTo,
|
|
1278
1579
|
props: { maintainVisibleContentPosition }
|
|
1279
1580
|
} = state;
|
|
1581
|
+
const scrollingTo = peek$(ctx, "scrollingTo");
|
|
1280
1582
|
let prevPosition;
|
|
1281
1583
|
let targetId;
|
|
1282
1584
|
const idsInViewWithPositions = [];
|
|
@@ -1352,7 +1654,7 @@ function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
|
|
|
1352
1654
|
const prevId = state.idCache[prevIndex];
|
|
1353
1655
|
const prevPosition = (_a3 = state.positions.get(prevId)) != null ? _a3 : 0;
|
|
1354
1656
|
const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
|
|
1355
|
-
const prevRowHeight = calculateRowMaxSize(state, prevRowStart, prevIndex, useAverageSize);
|
|
1657
|
+
const prevRowHeight = calculateRowMaxSize(ctx, state, prevRowStart, prevIndex, useAverageSize);
|
|
1356
1658
|
currentRowTop = prevPosition + prevRowHeight;
|
|
1357
1659
|
}
|
|
1358
1660
|
return {
|
|
@@ -1375,7 +1677,7 @@ function findRowStartIndex(state, numColumns, index) {
|
|
|
1375
1677
|
}
|
|
1376
1678
|
return rowStart;
|
|
1377
1679
|
}
|
|
1378
|
-
function calculateRowMaxSize(state, startIndex, endIndex, useAverageSize) {
|
|
1680
|
+
function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
|
|
1379
1681
|
if (endIndex < startIndex) {
|
|
1380
1682
|
return 0;
|
|
1381
1683
|
}
|
|
@@ -1389,7 +1691,7 @@ function calculateRowMaxSize(state, startIndex, endIndex, useAverageSize) {
|
|
|
1389
1691
|
continue;
|
|
1390
1692
|
}
|
|
1391
1693
|
const id = state.idCache[i];
|
|
1392
|
-
const size = getItemSize(state, id, i, data[i], useAverageSize);
|
|
1694
|
+
const size = getItemSize(ctx, state, id, i, data[i], useAverageSize);
|
|
1393
1695
|
if (size > maxSize) {
|
|
1394
1696
|
maxSize = size;
|
|
1395
1697
|
}
|
|
@@ -1397,82 +1699,43 @@ function calculateRowMaxSize(state, startIndex, endIndex, useAverageSize) {
|
|
|
1397
1699
|
return maxSize;
|
|
1398
1700
|
}
|
|
1399
1701
|
|
|
1400
|
-
// src/utils/
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
// src/utils/updateAlignItemsPaddingTop.ts
|
|
1420
|
-
function updateAlignItemsPaddingTop(ctx, state) {
|
|
1421
|
-
const {
|
|
1422
|
-
scrollLength,
|
|
1423
|
-
props: { alignItemsAtEnd, data }
|
|
1424
|
-
} = state;
|
|
1425
|
-
if (alignItemsAtEnd) {
|
|
1426
|
-
let alignItemsPaddingTop = 0;
|
|
1427
|
-
if ((data == null ? void 0 : data.length) > 0) {
|
|
1428
|
-
const contentSize = getContentSize(ctx);
|
|
1429
|
-
alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
|
|
1430
|
-
}
|
|
1431
|
-
setPaddingTop(ctx, state, { alignItemsPaddingTop });
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
|
-
|
|
1435
|
-
// src/core/updateTotalSize.ts
|
|
1436
|
-
function updateTotalSize(ctx, state) {
|
|
1437
|
-
const {
|
|
1438
|
-
positions,
|
|
1439
|
-
props: { data }
|
|
1440
|
-
} = state;
|
|
1441
|
-
if (data.length === 0) {
|
|
1442
|
-
addTotalSize(ctx, state, null, 0);
|
|
1443
|
-
} else {
|
|
1444
|
-
const lastId = getId(state, data.length - 1);
|
|
1445
|
-
if (lastId !== void 0) {
|
|
1446
|
-
const lastPosition = positions.get(lastId);
|
|
1447
|
-
if (lastPosition !== void 0) {
|
|
1448
|
-
const lastSize = getItemSize(state, lastId, data.length - 1, data[data.length - 1]);
|
|
1449
|
-
if (lastSize !== void 0) {
|
|
1450
|
-
const totalSize = lastPosition + lastSize;
|
|
1451
|
-
addTotalSize(ctx, state, null, totalSize);
|
|
1702
|
+
// src/utils/getScrollVelocity.ts
|
|
1703
|
+
var getScrollVelocity = (state) => {
|
|
1704
|
+
const { scrollHistory } = state;
|
|
1705
|
+
let velocity = 0;
|
|
1706
|
+
if (scrollHistory.length >= 1) {
|
|
1707
|
+
const newest = scrollHistory[scrollHistory.length - 1];
|
|
1708
|
+
let oldest;
|
|
1709
|
+
let start = 0;
|
|
1710
|
+
const now = Date.now();
|
|
1711
|
+
for (let i = 0; i < scrollHistory.length - 1; i++) {
|
|
1712
|
+
const entry = scrollHistory[i];
|
|
1713
|
+
const nextEntry = scrollHistory[i + 1];
|
|
1714
|
+
if (i > 0) {
|
|
1715
|
+
const prevEntry = scrollHistory[i - 1];
|
|
1716
|
+
const prevDirection = entry.scroll - prevEntry.scroll;
|
|
1717
|
+
const currentDirection = nextEntry.scroll - entry.scroll;
|
|
1718
|
+
if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
|
|
1719
|
+
start = i;
|
|
1720
|
+
break;
|
|
1452
1721
|
}
|
|
1453
1722
|
}
|
|
1454
1723
|
}
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
state.totalSize = add;
|
|
1462
|
-
if (state.timeoutSetPaddingTop) {
|
|
1463
|
-
clearTimeout(state.timeoutSetPaddingTop);
|
|
1464
|
-
state.timeoutSetPaddingTop = void 0;
|
|
1724
|
+
for (let i = start; i < scrollHistory.length - 1; i++) {
|
|
1725
|
+
const entry = scrollHistory[i];
|
|
1726
|
+
if (now - entry.time <= 1e3) {
|
|
1727
|
+
oldest = entry;
|
|
1728
|
+
break;
|
|
1729
|
+
}
|
|
1465
1730
|
}
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
set$(ctx, "totalSize", state.totalSize);
|
|
1471
|
-
if (alignItemsAtEnd) {
|
|
1472
|
-
updateAlignItemsPaddingTop(ctx, state);
|
|
1731
|
+
if (oldest && oldest !== newest) {
|
|
1732
|
+
const scrollDiff = newest.scroll - oldest.scroll;
|
|
1733
|
+
const timeDiff = newest.time - oldest.time;
|
|
1734
|
+
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
1473
1735
|
}
|
|
1474
1736
|
}
|
|
1475
|
-
|
|
1737
|
+
return velocity;
|
|
1738
|
+
};
|
|
1476
1739
|
|
|
1477
1740
|
// src/utils/updateSnapToOffsets.ts
|
|
1478
1741
|
function updateSnapToOffsets(ctx, state) {
|
|
@@ -1490,23 +1753,30 @@ function updateSnapToOffsets(ctx, state) {
|
|
|
1490
1753
|
}
|
|
1491
1754
|
|
|
1492
1755
|
// src/core/updateItemPositions.ts
|
|
1493
|
-
function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottomBuffered
|
|
1494
|
-
|
|
1756
|
+
function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false } = {
|
|
1757
|
+
forceFullUpdate: false,
|
|
1758
|
+
scrollBottomBuffered: -1,
|
|
1759
|
+
startIndex: 0
|
|
1760
|
+
}) {
|
|
1761
|
+
var _a3, _b, _c, _d, _e;
|
|
1495
1762
|
const {
|
|
1496
1763
|
columns,
|
|
1497
1764
|
indexByKey,
|
|
1498
1765
|
positions,
|
|
1499
1766
|
idCache,
|
|
1500
1767
|
sizesKnown,
|
|
1501
|
-
props: { getEstimatedItemSize, snapToIndices, enableAverages }
|
|
1768
|
+
props: { getEstimatedItemSize, snapToIndices, enableAverages, maintainVisibleContentPosition }
|
|
1502
1769
|
} = state;
|
|
1503
1770
|
const data = state.props.data;
|
|
1504
1771
|
const dataLength = data.length;
|
|
1505
1772
|
const numColumns = peek$(ctx, "numColumns");
|
|
1773
|
+
const scrollingTo = peek$(ctx, "scrollingTo");
|
|
1506
1774
|
const hasColumns = numColumns > 1;
|
|
1507
1775
|
const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
|
|
1776
|
+
const shouldOptimize = !forceFullUpdate && !dataChanged && Math.abs(getScrollVelocity(state)) > 0;
|
|
1508
1777
|
const maxVisibleArea = scrollBottomBuffered + 1e3;
|
|
1509
1778
|
const useAverageSize = enableAverages && !getEstimatedItemSize;
|
|
1779
|
+
const preferCachedSize = maintainVisibleContentPosition && (dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0) !== 0);
|
|
1510
1780
|
let currentRowTop = 0;
|
|
1511
1781
|
let column = 1;
|
|
1512
1782
|
let maxSizeInRow = 0;
|
|
@@ -1523,8 +1793,8 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1523
1793
|
} else if (startIndex < dataLength) {
|
|
1524
1794
|
const prevIndex = startIndex - 1;
|
|
1525
1795
|
const prevId = getId(state, prevIndex);
|
|
1526
|
-
const prevPosition = (
|
|
1527
|
-
const prevSize = (
|
|
1796
|
+
const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
|
|
1797
|
+
const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, state, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
|
|
1528
1798
|
currentRowTop = prevPosition + prevSize;
|
|
1529
1799
|
}
|
|
1530
1800
|
}
|
|
@@ -1532,16 +1802,16 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1532
1802
|
let didBreakEarly = false;
|
|
1533
1803
|
let breakAt;
|
|
1534
1804
|
for (let i = startIndex; i < dataLength; i++) {
|
|
1535
|
-
if (breakAt && i > breakAt) {
|
|
1805
|
+
if (shouldOptimize && breakAt !== void 0 && i > breakAt) {
|
|
1536
1806
|
didBreakEarly = true;
|
|
1537
1807
|
break;
|
|
1538
1808
|
}
|
|
1539
|
-
if (breakAt === void 0 && !dataChanged && currentRowTop > maxVisibleArea) {
|
|
1809
|
+
if (shouldOptimize && breakAt === void 0 && !scrollingTo && !dataChanged && currentRowTop > maxVisibleArea) {
|
|
1540
1810
|
const itemsPerRow = hasColumns ? numColumns : 1;
|
|
1541
1811
|
breakAt = i + itemsPerRow + 10;
|
|
1542
1812
|
}
|
|
1543
|
-
const id = (
|
|
1544
|
-
const size = (
|
|
1813
|
+
const id = (_d = idCache[i]) != null ? _d : getId(state, i);
|
|
1814
|
+
const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, state, id, i, data[i], useAverageSize, preferCachedSize);
|
|
1545
1815
|
if (IS_DEV && needsIndexByKey) {
|
|
1546
1816
|
if (indexByKeyForChecking.has(id)) {
|
|
1547
1817
|
console.error(
|
|
@@ -1759,16 +2029,6 @@ function isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize,
|
|
|
1759
2029
|
const value = ctx.mapViewabilityAmountValues.get(containerId) || computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
|
|
1760
2030
|
return value.isViewable;
|
|
1761
2031
|
}
|
|
1762
|
-
function findContainerId(ctx, key) {
|
|
1763
|
-
const numContainers = peek$(ctx, "numContainers");
|
|
1764
|
-
for (let i = 0; i < numContainers; i++) {
|
|
1765
|
-
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1766
|
-
if (itemKey === key) {
|
|
1767
|
-
return i;
|
|
1768
|
-
}
|
|
1769
|
-
}
|
|
1770
|
-
return -1;
|
|
1771
|
-
}
|
|
1772
2032
|
function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
|
|
1773
2033
|
const key = containerId + configId;
|
|
1774
2034
|
ctx.mapViewabilityValues.set(key, viewToken);
|
|
@@ -1817,7 +2077,7 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1817
2077
|
for (const containerIndex of stickyContainerPool) {
|
|
1818
2078
|
const key = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1819
2079
|
const isPendingRemoval = pendingRemovalSet.has(containerIndex);
|
|
1820
|
-
if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType)) {
|
|
2080
|
+
if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType) && !result.includes(containerIndex)) {
|
|
1821
2081
|
result.push(containerIndex);
|
|
1822
2082
|
if (isPendingRemoval && pendingRemovalSet.delete(containerIndex)) {
|
|
1823
2083
|
pendingRemovalChanged = true;
|
|
@@ -1905,149 +2165,35 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1905
2165
|
if (pendingRemovalChanged) {
|
|
1906
2166
|
pendingRemoval.length = 0;
|
|
1907
2167
|
for (const value of pendingRemovalSet) {
|
|
1908
|
-
pendingRemoval.push(value);
|
|
1909
|
-
}
|
|
1910
|
-
}
|
|
1911
|
-
return result.sort(comparatorDefault);
|
|
1912
|
-
}
|
|
1913
|
-
function comparatorByDistance(a, b) {
|
|
1914
|
-
return b.distance - a.distance;
|
|
1915
|
-
}
|
|
1916
|
-
|
|
1917
|
-
// src/utils/getScrollVelocity.ts
|
|
1918
|
-
var getScrollVelocity = (state) => {
|
|
1919
|
-
const { scrollHistory } = state;
|
|
1920
|
-
let velocity = 0;
|
|
1921
|
-
if (scrollHistory.length >= 1) {
|
|
1922
|
-
const newest = scrollHistory[scrollHistory.length - 1];
|
|
1923
|
-
let oldest;
|
|
1924
|
-
let start = 0;
|
|
1925
|
-
const now = Date.now();
|
|
1926
|
-
for (let i = 0; i < scrollHistory.length - 1; i++) {
|
|
1927
|
-
const entry = scrollHistory[i];
|
|
1928
|
-
const nextEntry = scrollHistory[i + 1];
|
|
1929
|
-
if (i > 0) {
|
|
1930
|
-
const prevEntry = scrollHistory[i - 1];
|
|
1931
|
-
const prevDirection = entry.scroll - prevEntry.scroll;
|
|
1932
|
-
const currentDirection = nextEntry.scroll - entry.scroll;
|
|
1933
|
-
if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
|
|
1934
|
-
start = i;
|
|
1935
|
-
break;
|
|
1936
|
-
}
|
|
1937
|
-
}
|
|
1938
|
-
}
|
|
1939
|
-
for (let i = start; i < scrollHistory.length - 1; i++) {
|
|
1940
|
-
const entry = scrollHistory[i];
|
|
1941
|
-
if (now - entry.time <= 1e3) {
|
|
1942
|
-
oldest = entry;
|
|
1943
|
-
break;
|
|
1944
|
-
}
|
|
1945
|
-
}
|
|
1946
|
-
if (oldest && oldest !== newest) {
|
|
1947
|
-
const scrollDiff = newest.scroll - oldest.scroll;
|
|
1948
|
-
const timeDiff = newest.time - oldest.time;
|
|
1949
|
-
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
1950
|
-
}
|
|
1951
|
-
}
|
|
1952
|
-
return velocity;
|
|
1953
|
-
};
|
|
1954
|
-
|
|
1955
|
-
// src/core/scrollToIndex.ts
|
|
1956
|
-
function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
|
|
1957
|
-
if (index >= state.props.data.length) {
|
|
1958
|
-
index = state.props.data.length - 1;
|
|
1959
|
-
} else if (index < 0) {
|
|
1960
|
-
index = 0;
|
|
1961
|
-
}
|
|
1962
|
-
const firstIndexOffset = calculateOffsetForIndex(ctx, state, index);
|
|
1963
|
-
const isLast = index === state.props.data.length - 1;
|
|
1964
|
-
if (isLast && viewPosition === void 0) {
|
|
1965
|
-
viewPosition = 1;
|
|
1966
|
-
}
|
|
1967
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
1968
|
-
scrollTo(state, {
|
|
1969
|
-
animated,
|
|
1970
|
-
index,
|
|
1971
|
-
offset: firstIndexOffset,
|
|
1972
|
-
viewOffset,
|
|
1973
|
-
viewPosition: viewPosition != null ? viewPosition : 0
|
|
1974
|
-
});
|
|
1975
|
-
}
|
|
1976
|
-
|
|
1977
|
-
// src/utils/checkThreshold.ts
|
|
1978
|
-
var HYSTERESIS_MULTIPLIER = 1.3;
|
|
1979
|
-
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
|
|
1980
|
-
const absDistance = Math.abs(distance);
|
|
1981
|
-
const within = atThreshold || threshold > 0 && absDistance <= threshold;
|
|
1982
|
-
const updateSnapshot = () => {
|
|
1983
|
-
setSnapshot == null ? void 0 : setSnapshot({
|
|
1984
|
-
atThreshold,
|
|
1985
|
-
contentSize: context.contentSize,
|
|
1986
|
-
dataLength: context.dataLength,
|
|
1987
|
-
scrollPosition: context.scrollPosition
|
|
1988
|
-
});
|
|
1989
|
-
};
|
|
1990
|
-
if (!wasReached) {
|
|
1991
|
-
if (!within) {
|
|
1992
|
-
return false;
|
|
1993
|
-
}
|
|
1994
|
-
onReached == null ? void 0 : onReached(distance);
|
|
1995
|
-
updateSnapshot();
|
|
1996
|
-
return true;
|
|
1997
|
-
}
|
|
1998
|
-
const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
|
|
1999
|
-
if (reset) {
|
|
2000
|
-
setSnapshot == null ? void 0 : setSnapshot(void 0);
|
|
2001
|
-
return false;
|
|
2002
|
-
}
|
|
2003
|
-
if (within) {
|
|
2004
|
-
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
2005
|
-
if (changed) {
|
|
2006
|
-
onReached == null ? void 0 : onReached(distance);
|
|
2007
|
-
updateSnapshot();
|
|
2168
|
+
pendingRemoval.push(value);
|
|
2008
2169
|
}
|
|
2009
2170
|
}
|
|
2010
|
-
return
|
|
2011
|
-
}
|
|
2171
|
+
return result.sort(comparatorDefault);
|
|
2172
|
+
}
|
|
2173
|
+
function comparatorByDistance(a, b) {
|
|
2174
|
+
return b.distance - a.distance;
|
|
2175
|
+
}
|
|
2012
2176
|
|
|
2013
|
-
// src/
|
|
2014
|
-
function
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2177
|
+
// src/core/scrollToIndex.ts
|
|
2178
|
+
function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
|
|
2179
|
+
if (index >= state.props.data.length) {
|
|
2180
|
+
index = state.props.data.length - 1;
|
|
2181
|
+
} else if (index < 0) {
|
|
2182
|
+
index = 0;
|
|
2018
2183
|
}
|
|
2019
|
-
const
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
maintainingScrollAtEnd,
|
|
2024
|
-
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
2025
|
-
} = state;
|
|
2026
|
-
const contentSize = getContentSize(ctx);
|
|
2027
|
-
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
2028
|
-
const distanceFromEnd = contentSize - scroll - scrollLength;
|
|
2029
|
-
const isContentLess = contentSize < scrollLength;
|
|
2030
|
-
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
2031
|
-
state.isEndReached = checkThreshold(
|
|
2032
|
-
distanceFromEnd,
|
|
2033
|
-
isContentLess,
|
|
2034
|
-
onEndReachedThreshold * scrollLength,
|
|
2035
|
-
state.isEndReached,
|
|
2036
|
-
state.endReachedSnapshot,
|
|
2037
|
-
{
|
|
2038
|
-
scrollPosition: scroll,
|
|
2039
|
-
contentSize,
|
|
2040
|
-
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length
|
|
2041
|
-
},
|
|
2042
|
-
(distance) => {
|
|
2043
|
-
var _a4, _b;
|
|
2044
|
-
return (_b = (_a4 = state.props).onEndReached) == null ? void 0 : _b.call(_a4, { distanceFromEnd: distance });
|
|
2045
|
-
},
|
|
2046
|
-
(snapshot) => {
|
|
2047
|
-
state.endReachedSnapshot = snapshot;
|
|
2048
|
-
}
|
|
2049
|
-
);
|
|
2184
|
+
const firstIndexOffset = calculateOffsetForIndex(ctx, state, index);
|
|
2185
|
+
const isLast = index === state.props.data.length - 1;
|
|
2186
|
+
if (isLast && viewPosition === void 0) {
|
|
2187
|
+
viewPosition = 1;
|
|
2050
2188
|
}
|
|
2189
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
2190
|
+
scrollTo(ctx, state, {
|
|
2191
|
+
animated,
|
|
2192
|
+
index,
|
|
2193
|
+
offset: firstIndexOffset,
|
|
2194
|
+
viewOffset,
|
|
2195
|
+
viewPosition: viewPosition != null ? viewPosition : 0
|
|
2196
|
+
});
|
|
2051
2197
|
}
|
|
2052
2198
|
|
|
2053
2199
|
// src/utils/setDidLayout.ts
|
|
@@ -2129,7 +2275,7 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
|
|
|
2129
2275
|
const currentId = (_b = state.idCache[itemIndex]) != null ? _b : getId(state, itemIndex);
|
|
2130
2276
|
if (currentId) {
|
|
2131
2277
|
const currentPos = state.positions.get(currentId);
|
|
2132
|
-
const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(state, currentId, itemIndex, state.props.data[itemIndex]);
|
|
2278
|
+
const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, state, currentId, itemIndex, state.props.data[itemIndex]);
|
|
2133
2279
|
shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
|
|
2134
2280
|
}
|
|
2135
2281
|
}
|
|
@@ -2140,21 +2286,22 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
|
|
|
2140
2286
|
}
|
|
2141
2287
|
function calculateItemsInView(ctx, state, params = {}) {
|
|
2142
2288
|
unstable_batchedUpdates(() => {
|
|
2143
|
-
var _a3, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
2289
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
2144
2290
|
const {
|
|
2145
2291
|
columns,
|
|
2146
2292
|
containerItemKeys,
|
|
2147
2293
|
enableScrollForNextCalculateItemsInView,
|
|
2148
2294
|
idCache,
|
|
2149
2295
|
indexByKey,
|
|
2296
|
+
initialScroll,
|
|
2150
2297
|
minIndexSizeChanged,
|
|
2151
2298
|
positions,
|
|
2299
|
+
props: { getItemType, itemsAreEqual, keyExtractor, onStickyHeaderChange, scrollBuffer },
|
|
2152
2300
|
scrollForNextCalculateItemsInView,
|
|
2153
2301
|
scrollLength,
|
|
2154
2302
|
sizes,
|
|
2155
2303
|
startBufferedId: startBufferedIdOrig,
|
|
2156
|
-
viewabilityConfigCallbackPairs
|
|
2157
|
-
props: { getItemType, initialScroll, itemsAreEqual, keyExtractor, onStickyHeaderChange, scrollBuffer }
|
|
2304
|
+
viewabilityConfigCallbackPairs
|
|
2158
2305
|
} = state;
|
|
2159
2306
|
const { data } = state.props;
|
|
2160
2307
|
const stickyIndicesArr = state.props.stickyIndicesArr || [];
|
|
@@ -2166,20 +2313,22 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2166
2313
|
const totalSize = peek$(ctx, "totalSize");
|
|
2167
2314
|
const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
|
|
2168
2315
|
const numColumns = peek$(ctx, "numColumns");
|
|
2169
|
-
const { dataChanged, doMVCP } = params;
|
|
2316
|
+
const { dataChanged, doMVCP, forceFullItemPositions } = params;
|
|
2170
2317
|
const speed = getScrollVelocity(state);
|
|
2171
2318
|
const scrollExtra = 0;
|
|
2172
2319
|
const { queuedInitialLayout } = state;
|
|
2173
2320
|
let { scroll: scrollState } = state;
|
|
2174
2321
|
if (!queuedInitialLayout && initialScroll) {
|
|
2175
2322
|
const updatedOffset = calculateOffsetWithOffsetPosition(
|
|
2323
|
+
ctx,
|
|
2176
2324
|
state,
|
|
2177
2325
|
calculateOffsetForIndex(ctx, state, initialScroll.index),
|
|
2178
2326
|
initialScroll
|
|
2179
2327
|
);
|
|
2180
2328
|
scrollState = updatedOffset;
|
|
2181
2329
|
}
|
|
2182
|
-
const
|
|
2330
|
+
const scrollAdjustPending = (_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0;
|
|
2331
|
+
const scrollAdjustPad = scrollAdjustPending - topPad;
|
|
2183
2332
|
let scroll = scrollState + scrollExtra + scrollAdjustPad;
|
|
2184
2333
|
if (scroll + scrollLength > totalSize) {
|
|
2185
2334
|
scroll = Math.max(0, totalSize - scrollLength);
|
|
@@ -2192,6 +2341,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2192
2341
|
const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
|
|
2193
2342
|
const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : void 0;
|
|
2194
2343
|
state.activeStickyIndex = nextActiveStickyIndex;
|
|
2344
|
+
set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
|
|
2195
2345
|
let scrollBufferTop = scrollBuffer;
|
|
2196
2346
|
let scrollBufferBottom = scrollBuffer;
|
|
2197
2347
|
if (speed > 0 || speed === 0 && scroll < Math.max(50, scrollBuffer)) {
|
|
@@ -2216,8 +2366,12 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2216
2366
|
idCache.length = 0;
|
|
2217
2367
|
positions.clear();
|
|
2218
2368
|
}
|
|
2219
|
-
const startIndex = dataChanged ? 0 : (
|
|
2220
|
-
updateItemPositions(ctx, state, dataChanged, {
|
|
2369
|
+
const startIndex = dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
|
|
2370
|
+
updateItemPositions(ctx, state, dataChanged, {
|
|
2371
|
+
forceFullUpdate: !!forceFullItemPositions,
|
|
2372
|
+
scrollBottomBuffered,
|
|
2373
|
+
startIndex
|
|
2374
|
+
});
|
|
2221
2375
|
if (minIndexSizeChanged !== void 0) {
|
|
2222
2376
|
state.minIndexSizeChanged = void 0;
|
|
2223
2377
|
}
|
|
@@ -2229,9 +2383,9 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2229
2383
|
let endBuffered = null;
|
|
2230
2384
|
let loopStart = !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
|
|
2231
2385
|
for (let i = loopStart; i >= 0; i--) {
|
|
2232
|
-
const id = (
|
|
2386
|
+
const id = (_c = idCache[i]) != null ? _c : getId(state, i);
|
|
2233
2387
|
const top = positions.get(id);
|
|
2234
|
-
const size = (
|
|
2388
|
+
const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, state, id, i, data[i]);
|
|
2235
2389
|
const bottom = top + size;
|
|
2236
2390
|
if (bottom > scroll - scrollBuffer) {
|
|
2237
2391
|
loopStart = i;
|
|
@@ -2257,8 +2411,8 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2257
2411
|
let firstFullyOnScreenIndex;
|
|
2258
2412
|
const dataLength = data.length;
|
|
2259
2413
|
for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
|
|
2260
|
-
const id = (
|
|
2261
|
-
const size = (
|
|
2414
|
+
const id = (_e = idCache[i]) != null ? _e : getId(state, i);
|
|
2415
|
+
const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, state, id, i, data[i]);
|
|
2262
2416
|
const top = positions.get(id);
|
|
2263
2417
|
if (!foundEnd) {
|
|
2264
2418
|
if (startNoBuffer === null && top + size > scroll) {
|
|
@@ -2287,7 +2441,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2287
2441
|
}
|
|
2288
2442
|
const idsInView = [];
|
|
2289
2443
|
for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
|
|
2290
|
-
const id = (
|
|
2444
|
+
const id = (_g = idCache[i]) != null ? _g : getId(state, i);
|
|
2291
2445
|
idsInView.push(id);
|
|
2292
2446
|
}
|
|
2293
2447
|
Object.assign(state, {
|
|
@@ -2319,7 +2473,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2319
2473
|
let numContainers2 = prevNumContainers;
|
|
2320
2474
|
const needNewContainers = [];
|
|
2321
2475
|
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
2322
|
-
const id = (
|
|
2476
|
+
const id = (_h = idCache[i]) != null ? _h : getId(state, i);
|
|
2323
2477
|
if (!containerItemKeys.has(id)) {
|
|
2324
2478
|
needNewContainers.push(i);
|
|
2325
2479
|
}
|
|
@@ -2337,6 +2491,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2337
2491
|
);
|
|
2338
2492
|
} else {
|
|
2339
2493
|
state.activeStickyIndex = void 0;
|
|
2494
|
+
set$(ctx, "activeStickyIndex", void 0);
|
|
2340
2495
|
}
|
|
2341
2496
|
if (needNewContainers.length > 0) {
|
|
2342
2497
|
const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
|
|
@@ -2356,7 +2511,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2356
2511
|
for (let idx = 0; idx < needNewContainers.length; idx++) {
|
|
2357
2512
|
const i = needNewContainers[idx];
|
|
2358
2513
|
const containerIndex = availableContainers[idx];
|
|
2359
|
-
const id = (
|
|
2514
|
+
const id = (_i = idCache[i]) != null ? _i : getId(state, i);
|
|
2360
2515
|
const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
2361
2516
|
if (oldKey && oldKey !== id) {
|
|
2362
2517
|
containerItemKeys.delete(oldKey);
|
|
@@ -2395,7 +2550,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2395
2550
|
for (let i = 0; i < numContainers; i++) {
|
|
2396
2551
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
2397
2552
|
if (pendingRemoval.includes(i)) {
|
|
2398
|
-
if (itemKey) {
|
|
2553
|
+
if (itemKey !== void 0) {
|
|
2399
2554
|
containerItemKeys.delete(itemKey);
|
|
2400
2555
|
}
|
|
2401
2556
|
state.containerItemTypes.delete(i);
|
|
@@ -2412,11 +2567,12 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2412
2567
|
const itemIndex = indexByKey.get(itemKey);
|
|
2413
2568
|
const item = data[itemIndex];
|
|
2414
2569
|
if (item !== void 0) {
|
|
2415
|
-
const id = (
|
|
2416
|
-
const
|
|
2417
|
-
if (
|
|
2570
|
+
const id = (_j = idCache[itemIndex]) != null ? _j : getId(state, itemIndex);
|
|
2571
|
+
const positionValue = positions.get(id);
|
|
2572
|
+
if (positionValue === void 0) {
|
|
2418
2573
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
2419
2574
|
} else {
|
|
2575
|
+
const position = (positionValue || 0) - scrollAdjustPending;
|
|
2420
2576
|
const column = columns.get(id) || 1;
|
|
2421
2577
|
const prevPos = peek$(ctx, `containerPosition${i}`);
|
|
2422
2578
|
const prevColumn = peek$(ctx, `containerColumn${i}`);
|
|
@@ -2455,6 +2611,26 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2455
2611
|
});
|
|
2456
2612
|
}
|
|
2457
2613
|
|
|
2614
|
+
// src/core/checkActualChange.ts
|
|
2615
|
+
function checkActualChange(state, dataProp, previousData) {
|
|
2616
|
+
if (!previousData || !dataProp || dataProp.length !== previousData.length) {
|
|
2617
|
+
return true;
|
|
2618
|
+
}
|
|
2619
|
+
const {
|
|
2620
|
+
idCache,
|
|
2621
|
+
props: { keyExtractor }
|
|
2622
|
+
} = state;
|
|
2623
|
+
for (let i = 0; i < dataProp.length; i++) {
|
|
2624
|
+
if (dataProp[i] !== previousData[i]) {
|
|
2625
|
+
return true;
|
|
2626
|
+
}
|
|
2627
|
+
if (keyExtractor ? idCache[i] !== keyExtractor(previousData[i], i) : dataProp[i] !== previousData[i]) {
|
|
2628
|
+
return true;
|
|
2629
|
+
}
|
|
2630
|
+
}
|
|
2631
|
+
return false;
|
|
2632
|
+
}
|
|
2633
|
+
|
|
2458
2634
|
// src/core/doMaintainScrollAtEnd.ts
|
|
2459
2635
|
function doMaintainScrollAtEnd(ctx, state, animated) {
|
|
2460
2636
|
const {
|
|
@@ -2485,40 +2661,6 @@ function doMaintainScrollAtEnd(ctx, state, animated) {
|
|
|
2485
2661
|
}
|
|
2486
2662
|
}
|
|
2487
2663
|
|
|
2488
|
-
// src/utils/checkAtTop.ts
|
|
2489
|
-
function checkAtTop(state) {
|
|
2490
|
-
var _a3;
|
|
2491
|
-
if (!state) {
|
|
2492
|
-
return;
|
|
2493
|
-
}
|
|
2494
|
-
const {
|
|
2495
|
-
scrollLength,
|
|
2496
|
-
scroll,
|
|
2497
|
-
props: { onStartReachedThreshold }
|
|
2498
|
-
} = state;
|
|
2499
|
-
const distanceFromTop = scroll;
|
|
2500
|
-
state.isAtStart = distanceFromTop <= 0;
|
|
2501
|
-
state.isStartReached = checkThreshold(
|
|
2502
|
-
distanceFromTop,
|
|
2503
|
-
false,
|
|
2504
|
-
onStartReachedThreshold * scrollLength,
|
|
2505
|
-
state.isStartReached,
|
|
2506
|
-
state.startReachedSnapshot,
|
|
2507
|
-
{
|
|
2508
|
-
scrollPosition: scroll,
|
|
2509
|
-
contentSize: state.totalSize,
|
|
2510
|
-
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length
|
|
2511
|
-
},
|
|
2512
|
-
(distance) => {
|
|
2513
|
-
var _a4, _b;
|
|
2514
|
-
return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
|
|
2515
|
-
},
|
|
2516
|
-
(snapshot) => {
|
|
2517
|
-
state.startReachedSnapshot = snapshot;
|
|
2518
|
-
}
|
|
2519
|
-
);
|
|
2520
|
-
}
|
|
2521
|
-
|
|
2522
2664
|
// src/utils/updateAveragesOnDataChange.ts
|
|
2523
2665
|
function updateAveragesOnDataChange(state, oldData, newData) {
|
|
2524
2666
|
var _a3;
|
|
@@ -2572,25 +2714,23 @@ function updateAveragesOnDataChange(state, oldData, newData) {
|
|
|
2572
2714
|
}
|
|
2573
2715
|
|
|
2574
2716
|
// src/core/checkResetContainers.ts
|
|
2575
|
-
function checkResetContainers(ctx, state,
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
state.isEndReached = false;
|
|
2587
|
-
}
|
|
2588
|
-
if (!didMaintainScrollAtEnd) {
|
|
2589
|
-
checkAtTop(state);
|
|
2590
|
-
checkAtBottom(ctx, state);
|
|
2591
|
-
}
|
|
2592
|
-
}
|
|
2717
|
+
function checkResetContainers(ctx, state, dataProp) {
|
|
2718
|
+
const { previousData } = state;
|
|
2719
|
+
if (previousData) {
|
|
2720
|
+
updateAveragesOnDataChange(state, previousData, dataProp);
|
|
2721
|
+
}
|
|
2722
|
+
const { maintainScrollAtEnd } = state.props;
|
|
2723
|
+
calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
|
|
2724
|
+
const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
|
|
2725
|
+
const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state, false);
|
|
2726
|
+
if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
|
|
2727
|
+
state.isEndReached = false;
|
|
2593
2728
|
}
|
|
2729
|
+
if (!didMaintainScrollAtEnd) {
|
|
2730
|
+
checkAtTop(state);
|
|
2731
|
+
checkAtBottom(ctx, state);
|
|
2732
|
+
}
|
|
2733
|
+
delete state.previousData;
|
|
2594
2734
|
}
|
|
2595
2735
|
|
|
2596
2736
|
// src/core/doInitialAllocateContainers.ts
|
|
@@ -2631,7 +2771,7 @@ function doInitialAllocateContainers(ctx, state) {
|
|
|
2631
2771
|
set$(ctx, "numContainers", numContainers);
|
|
2632
2772
|
set$(ctx, "numContainersPooled", numContainers * state.props.initialContainerPoolRatio);
|
|
2633
2773
|
if (state.lastLayout) {
|
|
2634
|
-
if (state.
|
|
2774
|
+
if (state.initialScroll) {
|
|
2635
2775
|
requestAnimationFrame(() => {
|
|
2636
2776
|
calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
|
|
2637
2777
|
});
|
|
@@ -2687,78 +2827,47 @@ function handleLayout(ctx, state, layout, setCanRender) {
|
|
|
2687
2827
|
setCanRender(true);
|
|
2688
2828
|
}
|
|
2689
2829
|
|
|
2690
|
-
// src/core/onScroll.ts
|
|
2691
|
-
function onScroll(ctx, state, event) {
|
|
2692
|
-
var _a3, _b, _c;
|
|
2693
|
-
const {
|
|
2694
|
-
scrollProcessingEnabled,
|
|
2695
|
-
props: { onScroll: onScrollProp }
|
|
2696
|
-
} = state;
|
|
2697
|
-
if (scrollProcessingEnabled === false) {
|
|
2698
|
-
return;
|
|
2699
|
-
}
|
|
2700
|
-
if (((_b = (_a3 = event.nativeEvent) == null ? void 0 : _a3.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
|
|
2701
|
-
return;
|
|
2702
|
-
}
|
|
2703
|
-
const newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
|
|
2704
|
-
state.scrollPending = newScroll;
|
|
2705
|
-
updateScroll(ctx, state, newScroll);
|
|
2706
|
-
onScrollProp == null ? void 0 : onScrollProp(event);
|
|
2707
|
-
}
|
|
2708
|
-
function updateScroll(ctx, state, newScroll) {
|
|
2709
|
-
const scrollingTo = state.scrollingTo;
|
|
2710
|
-
state.hasScrolled = true;
|
|
2711
|
-
state.lastBatchingAction = Date.now();
|
|
2712
|
-
const currentTime = Date.now();
|
|
2713
|
-
const adjust = state.scrollAdjustHandler.getAdjust();
|
|
2714
|
-
const lastHistoryAdjust = state.lastScrollAdjustForHistory;
|
|
2715
|
-
const adjustChanged = lastHistoryAdjust !== void 0 && Math.abs(adjust - lastHistoryAdjust) > 0.1;
|
|
2716
|
-
if (adjustChanged) {
|
|
2717
|
-
state.scrollHistory.length = 0;
|
|
2718
|
-
}
|
|
2719
|
-
state.lastScrollAdjustForHistory = adjust;
|
|
2720
|
-
if (scrollingTo === void 0 && !(state.scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
2721
|
-
if (!adjustChanged) {
|
|
2722
|
-
state.scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
2723
|
-
}
|
|
2724
|
-
}
|
|
2725
|
-
if (state.scrollHistory.length > 5) {
|
|
2726
|
-
state.scrollHistory.shift();
|
|
2727
|
-
}
|
|
2728
|
-
state.scrollPrev = state.scroll;
|
|
2729
|
-
state.scrollPrevTime = state.scrollTime;
|
|
2730
|
-
state.scroll = newScroll;
|
|
2731
|
-
state.scrollTime = currentTime;
|
|
2732
|
-
const ignoreScrollFromMVCP = state.ignoreScrollFromMVCP;
|
|
2733
|
-
if (ignoreScrollFromMVCP && !state.scrollingTo) {
|
|
2734
|
-
const { lt, gt } = ignoreScrollFromMVCP;
|
|
2735
|
-
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
2736
|
-
return;
|
|
2737
|
-
}
|
|
2738
|
-
}
|
|
2739
|
-
if (state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollPrev) > 2) {
|
|
2740
|
-
calculateItemsInView(ctx, state, { doMVCP: state.scrollingTo !== void 0 });
|
|
2741
|
-
checkAtBottom(ctx, state);
|
|
2742
|
-
checkAtTop(state);
|
|
2743
|
-
state.dataChangeNeedsScrollUpdate = false;
|
|
2744
|
-
}
|
|
2745
|
-
}
|
|
2746
|
-
|
|
2747
2830
|
// src/core/ScrollAdjustHandler.ts
|
|
2748
2831
|
var ScrollAdjustHandler = class {
|
|
2749
2832
|
constructor(ctx) {
|
|
2750
2833
|
this.appliedAdjust = 0;
|
|
2834
|
+
this.pendingAdjust = 0;
|
|
2751
2835
|
this.mounted = false;
|
|
2752
2836
|
this.context = ctx;
|
|
2837
|
+
{
|
|
2838
|
+
const commitPendingAdjust = () => {
|
|
2839
|
+
const state = this.context.internalState;
|
|
2840
|
+
const pending = this.pendingAdjust;
|
|
2841
|
+
if (pending !== 0) {
|
|
2842
|
+
this.pendingAdjust = 0;
|
|
2843
|
+
this.appliedAdjust += pending;
|
|
2844
|
+
state.scroll += pending;
|
|
2845
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
2846
|
+
set$(this.context, "scrollAdjustPending", 0);
|
|
2847
|
+
set$(this.context, "scrollAdjust", this.appliedAdjust);
|
|
2848
|
+
calculateItemsInView(this.context, this.context.internalState);
|
|
2849
|
+
}
|
|
2850
|
+
};
|
|
2851
|
+
listen$(this.context, "scrollingTo", (value) => {
|
|
2852
|
+
if (value === void 0) {
|
|
2853
|
+
commitPendingAdjust();
|
|
2854
|
+
}
|
|
2855
|
+
});
|
|
2856
|
+
}
|
|
2753
2857
|
}
|
|
2754
2858
|
requestAdjust(add) {
|
|
2755
|
-
const
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
set();
|
|
2859
|
+
const scrollingTo = peek$(this.context, "scrollingTo");
|
|
2860
|
+
if ((scrollingTo == null ? void 0 : scrollingTo.animated) && !scrollingTo.isInitialScroll) {
|
|
2861
|
+
this.pendingAdjust += add;
|
|
2862
|
+
set$(this.context, "scrollAdjustPending", this.pendingAdjust);
|
|
2760
2863
|
} else {
|
|
2761
|
-
|
|
2864
|
+
this.appliedAdjust += add;
|
|
2865
|
+
const setter = () => set$(this.context, "scrollAdjust", this.appliedAdjust);
|
|
2866
|
+
if (this.mounted) {
|
|
2867
|
+
setter();
|
|
2868
|
+
} else {
|
|
2869
|
+
requestAnimationFrame(setter);
|
|
2870
|
+
}
|
|
2762
2871
|
}
|
|
2763
2872
|
}
|
|
2764
2873
|
setMounted() {
|
|
@@ -2806,8 +2915,8 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
2806
2915
|
let minIndexSizeChanged;
|
|
2807
2916
|
let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
|
|
2808
2917
|
const prevSizeKnown = state.sizesKnown.get(itemKey);
|
|
2809
|
-
const diff = updateOneItemSize(state, itemKey, sizeObj);
|
|
2810
|
-
const size =
|
|
2918
|
+
const diff = updateOneItemSize(ctx, state, itemKey, sizeObj);
|
|
2919
|
+
const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
|
|
2811
2920
|
if (diff !== 0) {
|
|
2812
2921
|
minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
|
|
2813
2922
|
const { startBuffered, endBuffered } = state;
|
|
@@ -2828,7 +2937,6 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
2828
2937
|
if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
|
|
2829
2938
|
shouldMaintainScrollAtEnd = true;
|
|
2830
2939
|
}
|
|
2831
|
-
addTotalSize(ctx, state, itemKey, diff);
|
|
2832
2940
|
onItemSizeChanged == null ? void 0 : onItemSizeChanged({
|
|
2833
2941
|
index,
|
|
2834
2942
|
itemData: state.props.data[index],
|
|
@@ -2868,7 +2976,7 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
2868
2976
|
}
|
|
2869
2977
|
}
|
|
2870
2978
|
}
|
|
2871
|
-
function updateOneItemSize(state, itemKey, sizeObj) {
|
|
2979
|
+
function updateOneItemSize(ctx, state, itemKey, sizeObj) {
|
|
2872
2980
|
var _a3;
|
|
2873
2981
|
const {
|
|
2874
2982
|
sizes,
|
|
@@ -2879,7 +2987,7 @@ function updateOneItemSize(state, itemKey, sizeObj) {
|
|
|
2879
2987
|
} = state;
|
|
2880
2988
|
if (!data) return 0;
|
|
2881
2989
|
const index = indexByKey.get(itemKey);
|
|
2882
|
-
const prevSize = getItemSize(state, itemKey, index, data[index]);
|
|
2990
|
+
const prevSize = getItemSize(ctx, state, itemKey, index, data[index]);
|
|
2883
2991
|
const rawSize = horizontal ? sizeObj.width : sizeObj.height;
|
|
2884
2992
|
const size = Math.round(rawSize) ;
|
|
2885
2993
|
sizesKnown.set(itemKey, size);
|
|
@@ -2893,7 +3001,7 @@ function updateOneItemSize(state, itemKey, sizeObj) {
|
|
|
2893
3001
|
averages.num++;
|
|
2894
3002
|
}
|
|
2895
3003
|
if (!prevSize || Math.abs(prevSize - size) > 0.1) {
|
|
2896
|
-
|
|
3004
|
+
setSize(ctx, state, itemKey, size);
|
|
2897
3005
|
return size - prevSize;
|
|
2898
3006
|
}
|
|
2899
3007
|
return 0;
|
|
@@ -2938,6 +3046,91 @@ function createColumnWrapperStyle(contentContainerStyle) {
|
|
|
2938
3046
|
};
|
|
2939
3047
|
}
|
|
2940
3048
|
}
|
|
3049
|
+
|
|
3050
|
+
// src/utils/createImperativeHandle.ts
|
|
3051
|
+
function createImperativeHandle(ctx, state) {
|
|
3052
|
+
const scrollIndexIntoView = (options) => {
|
|
3053
|
+
if (state) {
|
|
3054
|
+
const { index, ...rest } = options;
|
|
3055
|
+
const { startNoBuffer, endNoBuffer } = state;
|
|
3056
|
+
if (index < startNoBuffer || index > endNoBuffer) {
|
|
3057
|
+
const viewPosition = index < startNoBuffer ? 0 : 1;
|
|
3058
|
+
scrollToIndex(ctx, state, {
|
|
3059
|
+
...rest,
|
|
3060
|
+
index,
|
|
3061
|
+
viewPosition
|
|
3062
|
+
});
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
};
|
|
3066
|
+
const refScroller = state.refScroller;
|
|
3067
|
+
return {
|
|
3068
|
+
flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
|
|
3069
|
+
getNativeScrollRef: () => refScroller.current,
|
|
3070
|
+
getScrollableNode: () => refScroller.current.getScrollableNode(),
|
|
3071
|
+
getScrollResponder: () => refScroller.current.getScrollResponder(),
|
|
3072
|
+
getState: () => ({
|
|
3073
|
+
activeStickyIndex: state.activeStickyIndex,
|
|
3074
|
+
contentLength: state.totalSize,
|
|
3075
|
+
data: state.props.data,
|
|
3076
|
+
elementAtIndex: (index) => {
|
|
3077
|
+
var _a3;
|
|
3078
|
+
return (_a3 = ctx.viewRefs.get(findContainerId(ctx, getId(state, index)))) == null ? void 0 : _a3.current;
|
|
3079
|
+
},
|
|
3080
|
+
end: state.endNoBuffer,
|
|
3081
|
+
endBuffered: state.endBuffered,
|
|
3082
|
+
isAtEnd: state.isAtEnd,
|
|
3083
|
+
isAtStart: state.isAtStart,
|
|
3084
|
+
positionAtIndex: (index) => state.positions.get(getId(state, index)),
|
|
3085
|
+
positions: state.positions,
|
|
3086
|
+
scroll: state.scroll,
|
|
3087
|
+
scrollLength: state.scrollLength,
|
|
3088
|
+
sizeAtIndex: (index) => state.sizesKnown.get(getId(state, index)),
|
|
3089
|
+
sizes: state.sizesKnown,
|
|
3090
|
+
start: state.startNoBuffer,
|
|
3091
|
+
startBuffered: state.startBuffered
|
|
3092
|
+
}),
|
|
3093
|
+
scrollIndexIntoView,
|
|
3094
|
+
scrollItemIntoView: ({ item, ...props }) => {
|
|
3095
|
+
const data = state.props.data;
|
|
3096
|
+
const index = data.indexOf(item);
|
|
3097
|
+
if (index !== -1) {
|
|
3098
|
+
scrollIndexIntoView({ index, ...props });
|
|
3099
|
+
}
|
|
3100
|
+
},
|
|
3101
|
+
scrollToEnd: (options) => {
|
|
3102
|
+
const data = state.props.data;
|
|
3103
|
+
const stylePaddingBottom = state.props.stylePaddingBottom;
|
|
3104
|
+
const index = data.length - 1;
|
|
3105
|
+
if (index !== -1) {
|
|
3106
|
+
const paddingBottom = stylePaddingBottom || 0;
|
|
3107
|
+
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
3108
|
+
scrollToIndex(ctx, state, {
|
|
3109
|
+
index,
|
|
3110
|
+
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
3111
|
+
viewPosition: 1,
|
|
3112
|
+
...options
|
|
3113
|
+
});
|
|
3114
|
+
}
|
|
3115
|
+
},
|
|
3116
|
+
scrollToIndex: (params) => scrollToIndex(ctx, state, params),
|
|
3117
|
+
scrollToItem: ({ item, ...props }) => {
|
|
3118
|
+
const data = state.props.data;
|
|
3119
|
+
const index = data.indexOf(item);
|
|
3120
|
+
if (index !== -1) {
|
|
3121
|
+
scrollToIndex(ctx, state, { index, ...props });
|
|
3122
|
+
}
|
|
3123
|
+
},
|
|
3124
|
+
scrollToOffset: (params) => scrollTo(ctx, state, params),
|
|
3125
|
+
setScrollProcessingEnabled: (enabled) => {
|
|
3126
|
+
state.scrollProcessingEnabled = enabled;
|
|
3127
|
+
},
|
|
3128
|
+
setVisibleContentAnchorOffset: (value) => {
|
|
3129
|
+
const val = isFunction(value) ? value(peek$(ctx, "scrollAdjustUserOffset") || 0) : value;
|
|
3130
|
+
set$(ctx, "scrollAdjustUserOffset", val);
|
|
3131
|
+
}
|
|
3132
|
+
};
|
|
3133
|
+
}
|
|
2941
3134
|
function getRenderedItem(ctx, state, key) {
|
|
2942
3135
|
var _a3;
|
|
2943
3136
|
if (!state) {
|
|
@@ -3038,6 +3231,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3038
3231
|
columnWrapperStyle,
|
|
3039
3232
|
contentContainerStyle: contentContainerStyleProp,
|
|
3040
3233
|
data: dataProp = [],
|
|
3234
|
+
dataVersion,
|
|
3041
3235
|
drawDistance = 250,
|
|
3042
3236
|
enableAverages = true,
|
|
3043
3237
|
estimatedItemSize: estimatedItemSizeProp,
|
|
@@ -3048,6 +3242,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3048
3242
|
getItemType,
|
|
3049
3243
|
horizontal,
|
|
3050
3244
|
initialContainerPoolRatio = 2,
|
|
3245
|
+
initialScrollAtEnd = false,
|
|
3051
3246
|
initialScrollIndex: initialScrollIndexProp,
|
|
3052
3247
|
initialScrollOffset: initialScrollOffsetProp,
|
|
3053
3248
|
itemsAreEqual,
|
|
@@ -3086,13 +3281,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3086
3281
|
waitForInitialLayout = true,
|
|
3087
3282
|
...rest
|
|
3088
3283
|
} = props;
|
|
3089
|
-
const [renderNum, setRenderNum] = useState(0);
|
|
3090
|
-
const initialScroll = initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
|
|
3091
|
-
const [canRender, setCanRender] = React3.useState(!IsNewArchitecture);
|
|
3092
3284
|
const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
|
|
3093
3285
|
const style = { ...StyleSheet.flatten(styleProp) };
|
|
3094
3286
|
const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
|
|
3095
3287
|
const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
|
|
3288
|
+
const [renderNum, setRenderNum] = useState(0);
|
|
3289
|
+
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;
|
|
3290
|
+
const [canRender, setCanRender] = React3.useState(!IsNewArchitecture);
|
|
3096
3291
|
const ctx = useStateContext();
|
|
3097
3292
|
ctx.columnWrapperStyle = columnWrapperStyle || (contentContainerStyle ? createColumnWrapperStyle(contentContainerStyle) : void 0);
|
|
3098
3293
|
const refScroller = useRef(null);
|
|
@@ -3111,6 +3306,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3111
3306
|
containerItemKeys: /* @__PURE__ */ new Set(),
|
|
3112
3307
|
containerItemTypes: /* @__PURE__ */ new Map(),
|
|
3113
3308
|
dataChangeNeedsScrollUpdate: false,
|
|
3309
|
+
didColumnsChange: false,
|
|
3310
|
+
didDataChange: false,
|
|
3114
3311
|
enableScrollForNextCalculateItemsInView: true,
|
|
3115
3312
|
endBuffered: -1,
|
|
3116
3313
|
endNoBuffer: -1,
|
|
@@ -3119,10 +3316,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3119
3316
|
idCache: [],
|
|
3120
3317
|
idsInView: [],
|
|
3121
3318
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
3122
|
-
initialScroll,
|
|
3319
|
+
initialScroll: initialScrollProp,
|
|
3123
3320
|
isAtEnd: false,
|
|
3124
3321
|
isAtStart: false,
|
|
3125
3322
|
isEndReached: false,
|
|
3323
|
+
isFirst: true,
|
|
3126
3324
|
isStartReached: false,
|
|
3127
3325
|
lastBatchingAction: Date.now(),
|
|
3128
3326
|
lastLayout: void 0,
|
|
@@ -3155,21 +3353,27 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3155
3353
|
totalSize: 0,
|
|
3156
3354
|
viewabilityConfigCallbackPairs: void 0
|
|
3157
3355
|
};
|
|
3356
|
+
const internalState = ctx.internalState;
|
|
3357
|
+
internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, internalState, params);
|
|
3158
3358
|
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
|
|
3159
3359
|
set$(ctx, "extraData", extraData);
|
|
3160
3360
|
}
|
|
3161
3361
|
refState.current = ctx.internalState;
|
|
3162
3362
|
}
|
|
3163
3363
|
const state = refState.current;
|
|
3164
|
-
const
|
|
3165
|
-
|
|
3166
|
-
|
|
3364
|
+
const isFirstLocal = state.isFirst;
|
|
3365
|
+
state.didColumnsChange = numColumnsProp !== state.props.numColumns;
|
|
3366
|
+
const didDataChangeLocal = state.props.dataVersion !== dataVersion || state.props.data !== dataProp && checkActualChange(state, dataProp, state.props.data);
|
|
3367
|
+
if (didDataChangeLocal) {
|
|
3167
3368
|
state.dataChangeNeedsScrollUpdate = true;
|
|
3369
|
+
state.didDataChange = true;
|
|
3370
|
+
state.previousData = state.props.data;
|
|
3168
3371
|
}
|
|
3169
3372
|
const throttleScrollFn = scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp;
|
|
3170
3373
|
state.props = {
|
|
3171
3374
|
alignItemsAtEnd,
|
|
3172
3375
|
data: dataProp,
|
|
3376
|
+
dataVersion,
|
|
3173
3377
|
enableAverages,
|
|
3174
3378
|
estimatedItemSize,
|
|
3175
3379
|
getEstimatedItemSize,
|
|
@@ -3177,7 +3381,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3177
3381
|
getItemType,
|
|
3178
3382
|
horizontal: !!horizontal,
|
|
3179
3383
|
initialContainerPoolRatio,
|
|
3180
|
-
initialScroll,
|
|
3181
3384
|
itemsAreEqual,
|
|
3182
3385
|
keyExtractor,
|
|
3183
3386
|
maintainScrollAtEnd,
|
|
@@ -3209,7 +3412,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3209
3412
|
{ length: Math.min(numColumnsProp, dataProp.length) },
|
|
3210
3413
|
(_, i) => getId(state, dataProp.length - 1 - i)
|
|
3211
3414
|
);
|
|
3212
|
-
}, [dataProp, numColumnsProp]);
|
|
3415
|
+
}, [dataProp, dataVersion, numColumnsProp]);
|
|
3213
3416
|
const initializeStateVars = () => {
|
|
3214
3417
|
set$(ctx, "lastItemKeys", memoizedLastItemKeys);
|
|
3215
3418
|
set$(ctx, "numColumns", numColumnsProp);
|
|
@@ -3224,7 +3427,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3224
3427
|
requestAdjust(ctx, state, paddingDiff);
|
|
3225
3428
|
}
|
|
3226
3429
|
};
|
|
3227
|
-
if (
|
|
3430
|
+
if (isFirstLocal) {
|
|
3228
3431
|
initializeStateVars();
|
|
3229
3432
|
updateItemPositions(
|
|
3230
3433
|
ctx,
|
|
@@ -3234,38 +3437,42 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3234
3437
|
);
|
|
3235
3438
|
}
|
|
3236
3439
|
const initialContentOffset = useMemo(() => {
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3440
|
+
const { initialScroll } = refState.current;
|
|
3441
|
+
if (!initialScroll) {
|
|
3442
|
+
return 0;
|
|
3443
|
+
}
|
|
3444
|
+
if (initialScroll.contentOffset !== void 0) {
|
|
3445
|
+
return initialScroll.contentOffset;
|
|
3446
|
+
}
|
|
3447
|
+
const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, state, initialScroll.index) : 0;
|
|
3448
|
+
const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, state, baseOffset, initialScroll);
|
|
3449
|
+
let clampedOffset = resolvedOffset;
|
|
3450
|
+
if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
|
|
3451
|
+
const maxOffset = Math.max(0, state.totalSize - state.scrollLength);
|
|
3452
|
+
clampedOffset = Math.min(clampedOffset, maxOffset);
|
|
3453
|
+
}
|
|
3454
|
+
clampedOffset = Math.max(0, clampedOffset);
|
|
3455
|
+
const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
|
|
3456
|
+
refState.current.initialScroll = updatedInitialScroll;
|
|
3457
|
+
state.initialScroll = updatedInitialScroll;
|
|
3458
|
+
refState.current.isStartReached = clampedOffset < refState.current.scrollLength * onStartReachedThreshold;
|
|
3459
|
+
return clampedOffset;
|
|
3460
|
+
}, [renderNum, state.initialScroll]);
|
|
3461
|
+
if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
3258
3462
|
refState.current.lastBatchingAction = Date.now();
|
|
3259
|
-
if (!keyExtractorProp && !
|
|
3463
|
+
if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
|
|
3260
3464
|
IS_DEV && warnDevOnce(
|
|
3261
3465
|
"keyExtractor",
|
|
3262
3466
|
"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."
|
|
3263
3467
|
);
|
|
3264
3468
|
refState.current.sizes.clear();
|
|
3265
3469
|
refState.current.positions.clear();
|
|
3470
|
+
refState.current.totalSize = 0;
|
|
3471
|
+
set$(ctx, "totalSize", 0);
|
|
3266
3472
|
}
|
|
3267
3473
|
}
|
|
3268
3474
|
const onLayoutHeader = useCallback((rect, fromLayoutEffect) => {
|
|
3475
|
+
const { initialScroll } = refState.current;
|
|
3269
3476
|
const size = rect[horizontal ? "width" : "height"];
|
|
3270
3477
|
set$(ctx, "headerSize", size);
|
|
3271
3478
|
if ((initialScroll == null ? void 0 : initialScroll.index) !== void 0) {
|
|
@@ -3276,31 +3483,57 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3276
3483
|
}
|
|
3277
3484
|
}
|
|
3278
3485
|
}, []);
|
|
3486
|
+
const doInitialScroll = useCallback(() => {
|
|
3487
|
+
var _a4;
|
|
3488
|
+
const initialScroll = state.initialScroll;
|
|
3489
|
+
if (initialScroll) {
|
|
3490
|
+
scrollTo(ctx, state, {
|
|
3491
|
+
animated: false,
|
|
3492
|
+
index: (_a4 = state.initialScroll) == null ? void 0 : _a4.index,
|
|
3493
|
+
offset: initialContentOffset,
|
|
3494
|
+
precomputedWithViewOffset: true
|
|
3495
|
+
});
|
|
3496
|
+
}
|
|
3497
|
+
}, [initialContentOffset, state.initialScroll]);
|
|
3498
|
+
const onLayoutChange = useCallback((layout) => {
|
|
3499
|
+
doInitialScroll();
|
|
3500
|
+
handleLayout(ctx, state, layout, setCanRender);
|
|
3501
|
+
}, []);
|
|
3502
|
+
const { onLayout } = useOnLayoutSync({
|
|
3503
|
+
onLayoutChange,
|
|
3504
|
+
onLayoutProp,
|
|
3505
|
+
ref: refScroller
|
|
3506
|
+
// the type of ScrollView doesn't include measure?
|
|
3507
|
+
});
|
|
3279
3508
|
useLayoutEffect(() => {
|
|
3280
3509
|
if (snapToIndices) {
|
|
3281
3510
|
updateSnapToOffsets(ctx, state);
|
|
3282
3511
|
}
|
|
3283
3512
|
}, [snapToIndices]);
|
|
3284
3513
|
useLayoutEffect(() => {
|
|
3285
|
-
const
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
);
|
|
3294
|
-
}
|
|
3295
|
-
|
|
3514
|
+
const {
|
|
3515
|
+
didColumnsChange,
|
|
3516
|
+
didDataChange,
|
|
3517
|
+
isFirst,
|
|
3518
|
+
props: { data }
|
|
3519
|
+
} = state;
|
|
3520
|
+
const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx, state);
|
|
3521
|
+
if (!didAllocateContainers && !isFirst && (didDataChange || didColumnsChange)) {
|
|
3522
|
+
checkResetContainers(ctx, state, data);
|
|
3523
|
+
}
|
|
3524
|
+
state.didColumnsChange = false;
|
|
3525
|
+
state.didDataChange = false;
|
|
3526
|
+
state.isFirst = false;
|
|
3527
|
+
}, [dataProp, dataVersion, numColumnsProp]);
|
|
3296
3528
|
useLayoutEffect(() => {
|
|
3297
3529
|
set$(ctx, "extraData", extraData);
|
|
3298
3530
|
}, [extraData]);
|
|
3299
3531
|
useLayoutEffect(initializeStateVars, [
|
|
3532
|
+
dataVersion,
|
|
3300
3533
|
memoizedLastItemKeys.join(","),
|
|
3301
3534
|
numColumnsProp,
|
|
3302
|
-
|
|
3303
|
-
|
|
3535
|
+
stylePaddingBottomState,
|
|
3536
|
+
stylePaddingTopState
|
|
3304
3537
|
]);
|
|
3305
3538
|
useEffect(() => {
|
|
3306
3539
|
const viewability = setupViewability({
|
|
@@ -3311,103 +3544,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3311
3544
|
state.viewabilityConfigCallbackPairs = viewability;
|
|
3312
3545
|
state.enableScrollForNextCalculateItemsInView = !viewability;
|
|
3313
3546
|
}, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
|
|
3314
|
-
|
|
3315
|
-
handleLayout(ctx, state, layout, setCanRender);
|
|
3316
|
-
}, []);
|
|
3317
|
-
const { onLayout } = useOnLayoutSync({
|
|
3318
|
-
onLayoutChange,
|
|
3319
|
-
onLayoutProp,
|
|
3320
|
-
ref: refScroller
|
|
3321
|
-
// the type of ScrollView doesn't include measure?
|
|
3322
|
-
});
|
|
3323
|
-
useImperativeHandle(forwardedRef, () => {
|
|
3324
|
-
const scrollIndexIntoView = (options) => {
|
|
3325
|
-
const state2 = refState.current;
|
|
3326
|
-
if (state2) {
|
|
3327
|
-
const { index, ...rest2 } = options;
|
|
3328
|
-
const { startNoBuffer, endNoBuffer } = state2;
|
|
3329
|
-
if (index < startNoBuffer || index > endNoBuffer) {
|
|
3330
|
-
const viewPosition = index < startNoBuffer ? 0 : 1;
|
|
3331
|
-
scrollToIndex(ctx, state2, {
|
|
3332
|
-
...rest2,
|
|
3333
|
-
index,
|
|
3334
|
-
viewPosition
|
|
3335
|
-
});
|
|
3336
|
-
}
|
|
3337
|
-
}
|
|
3338
|
-
};
|
|
3339
|
-
return {
|
|
3340
|
-
flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
|
|
3341
|
-
getNativeScrollRef: () => refScroller.current,
|
|
3342
|
-
getScrollableNode: () => refScroller.current.getScrollableNode(),
|
|
3343
|
-
getScrollResponder: () => refScroller.current.getScrollResponder(),
|
|
3344
|
-
getState: () => {
|
|
3345
|
-
const state2 = refState.current;
|
|
3346
|
-
return state2 ? {
|
|
3347
|
-
activeStickyIndex: state2.activeStickyIndex,
|
|
3348
|
-
contentLength: state2.totalSize,
|
|
3349
|
-
data: state2.props.data,
|
|
3350
|
-
end: state2.endNoBuffer,
|
|
3351
|
-
endBuffered: state2.endBuffered,
|
|
3352
|
-
isAtEnd: state2.isAtEnd,
|
|
3353
|
-
isAtStart: state2.isAtStart,
|
|
3354
|
-
positionAtIndex: (index) => state2.positions.get(getId(state2, index)),
|
|
3355
|
-
positions: state2.positions,
|
|
3356
|
-
scroll: state2.scroll,
|
|
3357
|
-
scrollLength: state2.scrollLength,
|
|
3358
|
-
sizeAtIndex: (index) => state2.sizesKnown.get(getId(state2, index)),
|
|
3359
|
-
sizes: state2.sizesKnown,
|
|
3360
|
-
start: state2.startNoBuffer,
|
|
3361
|
-
startBuffered: state2.startBuffered
|
|
3362
|
-
} : {};
|
|
3363
|
-
},
|
|
3364
|
-
scrollIndexIntoView,
|
|
3365
|
-
scrollItemIntoView: ({ item, ...props2 }) => {
|
|
3366
|
-
const data = refState.current.props.data;
|
|
3367
|
-
const index = data.indexOf(item);
|
|
3368
|
-
if (index !== -1) {
|
|
3369
|
-
scrollIndexIntoView({ index, ...props2 });
|
|
3370
|
-
}
|
|
3371
|
-
},
|
|
3372
|
-
scrollToEnd: (options) => {
|
|
3373
|
-
const data = refState.current.props.data;
|
|
3374
|
-
const stylePaddingBottom = refState.current.props.stylePaddingBottom;
|
|
3375
|
-
const index = data.length - 1;
|
|
3376
|
-
if (index !== -1) {
|
|
3377
|
-
const paddingBottom = stylePaddingBottom || 0;
|
|
3378
|
-
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
3379
|
-
scrollToIndex(ctx, state, {
|
|
3380
|
-
index,
|
|
3381
|
-
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
3382
|
-
viewPosition: 1,
|
|
3383
|
-
...options
|
|
3384
|
-
});
|
|
3385
|
-
}
|
|
3386
|
-
},
|
|
3387
|
-
scrollToIndex: (params) => scrollToIndex(ctx, state, params),
|
|
3388
|
-
scrollToItem: ({ item, ...props2 }) => {
|
|
3389
|
-
const data = refState.current.props.data;
|
|
3390
|
-
const index = data.indexOf(item);
|
|
3391
|
-
if (index !== -1) {
|
|
3392
|
-
scrollToIndex(ctx, state, { index, ...props2 });
|
|
3393
|
-
}
|
|
3394
|
-
},
|
|
3395
|
-
scrollToOffset: (params) => scrollTo(state, params),
|
|
3396
|
-
setScrollProcessingEnabled: (enabled) => {
|
|
3397
|
-
refState.current.scrollProcessingEnabled = enabled;
|
|
3398
|
-
},
|
|
3399
|
-
setVisibleContentAnchorOffset: (value) => {
|
|
3400
|
-
const val = typeof value === "function" ? value(peek$(ctx, "scrollAdjustUserOffset") || 0) : value;
|
|
3401
|
-
set$(ctx, "scrollAdjustUserOffset", val);
|
|
3402
|
-
}
|
|
3403
|
-
};
|
|
3404
|
-
}, []);
|
|
3547
|
+
useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx, state), []);
|
|
3405
3548
|
{
|
|
3406
|
-
useEffect(
|
|
3407
|
-
if (initialContentOffset) {
|
|
3408
|
-
scrollTo(state, { animated: false, offset: initialContentOffset, ...initialScroll || {} });
|
|
3409
|
-
}
|
|
3410
|
-
}, []);
|
|
3549
|
+
useEffect(doInitialScroll, []);
|
|
3411
3550
|
}
|
|
3412
3551
|
const fns = useMemo(
|
|
3413
3552
|
() => ({
|
|
@@ -3436,7 +3575,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3436
3575
|
onMomentumScrollEnd: (event) => {
|
|
3437
3576
|
{
|
|
3438
3577
|
requestAnimationFrame(() => {
|
|
3439
|
-
finishScrollTo(refState.current);
|
|
3578
|
+
finishScrollTo(ctx, refState.current);
|
|
3440
3579
|
});
|
|
3441
3580
|
}
|
|
3442
3581
|
if (onMomentumScrollEnd) {
|