@legendapp/list 3.0.0-beta.4 → 3.0.0-beta.40
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/.DS_Store +0 -0
- package/CHANGELOG.md +19 -0
- package/README.md +8 -1
- package/animated.d.ts +607 -5
- package/animated.js +2 -2
- package/animated.mjs +1 -1
- package/index.d.ts +1192 -11
- package/index.js +1989 -946
- package/index.mjs +1988 -947
- package/index.native.js +1758 -866
- package/index.native.mjs +1740 -850
- package/keyboard-test.d.ts +206 -0
- package/keyboard-test.js +34 -0
- package/keyboard-test.mjs +13 -0
- package/keyboard.d.ts +206 -8
- package/keyboard.js +340 -32
- package/keyboard.mjs +343 -34
- package/package.json +52 -1
- package/{types-JPHClxiw.d.mts → react-native.d.ts} +399 -154
- package/{section-list.native.js → react-native.js} +1838 -1094
- package/{section-list.native.mjs → react-native.mjs} +1811 -1077
- package/{types-JPHClxiw.d.ts → react.d.ts} +456 -154
- package/react.js +4812 -0
- package/react.mjs +4782 -0
- package/reanimated.d.ts +618 -7
- package/reanimated.js +156 -30
- package/reanimated.mjs +155 -29
- package/section-list.d.ts +607 -5
- package/section-list.js +38 -3679
- package/section-list.mjs +34 -3676
- package/animated.d.mts +0 -9
- package/index.d.mts +0 -23
- package/index.native.d.mts +0 -23
- package/index.native.d.ts +0 -23
- package/keyboard-controller.d.mts +0 -12
- package/keyboard-controller.d.ts +0 -12
- package/keyboard-controller.js +0 -69
- package/keyboard-controller.mjs +0 -48
- package/keyboard.d.mts +0 -13
- package/reanimated.d.mts +0 -18
- package/section-list.d.mts +0 -113
- package/section-list.native.d.mts +0 -113
- package/section-list.native.d.ts +0 -113
- package/types-YNdphn_A.d.mts +0 -670
- package/types-YNdphn_A.d.ts +0 -670
package/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var React3 = require('react');
|
|
4
4
|
var shim = require('use-sync-external-store/shim');
|
|
5
|
-
var
|
|
5
|
+
var ReactDOM = require('react-dom');
|
|
6
6
|
|
|
7
7
|
function _interopNamespace(e) {
|
|
8
8
|
if (e && e.__esModule) return e;
|
|
@@ -23,6 +23,7 @@ function _interopNamespace(e) {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
|
|
26
|
+
var ReactDOM__namespace = /*#__PURE__*/_interopNamespace(ReactDOM);
|
|
26
27
|
|
|
27
28
|
// src/components/LegendList.tsx
|
|
28
29
|
React3.forwardRef(function AnimatedView2(props, ref) {
|
|
@@ -33,31 +34,63 @@ var View = React3.forwardRef(function View2(props, ref) {
|
|
|
33
34
|
});
|
|
34
35
|
var Text = View;
|
|
35
36
|
|
|
37
|
+
// src/state/getContentInsetEnd.ts
|
|
38
|
+
function getContentInsetEnd(state) {
|
|
39
|
+
var _a3;
|
|
40
|
+
const { props } = state;
|
|
41
|
+
const horizontal = props.horizontal;
|
|
42
|
+
const contentInset = props.contentInset;
|
|
43
|
+
const baseInset = contentInset != null ? contentInset : state.nativeContentInset;
|
|
44
|
+
const overrideInset = (_a3 = state.contentInsetOverride) != null ? _a3 : void 0;
|
|
45
|
+
if (overrideInset) {
|
|
46
|
+
const mergedInset = { bottom: 0, right: 0, ...baseInset, ...overrideInset };
|
|
47
|
+
return (horizontal ? mergedInset.right : mergedInset.bottom) || 0;
|
|
48
|
+
}
|
|
49
|
+
if (baseInset) {
|
|
50
|
+
return (horizontal ? baseInset.right : baseInset.bottom) || 0;
|
|
51
|
+
}
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/state/getContentSize.ts
|
|
56
|
+
function getContentSize(ctx) {
|
|
57
|
+
var _a3;
|
|
58
|
+
const { values, state } = ctx;
|
|
59
|
+
const stylePaddingTop = values.get("stylePaddingTop") || 0;
|
|
60
|
+
const stylePaddingBottom = state.props.stylePaddingBottom || 0;
|
|
61
|
+
const headerSize = values.get("headerSize") || 0;
|
|
62
|
+
const footerSize = values.get("footerSize") || 0;
|
|
63
|
+
const contentInsetBottom = getContentInsetEnd(state);
|
|
64
|
+
const totalSize = (_a3 = state.pendingTotalSize) != null ? _a3 : values.get("totalSize");
|
|
65
|
+
return headerSize + footerSize + totalSize + stylePaddingTop + stylePaddingBottom + (contentInsetBottom || 0);
|
|
66
|
+
}
|
|
67
|
+
|
|
36
68
|
// src/platform/Animated.tsx
|
|
37
69
|
var createAnimatedValue = (value) => value;
|
|
38
70
|
|
|
39
71
|
// src/state/state.tsx
|
|
40
72
|
var ContextState = React3__namespace.createContext(null);
|
|
73
|
+
var contextNum = 0;
|
|
41
74
|
function StateProvider({ children }) {
|
|
42
75
|
const [value] = React3__namespace.useState(() => ({
|
|
43
76
|
animatedScrollY: createAnimatedValue(0),
|
|
44
77
|
columnWrapperStyle: void 0,
|
|
45
|
-
|
|
78
|
+
contextNum: contextNum++,
|
|
46
79
|
listeners: /* @__PURE__ */ new Map(),
|
|
47
80
|
mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
|
|
48
81
|
mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
|
|
49
82
|
mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
|
|
50
83
|
mapViewabilityConfigStates: /* @__PURE__ */ new Map(),
|
|
51
84
|
mapViewabilityValues: /* @__PURE__ */ new Map(),
|
|
85
|
+
positionListeners: /* @__PURE__ */ new Map(),
|
|
86
|
+
state: void 0,
|
|
52
87
|
values: /* @__PURE__ */ new Map([
|
|
53
|
-
["alignItemsPaddingTop", 0],
|
|
54
88
|
["stylePaddingTop", 0],
|
|
55
89
|
["headerSize", 0],
|
|
56
90
|
["numContainers", 0],
|
|
57
|
-
["activeStickyIndex",
|
|
91
|
+
["activeStickyIndex", -1],
|
|
58
92
|
["totalSize", 0],
|
|
59
|
-
["scrollAdjustPending", 0]
|
|
60
|
-
["scrollingTo", void 0]
|
|
93
|
+
["scrollAdjustPending", 0]
|
|
61
94
|
]),
|
|
62
95
|
viewRefs: /* @__PURE__ */ new Map()
|
|
63
96
|
}));
|
|
@@ -125,15 +158,24 @@ function set$(ctx, signalName, value) {
|
|
|
125
158
|
}
|
|
126
159
|
}
|
|
127
160
|
}
|
|
128
|
-
function
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
return
|
|
161
|
+
function listenPosition$(ctx, key, cb) {
|
|
162
|
+
const { positionListeners } = ctx;
|
|
163
|
+
let setListeners = positionListeners.get(key);
|
|
164
|
+
if (!setListeners) {
|
|
165
|
+
setListeners = /* @__PURE__ */ new Set();
|
|
166
|
+
positionListeners.set(key, setListeners);
|
|
167
|
+
}
|
|
168
|
+
setListeners.add(cb);
|
|
169
|
+
return () => setListeners.delete(cb);
|
|
170
|
+
}
|
|
171
|
+
function notifyPosition$(ctx, key, value) {
|
|
172
|
+
const { positionListeners } = ctx;
|
|
173
|
+
const setListeners = positionListeners.get(key);
|
|
174
|
+
if (setListeners) {
|
|
175
|
+
for (const listener of setListeners) {
|
|
176
|
+
listener(value);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
137
179
|
}
|
|
138
180
|
function useArr$(signalNames) {
|
|
139
181
|
const ctx = React3__namespace.useContext(ContextState);
|
|
@@ -152,7 +194,7 @@ function useSelector$(signalName, selector) {
|
|
|
152
194
|
var DebugRow = ({ children }) => {
|
|
153
195
|
return /* @__PURE__ */ React3__namespace.createElement(View, { style: { alignItems: "center", flexDirection: "row", justifyContent: "space-between" } }, children);
|
|
154
196
|
};
|
|
155
|
-
|
|
197
|
+
React3__namespace.memo(function DebugView2({ state }) {
|
|
156
198
|
const ctx = useStateContext();
|
|
157
199
|
const [totalSize = 0, scrollAdjust = 0, rawScroll = 0, scroll = 0, _numContainers = 0, _numContainersPooled = 0] = useArr$([
|
|
158
200
|
"totalSize",
|
|
@@ -204,14 +246,14 @@ var _a;
|
|
|
204
246
|
var envMode = typeof process !== "undefined" && typeof process.env === "object" && process.env ? (_a = process.env.NODE_ENV) != null ? _a : process.env.MODE : void 0;
|
|
205
247
|
var processDev = typeof envMode === "string" ? envMode.toLowerCase() !== "production" : void 0;
|
|
206
248
|
var _a2;
|
|
207
|
-
var IS_DEV = (_a2 =
|
|
249
|
+
var IS_DEV = (_a2 = processDev != null ? processDev : metroDev) != null ? _a2 : false;
|
|
208
250
|
|
|
209
251
|
// src/constants.ts
|
|
210
252
|
var POSITION_OUT_OF_VIEW = -1e7;
|
|
211
253
|
var ENABLE_DEVMODE = IS_DEV && false;
|
|
212
254
|
var ENABLE_DEBUG_VIEW = IS_DEV && false;
|
|
213
|
-
var typedForwardRef =
|
|
214
|
-
var typedMemo =
|
|
255
|
+
var typedForwardRef = React3__namespace.forwardRef;
|
|
256
|
+
var typedMemo = React3__namespace.memo;
|
|
215
257
|
|
|
216
258
|
// src/utils/helpers.ts
|
|
217
259
|
function isFunction(obj) {
|
|
@@ -244,6 +286,11 @@ function extractPadding(style, contentContainerStyle, type) {
|
|
|
244
286
|
return getPadding(style, type) + getPadding(contentContainerStyle, type);
|
|
245
287
|
}
|
|
246
288
|
function findContainerId(ctx, key) {
|
|
289
|
+
var _a3, _b;
|
|
290
|
+
const directMatch = (_b = (_a3 = ctx.state) == null ? void 0 : _a3.containerItemKeys) == null ? void 0 : _b.get(key);
|
|
291
|
+
if (directMatch !== void 0) {
|
|
292
|
+
return directMatch;
|
|
293
|
+
}
|
|
247
294
|
const numContainers = peek$(ctx, "numContainers");
|
|
248
295
|
for (let i = 0; i < numContainers; i++) {
|
|
249
296
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
@@ -255,12 +302,12 @@ function findContainerId(ctx, key) {
|
|
|
255
302
|
}
|
|
256
303
|
|
|
257
304
|
// src/components/PositionView.tsx
|
|
258
|
-
var PositionViewState = typedMemo(function
|
|
305
|
+
var PositionViewState = typedMemo(function PositionViewState2({
|
|
259
306
|
id,
|
|
260
307
|
horizontal,
|
|
261
308
|
style,
|
|
262
309
|
refView,
|
|
263
|
-
...
|
|
310
|
+
...props
|
|
264
311
|
}) {
|
|
265
312
|
const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
|
|
266
313
|
const base = {
|
|
@@ -268,7 +315,15 @@ var PositionViewState = typedMemo(function PositionView({
|
|
|
268
315
|
};
|
|
269
316
|
const composed = isArray(style) ? Object.assign({}, ...style) : style;
|
|
270
317
|
const combinedStyle = horizontal ? { ...base, ...composed, left: position } : { ...base, ...composed, top: position };
|
|
271
|
-
|
|
318
|
+
const {
|
|
319
|
+
animatedScrollY: _animatedScrollY,
|
|
320
|
+
index,
|
|
321
|
+
onLayout: _onLayout,
|
|
322
|
+
onLayoutChange: _onLayoutChange,
|
|
323
|
+
stickyHeaderConfig: _stickyHeaderConfig,
|
|
324
|
+
...webProps
|
|
325
|
+
} = props;
|
|
326
|
+
return /* @__PURE__ */ React3__namespace.createElement("div", { "data-index": index, ref: refView, ...webProps, style: combinedStyle });
|
|
272
327
|
});
|
|
273
328
|
var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
274
329
|
id,
|
|
@@ -276,14 +331,15 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
|
276
331
|
style,
|
|
277
332
|
refView,
|
|
278
333
|
index,
|
|
279
|
-
stickyOffset,
|
|
280
334
|
animatedScrollY: _animatedScrollY,
|
|
335
|
+
stickyHeaderConfig,
|
|
336
|
+
onLayout: _onLayout,
|
|
337
|
+
onLayoutChange: _onLayoutChange,
|
|
281
338
|
children,
|
|
282
|
-
...
|
|
339
|
+
...webProps
|
|
283
340
|
}) {
|
|
284
|
-
const [position = POSITION_OUT_OF_VIEW,
|
|
341
|
+
const [position = POSITION_OUT_OF_VIEW, activeStickyIndex] = useArr$([
|
|
285
342
|
`containerPosition${id}`,
|
|
286
|
-
"headerSize",
|
|
287
343
|
"activeStickyIndex"
|
|
288
344
|
]);
|
|
289
345
|
const base = {
|
|
@@ -300,7 +356,8 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
|
300
356
|
var _a3;
|
|
301
357
|
const styleBase = { ...base, ...composed };
|
|
302
358
|
delete styleBase.transform;
|
|
303
|
-
const
|
|
359
|
+
const stickyConfigOffset = (_a3 = stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.offset) != null ? _a3 : 0;
|
|
360
|
+
const offset = stickyConfigOffset != null ? stickyConfigOffset : 0;
|
|
304
361
|
const isActive = activeStickyIndex === index;
|
|
305
362
|
styleBase.position = isActive ? "sticky" : "absolute";
|
|
306
363
|
styleBase.zIndex = index + 1e3;
|
|
@@ -310,61 +367,89 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
|
310
367
|
styleBase.top = isActive ? offset : position;
|
|
311
368
|
}
|
|
312
369
|
return styleBase;
|
|
313
|
-
}, [composed, horizontal, position, index,
|
|
314
|
-
return /* @__PURE__ */ React3__namespace.createElement(
|
|
370
|
+
}, [composed, horizontal, position, index, activeStickyIndex, stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.offset]);
|
|
371
|
+
return /* @__PURE__ */ React3__namespace.createElement(
|
|
372
|
+
"div",
|
|
373
|
+
{
|
|
374
|
+
"data-index": index,
|
|
375
|
+
ref: refView,
|
|
376
|
+
style: viewStyle,
|
|
377
|
+
...webProps
|
|
378
|
+
},
|
|
379
|
+
children
|
|
380
|
+
);
|
|
315
381
|
});
|
|
316
|
-
var
|
|
317
|
-
|
|
318
|
-
// src/constants-platform.ts
|
|
319
|
-
var IsNewArchitecture = true;
|
|
382
|
+
var PositionView = PositionViewState;
|
|
320
383
|
function useInit(cb) {
|
|
321
384
|
React3.useState(() => cb());
|
|
322
385
|
}
|
|
323
386
|
|
|
324
387
|
// src/state/ContextContainer.ts
|
|
325
388
|
var ContextContainer = React3.createContext(null);
|
|
389
|
+
function useContextContainer() {
|
|
390
|
+
return React3.useContext(ContextContainer);
|
|
391
|
+
}
|
|
326
392
|
function useViewability(callback, configId) {
|
|
327
393
|
const ctx = useStateContext();
|
|
328
|
-
const
|
|
329
|
-
const key = containerId + (configId != null ? configId : "");
|
|
394
|
+
const containerContext = useContextContainer();
|
|
330
395
|
useInit(() => {
|
|
396
|
+
if (!containerContext) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
const { containerId } = containerContext;
|
|
400
|
+
const key = containerId + (configId != null ? configId : "");
|
|
331
401
|
const value = ctx.mapViewabilityValues.get(key);
|
|
332
402
|
if (value) {
|
|
333
403
|
callback(value);
|
|
334
404
|
}
|
|
335
405
|
});
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
406
|
+
React3.useEffect(() => {
|
|
407
|
+
if (!containerContext) {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
const { containerId } = containerContext;
|
|
411
|
+
const key = containerId + (configId != null ? configId : "");
|
|
412
|
+
ctx.mapViewabilityCallbacks.set(key, callback);
|
|
413
|
+
return () => {
|
|
339
414
|
ctx.mapViewabilityCallbacks.delete(key);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
);
|
|
415
|
+
};
|
|
416
|
+
}, [ctx, callback, configId, containerContext]);
|
|
343
417
|
}
|
|
344
418
|
function useViewabilityAmount(callback) {
|
|
345
419
|
const ctx = useStateContext();
|
|
346
|
-
const
|
|
420
|
+
const containerContext = useContextContainer();
|
|
347
421
|
useInit(() => {
|
|
422
|
+
if (!containerContext) {
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
const { containerId } = containerContext;
|
|
348
426
|
const value = ctx.mapViewabilityAmountValues.get(containerId);
|
|
349
427
|
if (value) {
|
|
350
428
|
callback(value);
|
|
351
429
|
}
|
|
352
430
|
});
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
431
|
+
React3.useEffect(() => {
|
|
432
|
+
if (!containerContext) {
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
const { containerId } = containerContext;
|
|
436
|
+
ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
|
|
437
|
+
return () => {
|
|
356
438
|
ctx.mapViewabilityAmountCallbacks.delete(containerId);
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
);
|
|
439
|
+
};
|
|
440
|
+
}, [ctx, callback, containerContext]);
|
|
360
441
|
}
|
|
361
442
|
function useRecyclingEffect(effect) {
|
|
362
|
-
const
|
|
443
|
+
const containerContext = useContextContainer();
|
|
363
444
|
const prevValues = React3.useRef({
|
|
364
445
|
prevIndex: void 0,
|
|
365
446
|
prevItem: void 0
|
|
366
447
|
});
|
|
367
448
|
React3.useEffect(() => {
|
|
449
|
+
if (!containerContext) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
const { index, value } = containerContext;
|
|
368
453
|
let ret;
|
|
369
454
|
if (prevValues.current.prevIndex !== void 0 && prevValues.current.prevItem !== void 0) {
|
|
370
455
|
ret = effect({
|
|
@@ -379,48 +464,73 @@ function useRecyclingEffect(effect) {
|
|
|
379
464
|
prevItem: value
|
|
380
465
|
};
|
|
381
466
|
return ret;
|
|
382
|
-
}, [
|
|
467
|
+
}, [effect, containerContext]);
|
|
383
468
|
}
|
|
384
469
|
function useRecyclingState(valueOrFun) {
|
|
385
|
-
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
|
|
470
|
+
var _a3, _b;
|
|
471
|
+
const containerContext = useContextContainer();
|
|
472
|
+
const computeValue = (ctx) => {
|
|
473
|
+
if (isFunction(valueOrFun)) {
|
|
474
|
+
const initializer = valueOrFun;
|
|
475
|
+
return ctx ? initializer({
|
|
476
|
+
index: ctx.index,
|
|
477
|
+
item: ctx.value,
|
|
478
|
+
prevIndex: void 0,
|
|
479
|
+
prevItem: void 0
|
|
480
|
+
}) : initializer();
|
|
481
|
+
}
|
|
482
|
+
return valueOrFun;
|
|
483
|
+
};
|
|
484
|
+
const [stateValue, setStateValue] = React3.useState(() => {
|
|
485
|
+
return computeValue(containerContext);
|
|
389
486
|
});
|
|
390
|
-
const
|
|
391
|
-
const
|
|
392
|
-
if (
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
index,
|
|
396
|
-
item: value,
|
|
397
|
-
prevIndex: void 0,
|
|
398
|
-
prevItem: void 0
|
|
399
|
-
}) : valueOrFun;
|
|
487
|
+
const prevItemKeyRef = React3.useRef((_a3 = containerContext == null ? void 0 : containerContext.itemKey) != null ? _a3 : null);
|
|
488
|
+
const currentItemKey = (_b = containerContext == null ? void 0 : containerContext.itemKey) != null ? _b : null;
|
|
489
|
+
if (currentItemKey !== null && prevItemKeyRef.current !== currentItemKey) {
|
|
490
|
+
prevItemKeyRef.current = currentItemKey;
|
|
491
|
+
setStateValue(computeValue(containerContext));
|
|
400
492
|
}
|
|
493
|
+
const triggerLayout = containerContext == null ? void 0 : containerContext.triggerLayout;
|
|
401
494
|
const setState = React3.useCallback(
|
|
402
495
|
(newState) => {
|
|
403
|
-
|
|
404
|
-
|
|
496
|
+
if (!triggerLayout) {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
setStateValue((prevValue) => {
|
|
500
|
+
return isFunction(newState) ? newState(prevValue) : newState;
|
|
501
|
+
});
|
|
405
502
|
triggerLayout();
|
|
406
503
|
},
|
|
407
|
-
[triggerLayout
|
|
504
|
+
[triggerLayout]
|
|
408
505
|
);
|
|
409
|
-
return [
|
|
506
|
+
return [stateValue, setState];
|
|
410
507
|
}
|
|
411
508
|
function useIsLastItem() {
|
|
412
|
-
const
|
|
413
|
-
const isLast = useSelector$("lastItemKeys", (lastItemKeys) =>
|
|
509
|
+
const containerContext = useContextContainer();
|
|
510
|
+
const isLast = useSelector$("lastItemKeys", (lastItemKeys) => {
|
|
511
|
+
if (containerContext) {
|
|
512
|
+
const { itemKey } = containerContext;
|
|
513
|
+
if (!isNullOrUndefined(itemKey)) {
|
|
514
|
+
return (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
return false;
|
|
518
|
+
});
|
|
414
519
|
return isLast;
|
|
415
520
|
}
|
|
416
521
|
function useListScrollSize() {
|
|
417
522
|
const [scrollSize] = useArr$(["scrollSize"]);
|
|
418
523
|
return scrollSize;
|
|
419
524
|
}
|
|
525
|
+
var noop = () => {
|
|
526
|
+
};
|
|
420
527
|
function useSyncLayout() {
|
|
421
|
-
|
|
422
|
-
|
|
528
|
+
const containerContext = useContextContainer();
|
|
529
|
+
if (containerContext) {
|
|
530
|
+
const { triggerLayout: syncLayout } = containerContext;
|
|
423
531
|
return syncLayout;
|
|
532
|
+
} else {
|
|
533
|
+
return noop;
|
|
424
534
|
}
|
|
425
535
|
}
|
|
426
536
|
|
|
@@ -466,10 +576,9 @@ function createResizeObserver(element, callback) {
|
|
|
466
576
|
}
|
|
467
577
|
callbacks.add(callback);
|
|
468
578
|
return () => {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
if (callbacks2.size === 0) {
|
|
579
|
+
if (callbacks) {
|
|
580
|
+
callbacks.delete(callback);
|
|
581
|
+
if (callbacks.size === 0) {
|
|
473
582
|
callbackMap.delete(element);
|
|
474
583
|
observer.unobserve(element);
|
|
475
584
|
}
|
|
@@ -481,7 +590,8 @@ function createResizeObserver(element, callback) {
|
|
|
481
590
|
function useOnLayoutSync({
|
|
482
591
|
ref,
|
|
483
592
|
onLayoutProp,
|
|
484
|
-
onLayoutChange
|
|
593
|
+
onLayoutChange,
|
|
594
|
+
webLayoutResync
|
|
485
595
|
}, deps) {
|
|
486
596
|
React3.useLayoutEffect(() => {
|
|
487
597
|
var _a3, _b;
|
|
@@ -504,10 +614,12 @@ function useOnLayoutSync({
|
|
|
504
614
|
return createResizeObserver(element, (entry) => {
|
|
505
615
|
var _a4;
|
|
506
616
|
const target = entry.target instanceof HTMLElement ? entry.target : void 0;
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
617
|
+
const rectObserved = (_a4 = entry.contentRect) != null ? _a4 : target == null ? void 0 : target.getBoundingClientRect();
|
|
618
|
+
const didSizeChange = rectObserved.width !== prevRect.width || rectObserved.height !== prevRect.height;
|
|
619
|
+
const shouldResyncLayout = !!(webLayoutResync == null ? void 0 : webLayoutResync());
|
|
620
|
+
if (didSizeChange || shouldResyncLayout) {
|
|
621
|
+
prevRect = rectObserved;
|
|
622
|
+
emit(toLayout(rectObserved), false);
|
|
511
623
|
}
|
|
512
624
|
});
|
|
513
625
|
}, deps || []);
|
|
@@ -525,6 +637,30 @@ function toLayout(rect) {
|
|
|
525
637
|
};
|
|
526
638
|
}
|
|
527
639
|
|
|
640
|
+
// src/platform/Platform.ts
|
|
641
|
+
var Platform = {
|
|
642
|
+
// Widen the type to avoid unreachable-branch lints in cross-platform code that compares against other OSes
|
|
643
|
+
OS: "web"
|
|
644
|
+
};
|
|
645
|
+
|
|
646
|
+
// src/utils/hasActiveMVCPAnchorLock.ts
|
|
647
|
+
function hasActiveMVCPAnchorLock(state) {
|
|
648
|
+
const lock = state.mvcpAnchorLock;
|
|
649
|
+
if (!lock) {
|
|
650
|
+
return false;
|
|
651
|
+
}
|
|
652
|
+
if (Date.now() > lock.expiresAt) {
|
|
653
|
+
state.mvcpAnchorLock = void 0;
|
|
654
|
+
return false;
|
|
655
|
+
}
|
|
656
|
+
return true;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// src/utils/isInMVCPActiveMode.ts
|
|
660
|
+
function isInMVCPActiveMode(state) {
|
|
661
|
+
return state.dataChangeNeedsScrollUpdate || hasActiveMVCPAnchorLock(state);
|
|
662
|
+
}
|
|
663
|
+
|
|
528
664
|
// src/components/Container.tsx
|
|
529
665
|
var Container = typedMemo(function Container2({
|
|
530
666
|
id,
|
|
@@ -532,22 +668,27 @@ var Container = typedMemo(function Container2({
|
|
|
532
668
|
horizontal,
|
|
533
669
|
getRenderedItem: getRenderedItem2,
|
|
534
670
|
updateItemSize: updateItemSize2,
|
|
535
|
-
ItemSeparatorComponent
|
|
671
|
+
ItemSeparatorComponent,
|
|
672
|
+
stickyHeaderConfig
|
|
536
673
|
}) {
|
|
537
674
|
const ctx = useStateContext();
|
|
538
675
|
const { columnWrapperStyle, animatedScrollY } = ctx;
|
|
539
|
-
const
|
|
676
|
+
const positionComponentInternal = ctx.state.props.positionComponentInternal;
|
|
677
|
+
const stickyPositionComponentInternal = ctx.state.props.stickyPositionComponentInternal;
|
|
678
|
+
const [column = 0, span = 1, data, itemKey, numColumns = 1, extraData, isSticky] = useArr$([
|
|
540
679
|
`containerColumn${id}`,
|
|
680
|
+
`containerSpan${id}`,
|
|
541
681
|
`containerItemData${id}`,
|
|
542
682
|
`containerItemKey${id}`,
|
|
543
683
|
"numColumns",
|
|
544
684
|
"extraData",
|
|
545
|
-
`containerSticky${id}
|
|
546
|
-
`containerStickyOffset${id}`
|
|
685
|
+
`containerSticky${id}`
|
|
547
686
|
]);
|
|
548
687
|
const itemLayoutRef = React3.useRef({
|
|
688
|
+
didLayout: false,
|
|
549
689
|
horizontal,
|
|
550
690
|
itemKey,
|
|
691
|
+
pendingShrinkToken: 0,
|
|
551
692
|
updateItemSize: updateItemSize2
|
|
552
693
|
});
|
|
553
694
|
itemLayoutRef.current.horizontal = horizontal;
|
|
@@ -555,9 +696,10 @@ var Container = typedMemo(function Container2({
|
|
|
555
696
|
itemLayoutRef.current.updateItemSize = updateItemSize2;
|
|
556
697
|
const ref = React3.useRef(null);
|
|
557
698
|
const [layoutRenderCount, forceLayoutRender] = React3.useState(0);
|
|
558
|
-
const
|
|
559
|
-
const
|
|
560
|
-
const
|
|
699
|
+
const resolvedColumn = column > 0 ? column : 1;
|
|
700
|
+
const resolvedSpan = Math.min(Math.max(span || 1, 1), numColumns);
|
|
701
|
+
const otherAxisPos = numColumns > 1 ? `${(resolvedColumn - 1) / numColumns * 100}%` : 0;
|
|
702
|
+
const otherAxisSize = numColumns > 1 ? `${resolvedSpan / numColumns * 100}%` : void 0;
|
|
561
703
|
const style = React3.useMemo(() => {
|
|
562
704
|
let paddingStyles;
|
|
563
705
|
if (columnWrapperStyle) {
|
|
@@ -611,19 +753,41 @@ var Container = typedMemo(function Container2({
|
|
|
611
753
|
const {
|
|
612
754
|
horizontal: currentHorizontal,
|
|
613
755
|
itemKey: currentItemKey,
|
|
614
|
-
updateItemSize: updateItemSizeFn
|
|
756
|
+
updateItemSize: updateItemSizeFn,
|
|
757
|
+
lastSize,
|
|
758
|
+
pendingShrinkToken
|
|
615
759
|
} = itemLayoutRef.current;
|
|
616
760
|
if (isNullOrUndefined(currentItemKey)) {
|
|
617
761
|
return;
|
|
618
762
|
}
|
|
619
|
-
|
|
763
|
+
itemLayoutRef.current.didLayout = true;
|
|
620
764
|
let layout = rectangle;
|
|
621
|
-
|
|
765
|
+
const axis = currentHorizontal ? "width" : "height";
|
|
766
|
+
const size = roundSize(rectangle[axis]);
|
|
767
|
+
const prevSize = lastSize ? roundSize(lastSize[axis]) : void 0;
|
|
622
768
|
const doUpdate = () => {
|
|
623
|
-
itemLayoutRef.current.lastSize =
|
|
769
|
+
itemLayoutRef.current.lastSize = layout;
|
|
624
770
|
updateItemSizeFn(currentItemKey, layout);
|
|
625
|
-
|
|
771
|
+
itemLayoutRef.current.didLayout = true;
|
|
626
772
|
};
|
|
773
|
+
const shouldDeferWebShrinkLayoutUpdate = !isInMVCPActiveMode(ctx.state) && prevSize !== void 0 && size + 1 < prevSize;
|
|
774
|
+
if (shouldDeferWebShrinkLayoutUpdate) {
|
|
775
|
+
const token = pendingShrinkToken + 1;
|
|
776
|
+
itemLayoutRef.current.pendingShrinkToken = token;
|
|
777
|
+
requestAnimationFrame(() => {
|
|
778
|
+
var _a4;
|
|
779
|
+
if (itemLayoutRef.current.pendingShrinkToken !== token) {
|
|
780
|
+
return;
|
|
781
|
+
}
|
|
782
|
+
const element = ref.current;
|
|
783
|
+
const rect = (_a4 = element == null ? void 0 : element.getBoundingClientRect) == null ? void 0 : _a4.call(element);
|
|
784
|
+
if (rect) {
|
|
785
|
+
layout = { height: rect.height, width: rect.width };
|
|
786
|
+
}
|
|
787
|
+
doUpdate();
|
|
788
|
+
});
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
627
791
|
{
|
|
628
792
|
doUpdate();
|
|
629
793
|
}
|
|
@@ -631,11 +795,12 @@ var Container = typedMemo(function Container2({
|
|
|
631
795
|
const { onLayout } = useOnLayoutSync(
|
|
632
796
|
{
|
|
633
797
|
onLayoutChange,
|
|
634
|
-
ref
|
|
798
|
+
ref,
|
|
799
|
+
webLayoutResync: () => isInMVCPActiveMode(ctx.state)
|
|
635
800
|
},
|
|
636
801
|
[itemKey, layoutRenderCount]
|
|
637
802
|
);
|
|
638
|
-
const PositionComponent = isSticky ? PositionViewSticky :
|
|
803
|
+
const PositionComponent = isSticky ? stickyPositionComponentInternal ? stickyPositionComponentInternal : PositionViewSticky : positionComponentInternal ? positionComponentInternal : PositionView;
|
|
639
804
|
return /* @__PURE__ */ React3__namespace.createElement(
|
|
640
805
|
PositionComponent,
|
|
641
806
|
{
|
|
@@ -646,23 +811,21 @@ var Container = typedMemo(function Container2({
|
|
|
646
811
|
key: recycleItems ? void 0 : itemKey,
|
|
647
812
|
onLayout,
|
|
648
813
|
refView: ref,
|
|
649
|
-
|
|
814
|
+
stickyHeaderConfig,
|
|
650
815
|
style
|
|
651
816
|
},
|
|
652
817
|
/* @__PURE__ */ React3__namespace.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React3__namespace.createElement(Separator, { ItemSeparatorComponent, leadingItem: renderedItemInfo.item }))
|
|
653
818
|
);
|
|
654
819
|
});
|
|
655
820
|
|
|
656
|
-
// src/platform/Platform.ts
|
|
657
|
-
var Platform = {
|
|
658
|
-
// Widen the type to avoid unreachable-branch lints in cross-platform code that compares against other OSes
|
|
659
|
-
OS: "web"
|
|
660
|
-
};
|
|
661
|
-
|
|
662
821
|
// src/utils/reordering.ts
|
|
663
822
|
var mapFn = (element) => {
|
|
664
|
-
const indexStr = element.getAttribute("index");
|
|
665
|
-
|
|
823
|
+
const indexStr = element.getAttribute("data-index");
|
|
824
|
+
if (indexStr === null) {
|
|
825
|
+
return [element, null];
|
|
826
|
+
}
|
|
827
|
+
const index = Number.parseInt(indexStr, 10);
|
|
828
|
+
return [element, Number.isNaN(index) ? null : index];
|
|
666
829
|
};
|
|
667
830
|
function sortDOMElements(container) {
|
|
668
831
|
const elements = Array.from(container.children);
|
|
@@ -805,7 +968,8 @@ var Containers = typedMemo(function Containers2({
|
|
|
805
968
|
ItemSeparatorComponent,
|
|
806
969
|
waitForInitialLayout,
|
|
807
970
|
updateItemSize: updateItemSize2,
|
|
808
|
-
getRenderedItem: getRenderedItem2
|
|
971
|
+
getRenderedItem: getRenderedItem2,
|
|
972
|
+
stickyHeaderConfig
|
|
809
973
|
}) {
|
|
810
974
|
const [numContainers, numColumns] = useArr$(["numContainersPooled", "numColumns"]);
|
|
811
975
|
const containers = [];
|
|
@@ -820,6 +984,7 @@ var Containers = typedMemo(function Containers2({
|
|
|
820
984
|
id: i,
|
|
821
985
|
key: i,
|
|
822
986
|
recycleItems,
|
|
987
|
+
stickyHeaderConfig,
|
|
823
988
|
updateItemSize: updateItemSize2
|
|
824
989
|
}
|
|
825
990
|
)
|
|
@@ -827,24 +992,6 @@ var Containers = typedMemo(function Containers2({
|
|
|
827
992
|
}
|
|
828
993
|
return /* @__PURE__ */ React3__namespace.createElement(ContainersInner, { horizontal, numColumns, waitForInitialLayout }, containers);
|
|
829
994
|
});
|
|
830
|
-
function DevNumbers() {
|
|
831
|
-
return IS_DEV && React3__namespace.memo(function DevNumbers2() {
|
|
832
|
-
return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React3__namespace.createElement(
|
|
833
|
-
"div",
|
|
834
|
-
{
|
|
835
|
-
key: index,
|
|
836
|
-
style: {
|
|
837
|
-
height: 100,
|
|
838
|
-
pointerEvents: "none",
|
|
839
|
-
position: "absolute",
|
|
840
|
-
top: index * 100,
|
|
841
|
-
width: "100%"
|
|
842
|
-
}
|
|
843
|
-
},
|
|
844
|
-
/* @__PURE__ */ React3__namespace.createElement("div", { style: { color: "red" } }, index * 100)
|
|
845
|
-
));
|
|
846
|
-
});
|
|
847
|
-
}
|
|
848
995
|
|
|
849
996
|
// src/platform/StyleSheet.tsx
|
|
850
997
|
function flattenStyles(styles) {
|
|
@@ -858,6 +1005,89 @@ var StyleSheet = {
|
|
|
858
1005
|
flatten: (style) => flattenStyles(style)
|
|
859
1006
|
};
|
|
860
1007
|
|
|
1008
|
+
// src/components/webScrollUtils.ts
|
|
1009
|
+
function getDocumentScrollerNode() {
|
|
1010
|
+
if (typeof document === "undefined") {
|
|
1011
|
+
return null;
|
|
1012
|
+
}
|
|
1013
|
+
return document.scrollingElement || document.documentElement || document.body;
|
|
1014
|
+
}
|
|
1015
|
+
function getWindowScrollPosition() {
|
|
1016
|
+
var _a3, _b, _c, _d;
|
|
1017
|
+
if (typeof window === "undefined") {
|
|
1018
|
+
return { x: 0, y: 0 };
|
|
1019
|
+
}
|
|
1020
|
+
return {
|
|
1021
|
+
x: (_b = (_a3 = window.scrollX) != null ? _a3 : window.pageXOffset) != null ? _b : 0,
|
|
1022
|
+
y: (_d = (_c = window.scrollY) != null ? _c : window.pageYOffset) != null ? _d : 0
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
1025
|
+
function getElementDocumentPosition(element, scroll) {
|
|
1026
|
+
var _a3, _b;
|
|
1027
|
+
const rect = element == null ? void 0 : element.getBoundingClientRect();
|
|
1028
|
+
return {
|
|
1029
|
+
left: ((_a3 = rect == null ? void 0 : rect.left) != null ? _a3 : 0) + scroll.x,
|
|
1030
|
+
top: ((_b = rect == null ? void 0 : rect.top) != null ? _b : 0) + scroll.y
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
function getContentSize2(content) {
|
|
1034
|
+
var _a3, _b;
|
|
1035
|
+
return {
|
|
1036
|
+
height: (_a3 = content == null ? void 0 : content.scrollHeight) != null ? _a3 : 0,
|
|
1037
|
+
width: (_b = content == null ? void 0 : content.scrollWidth) != null ? _b : 0
|
|
1038
|
+
};
|
|
1039
|
+
}
|
|
1040
|
+
function getScrollContentSize(scrollElement, contentElement, isWindowScroll) {
|
|
1041
|
+
return getContentSize2(isWindowScroll ? contentElement : scrollElement);
|
|
1042
|
+
}
|
|
1043
|
+
function getLayoutMeasurement(scrollElement, isWindowScroll, horizontal) {
|
|
1044
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
1045
|
+
if (isWindowScroll && typeof window !== "undefined") {
|
|
1046
|
+
const rect = scrollElement == null ? void 0 : scrollElement.getBoundingClientRect();
|
|
1047
|
+
return {
|
|
1048
|
+
// In window-scroll mode, use viewport size on the scroll axis.
|
|
1049
|
+
height: horizontal ? (_b = (_a3 = rect == null ? void 0 : rect.height) != null ? _a3 : scrollElement == null ? void 0 : scrollElement.clientHeight) != null ? _b : window.innerHeight : window.innerHeight,
|
|
1050
|
+
// Keep the cross-axis size list-relative to avoid inflating container measurements.
|
|
1051
|
+
width: horizontal ? window.innerWidth : (_d = (_c = rect == null ? void 0 : rect.width) != null ? _c : scrollElement == null ? void 0 : scrollElement.clientWidth) != null ? _d : window.innerWidth
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
return {
|
|
1055
|
+
height: (_e = scrollElement == null ? void 0 : scrollElement.clientHeight) != null ? _e : 0,
|
|
1056
|
+
width: (_f = scrollElement == null ? void 0 : scrollElement.clientWidth) != null ? _f : 0
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
function clampOffset(offset, maxOffset) {
|
|
1060
|
+
return Math.max(0, Math.min(offset, maxOffset));
|
|
1061
|
+
}
|
|
1062
|
+
function getAxisSize(size, horizontal) {
|
|
1063
|
+
return horizontal ? size.width : size.height;
|
|
1064
|
+
}
|
|
1065
|
+
function getMaxOffset(contentSize, layoutMeasurement, horizontal) {
|
|
1066
|
+
return Math.max(0, getAxisSize(contentSize, horizontal) - getAxisSize(layoutMeasurement, horizontal));
|
|
1067
|
+
}
|
|
1068
|
+
function resolveScrollableNode(scrollElement, isWindowScroll) {
|
|
1069
|
+
return isWindowScroll ? getDocumentScrollerNode() || scrollElement : scrollElement;
|
|
1070
|
+
}
|
|
1071
|
+
function resolveScrollEventTarget(scrollElement, isWindowScroll) {
|
|
1072
|
+
return isWindowScroll && typeof window !== "undefined" ? window : scrollElement;
|
|
1073
|
+
}
|
|
1074
|
+
function getLayoutRectangle(element, isWindowScroll, horizontal) {
|
|
1075
|
+
const rect = element.getBoundingClientRect();
|
|
1076
|
+
const scroll = getWindowScrollPosition();
|
|
1077
|
+
return {
|
|
1078
|
+
height: isWindowScroll && typeof window !== "undefined" && !horizontal ? window.innerHeight : rect.height,
|
|
1079
|
+
width: isWindowScroll && typeof window !== "undefined" && horizontal ? window.innerWidth : rect.width,
|
|
1080
|
+
x: isWindowScroll ? rect.left + scroll.x : rect.left,
|
|
1081
|
+
y: isWindowScroll ? rect.top + scroll.y : rect.top
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
1084
|
+
function resolveWindowScrollTarget({ clampedOffset, horizontal, listPos, scroll }) {
|
|
1085
|
+
return {
|
|
1086
|
+
left: horizontal ? listPos.left + clampedOffset : scroll.x,
|
|
1087
|
+
top: horizontal ? scroll.y : listPos.top + clampedOffset
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
1090
|
+
|
|
861
1091
|
// src/components/ListComponentScrollView.tsx
|
|
862
1092
|
var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView2({
|
|
863
1093
|
children,
|
|
@@ -867,125 +1097,163 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
|
|
|
867
1097
|
contentOffset,
|
|
868
1098
|
maintainVisibleContentPosition,
|
|
869
1099
|
onScroll: onScroll2,
|
|
870
|
-
onMomentumScrollEnd,
|
|
1100
|
+
onMomentumScrollEnd: _onMomentumScrollEnd,
|
|
871
1101
|
showsHorizontalScrollIndicator = true,
|
|
872
1102
|
showsVerticalScrollIndicator = true,
|
|
873
1103
|
refreshControl,
|
|
1104
|
+
useWindowScroll = false,
|
|
874
1105
|
onLayout,
|
|
875
1106
|
...props
|
|
876
1107
|
}, ref) {
|
|
877
1108
|
const scrollRef = React3.useRef(null);
|
|
878
1109
|
const contentRef = React3.useRef(null);
|
|
879
|
-
const
|
|
1110
|
+
const isWindowScroll = useWindowScroll;
|
|
1111
|
+
const getScrollTarget = React3.useCallback(
|
|
1112
|
+
() => resolveScrollEventTarget(scrollRef.current, isWindowScroll),
|
|
1113
|
+
[isWindowScroll]
|
|
1114
|
+
);
|
|
1115
|
+
const getMaxScrollOffset = React3.useCallback(() => {
|
|
1116
|
+
const scrollElement = scrollRef.current;
|
|
1117
|
+
const contentSize = getScrollContentSize(scrollElement, contentRef.current, isWindowScroll);
|
|
1118
|
+
const layoutMeasurement = getLayoutMeasurement(scrollElement, isWindowScroll, horizontal);
|
|
1119
|
+
return getMaxOffset(contentSize, layoutMeasurement, horizontal);
|
|
1120
|
+
}, [horizontal, isWindowScroll]);
|
|
1121
|
+
const getCurrentScrollOffset = React3.useCallback(() => {
|
|
1122
|
+
const scrollElement = scrollRef.current;
|
|
1123
|
+
if (isWindowScroll) {
|
|
1124
|
+
const maxOffset = getMaxScrollOffset();
|
|
1125
|
+
const scroll = getWindowScrollPosition();
|
|
1126
|
+
const listPos = getElementDocumentPosition(scrollElement, scroll);
|
|
1127
|
+
const rawOffset = horizontal ? scroll.x - listPos.left : scroll.y - listPos.top;
|
|
1128
|
+
return clampOffset(rawOffset, maxOffset);
|
|
1129
|
+
}
|
|
1130
|
+
if (!scrollElement) {
|
|
1131
|
+
return 0;
|
|
1132
|
+
}
|
|
1133
|
+
return horizontal ? scrollElement.scrollLeft : scrollElement.scrollTop;
|
|
1134
|
+
}, [getMaxScrollOffset, horizontal, isWindowScroll]);
|
|
1135
|
+
const scrollToLocalOffset = React3.useCallback(
|
|
1136
|
+
(offset, animated) => {
|
|
1137
|
+
const scrollElement = scrollRef.current;
|
|
1138
|
+
const target = getScrollTarget();
|
|
1139
|
+
if (!target || typeof target.scrollTo !== "function") {
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1142
|
+
const maxOffset = getMaxScrollOffset();
|
|
1143
|
+
const clampedOffset = clampOffset(offset, maxOffset);
|
|
1144
|
+
const behavior = animated ? "smooth" : "auto";
|
|
1145
|
+
const options = { behavior };
|
|
1146
|
+
if (isWindowScroll) {
|
|
1147
|
+
const scroll = getWindowScrollPosition();
|
|
1148
|
+
const listPos = getElementDocumentPosition(scrollElement, scroll);
|
|
1149
|
+
const { left, top } = resolveWindowScrollTarget({
|
|
1150
|
+
clampedOffset,
|
|
1151
|
+
horizontal,
|
|
1152
|
+
listPos,
|
|
1153
|
+
scroll
|
|
1154
|
+
});
|
|
1155
|
+
options.left = left;
|
|
1156
|
+
options.top = top;
|
|
1157
|
+
} else if (horizontal) {
|
|
1158
|
+
options.left = clampedOffset;
|
|
1159
|
+
} else {
|
|
1160
|
+
options.top = clampedOffset;
|
|
1161
|
+
}
|
|
1162
|
+
target.scrollTo(options);
|
|
1163
|
+
},
|
|
1164
|
+
[getMaxScrollOffset, getScrollTarget, horizontal, isWindowScroll]
|
|
1165
|
+
);
|
|
880
1166
|
React3.useImperativeHandle(ref, () => {
|
|
881
1167
|
const api = {
|
|
882
1168
|
getBoundingClientRect: () => {
|
|
883
1169
|
var _a3;
|
|
884
1170
|
return (_a3 = scrollRef.current) == null ? void 0 : _a3.getBoundingClientRect();
|
|
885
1171
|
},
|
|
886
|
-
|
|
887
|
-
|
|
1172
|
+
getContentNode: () => contentRef.current,
|
|
1173
|
+
getCurrentScrollOffset,
|
|
1174
|
+
getScrollableNode: () => resolveScrollableNode(scrollRef.current, isWindowScroll),
|
|
1175
|
+
getScrollEventTarget: () => getScrollTarget(),
|
|
1176
|
+
getScrollResponder: () => resolveScrollableNode(scrollRef.current, isWindowScroll),
|
|
1177
|
+
isWindowScroll: () => isWindowScroll,
|
|
888
1178
|
scrollBy: (x, y) => {
|
|
889
|
-
const
|
|
890
|
-
if (!
|
|
891
|
-
|
|
1179
|
+
const target = getScrollTarget();
|
|
1180
|
+
if (!target || typeof target.scrollBy !== "function") {
|
|
1181
|
+
return;
|
|
1182
|
+
}
|
|
1183
|
+
target.scrollBy({ behavior: "auto", left: x, top: y });
|
|
892
1184
|
},
|
|
893
1185
|
scrollTo: (options) => {
|
|
894
|
-
const el = scrollRef.current;
|
|
895
|
-
if (!el) return;
|
|
896
1186
|
const { x = 0, y = 0, animated = true } = options;
|
|
897
|
-
|
|
1187
|
+
scrollToLocalOffset(horizontal ? x : y, animated);
|
|
898
1188
|
},
|
|
899
1189
|
scrollToEnd: (options = {}) => {
|
|
900
|
-
const el = scrollRef.current;
|
|
901
|
-
if (!el) return;
|
|
902
1190
|
const { animated = true } = options;
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
} else {
|
|
906
|
-
el.scrollTo({ behavior: animated ? "smooth" : "auto", top: el.scrollHeight });
|
|
907
|
-
}
|
|
1191
|
+
const endOffset = getMaxScrollOffset();
|
|
1192
|
+
scrollToLocalOffset(endOffset, animated);
|
|
908
1193
|
},
|
|
909
1194
|
scrollToOffset: (params) => {
|
|
910
|
-
const el = scrollRef.current;
|
|
911
|
-
if (!el) return;
|
|
912
1195
|
const { offset, animated = true } = params;
|
|
913
|
-
|
|
914
|
-
el.scrollTo({ behavior: animated ? "smooth" : "auto", left: offset });
|
|
915
|
-
} else {
|
|
916
|
-
el.scrollTo({ behavior: animated ? "smooth" : "auto", top: offset });
|
|
917
|
-
}
|
|
1196
|
+
scrollToLocalOffset(offset, animated);
|
|
918
1197
|
}
|
|
919
1198
|
};
|
|
920
1199
|
return api;
|
|
921
|
-
}, [horizontal]);
|
|
1200
|
+
}, [getCurrentScrollOffset, getMaxScrollOffset, getScrollTarget, horizontal, isWindowScroll, scrollToLocalOffset]);
|
|
922
1201
|
const handleScroll = React3.useCallback(
|
|
923
|
-
(
|
|
924
|
-
if (!onScroll2
|
|
1202
|
+
(_event) => {
|
|
1203
|
+
if (!onScroll2) {
|
|
1204
|
+
return;
|
|
1205
|
+
}
|
|
1206
|
+
const target = scrollRef.current;
|
|
1207
|
+
if (!target) {
|
|
925
1208
|
return;
|
|
926
1209
|
}
|
|
927
|
-
const
|
|
1210
|
+
const contentSize = getContentSize2(contentRef.current);
|
|
1211
|
+
const layoutMeasurement = getLayoutMeasurement(scrollRef.current, isWindowScroll, horizontal);
|
|
1212
|
+
const offset = getCurrentScrollOffset();
|
|
928
1213
|
const scrollEvent = {
|
|
929
1214
|
nativeEvent: {
|
|
930
1215
|
contentOffset: {
|
|
931
|
-
x:
|
|
932
|
-
y:
|
|
1216
|
+
x: horizontal ? offset : 0,
|
|
1217
|
+
y: horizontal ? 0 : offset
|
|
933
1218
|
},
|
|
934
1219
|
contentSize: {
|
|
935
|
-
height:
|
|
936
|
-
width:
|
|
1220
|
+
height: contentSize.height,
|
|
1221
|
+
width: contentSize.width
|
|
937
1222
|
},
|
|
938
1223
|
layoutMeasurement: {
|
|
939
|
-
height:
|
|
940
|
-
width:
|
|
1224
|
+
height: layoutMeasurement.height,
|
|
1225
|
+
width: layoutMeasurement.width
|
|
941
1226
|
}
|
|
942
1227
|
}
|
|
943
1228
|
};
|
|
944
1229
|
onScroll2(scrollEvent);
|
|
945
|
-
if (onMomentumScrollEnd) {
|
|
946
|
-
if (momentumTimeout.current != null) clearTimeout(momentumTimeout.current);
|
|
947
|
-
momentumTimeout.current = setTimeout(() => {
|
|
948
|
-
onMomentumScrollEnd({
|
|
949
|
-
nativeEvent: {
|
|
950
|
-
contentOffset: scrollEvent.nativeEvent.contentOffset
|
|
951
|
-
}
|
|
952
|
-
});
|
|
953
|
-
}, 100);
|
|
954
|
-
}
|
|
955
1230
|
},
|
|
956
|
-
[
|
|
1231
|
+
[getCurrentScrollOffset, horizontal, isWindowScroll, onScroll2]
|
|
957
1232
|
);
|
|
958
1233
|
React3.useLayoutEffect(() => {
|
|
959
|
-
const
|
|
960
|
-
if (!
|
|
961
|
-
|
|
1234
|
+
const target = getScrollTarget();
|
|
1235
|
+
if (!target) return;
|
|
1236
|
+
target.addEventListener("scroll", handleScroll, { passive: true });
|
|
962
1237
|
return () => {
|
|
963
|
-
|
|
1238
|
+
target.removeEventListener("scroll", handleScroll);
|
|
964
1239
|
};
|
|
965
|
-
}, [handleScroll]);
|
|
1240
|
+
}, [getScrollTarget, handleScroll]);
|
|
966
1241
|
React3.useEffect(() => {
|
|
967
1242
|
const doScroll = () => {
|
|
968
|
-
if (contentOffset
|
|
969
|
-
|
|
970
|
-
scrollRef.current.scrollTop = contentOffset.y || 0;
|
|
1243
|
+
if (contentOffset) {
|
|
1244
|
+
scrollToLocalOffset(horizontal ? contentOffset.x || 0 : contentOffset.y || 0, false);
|
|
971
1245
|
}
|
|
972
1246
|
};
|
|
973
1247
|
doScroll();
|
|
974
1248
|
requestAnimationFrame(doScroll);
|
|
975
|
-
}, [contentOffset == null ? void 0 : contentOffset.x, contentOffset == null ? void 0 : contentOffset.y]);
|
|
1249
|
+
}, [contentOffset == null ? void 0 : contentOffset.x, contentOffset == null ? void 0 : contentOffset.y, horizontal, scrollToLocalOffset]);
|
|
976
1250
|
React3.useLayoutEffect(() => {
|
|
977
1251
|
if (!onLayout || !scrollRef.current) return;
|
|
978
1252
|
const element = scrollRef.current;
|
|
979
1253
|
const fireLayout = () => {
|
|
980
|
-
const rect = element.getBoundingClientRect();
|
|
981
1254
|
onLayout({
|
|
982
1255
|
nativeEvent: {
|
|
983
|
-
layout:
|
|
984
|
-
height: rect.height,
|
|
985
|
-
width: rect.width,
|
|
986
|
-
x: rect.left,
|
|
987
|
-
y: rect.top
|
|
988
|
-
}
|
|
1256
|
+
layout: getLayoutRectangle(element, isWindowScroll, horizontal)
|
|
989
1257
|
}
|
|
990
1258
|
});
|
|
991
1259
|
};
|
|
@@ -994,16 +1262,27 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
|
|
|
994
1262
|
fireLayout();
|
|
995
1263
|
});
|
|
996
1264
|
resizeObserver.observe(element);
|
|
997
|
-
|
|
998
|
-
|
|
1265
|
+
const onWindowResize = () => {
|
|
1266
|
+
fireLayout();
|
|
1267
|
+
};
|
|
1268
|
+
if (isWindowScroll && typeof window !== "undefined" && typeof window.addEventListener === "function") {
|
|
1269
|
+
window.addEventListener("resize", onWindowResize);
|
|
1270
|
+
}
|
|
1271
|
+
return () => {
|
|
1272
|
+
resizeObserver.disconnect();
|
|
1273
|
+
if (isWindowScroll && typeof window !== "undefined" && typeof window.removeEventListener === "function") {
|
|
1274
|
+
window.removeEventListener("resize", onWindowResize);
|
|
1275
|
+
}
|
|
1276
|
+
};
|
|
1277
|
+
}, [isWindowScroll, onLayout]);
|
|
999
1278
|
const scrollViewStyle = {
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1279
|
+
...isWindowScroll ? {} : {
|
|
1280
|
+
overflow: "auto",
|
|
1281
|
+
overflowX: horizontal ? "auto" : showsHorizontalScrollIndicator ? "auto" : "hidden",
|
|
1282
|
+
overflowY: horizontal ? showsVerticalScrollIndicator ? "auto" : "hidden" : "auto",
|
|
1283
|
+
WebkitOverflowScrolling: "touch"
|
|
1284
|
+
// iOS momentum scrolling
|
|
1285
|
+
},
|
|
1007
1286
|
...StyleSheet.flatten(style)
|
|
1008
1287
|
};
|
|
1009
1288
|
const contentStyle = {
|
|
@@ -1013,28 +1292,15 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
|
|
|
1013
1292
|
minWidth: horizontal ? "100%" : void 0,
|
|
1014
1293
|
...StyleSheet.flatten(contentContainerStyle)
|
|
1015
1294
|
};
|
|
1016
|
-
|
|
1295
|
+
const {
|
|
1296
|
+
contentInset: _contentInset,
|
|
1297
|
+
scrollEventThrottle: _scrollEventThrottle,
|
|
1298
|
+
ScrollComponent: _ScrollComponent,
|
|
1299
|
+
useWindowScroll: _useWindowScroll,
|
|
1300
|
+
...webProps
|
|
1301
|
+
} = props;
|
|
1302
|
+
return /* @__PURE__ */ React3__namespace.createElement("div", { ref: scrollRef, ...webProps, style: scrollViewStyle }, refreshControl, /* @__PURE__ */ React3__namespace.createElement("div", { ref: contentRef, style: contentStyle }, children));
|
|
1017
1303
|
});
|
|
1018
|
-
function Padding() {
|
|
1019
|
-
const [paddingTop] = useArr$(["alignItemsPaddingTop"]);
|
|
1020
|
-
return /* @__PURE__ */ React3__namespace.createElement("div", { style: { paddingTop } });
|
|
1021
|
-
}
|
|
1022
|
-
function PaddingDevMode() {
|
|
1023
|
-
const [paddingTop] = useArr$(["alignItemsPaddingTop"]);
|
|
1024
|
-
return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement("div", { style: { paddingTop } }), /* @__PURE__ */ React3__namespace.createElement(
|
|
1025
|
-
"div",
|
|
1026
|
-
{
|
|
1027
|
-
style: {
|
|
1028
|
-
backgroundColor: "green",
|
|
1029
|
-
height: paddingTop,
|
|
1030
|
-
left: 0,
|
|
1031
|
-
position: "absolute",
|
|
1032
|
-
right: 0,
|
|
1033
|
-
top: 0
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1036
|
-
));
|
|
1037
|
-
}
|
|
1038
1304
|
function useValueListener$(key, callback) {
|
|
1039
1305
|
const ctx = useStateContext();
|
|
1040
1306
|
React3.useLayoutEffect(() => {
|
|
@@ -1049,35 +1315,43 @@ function useValueListener$(key, callback) {
|
|
|
1049
1315
|
function ScrollAdjust() {
|
|
1050
1316
|
const ctx = useStateContext();
|
|
1051
1317
|
const lastScrollOffsetRef = React3__namespace.useRef(0);
|
|
1318
|
+
const resetPaddingRafRef = React3__namespace.useRef(void 0);
|
|
1052
1319
|
const callback = React3__namespace.useCallback(() => {
|
|
1053
1320
|
var _a3;
|
|
1054
1321
|
const scrollAdjust = peek$(ctx, "scrollAdjust");
|
|
1055
1322
|
const scrollAdjustUserOffset = peek$(ctx, "scrollAdjustUserOffset");
|
|
1056
1323
|
const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0);
|
|
1057
|
-
const scrollView = (_a3 = ctx.
|
|
1324
|
+
const scrollView = (_a3 = ctx.state) == null ? void 0 : _a3.refScroller.current;
|
|
1058
1325
|
if (scrollView && scrollOffset !== lastScrollOffsetRef.current) {
|
|
1059
1326
|
const scrollDelta = scrollOffset - lastScrollOffsetRef.current;
|
|
1060
1327
|
if (scrollDelta !== 0) {
|
|
1328
|
+
const contentNode = scrollView.getContentNode();
|
|
1329
|
+
const prevScroll = scrollView.getCurrentScrollOffset();
|
|
1061
1330
|
const el = scrollView.getScrollableNode();
|
|
1062
|
-
|
|
1331
|
+
if (!contentNode) {
|
|
1332
|
+
scrollView.scrollBy(0, scrollDelta);
|
|
1333
|
+
lastScrollOffsetRef.current = scrollOffset;
|
|
1334
|
+
return;
|
|
1335
|
+
}
|
|
1336
|
+
const totalSize = contentNode.scrollHeight;
|
|
1337
|
+
const viewportSize = el.clientHeight;
|
|
1063
1338
|
const nextScroll = prevScroll + scrollDelta;
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
const
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
child.style.paddingBottom = `${pad}px`;
|
|
1070
|
-
void el.offsetHeight;
|
|
1339
|
+
if (scrollDelta > 0 && !ctx.state.adjustingFromInitialMount && totalSize < nextScroll + viewportSize) {
|
|
1340
|
+
const paddingBottom = ctx.state.props.stylePaddingBottom || 0;
|
|
1341
|
+
const pad = (nextScroll + viewportSize - totalSize) * 2;
|
|
1342
|
+
contentNode.style.paddingBottom = `${pad}px`;
|
|
1343
|
+
void contentNode.offsetHeight;
|
|
1071
1344
|
scrollView.scrollBy(0, scrollDelta);
|
|
1072
|
-
|
|
1073
|
-
|
|
1345
|
+
if (resetPaddingRafRef.current !== void 0) {
|
|
1346
|
+
cancelAnimationFrame(resetPaddingRafRef.current);
|
|
1347
|
+
}
|
|
1348
|
+
resetPaddingRafRef.current = requestAnimationFrame(() => {
|
|
1349
|
+
resetPaddingRafRef.current = void 0;
|
|
1350
|
+
contentNode.style.paddingBottom = paddingBottom ? `${paddingBottom}px` : "0";
|
|
1074
1351
|
});
|
|
1075
1352
|
} else {
|
|
1076
1353
|
scrollView.scrollBy(0, scrollDelta);
|
|
1077
1354
|
}
|
|
1078
|
-
if (IS_DEV) {
|
|
1079
|
-
console.log("ScrollAdjust (web scrollBy)", scrollDelta, "total offset:", scrollOffset);
|
|
1080
|
-
}
|
|
1081
1355
|
}
|
|
1082
1356
|
lastScrollOffsetRef.current = scrollOffset;
|
|
1083
1357
|
}
|
|
@@ -1091,12 +1365,10 @@ function SnapWrapper({ ScrollComponent, ...props }) {
|
|
|
1091
1365
|
return /* @__PURE__ */ React3__namespace.createElement(ScrollComponent, { ...props, snapToOffsets });
|
|
1092
1366
|
}
|
|
1093
1367
|
var LayoutView = ({ onLayoutChange, refView, children, ...rest }) => {
|
|
1094
|
-
const ref = refView != null ? refView : React3.useRef();
|
|
1368
|
+
const ref = refView != null ? refView : React3.useRef(null);
|
|
1095
1369
|
useOnLayoutSync({ onLayoutChange, ref });
|
|
1096
1370
|
return /* @__PURE__ */ React3__namespace.createElement("div", { ...rest, ref }, children);
|
|
1097
1371
|
};
|
|
1098
|
-
|
|
1099
|
-
// src/components/ListComponent.tsx
|
|
1100
1372
|
var getComponent = (Component) => {
|
|
1101
1373
|
if (React3__namespace.isValidElement(Component)) {
|
|
1102
1374
|
return Component;
|
|
@@ -1106,6 +1378,8 @@ var getComponent = (Component) => {
|
|
|
1106
1378
|
}
|
|
1107
1379
|
return null;
|
|
1108
1380
|
};
|
|
1381
|
+
|
|
1382
|
+
// src/components/ListComponent.tsx
|
|
1109
1383
|
var ListComponent = typedMemo(function ListComponent2({
|
|
1110
1384
|
canRender,
|
|
1111
1385
|
style,
|
|
@@ -1114,7 +1388,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
1114
1388
|
initialContentOffset,
|
|
1115
1389
|
recycleItems,
|
|
1116
1390
|
ItemSeparatorComponent,
|
|
1117
|
-
alignItemsAtEnd,
|
|
1391
|
+
alignItemsAtEnd: _alignItemsAtEnd,
|
|
1118
1392
|
waitForInitialLayout,
|
|
1119
1393
|
onScroll: onScroll2,
|
|
1120
1394
|
onLayout,
|
|
@@ -1126,31 +1400,52 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
1126
1400
|
getRenderedItem: getRenderedItem2,
|
|
1127
1401
|
updateItemSize: updateItemSize2,
|
|
1128
1402
|
refScrollView,
|
|
1129
|
-
maintainVisibleContentPosition,
|
|
1130
1403
|
renderScrollComponent,
|
|
1404
|
+
onLayoutFooter,
|
|
1131
1405
|
scrollAdjustHandler,
|
|
1132
|
-
onLayoutHeader,
|
|
1133
1406
|
snapToIndices,
|
|
1407
|
+
stickyHeaderConfig,
|
|
1134
1408
|
stickyHeaderIndices,
|
|
1409
|
+
useWindowScroll = false,
|
|
1135
1410
|
...rest
|
|
1136
1411
|
}) {
|
|
1137
1412
|
const ctx = useStateContext();
|
|
1413
|
+
const maintainVisibleContentPosition = ctx.state.props.maintainVisibleContentPosition;
|
|
1138
1414
|
const ScrollComponent = renderScrollComponent ? React3.useMemo(
|
|
1139
|
-
() => React3__namespace.forwardRef(
|
|
1415
|
+
() => React3__namespace.forwardRef(
|
|
1416
|
+
(props, ref) => renderScrollComponent({ ...props, ref })
|
|
1417
|
+
),
|
|
1140
1418
|
[renderScrollComponent]
|
|
1141
1419
|
) : ListComponentScrollView;
|
|
1142
|
-
React3__namespace.useEffect(() => {
|
|
1143
|
-
if (canRender) {
|
|
1144
|
-
setTimeout(() => {
|
|
1145
|
-
scrollAdjustHandler.setMounted();
|
|
1146
|
-
}, 0);
|
|
1147
|
-
}
|
|
1148
|
-
}, [canRender]);
|
|
1149
1420
|
const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
|
|
1421
|
+
React3.useLayoutEffect(() => {
|
|
1422
|
+
if (!ListHeaderComponent) {
|
|
1423
|
+
set$(ctx, "headerSize", 0);
|
|
1424
|
+
}
|
|
1425
|
+
if (!ListFooterComponent) {
|
|
1426
|
+
set$(ctx, "footerSize", 0);
|
|
1427
|
+
}
|
|
1428
|
+
}, [ListHeaderComponent, ListFooterComponent, ctx]);
|
|
1429
|
+
const onLayoutHeader = React3.useCallback(
|
|
1430
|
+
(rect) => {
|
|
1431
|
+
const size = rect[horizontal ? "width" : "height"];
|
|
1432
|
+
set$(ctx, "headerSize", size);
|
|
1433
|
+
},
|
|
1434
|
+
[ctx, horizontal]
|
|
1435
|
+
);
|
|
1436
|
+
const onLayoutFooterInternal = React3.useCallback(
|
|
1437
|
+
(rect, fromLayoutEffect) => {
|
|
1438
|
+
const size = rect[horizontal ? "width" : "height"];
|
|
1439
|
+
set$(ctx, "footerSize", size);
|
|
1440
|
+
onLayoutFooter == null ? void 0 : onLayoutFooter(rect, fromLayoutEffect);
|
|
1441
|
+
},
|
|
1442
|
+
[ctx, horizontal, onLayoutFooter]
|
|
1443
|
+
);
|
|
1150
1444
|
return /* @__PURE__ */ React3__namespace.createElement(
|
|
1151
1445
|
SnapOrScroll,
|
|
1152
1446
|
{
|
|
1153
1447
|
...rest,
|
|
1448
|
+
...ScrollComponent === ListComponentScrollView ? { useWindowScroll } : {},
|
|
1154
1449
|
contentContainerStyle: [
|
|
1155
1450
|
contentContainerStyle,
|
|
1156
1451
|
horizontal ? {
|
|
@@ -1159,7 +1454,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
1159
1454
|
],
|
|
1160
1455
|
contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
|
|
1161
1456
|
horizontal,
|
|
1162
|
-
maintainVisibleContentPosition: maintainVisibleContentPosition ? { minIndexForVisible: 0 } : void 0,
|
|
1457
|
+
maintainVisibleContentPosition: maintainVisibleContentPosition.size || maintainVisibleContentPosition.data ? { minIndexForVisible: 0 } : void 0,
|
|
1163
1458
|
onLayout,
|
|
1164
1459
|
onScroll: onScroll2,
|
|
1165
1460
|
ref: refScrollView,
|
|
@@ -1167,7 +1462,6 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
1167
1462
|
style
|
|
1168
1463
|
},
|
|
1169
1464
|
/* @__PURE__ */ React3__namespace.createElement(ScrollAdjust, null),
|
|
1170
|
-
ENABLE_DEVMODE ? /* @__PURE__ */ React3__namespace.createElement(PaddingDevMode, null) : /* @__PURE__ */ React3__namespace.createElement(Padding, null),
|
|
1171
1465
|
ListHeaderComponent && /* @__PURE__ */ React3__namespace.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
|
|
1172
1466
|
ListEmptyComponent && getComponent(ListEmptyComponent),
|
|
1173
1467
|
canRender && !ListEmptyComponent && /* @__PURE__ */ React3__namespace.createElement(
|
|
@@ -1177,25 +1471,27 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
1177
1471
|
horizontal,
|
|
1178
1472
|
ItemSeparatorComponent,
|
|
1179
1473
|
recycleItems,
|
|
1474
|
+
stickyHeaderConfig,
|
|
1180
1475
|
updateItemSize: updateItemSize2,
|
|
1181
1476
|
waitForInitialLayout
|
|
1182
1477
|
}
|
|
1183
1478
|
),
|
|
1184
|
-
ListFooterComponent && /* @__PURE__ */ React3__namespace.createElement(
|
|
1185
|
-
|
|
1186
|
-
{
|
|
1187
|
-
onLayoutChange: (layout) => {
|
|
1188
|
-
const size = layout[horizontal ? "width" : "height"];
|
|
1189
|
-
set$(ctx, "footerSize", size);
|
|
1190
|
-
},
|
|
1191
|
-
style: ListFooterComponentStyle
|
|
1192
|
-
},
|
|
1193
|
-
getComponent(ListFooterComponent)
|
|
1194
|
-
),
|
|
1195
|
-
IS_DEV && ENABLE_DEVMODE && /* @__PURE__ */ React3__namespace.createElement(DevNumbers, null)
|
|
1479
|
+
ListFooterComponent && /* @__PURE__ */ React3__namespace.createElement(LayoutView, { onLayoutChange: onLayoutFooterInternal, style: ListFooterComponentStyle }, getComponent(ListFooterComponent)),
|
|
1480
|
+
IS_DEV && ENABLE_DEVMODE
|
|
1196
1481
|
);
|
|
1197
1482
|
});
|
|
1198
1483
|
|
|
1484
|
+
// src/core/calculateOffsetForIndex.ts
|
|
1485
|
+
function calculateOffsetForIndex(ctx, index) {
|
|
1486
|
+
const state = ctx.state;
|
|
1487
|
+
return index !== void 0 ? state.positions[index] || 0 : 0;
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
// src/core/getTopOffsetAdjustment.ts
|
|
1491
|
+
function getTopOffsetAdjustment(ctx) {
|
|
1492
|
+
return (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1199
1495
|
// src/utils/getId.ts
|
|
1200
1496
|
function getId(state, index) {
|
|
1201
1497
|
const { data, keyExtractor } = state.props;
|
|
@@ -1208,61 +1504,9 @@ function getId(state, index) {
|
|
|
1208
1504
|
return id;
|
|
1209
1505
|
}
|
|
1210
1506
|
|
|
1211
|
-
// src/core/calculateOffsetForIndex.ts
|
|
1212
|
-
function calculateOffsetForIndex(ctx, state, index) {
|
|
1213
|
-
let position = 0;
|
|
1214
|
-
if (index !== void 0) {
|
|
1215
|
-
position = (state == null ? void 0 : state.positions.get(getId(state, index))) || 0;
|
|
1216
|
-
const paddingTop = peek$(ctx, "stylePaddingTop");
|
|
1217
|
-
if (paddingTop) {
|
|
1218
|
-
position += paddingTop;
|
|
1219
|
-
}
|
|
1220
|
-
const headerSize = peek$(ctx, "headerSize");
|
|
1221
|
-
if (headerSize) {
|
|
1222
|
-
position += headerSize;
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
|
-
return position;
|
|
1226
|
-
}
|
|
1227
|
-
|
|
1228
|
-
// src/utils/setPaddingTop.ts
|
|
1229
|
-
function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
|
|
1230
|
-
if (stylePaddingTop !== void 0) {
|
|
1231
|
-
const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
|
|
1232
|
-
if (stylePaddingTop < prevStylePaddingTop) {
|
|
1233
|
-
let prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
1234
|
-
set$(ctx, "totalSize", prevTotalSize + prevStylePaddingTop);
|
|
1235
|
-
state.timeoutSetPaddingTop = setTimeout(() => {
|
|
1236
|
-
prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
1237
|
-
set$(ctx, "totalSize", prevTotalSize - prevStylePaddingTop);
|
|
1238
|
-
}, 16);
|
|
1239
|
-
}
|
|
1240
|
-
set$(ctx, "stylePaddingTop", stylePaddingTop);
|
|
1241
|
-
}
|
|
1242
|
-
if (alignItemsPaddingTop !== void 0) {
|
|
1243
|
-
set$(ctx, "alignItemsPaddingTop", alignItemsPaddingTop);
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
// src/utils/updateAlignItemsPaddingTop.ts
|
|
1248
|
-
function updateAlignItemsPaddingTop(ctx, state) {
|
|
1249
|
-
const {
|
|
1250
|
-
scrollLength,
|
|
1251
|
-
props: { alignItemsAtEnd, data }
|
|
1252
|
-
} = state;
|
|
1253
|
-
if (alignItemsAtEnd) {
|
|
1254
|
-
let alignItemsPaddingTop = 0;
|
|
1255
|
-
if ((data == null ? void 0 : data.length) > 0) {
|
|
1256
|
-
const contentSize = getContentSize(ctx);
|
|
1257
|
-
alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
|
|
1258
|
-
}
|
|
1259
|
-
setPaddingTop(ctx, state, { alignItemsPaddingTop });
|
|
1260
|
-
}
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
1507
|
// src/core/addTotalSize.ts
|
|
1264
|
-
function addTotalSize(ctx,
|
|
1265
|
-
const
|
|
1508
|
+
function addTotalSize(ctx, key, add) {
|
|
1509
|
+
const state = ctx.state;
|
|
1266
1510
|
const prevTotalSize = state.totalSize;
|
|
1267
1511
|
let totalSize = state.totalSize;
|
|
1268
1512
|
if (key === null) {
|
|
@@ -1279,48 +1523,47 @@ function addTotalSize(ctx, state, key, add) {
|
|
|
1279
1523
|
state.pendingTotalSize = void 0;
|
|
1280
1524
|
state.totalSize = totalSize;
|
|
1281
1525
|
set$(ctx, "totalSize", totalSize);
|
|
1282
|
-
if (alignItemsAtEnd) {
|
|
1283
|
-
updateAlignItemsPaddingTop(ctx, state);
|
|
1284
|
-
}
|
|
1285
1526
|
}
|
|
1286
1527
|
}
|
|
1287
1528
|
}
|
|
1288
1529
|
|
|
1289
1530
|
// src/core/setSize.ts
|
|
1290
|
-
function setSize(ctx,
|
|
1531
|
+
function setSize(ctx, itemKey, size) {
|
|
1532
|
+
const state = ctx.state;
|
|
1291
1533
|
const { sizes } = state;
|
|
1292
1534
|
const previousSize = sizes.get(itemKey);
|
|
1293
1535
|
const diff = previousSize !== void 0 ? size - previousSize : size;
|
|
1294
1536
|
if (diff !== 0) {
|
|
1295
|
-
addTotalSize(ctx,
|
|
1537
|
+
addTotalSize(ctx, itemKey, diff);
|
|
1296
1538
|
}
|
|
1297
1539
|
sizes.set(itemKey, size);
|
|
1298
1540
|
}
|
|
1299
1541
|
|
|
1300
1542
|
// src/utils/getItemSize.ts
|
|
1301
|
-
function getItemSize(ctx,
|
|
1543
|
+
function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize) {
|
|
1302
1544
|
var _a3, _b;
|
|
1545
|
+
const state = ctx.state;
|
|
1303
1546
|
const {
|
|
1304
1547
|
sizesKnown,
|
|
1305
1548
|
sizes,
|
|
1306
1549
|
averageSizes,
|
|
1307
|
-
props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
|
|
1550
|
+
props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType },
|
|
1551
|
+
scrollingTo
|
|
1308
1552
|
} = state;
|
|
1309
1553
|
const sizeKnown = sizesKnown.get(key);
|
|
1310
1554
|
if (sizeKnown !== void 0) {
|
|
1311
1555
|
return sizeKnown;
|
|
1312
1556
|
}
|
|
1313
1557
|
let size;
|
|
1314
|
-
const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
|
|
1315
|
-
const scrollingTo = peek$(ctx, "scrollingTo");
|
|
1316
1558
|
if (preferCachedSize) {
|
|
1317
1559
|
const cachedSize = sizes.get(key);
|
|
1318
1560
|
if (cachedSize !== void 0) {
|
|
1319
1561
|
return cachedSize;
|
|
1320
1562
|
}
|
|
1321
1563
|
}
|
|
1564
|
+
const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
|
|
1322
1565
|
if (getFixedItemSize) {
|
|
1323
|
-
size = getFixedItemSize(
|
|
1566
|
+
size = getFixedItemSize(data, index, itemType);
|
|
1324
1567
|
if (size !== void 0) {
|
|
1325
1568
|
sizesKnown.set(key, size);
|
|
1326
1569
|
}
|
|
@@ -1338,93 +1581,61 @@ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedS
|
|
|
1338
1581
|
}
|
|
1339
1582
|
}
|
|
1340
1583
|
if (size === void 0) {
|
|
1341
|
-
size = getEstimatedItemSize ? getEstimatedItemSize(
|
|
1584
|
+
size = getEstimatedItemSize ? getEstimatedItemSize(data, index, itemType) : estimatedItemSize;
|
|
1342
1585
|
}
|
|
1343
|
-
setSize(ctx,
|
|
1586
|
+
setSize(ctx, key, size);
|
|
1344
1587
|
return size;
|
|
1345
1588
|
}
|
|
1346
1589
|
|
|
1347
1590
|
// src/core/calculateOffsetWithOffsetPosition.ts
|
|
1348
|
-
function calculateOffsetWithOffsetPosition(ctx,
|
|
1591
|
+
function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
|
|
1592
|
+
const state = ctx.state;
|
|
1349
1593
|
const { index, viewOffset, viewPosition } = params;
|
|
1350
1594
|
let offset = offsetParam;
|
|
1351
1595
|
if (viewOffset) {
|
|
1352
1596
|
offset -= viewOffset;
|
|
1353
1597
|
}
|
|
1354
|
-
if (
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
}
|
|
1359
|
-
|
|
1360
|
-
// src/core/finishScrollTo.ts
|
|
1361
|
-
function finishScrollTo(ctx, state) {
|
|
1362
|
-
var _a3, _b;
|
|
1363
|
-
if (state) {
|
|
1364
|
-
state.scrollHistory.length = 0;
|
|
1365
|
-
state.initialScroll = void 0;
|
|
1366
|
-
state.initialAnchor = void 0;
|
|
1367
|
-
set$(ctx, "scrollingTo", void 0);
|
|
1368
|
-
if (state.pendingTotalSize !== void 0) {
|
|
1369
|
-
addTotalSize(ctx, state, null, state.pendingTotalSize);
|
|
1598
|
+
if (index !== void 0) {
|
|
1599
|
+
const topOffsetAdjustment = getTopOffsetAdjustment(ctx);
|
|
1600
|
+
if (topOffsetAdjustment) {
|
|
1601
|
+
offset += topOffsetAdjustment;
|
|
1370
1602
|
}
|
|
1371
|
-
|
|
1372
|
-
|
|
1603
|
+
}
|
|
1604
|
+
if (viewPosition !== void 0 && index !== void 0) {
|
|
1605
|
+
const itemSize = getItemSize(ctx, getId(state, index), index, state.props.data[index]);
|
|
1606
|
+
const trailingInset = getContentInsetEnd(state);
|
|
1607
|
+
offset -= viewPosition * (state.scrollLength - trailingInset - itemSize);
|
|
1608
|
+
if (index === state.props.data.length - 1) {
|
|
1609
|
+
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
1610
|
+
offset += footerSize;
|
|
1373
1611
|
}
|
|
1374
1612
|
}
|
|
1613
|
+
return offset;
|
|
1375
1614
|
}
|
|
1376
1615
|
|
|
1377
|
-
// src/core/
|
|
1378
|
-
function
|
|
1379
|
-
|
|
1380
|
-
const
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
state.scrollHistory.length = 0;
|
|
1392
|
-
if (!noScrollingTo) {
|
|
1393
|
-
set$(ctx, "scrollingTo", scrollTarget);
|
|
1394
|
-
}
|
|
1395
|
-
state.scrollPending = offset;
|
|
1396
|
-
if (!isInitialScroll || Platform.OS === "android") {
|
|
1397
|
-
(_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
|
|
1398
|
-
animated: !!animated,
|
|
1399
|
-
x: horizontal ? offset : 0,
|
|
1400
|
-
y: horizontal ? 0 : offset
|
|
1401
|
-
});
|
|
1402
|
-
}
|
|
1403
|
-
if (!animated) {
|
|
1404
|
-
state.scroll = offset;
|
|
1405
|
-
{
|
|
1406
|
-
const unlisten = listen$(ctx, "containersDidLayout", (value) => {
|
|
1407
|
-
if (value && peek$(ctx, "scrollingTo")) {
|
|
1408
|
-
finishScrollTo(ctx, state);
|
|
1409
|
-
unlisten();
|
|
1410
|
-
}
|
|
1411
|
-
});
|
|
1412
|
-
}
|
|
1413
|
-
if (isInitialScroll) {
|
|
1414
|
-
setTimeout(() => {
|
|
1415
|
-
state.initialScroll = void 0;
|
|
1416
|
-
}, 500);
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1616
|
+
// src/core/clampScrollOffset.ts
|
|
1617
|
+
function clampScrollOffset(ctx, offset, scrollTarget) {
|
|
1618
|
+
const state = ctx.state;
|
|
1619
|
+
const contentSize = getContentSize(ctx);
|
|
1620
|
+
let clampedOffset = offset;
|
|
1621
|
+
if (Number.isFinite(contentSize) && Number.isFinite(state.scrollLength) && (Platform.OS !== "android")) {
|
|
1622
|
+
const baseMaxOffset = Math.max(0, contentSize - state.scrollLength);
|
|
1623
|
+
const viewOffset = scrollTarget == null ? void 0 : scrollTarget.viewOffset;
|
|
1624
|
+
const extraEndOffset = typeof viewOffset === "number" && viewOffset < 0 ? -viewOffset : 0;
|
|
1625
|
+
const maxOffset = baseMaxOffset + extraEndOffset;
|
|
1626
|
+
clampedOffset = Math.min(offset, maxOffset);
|
|
1627
|
+
}
|
|
1628
|
+
clampedOffset = Math.max(0, clampedOffset);
|
|
1629
|
+
return clampedOffset;
|
|
1419
1630
|
}
|
|
1420
1631
|
|
|
1421
1632
|
// src/utils/checkThreshold.ts
|
|
1422
1633
|
var HYSTERESIS_MULTIPLIER = 1.3;
|
|
1423
|
-
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
|
|
1634
|
+
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot, allowReentryOnChange) => {
|
|
1424
1635
|
const absDistance = Math.abs(distance);
|
|
1425
1636
|
const within = atThreshold || threshold > 0 && absDistance <= threshold;
|
|
1426
1637
|
const updateSnapshot = () => {
|
|
1427
|
-
setSnapshot
|
|
1638
|
+
setSnapshot({
|
|
1428
1639
|
atThreshold,
|
|
1429
1640
|
contentSize: context.contentSize,
|
|
1430
1641
|
dataLength: context.dataLength,
|
|
@@ -1435,19 +1646,21 @@ var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, co
|
|
|
1435
1646
|
if (!within) {
|
|
1436
1647
|
return false;
|
|
1437
1648
|
}
|
|
1438
|
-
onReached
|
|
1649
|
+
onReached(distance);
|
|
1439
1650
|
updateSnapshot();
|
|
1440
1651
|
return true;
|
|
1441
1652
|
}
|
|
1442
1653
|
const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
|
|
1443
1654
|
if (reset) {
|
|
1444
|
-
setSnapshot
|
|
1655
|
+
setSnapshot(void 0);
|
|
1445
1656
|
return false;
|
|
1446
1657
|
}
|
|
1447
1658
|
if (within) {
|
|
1448
1659
|
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
1449
1660
|
if (changed) {
|
|
1450
|
-
|
|
1661
|
+
if (allowReentryOnChange) {
|
|
1662
|
+
onReached(distance);
|
|
1663
|
+
}
|
|
1451
1664
|
updateSnapshot();
|
|
1452
1665
|
}
|
|
1453
1666
|
}
|
|
@@ -1455,9 +1668,10 @@ var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, co
|
|
|
1455
1668
|
};
|
|
1456
1669
|
|
|
1457
1670
|
// src/utils/checkAtBottom.ts
|
|
1458
|
-
function checkAtBottom(ctx
|
|
1671
|
+
function checkAtBottom(ctx) {
|
|
1459
1672
|
var _a3;
|
|
1460
|
-
|
|
1673
|
+
const state = ctx.state;
|
|
1674
|
+
if (!state || state.initialScroll) {
|
|
1461
1675
|
return;
|
|
1462
1676
|
}
|
|
1463
1677
|
const {
|
|
@@ -1467,9 +1681,13 @@ function checkAtBottom(ctx, state) {
|
|
|
1467
1681
|
maintainingScrollAtEnd,
|
|
1468
1682
|
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
1469
1683
|
} = state;
|
|
1684
|
+
if (state.initialScroll) {
|
|
1685
|
+
return;
|
|
1686
|
+
}
|
|
1470
1687
|
const contentSize = getContentSize(ctx);
|
|
1471
1688
|
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1472
|
-
const
|
|
1689
|
+
const insetEnd = getContentInsetEnd(state);
|
|
1690
|
+
const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
|
|
1473
1691
|
const isContentLess = contentSize < scrollLength;
|
|
1474
1692
|
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
1475
1693
|
state.isEndReached = checkThreshold(
|
|
@@ -1489,72 +1707,257 @@ function checkAtBottom(ctx, state) {
|
|
|
1489
1707
|
},
|
|
1490
1708
|
(snapshot) => {
|
|
1491
1709
|
state.endReachedSnapshot = snapshot;
|
|
1492
|
-
}
|
|
1710
|
+
},
|
|
1711
|
+
true
|
|
1493
1712
|
);
|
|
1494
1713
|
}
|
|
1495
1714
|
}
|
|
1496
1715
|
|
|
1497
1716
|
// src/utils/checkAtTop.ts
|
|
1498
|
-
function checkAtTop(
|
|
1499
|
-
|
|
1500
|
-
if (!state) {
|
|
1717
|
+
function checkAtTop(ctx) {
|
|
1718
|
+
const state = ctx == null ? void 0 : ctx.state;
|
|
1719
|
+
if (!state || state.initialScroll || state.scrollingTo) {
|
|
1501
1720
|
return;
|
|
1502
1721
|
}
|
|
1503
1722
|
const {
|
|
1504
|
-
|
|
1723
|
+
dataChangeEpoch,
|
|
1724
|
+
isStartReached,
|
|
1725
|
+
props: { data, onStartReachedThreshold },
|
|
1505
1726
|
scroll,
|
|
1506
|
-
|
|
1727
|
+
scrollLength,
|
|
1728
|
+
startReachedSnapshot,
|
|
1729
|
+
startReachedSnapshotDataChangeEpoch,
|
|
1730
|
+
totalSize
|
|
1507
1731
|
} = state;
|
|
1508
|
-
const
|
|
1509
|
-
|
|
1732
|
+
const dataLength = data.length;
|
|
1733
|
+
const threshold = onStartReachedThreshold * scrollLength;
|
|
1734
|
+
const dataChanged = startReachedSnapshotDataChangeEpoch !== dataChangeEpoch;
|
|
1735
|
+
const withinThreshold = threshold > 0 && Math.abs(scroll) <= threshold;
|
|
1736
|
+
const allowReentryOnDataChange = !!isStartReached && withinThreshold && !!dataChanged && !isInMVCPActiveMode(state);
|
|
1737
|
+
if (isStartReached && threshold > 0 && scroll > threshold && startReachedSnapshot && (dataChanged || startReachedSnapshot.contentSize !== totalSize || startReachedSnapshot.dataLength !== dataLength)) {
|
|
1738
|
+
state.isStartReached = false;
|
|
1739
|
+
state.startReachedSnapshot = void 0;
|
|
1740
|
+
state.startReachedSnapshotDataChangeEpoch = void 0;
|
|
1741
|
+
}
|
|
1742
|
+
state.isAtStart = scroll <= 0;
|
|
1743
|
+
if (isStartReached && withinThreshold && dataChanged && !allowReentryOnDataChange) {
|
|
1744
|
+
return;
|
|
1745
|
+
}
|
|
1510
1746
|
state.isStartReached = checkThreshold(
|
|
1511
|
-
|
|
1747
|
+
scroll,
|
|
1512
1748
|
false,
|
|
1513
|
-
|
|
1749
|
+
threshold,
|
|
1514
1750
|
state.isStartReached,
|
|
1515
|
-
|
|
1751
|
+
allowReentryOnDataChange ? void 0 : startReachedSnapshot,
|
|
1516
1752
|
{
|
|
1517
|
-
contentSize:
|
|
1518
|
-
dataLength
|
|
1753
|
+
contentSize: totalSize,
|
|
1754
|
+
dataLength,
|
|
1519
1755
|
scrollPosition: scroll
|
|
1520
1756
|
},
|
|
1521
1757
|
(distance) => {
|
|
1522
|
-
var
|
|
1523
|
-
return (_b = (
|
|
1758
|
+
var _a3, _b;
|
|
1759
|
+
return (_b = (_a3 = state.props).onStartReached) == null ? void 0 : _b.call(_a3, { distanceFromStart: distance });
|
|
1524
1760
|
},
|
|
1525
1761
|
(snapshot) => {
|
|
1526
1762
|
state.startReachedSnapshot = snapshot;
|
|
1527
|
-
|
|
1763
|
+
state.startReachedSnapshotDataChangeEpoch = snapshot ? dataChangeEpoch : void 0;
|
|
1764
|
+
},
|
|
1765
|
+
allowReentryOnDataChange
|
|
1528
1766
|
);
|
|
1529
1767
|
}
|
|
1530
1768
|
|
|
1769
|
+
// src/utils/checkThresholds.ts
|
|
1770
|
+
function checkThresholds(ctx) {
|
|
1771
|
+
checkAtBottom(ctx);
|
|
1772
|
+
checkAtTop(ctx);
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
// src/utils/setInitialRenderState.ts
|
|
1776
|
+
function setInitialRenderState(ctx, {
|
|
1777
|
+
didLayout,
|
|
1778
|
+
didInitialScroll
|
|
1779
|
+
}) {
|
|
1780
|
+
const { state } = ctx;
|
|
1781
|
+
const {
|
|
1782
|
+
loadStartTime,
|
|
1783
|
+
props: { onLoad }
|
|
1784
|
+
} = state;
|
|
1785
|
+
if (didLayout) {
|
|
1786
|
+
state.didContainersLayout = true;
|
|
1787
|
+
}
|
|
1788
|
+
if (didInitialScroll) {
|
|
1789
|
+
state.didFinishInitialScroll = true;
|
|
1790
|
+
}
|
|
1791
|
+
const isReadyToRender = Boolean(state.didContainersLayout && state.didFinishInitialScroll);
|
|
1792
|
+
if (isReadyToRender && !peek$(ctx, "readyToRender")) {
|
|
1793
|
+
set$(ctx, "readyToRender", true);
|
|
1794
|
+
if (onLoad) {
|
|
1795
|
+
onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
// src/core/finishScrollTo.ts
|
|
1801
|
+
function finishScrollTo(ctx) {
|
|
1802
|
+
var _a3, _b;
|
|
1803
|
+
const state = ctx.state;
|
|
1804
|
+
if (state == null ? void 0 : state.scrollingTo) {
|
|
1805
|
+
const resolvePendingScroll = state.pendingScrollResolve;
|
|
1806
|
+
state.pendingScrollResolve = void 0;
|
|
1807
|
+
const scrollingTo = state.scrollingTo;
|
|
1808
|
+
state.scrollHistory.length = 0;
|
|
1809
|
+
state.initialScroll = void 0;
|
|
1810
|
+
state.initialAnchor = void 0;
|
|
1811
|
+
state.scrollingTo = void 0;
|
|
1812
|
+
if (state.pendingTotalSize !== void 0) {
|
|
1813
|
+
addTotalSize(ctx, null, state.pendingTotalSize);
|
|
1814
|
+
}
|
|
1815
|
+
if ((_a3 = state.props) == null ? void 0 : _a3.data) {
|
|
1816
|
+
(_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
|
|
1817
|
+
}
|
|
1818
|
+
{
|
|
1819
|
+
state.scrollAdjustHandler.commitPendingAdjust(scrollingTo);
|
|
1820
|
+
}
|
|
1821
|
+
setInitialRenderState(ctx, { didInitialScroll: true });
|
|
1822
|
+
checkThresholds(ctx);
|
|
1823
|
+
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
// src/core/doScrollTo.ts
|
|
1828
|
+
var SCROLL_END_IDLE_MS = 80;
|
|
1829
|
+
var SCROLL_END_MAX_MS = 1500;
|
|
1830
|
+
var SMOOTH_SCROLL_DURATION_MS = 320;
|
|
1831
|
+
var SCROLL_END_TARGET_EPSILON = 1;
|
|
1832
|
+
function doScrollTo(ctx, params) {
|
|
1833
|
+
const state = ctx.state;
|
|
1834
|
+
const { animated, horizontal, offset } = params;
|
|
1835
|
+
const scroller = state.refScroller.current;
|
|
1836
|
+
const node = scroller == null ? void 0 : scroller.getScrollableNode();
|
|
1837
|
+
if (!scroller || !node) {
|
|
1838
|
+
return;
|
|
1839
|
+
}
|
|
1840
|
+
const isAnimated = !!animated;
|
|
1841
|
+
const isHorizontal = !!horizontal;
|
|
1842
|
+
const left = isHorizontal ? offset : 0;
|
|
1843
|
+
const top = isHorizontal ? 0 : offset;
|
|
1844
|
+
scroller.scrollTo({ animated: isAnimated, x: left, y: top });
|
|
1845
|
+
if (isAnimated) {
|
|
1846
|
+
const target = scroller.getScrollEventTarget();
|
|
1847
|
+
listenForScrollEnd(ctx, {
|
|
1848
|
+
readOffset: () => scroller.getCurrentScrollOffset(),
|
|
1849
|
+
target,
|
|
1850
|
+
targetOffset: offset
|
|
1851
|
+
});
|
|
1852
|
+
} else {
|
|
1853
|
+
state.scroll = offset;
|
|
1854
|
+
setTimeout(() => {
|
|
1855
|
+
finishScrollTo(ctx);
|
|
1856
|
+
}, 100);
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
function listenForScrollEnd(ctx, params) {
|
|
1860
|
+
const { readOffset, target, targetOffset } = params;
|
|
1861
|
+
if (!target) {
|
|
1862
|
+
finishScrollTo(ctx);
|
|
1863
|
+
return;
|
|
1864
|
+
}
|
|
1865
|
+
const supportsScrollEnd = "onscrollend" in target;
|
|
1866
|
+
let idleTimeout;
|
|
1867
|
+
let settled = false;
|
|
1868
|
+
const targetToken = ctx.state.scrollingTo;
|
|
1869
|
+
const maxTimeout = setTimeout(() => finish("max"), SCROLL_END_MAX_MS);
|
|
1870
|
+
const cleanup = () => {
|
|
1871
|
+
target.removeEventListener("scroll", onScroll2);
|
|
1872
|
+
if (supportsScrollEnd) {
|
|
1873
|
+
target.removeEventListener("scrollend", onScrollEnd);
|
|
1874
|
+
}
|
|
1875
|
+
if (idleTimeout) {
|
|
1876
|
+
clearTimeout(idleTimeout);
|
|
1877
|
+
}
|
|
1878
|
+
clearTimeout(maxTimeout);
|
|
1879
|
+
};
|
|
1880
|
+
const finish = (reason) => {
|
|
1881
|
+
if (settled) return;
|
|
1882
|
+
if (targetToken !== ctx.state.scrollingTo) {
|
|
1883
|
+
settled = true;
|
|
1884
|
+
cleanup();
|
|
1885
|
+
return;
|
|
1886
|
+
}
|
|
1887
|
+
const currentOffset = readOffset();
|
|
1888
|
+
const isNearTarget = Math.abs(currentOffset - targetOffset) <= SCROLL_END_TARGET_EPSILON;
|
|
1889
|
+
if (reason === "scrollend" && !isNearTarget) {
|
|
1890
|
+
return;
|
|
1891
|
+
}
|
|
1892
|
+
settled = true;
|
|
1893
|
+
cleanup();
|
|
1894
|
+
finishScrollTo(ctx);
|
|
1895
|
+
};
|
|
1896
|
+
const onScroll2 = () => {
|
|
1897
|
+
if (idleTimeout) {
|
|
1898
|
+
clearTimeout(idleTimeout);
|
|
1899
|
+
}
|
|
1900
|
+
idleTimeout = setTimeout(() => finish("idle"), SCROLL_END_IDLE_MS);
|
|
1901
|
+
};
|
|
1902
|
+
const onScrollEnd = () => finish("scrollend");
|
|
1903
|
+
target.addEventListener("scroll", onScroll2);
|
|
1904
|
+
if (supportsScrollEnd) {
|
|
1905
|
+
target.addEventListener("scrollend", onScrollEnd);
|
|
1906
|
+
} else {
|
|
1907
|
+
idleTimeout = setTimeout(() => finish("idle"), SMOOTH_SCROLL_DURATION_MS);
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
// src/core/scrollTo.ts
|
|
1912
|
+
function scrollTo(ctx, params) {
|
|
1913
|
+
const state = ctx.state;
|
|
1914
|
+
const { noScrollingTo, forceScroll, ...scrollTarget } = params;
|
|
1915
|
+
const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
|
|
1916
|
+
const {
|
|
1917
|
+
props: { horizontal }
|
|
1918
|
+
} = state;
|
|
1919
|
+
if (state.animFrameCheckFinishedScroll) {
|
|
1920
|
+
cancelAnimationFrame(ctx.state.animFrameCheckFinishedScroll);
|
|
1921
|
+
}
|
|
1922
|
+
if (state.timeoutCheckFinishedScrollFallback) {
|
|
1923
|
+
clearTimeout(ctx.state.timeoutCheckFinishedScrollFallback);
|
|
1924
|
+
}
|
|
1925
|
+
let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, scrollTargetOffset, scrollTarget);
|
|
1926
|
+
offset = clampScrollOffset(ctx, offset, scrollTarget);
|
|
1927
|
+
state.scrollHistory.length = 0;
|
|
1928
|
+
if (!noScrollingTo) {
|
|
1929
|
+
state.scrollingTo = scrollTarget;
|
|
1930
|
+
}
|
|
1931
|
+
state.scrollPending = offset;
|
|
1932
|
+
if (forceScroll || !isInitialScroll || Platform.OS === "android") {
|
|
1933
|
+
doScrollTo(ctx, { animated, horizontal, offset });
|
|
1934
|
+
} else {
|
|
1935
|
+
state.scroll = offset;
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1531
1939
|
// src/core/updateScroll.ts
|
|
1532
|
-
function updateScroll(ctx,
|
|
1533
|
-
|
|
1534
|
-
const
|
|
1940
|
+
function updateScroll(ctx, newScroll, forceUpdate) {
|
|
1941
|
+
const state = ctx.state;
|
|
1942
|
+
const { ignoreScrollFromMVCP, lastScrollAdjustForHistory, scrollAdjustHandler, scrollHistory, scrollingTo } = state;
|
|
1943
|
+
const prevScroll = state.scroll;
|
|
1535
1944
|
state.hasScrolled = true;
|
|
1536
1945
|
state.lastBatchingAction = Date.now();
|
|
1537
1946
|
const currentTime = Date.now();
|
|
1538
|
-
const adjust =
|
|
1539
|
-
const
|
|
1540
|
-
const adjustChanged = lastHistoryAdjust !== void 0 && Math.abs(adjust - lastHistoryAdjust) > 0.1;
|
|
1947
|
+
const adjust = scrollAdjustHandler.getAdjust();
|
|
1948
|
+
const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
|
|
1541
1949
|
if (adjustChanged) {
|
|
1542
|
-
|
|
1950
|
+
scrollHistory.length = 0;
|
|
1543
1951
|
}
|
|
1544
1952
|
state.lastScrollAdjustForHistory = adjust;
|
|
1545
|
-
if (scrollingTo === void 0 && !(
|
|
1953
|
+
if (scrollingTo === void 0 && !(scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
1546
1954
|
if (!adjustChanged) {
|
|
1547
|
-
|
|
1955
|
+
scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
1548
1956
|
}
|
|
1549
1957
|
}
|
|
1550
|
-
if (
|
|
1551
|
-
|
|
1958
|
+
if (scrollHistory.length > 5) {
|
|
1959
|
+
scrollHistory.shift();
|
|
1552
1960
|
}
|
|
1553
|
-
state.scrollPrev = state.scroll;
|
|
1554
|
-
state.scrollPrevTime = state.scrollTime;
|
|
1555
|
-
state.scroll = newScroll;
|
|
1556
|
-
state.scrollTime = currentTime;
|
|
1557
|
-
const ignoreScrollFromMVCP = state.ignoreScrollFromMVCP;
|
|
1558
1961
|
if (ignoreScrollFromMVCP && !scrollingTo) {
|
|
1559
1962
|
const { lt, gt } = ignoreScrollFromMVCP;
|
|
1560
1963
|
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
@@ -1562,17 +1965,37 @@ function updateScroll(ctx, state, newScroll, forceUpdate) {
|
|
|
1562
1965
|
return;
|
|
1563
1966
|
}
|
|
1564
1967
|
}
|
|
1565
|
-
|
|
1968
|
+
state.scrollPrev = prevScroll;
|
|
1969
|
+
state.scrollPrevTime = state.scrollTime;
|
|
1970
|
+
state.scroll = newScroll;
|
|
1971
|
+
state.scrollTime = currentTime;
|
|
1972
|
+
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
1973
|
+
const scrollLength = state.scrollLength;
|
|
1974
|
+
const lastCalculated = state.scrollLastCalculate;
|
|
1975
|
+
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
1976
|
+
const shouldUpdate = useAggressiveItemRecalculation || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
1977
|
+
if (shouldUpdate) {
|
|
1978
|
+
state.scrollLastCalculate = state.scroll;
|
|
1566
1979
|
state.ignoreScrollFromMVCPIgnored = false;
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1980
|
+
state.lastScrollDelta = scrollDelta;
|
|
1981
|
+
const runCalculateItems = () => {
|
|
1982
|
+
var _a3;
|
|
1983
|
+
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
|
|
1984
|
+
checkThresholds(ctx);
|
|
1985
|
+
};
|
|
1986
|
+
if (scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength) {
|
|
1987
|
+
ReactDOM.flushSync(runCalculateItems);
|
|
1988
|
+
} else {
|
|
1989
|
+
runCalculateItems();
|
|
1990
|
+
}
|
|
1570
1991
|
state.dataChangeNeedsScrollUpdate = false;
|
|
1992
|
+
state.lastScrollDelta = 0;
|
|
1571
1993
|
}
|
|
1572
1994
|
}
|
|
1573
1995
|
|
|
1574
1996
|
// src/utils/requestAdjust.ts
|
|
1575
|
-
function requestAdjust(ctx,
|
|
1997
|
+
function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
1998
|
+
const state = ctx.state;
|
|
1576
1999
|
if (Math.abs(positionDiff) > 0.1) {
|
|
1577
2000
|
const doit = () => {
|
|
1578
2001
|
{
|
|
@@ -1584,8 +2007,8 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
|
|
|
1584
2007
|
};
|
|
1585
2008
|
state.scroll += positionDiff;
|
|
1586
2009
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
1587
|
-
const
|
|
1588
|
-
if (
|
|
2010
|
+
const readyToRender = peek$(ctx, "readyToRender");
|
|
2011
|
+
if (readyToRender) {
|
|
1589
2012
|
doit();
|
|
1590
2013
|
} else {
|
|
1591
2014
|
state.adjustingFromInitialMount = (state.adjustingFromInitialMount || 0) + 1;
|
|
@@ -1594,106 +2017,144 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
|
|
|
1594
2017
|
}
|
|
1595
2018
|
}
|
|
1596
2019
|
|
|
1597
|
-
// src/core/
|
|
1598
|
-
var
|
|
1599
|
-
var
|
|
1600
|
-
var
|
|
1601
|
-
function
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
if (settledTicks >= INITIAL_ANCHOR_SETTLED_TICKS) {
|
|
1626
|
-
state.initialAnchor = void 0;
|
|
1627
|
-
} else {
|
|
1628
|
-
anchor.settledTicks = settledTicks;
|
|
2020
|
+
// src/core/mvcp.ts
|
|
2021
|
+
var MVCP_POSITION_EPSILON = 0.1;
|
|
2022
|
+
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
2023
|
+
var MVCP_ANCHOR_LOCK_QUIET_PASSES_TO_RELEASE = 2;
|
|
2024
|
+
function resolveAnchorLock(state, enableMVCPAnchorLock, mvcpData, now) {
|
|
2025
|
+
if (!enableMVCPAnchorLock) {
|
|
2026
|
+
state.mvcpAnchorLock = void 0;
|
|
2027
|
+
return void 0;
|
|
2028
|
+
}
|
|
2029
|
+
const lock = state.mvcpAnchorLock;
|
|
2030
|
+
if (!lock) {
|
|
2031
|
+
return void 0;
|
|
2032
|
+
}
|
|
2033
|
+
const isExpired = now > lock.expiresAt;
|
|
2034
|
+
const isMissing = state.indexByKey.get(lock.id) === void 0;
|
|
2035
|
+
if (isExpired || isMissing || !mvcpData) {
|
|
2036
|
+
state.mvcpAnchorLock = void 0;
|
|
2037
|
+
return void 0;
|
|
2038
|
+
}
|
|
2039
|
+
return lock;
|
|
2040
|
+
}
|
|
2041
|
+
function updateAnchorLock(state, params) {
|
|
2042
|
+
{
|
|
2043
|
+
const { anchorId, anchorPosition, dataChanged, now, positionDiff } = params;
|
|
2044
|
+
const enableMVCPAnchorLock = !!dataChanged || !!state.mvcpAnchorLock;
|
|
2045
|
+
const mvcpData = state.props.maintainVisibleContentPosition.data;
|
|
2046
|
+
if (!enableMVCPAnchorLock || !mvcpData || state.scrollingTo || !anchorId || anchorPosition === void 0) {
|
|
2047
|
+
return;
|
|
1629
2048
|
}
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
2049
|
+
const existingLock = state.mvcpAnchorLock;
|
|
2050
|
+
const quietPasses = !dataChanged && Math.abs(positionDiff) <= MVCP_POSITION_EPSILON && (existingLock == null ? void 0 : existingLock.id) === anchorId ? existingLock.quietPasses + 1 : 0;
|
|
2051
|
+
if (!dataChanged && quietPasses >= MVCP_ANCHOR_LOCK_QUIET_PASSES_TO_RELEASE) {
|
|
2052
|
+
state.mvcpAnchorLock = void 0;
|
|
2053
|
+
return;
|
|
2054
|
+
}
|
|
2055
|
+
state.mvcpAnchorLock = {
|
|
2056
|
+
expiresAt: now + MVCP_ANCHOR_LOCK_TTL_MS,
|
|
2057
|
+
id: anchorId,
|
|
2058
|
+
position: anchorPosition,
|
|
2059
|
+
quietPasses
|
|
2060
|
+
};
|
|
1640
2061
|
}
|
|
1641
|
-
Object.assign(anchor, {
|
|
1642
|
-
attempts: ((_e = anchor.attempts) != null ? _e : 0) + 1,
|
|
1643
|
-
lastDelta: delta,
|
|
1644
|
-
settledTicks: 0
|
|
1645
|
-
});
|
|
1646
|
-
requestAdjust(ctx, state, delta);
|
|
1647
2062
|
}
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
function prepareMVCP(ctx, state, dataChanged) {
|
|
2063
|
+
function prepareMVCP(ctx, dataChanged) {
|
|
2064
|
+
const state = ctx.state;
|
|
1651
2065
|
const { idsInView, positions, props } = state;
|
|
1652
|
-
const {
|
|
1653
|
-
|
|
2066
|
+
const {
|
|
2067
|
+
maintainVisibleContentPosition: { data: mvcpData, size: mvcpScroll, shouldRestorePosition }
|
|
2068
|
+
} = props;
|
|
2069
|
+
const now = Date.now();
|
|
2070
|
+
const enableMVCPAnchorLock = (!!dataChanged || !!state.mvcpAnchorLock);
|
|
2071
|
+
const scrollingTo = state.scrollingTo;
|
|
2072
|
+
const anchorLock = resolveAnchorLock(state, enableMVCPAnchorLock, mvcpData, now) ;
|
|
1654
2073
|
let prevPosition;
|
|
1655
2074
|
let targetId;
|
|
1656
2075
|
const idsInViewWithPositions = [];
|
|
1657
2076
|
const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
|
|
1658
|
-
const
|
|
2077
|
+
const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
|
|
2078
|
+
const isEndAnchoredScrollTarget = scrollTarget !== void 0 && state.props.data.length > 0 && scrollTarget >= state.props.data.length - 1 && (scrollingToViewPosition != null ? scrollingToViewPosition : 0) > 0;
|
|
2079
|
+
const shouldMVCP = dataChanged ? mvcpData : mvcpScroll;
|
|
1659
2080
|
const indexByKey = state.indexByKey;
|
|
1660
2081
|
if (shouldMVCP) {
|
|
1661
|
-
if (scrollTarget
|
|
2082
|
+
if (anchorLock && scrollTarget === void 0) {
|
|
2083
|
+
targetId = anchorLock.id;
|
|
2084
|
+
prevPosition = anchorLock.position;
|
|
2085
|
+
} else if (scrollTarget !== void 0) {
|
|
1662
2086
|
targetId = getId(state, scrollTarget);
|
|
1663
|
-
} else if (idsInView.length > 0 &&
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
2087
|
+
} else if (idsInView.length > 0 && state.didContainersLayout && !dataChanged) {
|
|
2088
|
+
targetId = idsInView.find((id) => indexByKey.get(id) !== void 0);
|
|
2089
|
+
}
|
|
2090
|
+
if (dataChanged && idsInView.length > 0 && state.didContainersLayout) {
|
|
2091
|
+
for (let i = 0; i < idsInView.length; i++) {
|
|
2092
|
+
const id = idsInView[i];
|
|
2093
|
+
const index = indexByKey.get(id);
|
|
2094
|
+
if (index !== void 0) {
|
|
2095
|
+
const position = positions[index];
|
|
2096
|
+
if (position !== void 0) {
|
|
2097
|
+
idsInViewWithPositions.push({ id, position });
|
|
1670
2098
|
}
|
|
1671
2099
|
}
|
|
1672
|
-
} else {
|
|
1673
|
-
targetId = idsInView.find((id) => indexByKey.get(id) !== void 0);
|
|
1674
2100
|
}
|
|
1675
2101
|
}
|
|
1676
|
-
if (targetId !== void 0) {
|
|
1677
|
-
|
|
2102
|
+
if (targetId !== void 0 && prevPosition === void 0) {
|
|
2103
|
+
const targetIndex = indexByKey.get(targetId);
|
|
2104
|
+
if (targetIndex !== void 0) {
|
|
2105
|
+
prevPosition = positions[targetIndex];
|
|
2106
|
+
}
|
|
1678
2107
|
}
|
|
1679
2108
|
return () => {
|
|
1680
|
-
let positionDiff;
|
|
1681
|
-
|
|
2109
|
+
let positionDiff = 0;
|
|
2110
|
+
let anchorIdForLock = anchorLock == null ? void 0 : anchorLock.id;
|
|
2111
|
+
let anchorPositionForLock;
|
|
2112
|
+
let skipTargetAnchor = false;
|
|
2113
|
+
const data = state.props.data;
|
|
2114
|
+
const shouldValidateLockedAnchor = dataChanged && mvcpData && scrollTarget === void 0 && targetId !== void 0 && (anchorLock == null ? void 0 : anchorLock.id) === targetId && shouldRestorePosition !== void 0;
|
|
2115
|
+
if (shouldValidateLockedAnchor && targetId !== void 0) {
|
|
2116
|
+
const index = indexByKey.get(targetId);
|
|
2117
|
+
if (index !== void 0) {
|
|
2118
|
+
const item = data[index];
|
|
2119
|
+
skipTargetAnchor = item === void 0 || !shouldRestorePosition(item, index, data);
|
|
2120
|
+
if (skipTargetAnchor && (anchorLock == null ? void 0 : anchorLock.id) === targetId) {
|
|
2121
|
+
state.mvcpAnchorLock = void 0;
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
const shouldUseFallbackVisibleAnchor = dataChanged && mvcpData && scrollTarget === void 0 && (() => {
|
|
2126
|
+
if (targetId === void 0 || skipTargetAnchor) {
|
|
2127
|
+
return true;
|
|
2128
|
+
}
|
|
2129
|
+
const targetIndex = indexByKey.get(targetId);
|
|
2130
|
+
return targetIndex === void 0 || positions[targetIndex] === void 0;
|
|
2131
|
+
})();
|
|
2132
|
+
if (shouldUseFallbackVisibleAnchor) {
|
|
1682
2133
|
for (let i = 0; i < idsInViewWithPositions.length; i++) {
|
|
1683
2134
|
const { id, position } = idsInViewWithPositions[i];
|
|
1684
|
-
const
|
|
2135
|
+
const index = indexByKey.get(id);
|
|
2136
|
+
if (index !== void 0 && shouldRestorePosition) {
|
|
2137
|
+
const item = data[index];
|
|
2138
|
+
if (item === void 0 || !shouldRestorePosition(item, index, data)) {
|
|
2139
|
+
continue;
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
const newPosition = index !== void 0 ? positions[index] : void 0;
|
|
1685
2143
|
if (newPosition !== void 0) {
|
|
1686
2144
|
positionDiff = newPosition - position;
|
|
2145
|
+
anchorIdForLock = id;
|
|
2146
|
+
anchorPositionForLock = newPosition;
|
|
1687
2147
|
break;
|
|
1688
2148
|
}
|
|
1689
2149
|
}
|
|
1690
2150
|
}
|
|
1691
|
-
if (targetId !== void 0 && prevPosition !== void 0) {
|
|
1692
|
-
const
|
|
2151
|
+
if (!skipTargetAnchor && targetId !== void 0 && prevPosition !== void 0) {
|
|
2152
|
+
const targetIndex = indexByKey.get(targetId);
|
|
2153
|
+
const newPosition = targetIndex !== void 0 ? positions[targetIndex] : void 0;
|
|
1693
2154
|
if (newPosition !== void 0) {
|
|
1694
2155
|
const totalSize = getContentSize(ctx);
|
|
1695
2156
|
let diff = newPosition - prevPosition;
|
|
1696
|
-
if (diff !== 0 && state.scroll + state.scrollLength > totalSize) {
|
|
2157
|
+
if (diff !== 0 && isEndAnchoredScrollTarget && state.scroll + state.scrollLength > totalSize) {
|
|
1697
2158
|
if (diff > 0) {
|
|
1698
2159
|
diff = Math.max(0, totalSize - state.scroll - state.scrollLength);
|
|
1699
2160
|
} else {
|
|
@@ -1701,33 +2162,52 @@ function prepareMVCP(ctx, state, dataChanged) {
|
|
|
1701
2162
|
}
|
|
1702
2163
|
}
|
|
1703
2164
|
positionDiff = diff;
|
|
2165
|
+
anchorIdForLock = targetId;
|
|
2166
|
+
anchorPositionForLock = newPosition;
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2169
|
+
if (scrollingToViewPosition && scrollingToViewPosition > 0) {
|
|
2170
|
+
const newSize = getItemSize(ctx, targetId, scrollTarget, state.props.data[scrollTarget]);
|
|
2171
|
+
const prevSize = scrollingTo == null ? void 0 : scrollingTo.itemSize;
|
|
2172
|
+
if (newSize !== void 0 && prevSize !== void 0 && newSize !== prevSize) {
|
|
2173
|
+
const diff = newSize - prevSize;
|
|
2174
|
+
if (diff !== 0) {
|
|
2175
|
+
positionDiff += diff * scrollingToViewPosition;
|
|
2176
|
+
scrollingTo.itemSize = newSize;
|
|
2177
|
+
}
|
|
1704
2178
|
}
|
|
1705
2179
|
}
|
|
1706
|
-
|
|
1707
|
-
|
|
2180
|
+
updateAnchorLock(state, {
|
|
2181
|
+
anchorId: anchorIdForLock,
|
|
2182
|
+
anchorPosition: anchorPositionForLock,
|
|
2183
|
+
dataChanged,
|
|
2184
|
+
now,
|
|
2185
|
+
positionDiff
|
|
2186
|
+
});
|
|
2187
|
+
if (Math.abs(positionDiff) > MVCP_POSITION_EPSILON) {
|
|
2188
|
+
requestAdjust(ctx, positionDiff);
|
|
1708
2189
|
}
|
|
1709
2190
|
};
|
|
1710
2191
|
}
|
|
1711
2192
|
}
|
|
1712
2193
|
|
|
1713
2194
|
// src/core/prepareColumnStartState.ts
|
|
1714
|
-
function prepareColumnStartState(ctx,
|
|
2195
|
+
function prepareColumnStartState(ctx, startIndex, useAverageSize) {
|
|
1715
2196
|
var _a3;
|
|
2197
|
+
const state = ctx.state;
|
|
1716
2198
|
const numColumns = peek$(ctx, "numColumns");
|
|
1717
2199
|
let rowStartIndex = startIndex;
|
|
1718
|
-
const columnAtStart = state.columns
|
|
2200
|
+
const columnAtStart = state.columns[startIndex];
|
|
1719
2201
|
if (columnAtStart !== 1) {
|
|
1720
2202
|
rowStartIndex = findRowStartIndex(state, numColumns, startIndex);
|
|
1721
2203
|
}
|
|
1722
2204
|
let currentRowTop = 0;
|
|
1723
|
-
const
|
|
1724
|
-
const column = state.columns.get(curId);
|
|
2205
|
+
const column = state.columns[rowStartIndex];
|
|
1725
2206
|
if (rowStartIndex > 0) {
|
|
1726
2207
|
const prevIndex = rowStartIndex - 1;
|
|
1727
|
-
const
|
|
1728
|
-
const prevPosition = (_a3 = state.positions.get(prevId)) != null ? _a3 : 0;
|
|
2208
|
+
const prevPosition = (_a3 = state.positions[prevIndex]) != null ? _a3 : 0;
|
|
1729
2209
|
const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
|
|
1730
|
-
const prevRowHeight = calculateRowMaxSize(ctx,
|
|
2210
|
+
const prevRowHeight = calculateRowMaxSize(ctx, prevRowStart, prevIndex, useAverageSize);
|
|
1731
2211
|
currentRowTop = prevPosition + prevRowHeight;
|
|
1732
2212
|
}
|
|
1733
2213
|
return {
|
|
@@ -1742,7 +2222,7 @@ function findRowStartIndex(state, numColumns, index) {
|
|
|
1742
2222
|
}
|
|
1743
2223
|
let rowStart = Math.max(0, index);
|
|
1744
2224
|
while (rowStart > 0) {
|
|
1745
|
-
const columnForIndex = state.columns
|
|
2225
|
+
const columnForIndex = state.columns[rowStart];
|
|
1746
2226
|
if (columnForIndex === 1) {
|
|
1747
2227
|
break;
|
|
1748
2228
|
}
|
|
@@ -1750,7 +2230,8 @@ function findRowStartIndex(state, numColumns, index) {
|
|
|
1750
2230
|
}
|
|
1751
2231
|
return rowStart;
|
|
1752
2232
|
}
|
|
1753
|
-
function calculateRowMaxSize(ctx,
|
|
2233
|
+
function calculateRowMaxSize(ctx, startIndex, endIndex, useAverageSize) {
|
|
2234
|
+
const state = ctx.state;
|
|
1754
2235
|
if (endIndex < startIndex) {
|
|
1755
2236
|
return 0;
|
|
1756
2237
|
}
|
|
@@ -1764,7 +2245,7 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
|
|
|
1764
2245
|
continue;
|
|
1765
2246
|
}
|
|
1766
2247
|
const id = state.idCache[i];
|
|
1767
|
-
const size = getItemSize(ctx,
|
|
2248
|
+
const size = getItemSize(ctx, id, i, data[i], useAverageSize);
|
|
1768
2249
|
if (size > maxSize) {
|
|
1769
2250
|
maxSize = size;
|
|
1770
2251
|
}
|
|
@@ -1773,22 +2254,44 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
|
|
|
1773
2254
|
}
|
|
1774
2255
|
|
|
1775
2256
|
// src/core/updateTotalSize.ts
|
|
1776
|
-
function updateTotalSize(ctx
|
|
2257
|
+
function updateTotalSize(ctx) {
|
|
2258
|
+
var _a3, _b;
|
|
2259
|
+
const state = ctx.state;
|
|
1777
2260
|
const {
|
|
1778
2261
|
positions,
|
|
1779
2262
|
props: { data }
|
|
1780
2263
|
} = state;
|
|
2264
|
+
const numColumns = (_a3 = peek$(ctx, "numColumns")) != null ? _a3 : 1;
|
|
1781
2265
|
if (data.length === 0) {
|
|
1782
|
-
addTotalSize(ctx,
|
|
2266
|
+
addTotalSize(ctx, null, 0);
|
|
1783
2267
|
} else {
|
|
1784
|
-
const
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
2268
|
+
const lastIndex = data.length - 1;
|
|
2269
|
+
const lastId = getId(state, lastIndex);
|
|
2270
|
+
const lastPosition = positions[lastIndex];
|
|
2271
|
+
if (lastId !== void 0 && lastPosition !== void 0) {
|
|
2272
|
+
if (numColumns > 1) {
|
|
2273
|
+
let rowStart = lastIndex;
|
|
2274
|
+
while (rowStart > 0) {
|
|
2275
|
+
const column = state.columns[rowStart];
|
|
2276
|
+
if (column === 1 || column === void 0) {
|
|
2277
|
+
break;
|
|
2278
|
+
}
|
|
2279
|
+
rowStart -= 1;
|
|
2280
|
+
}
|
|
2281
|
+
let maxSize = 0;
|
|
2282
|
+
for (let i = rowStart; i <= lastIndex; i++) {
|
|
2283
|
+
const rowId = (_b = state.idCache[i]) != null ? _b : getId(state, i);
|
|
2284
|
+
const size = getItemSize(ctx, rowId, i, data[i]);
|
|
2285
|
+
if (size > maxSize) {
|
|
2286
|
+
maxSize = size;
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
2289
|
+
addTotalSize(ctx, null, lastPosition + maxSize);
|
|
2290
|
+
} else {
|
|
2291
|
+
const lastSize = getItemSize(ctx, lastId, lastIndex, data[lastIndex]);
|
|
1789
2292
|
if (lastSize !== void 0) {
|
|
1790
2293
|
const totalSize = lastPosition + lastSize;
|
|
1791
|
-
addTotalSize(ctx,
|
|
2294
|
+
addTotalSize(ctx, null, totalSize);
|
|
1792
2295
|
}
|
|
1793
2296
|
}
|
|
1794
2297
|
}
|
|
@@ -1798,90 +2301,107 @@ function updateTotalSize(ctx, state) {
|
|
|
1798
2301
|
// src/utils/getScrollVelocity.ts
|
|
1799
2302
|
var getScrollVelocity = (state) => {
|
|
1800
2303
|
const { scrollHistory } = state;
|
|
1801
|
-
|
|
1802
|
-
if (
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
const currentDirection = nextEntry.scroll - entry.scroll;
|
|
1814
|
-
if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
|
|
1815
|
-
start = i;
|
|
1816
|
-
break;
|
|
1817
|
-
}
|
|
1818
|
-
}
|
|
2304
|
+
const newestIndex = scrollHistory.length - 1;
|
|
2305
|
+
if (newestIndex < 1) {
|
|
2306
|
+
return 0;
|
|
2307
|
+
}
|
|
2308
|
+
const newest = scrollHistory[newestIndex];
|
|
2309
|
+
const now = Date.now();
|
|
2310
|
+
let direction = 0;
|
|
2311
|
+
for (let i = newestIndex; i > 0; i--) {
|
|
2312
|
+
const delta = scrollHistory[i].scroll - scrollHistory[i - 1].scroll;
|
|
2313
|
+
if (delta !== 0) {
|
|
2314
|
+
direction = Math.sign(delta);
|
|
2315
|
+
break;
|
|
1819
2316
|
}
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
2317
|
+
}
|
|
2318
|
+
if (direction === 0) {
|
|
2319
|
+
return 0;
|
|
2320
|
+
}
|
|
2321
|
+
let oldest = newest;
|
|
2322
|
+
for (let i = newestIndex - 1; i >= 0; i--) {
|
|
2323
|
+
const current = scrollHistory[i];
|
|
2324
|
+
const next = scrollHistory[i + 1];
|
|
2325
|
+
const delta = next.scroll - current.scroll;
|
|
2326
|
+
const deltaSign = Math.sign(delta);
|
|
2327
|
+
if (deltaSign !== 0 && deltaSign !== direction) {
|
|
2328
|
+
break;
|
|
1826
2329
|
}
|
|
1827
|
-
if (
|
|
1828
|
-
|
|
1829
|
-
const timeDiff = newest.time - oldest.time;
|
|
1830
|
-
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
2330
|
+
if (now - current.time > 1e3) {
|
|
2331
|
+
break;
|
|
1831
2332
|
}
|
|
2333
|
+
oldest = current;
|
|
1832
2334
|
}
|
|
1833
|
-
|
|
2335
|
+
const scrollDiff = newest.scroll - oldest.scroll;
|
|
2336
|
+
const timeDiff = newest.time - oldest.time;
|
|
2337
|
+
return timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
1834
2338
|
};
|
|
1835
2339
|
|
|
1836
2340
|
// src/utils/updateSnapToOffsets.ts
|
|
1837
|
-
function updateSnapToOffsets(ctx
|
|
2341
|
+
function updateSnapToOffsets(ctx) {
|
|
2342
|
+
const state = ctx.state;
|
|
1838
2343
|
const {
|
|
1839
|
-
positions,
|
|
1840
2344
|
props: { snapToIndices }
|
|
1841
2345
|
} = state;
|
|
1842
2346
|
const snapToOffsets = Array(snapToIndices.length);
|
|
1843
2347
|
for (let i = 0; i < snapToIndices.length; i++) {
|
|
1844
2348
|
const idx = snapToIndices[i];
|
|
1845
|
-
|
|
1846
|
-
snapToOffsets[i] = positions
|
|
2349
|
+
getId(state, idx);
|
|
2350
|
+
snapToOffsets[i] = state.positions[idx];
|
|
1847
2351
|
}
|
|
1848
2352
|
set$(ctx, "snapToOffsets", snapToOffsets);
|
|
1849
2353
|
}
|
|
1850
2354
|
|
|
1851
2355
|
// src/core/updateItemPositions.ts
|
|
1852
|
-
function updateItemPositions(ctx,
|
|
2356
|
+
function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
|
|
1853
2357
|
doMVCP: false,
|
|
1854
2358
|
forceFullUpdate: false,
|
|
1855
2359
|
scrollBottomBuffered: -1,
|
|
1856
2360
|
startIndex: 0
|
|
1857
2361
|
}) {
|
|
1858
2362
|
var _a3, _b, _c, _d, _e;
|
|
2363
|
+
const state = ctx.state;
|
|
2364
|
+
const hasPositionListeners = ctx.positionListeners.size > 0;
|
|
1859
2365
|
const {
|
|
1860
2366
|
columns,
|
|
2367
|
+
columnSpans,
|
|
1861
2368
|
indexByKey,
|
|
1862
2369
|
positions,
|
|
1863
2370
|
idCache,
|
|
1864
2371
|
sizesKnown,
|
|
1865
|
-
props: { getEstimatedItemSize,
|
|
2372
|
+
props: { data, getEstimatedItemSize, overrideItemLayout, snapToIndices },
|
|
2373
|
+
scrollingTo
|
|
1866
2374
|
} = state;
|
|
1867
|
-
const data = state.props.data;
|
|
1868
2375
|
const dataLength = data.length;
|
|
1869
|
-
const numColumns = peek$(ctx, "numColumns");
|
|
1870
|
-
const scrollingTo = peek$(ctx, "scrollingTo");
|
|
2376
|
+
const numColumns = (_a3 = peek$(ctx, "numColumns")) != null ? _a3 : 1;
|
|
1871
2377
|
const hasColumns = numColumns > 1;
|
|
1872
2378
|
const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
|
|
1873
|
-
const
|
|
2379
|
+
const extraData = peek$(ctx, "extraData");
|
|
2380
|
+
const layoutConfig = overrideItemLayout ? { span: 1 } : void 0;
|
|
2381
|
+
const lastScrollDelta = state.lastScrollDelta;
|
|
2382
|
+
const velocity = getScrollVelocity(state);
|
|
2383
|
+
const shouldOptimize = !forceFullUpdate && !dataChanged && (Math.abs(velocity) > 0 || state.scrollLength > 0 && lastScrollDelta > state.scrollLength);
|
|
1874
2384
|
const maxVisibleArea = scrollBottomBuffered + 1e3;
|
|
1875
|
-
const useAverageSize =
|
|
1876
|
-
const preferCachedSize = !doMVCP || dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((
|
|
2385
|
+
const useAverageSize = !getEstimatedItemSize;
|
|
2386
|
+
const preferCachedSize = !doMVCP || dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_b = peek$(ctx, "scrollAdjustPending")) != null ? _b : 0) !== 0;
|
|
1877
2387
|
let currentRowTop = 0;
|
|
1878
2388
|
let column = 1;
|
|
1879
2389
|
let maxSizeInRow = 0;
|
|
2390
|
+
if (dataChanged) {
|
|
2391
|
+
columnSpans.length = 0;
|
|
2392
|
+
}
|
|
2393
|
+
if (!hasColumns) {
|
|
2394
|
+
if (columns.length) {
|
|
2395
|
+
columns.length = 0;
|
|
2396
|
+
}
|
|
2397
|
+
if (columnSpans.length) {
|
|
2398
|
+
columnSpans.length = 0;
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
1880
2401
|
if (startIndex > 0) {
|
|
1881
2402
|
if (hasColumns) {
|
|
1882
2403
|
const { startIndex: processedStartIndex, currentRowTop: initialRowTop } = prepareColumnStartState(
|
|
1883
2404
|
ctx,
|
|
1884
|
-
state,
|
|
1885
2405
|
startIndex,
|
|
1886
2406
|
useAverageSize
|
|
1887
2407
|
);
|
|
@@ -1890,12 +2410,13 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1890
2410
|
} else if (startIndex < dataLength) {
|
|
1891
2411
|
const prevIndex = startIndex - 1;
|
|
1892
2412
|
const prevId = getId(state, prevIndex);
|
|
1893
|
-
const prevPosition = (
|
|
1894
|
-
const prevSize = (
|
|
2413
|
+
const prevPosition = (_c = positions[prevIndex]) != null ? _c : 0;
|
|
2414
|
+
const prevSize = (_d = sizesKnown.get(prevId)) != null ? _d : getItemSize(ctx, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
|
|
1895
2415
|
currentRowTop = prevPosition + prevSize;
|
|
1896
2416
|
}
|
|
1897
2417
|
}
|
|
1898
2418
|
const needsIndexByKey = dataChanged || indexByKey.size === 0;
|
|
2419
|
+
const canOverrideSpan = hasColumns && !!overrideItemLayout && !!layoutConfig;
|
|
1899
2420
|
let didBreakEarly = false;
|
|
1900
2421
|
let breakAt;
|
|
1901
2422
|
for (let i = startIndex; i < dataLength; i++) {
|
|
@@ -1907,8 +2428,23 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1907
2428
|
const itemsPerRow = hasColumns ? numColumns : 1;
|
|
1908
2429
|
breakAt = i + itemsPerRow + 10;
|
|
1909
2430
|
}
|
|
1910
|
-
const id = (
|
|
1911
|
-
|
|
2431
|
+
const id = (_e = idCache[i]) != null ? _e : getId(state, i);
|
|
2432
|
+
let span = 1;
|
|
2433
|
+
if (canOverrideSpan) {
|
|
2434
|
+
layoutConfig.span = 1;
|
|
2435
|
+
overrideItemLayout(layoutConfig, data[i], i, numColumns, extraData);
|
|
2436
|
+
const requestedSpan = layoutConfig.span;
|
|
2437
|
+
if (requestedSpan !== void 0 && Number.isFinite(requestedSpan)) {
|
|
2438
|
+
span = Math.max(1, Math.min(numColumns, Math.round(requestedSpan)));
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
if (hasColumns && column + span - 1 > numColumns) {
|
|
2442
|
+
currentRowTop += maxSizeInRow;
|
|
2443
|
+
column = 1;
|
|
2444
|
+
maxSizeInRow = 0;
|
|
2445
|
+
}
|
|
2446
|
+
const knownSize = sizesKnown.get(id);
|
|
2447
|
+
const size = knownSize !== void 0 ? knownSize : getItemSize(ctx, id, i, data[i], useAverageSize, preferCachedSize);
|
|
1912
2448
|
if (IS_DEV && needsIndexByKey) {
|
|
1913
2449
|
if (indexByKeyForChecking.has(id)) {
|
|
1914
2450
|
console.error(
|
|
@@ -1917,30 +2453,36 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1917
2453
|
}
|
|
1918
2454
|
indexByKeyForChecking.set(id, i);
|
|
1919
2455
|
}
|
|
1920
|
-
|
|
2456
|
+
if (currentRowTop !== positions[i]) {
|
|
2457
|
+
positions[i] = currentRowTop;
|
|
2458
|
+
if (hasPositionListeners) {
|
|
2459
|
+
notifyPosition$(ctx, id, currentRowTop);
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
1921
2462
|
if (needsIndexByKey) {
|
|
1922
2463
|
indexByKey.set(id, i);
|
|
1923
2464
|
}
|
|
1924
|
-
|
|
1925
|
-
|
|
2465
|
+
if (!hasColumns) {
|
|
2466
|
+
currentRowTop += size;
|
|
2467
|
+
} else {
|
|
2468
|
+
columns[i] = column;
|
|
2469
|
+
columnSpans[i] = span;
|
|
1926
2470
|
if (size > maxSizeInRow) {
|
|
1927
2471
|
maxSizeInRow = size;
|
|
1928
2472
|
}
|
|
1929
|
-
column
|
|
2473
|
+
column += span;
|
|
1930
2474
|
if (column > numColumns) {
|
|
1931
2475
|
currentRowTop += maxSizeInRow;
|
|
1932
2476
|
column = 1;
|
|
1933
2477
|
maxSizeInRow = 0;
|
|
1934
2478
|
}
|
|
1935
|
-
} else {
|
|
1936
|
-
currentRowTop += size;
|
|
1937
2479
|
}
|
|
1938
2480
|
}
|
|
1939
2481
|
if (!didBreakEarly) {
|
|
1940
|
-
updateTotalSize(ctx
|
|
2482
|
+
updateTotalSize(ctx);
|
|
1941
2483
|
}
|
|
1942
2484
|
if (snapToIndices) {
|
|
1943
|
-
updateSnapToOffsets(ctx
|
|
2485
|
+
updateSnapToOffsets(ctx);
|
|
1944
2486
|
}
|
|
1945
2487
|
}
|
|
1946
2488
|
|
|
@@ -2018,7 +2560,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
|
|
|
2018
2560
|
if (previousViewableItems) {
|
|
2019
2561
|
for (const viewToken of previousViewableItems) {
|
|
2020
2562
|
const containerId = findContainerId(ctx, viewToken.key);
|
|
2021
|
-
if (!
|
|
2563
|
+
if (!checkIsViewable(
|
|
2022
2564
|
state,
|
|
2023
2565
|
ctx,
|
|
2024
2566
|
viewabilityConfig,
|
|
@@ -2039,7 +2581,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
|
|
|
2039
2581
|
if (item) {
|
|
2040
2582
|
const key = getId(state, i);
|
|
2041
2583
|
const containerId = findContainerId(ctx, key);
|
|
2042
|
-
if (
|
|
2584
|
+
if (checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
|
|
2043
2585
|
const viewToken = {
|
|
2044
2586
|
containerId,
|
|
2045
2587
|
index: i,
|
|
@@ -2085,25 +2627,49 @@ function shallowEqual(prev, next) {
|
|
|
2085
2627
|
return true;
|
|
2086
2628
|
}
|
|
2087
2629
|
function computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
|
|
2088
|
-
const { sizes,
|
|
2630
|
+
const { sizes, scroll: scrollState } = state;
|
|
2089
2631
|
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
2090
2632
|
const { itemVisiblePercentThreshold, viewAreaCoveragePercentThreshold } = viewabilityConfig;
|
|
2091
2633
|
const viewAreaMode = viewAreaCoveragePercentThreshold != null;
|
|
2092
2634
|
const viewablePercentThreshold = viewAreaMode ? viewAreaCoveragePercentThreshold : itemVisiblePercentThreshold;
|
|
2093
2635
|
const scroll = scrollState - topPad;
|
|
2094
|
-
const
|
|
2636
|
+
const position = state.positions[index];
|
|
2095
2637
|
const size = sizes.get(key) || 0;
|
|
2638
|
+
if (position === void 0) {
|
|
2639
|
+
const value2 = {
|
|
2640
|
+
containerId,
|
|
2641
|
+
index,
|
|
2642
|
+
isViewable: false,
|
|
2643
|
+
item,
|
|
2644
|
+
key,
|
|
2645
|
+
percentOfScroller: 0,
|
|
2646
|
+
percentVisible: 0,
|
|
2647
|
+
scrollSize,
|
|
2648
|
+
size,
|
|
2649
|
+
sizeVisible: -1
|
|
2650
|
+
};
|
|
2651
|
+
const prev2 = ctx.mapViewabilityAmountValues.get(containerId);
|
|
2652
|
+
if (!shallowEqual(prev2, value2)) {
|
|
2653
|
+
ctx.mapViewabilityAmountValues.set(containerId, value2);
|
|
2654
|
+
const cb = ctx.mapViewabilityAmountCallbacks.get(containerId);
|
|
2655
|
+
if (cb) {
|
|
2656
|
+
cb(value2);
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
return value2;
|
|
2660
|
+
}
|
|
2661
|
+
const top = position - scroll;
|
|
2096
2662
|
const bottom = top + size;
|
|
2097
2663
|
const isEntirelyVisible = top >= 0 && bottom <= scrollSize && bottom > top;
|
|
2098
2664
|
const sizeVisible = isEntirelyVisible ? size : Math.min(bottom, scrollSize) - Math.max(top, 0);
|
|
2099
2665
|
const percentVisible = size ? isEntirelyVisible ? 100 : 100 * (sizeVisible / size) : 0;
|
|
2100
2666
|
const percentOfScroller = size ? 100 * (sizeVisible / scrollSize) : 0;
|
|
2101
2667
|
const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
|
|
2102
|
-
const
|
|
2668
|
+
const isViewable = percent >= viewablePercentThreshold;
|
|
2103
2669
|
const value = {
|
|
2104
2670
|
containerId,
|
|
2105
2671
|
index,
|
|
2106
|
-
isViewable
|
|
2672
|
+
isViewable,
|
|
2107
2673
|
item,
|
|
2108
2674
|
key,
|
|
2109
2675
|
percentOfScroller,
|
|
@@ -2122,8 +2688,11 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
|
|
|
2122
2688
|
}
|
|
2123
2689
|
return value;
|
|
2124
2690
|
}
|
|
2125
|
-
function
|
|
2126
|
-
|
|
2691
|
+
function checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
|
|
2692
|
+
let value = ctx.mapViewabilityAmountValues.get(containerId);
|
|
2693
|
+
if (!value || value.key !== key) {
|
|
2694
|
+
value = computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
|
|
2695
|
+
}
|
|
2127
2696
|
return value.isViewable;
|
|
2128
2697
|
}
|
|
2129
2698
|
function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
|
|
@@ -2132,6 +2701,8 @@ function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
|
|
|
2132
2701
|
const cb = ctx.mapViewabilityCallbacks.get(key);
|
|
2133
2702
|
cb == null ? void 0 : cb(viewToken);
|
|
2134
2703
|
}
|
|
2704
|
+
var unstableBatchedUpdates = ReactDOM__namespace.unstable_batchedUpdates;
|
|
2705
|
+
var batchedUpdates = typeof unstableBatchedUpdates === "function" ? unstableBatchedUpdates : (fn) => fn();
|
|
2135
2706
|
|
|
2136
2707
|
// src/utils/checkAllSizesKnown.ts
|
|
2137
2708
|
function isNullOrUndefined2(value) {
|
|
@@ -2151,8 +2722,9 @@ function checkAllSizesKnown(state) {
|
|
|
2151
2722
|
}
|
|
2152
2723
|
|
|
2153
2724
|
// src/utils/findAvailableContainers.ts
|
|
2154
|
-
function findAvailableContainers(ctx,
|
|
2725
|
+
function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
|
|
2155
2726
|
const numContainers = peek$(ctx, "numContainers");
|
|
2727
|
+
const state = ctx.state;
|
|
2156
2728
|
const { stickyContainerPool, containerItemTypes } = state;
|
|
2157
2729
|
const result = [];
|
|
2158
2730
|
const availableContainers = [];
|
|
@@ -2272,92 +2844,93 @@ function comparatorByDistance(a, b) {
|
|
|
2272
2844
|
}
|
|
2273
2845
|
|
|
2274
2846
|
// src/core/scrollToIndex.ts
|
|
2275
|
-
function scrollToIndex(ctx,
|
|
2276
|
-
|
|
2277
|
-
|
|
2847
|
+
function scrollToIndex(ctx, { index, viewOffset = 0, animated = true, viewPosition }) {
|
|
2848
|
+
const state = ctx.state;
|
|
2849
|
+
const { data } = state.props;
|
|
2850
|
+
if (index >= data.length) {
|
|
2851
|
+
index = data.length - 1;
|
|
2278
2852
|
} else if (index < 0) {
|
|
2279
2853
|
index = 0;
|
|
2280
2854
|
}
|
|
2281
|
-
const firstIndexOffset = calculateOffsetForIndex(ctx,
|
|
2282
|
-
const isLast = index ===
|
|
2855
|
+
const firstIndexOffset = calculateOffsetForIndex(ctx, index);
|
|
2856
|
+
const isLast = index === data.length - 1;
|
|
2283
2857
|
if (isLast && viewPosition === void 0) {
|
|
2284
2858
|
viewPosition = 1;
|
|
2285
2859
|
}
|
|
2286
2860
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
2287
|
-
|
|
2861
|
+
const targetId = getId(state, index);
|
|
2862
|
+
const itemSize = getItemSize(ctx, targetId, index, state.props.data[index]);
|
|
2863
|
+
scrollTo(ctx, {
|
|
2288
2864
|
animated,
|
|
2289
2865
|
index,
|
|
2866
|
+
itemSize,
|
|
2290
2867
|
offset: firstIndexOffset,
|
|
2291
2868
|
viewOffset,
|
|
2292
2869
|
viewPosition: viewPosition != null ? viewPosition : 0
|
|
2293
2870
|
});
|
|
2294
|
-
}
|
|
2295
|
-
|
|
2296
|
-
// src/utils/setDidLayout.ts
|
|
2297
|
-
function setDidLayout(ctx
|
|
2298
|
-
const
|
|
2299
|
-
|
|
2300
|
-
initialScroll,
|
|
2301
|
-
props: { onLoad }
|
|
2302
|
-
} = state;
|
|
2871
|
+
}
|
|
2872
|
+
|
|
2873
|
+
// src/utils/setDidLayout.ts
|
|
2874
|
+
function setDidLayout(ctx) {
|
|
2875
|
+
const state = ctx.state;
|
|
2876
|
+
const { initialScroll } = state;
|
|
2303
2877
|
state.queuedInitialLayout = true;
|
|
2304
|
-
checkAtBottom(ctx
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
}
|
|
2311
|
-
{
|
|
2312
|
-
setIt();
|
|
2313
|
-
}
|
|
2878
|
+
checkAtBottom(ctx);
|
|
2879
|
+
if ((initialScroll == null ? void 0 : initialScroll.index) !== void 0) {
|
|
2880
|
+
const target = initialScroll;
|
|
2881
|
+
const runScroll = () => scrollToIndex(ctx, { ...target, animated: false });
|
|
2882
|
+
runScroll();
|
|
2883
|
+
requestAnimationFrame(runScroll);
|
|
2884
|
+
}
|
|
2885
|
+
setInitialRenderState(ctx, { didLayout: true });
|
|
2314
2886
|
}
|
|
2315
2887
|
|
|
2316
2888
|
// src/core/calculateItemsInView.ts
|
|
2317
2889
|
function findCurrentStickyIndex(stickyArray, scroll, state) {
|
|
2318
|
-
var _a3;
|
|
2319
|
-
const idCache = state.idCache;
|
|
2320
2890
|
const positions = state.positions;
|
|
2321
2891
|
for (let i = stickyArray.length - 1; i >= 0; i--) {
|
|
2322
2892
|
const stickyIndex = stickyArray[i];
|
|
2323
|
-
const
|
|
2324
|
-
const stickyPos = stickyId ? positions.get(stickyId) : void 0;
|
|
2893
|
+
const stickyPos = positions[stickyIndex];
|
|
2325
2894
|
if (stickyPos !== void 0 && scroll >= stickyPos) {
|
|
2326
2895
|
return i;
|
|
2327
2896
|
}
|
|
2328
2897
|
}
|
|
2329
2898
|
return -1;
|
|
2330
2899
|
}
|
|
2331
|
-
function getActiveStickyIndices(ctx,
|
|
2900
|
+
function getActiveStickyIndices(ctx, stickyHeaderIndices) {
|
|
2901
|
+
const state = ctx.state;
|
|
2332
2902
|
return new Set(
|
|
2333
2903
|
Array.from(state.stickyContainerPool).map((i) => peek$(ctx, `containerItemKey${i}`)).map((key) => key ? state.indexByKey.get(key) : void 0).filter((idx) => idx !== void 0 && stickyHeaderIndices.has(idx))
|
|
2334
2904
|
);
|
|
2335
2905
|
}
|
|
2336
|
-
function handleStickyActivation(ctx,
|
|
2906
|
+
function handleStickyActivation(ctx, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, needNewContainersSet, startBuffered, endBuffered) {
|
|
2337
2907
|
var _a3;
|
|
2338
|
-
const
|
|
2339
|
-
|
|
2908
|
+
const state = ctx.state;
|
|
2909
|
+
const activeIndices = getActiveStickyIndices(ctx, stickyHeaderIndices);
|
|
2910
|
+
set$(ctx, "activeStickyIndex", currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : -1);
|
|
2340
2911
|
for (let offset = 0; offset <= 1; offset++) {
|
|
2341
2912
|
const idx = currentStickyIdx - offset;
|
|
2342
2913
|
if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
|
|
2343
2914
|
const stickyIndex = stickyArray[idx];
|
|
2344
2915
|
const stickyId = (_a3 = state.idCache[stickyIndex]) != null ? _a3 : getId(state, stickyIndex);
|
|
2345
|
-
if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered)) {
|
|
2916
|
+
if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered) && !needNewContainersSet.has(stickyIndex)) {
|
|
2917
|
+
needNewContainersSet.add(stickyIndex);
|
|
2346
2918
|
needNewContainers.push(stickyIndex);
|
|
2347
2919
|
}
|
|
2348
2920
|
}
|
|
2349
2921
|
}
|
|
2350
|
-
function handleStickyRecycling(ctx,
|
|
2351
|
-
var _a3, _b
|
|
2922
|
+
function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentStickyIdx, pendingRemoval, alwaysRenderIndicesSet) {
|
|
2923
|
+
var _a3, _b;
|
|
2924
|
+
const state = ctx.state;
|
|
2352
2925
|
for (const containerIndex of state.stickyContainerPool) {
|
|
2353
2926
|
const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
2354
2927
|
const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
|
|
2355
2928
|
if (itemIndex === void 0) continue;
|
|
2929
|
+
if (alwaysRenderIndicesSet.has(itemIndex)) continue;
|
|
2356
2930
|
const arrayIdx = stickyArray.indexOf(itemIndex);
|
|
2357
2931
|
if (arrayIdx === -1) {
|
|
2358
2932
|
state.stickyContainerPool.delete(containerIndex);
|
|
2359
2933
|
set$(ctx, `containerSticky${containerIndex}`, false);
|
|
2360
|
-
set$(ctx, `containerStickyOffset${containerIndex}`, void 0);
|
|
2361
2934
|
continue;
|
|
2362
2935
|
}
|
|
2363
2936
|
const isRecentSticky = arrayIdx >= currentStickyIdx - 1 && arrayIdx <= currentStickyIdx + 1;
|
|
@@ -2365,15 +2938,14 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
|
|
|
2365
2938
|
const nextIndex = stickyArray[arrayIdx + 1];
|
|
2366
2939
|
let shouldRecycle = false;
|
|
2367
2940
|
if (nextIndex) {
|
|
2368
|
-
const
|
|
2369
|
-
|
|
2370
|
-
shouldRecycle = nextPos !== void 0 && scroll > nextPos + scrollBuffer * 2;
|
|
2941
|
+
const nextPos = state.positions[nextIndex];
|
|
2942
|
+
shouldRecycle = nextPos !== void 0 && scroll > nextPos + drawDistance * 2;
|
|
2371
2943
|
} else {
|
|
2372
|
-
const currentId = (
|
|
2944
|
+
const currentId = (_a3 = state.idCache[itemIndex]) != null ? _a3 : getId(state, itemIndex);
|
|
2373
2945
|
if (currentId) {
|
|
2374
|
-
const currentPos = state.positions
|
|
2375
|
-
const currentSize = (
|
|
2376
|
-
shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize +
|
|
2946
|
+
const currentPos = state.positions[itemIndex];
|
|
2947
|
+
const currentSize = (_b = state.sizes.get(currentId)) != null ? _b : getItemSize(ctx, currentId, itemIndex, state.props.data[itemIndex]);
|
|
2948
|
+
shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + drawDistance * 3;
|
|
2377
2949
|
}
|
|
2378
2950
|
}
|
|
2379
2951
|
if (shouldRecycle) {
|
|
@@ -2381,11 +2953,13 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
|
|
|
2381
2953
|
}
|
|
2382
2954
|
}
|
|
2383
2955
|
}
|
|
2384
|
-
function calculateItemsInView(ctx,
|
|
2385
|
-
|
|
2386
|
-
|
|
2956
|
+
function calculateItemsInView(ctx, params = {}) {
|
|
2957
|
+
const state = ctx.state;
|
|
2958
|
+
batchedUpdates(() => {
|
|
2959
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
2387
2960
|
const {
|
|
2388
2961
|
columns,
|
|
2962
|
+
columnSpans,
|
|
2389
2963
|
containerItemKeys,
|
|
2390
2964
|
enableScrollForNextCalculateItemsInView,
|
|
2391
2965
|
idCache,
|
|
@@ -2393,7 +2967,15 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2393
2967
|
initialScroll,
|
|
2394
2968
|
minIndexSizeChanged,
|
|
2395
2969
|
positions,
|
|
2396
|
-
props: {
|
|
2970
|
+
props: {
|
|
2971
|
+
alwaysRenderIndicesArr,
|
|
2972
|
+
alwaysRenderIndicesSet,
|
|
2973
|
+
drawDistance,
|
|
2974
|
+
getItemType,
|
|
2975
|
+
itemsAreEqual,
|
|
2976
|
+
keyExtractor,
|
|
2977
|
+
onStickyHeaderChange
|
|
2978
|
+
},
|
|
2397
2979
|
scrollForNextCalculateItemsInView,
|
|
2398
2980
|
scrollLength,
|
|
2399
2981
|
sizes,
|
|
@@ -2403,17 +2985,16 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2403
2985
|
const { data } = state.props;
|
|
2404
2986
|
const stickyIndicesArr = state.props.stickyIndicesArr || [];
|
|
2405
2987
|
const stickyIndicesSet = state.props.stickyIndicesSet || /* @__PURE__ */ new Set();
|
|
2988
|
+
const alwaysRenderArr = alwaysRenderIndicesArr || [];
|
|
2989
|
+
const alwaysRenderSet = alwaysRenderIndicesSet || /* @__PURE__ */ new Set();
|
|
2990
|
+
const { dataChanged, doMVCP, forceFullItemPositions } = params;
|
|
2406
2991
|
const prevNumContainers = peek$(ctx, "numContainers");
|
|
2407
2992
|
if (!data || scrollLength === 0 || !prevNumContainers) {
|
|
2408
|
-
if (state.initialAnchor) {
|
|
2409
|
-
ensureInitialAnchor(ctx, state);
|
|
2410
|
-
}
|
|
2411
2993
|
return;
|
|
2412
2994
|
}
|
|
2413
2995
|
const totalSize = getContentSize(ctx);
|
|
2414
2996
|
const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
|
|
2415
2997
|
const numColumns = peek$(ctx, "numColumns");
|
|
2416
|
-
const { dataChanged, doMVCP, forceFullItemPositions } = params;
|
|
2417
2998
|
const speed = getScrollVelocity(state);
|
|
2418
2999
|
const scrollExtra = 0;
|
|
2419
3000
|
const { queuedInitialLayout } = state;
|
|
@@ -2421,56 +3002,55 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2421
3002
|
if (!queuedInitialLayout && initialScroll) {
|
|
2422
3003
|
const updatedOffset = calculateOffsetWithOffsetPosition(
|
|
2423
3004
|
ctx,
|
|
2424
|
-
|
|
2425
|
-
calculateOffsetForIndex(ctx, state, initialScroll.index),
|
|
3005
|
+
calculateOffsetForIndex(ctx, initialScroll.index),
|
|
2426
3006
|
initialScroll
|
|
2427
3007
|
);
|
|
2428
3008
|
scrollState = updatedOffset;
|
|
2429
3009
|
}
|
|
2430
3010
|
const scrollAdjustPending = (_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0;
|
|
2431
3011
|
const scrollAdjustPad = scrollAdjustPending - topPad;
|
|
2432
|
-
let scroll = scrollState + scrollExtra + scrollAdjustPad;
|
|
3012
|
+
let scroll = Math.round(scrollState + scrollExtra + scrollAdjustPad);
|
|
2433
3013
|
if (scroll + scrollLength > totalSize) {
|
|
2434
3014
|
scroll = Math.max(0, totalSize - scrollLength);
|
|
2435
3015
|
}
|
|
2436
|
-
|
|
2437
|
-
set$(ctx, "debugRawScroll", scrollState);
|
|
2438
|
-
set$(ctx, "debugComputedScroll", scroll);
|
|
2439
|
-
}
|
|
2440
|
-
const previousStickyIndex = state.activeStickyIndex;
|
|
3016
|
+
const previousStickyIndex = peek$(ctx, "activeStickyIndex");
|
|
2441
3017
|
const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
|
|
2442
|
-
const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] :
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
let
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
3018
|
+
const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : -1;
|
|
3019
|
+
if (currentStickyIdx >= 0 || previousStickyIndex >= 0) {
|
|
3020
|
+
set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
|
|
3021
|
+
}
|
|
3022
|
+
let scrollBufferTop = drawDistance;
|
|
3023
|
+
let scrollBufferBottom = drawDistance;
|
|
3024
|
+
if (speed > 0 || speed === 0 && scroll < Math.max(50, drawDistance)) {
|
|
3025
|
+
scrollBufferTop = drawDistance * 0.5;
|
|
3026
|
+
scrollBufferBottom = drawDistance * 1.5;
|
|
2450
3027
|
} else {
|
|
2451
|
-
scrollBufferTop =
|
|
2452
|
-
scrollBufferBottom =
|
|
3028
|
+
scrollBufferTop = drawDistance * 1.5;
|
|
3029
|
+
scrollBufferBottom = drawDistance * 0.5;
|
|
2453
3030
|
}
|
|
2454
3031
|
const scrollTopBuffered = scroll - scrollBufferTop;
|
|
2455
3032
|
const scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
|
|
2456
3033
|
const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
|
|
2457
|
-
if (!dataChanged && scrollForNextCalculateItemsInView) {
|
|
3034
|
+
if (!dataChanged && !forceFullItemPositions && scrollForNextCalculateItemsInView) {
|
|
2458
3035
|
const { top, bottom } = scrollForNextCalculateItemsInView;
|
|
2459
|
-
if (
|
|
2460
|
-
|
|
2461
|
-
|
|
3036
|
+
if (top === null && bottom === null) {
|
|
3037
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
3038
|
+
} else if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
|
|
3039
|
+
if (!isInMVCPActiveMode(state)) {
|
|
3040
|
+
return;
|
|
2462
3041
|
}
|
|
2463
|
-
return;
|
|
2464
3042
|
}
|
|
2465
3043
|
}
|
|
2466
|
-
const checkMVCP = doMVCP ? prepareMVCP(ctx,
|
|
3044
|
+
const checkMVCP = doMVCP ? prepareMVCP(ctx, dataChanged) : void 0;
|
|
2467
3045
|
if (dataChanged) {
|
|
2468
3046
|
indexByKey.clear();
|
|
2469
3047
|
idCache.length = 0;
|
|
2470
|
-
positions.
|
|
3048
|
+
positions.length = 0;
|
|
3049
|
+
columns.length = 0;
|
|
3050
|
+
columnSpans.length = 0;
|
|
2471
3051
|
}
|
|
2472
|
-
const startIndex = dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
|
|
2473
|
-
updateItemPositions(ctx,
|
|
3052
|
+
const startIndex = forceFullItemPositions || dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
|
|
3053
|
+
updateItemPositions(ctx, dataChanged, {
|
|
2474
3054
|
doMVCP,
|
|
2475
3055
|
forceFullUpdate: !!forceFullItemPositions,
|
|
2476
3056
|
scrollBottomBuffered,
|
|
@@ -2488,18 +3068,23 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2488
3068
|
let loopStart = !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
|
|
2489
3069
|
for (let i = loopStart; i >= 0; i--) {
|
|
2490
3070
|
const id = (_c = idCache[i]) != null ? _c : getId(state, i);
|
|
2491
|
-
const top = positions
|
|
2492
|
-
const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx,
|
|
3071
|
+
const top = positions[i];
|
|
3072
|
+
const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, id, i, data[i]);
|
|
2493
3073
|
const bottom = top + size;
|
|
2494
|
-
if (bottom > scroll -
|
|
3074
|
+
if (bottom > scroll - scrollBufferTop) {
|
|
2495
3075
|
loopStart = i;
|
|
2496
3076
|
} else {
|
|
2497
3077
|
break;
|
|
2498
3078
|
}
|
|
2499
3079
|
}
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
3080
|
+
if (numColumns > 1) {
|
|
3081
|
+
while (loopStart > 0) {
|
|
3082
|
+
const loopColumn = columns[loopStart];
|
|
3083
|
+
if (loopColumn === 1 || loopColumn === void 0) {
|
|
3084
|
+
break;
|
|
3085
|
+
}
|
|
3086
|
+
loopStart -= 1;
|
|
3087
|
+
}
|
|
2503
3088
|
}
|
|
2504
3089
|
let foundEnd = false;
|
|
2505
3090
|
let nextTop;
|
|
@@ -2516,8 +3101,8 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2516
3101
|
const dataLength = data.length;
|
|
2517
3102
|
for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
|
|
2518
3103
|
const id = (_e = idCache[i]) != null ? _e : getId(state, i);
|
|
2519
|
-
const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx,
|
|
2520
|
-
const top = positions
|
|
3104
|
+
const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, id, i, data[i]);
|
|
3105
|
+
const top = positions[i];
|
|
2521
3106
|
if (!foundEnd) {
|
|
2522
3107
|
if (startNoBuffer === null && top + size > scroll) {
|
|
2523
3108
|
startNoBuffer = i;
|
|
@@ -2528,7 +3113,11 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2528
3113
|
if (startBuffered === null && top + size > scrollTopBuffered) {
|
|
2529
3114
|
startBuffered = i;
|
|
2530
3115
|
startBufferedId = id;
|
|
2531
|
-
|
|
3116
|
+
if (scrollTopBuffered < 0) {
|
|
3117
|
+
nextTop = null;
|
|
3118
|
+
} else {
|
|
3119
|
+
nextTop = top;
|
|
3120
|
+
}
|
|
2532
3121
|
}
|
|
2533
3122
|
if (startNoBuffer !== null) {
|
|
2534
3123
|
if (top <= scrollBottom) {
|
|
@@ -2536,7 +3125,11 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2536
3125
|
}
|
|
2537
3126
|
if (top <= scrollBottomBuffered) {
|
|
2538
3127
|
endBuffered = i;
|
|
2539
|
-
|
|
3128
|
+
if (scrollBottomBuffered > totalSize) {
|
|
3129
|
+
nextBottom = null;
|
|
3130
|
+
} else {
|
|
3131
|
+
nextBottom = top + size;
|
|
3132
|
+
}
|
|
2540
3133
|
} else {
|
|
2541
3134
|
foundEnd = true;
|
|
2542
3135
|
}
|
|
@@ -2558,12 +3151,12 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2558
3151
|
startNoBuffer
|
|
2559
3152
|
});
|
|
2560
3153
|
if (enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0) {
|
|
2561
|
-
state.scrollForNextCalculateItemsInView = nextTop
|
|
3154
|
+
state.scrollForNextCalculateItemsInView = isNullOrUndefined(nextTop) && isNullOrUndefined(nextBottom) ? void 0 : {
|
|
2562
3155
|
bottom: nextBottom,
|
|
2563
3156
|
top: nextTop
|
|
2564
|
-
}
|
|
3157
|
+
};
|
|
2565
3158
|
}
|
|
2566
|
-
|
|
3159
|
+
let numContainers = prevNumContainers;
|
|
2567
3160
|
const pendingRemoval = [];
|
|
2568
3161
|
if (dataChanged) {
|
|
2569
3162
|
for (let i = 0; i < numContainers; i++) {
|
|
@@ -2574,37 +3167,46 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2574
3167
|
}
|
|
2575
3168
|
}
|
|
2576
3169
|
if (startBuffered !== null && endBuffered !== null) {
|
|
2577
|
-
let numContainers2 = prevNumContainers;
|
|
2578
3170
|
const needNewContainers = [];
|
|
3171
|
+
const needNewContainersSet = /* @__PURE__ */ new Set();
|
|
2579
3172
|
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
2580
3173
|
const id = (_h = idCache[i]) != null ? _h : getId(state, i);
|
|
2581
3174
|
if (!containerItemKeys.has(id)) {
|
|
3175
|
+
needNewContainersSet.add(i);
|
|
2582
3176
|
needNewContainers.push(i);
|
|
2583
3177
|
}
|
|
2584
3178
|
}
|
|
3179
|
+
if (alwaysRenderArr.length > 0) {
|
|
3180
|
+
for (const index of alwaysRenderArr) {
|
|
3181
|
+
if (index < 0 || index >= dataLength) continue;
|
|
3182
|
+
const id = (_i = idCache[index]) != null ? _i : getId(state, index);
|
|
3183
|
+
if (id && !containerItemKeys.has(id) && !needNewContainersSet.has(index)) {
|
|
3184
|
+
needNewContainersSet.add(index);
|
|
3185
|
+
needNewContainers.push(index);
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
}
|
|
2585
3189
|
if (stickyIndicesArr.length > 0) {
|
|
2586
3190
|
handleStickyActivation(
|
|
2587
3191
|
ctx,
|
|
2588
|
-
state,
|
|
2589
3192
|
stickyIndicesSet,
|
|
2590
3193
|
stickyIndicesArr,
|
|
2591
3194
|
currentStickyIdx,
|
|
2592
3195
|
needNewContainers,
|
|
3196
|
+
needNewContainersSet,
|
|
2593
3197
|
startBuffered,
|
|
2594
3198
|
endBuffered
|
|
2595
3199
|
);
|
|
2596
|
-
} else {
|
|
2597
|
-
|
|
2598
|
-
set$(ctx, "activeStickyIndex", void 0);
|
|
3200
|
+
} else if (previousStickyIndex !== -1) {
|
|
3201
|
+
set$(ctx, "activeStickyIndex", -1);
|
|
2599
3202
|
}
|
|
2600
3203
|
if (needNewContainers.length > 0) {
|
|
2601
3204
|
const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
|
|
2602
3205
|
const itemType = getItemType(data[i], i);
|
|
2603
|
-
return itemType ? String(itemType) : "";
|
|
3206
|
+
return itemType !== void 0 ? String(itemType) : "";
|
|
2604
3207
|
}) : void 0;
|
|
2605
3208
|
const availableContainers = findAvailableContainers(
|
|
2606
3209
|
ctx,
|
|
2607
|
-
state,
|
|
2608
3210
|
needNewContainers.length,
|
|
2609
3211
|
startBuffered,
|
|
2610
3212
|
endBuffered,
|
|
@@ -2615,7 +3217,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2615
3217
|
for (let idx = 0; idx < needNewContainers.length; idx++) {
|
|
2616
3218
|
const i = needNewContainers[idx];
|
|
2617
3219
|
const containerIndex = availableContainers[idx];
|
|
2618
|
-
const id = (
|
|
3220
|
+
const id = (_j = idCache[i]) != null ? _j : getId(state, i);
|
|
2619
3221
|
const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
2620
3222
|
if (oldKey && oldKey !== id) {
|
|
2621
3223
|
containerItemKeys.delete(oldKey);
|
|
@@ -2625,30 +3227,55 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2625
3227
|
if (requiredItemTypes) {
|
|
2626
3228
|
state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
|
|
2627
3229
|
}
|
|
2628
|
-
containerItemKeys.
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
3230
|
+
containerItemKeys.set(id, containerIndex);
|
|
3231
|
+
const containerSticky = `containerSticky${containerIndex}`;
|
|
3232
|
+
const isSticky = stickyIndicesSet.has(i);
|
|
3233
|
+
const isAlwaysRender = alwaysRenderSet.has(i);
|
|
3234
|
+
if (isSticky) {
|
|
3235
|
+
set$(ctx, containerSticky, true);
|
|
2633
3236
|
state.stickyContainerPool.add(containerIndex);
|
|
2634
3237
|
} else {
|
|
2635
|
-
|
|
2636
|
-
|
|
3238
|
+
if (peek$(ctx, containerSticky)) {
|
|
3239
|
+
set$(ctx, containerSticky, false);
|
|
3240
|
+
}
|
|
3241
|
+
if (isAlwaysRender) {
|
|
3242
|
+
state.stickyContainerPool.add(containerIndex);
|
|
3243
|
+
} else if (state.stickyContainerPool.has(containerIndex)) {
|
|
3244
|
+
state.stickyContainerPool.delete(containerIndex);
|
|
3245
|
+
}
|
|
3246
|
+
}
|
|
3247
|
+
if (containerIndex >= numContainers) {
|
|
3248
|
+
numContainers = containerIndex + 1;
|
|
2637
3249
|
}
|
|
2638
|
-
|
|
2639
|
-
|
|
3250
|
+
}
|
|
3251
|
+
if (numContainers !== prevNumContainers) {
|
|
3252
|
+
set$(ctx, "numContainers", numContainers);
|
|
3253
|
+
if (numContainers > peek$(ctx, "numContainersPooled")) {
|
|
3254
|
+
set$(ctx, "numContainersPooled", Math.ceil(numContainers * 1.5));
|
|
2640
3255
|
}
|
|
2641
3256
|
}
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
3257
|
+
}
|
|
3258
|
+
if (alwaysRenderArr.length > 0) {
|
|
3259
|
+
for (const index of alwaysRenderArr) {
|
|
3260
|
+
if (index < 0 || index >= dataLength) continue;
|
|
3261
|
+
const id = (_k = idCache[index]) != null ? _k : getId(state, index);
|
|
3262
|
+
const containerIndex = containerItemKeys.get(id);
|
|
3263
|
+
if (containerIndex !== void 0) {
|
|
3264
|
+
state.stickyContainerPool.add(containerIndex);
|
|
2646
3265
|
}
|
|
2647
3266
|
}
|
|
2648
3267
|
}
|
|
2649
3268
|
}
|
|
2650
|
-
if (
|
|
2651
|
-
handleStickyRecycling(
|
|
3269
|
+
if (state.stickyContainerPool.size > 0) {
|
|
3270
|
+
handleStickyRecycling(
|
|
3271
|
+
ctx,
|
|
3272
|
+
stickyIndicesArr,
|
|
3273
|
+
scroll,
|
|
3274
|
+
drawDistance,
|
|
3275
|
+
currentStickyIdx,
|
|
3276
|
+
pendingRemoval,
|
|
3277
|
+
alwaysRenderSet
|
|
3278
|
+
);
|
|
2652
3279
|
}
|
|
2653
3280
|
let didChangePositions = false;
|
|
2654
3281
|
for (let i = 0; i < numContainers; i++) {
|
|
@@ -2660,26 +3287,27 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2660
3287
|
state.containerItemTypes.delete(i);
|
|
2661
3288
|
if (state.stickyContainerPool.has(i)) {
|
|
2662
3289
|
set$(ctx, `containerSticky${i}`, false);
|
|
2663
|
-
set$(ctx, `containerStickyOffset${i}`, void 0);
|
|
2664
3290
|
state.stickyContainerPool.delete(i);
|
|
2665
3291
|
}
|
|
2666
3292
|
set$(ctx, `containerItemKey${i}`, void 0);
|
|
2667
3293
|
set$(ctx, `containerItemData${i}`, void 0);
|
|
2668
3294
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
2669
3295
|
set$(ctx, `containerColumn${i}`, -1);
|
|
3296
|
+
set$(ctx, `containerSpan${i}`, 1);
|
|
2670
3297
|
} else {
|
|
2671
3298
|
const itemIndex = indexByKey.get(itemKey);
|
|
2672
3299
|
const item = data[itemIndex];
|
|
2673
3300
|
if (item !== void 0) {
|
|
2674
|
-
const
|
|
2675
|
-
const positionValue = positions.get(id);
|
|
3301
|
+
const positionValue = positions[itemIndex];
|
|
2676
3302
|
if (positionValue === void 0) {
|
|
2677
3303
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
2678
3304
|
} else {
|
|
2679
3305
|
const position = (positionValue || 0) - scrollAdjustPending;
|
|
2680
|
-
const column = columns
|
|
3306
|
+
const column = columns[itemIndex] || 1;
|
|
3307
|
+
const span = columnSpans[itemIndex] || 1;
|
|
2681
3308
|
const prevPos = peek$(ctx, `containerPosition${i}`);
|
|
2682
3309
|
const prevColumn = peek$(ctx, `containerColumn${i}`);
|
|
3310
|
+
const prevSpan = peek$(ctx, `containerSpan${i}`);
|
|
2683
3311
|
const prevData = peek$(ctx, `containerItemData${i}`);
|
|
2684
3312
|
if (position > POSITION_OUT_OF_VIEW && position !== prevPos) {
|
|
2685
3313
|
set$(ctx, `containerPosition${i}`, position);
|
|
@@ -2688,6 +3316,9 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2688
3316
|
if (column >= 0 && column !== prevColumn) {
|
|
2689
3317
|
set$(ctx, `containerColumn${i}`, column);
|
|
2690
3318
|
}
|
|
3319
|
+
if (span !== prevSpan) {
|
|
3320
|
+
set$(ctx, `containerSpan${i}`, span);
|
|
3321
|
+
}
|
|
2691
3322
|
if (prevData !== item && (itemsAreEqual ? !itemsAreEqual(prevData, item, itemIndex, data) : true)) {
|
|
2692
3323
|
set$(ctx, `containerItemData${i}`, item);
|
|
2693
3324
|
}
|
|
@@ -2700,7 +3331,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2700
3331
|
}
|
|
2701
3332
|
if (!queuedInitialLayout && endBuffered !== null) {
|
|
2702
3333
|
if (checkAllSizesKnown(state)) {
|
|
2703
|
-
setDidLayout(ctx
|
|
3334
|
+
setDidLayout(ctx);
|
|
2704
3335
|
}
|
|
2705
3336
|
}
|
|
2706
3337
|
if (viewabilityConfigCallbackPairs) {
|
|
@@ -2713,9 +3344,6 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2713
3344
|
}
|
|
2714
3345
|
}
|
|
2715
3346
|
});
|
|
2716
|
-
if (state.initialAnchor) {
|
|
2717
|
-
ensureInitialAnchor(ctx, state);
|
|
2718
|
-
}
|
|
2719
3347
|
}
|
|
2720
3348
|
|
|
2721
3349
|
// src/core/checkActualChange.ts
|
|
@@ -2738,20 +3366,74 @@ function checkActualChange(state, dataProp, previousData) {
|
|
|
2738
3366
|
return false;
|
|
2739
3367
|
}
|
|
2740
3368
|
|
|
3369
|
+
// src/core/checkFinishedScroll.ts
|
|
3370
|
+
function checkFinishedScroll(ctx) {
|
|
3371
|
+
ctx.state.animFrameCheckFinishedScroll = requestAnimationFrame(() => checkFinishedScrollFrame(ctx));
|
|
3372
|
+
}
|
|
3373
|
+
function checkFinishedScrollFrame(ctx) {
|
|
3374
|
+
const scrollingTo = ctx.state.scrollingTo;
|
|
3375
|
+
if (scrollingTo) {
|
|
3376
|
+
const { state } = ctx;
|
|
3377
|
+
state.animFrameCheckFinishedScroll = void 0;
|
|
3378
|
+
const scroll = state.scrollPending;
|
|
3379
|
+
const adjust = state.scrollAdjustHandler.getAdjust();
|
|
3380
|
+
const clampedTargetOffset = clampScrollOffset(
|
|
3381
|
+
ctx,
|
|
3382
|
+
scrollingTo.offset - (scrollingTo.viewOffset || 0),
|
|
3383
|
+
scrollingTo
|
|
3384
|
+
);
|
|
3385
|
+
const maxOffset = clampScrollOffset(ctx, scroll, scrollingTo);
|
|
3386
|
+
const diff1 = Math.abs(scroll - clampedTargetOffset);
|
|
3387
|
+
const diff2 = Math.abs(diff1 - adjust);
|
|
3388
|
+
const isNotOverscrolled = Math.abs(scroll - maxOffset) < 1;
|
|
3389
|
+
const isAtTarget = diff1 < 1 || !scrollingTo.animated && diff2 < 1;
|
|
3390
|
+
if (isNotOverscrolled && isAtTarget) {
|
|
3391
|
+
finishScrollTo(ctx);
|
|
3392
|
+
}
|
|
3393
|
+
}
|
|
3394
|
+
}
|
|
3395
|
+
function checkFinishedScrollFallback(ctx) {
|
|
3396
|
+
const state = ctx.state;
|
|
3397
|
+
const scrollingTo = state.scrollingTo;
|
|
3398
|
+
const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) || !state.didContainersLayout;
|
|
3399
|
+
state.timeoutCheckFinishedScrollFallback = setTimeout(
|
|
3400
|
+
() => {
|
|
3401
|
+
let numChecks = 0;
|
|
3402
|
+
const checkHasScrolled = () => {
|
|
3403
|
+
state.timeoutCheckFinishedScrollFallback = void 0;
|
|
3404
|
+
const isStillScrollingTo = state.scrollingTo;
|
|
3405
|
+
if (isStillScrollingTo) {
|
|
3406
|
+
numChecks++;
|
|
3407
|
+
if (state.hasScrolled || numChecks > 5) {
|
|
3408
|
+
finishScrollTo(ctx);
|
|
3409
|
+
} else {
|
|
3410
|
+
state.timeoutCheckFinishedScrollFallback = setTimeout(checkHasScrolled, 100);
|
|
3411
|
+
}
|
|
3412
|
+
}
|
|
3413
|
+
};
|
|
3414
|
+
checkHasScrolled();
|
|
3415
|
+
},
|
|
3416
|
+
slowTimeout ? 500 : 100
|
|
3417
|
+
);
|
|
3418
|
+
}
|
|
3419
|
+
|
|
2741
3420
|
// src/core/doMaintainScrollAtEnd.ts
|
|
2742
|
-
function doMaintainScrollAtEnd(ctx,
|
|
3421
|
+
function doMaintainScrollAtEnd(ctx, animated) {
|
|
3422
|
+
const state = ctx.state;
|
|
2743
3423
|
const {
|
|
3424
|
+
didContainersLayout,
|
|
3425
|
+
isAtEnd,
|
|
2744
3426
|
refScroller,
|
|
2745
3427
|
props: { maintainScrollAtEnd }
|
|
2746
3428
|
} = state;
|
|
2747
|
-
if (
|
|
2748
|
-
const
|
|
2749
|
-
if (
|
|
3429
|
+
if (isAtEnd && maintainScrollAtEnd && didContainersLayout) {
|
|
3430
|
+
const contentSize = getContentSize(ctx);
|
|
3431
|
+
if (contentSize < state.scrollLength) {
|
|
2750
3432
|
state.scroll = 0;
|
|
2751
3433
|
}
|
|
2752
3434
|
requestAnimationFrame(() => {
|
|
2753
3435
|
var _a3;
|
|
2754
|
-
if (state
|
|
3436
|
+
if (state.isAtEnd) {
|
|
2755
3437
|
state.maintainingScrollAtEnd = true;
|
|
2756
3438
|
(_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
|
|
2757
3439
|
animated
|
|
@@ -2822,36 +3504,37 @@ function updateAveragesOnDataChange(state, oldData, newData) {
|
|
|
2822
3504
|
}
|
|
2823
3505
|
|
|
2824
3506
|
// src/core/checkResetContainers.ts
|
|
2825
|
-
function checkResetContainers(ctx,
|
|
3507
|
+
function checkResetContainers(ctx, dataProp) {
|
|
3508
|
+
const state = ctx.state;
|
|
2826
3509
|
const { previousData } = state;
|
|
2827
3510
|
if (previousData) {
|
|
2828
3511
|
updateAveragesOnDataChange(state, previousData, dataProp);
|
|
2829
3512
|
}
|
|
2830
3513
|
const { maintainScrollAtEnd } = state.props;
|
|
2831
|
-
calculateItemsInView(ctx,
|
|
3514
|
+
calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
|
|
2832
3515
|
const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
|
|
2833
|
-
const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx,
|
|
3516
|
+
const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, false);
|
|
2834
3517
|
if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
|
|
2835
3518
|
state.isEndReached = false;
|
|
2836
3519
|
}
|
|
2837
3520
|
if (!didMaintainScrollAtEnd) {
|
|
2838
|
-
|
|
2839
|
-
checkAtBottom(ctx, state);
|
|
3521
|
+
checkThresholds(ctx);
|
|
2840
3522
|
}
|
|
2841
3523
|
delete state.previousData;
|
|
2842
3524
|
}
|
|
2843
3525
|
|
|
2844
3526
|
// src/core/doInitialAllocateContainers.ts
|
|
2845
|
-
function doInitialAllocateContainers(ctx
|
|
3527
|
+
function doInitialAllocateContainers(ctx) {
|
|
2846
3528
|
var _a3, _b, _c;
|
|
3529
|
+
const state = ctx.state;
|
|
2847
3530
|
const {
|
|
2848
3531
|
scrollLength,
|
|
2849
3532
|
props: {
|
|
2850
3533
|
data,
|
|
3534
|
+
drawDistance,
|
|
2851
3535
|
getEstimatedItemSize,
|
|
2852
3536
|
getFixedItemSize,
|
|
2853
3537
|
getItemType,
|
|
2854
|
-
scrollBuffer,
|
|
2855
3538
|
numColumns,
|
|
2856
3539
|
estimatedItemSize
|
|
2857
3540
|
}
|
|
@@ -2864,40 +3547,62 @@ function doInitialAllocateContainers(ctx, state, dataChanged) {
|
|
|
2864
3547
|
const num = Math.min(20, data.length);
|
|
2865
3548
|
for (let i = 0; i < num; i++) {
|
|
2866
3549
|
const item = data[i];
|
|
2867
|
-
|
|
2868
|
-
|
|
3550
|
+
if (item !== void 0) {
|
|
3551
|
+
const itemType = (_a3 = getItemType == null ? void 0 : getItemType(item, i)) != null ? _a3 : "";
|
|
3552
|
+
totalSize += (_c = (_b = getFixedItemSize == null ? void 0 : getFixedItemSize(item, i, itemType)) != null ? _b : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(item, i, itemType)) != null ? _c : estimatedItemSize;
|
|
3553
|
+
}
|
|
2869
3554
|
}
|
|
2870
3555
|
averageItemSize = totalSize / num;
|
|
2871
3556
|
} else {
|
|
2872
3557
|
averageItemSize = estimatedItemSize;
|
|
2873
3558
|
}
|
|
2874
|
-
const numContainers = Math.ceil((scrollLength +
|
|
3559
|
+
const numContainers = Math.ceil((scrollLength + drawDistance * 2) / averageItemSize * numColumns);
|
|
2875
3560
|
for (let i = 0; i < numContainers; i++) {
|
|
2876
3561
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
2877
3562
|
set$(ctx, `containerColumn${i}`, -1);
|
|
3563
|
+
set$(ctx, `containerSpan${i}`, 1);
|
|
2878
3564
|
}
|
|
2879
3565
|
set$(ctx, "numContainers", numContainers);
|
|
2880
3566
|
set$(ctx, "numContainersPooled", numContainers * state.props.initialContainerPoolRatio);
|
|
2881
3567
|
if (state.lastLayout) {
|
|
2882
3568
|
if (state.initialScroll) {
|
|
2883
3569
|
requestAnimationFrame(() => {
|
|
2884
|
-
calculateItemsInView(ctx,
|
|
3570
|
+
calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
|
|
2885
3571
|
});
|
|
2886
3572
|
} else {
|
|
2887
|
-
calculateItemsInView(ctx,
|
|
3573
|
+
calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
|
|
2888
3574
|
}
|
|
2889
3575
|
}
|
|
2890
3576
|
return true;
|
|
2891
3577
|
}
|
|
2892
3578
|
}
|
|
2893
3579
|
|
|
3580
|
+
// src/platform/getWindowSize.ts
|
|
3581
|
+
function getWindowSize() {
|
|
3582
|
+
if (typeof window === "undefined") {
|
|
3583
|
+
return { height: 0, width: 0 };
|
|
3584
|
+
}
|
|
3585
|
+
return {
|
|
3586
|
+
height: window.innerHeight,
|
|
3587
|
+
width: window.innerWidth
|
|
3588
|
+
};
|
|
3589
|
+
}
|
|
3590
|
+
|
|
2894
3591
|
// src/core/handleLayout.ts
|
|
2895
|
-
function handleLayout(ctx,
|
|
2896
|
-
const
|
|
2897
|
-
const
|
|
3592
|
+
function handleLayout(ctx, layoutParam, setCanRender) {
|
|
3593
|
+
const state = ctx.state;
|
|
3594
|
+
const { maintainScrollAtEnd, useWindowScroll } = state.props;
|
|
3595
|
+
const scrollAxis = state.props.horizontal ? "width" : "height";
|
|
3596
|
+
const otherAxis = state.props.horizontal ? "height" : "width";
|
|
3597
|
+
let layout = layoutParam;
|
|
3598
|
+
if (useWindowScroll) {
|
|
3599
|
+
const windowScrollAxisLength = getWindowSize()[scrollAxis];
|
|
3600
|
+
layout = windowScrollAxisLength > 0 ? { ...layoutParam, [scrollAxis]: windowScrollAxisLength } : layoutParam;
|
|
3601
|
+
}
|
|
3602
|
+
const measuredLength = layout[scrollAxis];
|
|
2898
3603
|
const previousLength = state.scrollLength;
|
|
2899
3604
|
const scrollLength = measuredLength > 0 ? measuredLength : previousLength;
|
|
2900
|
-
const otherAxisSize = layout[
|
|
3605
|
+
const otherAxisSize = layout[otherAxis];
|
|
2901
3606
|
const needsCalculate = !state.lastLayout || scrollLength > state.scrollLength || state.lastLayout.x !== layout.x || state.lastLayout.y !== layout.y;
|
|
2902
3607
|
state.lastLayout = layout;
|
|
2903
3608
|
const prevOtherAxisSize = state.otherAxisSize;
|
|
@@ -2908,20 +3613,18 @@ function handleLayout(ctx, state, layout, setCanRender) {
|
|
|
2908
3613
|
state.lastBatchingAction = Date.now();
|
|
2909
3614
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
2910
3615
|
if (scrollLength > 0) {
|
|
2911
|
-
doInitialAllocateContainers(ctx
|
|
3616
|
+
doInitialAllocateContainers(ctx);
|
|
2912
3617
|
}
|
|
2913
3618
|
if (needsCalculate) {
|
|
2914
|
-
calculateItemsInView(ctx,
|
|
3619
|
+
calculateItemsInView(ctx, { doMVCP: true });
|
|
2915
3620
|
}
|
|
2916
3621
|
if (didChange || otherAxisSize !== prevOtherAxisSize) {
|
|
2917
3622
|
set$(ctx, "scrollSize", { height: layout.height, width: layout.width });
|
|
2918
3623
|
}
|
|
2919
3624
|
if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
|
|
2920
|
-
doMaintainScrollAtEnd(ctx,
|
|
3625
|
+
doMaintainScrollAtEnd(ctx, false);
|
|
2921
3626
|
}
|
|
2922
|
-
|
|
2923
|
-
checkAtBottom(ctx, state);
|
|
2924
|
-
checkAtTop(state);
|
|
3627
|
+
checkThresholds(ctx);
|
|
2925
3628
|
if (state) {
|
|
2926
3629
|
state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
|
|
2927
3630
|
}
|
|
@@ -2936,8 +3639,9 @@ function handleLayout(ctx, state, layout, setCanRender) {
|
|
|
2936
3639
|
}
|
|
2937
3640
|
|
|
2938
3641
|
// src/core/onScroll.ts
|
|
2939
|
-
function onScroll(ctx,
|
|
2940
|
-
var _a3, _b, _c;
|
|
3642
|
+
function onScroll(ctx, event) {
|
|
3643
|
+
var _a3, _b, _c, _d;
|
|
3644
|
+
const state = ctx.state;
|
|
2941
3645
|
const {
|
|
2942
3646
|
scrollProcessingEnabled,
|
|
2943
3647
|
props: { onScroll: onScrollProp }
|
|
@@ -2948,17 +3652,34 @@ function onScroll(ctx, state, event) {
|
|
|
2948
3652
|
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) {
|
|
2949
3653
|
return;
|
|
2950
3654
|
}
|
|
3655
|
+
let insetChanged = false;
|
|
3656
|
+
if ((_d = event.nativeEvent) == null ? void 0 : _d.contentInset) {
|
|
3657
|
+
const { contentInset } = event.nativeEvent;
|
|
3658
|
+
const prevInset = state.nativeContentInset;
|
|
3659
|
+
if (!prevInset || prevInset.top !== contentInset.top || prevInset.bottom !== contentInset.bottom || prevInset.left !== contentInset.left || prevInset.right !== contentInset.right) {
|
|
3660
|
+
state.nativeContentInset = contentInset;
|
|
3661
|
+
insetChanged = true;
|
|
3662
|
+
}
|
|
3663
|
+
}
|
|
2951
3664
|
let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
|
|
3665
|
+
if (state.scrollingTo && state.scrollingTo.offset >= newScroll) {
|
|
3666
|
+
const maxOffset = clampScrollOffset(ctx, newScroll, state.scrollingTo);
|
|
3667
|
+
if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
|
|
3668
|
+
newScroll = maxOffset;
|
|
3669
|
+
scrollTo(ctx, {
|
|
3670
|
+
forceScroll: true,
|
|
3671
|
+
isInitialScroll: true,
|
|
3672
|
+
noScrollingTo: true,
|
|
3673
|
+
offset: newScroll
|
|
3674
|
+
});
|
|
3675
|
+
return;
|
|
3676
|
+
}
|
|
3677
|
+
}
|
|
2952
3678
|
state.scrollPending = newScroll;
|
|
2953
|
-
|
|
2954
|
-
if (state.
|
|
2955
|
-
|
|
2956
|
-
scrollTo(ctx, state, {
|
|
2957
|
-
noScrollingTo: true,
|
|
2958
|
-
offset: newScroll
|
|
2959
|
-
});
|
|
3679
|
+
updateScroll(ctx, newScroll, insetChanged);
|
|
3680
|
+
if (state.scrollingTo) {
|
|
3681
|
+
checkFinishedScroll(ctx);
|
|
2960
3682
|
}
|
|
2961
|
-
updateScroll(ctx, state, newScroll);
|
|
2962
3683
|
onScrollProp == null ? void 0 : onScrollProp(event);
|
|
2963
3684
|
}
|
|
2964
3685
|
|
|
@@ -2967,51 +3688,78 @@ var ScrollAdjustHandler = class {
|
|
|
2967
3688
|
constructor(ctx) {
|
|
2968
3689
|
this.appliedAdjust = 0;
|
|
2969
3690
|
this.pendingAdjust = 0;
|
|
2970
|
-
this.
|
|
2971
|
-
this.context = ctx;
|
|
2972
|
-
{
|
|
2973
|
-
const commitPendingAdjust = () => {
|
|
2974
|
-
const state = this.context.internalState;
|
|
2975
|
-
const pending = this.pendingAdjust;
|
|
2976
|
-
if (pending !== 0) {
|
|
2977
|
-
this.pendingAdjust = 0;
|
|
2978
|
-
this.appliedAdjust += pending;
|
|
2979
|
-
state.scroll += pending;
|
|
2980
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
2981
|
-
set$(this.context, "scrollAdjustPending", 0);
|
|
2982
|
-
set$(this.context, "scrollAdjust", this.appliedAdjust);
|
|
2983
|
-
calculateItemsInView(this.context, this.context.internalState);
|
|
2984
|
-
}
|
|
2985
|
-
};
|
|
2986
|
-
listen$(this.context, "scrollingTo", (value) => {
|
|
2987
|
-
if (value === void 0) {
|
|
2988
|
-
commitPendingAdjust();
|
|
2989
|
-
}
|
|
2990
|
-
});
|
|
2991
|
-
}
|
|
3691
|
+
this.ctx = ctx;
|
|
2992
3692
|
}
|
|
2993
3693
|
requestAdjust(add) {
|
|
2994
|
-
const scrollingTo =
|
|
3694
|
+
const scrollingTo = this.ctx.state.scrollingTo;
|
|
2995
3695
|
if ((scrollingTo == null ? void 0 : scrollingTo.animated) && !scrollingTo.isInitialScroll) {
|
|
2996
3696
|
this.pendingAdjust += add;
|
|
2997
|
-
set$(this.
|
|
3697
|
+
set$(this.ctx, "scrollAdjustPending", this.pendingAdjust);
|
|
2998
3698
|
} else {
|
|
2999
3699
|
this.appliedAdjust += add;
|
|
3000
|
-
set$(this.
|
|
3700
|
+
set$(this.ctx, "scrollAdjust", this.appliedAdjust);
|
|
3701
|
+
}
|
|
3702
|
+
if (this.ctx.state.scrollingTo) {
|
|
3703
|
+
checkFinishedScroll(this.ctx);
|
|
3001
3704
|
}
|
|
3002
|
-
}
|
|
3003
|
-
setMounted() {
|
|
3004
|
-
this.mounted = true;
|
|
3005
3705
|
}
|
|
3006
3706
|
getAdjust() {
|
|
3007
3707
|
return this.appliedAdjust;
|
|
3008
3708
|
}
|
|
3709
|
+
commitPendingAdjust(scrollTarget) {
|
|
3710
|
+
{
|
|
3711
|
+
const state = this.ctx.state;
|
|
3712
|
+
const pending = this.pendingAdjust;
|
|
3713
|
+
this.pendingAdjust = 0;
|
|
3714
|
+
if (pending !== 0) {
|
|
3715
|
+
let targetScroll;
|
|
3716
|
+
if ((scrollTarget == null ? void 0 : scrollTarget.index) !== void 0) {
|
|
3717
|
+
const currentOffset = calculateOffsetForIndex(this.ctx, scrollTarget.index);
|
|
3718
|
+
targetScroll = calculateOffsetWithOffsetPosition(this.ctx, currentOffset, scrollTarget);
|
|
3719
|
+
targetScroll = clampScrollOffset(this.ctx, targetScroll, scrollTarget);
|
|
3720
|
+
} else {
|
|
3721
|
+
targetScroll = clampScrollOffset(this.ctx, state.scroll + pending);
|
|
3722
|
+
}
|
|
3723
|
+
const adjustment = targetScroll - state.scroll;
|
|
3724
|
+
if (Math.abs(adjustment) > 0.1 || Math.abs(pending) > 0.1) {
|
|
3725
|
+
this.appliedAdjust += adjustment;
|
|
3726
|
+
state.scroll = targetScroll;
|
|
3727
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
3728
|
+
set$(this.ctx, "scrollAdjust", this.appliedAdjust);
|
|
3729
|
+
}
|
|
3730
|
+
set$(this.ctx, "scrollAdjustPending", 0);
|
|
3731
|
+
calculateItemsInView(this.ctx);
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
}
|
|
3009
3735
|
};
|
|
3010
3736
|
|
|
3011
3737
|
// src/core/updateItemSize.ts
|
|
3012
|
-
function
|
|
3738
|
+
function runOrScheduleMVCPRecalculate(ctx) {
|
|
3739
|
+
const state = ctx.state;
|
|
3740
|
+
{
|
|
3741
|
+
if (!state.mvcpAnchorLock) {
|
|
3742
|
+
if (state.queuedMVCPRecalculate !== void 0) {
|
|
3743
|
+
cancelAnimationFrame(state.queuedMVCPRecalculate);
|
|
3744
|
+
state.queuedMVCPRecalculate = void 0;
|
|
3745
|
+
}
|
|
3746
|
+
calculateItemsInView(ctx, { doMVCP: true });
|
|
3747
|
+
return;
|
|
3748
|
+
}
|
|
3749
|
+
if (state.queuedMVCPRecalculate !== void 0) {
|
|
3750
|
+
return;
|
|
3751
|
+
}
|
|
3752
|
+
state.queuedMVCPRecalculate = requestAnimationFrame(() => {
|
|
3753
|
+
state.queuedMVCPRecalculate = void 0;
|
|
3754
|
+
calculateItemsInView(ctx, { doMVCP: true });
|
|
3755
|
+
});
|
|
3756
|
+
}
|
|
3757
|
+
}
|
|
3758
|
+
function updateItemSize(ctx, itemKey, sizeObj) {
|
|
3013
3759
|
var _a3;
|
|
3760
|
+
const state = ctx.state;
|
|
3014
3761
|
const {
|
|
3762
|
+
didContainersLayout,
|
|
3015
3763
|
sizesKnown,
|
|
3016
3764
|
props: {
|
|
3017
3765
|
getFixedItemSize,
|
|
@@ -3034,31 +3782,24 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
3034
3782
|
return;
|
|
3035
3783
|
}
|
|
3036
3784
|
const type = getItemType ? (_a3 = getItemType(itemData, index)) != null ? _a3 : "" : "";
|
|
3037
|
-
const size2 = getFixedItemSize(
|
|
3785
|
+
const size2 = getFixedItemSize(itemData, index, type);
|
|
3038
3786
|
if (size2 !== void 0 && size2 === sizesKnown.get(itemKey)) {
|
|
3039
3787
|
return;
|
|
3040
3788
|
}
|
|
3041
3789
|
}
|
|
3042
|
-
|
|
3043
|
-
let needsRecalculate = !containersDidLayout;
|
|
3790
|
+
let needsRecalculate = !didContainersLayout;
|
|
3044
3791
|
let shouldMaintainScrollAtEnd = false;
|
|
3045
3792
|
let minIndexSizeChanged;
|
|
3046
3793
|
let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
|
|
3047
3794
|
const prevSizeKnown = state.sizesKnown.get(itemKey);
|
|
3048
|
-
const diff = updateOneItemSize(ctx,
|
|
3795
|
+
const diff = updateOneItemSize(ctx, itemKey, sizeObj);
|
|
3049
3796
|
const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
|
|
3050
3797
|
if (diff !== 0) {
|
|
3051
3798
|
minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
|
|
3052
3799
|
const { startBuffered, endBuffered } = state;
|
|
3053
3800
|
needsRecalculate || (needsRecalculate = index >= startBuffered && index <= endBuffered);
|
|
3054
|
-
if (!needsRecalculate) {
|
|
3055
|
-
|
|
3056
|
-
for (let i = 0; i < numContainers; i++) {
|
|
3057
|
-
if (peek$(ctx, `containerItemKey${i}`) === itemKey) {
|
|
3058
|
-
needsRecalculate = true;
|
|
3059
|
-
break;
|
|
3060
|
-
}
|
|
3061
|
-
}
|
|
3801
|
+
if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
|
|
3802
|
+
needsRecalculate = true;
|
|
3062
3803
|
}
|
|
3063
3804
|
if (state.needsOtherAxisSize) {
|
|
3064
3805
|
const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
|
|
@@ -3094,20 +3835,21 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
3094
3835
|
if (!cur || maxOtherAxisSize > cur) {
|
|
3095
3836
|
set$(ctx, "otherAxisSize", maxOtherAxisSize);
|
|
3096
3837
|
}
|
|
3097
|
-
if (
|
|
3838
|
+
if (didContainersLayout || checkAllSizesKnown(state)) {
|
|
3098
3839
|
if (needsRecalculate) {
|
|
3099
3840
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
3100
|
-
|
|
3841
|
+
runOrScheduleMVCPRecalculate(ctx);
|
|
3101
3842
|
}
|
|
3102
3843
|
if (shouldMaintainScrollAtEnd) {
|
|
3103
3844
|
if (maintainScrollAtEnd === true || maintainScrollAtEnd.onItemLayout) {
|
|
3104
|
-
doMaintainScrollAtEnd(ctx,
|
|
3845
|
+
doMaintainScrollAtEnd(ctx, false);
|
|
3105
3846
|
}
|
|
3106
3847
|
}
|
|
3107
3848
|
}
|
|
3108
3849
|
}
|
|
3109
|
-
function updateOneItemSize(ctx,
|
|
3850
|
+
function updateOneItemSize(ctx, itemKey, sizeObj) {
|
|
3110
3851
|
var _a3;
|
|
3852
|
+
const state = ctx.state;
|
|
3111
3853
|
const {
|
|
3112
3854
|
indexByKey,
|
|
3113
3855
|
sizesKnown,
|
|
@@ -3116,9 +3858,10 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
3116
3858
|
} = state;
|
|
3117
3859
|
if (!data) return 0;
|
|
3118
3860
|
const index = indexByKey.get(itemKey);
|
|
3119
|
-
const prevSize = getItemSize(ctx,
|
|
3861
|
+
const prevSize = getItemSize(ctx, itemKey, index, data[index]);
|
|
3120
3862
|
const rawSize = horizontal ? sizeObj.width : sizeObj.height;
|
|
3121
3863
|
const size = Math.round(rawSize) ;
|
|
3864
|
+
const prevSizeKnown = sizesKnown.get(itemKey);
|
|
3122
3865
|
sizesKnown.set(itemKey, size);
|
|
3123
3866
|
if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
|
|
3124
3867
|
const itemType = getItemType ? (_a3 = getItemType(data[index], index)) != null ? _a3 : "" : "";
|
|
@@ -3126,15 +3869,28 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
3126
3869
|
if (!averages) {
|
|
3127
3870
|
averages = averageSizes[itemType] = { avg: 0, num: 0 };
|
|
3128
3871
|
}
|
|
3129
|
-
|
|
3130
|
-
|
|
3872
|
+
if (averages.num === 0) {
|
|
3873
|
+
averages.avg = size;
|
|
3874
|
+
averages.num++;
|
|
3875
|
+
} else if (prevSizeKnown !== void 0 && prevSizeKnown > 0) {
|
|
3876
|
+
averages.avg += (size - prevSizeKnown) / averages.num;
|
|
3877
|
+
} else {
|
|
3878
|
+
averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
|
|
3879
|
+
averages.num++;
|
|
3880
|
+
}
|
|
3131
3881
|
}
|
|
3132
3882
|
if (!prevSize || Math.abs(prevSize - size) > 0.1) {
|
|
3133
|
-
setSize(ctx,
|
|
3883
|
+
setSize(ctx, itemKey, size);
|
|
3134
3884
|
return size - prevSize;
|
|
3135
3885
|
}
|
|
3136
3886
|
return 0;
|
|
3137
3887
|
}
|
|
3888
|
+
function useWrapIfItem(fn) {
|
|
3889
|
+
return React3.useMemo(
|
|
3890
|
+
() => fn ? (arg1, arg2, arg3) => arg1 !== void 0 && arg2 !== void 0 ? fn(arg1, arg2, arg3) : void 0 : void 0,
|
|
3891
|
+
[fn]
|
|
3892
|
+
);
|
|
3893
|
+
}
|
|
3138
3894
|
var useCombinedRef = (...refs) => {
|
|
3139
3895
|
const callback = React3.useCallback((element) => {
|
|
3140
3896
|
for (const ref of refs) {
|
|
@@ -3177,30 +3933,104 @@ function createColumnWrapperStyle(contentContainerStyle) {
|
|
|
3177
3933
|
}
|
|
3178
3934
|
|
|
3179
3935
|
// src/utils/createImperativeHandle.ts
|
|
3180
|
-
function createImperativeHandle(ctx
|
|
3936
|
+
function createImperativeHandle(ctx) {
|
|
3937
|
+
const state = ctx.state;
|
|
3938
|
+
const IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS = 800;
|
|
3939
|
+
const IMPERATIVE_SCROLL_SETTLE_STABLE_FRAMES = 2;
|
|
3940
|
+
let imperativeScrollToken = 0;
|
|
3941
|
+
const isSettlingAfterDataChange = () => !!state.didDataChange || !!state.didColumnsChange || state.queuedMVCPRecalculate !== void 0 || state.ignoreScrollFromMVCP !== void 0 || hasActiveMVCPAnchorLock(state);
|
|
3942
|
+
const runWhenSettled = (token, run) => {
|
|
3943
|
+
const startedAt = Date.now();
|
|
3944
|
+
let stableFrames = 0;
|
|
3945
|
+
const check = () => {
|
|
3946
|
+
if (token !== imperativeScrollToken) {
|
|
3947
|
+
return;
|
|
3948
|
+
}
|
|
3949
|
+
if (isSettlingAfterDataChange()) {
|
|
3950
|
+
stableFrames = 0;
|
|
3951
|
+
} else {
|
|
3952
|
+
stableFrames += 1;
|
|
3953
|
+
}
|
|
3954
|
+
const timedOut = Date.now() - startedAt >= IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS;
|
|
3955
|
+
if (stableFrames >= IMPERATIVE_SCROLL_SETTLE_STABLE_FRAMES || timedOut) {
|
|
3956
|
+
run();
|
|
3957
|
+
return;
|
|
3958
|
+
}
|
|
3959
|
+
requestAnimationFrame(check);
|
|
3960
|
+
};
|
|
3961
|
+
requestAnimationFrame(check);
|
|
3962
|
+
};
|
|
3963
|
+
const runScrollWithPromise = (run) => new Promise((resolve) => {
|
|
3964
|
+
var _a3;
|
|
3965
|
+
const token = ++imperativeScrollToken;
|
|
3966
|
+
(_a3 = state.pendingScrollResolve) == null ? void 0 : _a3.call(state);
|
|
3967
|
+
state.pendingScrollResolve = resolve;
|
|
3968
|
+
const runNow = () => {
|
|
3969
|
+
if (token !== imperativeScrollToken) {
|
|
3970
|
+
return;
|
|
3971
|
+
}
|
|
3972
|
+
const didStartScroll = run();
|
|
3973
|
+
if (!didStartScroll || !state.scrollingTo) {
|
|
3974
|
+
if (state.pendingScrollResolve === resolve) {
|
|
3975
|
+
state.pendingScrollResolve = void 0;
|
|
3976
|
+
}
|
|
3977
|
+
resolve();
|
|
3978
|
+
}
|
|
3979
|
+
};
|
|
3980
|
+
if (isSettlingAfterDataChange()) {
|
|
3981
|
+
runWhenSettled(token, runNow);
|
|
3982
|
+
return;
|
|
3983
|
+
}
|
|
3984
|
+
runNow();
|
|
3985
|
+
});
|
|
3181
3986
|
const scrollIndexIntoView = (options) => {
|
|
3182
3987
|
if (state) {
|
|
3183
3988
|
const { index, ...rest } = options;
|
|
3184
3989
|
const { startNoBuffer, endNoBuffer } = state;
|
|
3185
3990
|
if (index < startNoBuffer || index > endNoBuffer) {
|
|
3186
3991
|
const viewPosition = index < startNoBuffer ? 0 : 1;
|
|
3187
|
-
scrollToIndex(ctx,
|
|
3992
|
+
scrollToIndex(ctx, {
|
|
3188
3993
|
...rest,
|
|
3189
3994
|
index,
|
|
3190
3995
|
viewPosition
|
|
3191
3996
|
});
|
|
3997
|
+
return true;
|
|
3192
3998
|
}
|
|
3193
3999
|
}
|
|
4000
|
+
return false;
|
|
3194
4001
|
};
|
|
3195
4002
|
const refScroller = state.refScroller;
|
|
4003
|
+
const clearCaches = (options) => {
|
|
4004
|
+
var _a3, _b;
|
|
4005
|
+
const mode = (_a3 = options == null ? void 0 : options.mode) != null ? _a3 : "sizes";
|
|
4006
|
+
state.sizes.clear();
|
|
4007
|
+
state.sizesKnown.clear();
|
|
4008
|
+
for (const key in state.averageSizes) {
|
|
4009
|
+
delete state.averageSizes[key];
|
|
4010
|
+
}
|
|
4011
|
+
state.minIndexSizeChanged = 0;
|
|
4012
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
4013
|
+
state.pendingTotalSize = void 0;
|
|
4014
|
+
state.totalSize = 0;
|
|
4015
|
+
set$(ctx, "totalSize", 0);
|
|
4016
|
+
if (mode === "full") {
|
|
4017
|
+
state.indexByKey.clear();
|
|
4018
|
+
state.idCache.length = 0;
|
|
4019
|
+
state.positions.length = 0;
|
|
4020
|
+
state.columns.length = 0;
|
|
4021
|
+
state.columnSpans.length = 0;
|
|
4022
|
+
}
|
|
4023
|
+
(_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
|
|
4024
|
+
};
|
|
3196
4025
|
return {
|
|
4026
|
+
clearCaches,
|
|
3197
4027
|
flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
|
|
3198
4028
|
getNativeScrollRef: () => refScroller.current,
|
|
3199
4029
|
getScrollableNode: () => refScroller.current.getScrollableNode(),
|
|
3200
4030
|
getScrollResponder: () => refScroller.current.getScrollResponder(),
|
|
3201
4031
|
getState: () => ({
|
|
3202
|
-
activeStickyIndex:
|
|
3203
|
-
contentLength:
|
|
4032
|
+
activeStickyIndex: peek$(ctx, "activeStickyIndex"),
|
|
4033
|
+
contentLength: getContentSize(ctx),
|
|
3204
4034
|
data: state.props.data,
|
|
3205
4035
|
elementAtIndex: (index) => {
|
|
3206
4036
|
var _a3;
|
|
@@ -3210,47 +4040,71 @@ function createImperativeHandle(ctx, state) {
|
|
|
3210
4040
|
endBuffered: state.endBuffered,
|
|
3211
4041
|
isAtEnd: state.isAtEnd,
|
|
3212
4042
|
isAtStart: state.isAtStart,
|
|
3213
|
-
|
|
3214
|
-
|
|
4043
|
+
isEndReached: state.isEndReached,
|
|
4044
|
+
isStartReached: state.isStartReached,
|
|
4045
|
+
listen: (signalName, cb) => listen$(ctx, signalName, cb),
|
|
4046
|
+
listenToPosition: (key, cb) => listenPosition$(ctx, key, cb),
|
|
4047
|
+
positionAtIndex: (index) => state.positions[index],
|
|
4048
|
+
positionByKey: (key) => {
|
|
4049
|
+
const index = state.indexByKey.get(key);
|
|
4050
|
+
return index === void 0 ? void 0 : state.positions[index];
|
|
4051
|
+
},
|
|
3215
4052
|
scroll: state.scroll,
|
|
3216
4053
|
scrollLength: state.scrollLength,
|
|
4054
|
+
scrollVelocity: getScrollVelocity(state),
|
|
3217
4055
|
sizeAtIndex: (index) => state.sizesKnown.get(getId(state, index)),
|
|
3218
4056
|
sizes: state.sizesKnown,
|
|
3219
4057
|
start: state.startNoBuffer,
|
|
3220
4058
|
startBuffered: state.startBuffered
|
|
3221
4059
|
}),
|
|
3222
|
-
|
|
3223
|
-
|
|
4060
|
+
reportContentInset: (inset) => {
|
|
4061
|
+
state.contentInsetOverride = inset != null ? inset : void 0;
|
|
4062
|
+
updateScroll(ctx, state.scroll, true);
|
|
4063
|
+
},
|
|
4064
|
+
scrollIndexIntoView: (options) => runScrollWithPromise(() => scrollIndexIntoView(options)),
|
|
4065
|
+
scrollItemIntoView: ({ item, ...props }) => runScrollWithPromise(() => {
|
|
3224
4066
|
const data = state.props.data;
|
|
3225
4067
|
const index = data.indexOf(item);
|
|
3226
4068
|
if (index !== -1) {
|
|
3227
4069
|
scrollIndexIntoView({ index, ...props });
|
|
4070
|
+
return true;
|
|
3228
4071
|
}
|
|
3229
|
-
|
|
3230
|
-
|
|
4072
|
+
return false;
|
|
4073
|
+
}),
|
|
4074
|
+
scrollToEnd: (options) => runScrollWithPromise(() => {
|
|
3231
4075
|
const data = state.props.data;
|
|
3232
4076
|
const stylePaddingBottom = state.props.stylePaddingBottom;
|
|
3233
4077
|
const index = data.length - 1;
|
|
3234
4078
|
if (index !== -1) {
|
|
3235
4079
|
const paddingBottom = stylePaddingBottom || 0;
|
|
3236
4080
|
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
3237
|
-
scrollToIndex(ctx,
|
|
4081
|
+
scrollToIndex(ctx, {
|
|
4082
|
+
...options,
|
|
3238
4083
|
index,
|
|
3239
4084
|
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
3240
|
-
viewPosition: 1
|
|
3241
|
-
...options
|
|
4085
|
+
viewPosition: 1
|
|
3242
4086
|
});
|
|
4087
|
+
return true;
|
|
3243
4088
|
}
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
4089
|
+
return false;
|
|
4090
|
+
}),
|
|
4091
|
+
scrollToIndex: (params) => runScrollWithPromise(() => {
|
|
4092
|
+
scrollToIndex(ctx, params);
|
|
4093
|
+
return true;
|
|
4094
|
+
}),
|
|
4095
|
+
scrollToItem: ({ item, ...props }) => runScrollWithPromise(() => {
|
|
3247
4096
|
const data = state.props.data;
|
|
3248
4097
|
const index = data.indexOf(item);
|
|
3249
4098
|
if (index !== -1) {
|
|
3250
|
-
scrollToIndex(ctx,
|
|
4099
|
+
scrollToIndex(ctx, { index, ...props });
|
|
4100
|
+
return true;
|
|
3251
4101
|
}
|
|
3252
|
-
|
|
3253
|
-
|
|
4102
|
+
return false;
|
|
4103
|
+
}),
|
|
4104
|
+
scrollToOffset: (params) => runScrollWithPromise(() => {
|
|
4105
|
+
scrollTo(ctx, params);
|
|
4106
|
+
return true;
|
|
4107
|
+
}),
|
|
3254
4108
|
setScrollProcessingEnabled: (enabled) => {
|
|
3255
4109
|
state.scrollProcessingEnabled = enabled;
|
|
3256
4110
|
},
|
|
@@ -3260,8 +4114,57 @@ function createImperativeHandle(ctx, state) {
|
|
|
3260
4114
|
}
|
|
3261
4115
|
};
|
|
3262
4116
|
}
|
|
3263
|
-
|
|
4117
|
+
|
|
4118
|
+
// src/utils/getAlwaysRenderIndices.ts
|
|
4119
|
+
var sortAsc = (a, b) => a - b;
|
|
4120
|
+
var toCount = (value) => typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;
|
|
4121
|
+
var addIndex = (result, dataLength, index) => {
|
|
4122
|
+
if (index >= 0 && index < dataLength) {
|
|
4123
|
+
result.add(index);
|
|
4124
|
+
}
|
|
4125
|
+
};
|
|
4126
|
+
function getAlwaysRenderIndices(config, data, keyExtractor) {
|
|
4127
|
+
var _a3, _b;
|
|
4128
|
+
if (!config || data.length === 0) {
|
|
4129
|
+
return [];
|
|
4130
|
+
}
|
|
4131
|
+
const result = /* @__PURE__ */ new Set();
|
|
4132
|
+
const dataLength = data.length;
|
|
4133
|
+
const topCount = toCount(config.top);
|
|
4134
|
+
if (topCount > 0) {
|
|
4135
|
+
for (let i = 0; i < Math.min(topCount, dataLength); i++) {
|
|
4136
|
+
addIndex(result, dataLength, i);
|
|
4137
|
+
}
|
|
4138
|
+
}
|
|
4139
|
+
const bottomCount = toCount(config.bottom);
|
|
4140
|
+
if (bottomCount > 0) {
|
|
4141
|
+
for (let i = Math.max(0, dataLength - bottomCount); i < dataLength; i++) {
|
|
4142
|
+
addIndex(result, dataLength, i);
|
|
4143
|
+
}
|
|
4144
|
+
}
|
|
4145
|
+
if ((_a3 = config.indices) == null ? void 0 : _a3.length) {
|
|
4146
|
+
for (const index of config.indices) {
|
|
4147
|
+
if (!Number.isFinite(index)) continue;
|
|
4148
|
+
addIndex(result, dataLength, Math.floor(index));
|
|
4149
|
+
}
|
|
4150
|
+
}
|
|
4151
|
+
if ((_b = config.keys) == null ? void 0 : _b.length) {
|
|
4152
|
+
const keys = new Set(config.keys);
|
|
4153
|
+
for (let i = 0; i < dataLength && keys.size > 0; i++) {
|
|
4154
|
+
const key = keyExtractor(data[i], i);
|
|
4155
|
+
if (keys.has(key)) {
|
|
4156
|
+
addIndex(result, dataLength, i);
|
|
4157
|
+
keys.delete(key);
|
|
4158
|
+
}
|
|
4159
|
+
}
|
|
4160
|
+
}
|
|
4161
|
+
const indices = Array.from(result);
|
|
4162
|
+
indices.sort(sortAsc);
|
|
4163
|
+
return indices;
|
|
4164
|
+
}
|
|
4165
|
+
function getRenderedItem(ctx, key) {
|
|
3264
4166
|
var _a3;
|
|
4167
|
+
const state = ctx.state;
|
|
3265
4168
|
if (!state) {
|
|
3266
4169
|
return null;
|
|
3267
4170
|
}
|
|
@@ -3288,6 +4191,42 @@ function getRenderedItem(ctx, state, key) {
|
|
|
3288
4191
|
}
|
|
3289
4192
|
return { index, item: data[index], renderedItem };
|
|
3290
4193
|
}
|
|
4194
|
+
|
|
4195
|
+
// src/utils/normalizeMaintainVisibleContentPosition.ts
|
|
4196
|
+
function normalizeMaintainVisibleContentPosition(value) {
|
|
4197
|
+
var _a3, _b;
|
|
4198
|
+
if (value === true) {
|
|
4199
|
+
return { data: true, size: true };
|
|
4200
|
+
}
|
|
4201
|
+
if (value && typeof value === "object") {
|
|
4202
|
+
return {
|
|
4203
|
+
data: (_a3 = value.data) != null ? _a3 : false,
|
|
4204
|
+
shouldRestorePosition: value.shouldRestorePosition,
|
|
4205
|
+
size: (_b = value.size) != null ? _b : true
|
|
4206
|
+
};
|
|
4207
|
+
}
|
|
4208
|
+
if (value === false) {
|
|
4209
|
+
return { data: false, size: false };
|
|
4210
|
+
}
|
|
4211
|
+
return { data: false, size: true };
|
|
4212
|
+
}
|
|
4213
|
+
|
|
4214
|
+
// src/utils/setPaddingTop.ts
|
|
4215
|
+
function setPaddingTop(ctx, { stylePaddingTop }) {
|
|
4216
|
+
const state = ctx.state;
|
|
4217
|
+
if (stylePaddingTop !== void 0) {
|
|
4218
|
+
const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
|
|
4219
|
+
if (stylePaddingTop < prevStylePaddingTop) {
|
|
4220
|
+
let prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
4221
|
+
set$(ctx, "totalSize", prevTotalSize + prevStylePaddingTop);
|
|
4222
|
+
state.timeoutSetPaddingTop = setTimeout(() => {
|
|
4223
|
+
prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
4224
|
+
set$(ctx, "totalSize", prevTotalSize - prevStylePaddingTop);
|
|
4225
|
+
}, 16);
|
|
4226
|
+
}
|
|
4227
|
+
set$(ctx, "stylePaddingTop", stylePaddingTop);
|
|
4228
|
+
}
|
|
4229
|
+
}
|
|
3291
4230
|
function useThrottleDebounce(mode) {
|
|
3292
4231
|
const timeoutRef = React3.useRef(null);
|
|
3293
4232
|
const lastCallTimeRef = React3.useRef(0);
|
|
@@ -3335,9 +4274,8 @@ function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
|
|
|
3335
4274
|
}
|
|
3336
4275
|
|
|
3337
4276
|
// src/components/LegendList.tsx
|
|
3338
|
-
var DEFAULT_DRAW_DISTANCE = 250;
|
|
3339
|
-
var DEFAULT_ITEM_SIZE = 100;
|
|
3340
4277
|
var LegendList = typedMemo(
|
|
4278
|
+
// biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
|
|
3341
4279
|
typedForwardRef(function LegendList2(props, forwardedRef) {
|
|
3342
4280
|
const { children, data: dataProp, renderItem: renderItemProp, ...restProps } = props;
|
|
3343
4281
|
const isChildrenMode = children !== void 0 && dataProp === void 0;
|
|
@@ -3355,16 +4293,17 @@ var LegendList = typedMemo(
|
|
|
3355
4293
|
})
|
|
3356
4294
|
);
|
|
3357
4295
|
var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
|
|
3358
|
-
var _a3, _b;
|
|
4296
|
+
var _a3, _b, _c, _d, _e;
|
|
3359
4297
|
const {
|
|
3360
4298
|
alignItemsAtEnd = false,
|
|
4299
|
+
alwaysRender,
|
|
3361
4300
|
columnWrapperStyle,
|
|
3362
4301
|
contentContainerStyle: contentContainerStyleProp,
|
|
4302
|
+
contentInset,
|
|
3363
4303
|
data: dataProp = [],
|
|
3364
4304
|
dataVersion,
|
|
3365
4305
|
drawDistance = 250,
|
|
3366
|
-
|
|
3367
|
-
estimatedItemSize: estimatedItemSizeProp,
|
|
4306
|
+
estimatedItemSize = 100,
|
|
3368
4307
|
estimatedListSize,
|
|
3369
4308
|
extraData,
|
|
3370
4309
|
getEstimatedItemSize,
|
|
@@ -3381,11 +4320,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3381
4320
|
ListHeaderComponent,
|
|
3382
4321
|
maintainScrollAtEnd = false,
|
|
3383
4322
|
maintainScrollAtEndThreshold = 0.1,
|
|
3384
|
-
maintainVisibleContentPosition
|
|
4323
|
+
maintainVisibleContentPosition: maintainVisibleContentPositionProp,
|
|
3385
4324
|
numColumns: numColumnsProp = 1,
|
|
4325
|
+
overrideItemLayout,
|
|
3386
4326
|
onEndReached,
|
|
3387
4327
|
onEndReachedThreshold = 0.5,
|
|
3388
4328
|
onItemSizeChanged,
|
|
4329
|
+
onMetricsChange,
|
|
3389
4330
|
onLayout: onLayoutProp,
|
|
3390
4331
|
onLoad,
|
|
3391
4332
|
onMomentumScrollEnd,
|
|
@@ -3400,50 +4341,102 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3400
4341
|
refreshControl,
|
|
3401
4342
|
refreshing,
|
|
3402
4343
|
refScrollView,
|
|
4344
|
+
renderScrollComponent,
|
|
3403
4345
|
renderItem,
|
|
3404
4346
|
scrollEventThrottle,
|
|
3405
4347
|
snapToIndices,
|
|
3406
4348
|
stickyHeaderIndices: stickyHeaderIndicesProp,
|
|
3407
4349
|
stickyIndices: stickyIndicesDeprecated,
|
|
4350
|
+
// TODOV3: Remove from v3 release
|
|
3408
4351
|
style: styleProp,
|
|
3409
4352
|
suggestEstimatedItemSize,
|
|
4353
|
+
useWindowScroll = false,
|
|
3410
4354
|
viewabilityConfig,
|
|
3411
4355
|
viewabilityConfigCallbackPairs,
|
|
3412
4356
|
waitForInitialLayout = true,
|
|
3413
4357
|
...rest
|
|
3414
4358
|
} = props;
|
|
3415
|
-
const
|
|
3416
|
-
const
|
|
4359
|
+
const animatedPropsInternal = props.animatedPropsInternal;
|
|
4360
|
+
const positionComponentInternal = props.positionComponentInternal;
|
|
4361
|
+
const stickyPositionComponentInternal = props.stickyPositionComponentInternal;
|
|
4362
|
+
const {
|
|
4363
|
+
childrenMode,
|
|
4364
|
+
positionComponentInternal: _positionComponentInternal,
|
|
4365
|
+
stickyPositionComponentInternal: _stickyPositionComponentInternal,
|
|
4366
|
+
...restProps
|
|
4367
|
+
} = rest;
|
|
4368
|
+
const contentContainerStyleBase = StyleSheet.flatten(contentContainerStyleProp);
|
|
4369
|
+
const shouldFlexGrow = alignItemsAtEnd && (horizontal ? (contentContainerStyleBase == null ? void 0 : contentContainerStyleBase.minWidth) == null : (contentContainerStyleBase == null ? void 0 : contentContainerStyleBase.minHeight) == null);
|
|
4370
|
+
const contentContainerStyle = {
|
|
4371
|
+
...contentContainerStyleBase,
|
|
4372
|
+
...alignItemsAtEnd ? {
|
|
4373
|
+
display: "flex",
|
|
4374
|
+
flexDirection: horizontal ? "row" : "column",
|
|
4375
|
+
...shouldFlexGrow ? { flexGrow: 1 } : {},
|
|
4376
|
+
justifyContent: "flex-end"
|
|
4377
|
+
} : {}
|
|
4378
|
+
};
|
|
3417
4379
|
const style = { ...StyleSheet.flatten(styleProp) };
|
|
3418
4380
|
const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
|
|
3419
4381
|
const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
|
|
3420
|
-
const
|
|
3421
|
-
|
|
3422
|
-
|
|
4382
|
+
const maintainVisibleContentPositionConfig = normalizeMaintainVisibleContentPosition(
|
|
4383
|
+
maintainVisibleContentPositionProp
|
|
4384
|
+
);
|
|
4385
|
+
const initialScrollProp = initialScrollAtEnd ? { index: Math.max(0, dataProp.length - 1), viewOffset: -stylePaddingBottomState, viewPosition: 1 } : initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? {
|
|
4386
|
+
index: initialScrollIndexProp.index || 0,
|
|
4387
|
+
viewOffset: initialScrollIndexProp.viewOffset || (initialScrollIndexProp.viewPosition === 1 ? -stylePaddingBottomState : 0),
|
|
4388
|
+
viewPosition: initialScrollIndexProp.viewPosition || 0
|
|
4389
|
+
} : {
|
|
4390
|
+
index: initialScrollIndexProp || 0,
|
|
4391
|
+
viewOffset: initialScrollOffsetProp || 0
|
|
4392
|
+
} : void 0;
|
|
4393
|
+
const [canRender, setCanRender] = React3__namespace.useState(false);
|
|
3423
4394
|
const ctx = useStateContext();
|
|
3424
4395
|
ctx.columnWrapperStyle = columnWrapperStyle || (contentContainerStyle ? createColumnWrapperStyle(contentContainerStyle) : void 0);
|
|
3425
4396
|
const refScroller = React3.useRef(null);
|
|
3426
4397
|
const combinedRef = useCombinedRef(refScroller, refScrollView);
|
|
3427
|
-
const
|
|
3428
|
-
const scrollBuffer = (drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE) || 1;
|
|
3429
|
-
const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (_item, index) => index.toString();
|
|
4398
|
+
const keyExtractor = keyExtractorProp != null ? keyExtractorProp : ((_item, index) => index.toString());
|
|
3430
4399
|
const stickyHeaderIndices = stickyHeaderIndicesProp != null ? stickyHeaderIndicesProp : stickyIndicesDeprecated;
|
|
4400
|
+
const alwaysRenderIndices = React3.useMemo(() => {
|
|
4401
|
+
const indices = getAlwaysRenderIndices(alwaysRender, dataProp, keyExtractor);
|
|
4402
|
+
return { arr: indices, set: new Set(indices) };
|
|
4403
|
+
}, [
|
|
4404
|
+
alwaysRender == null ? void 0 : alwaysRender.top,
|
|
4405
|
+
alwaysRender == null ? void 0 : alwaysRender.bottom,
|
|
4406
|
+
(_a3 = alwaysRender == null ? void 0 : alwaysRender.indices) == null ? void 0 : _a3.join(","),
|
|
4407
|
+
(_b = alwaysRender == null ? void 0 : alwaysRender.keys) == null ? void 0 : _b.join(","),
|
|
4408
|
+
dataProp,
|
|
4409
|
+
dataVersion,
|
|
4410
|
+
keyExtractor
|
|
4411
|
+
]);
|
|
3431
4412
|
if (IS_DEV && stickyIndicesDeprecated && !stickyHeaderIndicesProp) {
|
|
3432
4413
|
warnDevOnce(
|
|
3433
4414
|
"stickyIndices",
|
|
3434
4415
|
"stickyIndices has been renamed to stickyHeaderIndices. Please update your props to use stickyHeaderIndices."
|
|
3435
4416
|
);
|
|
3436
4417
|
}
|
|
3437
|
-
|
|
4418
|
+
if (IS_DEV && useWindowScroll && renderScrollComponent) {
|
|
4419
|
+
warnDevOnce(
|
|
4420
|
+
"useWindowScrollRenderScrollComponent",
|
|
4421
|
+
"useWindowScroll is not supported when renderScrollComponent is provided."
|
|
4422
|
+
);
|
|
4423
|
+
}
|
|
4424
|
+
const useWindowScrollResolved = !!useWindowScroll && !renderScrollComponent;
|
|
4425
|
+
const refState = React3.useRef(void 0);
|
|
4426
|
+
const hasOverrideItemLayout = !!overrideItemLayout;
|
|
4427
|
+
const prevHasOverrideItemLayout = React3.useRef(hasOverrideItemLayout);
|
|
3438
4428
|
if (!refState.current) {
|
|
3439
|
-
if (!ctx.
|
|
4429
|
+
if (!ctx.state) {
|
|
3440
4430
|
const initialScrollLength = (estimatedListSize != null ? estimatedListSize : { height: 0, width: 0 } )[horizontal ? "width" : "height"];
|
|
3441
|
-
ctx.
|
|
3442
|
-
activeStickyIndex:
|
|
4431
|
+
ctx.state = {
|
|
4432
|
+
activeStickyIndex: -1,
|
|
3443
4433
|
averageSizes: {},
|
|
3444
|
-
|
|
3445
|
-
|
|
4434
|
+
columnSpans: [],
|
|
4435
|
+
columns: [],
|
|
4436
|
+
containerItemKeys: /* @__PURE__ */ new Map(),
|
|
3446
4437
|
containerItemTypes: /* @__PURE__ */ new Map(),
|
|
4438
|
+
contentInsetOverride: void 0,
|
|
4439
|
+
dataChangeEpoch: 0,
|
|
3447
4440
|
dataChangeNeedsScrollUpdate: false,
|
|
3448
4441
|
didColumnsChange: false,
|
|
3449
4442
|
didDataChange: false,
|
|
@@ -3459,24 +4452,26 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3459
4452
|
attempts: 0,
|
|
3460
4453
|
index: initialScrollProp.index,
|
|
3461
4454
|
settledTicks: 0,
|
|
3462
|
-
viewOffset: (
|
|
4455
|
+
viewOffset: (_c = initialScrollProp.viewOffset) != null ? _c : 0,
|
|
3463
4456
|
viewPosition: initialScrollProp.viewPosition
|
|
3464
4457
|
} : void 0,
|
|
3465
4458
|
initialScroll: initialScrollProp,
|
|
3466
4459
|
isAtEnd: false,
|
|
3467
4460
|
isAtStart: false,
|
|
3468
|
-
isEndReached:
|
|
4461
|
+
isEndReached: null,
|
|
3469
4462
|
isFirst: true,
|
|
3470
|
-
isStartReached:
|
|
4463
|
+
isStartReached: null,
|
|
3471
4464
|
lastBatchingAction: Date.now(),
|
|
3472
4465
|
lastLayout: void 0,
|
|
4466
|
+
lastScrollDelta: 0,
|
|
3473
4467
|
loadStartTime: Date.now(),
|
|
3474
4468
|
minIndexSizeChanged: 0,
|
|
4469
|
+
nativeContentInset: void 0,
|
|
3475
4470
|
nativeMarginTop: 0,
|
|
3476
|
-
positions:
|
|
4471
|
+
positions: [],
|
|
3477
4472
|
props: {},
|
|
3478
4473
|
queuedCalculateItemsInView: 0,
|
|
3479
|
-
refScroller:
|
|
4474
|
+
refScroller: { current: null },
|
|
3480
4475
|
scroll: 0,
|
|
3481
4476
|
scrollAdjustHandler: new ScrollAdjustHandler(ctx),
|
|
3482
4477
|
scrollForNextCalculateItemsInView: void 0,
|
|
@@ -3492,6 +4487,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3492
4487
|
startBuffered: -1,
|
|
3493
4488
|
startNoBuffer: -1,
|
|
3494
4489
|
startReachedSnapshot: void 0,
|
|
4490
|
+
startReachedSnapshotDataChangeEpoch: void 0,
|
|
3495
4491
|
stickyContainerPool: /* @__PURE__ */ new Set(),
|
|
3496
4492
|
stickyContainers: /* @__PURE__ */ new Map(),
|
|
3497
4493
|
timeoutSizeMessage: 0,
|
|
@@ -3499,18 +4495,19 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3499
4495
|
totalSize: 0,
|
|
3500
4496
|
viewabilityConfigCallbackPairs: void 0
|
|
3501
4497
|
};
|
|
3502
|
-
const internalState = ctx.
|
|
3503
|
-
internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx,
|
|
3504
|
-
set$(ctx, "maintainVisibleContentPosition",
|
|
4498
|
+
const internalState = ctx.state;
|
|
4499
|
+
internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
|
|
4500
|
+
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
|
|
3505
4501
|
set$(ctx, "extraData", extraData);
|
|
3506
4502
|
}
|
|
3507
|
-
refState.current = ctx.
|
|
4503
|
+
refState.current = ctx.state;
|
|
3508
4504
|
}
|
|
3509
4505
|
const state = refState.current;
|
|
3510
4506
|
const isFirstLocal = state.isFirst;
|
|
3511
4507
|
state.didColumnsChange = numColumnsProp !== state.props.numColumns;
|
|
3512
4508
|
const didDataChangeLocal = state.props.dataVersion !== dataVersion || state.props.data !== dataProp && checkActualChange(state, dataProp, state.props.data);
|
|
3513
4509
|
if (didDataChangeLocal) {
|
|
4510
|
+
state.dataChangeEpoch += 1;
|
|
3514
4511
|
state.dataChangeNeedsScrollUpdate = true;
|
|
3515
4512
|
state.didDataChange = true;
|
|
3516
4513
|
state.previousData = state.props.data;
|
|
@@ -3518,20 +4515,25 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3518
4515
|
const throttleScrollFn = scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp;
|
|
3519
4516
|
state.props = {
|
|
3520
4517
|
alignItemsAtEnd,
|
|
4518
|
+
alwaysRender,
|
|
4519
|
+
alwaysRenderIndicesArr: alwaysRenderIndices.arr,
|
|
4520
|
+
alwaysRenderIndicesSet: alwaysRenderIndices.set,
|
|
4521
|
+
animatedProps: animatedPropsInternal,
|
|
4522
|
+
contentInset,
|
|
3521
4523
|
data: dataProp,
|
|
3522
4524
|
dataVersion,
|
|
3523
|
-
|
|
4525
|
+
drawDistance,
|
|
3524
4526
|
estimatedItemSize,
|
|
3525
|
-
getEstimatedItemSize,
|
|
3526
|
-
getFixedItemSize,
|
|
3527
|
-
getItemType,
|
|
4527
|
+
getEstimatedItemSize: useWrapIfItem(getEstimatedItemSize),
|
|
4528
|
+
getFixedItemSize: useWrapIfItem(getFixedItemSize),
|
|
4529
|
+
getItemType: useWrapIfItem(getItemType),
|
|
3528
4530
|
horizontal: !!horizontal,
|
|
3529
4531
|
initialContainerPoolRatio,
|
|
3530
4532
|
itemsAreEqual,
|
|
3531
|
-
keyExtractor,
|
|
4533
|
+
keyExtractor: useWrapIfItem(keyExtractor),
|
|
3532
4534
|
maintainScrollAtEnd,
|
|
3533
4535
|
maintainScrollAtEndThreshold,
|
|
3534
|
-
maintainVisibleContentPosition,
|
|
4536
|
+
maintainVisibleContentPosition: maintainVisibleContentPositionConfig,
|
|
3535
4537
|
numColumns: numColumnsProp,
|
|
3536
4538
|
onEndReached,
|
|
3537
4539
|
onEndReachedThreshold,
|
|
@@ -3541,15 +4543,18 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3541
4543
|
onStartReached,
|
|
3542
4544
|
onStartReachedThreshold,
|
|
3543
4545
|
onStickyHeaderChange,
|
|
4546
|
+
overrideItemLayout,
|
|
4547
|
+
positionComponentInternal,
|
|
3544
4548
|
recycleItems: !!recycleItems,
|
|
3545
4549
|
renderItem,
|
|
3546
|
-
scrollBuffer,
|
|
3547
4550
|
snapToIndices,
|
|
3548
4551
|
stickyIndicesArr: stickyHeaderIndices != null ? stickyHeaderIndices : [],
|
|
3549
4552
|
stickyIndicesSet: React3.useMemo(() => new Set(stickyHeaderIndices != null ? stickyHeaderIndices : []), [stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.join(",")]),
|
|
4553
|
+
stickyPositionComponentInternal,
|
|
3550
4554
|
stylePaddingBottom: stylePaddingBottomState,
|
|
3551
4555
|
stylePaddingTop: stylePaddingTopState,
|
|
3552
|
-
suggestEstimatedItemSize: !!suggestEstimatedItemSize
|
|
4556
|
+
suggestEstimatedItemSize: !!suggestEstimatedItemSize,
|
|
4557
|
+
useWindowScroll: useWindowScrollResolved
|
|
3553
4558
|
};
|
|
3554
4559
|
state.refScroller = refScroller;
|
|
3555
4560
|
const memoizedLastItemKeys = React3.useMemo(() => {
|
|
@@ -3559,62 +4564,50 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3559
4564
|
(_, i) => getId(state, dataProp.length - 1 - i)
|
|
3560
4565
|
);
|
|
3561
4566
|
}, [dataProp, dataVersion, numColumnsProp]);
|
|
3562
|
-
const initializeStateVars = () => {
|
|
4567
|
+
const initializeStateVars = (shouldAdjustPadding) => {
|
|
3563
4568
|
set$(ctx, "lastItemKeys", memoizedLastItemKeys);
|
|
3564
4569
|
set$(ctx, "numColumns", numColumnsProp);
|
|
3565
4570
|
const prevPaddingTop = peek$(ctx, "stylePaddingTop");
|
|
3566
|
-
setPaddingTop(ctx,
|
|
4571
|
+
setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
|
|
3567
4572
|
refState.current.props.stylePaddingBottom = stylePaddingBottomState;
|
|
3568
4573
|
let paddingDiff = stylePaddingTopState - prevPaddingTop;
|
|
3569
|
-
if (paddingDiff && prevPaddingTop !== void 0 && Platform.OS === "ios")
|
|
3570
|
-
if (state.scroll < 0) {
|
|
3571
|
-
paddingDiff += state.scroll;
|
|
3572
|
-
}
|
|
3573
|
-
requestAdjust(ctx, state, paddingDiff);
|
|
3574
|
-
}
|
|
4574
|
+
if (shouldAdjustPadding && maintainVisibleContentPositionConfig.size && paddingDiff && prevPaddingTop !== void 0 && Platform.OS === "ios") ;
|
|
3575
4575
|
};
|
|
3576
4576
|
if (isFirstLocal) {
|
|
3577
|
-
initializeStateVars();
|
|
4577
|
+
initializeStateVars(false);
|
|
3578
4578
|
updateItemPositions(
|
|
3579
4579
|
ctx,
|
|
3580
|
-
state,
|
|
3581
4580
|
/*dataChanged*/
|
|
3582
4581
|
true
|
|
3583
4582
|
);
|
|
3584
4583
|
}
|
|
4584
|
+
const resolveInitialScrollOffset = React3.useCallback((initialScroll) => {
|
|
4585
|
+
const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
|
|
4586
|
+
const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
|
|
4587
|
+
return clampScrollOffset(ctx, resolvedOffset, initialScroll);
|
|
4588
|
+
}, []);
|
|
3585
4589
|
const initialContentOffset = React3.useMemo(() => {
|
|
3586
|
-
|
|
3587
|
-
const { initialScroll } = refState.current;
|
|
3588
|
-
if (
|
|
4590
|
+
let value;
|
|
4591
|
+
const { initialScroll, initialAnchor } = refState.current;
|
|
4592
|
+
if (initialScroll) {
|
|
4593
|
+
if (initialScroll.contentOffset !== void 0) {
|
|
4594
|
+
value = initialScroll.contentOffset;
|
|
4595
|
+
} else {
|
|
4596
|
+
const clampedOffset = resolveInitialScrollOffset(initialScroll);
|
|
4597
|
+
const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
|
|
4598
|
+
refState.current.initialScroll = updatedInitialScroll;
|
|
4599
|
+
state.initialScroll = updatedInitialScroll;
|
|
4600
|
+
value = clampedOffset;
|
|
4601
|
+
}
|
|
4602
|
+
} else {
|
|
3589
4603
|
refState.current.initialAnchor = void 0;
|
|
3590
|
-
|
|
4604
|
+
value = 0;
|
|
3591
4605
|
}
|
|
3592
|
-
if (
|
|
3593
|
-
|
|
3594
|
-
attempts: 0,
|
|
3595
|
-
index: initialScroll.index,
|
|
3596
|
-
settledTicks: 0,
|
|
3597
|
-
viewOffset: (_b2 = initialScroll.viewOffset) != null ? _b2 : 0,
|
|
3598
|
-
viewPosition: initialScroll.viewPosition
|
|
3599
|
-
};
|
|
4606
|
+
if (!value) {
|
|
4607
|
+
setInitialRenderState(ctx, { didInitialScroll: true });
|
|
3600
4608
|
}
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
}
|
|
3604
|
-
const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, state, initialScroll.index) : 0;
|
|
3605
|
-
const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, state, baseOffset, initialScroll);
|
|
3606
|
-
let clampedOffset = resolvedOffset;
|
|
3607
|
-
if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
|
|
3608
|
-
const maxOffset = Math.max(0, state.totalSize - state.scrollLength);
|
|
3609
|
-
clampedOffset = Math.min(clampedOffset, maxOffset);
|
|
3610
|
-
}
|
|
3611
|
-
clampedOffset = Math.max(0, clampedOffset);
|
|
3612
|
-
const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
|
|
3613
|
-
refState.current.initialScroll = updatedInitialScroll;
|
|
3614
|
-
state.initialScroll = updatedInitialScroll;
|
|
3615
|
-
refState.current.isStartReached = clampedOffset < refState.current.scrollLength * onStartReachedThreshold;
|
|
3616
|
-
return clampedOffset;
|
|
3617
|
-
}, [renderNum]);
|
|
4609
|
+
return value;
|
|
4610
|
+
}, []);
|
|
3618
4611
|
if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
3619
4612
|
refState.current.lastBatchingAction = Date.now();
|
|
3620
4613
|
if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
|
|
@@ -3623,39 +4616,53 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3623
4616
|
"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."
|
|
3624
4617
|
);
|
|
3625
4618
|
refState.current.sizes.clear();
|
|
3626
|
-
refState.current.positions.
|
|
4619
|
+
refState.current.positions.length = 0;
|
|
3627
4620
|
refState.current.totalSize = 0;
|
|
3628
4621
|
set$(ctx, "totalSize", 0);
|
|
3629
4622
|
}
|
|
3630
4623
|
}
|
|
3631
|
-
const onLayoutHeader = React3.useCallback((rect, fromLayoutEffect) => {
|
|
3632
|
-
const { initialScroll } = refState.current;
|
|
3633
|
-
const size = rect[horizontal ? "width" : "height"];
|
|
3634
|
-
set$(ctx, "headerSize", size);
|
|
3635
|
-
if ((initialScroll == null ? void 0 : initialScroll.index) !== void 0) {
|
|
3636
|
-
{
|
|
3637
|
-
if (fromLayoutEffect) {
|
|
3638
|
-
setRenderNum((v) => v + 1);
|
|
3639
|
-
}
|
|
3640
|
-
}
|
|
3641
|
-
}
|
|
3642
|
-
}, []);
|
|
3643
4624
|
const doInitialScroll = React3.useCallback(() => {
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
4625
|
+
const { initialScroll, didFinishInitialScroll, queuedInitialLayout, scrollingTo } = state;
|
|
4626
|
+
if (initialScroll && !queuedInitialLayout && !didFinishInitialScroll && !scrollingTo) {
|
|
4627
|
+
const offset = resolveInitialScrollOffset(initialScroll);
|
|
4628
|
+
const updatedInitialScroll = { ...initialScroll, contentOffset: offset };
|
|
4629
|
+
refState.current.initialScroll = updatedInitialScroll;
|
|
4630
|
+
state.initialScroll = updatedInitialScroll;
|
|
4631
|
+
scrollTo(ctx, {
|
|
3648
4632
|
animated: false,
|
|
3649
|
-
index:
|
|
4633
|
+
index: initialScroll.index,
|
|
3650
4634
|
isInitialScroll: true,
|
|
3651
|
-
offset
|
|
4635
|
+
offset,
|
|
3652
4636
|
precomputedWithViewOffset: true
|
|
3653
4637
|
});
|
|
3654
4638
|
}
|
|
3655
|
-
}, [
|
|
4639
|
+
}, []);
|
|
4640
|
+
const onLayoutFooter = React3.useCallback(
|
|
4641
|
+
(layout) => {
|
|
4642
|
+
if (!initialScrollAtEnd) {
|
|
4643
|
+
return;
|
|
4644
|
+
}
|
|
4645
|
+
const { initialScroll } = state;
|
|
4646
|
+
if (!initialScroll) {
|
|
4647
|
+
return;
|
|
4648
|
+
}
|
|
4649
|
+
const lastIndex = Math.max(0, dataProp.length - 1);
|
|
4650
|
+
if (initialScroll.index !== lastIndex || initialScroll.viewPosition !== 1) {
|
|
4651
|
+
return;
|
|
4652
|
+
}
|
|
4653
|
+
const footerSize = layout[horizontal ? "width" : "height"];
|
|
4654
|
+
const viewOffset = -stylePaddingBottomState - footerSize;
|
|
4655
|
+
if (initialScroll.viewOffset !== viewOffset) {
|
|
4656
|
+
const updatedInitialScroll = { ...initialScroll, viewOffset };
|
|
4657
|
+
refState.current.initialScroll = updatedInitialScroll;
|
|
4658
|
+
state.initialScroll = updatedInitialScroll;
|
|
4659
|
+
}
|
|
4660
|
+
},
|
|
4661
|
+
[dataProp.length, horizontal, initialScrollAtEnd, stylePaddingBottomState]
|
|
4662
|
+
);
|
|
3656
4663
|
const onLayoutChange = React3.useCallback((layout) => {
|
|
3657
4664
|
doInitialScroll();
|
|
3658
|
-
handleLayout(ctx,
|
|
4665
|
+
handleLayout(ctx, layout, setCanRender);
|
|
3659
4666
|
}, []);
|
|
3660
4667
|
const { onLayout } = useOnLayoutSync({
|
|
3661
4668
|
onLayoutChange,
|
|
@@ -3665,7 +4672,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3665
4672
|
});
|
|
3666
4673
|
React3.useLayoutEffect(() => {
|
|
3667
4674
|
if (snapToIndices) {
|
|
3668
|
-
updateSnapToOffsets(ctx
|
|
4675
|
+
updateSnapToOffsets(ctx);
|
|
3669
4676
|
}
|
|
3670
4677
|
}, [snapToIndices]);
|
|
3671
4678
|
React3.useLayoutEffect(() => {
|
|
@@ -3675,24 +4682,50 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3675
4682
|
isFirst,
|
|
3676
4683
|
props: { data }
|
|
3677
4684
|
} = state;
|
|
3678
|
-
const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx
|
|
4685
|
+
const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx);
|
|
3679
4686
|
if (!didAllocateContainers && !isFirst && (didDataChange || didColumnsChange)) {
|
|
3680
|
-
checkResetContainers(ctx,
|
|
4687
|
+
checkResetContainers(ctx, data);
|
|
3681
4688
|
}
|
|
3682
4689
|
state.didColumnsChange = false;
|
|
3683
4690
|
state.didDataChange = false;
|
|
3684
4691
|
state.isFirst = false;
|
|
3685
4692
|
}, [dataProp, dataVersion, numColumnsProp]);
|
|
3686
4693
|
React3.useLayoutEffect(() => {
|
|
4694
|
+
var _a4;
|
|
3687
4695
|
set$(ctx, "extraData", extraData);
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
4696
|
+
const didToggleOverride = prevHasOverrideItemLayout.current !== hasOverrideItemLayout;
|
|
4697
|
+
prevHasOverrideItemLayout.current = hasOverrideItemLayout;
|
|
4698
|
+
if ((hasOverrideItemLayout || didToggleOverride) && numColumnsProp > 1) {
|
|
4699
|
+
(_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, { forceFullItemPositions: true });
|
|
4700
|
+
}
|
|
4701
|
+
}, [extraData, hasOverrideItemLayout, numColumnsProp]);
|
|
4702
|
+
React3.useLayoutEffect(
|
|
4703
|
+
() => initializeStateVars(true),
|
|
4704
|
+
[dataVersion, memoizedLastItemKeys.join(","), numColumnsProp, stylePaddingBottomState, stylePaddingTopState]
|
|
4705
|
+
);
|
|
4706
|
+
React3.useEffect(() => {
|
|
4707
|
+
if (!onMetricsChange) {
|
|
4708
|
+
return;
|
|
4709
|
+
}
|
|
4710
|
+
let lastMetrics;
|
|
4711
|
+
const emitMetrics = () => {
|
|
4712
|
+
const metrics = {
|
|
4713
|
+
footerSize: peek$(ctx, "footerSize") || 0,
|
|
4714
|
+
headerSize: peek$(ctx, "headerSize") || 0
|
|
4715
|
+
};
|
|
4716
|
+
if (!lastMetrics || metrics.headerSize !== lastMetrics.headerSize || metrics.footerSize !== lastMetrics.footerSize) {
|
|
4717
|
+
lastMetrics = metrics;
|
|
4718
|
+
onMetricsChange(metrics);
|
|
4719
|
+
}
|
|
4720
|
+
};
|
|
4721
|
+
emitMetrics();
|
|
4722
|
+
const unsubscribe = [listen$(ctx, "headerSize", emitMetrics), listen$(ctx, "footerSize", emitMetrics)];
|
|
4723
|
+
return () => {
|
|
4724
|
+
for (const unsub of unsubscribe) {
|
|
4725
|
+
unsub();
|
|
4726
|
+
}
|
|
4727
|
+
};
|
|
4728
|
+
}, [ctx, onMetricsChange]);
|
|
3696
4729
|
React3.useEffect(() => {
|
|
3697
4730
|
const viewability = setupViewability({
|
|
3698
4731
|
onViewableItemsChanged,
|
|
@@ -3702,49 +4735,47 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3702
4735
|
state.viewabilityConfigCallbackPairs = viewability;
|
|
3703
4736
|
state.enableScrollForNextCalculateItemsInView = !viewability;
|
|
3704
4737
|
}, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
|
|
3705
|
-
React3.useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx
|
|
4738
|
+
React3.useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx), []);
|
|
3706
4739
|
{
|
|
3707
4740
|
React3.useEffect(doInitialScroll, []);
|
|
3708
4741
|
}
|
|
3709
4742
|
const fns = React3.useMemo(
|
|
3710
4743
|
() => ({
|
|
3711
|
-
getRenderedItem: (key) => getRenderedItem(ctx,
|
|
3712
|
-
|
|
3713
|
-
|
|
4744
|
+
getRenderedItem: (key) => getRenderedItem(ctx, key),
|
|
4745
|
+
onMomentumScrollEnd: (event) => {
|
|
4746
|
+
checkFinishedScrollFallback(ctx);
|
|
4747
|
+
if (onMomentumScrollEnd) {
|
|
4748
|
+
onMomentumScrollEnd(event);
|
|
4749
|
+
}
|
|
4750
|
+
},
|
|
4751
|
+
onScroll: (event) => onScroll(ctx, event),
|
|
4752
|
+
updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, itemKey, sizeObj)
|
|
3714
4753
|
}),
|
|
3715
4754
|
[]
|
|
3716
4755
|
);
|
|
3717
4756
|
const onScrollHandler = useStickyScrollHandler(stickyHeaderIndices, horizontal, ctx, fns.onScroll);
|
|
4757
|
+
const refreshControlElement = refreshControl;
|
|
3718
4758
|
return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement(
|
|
3719
4759
|
ListComponent,
|
|
3720
4760
|
{
|
|
3721
|
-
...
|
|
4761
|
+
...restProps,
|
|
3722
4762
|
alignItemsAtEnd,
|
|
3723
4763
|
canRender,
|
|
3724
4764
|
contentContainerStyle,
|
|
4765
|
+
contentInset,
|
|
3725
4766
|
getRenderedItem: fns.getRenderedItem,
|
|
3726
4767
|
horizontal,
|
|
3727
4768
|
initialContentOffset,
|
|
3728
4769
|
ListEmptyComponent: dataProp.length === 0 ? ListEmptyComponent : void 0,
|
|
3729
4770
|
ListHeaderComponent,
|
|
3730
|
-
maintainVisibleContentPosition,
|
|
3731
4771
|
onLayout,
|
|
3732
|
-
|
|
3733
|
-
onMomentumScrollEnd:
|
|
3734
|
-
{
|
|
3735
|
-
requestAnimationFrame(() => {
|
|
3736
|
-
finishScrollTo(ctx, refState.current);
|
|
3737
|
-
});
|
|
3738
|
-
}
|
|
3739
|
-
if (onMomentumScrollEnd) {
|
|
3740
|
-
onMomentumScrollEnd(event);
|
|
3741
|
-
}
|
|
3742
|
-
},
|
|
4772
|
+
onLayoutFooter,
|
|
4773
|
+
onMomentumScrollEnd: fns.onMomentumScrollEnd,
|
|
3743
4774
|
onScroll: onScrollHandler,
|
|
3744
4775
|
recycleItems,
|
|
3745
|
-
refreshControl:
|
|
3746
|
-
progressViewOffset: (
|
|
3747
|
-
}) :
|
|
4776
|
+
refreshControl: refreshControlElement ? stylePaddingTopState > 0 ? React3__namespace.cloneElement(refreshControlElement, {
|
|
4777
|
+
progressViewOffset: ((_d = refreshControlElement.props.progressViewOffset) != null ? _d : 0) + stylePaddingTopState
|
|
4778
|
+
}) : refreshControlElement : onRefresh && /* @__PURE__ */ React3__namespace.createElement(
|
|
3748
4779
|
RefreshControl,
|
|
3749
4780
|
{
|
|
3750
4781
|
onRefresh,
|
|
@@ -3753,18 +4784,30 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3753
4784
|
}
|
|
3754
4785
|
),
|
|
3755
4786
|
refScrollView: combinedRef,
|
|
3756
|
-
|
|
3757
|
-
|
|
4787
|
+
renderScrollComponent,
|
|
4788
|
+
scrollAdjustHandler: (_e = refState.current) == null ? void 0 : _e.scrollAdjustHandler,
|
|
4789
|
+
scrollEventThrottle: 0,
|
|
3758
4790
|
snapToIndices,
|
|
3759
4791
|
stickyHeaderIndices,
|
|
3760
4792
|
style,
|
|
3761
4793
|
updateItemSize: fns.updateItemSize,
|
|
4794
|
+
useWindowScroll: useWindowScrollResolved,
|
|
3762
4795
|
waitForInitialLayout
|
|
3763
4796
|
}
|
|
3764
|
-
), IS_DEV && ENABLE_DEBUG_VIEW
|
|
4797
|
+
), IS_DEV && ENABLE_DEBUG_VIEW);
|
|
3765
4798
|
});
|
|
3766
4799
|
|
|
3767
|
-
|
|
4800
|
+
// src/index.ts
|
|
4801
|
+
var LegendList3 = LegendList;
|
|
4802
|
+
if (IS_DEV) {
|
|
4803
|
+
console.warn(
|
|
4804
|
+
"[legend-list] Legend List 3.0 deprecates the root import (@legendapp/list) because it now supports both react and react-native. The root import is fully functional, but please switch to platform-specific imports for strict platform types:\n - React Native: @legendapp/list/react-native\n - React: @legendapp/list/react\nSee README for details."
|
|
4805
|
+
);
|
|
4806
|
+
}
|
|
4807
|
+
|
|
4808
|
+
exports.LegendList = LegendList3;
|
|
4809
|
+
exports.typedForwardRef = typedForwardRef;
|
|
4810
|
+
exports.typedMemo = typedMemo;
|
|
3768
4811
|
exports.useIsLastItem = useIsLastItem;
|
|
3769
4812
|
exports.useListScrollSize = useListScrollSize;
|
|
3770
4813
|
exports.useRecyclingEffect = useRecyclingEffect;
|