@legendapp/list 2.0.0-next.9 → 2.1.0-next.1
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/animated.d.mts +3 -65
- package/animated.d.ts +3 -65
- package/index.d.mts +123 -339
- package/index.d.ts +123 -339
- package/index.js +1497 -793
- package/index.mjs +1454 -750
- package/keyboard-controller.d.mts +7 -260
- package/keyboard-controller.d.ts +7 -260
- package/package.json +1 -1
- package/reanimated.d.mts +1 -1
- package/reanimated.d.ts +1 -1
- package/reanimated.js +19 -17
- package/reanimated.mjs +20 -18
package/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var reactNative = require('react-native');
|
|
3
|
+
var React4 = require('react');
|
|
5
4
|
var shim = require('use-sync-external-store/shim');
|
|
5
|
+
var reactDom = require('react-dom');
|
|
6
6
|
|
|
7
7
|
function _interopNamespace(e) {
|
|
8
8
|
if (e && e.__esModule) return e;
|
|
@@ -22,17 +22,32 @@ function _interopNamespace(e) {
|
|
|
22
22
|
return Object.freeze(n);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
var
|
|
25
|
+
var React4__namespace = /*#__PURE__*/_interopNamespace(React4);
|
|
26
26
|
|
|
27
|
-
// src/components/
|
|
28
|
-
var
|
|
27
|
+
// src/components/LegendList.tsx
|
|
28
|
+
var AnimatedView = React4.forwardRef(function AnimatedView2(props, ref) {
|
|
29
|
+
return /* @__PURE__ */ React4__namespace.createElement("div", { ref, ...props });
|
|
30
|
+
});
|
|
31
|
+
var View = React4.forwardRef(function View2(props, ref) {
|
|
32
|
+
return /* @__PURE__ */ React4__namespace.createElement("div", { ref, ...props });
|
|
33
|
+
});
|
|
34
|
+
var Text = View;
|
|
35
|
+
|
|
36
|
+
// src/platform/Animated.tsx
|
|
37
|
+
var createAnimatedValue = (value) => value;
|
|
38
|
+
|
|
39
|
+
// src/state/state.tsx
|
|
40
|
+
var ContextState = React4__namespace.createContext(null);
|
|
29
41
|
function StateProvider({ children }) {
|
|
30
|
-
const [value] =
|
|
42
|
+
const [value] = React4__namespace.useState(() => ({
|
|
43
|
+
animatedScrollY: createAnimatedValue(0),
|
|
31
44
|
columnWrapperStyle: void 0,
|
|
45
|
+
internalState: void 0,
|
|
32
46
|
listeners: /* @__PURE__ */ new Map(),
|
|
33
47
|
mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
|
|
34
48
|
mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
|
|
35
49
|
mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
|
|
50
|
+
mapViewabilityConfigStates: /* @__PURE__ */ new Map(),
|
|
36
51
|
mapViewabilityValues: /* @__PURE__ */ new Map(),
|
|
37
52
|
values: /* @__PURE__ */ new Map([
|
|
38
53
|
["alignItemsPaddingTop", 0],
|
|
@@ -43,10 +58,10 @@ function StateProvider({ children }) {
|
|
|
43
58
|
]),
|
|
44
59
|
viewRefs: /* @__PURE__ */ new Map()
|
|
45
60
|
}));
|
|
46
|
-
return /* @__PURE__ */
|
|
61
|
+
return /* @__PURE__ */ React4__namespace.createElement(ContextState.Provider, { value }, children);
|
|
47
62
|
}
|
|
48
63
|
function useStateContext() {
|
|
49
|
-
return
|
|
64
|
+
return React4__namespace.useContext(ContextState);
|
|
50
65
|
}
|
|
51
66
|
function createSelectorFunctionsArr(ctx, signalNames) {
|
|
52
67
|
let lastValues = [];
|
|
@@ -116,23 +131,23 @@ function getContentSize(ctx) {
|
|
|
116
131
|
return headerSize + footerSize + totalSize + stylePaddingTop;
|
|
117
132
|
}
|
|
118
133
|
function useArr$(signalNames) {
|
|
119
|
-
const ctx =
|
|
120
|
-
const { subscribe, get } =
|
|
134
|
+
const ctx = React4__namespace.useContext(ContextState);
|
|
135
|
+
const { subscribe, get } = React4__namespace.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
|
|
121
136
|
const value = shim.useSyncExternalStore(subscribe, get);
|
|
122
137
|
return value;
|
|
123
138
|
}
|
|
124
139
|
function useSelector$(signalName, selector) {
|
|
125
|
-
const ctx =
|
|
126
|
-
const { subscribe, get } =
|
|
140
|
+
const ctx = React4__namespace.useContext(ContextState);
|
|
141
|
+
const { subscribe, get } = React4__namespace.useMemo(() => createSelectorFunctionsArr(ctx, [signalName]), [ctx, signalName]);
|
|
127
142
|
const value = shim.useSyncExternalStore(subscribe, () => selector(get()[0]));
|
|
128
143
|
return value;
|
|
129
144
|
}
|
|
130
145
|
|
|
131
146
|
// src/components/DebugView.tsx
|
|
132
147
|
var DebugRow = ({ children }) => {
|
|
133
|
-
return /* @__PURE__ */
|
|
148
|
+
return /* @__PURE__ */ React4__namespace.createElement(View, { style: { alignItems: "center", flexDirection: "row", justifyContent: "space-between" } }, children);
|
|
134
149
|
};
|
|
135
|
-
var DebugView =
|
|
150
|
+
var DebugView = React4__namespace.memo(function DebugView2({ state }) {
|
|
136
151
|
const ctx = useStateContext();
|
|
137
152
|
const [totalSize = 0, scrollAdjust = 0, rawScroll = 0, scroll = 0, _numContainers = 0, _numContainersPooled = 0] = useArr$([
|
|
138
153
|
"totalSize",
|
|
@@ -143,12 +158,12 @@ var DebugView = React3__namespace.memo(function DebugView2({ state }) {
|
|
|
143
158
|
"numContainersPooled"
|
|
144
159
|
]);
|
|
145
160
|
const contentSize = getContentSize(ctx);
|
|
146
|
-
const [, forceUpdate] =
|
|
161
|
+
const [, forceUpdate] = React4.useReducer((x) => x + 1, 0);
|
|
147
162
|
useInterval(() => {
|
|
148
163
|
forceUpdate();
|
|
149
164
|
}, 100);
|
|
150
|
-
return /* @__PURE__ */
|
|
151
|
-
|
|
165
|
+
return /* @__PURE__ */ React4__namespace.createElement(
|
|
166
|
+
View,
|
|
152
167
|
{
|
|
153
168
|
pointerEvents: "none",
|
|
154
169
|
style: {
|
|
@@ -163,43 +178,158 @@ var DebugView = React3__namespace.memo(function DebugView2({ state }) {
|
|
|
163
178
|
top: 0
|
|
164
179
|
}
|
|
165
180
|
},
|
|
166
|
-
/* @__PURE__ */
|
|
167
|
-
/* @__PURE__ */
|
|
168
|
-
/* @__PURE__ */
|
|
169
|
-
/* @__PURE__ */
|
|
170
|
-
/* @__PURE__ */
|
|
171
|
-
/* @__PURE__ */
|
|
172
|
-
/* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "RawScroll: "), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, rawScroll.toFixed(2))),
|
|
173
|
-
/* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "ComputedScroll: "), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, scroll.toFixed(2)))
|
|
181
|
+
/* @__PURE__ */ React4__namespace.createElement(DebugRow, null, /* @__PURE__ */ React4__namespace.createElement(Text, null, "TotalSize:"), /* @__PURE__ */ React4__namespace.createElement(Text, null, totalSize.toFixed(2))),
|
|
182
|
+
/* @__PURE__ */ React4__namespace.createElement(DebugRow, null, /* @__PURE__ */ React4__namespace.createElement(Text, null, "ContentSize:"), /* @__PURE__ */ React4__namespace.createElement(Text, null, contentSize.toFixed(2))),
|
|
183
|
+
/* @__PURE__ */ React4__namespace.createElement(DebugRow, null, /* @__PURE__ */ React4__namespace.createElement(Text, null, "At end:"), /* @__PURE__ */ React4__namespace.createElement(Text, null, String(state.isAtEnd))),
|
|
184
|
+
/* @__PURE__ */ React4__namespace.createElement(DebugRow, null, /* @__PURE__ */ React4__namespace.createElement(Text, null, "ScrollAdjust:"), /* @__PURE__ */ React4__namespace.createElement(Text, null, scrollAdjust.toFixed(2))),
|
|
185
|
+
/* @__PURE__ */ React4__namespace.createElement(DebugRow, null, /* @__PURE__ */ React4__namespace.createElement(Text, null, "RawScroll: "), /* @__PURE__ */ React4__namespace.createElement(Text, null, rawScroll.toFixed(2))),
|
|
186
|
+
/* @__PURE__ */ React4__namespace.createElement(DebugRow, null, /* @__PURE__ */ React4__namespace.createElement(Text, null, "ComputedScroll: "), /* @__PURE__ */ React4__namespace.createElement(Text, null, scroll.toFixed(2)))
|
|
174
187
|
);
|
|
175
188
|
});
|
|
176
189
|
function useInterval(callback, delay) {
|
|
177
|
-
|
|
190
|
+
React4.useEffect(() => {
|
|
178
191
|
const interval = setInterval(callback, delay);
|
|
179
192
|
return () => clearInterval(interval);
|
|
180
193
|
}, [delay]);
|
|
181
194
|
}
|
|
182
|
-
var
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
195
|
+
var globalResizeObserver = null;
|
|
196
|
+
function getGlobalResizeObserver() {
|
|
197
|
+
if (!globalResizeObserver) {
|
|
198
|
+
globalResizeObserver = new ResizeObserver((entries) => {
|
|
199
|
+
for (const entry of entries) {
|
|
200
|
+
const callbacks = callbackMap.get(entry.target);
|
|
201
|
+
if (callbacks) {
|
|
202
|
+
for (const callback of callbacks) {
|
|
203
|
+
callback(entry);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return globalResizeObserver;
|
|
210
|
+
}
|
|
211
|
+
var callbackMap = /* @__PURE__ */ new WeakMap();
|
|
212
|
+
function useResizeObserver(element, callback) {
|
|
213
|
+
React4.useEffect(() => {
|
|
214
|
+
if (!element) return;
|
|
215
|
+
const observer = getGlobalResizeObserver();
|
|
216
|
+
let callbacks = callbackMap.get(element);
|
|
217
|
+
if (!callbacks) {
|
|
218
|
+
callbacks = /* @__PURE__ */ new Set();
|
|
219
|
+
callbackMap.set(element, callbacks);
|
|
220
|
+
observer.observe(element);
|
|
221
|
+
}
|
|
222
|
+
callbacks.add(callback);
|
|
223
|
+
return () => {
|
|
224
|
+
const callbacks2 = callbackMap.get(element);
|
|
225
|
+
if (callbacks2) {
|
|
226
|
+
callbacks2.delete(callback);
|
|
227
|
+
if (callbacks2.size === 0) {
|
|
228
|
+
callbackMap.delete(element);
|
|
229
|
+
observer.unobserve(element);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
}, [element, callback]);
|
|
234
|
+
}
|
|
187
235
|
|
|
188
|
-
// src/
|
|
189
|
-
function
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
236
|
+
// src/hooks/useSyncLayout.tsx
|
|
237
|
+
function useSyncLayout({
|
|
238
|
+
ref,
|
|
239
|
+
onLayoutChange
|
|
240
|
+
}) {
|
|
241
|
+
var _a, _b;
|
|
242
|
+
useResizeObserver(
|
|
243
|
+
((_b = (_a = ref.current) == null ? void 0 : _a.getScrollableNode) == null ? void 0 : _b.call(_a)) || ref.current,
|
|
244
|
+
React4.useCallback(
|
|
245
|
+
(entry) => {
|
|
246
|
+
onLayoutChange(entry.contentRect, false);
|
|
247
|
+
},
|
|
248
|
+
[onLayoutChange]
|
|
249
|
+
)
|
|
250
|
+
);
|
|
251
|
+
React4.useLayoutEffect(() => {
|
|
252
|
+
if (ref.current) {
|
|
253
|
+
const rect = ref.current.getBoundingClientRect();
|
|
254
|
+
onLayoutChange(
|
|
255
|
+
{
|
|
256
|
+
height: rect.height,
|
|
257
|
+
width: rect.width,
|
|
258
|
+
x: rect.left,
|
|
259
|
+
y: rect.top
|
|
260
|
+
},
|
|
261
|
+
true
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
}, []);
|
|
265
|
+
return {};
|
|
193
266
|
}
|
|
194
267
|
|
|
268
|
+
// src/components/LayoutView.tsx
|
|
269
|
+
var LayoutView = ({ onLayoutChange, refView, children, ...rest }) => {
|
|
270
|
+
const ref = refView != null ? refView : React4.useRef();
|
|
271
|
+
useSyncLayout({ onLayoutChange, ref });
|
|
272
|
+
return /* @__PURE__ */ React4__namespace.createElement("div", { ...rest, ref }, children);
|
|
273
|
+
};
|
|
274
|
+
|
|
195
275
|
// src/constants.ts
|
|
196
276
|
var POSITION_OUT_OF_VIEW = -1e7;
|
|
197
277
|
var ENABLE_DEVMODE = __DEV__ && false;
|
|
198
278
|
var ENABLE_DEBUG_VIEW = __DEV__ && false;
|
|
199
|
-
var
|
|
279
|
+
var typedForwardRef = React4.forwardRef;
|
|
280
|
+
var typedMemo = React4.memo;
|
|
281
|
+
|
|
282
|
+
// src/components/PositionView.tsx
|
|
283
|
+
var PositionViewState = typedMemo(function PositionView({
|
|
284
|
+
id,
|
|
285
|
+
horizontal,
|
|
286
|
+
style,
|
|
287
|
+
refView,
|
|
288
|
+
...rest
|
|
289
|
+
}) {
|
|
290
|
+
const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
|
|
291
|
+
const base = Array.isArray(style) ? Object.assign({}, ...style) : style;
|
|
292
|
+
const combinedStyle = horizontal ? { ...base, left: position } : { ...base, top: position };
|
|
293
|
+
return /* @__PURE__ */ React4__namespace.createElement(LayoutView, { refView, style: combinedStyle, ...rest });
|
|
294
|
+
});
|
|
295
|
+
var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
296
|
+
id,
|
|
297
|
+
horizontal,
|
|
298
|
+
style,
|
|
299
|
+
refView,
|
|
300
|
+
index,
|
|
301
|
+
...rest
|
|
302
|
+
}) {
|
|
303
|
+
const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
|
|
304
|
+
const viewStyle = React4__namespace.useMemo(() => {
|
|
305
|
+
const base = Array.isArray(style) ? Object.assign({}, ...style) : style;
|
|
306
|
+
const axisStyle = horizontal ? { transform: `translateX(${position}px)` } : { top: position };
|
|
307
|
+
return {
|
|
308
|
+
...base,
|
|
309
|
+
zIndex: index + 1e3,
|
|
310
|
+
...axisStyle
|
|
311
|
+
};
|
|
312
|
+
}, [style, position, horizontal, index]);
|
|
313
|
+
return /* @__PURE__ */ React4__namespace.createElement(LayoutView, { refView, style: viewStyle, ...rest });
|
|
314
|
+
});
|
|
315
|
+
var PositionView2 = PositionViewState;
|
|
316
|
+
function Separator({ ItemSeparatorComponent, itemKey, leadingItem }) {
|
|
317
|
+
const [lastItemKeys] = useArr$(["lastItemKeys"]);
|
|
318
|
+
const isALastItem = lastItemKeys.includes(itemKey);
|
|
319
|
+
return isALastItem ? null : /* @__PURE__ */ React4__namespace.createElement(ItemSeparatorComponent, { leadingItem });
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// src/constants-platform.ts
|
|
323
|
+
var IsNewArchitecture = true;
|
|
324
|
+
|
|
325
|
+
// src/platform/Platform.ts
|
|
326
|
+
var Platform = {
|
|
327
|
+
// Widen the type to avoid unreachable-branch lints in cross-platform code that compares against other OSes
|
|
328
|
+
OS: "web"
|
|
329
|
+
};
|
|
200
330
|
var symbolFirst = Symbol();
|
|
201
331
|
function useInit(cb) {
|
|
202
|
-
const refValue =
|
|
332
|
+
const refValue = React4.useRef(symbolFirst);
|
|
203
333
|
if (refValue.current === symbolFirst) {
|
|
204
334
|
refValue.current = cb();
|
|
205
335
|
}
|
|
@@ -238,10 +368,10 @@ function extractPadding(style, contentContainerStyle, type) {
|
|
|
238
368
|
}
|
|
239
369
|
|
|
240
370
|
// src/state/ContextContainer.ts
|
|
241
|
-
var ContextContainer =
|
|
371
|
+
var ContextContainer = React4.createContext(null);
|
|
242
372
|
function useViewability(callback, configId) {
|
|
243
373
|
const ctx = useStateContext();
|
|
244
|
-
const { containerId } =
|
|
374
|
+
const { containerId } = React4.useContext(ContextContainer);
|
|
245
375
|
const key = containerId + (configId != null ? configId : "");
|
|
246
376
|
useInit(() => {
|
|
247
377
|
const value = ctx.mapViewabilityValues.get(key);
|
|
@@ -250,7 +380,7 @@ function useViewability(callback, configId) {
|
|
|
250
380
|
}
|
|
251
381
|
});
|
|
252
382
|
ctx.mapViewabilityCallbacks.set(key, callback);
|
|
253
|
-
|
|
383
|
+
React4.useEffect(
|
|
254
384
|
() => () => {
|
|
255
385
|
ctx.mapViewabilityCallbacks.delete(key);
|
|
256
386
|
},
|
|
@@ -259,7 +389,7 @@ function useViewability(callback, configId) {
|
|
|
259
389
|
}
|
|
260
390
|
function useViewabilityAmount(callback) {
|
|
261
391
|
const ctx = useStateContext();
|
|
262
|
-
const { containerId } =
|
|
392
|
+
const { containerId } = React4.useContext(ContextContainer);
|
|
263
393
|
useInit(() => {
|
|
264
394
|
const value = ctx.mapViewabilityAmountValues.get(containerId);
|
|
265
395
|
if (value) {
|
|
@@ -267,7 +397,7 @@ function useViewabilityAmount(callback) {
|
|
|
267
397
|
}
|
|
268
398
|
});
|
|
269
399
|
ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
|
|
270
|
-
|
|
400
|
+
React4.useEffect(
|
|
271
401
|
() => () => {
|
|
272
402
|
ctx.mapViewabilityAmountCallbacks.delete(containerId);
|
|
273
403
|
},
|
|
@@ -275,12 +405,12 @@ function useViewabilityAmount(callback) {
|
|
|
275
405
|
);
|
|
276
406
|
}
|
|
277
407
|
function useRecyclingEffect(effect) {
|
|
278
|
-
const { index, value } =
|
|
279
|
-
const prevValues =
|
|
408
|
+
const { index, value } = React4.useContext(ContextContainer);
|
|
409
|
+
const prevValues = React4.useRef({
|
|
280
410
|
prevIndex: void 0,
|
|
281
411
|
prevItem: void 0
|
|
282
412
|
});
|
|
283
|
-
|
|
413
|
+
React4.useEffect(() => {
|
|
284
414
|
let ret;
|
|
285
415
|
if (prevValues.current.prevIndex !== void 0 && prevValues.current.prevItem !== void 0) {
|
|
286
416
|
ret = effect({
|
|
@@ -298,12 +428,12 @@ function useRecyclingEffect(effect) {
|
|
|
298
428
|
}, [index, value, effect]);
|
|
299
429
|
}
|
|
300
430
|
function useRecyclingState(valueOrFun) {
|
|
301
|
-
const { index, value, itemKey, triggerLayout } =
|
|
302
|
-
const refState =
|
|
431
|
+
const { index, value, itemKey, triggerLayout } = React4.useContext(ContextContainer);
|
|
432
|
+
const refState = React4.useRef({
|
|
303
433
|
itemKey: null,
|
|
304
434
|
value: null
|
|
305
435
|
});
|
|
306
|
-
const [_, setRenderNum] =
|
|
436
|
+
const [_, setRenderNum] = React4.useState(0);
|
|
307
437
|
const state = refState.current;
|
|
308
438
|
if (state.itemKey !== itemKey) {
|
|
309
439
|
state.itemKey = itemKey;
|
|
@@ -314,7 +444,7 @@ function useRecyclingState(valueOrFun) {
|
|
|
314
444
|
prevItem: void 0
|
|
315
445
|
}) : valueOrFun;
|
|
316
446
|
}
|
|
317
|
-
const setState =
|
|
447
|
+
const setState = React4.useCallback(
|
|
318
448
|
(newState) => {
|
|
319
449
|
state.value = isFunction(newState) ? newState(state.value) : newState;
|
|
320
450
|
setRenderNum((v) => v + 1);
|
|
@@ -325,7 +455,7 @@ function useRecyclingState(valueOrFun) {
|
|
|
325
455
|
return [state.value, setState];
|
|
326
456
|
}
|
|
327
457
|
function useIsLastItem() {
|
|
328
|
-
const { itemKey } =
|
|
458
|
+
const { itemKey } = React4.useContext(ContextContainer);
|
|
329
459
|
const isLast = useSelector$("lastItemKeys", (lastItemKeys) => (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false);
|
|
330
460
|
return isLast;
|
|
331
461
|
}
|
|
@@ -333,8 +463,12 @@ function useListScrollSize() {
|
|
|
333
463
|
const [scrollSize] = useArr$(["scrollSize"]);
|
|
334
464
|
return scrollSize;
|
|
335
465
|
}
|
|
336
|
-
|
|
337
|
-
|
|
466
|
+
function useSyncLayout2() {
|
|
467
|
+
{
|
|
468
|
+
const { triggerLayout: syncLayout } = React4.useContext(ContextContainer);
|
|
469
|
+
return syncLayout;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
338
472
|
|
|
339
473
|
// src/components/Container.tsx
|
|
340
474
|
var Container = typedMemo(function Container2({
|
|
@@ -346,57 +480,62 @@ var Container = typedMemo(function Container2({
|
|
|
346
480
|
ItemSeparatorComponent
|
|
347
481
|
}) {
|
|
348
482
|
const ctx = useStateContext();
|
|
349
|
-
const columnWrapperStyle = ctx
|
|
350
|
-
const [column = 0, data, itemKey,
|
|
483
|
+
const { columnWrapperStyle } = ctx;
|
|
484
|
+
const [column = 0, data, itemKey, numColumns, extraData, isSticky] = useArr$([
|
|
351
485
|
`containerColumn${id}`,
|
|
352
486
|
`containerItemData${id}`,
|
|
353
487
|
`containerItemKey${id}`,
|
|
354
|
-
`containerPosition${id}`,
|
|
355
488
|
"numColumns",
|
|
356
|
-
"extraData"
|
|
489
|
+
"extraData",
|
|
490
|
+
`containerSticky${id}`
|
|
357
491
|
]);
|
|
358
|
-
const refLastSize =
|
|
359
|
-
const ref =
|
|
360
|
-
const [
|
|
492
|
+
const refLastSize = React4.useRef();
|
|
493
|
+
const ref = React4.useRef(null);
|
|
494
|
+
const [_, forceLayoutRender] = React4.useState(0);
|
|
361
495
|
const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
|
|
362
496
|
const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
497
|
+
const style = React4.useMemo(() => {
|
|
498
|
+
let paddingStyles;
|
|
499
|
+
if (columnWrapperStyle) {
|
|
500
|
+
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
501
|
+
if (horizontal) {
|
|
502
|
+
const py = numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0;
|
|
503
|
+
paddingStyles = {
|
|
504
|
+
paddingBottom: py,
|
|
505
|
+
paddingRight: columnGap || gap || void 0,
|
|
506
|
+
paddingTop: py
|
|
507
|
+
};
|
|
508
|
+
} else {
|
|
509
|
+
const px = numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0;
|
|
510
|
+
paddingStyles = {
|
|
511
|
+
paddingBottom: rowGap || gap || void 0,
|
|
512
|
+
paddingLeft: px,
|
|
513
|
+
paddingRight: px
|
|
514
|
+
};
|
|
515
|
+
}
|
|
377
516
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
};
|
|
394
|
-
const renderedItemInfo =
|
|
517
|
+
return horizontal ? {
|
|
518
|
+
flexDirection: ItemSeparatorComponent ? "row" : void 0,
|
|
519
|
+
height: otherAxisSize,
|
|
520
|
+
left: 0,
|
|
521
|
+
position: "absolute",
|
|
522
|
+
top: otherAxisPos,
|
|
523
|
+
...paddingStyles || {}
|
|
524
|
+
} : {
|
|
525
|
+
left: otherAxisPos,
|
|
526
|
+
position: "absolute",
|
|
527
|
+
right: numColumns > 1 ? void 0 : 0,
|
|
528
|
+
top: 0,
|
|
529
|
+
width: otherAxisSize,
|
|
530
|
+
...paddingStyles || {}
|
|
531
|
+
};
|
|
532
|
+
}, [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns]);
|
|
533
|
+
const renderedItemInfo = React4.useMemo(
|
|
395
534
|
() => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
|
|
396
535
|
[itemKey, data, extraData]
|
|
397
536
|
);
|
|
398
537
|
const { index, renderedItem } = renderedItemInfo || {};
|
|
399
|
-
const contextValue =
|
|
538
|
+
const contextValue = React4.useMemo(() => {
|
|
400
539
|
ctx.viewRefs.set(id, ref);
|
|
401
540
|
return {
|
|
402
541
|
containerId: id,
|
|
@@ -408,104 +547,183 @@ var Container = typedMemo(function Container2({
|
|
|
408
547
|
value: data
|
|
409
548
|
};
|
|
410
549
|
}, [id, itemKey, index, data]);
|
|
411
|
-
const
|
|
412
|
-
var _a, _b;
|
|
550
|
+
const onLayoutChange = (rectangle) => {
|
|
413
551
|
if (!isNullOrUndefined(itemKey)) {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
const size = layout[horizontal ? "width" : "height"];
|
|
552
|
+
let layout = rectangle;
|
|
553
|
+
layout[horizontal ? "width" : "height"];
|
|
417
554
|
const doUpdate = () => {
|
|
418
555
|
refLastSize.current = { height: layout.height, width: layout.width };
|
|
419
556
|
updateItemSize2(itemKey, layout);
|
|
420
557
|
};
|
|
421
|
-
|
|
558
|
+
{
|
|
422
559
|
doUpdate();
|
|
423
|
-
} else {
|
|
424
|
-
(_b = (_a = ref.current) == null ? void 0 : _a.measure) == null ? void 0 : _b.call(_a, (_x, _y, width, height) => {
|
|
425
|
-
layout = { height, width };
|
|
426
|
-
doUpdate();
|
|
427
|
-
});
|
|
428
560
|
}
|
|
429
561
|
}
|
|
430
562
|
};
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
563
|
+
const PositionComponent = isSticky ? PositionViewSticky : PositionView2;
|
|
564
|
+
return /* @__PURE__ */ React4__namespace.createElement(ContextContainer.Provider, { value: contextValue }, /* @__PURE__ */ React4__namespace.createElement(
|
|
565
|
+
PositionComponent,
|
|
566
|
+
{
|
|
567
|
+
horizontal,
|
|
568
|
+
id,
|
|
569
|
+
index,
|
|
570
|
+
key: recycleItems ? void 0 : itemKey,
|
|
571
|
+
onLayoutChange,
|
|
572
|
+
refView: ref,
|
|
573
|
+
style
|
|
574
|
+
},
|
|
575
|
+
renderedItem,
|
|
576
|
+
renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React4__namespace.createElement(
|
|
577
|
+
Separator,
|
|
578
|
+
{
|
|
579
|
+
ItemSeparatorComponent,
|
|
580
|
+
itemKey,
|
|
581
|
+
leadingItem: renderedItemInfo.item
|
|
582
|
+
}
|
|
583
|
+
)
|
|
584
|
+
));
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
// src/utils/reordering.ts
|
|
588
|
+
var mapFn = (element) => {
|
|
589
|
+
const indexStr = element.getAttribute("index");
|
|
590
|
+
return [element, indexStr === null ? null : parseInt(indexStr)];
|
|
591
|
+
};
|
|
592
|
+
function sortDOMElementsPatience(container) {
|
|
593
|
+
const elements = Array.from(container.children);
|
|
594
|
+
if (elements.length <= 1) return elements;
|
|
595
|
+
const items = elements.map(mapFn);
|
|
596
|
+
items.sort((a, b) => {
|
|
597
|
+
const aKey = a[1];
|
|
598
|
+
const bKey = b[1];
|
|
599
|
+
if (aKey === null) {
|
|
600
|
+
return 1;
|
|
601
|
+
}
|
|
602
|
+
if (bKey === null) {
|
|
603
|
+
return -1;
|
|
604
|
+
}
|
|
605
|
+
return aKey - bKey;
|
|
606
|
+
});
|
|
607
|
+
const targetPositions = /* @__PURE__ */ new Map();
|
|
608
|
+
items.forEach((item, index) => {
|
|
609
|
+
targetPositions.set(item[0], index);
|
|
610
|
+
});
|
|
611
|
+
const currentPositions = elements.map((el) => targetPositions.get(el));
|
|
612
|
+
const lis = findLIS(currentPositions);
|
|
613
|
+
const stableIndices = new Set(lis);
|
|
614
|
+
for (let targetPos = 0; targetPos < items.length; targetPos++) {
|
|
615
|
+
const element = items[targetPos][0];
|
|
616
|
+
const currentPos = elements.indexOf(element);
|
|
617
|
+
if (!stableIndices.has(currentPos)) {
|
|
618
|
+
let nextStableElement = null;
|
|
619
|
+
for (let i = targetPos + 1; i < items.length; i++) {
|
|
620
|
+
const nextEl = items[i][0];
|
|
621
|
+
const nextCurrentPos = elements.indexOf(nextEl);
|
|
622
|
+
if (stableIndices.has(nextCurrentPos)) {
|
|
623
|
+
nextStableElement = nextEl;
|
|
624
|
+
break;
|
|
441
625
|
}
|
|
442
626
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
const timeout = setTimeout(() => {
|
|
448
|
-
if (!didLayout && refLastSize.current) {
|
|
449
|
-
updateItemSize2(itemKey, refLastSize.current);
|
|
450
|
-
}
|
|
451
|
-
}, 16);
|
|
452
|
-
return () => {
|
|
453
|
-
clearTimeout(timeout);
|
|
454
|
-
};
|
|
627
|
+
if (nextStableElement) {
|
|
628
|
+
container.insertBefore(element, nextStableElement);
|
|
629
|
+
} else {
|
|
630
|
+
container.appendChild(element);
|
|
455
631
|
}
|
|
456
|
-
}
|
|
632
|
+
}
|
|
457
633
|
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
634
|
+
}
|
|
635
|
+
function findLIS(arr) {
|
|
636
|
+
const n = arr.length;
|
|
637
|
+
const tails = [];
|
|
638
|
+
const predecessors = new Array(n).fill(-1);
|
|
639
|
+
const indices = [];
|
|
640
|
+
for (let i = 0; i < n; i++) {
|
|
641
|
+
const num = arr[i];
|
|
642
|
+
let left = 0, right = tails.length;
|
|
643
|
+
while (left < right) {
|
|
644
|
+
const mid = Math.floor((left + right) / 2);
|
|
645
|
+
if (arr[indices[mid]] < num) {
|
|
646
|
+
left = mid + 1;
|
|
647
|
+
} else {
|
|
648
|
+
right = mid;
|
|
649
|
+
}
|
|
464
650
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
651
|
+
if (left === tails.length) {
|
|
652
|
+
tails.push(num);
|
|
653
|
+
indices.push(i);
|
|
654
|
+
} else {
|
|
655
|
+
tails[left] = num;
|
|
656
|
+
indices[left] = i;
|
|
657
|
+
}
|
|
658
|
+
if (left > 0) {
|
|
659
|
+
predecessors[i] = indices[left - 1];
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
const result = [];
|
|
663
|
+
let k = indices[indices.length - 1];
|
|
664
|
+
while (k !== -1) {
|
|
665
|
+
result.unshift(k);
|
|
666
|
+
k = predecessors[k];
|
|
667
|
+
}
|
|
668
|
+
return result;
|
|
669
|
+
}
|
|
470
670
|
|
|
471
|
-
// src/hooks/
|
|
472
|
-
function
|
|
473
|
-
var _a;
|
|
474
|
-
const { getValue, delay } = params || {};
|
|
671
|
+
// src/hooks/useDOMOrder.ts
|
|
672
|
+
function useDOMOrder(ref) {
|
|
475
673
|
const ctx = useStateContext();
|
|
476
|
-
const
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
if (newValue !== void 0) {
|
|
487
|
-
animValue.setValue(newValue);
|
|
488
|
-
}
|
|
489
|
-
};
|
|
490
|
-
const delayValue = typeof delay === "function" ? delay(newValue, prevValue) : delay;
|
|
491
|
-
prevValue = newValue;
|
|
492
|
-
if (!didQueueTask) {
|
|
493
|
-
didQueueTask = true;
|
|
494
|
-
if (delayValue === 0) {
|
|
495
|
-
queueMicrotask(fn);
|
|
496
|
-
} else {
|
|
497
|
-
setTimeout(fn, delayValue);
|
|
498
|
-
}
|
|
674
|
+
const debounceRef = React4.useRef(void 0);
|
|
675
|
+
React4.useEffect(() => {
|
|
676
|
+
const unsubscribe = listen$(ctx, "lastPositionUpdate", () => {
|
|
677
|
+
if (debounceRef.current !== void 0) {
|
|
678
|
+
clearTimeout(debounceRef.current);
|
|
679
|
+
}
|
|
680
|
+
debounceRef.current = setTimeout(() => {
|
|
681
|
+
const parent = ref.current;
|
|
682
|
+
if (parent) {
|
|
683
|
+
sortDOMElementsPatience(parent);
|
|
499
684
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
}
|
|
685
|
+
debounceRef.current = void 0;
|
|
686
|
+
}, 500);
|
|
503
687
|
});
|
|
504
|
-
|
|
505
|
-
|
|
688
|
+
return () => {
|
|
689
|
+
unsubscribe();
|
|
690
|
+
if (debounceRef.current !== void 0) {
|
|
691
|
+
clearTimeout(debounceRef.current);
|
|
692
|
+
}
|
|
693
|
+
};
|
|
694
|
+
}, [ctx]);
|
|
506
695
|
}
|
|
507
696
|
|
|
508
697
|
// src/components/Containers.tsx
|
|
698
|
+
var ContainersInner = typedMemo(function ContainersInner2({ horizontal, numColumns, children }) {
|
|
699
|
+
const ref = React4.useRef(null);
|
|
700
|
+
const ctx = useStateContext();
|
|
701
|
+
const columnWrapperStyle = ctx.columnWrapperStyle;
|
|
702
|
+
const [totalSize, otherAxisSize] = useArr$(["totalSize", "otherAxisSize"]);
|
|
703
|
+
useDOMOrder(ref);
|
|
704
|
+
const style = horizontal ? { minHeight: otherAxisSize, width: totalSize } : { height: totalSize, minWidth: otherAxisSize };
|
|
705
|
+
if (columnWrapperStyle && numColumns > 1) {
|
|
706
|
+
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
707
|
+
const gapX = columnGap || gap || 0;
|
|
708
|
+
const gapY = rowGap || gap || 0;
|
|
709
|
+
if (horizontal) {
|
|
710
|
+
if (gapY) {
|
|
711
|
+
style.marginTop = style.marginBottom = -gapY / 2;
|
|
712
|
+
}
|
|
713
|
+
if (gapX) {
|
|
714
|
+
style.marginRight = -gapX;
|
|
715
|
+
}
|
|
716
|
+
} else {
|
|
717
|
+
if (gapX) {
|
|
718
|
+
style.marginLeft = style.marginRight = -gapX;
|
|
719
|
+
}
|
|
720
|
+
if (gapY) {
|
|
721
|
+
style.marginBottom = -gapY;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
return /* @__PURE__ */ React4__namespace.createElement("div", { ref, style }, children);
|
|
726
|
+
});
|
|
509
727
|
var Containers = typedMemo(function Containers2({
|
|
510
728
|
horizontal,
|
|
511
729
|
recycleItems,
|
|
@@ -514,19 +732,11 @@ var Containers = typedMemo(function Containers2({
|
|
|
514
732
|
updateItemSize: updateItemSize2,
|
|
515
733
|
getRenderedItem: getRenderedItem2
|
|
516
734
|
}) {
|
|
517
|
-
const ctx = useStateContext();
|
|
518
|
-
const columnWrapperStyle = ctx.columnWrapperStyle;
|
|
519
735
|
const [numContainers, numColumns] = useArr$(["numContainersPooled", "numColumns"]);
|
|
520
|
-
const animSize = useValue$("totalSize", {
|
|
521
|
-
// Use a microtask if increasing the size significantly, otherwise use a timeout
|
|
522
|
-
delay: (value, prevValue) => !prevValue || value - prevValue > 20 ? 0 : 200
|
|
523
|
-
});
|
|
524
|
-
const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("containersDidLayout", { getValue: (value) => value ? 1 : 0 }) : void 0;
|
|
525
|
-
const otherAxisSize = useValue$("otherAxisSize", { delay: 0 });
|
|
526
736
|
const containers = [];
|
|
527
737
|
for (let i = 0; i < numContainers; i++) {
|
|
528
738
|
containers.push(
|
|
529
|
-
/* @__PURE__ */
|
|
739
|
+
/* @__PURE__ */ React4__namespace.createElement(
|
|
530
740
|
Container,
|
|
531
741
|
{
|
|
532
742
|
getRenderedItem: getRenderedItem2,
|
|
@@ -540,45 +750,209 @@ var Containers = typedMemo(function Containers2({
|
|
|
540
750
|
)
|
|
541
751
|
);
|
|
542
752
|
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
753
|
+
return /* @__PURE__ */ React4__namespace.createElement(ContainersInner, { horizontal, numColumns, waitForInitialLayout }, containers);
|
|
754
|
+
});
|
|
755
|
+
var DevNumbers = __DEV__ && React4__namespace.memo(function DevNumbers2() {
|
|
756
|
+
return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React4__namespace.createElement(
|
|
757
|
+
View,
|
|
758
|
+
{
|
|
759
|
+
key: index,
|
|
760
|
+
style: {
|
|
761
|
+
height: 100,
|
|
762
|
+
pointerEvents: "none",
|
|
763
|
+
position: "absolute",
|
|
764
|
+
top: index * 100,
|
|
765
|
+
width: "100%"
|
|
551
766
|
}
|
|
552
|
-
|
|
553
|
-
|
|
767
|
+
},
|
|
768
|
+
/* @__PURE__ */ React4__namespace.createElement(Text, { style: { color: "red" } }, index * 100)
|
|
769
|
+
));
|
|
770
|
+
});
|
|
771
|
+
var ListComponentScrollView = React4.forwardRef(function ListComponentScrollView2({
|
|
772
|
+
children,
|
|
773
|
+
style,
|
|
774
|
+
contentContainerStyle,
|
|
775
|
+
horizontal = false,
|
|
776
|
+
contentOffset,
|
|
777
|
+
maintainVisibleContentPosition,
|
|
778
|
+
onScroll: onScroll2,
|
|
779
|
+
onMomentumScrollEnd,
|
|
780
|
+
showsHorizontalScrollIndicator = true,
|
|
781
|
+
showsVerticalScrollIndicator = true,
|
|
782
|
+
refreshControl,
|
|
783
|
+
onLayout,
|
|
784
|
+
ScrollComponent,
|
|
785
|
+
...props
|
|
786
|
+
}, ref) {
|
|
787
|
+
const scrollRef = React4.useRef(null);
|
|
788
|
+
const contentRef = React4.useRef(null);
|
|
789
|
+
const momentumTimeout = React4.useRef(null);
|
|
790
|
+
React4.useImperativeHandle(ref, () => {
|
|
791
|
+
const api = {
|
|
792
|
+
getBoundingClientRect: () => {
|
|
793
|
+
var _a;
|
|
794
|
+
return (_a = scrollRef.current) == null ? void 0 : _a.getBoundingClientRect();
|
|
795
|
+
},
|
|
796
|
+
getScrollableNode: () => scrollRef.current,
|
|
797
|
+
getScrollResponder: () => scrollRef.current,
|
|
798
|
+
scrollBy: (options) => {
|
|
799
|
+
const el = scrollRef.current;
|
|
800
|
+
if (!el) return;
|
|
801
|
+
const { x = 0, y = 0, animated = true } = options;
|
|
802
|
+
el.scrollBy({ behavior: animated ? "smooth" : "auto", left: x, top: y });
|
|
803
|
+
},
|
|
804
|
+
scrollTo: (options) => {
|
|
805
|
+
const el = scrollRef.current;
|
|
806
|
+
if (!el) return;
|
|
807
|
+
const { x = 0, y = 0, animated = true } = options;
|
|
808
|
+
el.scrollTo({ behavior: animated ? "smooth" : "auto", left: x, top: y });
|
|
809
|
+
},
|
|
810
|
+
scrollToEnd: (options = {}) => {
|
|
811
|
+
const el = scrollRef.current;
|
|
812
|
+
if (!el) return;
|
|
813
|
+
const { animated = true } = options;
|
|
814
|
+
if (horizontal) {
|
|
815
|
+
el.scrollTo({ behavior: animated ? "smooth" : "auto", left: el.scrollWidth });
|
|
816
|
+
} else {
|
|
817
|
+
el.scrollTo({ behavior: animated ? "smooth" : "auto", top: el.scrollHeight });
|
|
818
|
+
}
|
|
819
|
+
},
|
|
820
|
+
scrollToOffset: (params) => {
|
|
821
|
+
const el = scrollRef.current;
|
|
822
|
+
if (!el) return;
|
|
823
|
+
const { offset, animated = true } = params;
|
|
824
|
+
if (horizontal) {
|
|
825
|
+
el.scrollTo({ behavior: animated ? "smooth" : "auto", left: offset });
|
|
826
|
+
} else {
|
|
827
|
+
el.scrollTo({ behavior: animated ? "smooth" : "auto", top: offset });
|
|
828
|
+
}
|
|
554
829
|
}
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
|
|
830
|
+
};
|
|
831
|
+
return api;
|
|
832
|
+
}, [horizontal]);
|
|
833
|
+
const handleScroll = React4.useCallback(
|
|
834
|
+
(event) => {
|
|
835
|
+
if (!onScroll2 || !(event == null ? void 0 : event.target)) {
|
|
836
|
+
return;
|
|
558
837
|
}
|
|
559
|
-
|
|
560
|
-
|
|
838
|
+
const target = event.target;
|
|
839
|
+
const scrollEvent = {
|
|
840
|
+
nativeEvent: {
|
|
841
|
+
contentOffset: {
|
|
842
|
+
x: target.scrollLeft,
|
|
843
|
+
y: target.scrollTop
|
|
844
|
+
},
|
|
845
|
+
contentSize: {
|
|
846
|
+
height: target.scrollHeight,
|
|
847
|
+
width: target.scrollWidth
|
|
848
|
+
},
|
|
849
|
+
layoutMeasurement: {
|
|
850
|
+
height: target.clientHeight,
|
|
851
|
+
width: target.clientWidth
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
};
|
|
855
|
+
onScroll2(scrollEvent);
|
|
856
|
+
if (onMomentumScrollEnd) {
|
|
857
|
+
if (momentumTimeout.current != null) clearTimeout(momentumTimeout.current);
|
|
858
|
+
momentumTimeout.current = setTimeout(() => {
|
|
859
|
+
onMomentumScrollEnd({
|
|
860
|
+
nativeEvent: {
|
|
861
|
+
contentOffset: scrollEvent.nativeEvent.contentOffset
|
|
862
|
+
}
|
|
863
|
+
});
|
|
864
|
+
}, 100);
|
|
561
865
|
}
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
|
|
866
|
+
},
|
|
867
|
+
[onScroll2, onMomentumScrollEnd]
|
|
868
|
+
);
|
|
869
|
+
React4.useLayoutEffect(() => {
|
|
870
|
+
const element = scrollRef.current;
|
|
871
|
+
if (!element) return;
|
|
872
|
+
element.addEventListener("scroll", handleScroll, { passive: true });
|
|
873
|
+
return () => {
|
|
874
|
+
element.removeEventListener("scroll", handleScroll);
|
|
875
|
+
};
|
|
876
|
+
}, [handleScroll]);
|
|
877
|
+
React4.useLayoutEffect(() => {
|
|
878
|
+
if (contentOffset && scrollRef.current) {
|
|
879
|
+
scrollRef.current.scrollLeft = contentOffset.x || 0;
|
|
880
|
+
scrollRef.current.scrollTop = contentOffset.y || 0;
|
|
881
|
+
}
|
|
882
|
+
}, [contentOffset]);
|
|
883
|
+
React4.useLayoutEffect(() => {
|
|
884
|
+
if (!onLayout || !scrollRef.current) return;
|
|
885
|
+
const element = scrollRef.current;
|
|
886
|
+
const fireLayout = () => {
|
|
887
|
+
const rect = element.getBoundingClientRect();
|
|
888
|
+
onLayout({
|
|
889
|
+
nativeEvent: {
|
|
890
|
+
layout: {
|
|
891
|
+
height: rect.height,
|
|
892
|
+
width: rect.width,
|
|
893
|
+
x: rect.left,
|
|
894
|
+
y: rect.top
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
});
|
|
898
|
+
};
|
|
899
|
+
fireLayout();
|
|
900
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
901
|
+
fireLayout();
|
|
902
|
+
});
|
|
903
|
+
resizeObserver.observe(element);
|
|
904
|
+
return () => resizeObserver.disconnect();
|
|
905
|
+
}, [onLayout]);
|
|
906
|
+
const scrollViewStyle = {
|
|
907
|
+
overflow: "auto",
|
|
908
|
+
overflowX: horizontal ? "auto" : showsHorizontalScrollIndicator ? "auto" : "hidden",
|
|
909
|
+
overflowY: horizontal ? showsVerticalScrollIndicator ? "auto" : "hidden" : "auto",
|
|
910
|
+
position: "relative",
|
|
911
|
+
// Ensure proper positioning context
|
|
912
|
+
WebkitOverflowScrolling: "touch",
|
|
913
|
+
// iOS momentum scrolling
|
|
914
|
+
...style
|
|
915
|
+
};
|
|
916
|
+
const contentStyle = {
|
|
917
|
+
display: horizontal ? "flex" : "block",
|
|
918
|
+
flexDirection: horizontal ? "row" : void 0,
|
|
919
|
+
minHeight: horizontal ? void 0 : "100%",
|
|
920
|
+
minWidth: horizontal ? "100%" : void 0,
|
|
921
|
+
...contentContainerStyle
|
|
922
|
+
};
|
|
923
|
+
return /* @__PURE__ */ React4__namespace.createElement("div", { ref: scrollRef, style: scrollViewStyle, ...props }, refreshControl, /* @__PURE__ */ React4__namespace.createElement("div", { ref: contentRef, style: contentStyle }, children));
|
|
565
924
|
});
|
|
925
|
+
function useValueListener$(key, callback) {
|
|
926
|
+
const ctx = useStateContext();
|
|
927
|
+
React4.useLayoutEffect(() => {
|
|
928
|
+
listen$(ctx, key, (value) => {
|
|
929
|
+
callback(value);
|
|
930
|
+
});
|
|
931
|
+
}, []);
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
// src/components/ScrollAdjust.tsx
|
|
566
935
|
function ScrollAdjust() {
|
|
567
|
-
const
|
|
568
|
-
const
|
|
569
|
-
const
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
936
|
+
const ctx = useStateContext();
|
|
937
|
+
const lastScrollOffsetRef = React4__namespace.useRef(0);
|
|
938
|
+
const callback = React4__namespace.useCallback(() => {
|
|
939
|
+
var _a;
|
|
940
|
+
const scrollAdjust = peek$(ctx, "scrollAdjust");
|
|
941
|
+
const scrollAdjustUserOffset = peek$(ctx, "scrollAdjustUserOffset");
|
|
942
|
+
const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0);
|
|
943
|
+
const scrollView = (_a = ctx.internalState) == null ? void 0 : _a.refScroller.current;
|
|
944
|
+
if (scrollView && scrollOffset !== lastScrollOffsetRef.current) {
|
|
945
|
+
const scrollDelta = scrollOffset - lastScrollOffsetRef.current;
|
|
946
|
+
if (scrollDelta !== 0) {
|
|
947
|
+
scrollView.scrollBy(0, scrollDelta);
|
|
948
|
+
console.log("ScrollAdjust (web scrollBy)", scrollDelta, "total offset:", scrollOffset);
|
|
949
|
+
}
|
|
950
|
+
lastScrollOffsetRef.current = scrollOffset;
|
|
580
951
|
}
|
|
581
|
-
);
|
|
952
|
+
}, []);
|
|
953
|
+
useValueListener$("scrollAdjust", callback);
|
|
954
|
+
useValueListener$("scrollAdjustUserOffset", callback);
|
|
955
|
+
return null;
|
|
582
956
|
}
|
|
583
957
|
|
|
584
958
|
// src/components/SnapWrapper.tsx
|
|
@@ -586,46 +960,31 @@ function SnapWrapper({ ScrollComponent, ...props }) {
|
|
|
586
960
|
const [snapToOffsets] = useArr$(["snapToOffsets"]);
|
|
587
961
|
return /* @__PURE__ */ React.createElement(ScrollComponent, { ...props, snapToOffsets });
|
|
588
962
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
const
|
|
593
|
-
|
|
594
|
-
(event) => {
|
|
595
|
-
onChange(event.nativeEvent.layout, false);
|
|
596
|
-
},
|
|
597
|
-
[onChange]
|
|
598
|
-
);
|
|
599
|
-
if (IsNewArchitecture) {
|
|
600
|
-
React3.useLayoutEffect(() => {
|
|
601
|
-
if (ref.current) {
|
|
602
|
-
ref.current.measure((x, y, width, height) => {
|
|
603
|
-
onChange({ height, width, x, y }, true);
|
|
604
|
-
});
|
|
605
|
-
}
|
|
606
|
-
}, []);
|
|
607
|
-
}
|
|
608
|
-
return { onLayout, ref };
|
|
963
|
+
|
|
964
|
+
// src/hooks/useValue$.ts
|
|
965
|
+
function useValue$(key, params) {
|
|
966
|
+
const [value] = useArr$([key]);
|
|
967
|
+
return value;
|
|
609
968
|
}
|
|
610
969
|
|
|
611
970
|
// src/components/ListComponent.tsx
|
|
612
971
|
var getComponent = (Component) => {
|
|
613
|
-
if (
|
|
972
|
+
if (React4__namespace.isValidElement(Component)) {
|
|
614
973
|
return Component;
|
|
615
974
|
}
|
|
616
975
|
if (Component) {
|
|
617
|
-
return /* @__PURE__ */
|
|
976
|
+
return /* @__PURE__ */ React4__namespace.createElement(Component, null);
|
|
618
977
|
}
|
|
619
978
|
return null;
|
|
620
979
|
};
|
|
621
980
|
var Padding = () => {
|
|
622
|
-
const animPaddingTop = useValue$("alignItemsPaddingTop"
|
|
623
|
-
return /* @__PURE__ */
|
|
981
|
+
const animPaddingTop = useValue$("alignItemsPaddingTop");
|
|
982
|
+
return /* @__PURE__ */ React4__namespace.createElement(AnimatedView, { style: { paddingTop: animPaddingTop } });
|
|
624
983
|
};
|
|
625
984
|
var PaddingDevMode = () => {
|
|
626
|
-
const animPaddingTop = useValue$("alignItemsPaddingTop"
|
|
627
|
-
return /* @__PURE__ */
|
|
628
|
-
|
|
985
|
+
const animPaddingTop = useValue$("alignItemsPaddingTop");
|
|
986
|
+
return /* @__PURE__ */ React4__namespace.createElement(React4__namespace.Fragment, null, /* @__PURE__ */ React4__namespace.createElement(AnimatedView, { style: { paddingTop: animPaddingTop } }), /* @__PURE__ */ React4__namespace.createElement(
|
|
987
|
+
AnimatedView,
|
|
629
988
|
{
|
|
630
989
|
style: {
|
|
631
990
|
backgroundColor: "green",
|
|
@@ -663,17 +1022,16 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
663
1022
|
scrollAdjustHandler,
|
|
664
1023
|
onLayoutHeader,
|
|
665
1024
|
snapToIndices,
|
|
1025
|
+
stickyIndices,
|
|
666
1026
|
...rest
|
|
667
1027
|
}) {
|
|
668
1028
|
const ctx = useStateContext();
|
|
669
|
-
const
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
const ScrollComponent = renderScrollComponent ? React3.useMemo(
|
|
673
|
-
() => React3__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
|
|
1029
|
+
const refHeader = React4__namespace.useRef(null);
|
|
1030
|
+
const ScrollComponent = renderScrollComponent ? React4.useMemo(
|
|
1031
|
+
() => React4__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
|
|
674
1032
|
[renderScrollComponent]
|
|
675
|
-
) :
|
|
676
|
-
|
|
1033
|
+
) : ListComponentScrollView;
|
|
1034
|
+
React4__namespace.useEffect(() => {
|
|
677
1035
|
if (canRender) {
|
|
678
1036
|
setTimeout(() => {
|
|
679
1037
|
scrollAdjustHandler.setMounted();
|
|
@@ -681,16 +1039,17 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
681
1039
|
}
|
|
682
1040
|
}, [canRender]);
|
|
683
1041
|
const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
|
|
684
|
-
|
|
1042
|
+
const contentContainerStyleWeb = React4.useMemo(() => {
|
|
1043
|
+
const base = contentContainerStyle || void 0;
|
|
1044
|
+
if (!horizontal) return base;
|
|
1045
|
+
if (base && base.height === "100%") return base;
|
|
1046
|
+
return { ...base || {}, height: "100%" };
|
|
1047
|
+
}, [horizontal, (contentContainerStyle == null ? void 0 : contentContainerStyle.height) === "100%" ? 1 : 0]);
|
|
1048
|
+
return /* @__PURE__ */ React4__namespace.createElement(
|
|
685
1049
|
SnapOrScroll,
|
|
686
1050
|
{
|
|
687
1051
|
...rest,
|
|
688
|
-
contentContainerStyle:
|
|
689
|
-
contentContainerStyle,
|
|
690
|
-
horizontal ? {
|
|
691
|
-
height: "100%"
|
|
692
|
-
} : {}
|
|
693
|
-
],
|
|
1052
|
+
contentContainerStyle: contentContainerStyleWeb,
|
|
694
1053
|
contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
|
|
695
1054
|
horizontal,
|
|
696
1055
|
maintainVisibleContentPosition: maintainVisibleContentPosition && !ListEmptyComponent ? { minIndexForVisible: 0 } : void 0,
|
|
@@ -700,11 +1059,19 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
700
1059
|
ScrollComponent: snapToIndices ? ScrollComponent : void 0,
|
|
701
1060
|
style
|
|
702
1061
|
},
|
|
703
|
-
maintainVisibleContentPosition && /* @__PURE__ */
|
|
704
|
-
ENABLE_DEVMODE ? /* @__PURE__ */
|
|
705
|
-
ListHeaderComponent && /* @__PURE__ */
|
|
1062
|
+
maintainVisibleContentPosition && /* @__PURE__ */ React4__namespace.createElement(ScrollAdjust, null),
|
|
1063
|
+
ENABLE_DEVMODE ? /* @__PURE__ */ React4__namespace.createElement(PaddingDevMode, null) : /* @__PURE__ */ React4__namespace.createElement(Padding, null),
|
|
1064
|
+
ListHeaderComponent && /* @__PURE__ */ React4__namespace.createElement(
|
|
1065
|
+
LayoutView,
|
|
1066
|
+
{
|
|
1067
|
+
onLayoutChange: onLayoutHeader,
|
|
1068
|
+
refView: refHeader,
|
|
1069
|
+
style: ListHeaderComponentStyle
|
|
1070
|
+
},
|
|
1071
|
+
getComponent(ListHeaderComponent)
|
|
1072
|
+
),
|
|
706
1073
|
ListEmptyComponent && getComponent(ListEmptyComponent),
|
|
707
|
-
canRender && /* @__PURE__ */
|
|
1074
|
+
canRender && /* @__PURE__ */ React4__namespace.createElement(
|
|
708
1075
|
Containers,
|
|
709
1076
|
{
|
|
710
1077
|
getRenderedItem: getRenderedItem2,
|
|
@@ -715,17 +1082,18 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
715
1082
|
waitForInitialLayout
|
|
716
1083
|
}
|
|
717
1084
|
),
|
|
718
|
-
ListFooterComponent && /* @__PURE__ */
|
|
719
|
-
|
|
1085
|
+
ListFooterComponent && /* @__PURE__ */ React4__namespace.createElement(
|
|
1086
|
+
LayoutView,
|
|
720
1087
|
{
|
|
721
|
-
|
|
722
|
-
const size =
|
|
1088
|
+
onLayoutChange: (layout) => {
|
|
1089
|
+
const size = layout[horizontal ? "width" : "height"];
|
|
723
1090
|
set$(ctx, "footerSize", size);
|
|
724
1091
|
},
|
|
725
1092
|
style: ListFooterComponentStyle
|
|
726
1093
|
},
|
|
727
1094
|
getComponent(ListFooterComponent)
|
|
728
|
-
)
|
|
1095
|
+
),
|
|
1096
|
+
__DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React4__namespace.createElement(DevNumbers, null)
|
|
729
1097
|
);
|
|
730
1098
|
});
|
|
731
1099
|
|
|
@@ -746,33 +1114,45 @@ function calculateOffsetForIndex(ctx, state, index) {
|
|
|
746
1114
|
let position = 0;
|
|
747
1115
|
if (index !== void 0) {
|
|
748
1116
|
position = (state == null ? void 0 : state.positions.get(getId(state, index))) || 0;
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
1117
|
+
const paddingTop = peek$(ctx, "stylePaddingTop");
|
|
1118
|
+
if (paddingTop) {
|
|
1119
|
+
position += paddingTop;
|
|
1120
|
+
}
|
|
1121
|
+
const headerSize = peek$(ctx, "headerSize");
|
|
1122
|
+
if (headerSize) {
|
|
1123
|
+
position += headerSize;
|
|
1124
|
+
}
|
|
757
1125
|
}
|
|
758
1126
|
return position;
|
|
759
1127
|
}
|
|
760
1128
|
|
|
761
1129
|
// src/utils/getItemSize.ts
|
|
762
1130
|
function getItemSize(state, key, index, data, useAverageSize) {
|
|
1131
|
+
var _a, _b;
|
|
763
1132
|
const {
|
|
764
1133
|
sizesKnown,
|
|
765
1134
|
sizes,
|
|
766
1135
|
scrollingTo,
|
|
767
|
-
|
|
1136
|
+
averageSizes,
|
|
1137
|
+
props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
|
|
768
1138
|
} = state;
|
|
769
1139
|
const sizeKnown = sizesKnown.get(key);
|
|
770
1140
|
if (sizeKnown !== void 0) {
|
|
771
1141
|
return sizeKnown;
|
|
772
1142
|
}
|
|
773
1143
|
let size;
|
|
774
|
-
|
|
775
|
-
|
|
1144
|
+
const itemType = getItemType ? (_a = getItemType(data, index)) != null ? _a : "" : "";
|
|
1145
|
+
if (getFixedItemSize) {
|
|
1146
|
+
size = getFixedItemSize(index, data, itemType);
|
|
1147
|
+
if (size !== void 0) {
|
|
1148
|
+
sizesKnown.set(key, size);
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
if (size === void 0 && useAverageSize && sizeKnown === void 0 && !scrollingTo) {
|
|
1152
|
+
const averageSizeForType = (_b = averageSizes[itemType]) == null ? void 0 : _b.avg;
|
|
1153
|
+
if (averageSizeForType !== void 0) {
|
|
1154
|
+
size = roundSize(averageSizeForType);
|
|
1155
|
+
}
|
|
776
1156
|
}
|
|
777
1157
|
if (size === void 0) {
|
|
778
1158
|
size = sizes.get(key);
|
|
@@ -781,7 +1161,7 @@ function getItemSize(state, key, index, data, useAverageSize) {
|
|
|
781
1161
|
}
|
|
782
1162
|
}
|
|
783
1163
|
if (size === void 0) {
|
|
784
|
-
size = getEstimatedItemSize ? getEstimatedItemSize(index, data) : estimatedItemSize;
|
|
1164
|
+
size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
|
|
785
1165
|
}
|
|
786
1166
|
sizes.set(key, size);
|
|
787
1167
|
return size;
|
|
@@ -800,11 +1180,46 @@ function calculateOffsetWithOffsetPosition(state, offsetParam, params) {
|
|
|
800
1180
|
return offset;
|
|
801
1181
|
}
|
|
802
1182
|
|
|
1183
|
+
// src/core/finishScrollTo.ts
|
|
1184
|
+
var finishScrollTo = (state) => {
|
|
1185
|
+
if (state) {
|
|
1186
|
+
state.scrollingTo = void 0;
|
|
1187
|
+
state.scrollHistory.length = 0;
|
|
1188
|
+
}
|
|
1189
|
+
};
|
|
1190
|
+
|
|
1191
|
+
// src/core/scrollTo.ts
|
|
1192
|
+
function scrollTo(state, params = {}) {
|
|
1193
|
+
var _a;
|
|
1194
|
+
const { animated, noScrollingTo } = params;
|
|
1195
|
+
const {
|
|
1196
|
+
refScroller,
|
|
1197
|
+
props: { horizontal }
|
|
1198
|
+
} = state;
|
|
1199
|
+
const offset = calculateOffsetWithOffsetPosition(state, params.offset, params);
|
|
1200
|
+
state.scrollHistory.length = 0;
|
|
1201
|
+
if (!noScrollingTo) {
|
|
1202
|
+
state.scrollingTo = params;
|
|
1203
|
+
}
|
|
1204
|
+
state.scrollPending = offset;
|
|
1205
|
+
(_a = refScroller.current) == null ? void 0 : _a.scrollTo({
|
|
1206
|
+
animated: !!animated,
|
|
1207
|
+
x: horizontal ? offset : 0,
|
|
1208
|
+
y: horizontal ? 0 : offset
|
|
1209
|
+
});
|
|
1210
|
+
if (!animated) {
|
|
1211
|
+
state.scroll = offset;
|
|
1212
|
+
setTimeout(() => finishScrollTo(state), 100);
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
|
|
803
1216
|
// src/utils/requestAdjust.ts
|
|
804
|
-
function requestAdjust(ctx, state, positionDiff) {
|
|
1217
|
+
function requestAdjust(ctx, state, positionDiff, dataChanged) {
|
|
805
1218
|
if (Math.abs(positionDiff) > 0.1) {
|
|
806
1219
|
const doit = () => {
|
|
807
|
-
|
|
1220
|
+
{
|
|
1221
|
+
state.scrollAdjustHandler.requestAdjust(positionDiff);
|
|
1222
|
+
}
|
|
808
1223
|
};
|
|
809
1224
|
state.scroll += positionDiff;
|
|
810
1225
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
@@ -823,49 +1238,72 @@ function requestAdjust(ctx, state, positionDiff) {
|
|
|
823
1238
|
if (state.ignoreScrollFromMVCPTimeout) {
|
|
824
1239
|
clearTimeout(state.ignoreScrollFromMVCPTimeout);
|
|
825
1240
|
}
|
|
826
|
-
state.ignoreScrollFromMVCPTimeout = setTimeout(
|
|
827
|
-
|
|
828
|
-
|
|
1241
|
+
state.ignoreScrollFromMVCPTimeout = setTimeout(
|
|
1242
|
+
() => {
|
|
1243
|
+
state.ignoreScrollFromMVCP = void 0;
|
|
1244
|
+
},
|
|
1245
|
+
100
|
|
1246
|
+
);
|
|
829
1247
|
} else {
|
|
830
1248
|
requestAnimationFrame(doit);
|
|
831
1249
|
}
|
|
832
1250
|
}
|
|
833
1251
|
}
|
|
834
1252
|
|
|
835
|
-
// src/core/
|
|
836
|
-
function prepareMVCP(ctx, state) {
|
|
1253
|
+
// src/core/mvcp.ts
|
|
1254
|
+
function prepareMVCP(ctx, state, dataChanged) {
|
|
837
1255
|
const {
|
|
1256
|
+
idsInView,
|
|
838
1257
|
positions,
|
|
839
1258
|
scrollingTo,
|
|
840
1259
|
props: { maintainVisibleContentPosition }
|
|
841
1260
|
} = state;
|
|
842
1261
|
let prevPosition;
|
|
843
1262
|
let targetId;
|
|
844
|
-
|
|
1263
|
+
const idsInViewWithPositions = [];
|
|
845
1264
|
const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
|
|
846
1265
|
if (maintainVisibleContentPosition) {
|
|
847
1266
|
const indexByKey = state.indexByKey;
|
|
848
1267
|
if (scrollTarget !== void 0) {
|
|
849
1268
|
targetId = getId(state, scrollTarget);
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
1269
|
+
} else if (idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
|
|
1270
|
+
if (dataChanged) {
|
|
1271
|
+
for (let i = 0; i < idsInView.length; i++) {
|
|
1272
|
+
const id = idsInView[i];
|
|
1273
|
+
const index = indexByKey.get(id);
|
|
1274
|
+
if (index !== void 0) {
|
|
1275
|
+
idsInViewWithPositions.push({ id, position: positions.get(id) });
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
} else {
|
|
1279
|
+
targetId = state.idsInView.find((id) => indexByKey.get(id) !== void 0);
|
|
1280
|
+
}
|
|
854
1281
|
}
|
|
855
|
-
if (targetId !== void 0
|
|
1282
|
+
if (targetId !== void 0) {
|
|
856
1283
|
prevPosition = positions.get(targetId);
|
|
857
1284
|
}
|
|
858
1285
|
}
|
|
859
1286
|
return () => {
|
|
1287
|
+
let positionDiff;
|
|
1288
|
+
if (dataChanged && targetId === void 0) {
|
|
1289
|
+
for (let i = 0; i < idsInViewWithPositions.length; i++) {
|
|
1290
|
+
const { id, position } = idsInViewWithPositions[i];
|
|
1291
|
+
const newPosition = positions.get(id);
|
|
1292
|
+
if (newPosition !== void 0) {
|
|
1293
|
+
positionDiff = newPosition - position;
|
|
1294
|
+
break;
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
860
1298
|
if (targetId !== void 0 && prevPosition !== void 0) {
|
|
861
1299
|
const newPosition = positions.get(targetId);
|
|
862
1300
|
if (newPosition !== void 0) {
|
|
863
|
-
|
|
864
|
-
if (Math.abs(positionDiff) > 0.1) {
|
|
865
|
-
requestAdjust(ctx, state, positionDiff);
|
|
866
|
-
}
|
|
1301
|
+
positionDiff = newPosition - prevPosition;
|
|
867
1302
|
}
|
|
868
1303
|
}
|
|
1304
|
+
if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
|
|
1305
|
+
requestAdjust(ctx, state, positionDiff);
|
|
1306
|
+
}
|
|
869
1307
|
};
|
|
870
1308
|
}
|
|
871
1309
|
|
|
@@ -874,10 +1312,10 @@ function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
|
|
|
874
1312
|
if (stylePaddingTop !== void 0) {
|
|
875
1313
|
const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
|
|
876
1314
|
if (stylePaddingTop < prevStylePaddingTop) {
|
|
877
|
-
let prevTotalSize = peek$(ctx, "totalSize");
|
|
1315
|
+
let prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
878
1316
|
set$(ctx, "totalSize", prevTotalSize + prevStylePaddingTop);
|
|
879
1317
|
state.timeoutSetPaddingTop = setTimeout(() => {
|
|
880
|
-
prevTotalSize = peek$(ctx, "totalSize");
|
|
1318
|
+
prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
881
1319
|
set$(ctx, "totalSize", prevTotalSize - prevStylePaddingTop);
|
|
882
1320
|
}, 16);
|
|
883
1321
|
}
|
|
@@ -941,43 +1379,6 @@ function addTotalSize(ctx, state, key, add) {
|
|
|
941
1379
|
}
|
|
942
1380
|
}
|
|
943
1381
|
|
|
944
|
-
// src/utils/getScrollVelocity.ts
|
|
945
|
-
var getScrollVelocity = (state) => {
|
|
946
|
-
const { scrollHistory } = state;
|
|
947
|
-
let velocity = 0;
|
|
948
|
-
if (scrollHistory.length >= 1) {
|
|
949
|
-
const newest = scrollHistory[scrollHistory.length - 1];
|
|
950
|
-
let oldest;
|
|
951
|
-
let start = 0;
|
|
952
|
-
for (let i = 0; i < scrollHistory.length - 1; i++) {
|
|
953
|
-
const entry = scrollHistory[i];
|
|
954
|
-
const nextEntry = scrollHistory[i + 1];
|
|
955
|
-
if (i > 0) {
|
|
956
|
-
const prevEntry = scrollHistory[i - 1];
|
|
957
|
-
const prevDirection = entry.scroll - prevEntry.scroll;
|
|
958
|
-
const currentDirection = nextEntry.scroll - entry.scroll;
|
|
959
|
-
if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
|
|
960
|
-
start = i;
|
|
961
|
-
break;
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
for (let i = start; i < scrollHistory.length - 1; i++) {
|
|
966
|
-
const entry = scrollHistory[i];
|
|
967
|
-
if (newest.time - entry.time <= 1e3) {
|
|
968
|
-
oldest = entry;
|
|
969
|
-
break;
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
if (oldest) {
|
|
973
|
-
const scrollDiff = newest.scroll - oldest.scroll;
|
|
974
|
-
const timeDiff = newest.time - oldest.time;
|
|
975
|
-
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
return velocity;
|
|
979
|
-
};
|
|
980
|
-
|
|
981
1382
|
// src/utils/updateSnapToOffsets.ts
|
|
982
1383
|
function updateSnapToOffsets(ctx, state) {
|
|
983
1384
|
const {
|
|
@@ -994,69 +1395,42 @@ function updateSnapToOffsets(ctx, state) {
|
|
|
994
1395
|
}
|
|
995
1396
|
|
|
996
1397
|
// src/core/updateAllPositions.ts
|
|
997
|
-
function updateAllPositions(ctx, state, dataChanged) {
|
|
998
|
-
var _a, _b, _c, _d, _e;
|
|
1398
|
+
function updateAllPositions(ctx, state, dataChanged, startIndex = 0) {
|
|
1399
|
+
var _a, _b, _c, _d, _e, _f;
|
|
999
1400
|
const {
|
|
1000
|
-
averageSizes,
|
|
1001
1401
|
columns,
|
|
1002
1402
|
indexByKey,
|
|
1003
1403
|
positions,
|
|
1004
|
-
firstFullyOnScreenIndex,
|
|
1005
1404
|
idCache,
|
|
1006
1405
|
sizesKnown,
|
|
1007
|
-
props: { snapToIndices }
|
|
1406
|
+
props: { getEstimatedItemSize, snapToIndices, enableAverages }
|
|
1008
1407
|
} = state;
|
|
1009
1408
|
const data = state.props.data;
|
|
1010
1409
|
const numColumns = peek$(ctx, "numColumns");
|
|
1011
1410
|
const indexByKeyForChecking = __DEV__ ? /* @__PURE__ */ new Map() : void 0;
|
|
1012
|
-
const
|
|
1013
|
-
if (dataChanged) {
|
|
1014
|
-
indexByKey.clear();
|
|
1015
|
-
idCache.clear();
|
|
1016
|
-
}
|
|
1017
|
-
const itemType = "";
|
|
1018
|
-
let averageSize = (_a = averageSizes[itemType]) == null ? void 0 : _a.avg;
|
|
1019
|
-
if (averageSize !== void 0) {
|
|
1020
|
-
averageSize = roundSize(averageSize);
|
|
1021
|
-
}
|
|
1022
|
-
const shouldUseBackwards = !dataChanged && scrollVelocity < 0 && firstFullyOnScreenIndex > 5 && firstFullyOnScreenIndex < data.length;
|
|
1023
|
-
if (shouldUseBackwards && firstFullyOnScreenIndex !== void 0) {
|
|
1024
|
-
const anchorId = getId(state, firstFullyOnScreenIndex);
|
|
1025
|
-
const anchorPosition = positions.get(anchorId);
|
|
1026
|
-
if (anchorPosition !== void 0) {
|
|
1027
|
-
let currentRowTop2 = anchorPosition;
|
|
1028
|
-
let maxSizeInRow2 = 0;
|
|
1029
|
-
let bailout = false;
|
|
1030
|
-
for (let i = firstFullyOnScreenIndex - 1; i >= 0; i--) {
|
|
1031
|
-
const id = (_b = idCache.get(i)) != null ? _b : getId(state, i);
|
|
1032
|
-
const size = (_c = sizesKnown.get(id)) != null ? _c : getItemSize(state, id, i, data[i], averageSize);
|
|
1033
|
-
const itemColumn = columns.get(id);
|
|
1034
|
-
maxSizeInRow2 = Math.max(maxSizeInRow2, size);
|
|
1035
|
-
if (itemColumn === 1) {
|
|
1036
|
-
currentRowTop2 -= maxSizeInRow2;
|
|
1037
|
-
maxSizeInRow2 = 0;
|
|
1038
|
-
}
|
|
1039
|
-
if (currentRowTop2 < -2e3) {
|
|
1040
|
-
bailout = true;
|
|
1041
|
-
break;
|
|
1042
|
-
}
|
|
1043
|
-
positions.set(id, currentRowTop2);
|
|
1044
|
-
}
|
|
1045
|
-
if (!bailout) {
|
|
1046
|
-
updateTotalSize(ctx, state);
|
|
1047
|
-
return;
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1411
|
+
const useAverageSize = enableAverages && !getEstimatedItemSize;
|
|
1051
1412
|
let currentRowTop = 0;
|
|
1052
1413
|
let column = 1;
|
|
1053
1414
|
let maxSizeInRow = 0;
|
|
1054
1415
|
const hasColumns = numColumns > 1;
|
|
1416
|
+
if (startIndex > 0) {
|
|
1417
|
+
const prevIndex = startIndex - 1;
|
|
1418
|
+
const prevId = (_a = idCache.get(prevIndex)) != null ? _a : getId(state, prevIndex);
|
|
1419
|
+
const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
|
|
1420
|
+
if (hasColumns) {
|
|
1421
|
+
const prevColumn = (_c = columns.get(prevId)) != null ? _c : 1;
|
|
1422
|
+
currentRowTop = prevPosition;
|
|
1423
|
+
column = prevColumn % numColumns + 1;
|
|
1424
|
+
} else {
|
|
1425
|
+
const prevSize = (_d = sizesKnown.get(prevId)) != null ? _d : getItemSize(state, prevId, prevIndex, data[prevIndex], useAverageSize);
|
|
1426
|
+
currentRowTop = prevPosition + prevSize;
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1055
1429
|
const needsIndexByKey = dataChanged || indexByKey.size === 0;
|
|
1056
1430
|
const dataLength = data.length;
|
|
1057
|
-
for (let i =
|
|
1058
|
-
const id = (
|
|
1059
|
-
const size = (
|
|
1431
|
+
for (let i = startIndex; i < dataLength; i++) {
|
|
1432
|
+
const id = (_e = idCache.get(i)) != null ? _e : getId(state, i);
|
|
1433
|
+
const size = (_f = sizesKnown.get(id)) != null ? _f : getItemSize(state, id, i, data[i], useAverageSize);
|
|
1060
1434
|
if (__DEV__ && needsIndexByKey) {
|
|
1061
1435
|
if (indexByKeyForChecking.has(id)) {
|
|
1062
1436
|
console.error(
|
|
@@ -1091,32 +1465,18 @@ function updateAllPositions(ctx, state, dataChanged) {
|
|
|
1091
1465
|
}
|
|
1092
1466
|
|
|
1093
1467
|
// src/core/viewability.ts
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
...viewabilityConfigCallbackPairs || [],
|
|
1100
|
-
{
|
|
1101
|
-
onViewableItemsChanged,
|
|
1102
|
-
viewabilityConfig: viewabilityConfig || {
|
|
1103
|
-
viewAreaCoveragePercentThreshold: 0
|
|
1104
|
-
}
|
|
1105
|
-
}
|
|
1106
|
-
];
|
|
1468
|
+
function ensureViewabilityState(ctx, configId) {
|
|
1469
|
+
let map = ctx.mapViewabilityConfigStates;
|
|
1470
|
+
if (!map) {
|
|
1471
|
+
map = /* @__PURE__ */ new Map();
|
|
1472
|
+
ctx.mapViewabilityConfigStates = map;
|
|
1107
1473
|
}
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
previousEnd: -1,
|
|
1113
|
-
previousStart: -1,
|
|
1114
|
-
start: -1,
|
|
1115
|
-
viewableItems: []
|
|
1116
|
-
});
|
|
1117
|
-
}
|
|
1474
|
+
let state = map.get(configId);
|
|
1475
|
+
if (!state) {
|
|
1476
|
+
state = { end: -1, previousEnd: -1, previousStart: -1, start: -1, viewableItems: [] };
|
|
1477
|
+
map.set(configId, state);
|
|
1118
1478
|
}
|
|
1119
|
-
return
|
|
1479
|
+
return state;
|
|
1120
1480
|
}
|
|
1121
1481
|
function updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollSize, start, end) {
|
|
1122
1482
|
const {
|
|
@@ -1124,9 +1484,7 @@ function updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollS
|
|
|
1124
1484
|
props: { data }
|
|
1125
1485
|
} = state;
|
|
1126
1486
|
for (const viewabilityConfigCallbackPair of viewabilityConfigCallbackPairs) {
|
|
1127
|
-
const viewabilityState =
|
|
1128
|
-
viewabilityConfigCallbackPair.viewabilityConfig.id
|
|
1129
|
-
);
|
|
1487
|
+
const viewabilityState = ensureViewabilityState(ctx, viewabilityConfigCallbackPair.viewabilityConfig.id);
|
|
1130
1488
|
viewabilityState.start = start;
|
|
1131
1489
|
viewabilityState.end = end;
|
|
1132
1490
|
if (viewabilityConfigCallbackPair.viewabilityConfig.minimumViewTime) {
|
|
@@ -1143,7 +1501,7 @@ function updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollS
|
|
|
1143
1501
|
function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, state, ctx, scrollSize) {
|
|
1144
1502
|
const { viewabilityConfig, onViewableItemsChanged } = viewabilityConfigCallbackPair;
|
|
1145
1503
|
const configId = viewabilityConfig.id;
|
|
1146
|
-
const viewabilityState =
|
|
1504
|
+
const viewabilityState = ensureViewabilityState(ctx, configId);
|
|
1147
1505
|
const { viewableItems: previousViewableItems, start, end } = viewabilityState;
|
|
1148
1506
|
const viewabilityTokens = /* @__PURE__ */ new Map();
|
|
1149
1507
|
for (const [containerId, value] of ctx.mapViewabilityAmountValues) {
|
|
@@ -1222,6 +1580,15 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
|
|
|
1222
1580
|
}
|
|
1223
1581
|
}
|
|
1224
1582
|
}
|
|
1583
|
+
function shallowEqual(prev, next) {
|
|
1584
|
+
if (!prev) return false;
|
|
1585
|
+
const keys = Object.keys(next);
|
|
1586
|
+
for (let i = 0; i < keys.length; i++) {
|
|
1587
|
+
const k = keys[i];
|
|
1588
|
+
if (prev[k] !== next[k]) return false;
|
|
1589
|
+
}
|
|
1590
|
+
return true;
|
|
1591
|
+
}
|
|
1225
1592
|
function computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
|
|
1226
1593
|
const { sizes, positions, scroll: scrollState } = state;
|
|
1227
1594
|
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
@@ -1250,7 +1617,8 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
|
|
|
1250
1617
|
size,
|
|
1251
1618
|
sizeVisible
|
|
1252
1619
|
};
|
|
1253
|
-
|
|
1620
|
+
const prev = ctx.mapViewabilityAmountValues.get(containerId);
|
|
1621
|
+
if (!shallowEqual(prev, value)) {
|
|
1254
1622
|
ctx.mapViewabilityAmountValues.set(containerId, value);
|
|
1255
1623
|
const cb = ctx.mapViewabilityAmountCallbacks.get(containerId);
|
|
1256
1624
|
if (cb) {
|
|
@@ -1283,7 +1651,7 @@ function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
|
|
|
1283
1651
|
// src/utils/checkAllSizesKnown.ts
|
|
1284
1652
|
function checkAllSizesKnown(state) {
|
|
1285
1653
|
const { startBuffered, endBuffered, sizesKnown } = state;
|
|
1286
|
-
if (endBuffered !== null) {
|
|
1654
|
+
if (endBuffered !== null && startBuffered >= 0 && endBuffered >= 0) {
|
|
1287
1655
|
let areAllKnown = true;
|
|
1288
1656
|
for (let i = startBuffered; areAllKnown && i <= endBuffered; i++) {
|
|
1289
1657
|
const key = getId(state, i);
|
|
@@ -1295,35 +1663,79 @@ function checkAllSizesKnown(state) {
|
|
|
1295
1663
|
}
|
|
1296
1664
|
|
|
1297
1665
|
// src/utils/findAvailableContainers.ts
|
|
1298
|
-
function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval) {
|
|
1666
|
+
function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
|
|
1299
1667
|
const numContainers = peek$(ctx, "numContainers");
|
|
1668
|
+
const { stickyContainerPool, containerItemTypes } = state;
|
|
1300
1669
|
const result = [];
|
|
1301
1670
|
const availableContainers = [];
|
|
1302
|
-
|
|
1671
|
+
const stickyIndicesSet = state.props.stickyIndicesSet;
|
|
1672
|
+
const stickyItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => stickyIndicesSet.has(index))) || [];
|
|
1673
|
+
const canReuseContainer = (containerIndex, requiredType) => {
|
|
1674
|
+
if (!requiredType) return true;
|
|
1675
|
+
const existingType = containerItemTypes.get(containerIndex);
|
|
1676
|
+
if (!existingType) return true;
|
|
1677
|
+
return existingType === requiredType;
|
|
1678
|
+
};
|
|
1679
|
+
const neededTypes = requiredItemTypes ? [...requiredItemTypes] : [];
|
|
1680
|
+
let typeIndex = 0;
|
|
1681
|
+
for (let i = 0; i < stickyItemIndices.length; i++) {
|
|
1682
|
+
const requiredType = neededTypes[typeIndex];
|
|
1683
|
+
let foundContainer = false;
|
|
1684
|
+
for (const containerIndex of stickyContainerPool) {
|
|
1685
|
+
const key = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1686
|
+
const isPendingRemoval = pendingRemoval.includes(containerIndex);
|
|
1687
|
+
if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType)) {
|
|
1688
|
+
result.push(containerIndex);
|
|
1689
|
+
if (isPendingRemoval) {
|
|
1690
|
+
const index = pendingRemoval.indexOf(containerIndex);
|
|
1691
|
+
pendingRemoval.splice(index, 1);
|
|
1692
|
+
}
|
|
1693
|
+
foundContainer = true;
|
|
1694
|
+
if (requiredItemTypes) typeIndex++;
|
|
1695
|
+
break;
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
if (!foundContainer) {
|
|
1699
|
+
const newContainerIndex = numContainers + result.filter((index) => index >= numContainers).length;
|
|
1700
|
+
result.push(newContainerIndex);
|
|
1701
|
+
stickyContainerPool.add(newContainerIndex);
|
|
1702
|
+
if (requiredItemTypes) typeIndex++;
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
for (let u = 0; u < numContainers && result.length < numNeeded; u++) {
|
|
1706
|
+
if (stickyContainerPool.has(u)) {
|
|
1707
|
+
continue;
|
|
1708
|
+
}
|
|
1303
1709
|
const key = peek$(ctx, `containerItemKey${u}`);
|
|
1304
1710
|
let isOk = key === void 0;
|
|
1305
1711
|
if (!isOk) {
|
|
1306
1712
|
const index = pendingRemoval.indexOf(u);
|
|
1307
1713
|
if (index !== -1) {
|
|
1308
1714
|
pendingRemoval.splice(index, 1);
|
|
1309
|
-
|
|
1715
|
+
const requiredType = neededTypes[typeIndex];
|
|
1716
|
+
isOk = canReuseContainer(u, requiredType);
|
|
1310
1717
|
}
|
|
1311
1718
|
}
|
|
1312
1719
|
if (isOk) {
|
|
1313
1720
|
result.push(u);
|
|
1314
|
-
if (
|
|
1315
|
-
|
|
1721
|
+
if (requiredItemTypes) {
|
|
1722
|
+
typeIndex++;
|
|
1316
1723
|
}
|
|
1317
1724
|
}
|
|
1318
1725
|
}
|
|
1319
|
-
for (let u = 0; u < numContainers; u++) {
|
|
1726
|
+
for (let u = 0; u < numContainers && result.length < numNeeded; u++) {
|
|
1727
|
+
if (stickyContainerPool.has(u)) {
|
|
1728
|
+
continue;
|
|
1729
|
+
}
|
|
1320
1730
|
const key = peek$(ctx, `containerItemKey${u}`);
|
|
1321
1731
|
if (key === void 0) continue;
|
|
1322
1732
|
const index = state.indexByKey.get(key);
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1733
|
+
const isOutOfView = index < startBuffered || index > endBuffered;
|
|
1734
|
+
if (isOutOfView) {
|
|
1735
|
+
const distance = index < startBuffered ? startBuffered - index : index - endBuffered;
|
|
1736
|
+
if (!requiredItemTypes || typeIndex < neededTypes.length && canReuseContainer(u, neededTypes[typeIndex])) {
|
|
1737
|
+
availableContainers.push({ distance, index: u });
|
|
1738
|
+
}
|
|
1327
1739
|
}
|
|
1328
1740
|
}
|
|
1329
1741
|
const remaining = numNeeded - result.length;
|
|
@@ -1335,6 +1747,9 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1335
1747
|
}
|
|
1336
1748
|
for (const container of availableContainers) {
|
|
1337
1749
|
result.push(container.index);
|
|
1750
|
+
if (requiredItemTypes) {
|
|
1751
|
+
typeIndex++;
|
|
1752
|
+
}
|
|
1338
1753
|
}
|
|
1339
1754
|
}
|
|
1340
1755
|
const stillNeeded = numNeeded - result.length;
|
|
@@ -1363,37 +1778,44 @@ function comparatorByDistance(a, b) {
|
|
|
1363
1778
|
return b.distance - a.distance;
|
|
1364
1779
|
}
|
|
1365
1780
|
|
|
1366
|
-
// src/
|
|
1367
|
-
var
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1781
|
+
// src/utils/getScrollVelocity.ts
|
|
1782
|
+
var getScrollVelocity = (state) => {
|
|
1783
|
+
const { scrollHistory } = state;
|
|
1784
|
+
let velocity = 0;
|
|
1785
|
+
if (scrollHistory.length >= 1) {
|
|
1786
|
+
const newest = scrollHistory[scrollHistory.length - 1];
|
|
1787
|
+
let oldest;
|
|
1788
|
+
let start = 0;
|
|
1789
|
+
const now = Date.now();
|
|
1790
|
+
for (let i = 0; i < scrollHistory.length - 1; i++) {
|
|
1791
|
+
const entry = scrollHistory[i];
|
|
1792
|
+
const nextEntry = scrollHistory[i + 1];
|
|
1793
|
+
if (i > 0) {
|
|
1794
|
+
const prevEntry = scrollHistory[i - 1];
|
|
1795
|
+
const prevDirection = entry.scroll - prevEntry.scroll;
|
|
1796
|
+
const currentDirection = nextEntry.scroll - entry.scroll;
|
|
1797
|
+
if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
|
|
1798
|
+
start = i;
|
|
1799
|
+
break;
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
for (let i = start; i < scrollHistory.length - 1; i++) {
|
|
1804
|
+
const entry = scrollHistory[i];
|
|
1805
|
+
if (now - entry.time <= 1e3) {
|
|
1806
|
+
oldest = entry;
|
|
1807
|
+
break;
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
if (oldest && oldest !== newest) {
|
|
1811
|
+
const scrollDiff = newest.scroll - oldest.scroll;
|
|
1812
|
+
const timeDiff = newest.time - oldest.time;
|
|
1813
|
+
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
1814
|
+
}
|
|
1371
1815
|
}
|
|
1816
|
+
return velocity;
|
|
1372
1817
|
};
|
|
1373
1818
|
|
|
1374
|
-
// src/core/scrollTo.ts
|
|
1375
|
-
function scrollTo(state, params = {}) {
|
|
1376
|
-
var _a;
|
|
1377
|
-
const { animated } = params;
|
|
1378
|
-
const {
|
|
1379
|
-
refScroller,
|
|
1380
|
-
props: { horizontal }
|
|
1381
|
-
} = state;
|
|
1382
|
-
const offset = calculateOffsetWithOffsetPosition(state, params.offset, params);
|
|
1383
|
-
state.scrollHistory.length = 0;
|
|
1384
|
-
state.scrollingTo = params;
|
|
1385
|
-
state.scrollPending = offset;
|
|
1386
|
-
(_a = refScroller.current) == null ? void 0 : _a.scrollTo({
|
|
1387
|
-
animated: !!animated,
|
|
1388
|
-
x: horizontal ? offset : 0,
|
|
1389
|
-
y: horizontal ? 0 : offset
|
|
1390
|
-
});
|
|
1391
|
-
if (!animated) {
|
|
1392
|
-
state.scroll = offset;
|
|
1393
|
-
setTimeout(() => finishScrollTo(state), 100);
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
|
|
1397
1819
|
// src/core/scrollToIndex.ts
|
|
1398
1820
|
function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
|
|
1399
1821
|
if (index >= state.props.data.length) {
|
|
@@ -1481,33 +1903,101 @@ function setDidLayout(ctx, state) {
|
|
|
1481
1903
|
} = state;
|
|
1482
1904
|
state.queuedInitialLayout = true;
|
|
1483
1905
|
checkAtBottom(ctx, state);
|
|
1484
|
-
|
|
1485
|
-
|
|
1906
|
+
const setIt = () => {
|
|
1907
|
+
set$(ctx, "containersDidLayout", true);
|
|
1908
|
+
if (onLoad) {
|
|
1909
|
+
onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
|
|
1910
|
+
}
|
|
1911
|
+
};
|
|
1912
|
+
{
|
|
1913
|
+
setIt();
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1917
|
+
// src/core/calculateItemsInView.ts
|
|
1918
|
+
function findCurrentStickyIndex(stickyArray, scroll, state) {
|
|
1919
|
+
var _a;
|
|
1920
|
+
const idCache = state.idCache;
|
|
1921
|
+
const positions = state.positions;
|
|
1922
|
+
for (let i = stickyArray.length - 1; i >= 0; i--) {
|
|
1923
|
+
const stickyId = (_a = idCache.get(stickyArray[i])) != null ? _a : getId(state, stickyArray[i]);
|
|
1924
|
+
const stickyPos = stickyId ? positions.get(stickyId) : void 0;
|
|
1925
|
+
if (stickyPos !== void 0 && scroll >= stickyPos) {
|
|
1926
|
+
return i;
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
return -1;
|
|
1930
|
+
}
|
|
1931
|
+
function getActiveStickyIndices(ctx, state, stickyIndices) {
|
|
1932
|
+
return new Set(
|
|
1933
|
+
Array.from(state.stickyContainerPool).map((i) => peek$(ctx, `containerItemKey${i}`)).map((key) => key ? state.indexByKey.get(key) : void 0).filter((idx) => idx !== void 0 && stickyIndices.has(idx))
|
|
1934
|
+
);
|
|
1935
|
+
}
|
|
1936
|
+
function handleStickyActivation(ctx, state, stickyIndices, stickyArray, scroll, needNewContainers, startBuffered, endBuffered) {
|
|
1937
|
+
var _a;
|
|
1938
|
+
const activeIndices = getActiveStickyIndices(ctx, state, stickyIndices);
|
|
1939
|
+
const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
|
|
1940
|
+
for (let offset = 0; offset <= 1; offset++) {
|
|
1941
|
+
const idx = currentStickyIdx - offset;
|
|
1942
|
+
if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
|
|
1943
|
+
const stickyIndex = stickyArray[idx];
|
|
1944
|
+
const stickyId = (_a = state.idCache.get(stickyIndex)) != null ? _a : getId(state, stickyIndex);
|
|
1945
|
+
if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered)) {
|
|
1946
|
+
needNewContainers.push(stickyIndex);
|
|
1947
|
+
}
|
|
1486
1948
|
}
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1949
|
+
}
|
|
1950
|
+
function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, pendingRemoval) {
|
|
1951
|
+
var _a, _b, _c;
|
|
1952
|
+
const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
|
|
1953
|
+
for (const containerIndex of state.stickyContainerPool) {
|
|
1954
|
+
const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1955
|
+
const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
|
|
1956
|
+
if (itemIndex === void 0) continue;
|
|
1957
|
+
const arrayIdx = stickyArray.indexOf(itemIndex);
|
|
1958
|
+
if (arrayIdx === -1) continue;
|
|
1959
|
+
const isRecentSticky = arrayIdx >= currentStickyIdx - 1 && arrayIdx <= currentStickyIdx + 1;
|
|
1960
|
+
if (isRecentSticky) continue;
|
|
1961
|
+
const nextIndex = stickyArray[arrayIdx + 1];
|
|
1962
|
+
let shouldRecycle = false;
|
|
1963
|
+
if (nextIndex) {
|
|
1964
|
+
const nextId = (_a = state.idCache.get(nextIndex)) != null ? _a : getId(state, nextIndex);
|
|
1965
|
+
const nextPos = nextId ? state.positions.get(nextId) : void 0;
|
|
1966
|
+
shouldRecycle = nextPos !== void 0 && scroll > nextPos + scrollBuffer * 2;
|
|
1967
|
+
} else {
|
|
1968
|
+
const currentId = (_b = state.idCache.get(itemIndex)) != null ? _b : getId(state, itemIndex);
|
|
1969
|
+
if (currentId) {
|
|
1970
|
+
const currentPos = state.positions.get(currentId);
|
|
1971
|
+
const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(state, currentId, itemIndex, state.props.data[itemIndex]);
|
|
1972
|
+
shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
if (shouldRecycle) {
|
|
1976
|
+
pendingRemoval.push(containerIndex);
|
|
1977
|
+
}
|
|
1490
1978
|
}
|
|
1491
1979
|
}
|
|
1492
|
-
|
|
1493
|
-
// src/core/calculateItemsInView.ts
|
|
1494
1980
|
function calculateItemsInView(ctx, state, params = {}) {
|
|
1495
|
-
|
|
1981
|
+
reactDom.unstable_batchedUpdates(() => {
|
|
1496
1982
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1497
1983
|
const {
|
|
1498
|
-
scrollLength,
|
|
1499
|
-
startBufferedId: startBufferedIdOrig,
|
|
1500
|
-
positions,
|
|
1501
1984
|
columns,
|
|
1502
1985
|
containerItemKeys,
|
|
1986
|
+
enableScrollForNextCalculateItemsInView,
|
|
1503
1987
|
idCache,
|
|
1504
|
-
sizes,
|
|
1505
1988
|
indexByKey,
|
|
1989
|
+
minIndexSizeChanged,
|
|
1990
|
+
positions,
|
|
1506
1991
|
scrollForNextCalculateItemsInView,
|
|
1507
|
-
|
|
1508
|
-
|
|
1992
|
+
scrollLength,
|
|
1993
|
+
sizes,
|
|
1994
|
+
startBufferedId: startBufferedIdOrig,
|
|
1995
|
+
viewabilityConfigCallbackPairs,
|
|
1996
|
+
props: { getItemType, initialScroll, itemsAreEqual, keyExtractor, scrollBuffer }
|
|
1509
1997
|
} = state;
|
|
1510
|
-
const data = state.props
|
|
1998
|
+
const { data } = state.props;
|
|
1999
|
+
const stickyIndicesArr = state.props.stickyIndicesArr || [];
|
|
2000
|
+
const stickyIndicesSet = state.props.stickyIndicesSet || /* @__PURE__ */ new Set();
|
|
1511
2001
|
const prevNumContainers = peek$(ctx, "numContainers");
|
|
1512
2002
|
if (!data || scrollLength === 0 || !prevNumContainers) {
|
|
1513
2003
|
return;
|
|
@@ -1519,14 +2009,22 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1519
2009
|
const { dataChanged, doMVCP } = params;
|
|
1520
2010
|
const speed = getScrollVelocity(state);
|
|
1521
2011
|
if (doMVCP || dataChanged) {
|
|
1522
|
-
const checkMVCP = doMVCP ? prepareMVCP(ctx, state) : void 0;
|
|
1523
|
-
|
|
2012
|
+
const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
|
|
2013
|
+
if (dataChanged) {
|
|
2014
|
+
indexByKey.clear();
|
|
2015
|
+
idCache.clear();
|
|
2016
|
+
positions.clear();
|
|
2017
|
+
}
|
|
2018
|
+
const startIndex = dataChanged ? 0 : minIndexSizeChanged != null ? minIndexSizeChanged : 0;
|
|
2019
|
+
updateAllPositions(ctx, state, dataChanged, startIndex);
|
|
2020
|
+
if (minIndexSizeChanged !== void 0) {
|
|
2021
|
+
state.minIndexSizeChanged = void 0;
|
|
2022
|
+
}
|
|
1524
2023
|
checkMVCP == null ? void 0 : checkMVCP();
|
|
1525
2024
|
}
|
|
1526
2025
|
const scrollExtra = 0;
|
|
1527
2026
|
const { queuedInitialLayout } = state;
|
|
1528
2027
|
let { scroll: scrollState } = state;
|
|
1529
|
-
const initialScroll = state.props.initialScroll;
|
|
1530
2028
|
if (!queuedInitialLayout && initialScroll) {
|
|
1531
2029
|
const updatedOffset = calculateOffsetWithOffsetPosition(
|
|
1532
2030
|
state,
|
|
@@ -1538,16 +2036,15 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1538
2036
|
const scrollAdjustPad = -previousScrollAdjust - topPad;
|
|
1539
2037
|
let scroll = scrollState + scrollExtra + scrollAdjustPad;
|
|
1540
2038
|
if (scroll + scrollLength > totalSize) {
|
|
1541
|
-
scroll = totalSize - scrollLength;
|
|
2039
|
+
scroll = Math.max(0, totalSize - scrollLength);
|
|
1542
2040
|
}
|
|
1543
2041
|
if (ENABLE_DEBUG_VIEW) {
|
|
1544
2042
|
set$(ctx, "debugRawScroll", scrollState);
|
|
1545
2043
|
set$(ctx, "debugComputedScroll", scroll);
|
|
1546
2044
|
}
|
|
1547
|
-
const scrollBuffer = state.props.scrollBuffer;
|
|
1548
2045
|
let scrollBufferTop = scrollBuffer;
|
|
1549
2046
|
let scrollBufferBottom = scrollBuffer;
|
|
1550
|
-
if (speed > 0) {
|
|
2047
|
+
if (speed > 0 || speed === 0 && scroll < Math.max(50, scrollBuffer)) {
|
|
1551
2048
|
scrollBufferTop = scrollBuffer * 0.5;
|
|
1552
2049
|
scrollBufferBottom = scrollBuffer * 1.5;
|
|
1553
2050
|
} else {
|
|
@@ -1555,7 +2052,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1555
2052
|
scrollBufferBottom = scrollBuffer * 0.5;
|
|
1556
2053
|
}
|
|
1557
2054
|
const scrollTopBuffered = scroll - scrollBufferTop;
|
|
1558
|
-
const scrollBottom = scroll + scrollLength;
|
|
2055
|
+
const scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
|
|
1559
2056
|
const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
|
|
1560
2057
|
if (scrollForNextCalculateItemsInView) {
|
|
1561
2058
|
const { top, bottom } = scrollForNextCalculateItemsInView;
|
|
@@ -1569,10 +2066,6 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1569
2066
|
let endNoBuffer = null;
|
|
1570
2067
|
let endBuffered = null;
|
|
1571
2068
|
let loopStart = startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
|
|
1572
|
-
if (minIndexSizeChanged !== void 0) {
|
|
1573
|
-
loopStart = Math.min(minIndexSizeChanged, loopStart);
|
|
1574
|
-
state.minIndexSizeChanged = void 0;
|
|
1575
|
-
}
|
|
1576
2069
|
for (let i = loopStart; i >= 0; i--) {
|
|
1577
2070
|
const id = (_a = idCache.get(i)) != null ? _a : getId(state, i);
|
|
1578
2071
|
const top = positions.get(id);
|
|
@@ -1655,7 +2148,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1655
2148
|
if (dataChanged) {
|
|
1656
2149
|
for (let i = 0; i < numContainers; i++) {
|
|
1657
2150
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1658
|
-
if (!
|
|
2151
|
+
if (!keyExtractor || itemKey && indexByKey.get(itemKey) === void 0) {
|
|
1659
2152
|
pendingRemoval.push(i);
|
|
1660
2153
|
}
|
|
1661
2154
|
}
|
|
@@ -1669,14 +2162,32 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1669
2162
|
needNewContainers.push(i);
|
|
1670
2163
|
}
|
|
1671
2164
|
}
|
|
2165
|
+
if (stickyIndicesArr.length > 0) {
|
|
2166
|
+
handleStickyActivation(
|
|
2167
|
+
ctx,
|
|
2168
|
+
state,
|
|
2169
|
+
stickyIndicesSet,
|
|
2170
|
+
stickyIndicesArr,
|
|
2171
|
+
scroll,
|
|
2172
|
+
needNewContainers,
|
|
2173
|
+
startBuffered,
|
|
2174
|
+
endBuffered
|
|
2175
|
+
);
|
|
2176
|
+
}
|
|
1672
2177
|
if (needNewContainers.length > 0) {
|
|
2178
|
+
const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
|
|
2179
|
+
const itemType = getItemType(data[i], i);
|
|
2180
|
+
return itemType ? String(itemType) : "";
|
|
2181
|
+
}) : void 0;
|
|
1673
2182
|
const availableContainers = findAvailableContainers(
|
|
1674
2183
|
ctx,
|
|
1675
2184
|
state,
|
|
1676
2185
|
needNewContainers.length,
|
|
1677
2186
|
startBuffered,
|
|
1678
2187
|
endBuffered,
|
|
1679
|
-
pendingRemoval
|
|
2188
|
+
pendingRemoval,
|
|
2189
|
+
requiredItemTypes,
|
|
2190
|
+
needNewContainers
|
|
1680
2191
|
);
|
|
1681
2192
|
for (let idx = 0; idx < needNewContainers.length; idx++) {
|
|
1682
2193
|
const i = needNewContainers[idx];
|
|
@@ -1688,7 +2199,18 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1688
2199
|
}
|
|
1689
2200
|
set$(ctx, `containerItemKey${containerIndex}`, id);
|
|
1690
2201
|
set$(ctx, `containerItemData${containerIndex}`, data[i]);
|
|
2202
|
+
if (requiredItemTypes) {
|
|
2203
|
+
state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
|
|
2204
|
+
}
|
|
1691
2205
|
containerItemKeys.add(id);
|
|
2206
|
+
if (stickyIndicesSet.has(i)) {
|
|
2207
|
+
set$(ctx, `containerSticky${containerIndex}`, true);
|
|
2208
|
+
const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
2209
|
+
set$(ctx, `containerStickyOffset${containerIndex}`, createAnimatedValue(topPadding));
|
|
2210
|
+
state.stickyContainerPool.add(containerIndex);
|
|
2211
|
+
} else {
|
|
2212
|
+
state.stickyContainerPool.delete(containerIndex);
|
|
2213
|
+
}
|
|
1692
2214
|
if (containerIndex >= numContainers2) {
|
|
1693
2215
|
numContainers2 = containerIndex + 1;
|
|
1694
2216
|
}
|
|
@@ -1701,12 +2223,22 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1701
2223
|
}
|
|
1702
2224
|
}
|
|
1703
2225
|
}
|
|
2226
|
+
if (stickyIndicesArr.length > 0) {
|
|
2227
|
+
handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, pendingRemoval);
|
|
2228
|
+
}
|
|
2229
|
+
let didChangePositions = false;
|
|
1704
2230
|
for (let i = 0; i < numContainers; i++) {
|
|
1705
2231
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1706
2232
|
if (pendingRemoval.includes(i)) {
|
|
1707
2233
|
if (itemKey) {
|
|
1708
2234
|
containerItemKeys.delete(itemKey);
|
|
1709
2235
|
}
|
|
2236
|
+
state.containerItemTypes.delete(i);
|
|
2237
|
+
if (state.stickyContainerPool.has(i)) {
|
|
2238
|
+
set$(ctx, `containerSticky${i}`, false);
|
|
2239
|
+
set$(ctx, `containerStickyOffset${i}`, void 0);
|
|
2240
|
+
state.stickyContainerPool.delete(i);
|
|
2241
|
+
}
|
|
1710
2242
|
set$(ctx, `containerItemKey${i}`, void 0);
|
|
1711
2243
|
set$(ctx, `containerItemData${i}`, void 0);
|
|
1712
2244
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
@@ -1726,58 +2258,75 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
1726
2258
|
const prevData = peek$(ctx, `containerItemData${i}`);
|
|
1727
2259
|
if (position > POSITION_OUT_OF_VIEW && position !== prevPos) {
|
|
1728
2260
|
set$(ctx, `containerPosition${i}`, position);
|
|
2261
|
+
didChangePositions = true;
|
|
1729
2262
|
}
|
|
1730
2263
|
if (column >= 0 && column !== prevColumn) {
|
|
1731
2264
|
set$(ctx, `containerColumn${i}`, column);
|
|
1732
2265
|
}
|
|
1733
|
-
if (prevData !== item) {
|
|
2266
|
+
if (prevData !== item && (itemsAreEqual ? !itemsAreEqual(prevData, item, itemIndex, data) : true)) {
|
|
1734
2267
|
set$(ctx, `containerItemData${i}`, data[itemIndex]);
|
|
1735
2268
|
}
|
|
1736
2269
|
}
|
|
1737
2270
|
}
|
|
1738
2271
|
}
|
|
1739
2272
|
}
|
|
2273
|
+
if (didChangePositions) {
|
|
2274
|
+
set$(ctx, "lastPositionUpdate", Date.now());
|
|
2275
|
+
}
|
|
1740
2276
|
if (!queuedInitialLayout && endBuffered !== null) {
|
|
1741
2277
|
if (checkAllSizesKnown(state)) {
|
|
1742
2278
|
setDidLayout(ctx, state);
|
|
1743
2279
|
}
|
|
1744
2280
|
}
|
|
1745
|
-
if (
|
|
1746
|
-
updateViewableItems(
|
|
1747
|
-
state,
|
|
1748
|
-
ctx,
|
|
1749
|
-
state.viewabilityConfigCallbackPairs,
|
|
1750
|
-
scrollLength,
|
|
1751
|
-
startNoBuffer,
|
|
1752
|
-
endNoBuffer
|
|
1753
|
-
);
|
|
2281
|
+
if (viewabilityConfigCallbackPairs) {
|
|
2282
|
+
updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollLength, startNoBuffer, endNoBuffer);
|
|
1754
2283
|
}
|
|
1755
2284
|
});
|
|
1756
2285
|
}
|
|
1757
2286
|
|
|
1758
2287
|
// src/core/doInitialAllocateContainers.ts
|
|
1759
2288
|
function doInitialAllocateContainers(ctx, state) {
|
|
1760
|
-
|
|
1761
|
-
const
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
2289
|
+
var _a;
|
|
2290
|
+
const {
|
|
2291
|
+
scrollLength,
|
|
2292
|
+
props: {
|
|
2293
|
+
data,
|
|
2294
|
+
getEstimatedItemSize,
|
|
2295
|
+
getFixedItemSize,
|
|
2296
|
+
getItemType,
|
|
2297
|
+
scrollBuffer,
|
|
2298
|
+
numColumns,
|
|
2299
|
+
estimatedItemSize
|
|
2300
|
+
}
|
|
2301
|
+
} = state;
|
|
2302
|
+
const hasContainers = peek$(ctx, "numContainers");
|
|
2303
|
+
if (scrollLength > 0 && data.length > 0 && !hasContainers) {
|
|
2304
|
+
let averageItemSize;
|
|
2305
|
+
const fn = getFixedItemSize || getEstimatedItemSize;
|
|
2306
|
+
if (fn) {
|
|
2307
|
+
let totalSize = 0;
|
|
2308
|
+
const num = Math.min(20, data.length);
|
|
2309
|
+
for (let i = 0; i < num; i++) {
|
|
2310
|
+
totalSize += fn(0, data[0], getItemType ? (_a = getItemType(data[0], 0)) != null ? _a : "" : "");
|
|
2311
|
+
}
|
|
2312
|
+
averageItemSize = totalSize / num;
|
|
2313
|
+
} else {
|
|
2314
|
+
averageItemSize = estimatedItemSize;
|
|
2315
|
+
}
|
|
2316
|
+
const numContainers = Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize * numColumns);
|
|
1768
2317
|
for (let i = 0; i < numContainers; i++) {
|
|
1769
2318
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
1770
2319
|
set$(ctx, `containerColumn${i}`, -1);
|
|
1771
2320
|
}
|
|
1772
2321
|
set$(ctx, "numContainers", numContainers);
|
|
1773
2322
|
set$(ctx, "numContainersPooled", numContainers * state.props.initialContainerPoolRatio);
|
|
1774
|
-
if (
|
|
2323
|
+
if (state.lastLayout) {
|
|
1775
2324
|
if (state.props.initialScroll) {
|
|
1776
2325
|
requestAnimationFrame(() => {
|
|
1777
|
-
calculateItemsInView(ctx, state);
|
|
2326
|
+
calculateItemsInView(ctx, state, { dataChanged: true });
|
|
1778
2327
|
});
|
|
1779
2328
|
} else {
|
|
1780
|
-
calculateItemsInView(ctx, state);
|
|
2329
|
+
calculateItemsInView(ctx, state, { dataChanged: true });
|
|
1781
2330
|
}
|
|
1782
2331
|
}
|
|
1783
2332
|
return true;
|
|
@@ -1797,16 +2346,18 @@ function doMaintainScrollAtEnd(ctx, state, animated) {
|
|
|
1797
2346
|
}
|
|
1798
2347
|
requestAnimationFrame(() => {
|
|
1799
2348
|
var _a;
|
|
1800
|
-
state.
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
(
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
2349
|
+
if (state == null ? void 0 : state.isAtEnd) {
|
|
2350
|
+
state.maintainingScrollAtEnd = true;
|
|
2351
|
+
(_a = refScroller.current) == null ? void 0 : _a.scrollToEnd({
|
|
2352
|
+
animated
|
|
2353
|
+
});
|
|
2354
|
+
setTimeout(
|
|
2355
|
+
() => {
|
|
2356
|
+
state.maintainingScrollAtEnd = false;
|
|
2357
|
+
},
|
|
2358
|
+
0
|
|
2359
|
+
);
|
|
2360
|
+
}
|
|
1810
2361
|
});
|
|
1811
2362
|
return true;
|
|
1812
2363
|
}
|
|
@@ -1843,44 +2394,57 @@ function checkAtTop(state) {
|
|
|
1843
2394
|
// src/core/handleLayout.ts
|
|
1844
2395
|
function handleLayout(ctx, state, layout, setCanRender) {
|
|
1845
2396
|
const { maintainScrollAtEnd } = state.props;
|
|
1846
|
-
const
|
|
2397
|
+
const measuredLength = layout[state.props.horizontal ? "width" : "height"];
|
|
2398
|
+
const previousLength = state.scrollLength;
|
|
2399
|
+
const scrollLength = measuredLength > 0 ? measuredLength : previousLength;
|
|
1847
2400
|
const otherAxisSize = layout[state.props.horizontal ? "height" : "width"];
|
|
1848
2401
|
const needsCalculate = !state.lastLayout || scrollLength > state.scrollLength || state.lastLayout.x !== layout.x || state.lastLayout.y !== layout.y;
|
|
1849
2402
|
state.lastLayout = layout;
|
|
1850
|
-
const didChange = scrollLength !== state.scrollLength;
|
|
1851
2403
|
const prevOtherAxisSize = state.otherAxisSize;
|
|
1852
|
-
state.scrollLength
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
)
|
|
2404
|
+
const didChange = scrollLength !== state.scrollLength || otherAxisSize !== prevOtherAxisSize;
|
|
2405
|
+
if (didChange) {
|
|
2406
|
+
state.scrollLength = scrollLength;
|
|
2407
|
+
state.otherAxisSize = otherAxisSize;
|
|
2408
|
+
state.lastBatchingAction = Date.now();
|
|
2409
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
2410
|
+
if (scrollLength > 0) {
|
|
2411
|
+
doInitialAllocateContainers(ctx, state);
|
|
2412
|
+
}
|
|
2413
|
+
if (needsCalculate) {
|
|
2414
|
+
calculateItemsInView(ctx, state, { doMVCP: true });
|
|
2415
|
+
}
|
|
2416
|
+
if (didChange || otherAxisSize !== prevOtherAxisSize) {
|
|
2417
|
+
set$(ctx, "scrollSize", { height: layout.height, width: layout.width });
|
|
2418
|
+
}
|
|
2419
|
+
if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
|
|
2420
|
+
doMaintainScrollAtEnd(ctx, state, false);
|
|
2421
|
+
}
|
|
2422
|
+
updateAlignItemsPaddingTop(ctx, state);
|
|
2423
|
+
checkAtBottom(ctx, state);
|
|
2424
|
+
checkAtTop(state);
|
|
2425
|
+
if (state) {
|
|
2426
|
+
state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
|
|
2427
|
+
}
|
|
2428
|
+
if (__DEV__ && measuredLength === 0) {
|
|
2429
|
+
warnDevOnce(
|
|
2430
|
+
"height0",
|
|
2431
|
+
`List ${state.props.horizontal ? "width" : "height"} is 0. You may need to set a style or \`flex: \` for the list, because children are absolutely positioned.`
|
|
2432
|
+
);
|
|
2433
|
+
}
|
|
2434
|
+
setCanRender(true);
|
|
1877
2435
|
}
|
|
1878
|
-
setCanRender(true);
|
|
1879
2436
|
}
|
|
1880
2437
|
|
|
1881
2438
|
// src/core/onScroll.ts
|
|
1882
2439
|
function onScroll(ctx, state, event) {
|
|
1883
|
-
var _a, _b, _c
|
|
2440
|
+
var _a, _b, _c;
|
|
2441
|
+
const {
|
|
2442
|
+
scrollProcessingEnabled,
|
|
2443
|
+
props: { onScroll: onScrollProp }
|
|
2444
|
+
} = state;
|
|
2445
|
+
if (scrollProcessingEnabled === false) {
|
|
2446
|
+
return;
|
|
2447
|
+
}
|
|
1884
2448
|
if (((_b = (_a = event.nativeEvent) == null ? void 0 : _a.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
|
|
1885
2449
|
return;
|
|
1886
2450
|
}
|
|
@@ -1893,16 +2457,25 @@ function onScroll(ctx, state, event) {
|
|
|
1893
2457
|
}
|
|
1894
2458
|
}
|
|
1895
2459
|
state.scrollPending = newScroll;
|
|
1896
|
-
|
|
1897
|
-
|
|
2460
|
+
{
|
|
2461
|
+
if (!state.onScrollRafScheduled) {
|
|
2462
|
+
state.onScrollRafScheduled = true;
|
|
2463
|
+
requestAnimationFrame(() => {
|
|
2464
|
+
state.onScrollRafScheduled = false;
|
|
2465
|
+
updateScroll(ctx, state, newScroll);
|
|
2466
|
+
});
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2469
|
+
onScrollProp == null ? void 0 : onScrollProp(event);
|
|
1898
2470
|
}
|
|
1899
2471
|
function updateScroll(ctx, state, newScroll) {
|
|
1900
2472
|
const scrollingTo = state.scrollingTo;
|
|
1901
2473
|
state.hasScrolled = true;
|
|
1902
2474
|
state.lastBatchingAction = Date.now();
|
|
1903
|
-
const currentTime =
|
|
2475
|
+
const currentTime = Date.now();
|
|
1904
2476
|
if (scrollingTo === void 0 && !(state.scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
1905
|
-
state.
|
|
2477
|
+
const adjust = state.scrollAdjustHandler.getAdjust();
|
|
2478
|
+
state.scrollHistory.push({ scroll: newScroll - adjust, time: currentTime });
|
|
1906
2479
|
}
|
|
1907
2480
|
if (state.scrollHistory.length > 5) {
|
|
1908
2481
|
state.scrollHistory.shift();
|
|
@@ -1911,9 +2484,11 @@ function updateScroll(ctx, state, newScroll) {
|
|
|
1911
2484
|
state.scrollPrevTime = state.scrollTime;
|
|
1912
2485
|
state.scroll = newScroll;
|
|
1913
2486
|
state.scrollTime = currentTime;
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
2487
|
+
if (Math.abs(state.scroll - state.scrollPrev) > 2) {
|
|
2488
|
+
calculateItemsInView(ctx, state);
|
|
2489
|
+
checkAtBottom(ctx, state);
|
|
2490
|
+
checkAtTop(state);
|
|
2491
|
+
}
|
|
1917
2492
|
}
|
|
1918
2493
|
|
|
1919
2494
|
// src/core/ScrollAdjustHandler.ts
|
|
@@ -1936,13 +2511,19 @@ var ScrollAdjustHandler = class {
|
|
|
1936
2511
|
setMounted() {
|
|
1937
2512
|
this.mounted = true;
|
|
1938
2513
|
}
|
|
2514
|
+
getAdjust() {
|
|
2515
|
+
return this.appliedAdjust;
|
|
2516
|
+
}
|
|
1939
2517
|
};
|
|
1940
2518
|
|
|
1941
2519
|
// src/core/updateItemSize.ts
|
|
1942
|
-
function
|
|
1943
|
-
var _a;
|
|
2520
|
+
function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
2521
|
+
var _a, _b;
|
|
1944
2522
|
const {
|
|
2523
|
+
sizesKnown,
|
|
1945
2524
|
props: {
|
|
2525
|
+
getFixedItemSize,
|
|
2526
|
+
getItemType,
|
|
1946
2527
|
horizontal,
|
|
1947
2528
|
maintainVisibleContentPosition,
|
|
1948
2529
|
suggestEstimatedItemSize,
|
|
@@ -1952,47 +2533,60 @@ function updateItemSizes(ctx, state, itemUpdates) {
|
|
|
1952
2533
|
}
|
|
1953
2534
|
} = state;
|
|
1954
2535
|
if (!data) return;
|
|
2536
|
+
if (getFixedItemSize) {
|
|
2537
|
+
const index2 = state.indexByKey.get(itemKey);
|
|
2538
|
+
if (index2 === void 0) {
|
|
2539
|
+
return;
|
|
2540
|
+
}
|
|
2541
|
+
const itemData = state.props.data[index2];
|
|
2542
|
+
if (itemData === void 0) {
|
|
2543
|
+
return;
|
|
2544
|
+
}
|
|
2545
|
+
const type = getItemType ? (_a = getItemType(itemData, index2)) != null ? _a : "" : "";
|
|
2546
|
+
const size2 = getFixedItemSize(index2, itemData, type);
|
|
2547
|
+
if (size2 !== void 0 && size2 === sizesKnown.get(itemKey)) {
|
|
2548
|
+
return;
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
1955
2551
|
const containersDidLayout = peek$(ctx, "containersDidLayout");
|
|
1956
2552
|
let needsRecalculate = !containersDidLayout;
|
|
1957
2553
|
let shouldMaintainScrollAtEnd = false;
|
|
1958
2554
|
let minIndexSizeChanged;
|
|
1959
2555
|
let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
break;
|
|
1978
|
-
}
|
|
2556
|
+
const index = state.indexByKey.get(itemKey);
|
|
2557
|
+
const prevSizeKnown = state.sizesKnown.get(itemKey);
|
|
2558
|
+
const diff = updateOneItemSize(state, itemKey, sizeObj);
|
|
2559
|
+
const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
|
|
2560
|
+
if (diff !== 0) {
|
|
2561
|
+
minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
|
|
2562
|
+
if (((_b = state.scrollingTo) == null ? void 0 : _b.viewPosition) && maintainVisibleContentPosition && index === state.scrollingTo.index && diff > 0) {
|
|
2563
|
+
requestAdjust(ctx, state, diff * state.scrollingTo.viewPosition);
|
|
2564
|
+
}
|
|
2565
|
+
const { startBuffered, endBuffered } = state;
|
|
2566
|
+
needsRecalculate || (needsRecalculate = index >= startBuffered && index <= endBuffered);
|
|
2567
|
+
if (!needsRecalculate) {
|
|
2568
|
+
const numContainers = ctx.values.get("numContainers");
|
|
2569
|
+
for (let i = 0; i < numContainers; i++) {
|
|
2570
|
+
if (peek$(ctx, `containerItemKey${i}`) === itemKey) {
|
|
2571
|
+
needsRecalculate = true;
|
|
2572
|
+
break;
|
|
1979
2573
|
}
|
|
1980
2574
|
}
|
|
1981
|
-
if (state.needsOtherAxisSize) {
|
|
1982
|
-
const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
|
|
1983
|
-
maxOtherAxisSize = Math.max(maxOtherAxisSize, otherAxisSize);
|
|
1984
|
-
}
|
|
1985
|
-
if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
|
|
1986
|
-
shouldMaintainScrollAtEnd = true;
|
|
1987
|
-
}
|
|
1988
|
-
onItemSizeChanged == null ? void 0 : onItemSizeChanged({
|
|
1989
|
-
index,
|
|
1990
|
-
itemData: state.props.data[index],
|
|
1991
|
-
itemKey,
|
|
1992
|
-
previous: size - diff,
|
|
1993
|
-
size
|
|
1994
|
-
});
|
|
1995
2575
|
}
|
|
2576
|
+
if (state.needsOtherAxisSize) {
|
|
2577
|
+
const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
|
|
2578
|
+
maxOtherAxisSize = Math.max(maxOtherAxisSize, otherAxisSize);
|
|
2579
|
+
}
|
|
2580
|
+
if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
|
|
2581
|
+
shouldMaintainScrollAtEnd = true;
|
|
2582
|
+
}
|
|
2583
|
+
onItemSizeChanged == null ? void 0 : onItemSizeChanged({
|
|
2584
|
+
index,
|
|
2585
|
+
itemData: state.props.data[index],
|
|
2586
|
+
itemKey,
|
|
2587
|
+
previous: size - diff,
|
|
2588
|
+
size
|
|
2589
|
+
});
|
|
1996
2590
|
}
|
|
1997
2591
|
if (minIndexSizeChanged !== void 0) {
|
|
1998
2592
|
state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, minIndexSizeChanged) : minIndexSizeChanged;
|
|
@@ -2025,43 +2619,30 @@ function updateItemSizes(ctx, state, itemUpdates) {
|
|
|
2025
2619
|
}
|
|
2026
2620
|
}
|
|
2027
2621
|
}
|
|
2028
|
-
function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
2029
|
-
const { queuedItemSizeUpdates, queuedItemSizeUpdatesWaiting } = state;
|
|
2030
|
-
const containersDidLayout = peek$(ctx, "containersDidLayout");
|
|
2031
|
-
if (!containersDidLayout || !queuedItemSizeUpdatesWaiting) {
|
|
2032
|
-
updateItemSizes(ctx, state, [{ itemKey, sizeObj }]);
|
|
2033
|
-
if (containersDidLayout) {
|
|
2034
|
-
state.queuedItemSizeUpdatesWaiting = true;
|
|
2035
|
-
requestAnimationFrame(() => {
|
|
2036
|
-
state.queuedItemSizeUpdatesWaiting = false;
|
|
2037
|
-
updateItemSizes(ctx, state, queuedItemSizeUpdates);
|
|
2038
|
-
queuedItemSizeUpdates.length = 0;
|
|
2039
|
-
});
|
|
2040
|
-
}
|
|
2041
|
-
} else {
|
|
2042
|
-
queuedItemSizeUpdates.push({ itemKey, sizeObj });
|
|
2043
|
-
}
|
|
2044
|
-
}
|
|
2045
2622
|
function updateOneItemSize(state, itemKey, sizeObj) {
|
|
2623
|
+
var _a;
|
|
2046
2624
|
const {
|
|
2047
2625
|
sizes,
|
|
2048
2626
|
indexByKey,
|
|
2049
2627
|
sizesKnown,
|
|
2050
2628
|
averageSizes,
|
|
2051
|
-
props: { data, horizontal }
|
|
2629
|
+
props: { data, horizontal, getEstimatedItemSize, getItemType, getFixedItemSize }
|
|
2052
2630
|
} = state;
|
|
2053
2631
|
if (!data) return 0;
|
|
2054
2632
|
const index = indexByKey.get(itemKey);
|
|
2055
2633
|
const prevSize = getItemSize(state, itemKey, index, data);
|
|
2056
|
-
const
|
|
2634
|
+
const rawSize = horizontal ? sizeObj.width : sizeObj.height;
|
|
2635
|
+
const size = Math.round(rawSize) ;
|
|
2057
2636
|
sizesKnown.set(itemKey, size);
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
averages
|
|
2637
|
+
if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
|
|
2638
|
+
const itemType = getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : "";
|
|
2639
|
+
let averages = averageSizes[itemType];
|
|
2640
|
+
if (!averages) {
|
|
2641
|
+
averages = averageSizes[itemType] = { avg: 0, num: 0 };
|
|
2642
|
+
}
|
|
2643
|
+
averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
|
|
2644
|
+
averages.num++;
|
|
2062
2645
|
}
|
|
2063
|
-
averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
|
|
2064
|
-
averages.num++;
|
|
2065
2646
|
if (!prevSize || Math.abs(prevSize - size) > 0.1) {
|
|
2066
2647
|
sizes.set(itemKey, size);
|
|
2067
2648
|
return size - prevSize;
|
|
@@ -2069,7 +2650,7 @@ function updateOneItemSize(state, itemKey, sizeObj) {
|
|
|
2069
2650
|
return 0;
|
|
2070
2651
|
}
|
|
2071
2652
|
var useCombinedRef = (...refs) => {
|
|
2072
|
-
const callback =
|
|
2653
|
+
const callback = React4.useCallback((element) => {
|
|
2073
2654
|
for (const ref of refs) {
|
|
2074
2655
|
if (!ref) {
|
|
2075
2656
|
continue;
|
|
@@ -2084,6 +2665,22 @@ var useCombinedRef = (...refs) => {
|
|
|
2084
2665
|
return callback;
|
|
2085
2666
|
};
|
|
2086
2667
|
|
|
2668
|
+
// src/platform/RefreshControl.tsx
|
|
2669
|
+
function RefreshControl(props) {
|
|
2670
|
+
return null;
|
|
2671
|
+
}
|
|
2672
|
+
|
|
2673
|
+
// src/platform/StyleSheet.tsx
|
|
2674
|
+
var StyleSheet = {
|
|
2675
|
+
create: (styles) => styles,
|
|
2676
|
+
flatten: (style) => style
|
|
2677
|
+
};
|
|
2678
|
+
|
|
2679
|
+
// src/platform/useStickyScrollHandler.ts
|
|
2680
|
+
function useStickyScrollHandler(stickyIndices, horizontal, ctx, onScroll2) {
|
|
2681
|
+
return onScroll2;
|
|
2682
|
+
}
|
|
2683
|
+
|
|
2087
2684
|
// src/utils/createColumnWrapperStyle.ts
|
|
2088
2685
|
function createColumnWrapperStyle(contentContainerStyle) {
|
|
2089
2686
|
const { gap, columnGap, rowGap } = contentContainerStyle;
|
|
@@ -2099,162 +2696,290 @@ function createColumnWrapperStyle(contentContainerStyle) {
|
|
|
2099
2696
|
}
|
|
2100
2697
|
}
|
|
2101
2698
|
function getRenderedItem(ctx, state, key) {
|
|
2699
|
+
var _a;
|
|
2102
2700
|
if (!state) {
|
|
2103
2701
|
return null;
|
|
2104
2702
|
}
|
|
2105
2703
|
const {
|
|
2106
2704
|
indexByKey,
|
|
2107
|
-
props: { data, renderItem
|
|
2705
|
+
props: { data, getItemType, renderItem }
|
|
2108
2706
|
} = state;
|
|
2109
2707
|
const index = indexByKey.get(key);
|
|
2110
2708
|
if (index === void 0) {
|
|
2111
2709
|
return null;
|
|
2112
2710
|
}
|
|
2113
2711
|
let renderedItem = null;
|
|
2114
|
-
if (
|
|
2712
|
+
if (renderItem && data[index]) {
|
|
2115
2713
|
const itemProps = {
|
|
2714
|
+
data,
|
|
2116
2715
|
extraData: peek$(ctx, "extraData"),
|
|
2117
2716
|
index,
|
|
2118
|
-
item: data[index]
|
|
2717
|
+
item: data[index],
|
|
2718
|
+
type: getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : ""
|
|
2119
2719
|
};
|
|
2120
|
-
renderedItem =
|
|
2720
|
+
renderedItem = isFunction(renderItem) ? renderItem(itemProps) : React4__namespace.default.createElement(renderItem, itemProps);
|
|
2121
2721
|
}
|
|
2122
2722
|
return { index, item: data[index], renderedItem };
|
|
2123
2723
|
}
|
|
2724
|
+
function useThrottleDebounce(mode) {
|
|
2725
|
+
const timeoutRef = React4.useRef(null);
|
|
2726
|
+
const lastCallTimeRef = React4.useRef(0);
|
|
2727
|
+
const lastArgsRef = React4.useRef(null);
|
|
2728
|
+
const clearTimeoutRef = () => {
|
|
2729
|
+
if (timeoutRef.current) {
|
|
2730
|
+
clearTimeout(timeoutRef.current);
|
|
2731
|
+
timeoutRef.current = null;
|
|
2732
|
+
}
|
|
2733
|
+
};
|
|
2734
|
+
const execute = React4.useCallback(
|
|
2735
|
+
(callback, delay, ...args) => {
|
|
2736
|
+
{
|
|
2737
|
+
const now = Date.now();
|
|
2738
|
+
lastArgsRef.current = args;
|
|
2739
|
+
if (now - lastCallTimeRef.current >= delay) {
|
|
2740
|
+
lastCallTimeRef.current = now;
|
|
2741
|
+
callback(...args);
|
|
2742
|
+
clearTimeoutRef();
|
|
2743
|
+
} else {
|
|
2744
|
+
clearTimeoutRef();
|
|
2745
|
+
timeoutRef.current = setTimeout(
|
|
2746
|
+
() => {
|
|
2747
|
+
if (lastArgsRef.current) {
|
|
2748
|
+
lastCallTimeRef.current = Date.now();
|
|
2749
|
+
callback(...lastArgsRef.current);
|
|
2750
|
+
timeoutRef.current = null;
|
|
2751
|
+
lastArgsRef.current = null;
|
|
2752
|
+
}
|
|
2753
|
+
},
|
|
2754
|
+
delay - (now - lastCallTimeRef.current)
|
|
2755
|
+
);
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2758
|
+
},
|
|
2759
|
+
[mode]
|
|
2760
|
+
);
|
|
2761
|
+
return execute;
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2764
|
+
// src/utils/throttledOnScroll.ts
|
|
2765
|
+
function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
|
|
2766
|
+
const throttle = useThrottleDebounce("throttle");
|
|
2767
|
+
return (event) => throttle(originalHandler, scrollEventThrottle, { nativeEvent: event.nativeEvent });
|
|
2768
|
+
}
|
|
2769
|
+
|
|
2770
|
+
// src/utils/updateAveragesOnDataChange.ts
|
|
2771
|
+
function updateAveragesOnDataChange(state, oldData, newData) {
|
|
2772
|
+
var _a;
|
|
2773
|
+
const {
|
|
2774
|
+
averageSizes,
|
|
2775
|
+
sizesKnown,
|
|
2776
|
+
indexByKey,
|
|
2777
|
+
props: { itemsAreEqual, getItemType, keyExtractor }
|
|
2778
|
+
} = state;
|
|
2779
|
+
if (!itemsAreEqual || !oldData.length || !newData.length) {
|
|
2780
|
+
for (const key in averageSizes) {
|
|
2781
|
+
delete averageSizes[key];
|
|
2782
|
+
}
|
|
2783
|
+
return;
|
|
2784
|
+
}
|
|
2785
|
+
const itemTypesToPreserve = {};
|
|
2786
|
+
const newDataLength = newData.length;
|
|
2787
|
+
const oldDataLength = oldData.length;
|
|
2788
|
+
for (let newIndex = 0; newIndex < newDataLength; newIndex++) {
|
|
2789
|
+
const newItem = newData[newIndex];
|
|
2790
|
+
const id = keyExtractor ? keyExtractor(newItem, newIndex) : String(newIndex);
|
|
2791
|
+
const oldIndex = indexByKey.get(id);
|
|
2792
|
+
if (oldIndex !== void 0 && oldIndex < oldDataLength) {
|
|
2793
|
+
const knownSize = sizesKnown.get(id);
|
|
2794
|
+
if (knownSize === void 0) continue;
|
|
2795
|
+
const oldItem = oldData[oldIndex];
|
|
2796
|
+
const areEqual = itemsAreEqual(oldItem, newItem, newIndex, newData);
|
|
2797
|
+
if (areEqual) {
|
|
2798
|
+
const itemType = getItemType ? (_a = getItemType(newItem, newIndex)) != null ? _a : "" : "";
|
|
2799
|
+
let typeData = itemTypesToPreserve[itemType];
|
|
2800
|
+
if (!typeData) {
|
|
2801
|
+
typeData = itemTypesToPreserve[itemType] = { count: 0, totalSize: 0 };
|
|
2802
|
+
}
|
|
2803
|
+
typeData.totalSize += knownSize;
|
|
2804
|
+
typeData.count++;
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
for (const key in averageSizes) {
|
|
2809
|
+
delete averageSizes[key];
|
|
2810
|
+
}
|
|
2811
|
+
for (const itemType in itemTypesToPreserve) {
|
|
2812
|
+
const { totalSize, count } = itemTypesToPreserve[itemType];
|
|
2813
|
+
if (count > 0) {
|
|
2814
|
+
averageSizes[itemType] = {
|
|
2815
|
+
avg: totalSize / count,
|
|
2816
|
+
num: count
|
|
2817
|
+
};
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2124
2821
|
|
|
2125
2822
|
// src/components/LegendList.tsx
|
|
2126
2823
|
var DEFAULT_DRAW_DISTANCE = 250;
|
|
2127
2824
|
var DEFAULT_ITEM_SIZE = 100;
|
|
2128
|
-
var LegendList =
|
|
2129
|
-
|
|
2130
|
-
}
|
|
2825
|
+
var LegendList = typedMemo(
|
|
2826
|
+
typedForwardRef(function LegendList2(props, forwardedRef) {
|
|
2827
|
+
const { children, data: dataProp, renderItem: renderItemProp, ...restProps } = props;
|
|
2828
|
+
const isChildrenMode = children !== void 0 && dataProp === void 0;
|
|
2829
|
+
const processedProps = isChildrenMode ? {
|
|
2830
|
+
...restProps,
|
|
2831
|
+
data: (isArray(children) ? children : React4__namespace.Children.toArray(children)).flat(1),
|
|
2832
|
+
renderItem: ({ item }) => item
|
|
2833
|
+
} : {
|
|
2834
|
+
...restProps,
|
|
2835
|
+
data: dataProp || [],
|
|
2836
|
+
renderItem: renderItemProp
|
|
2837
|
+
};
|
|
2838
|
+
return /* @__PURE__ */ React4__namespace.createElement(StateProvider, null, /* @__PURE__ */ React4__namespace.createElement(LegendListInner, { ...processedProps, ref: forwardedRef }));
|
|
2839
|
+
})
|
|
2840
|
+
);
|
|
2131
2841
|
var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
|
|
2132
|
-
var _a;
|
|
2133
2842
|
const {
|
|
2134
|
-
data: dataProp = [],
|
|
2135
|
-
initialScrollIndex: initialScrollIndexProp,
|
|
2136
|
-
initialScrollOffset,
|
|
2137
|
-
horizontal,
|
|
2138
|
-
drawDistance = 250,
|
|
2139
|
-
recycleItems = false,
|
|
2140
|
-
onEndReachedThreshold = 0.5,
|
|
2141
|
-
onStartReachedThreshold = 0.5,
|
|
2142
|
-
maintainScrollAtEnd = false,
|
|
2143
|
-
maintainScrollAtEndThreshold = 0.1,
|
|
2144
2843
|
alignItemsAtEnd = false,
|
|
2145
|
-
maintainVisibleContentPosition = false,
|
|
2146
|
-
onScroll: onScrollProp,
|
|
2147
|
-
onMomentumScrollEnd,
|
|
2148
|
-
numColumns: numColumnsProp = 1,
|
|
2149
2844
|
columnWrapperStyle,
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2845
|
+
contentContainerStyle: contentContainerStyleProp,
|
|
2846
|
+
data: dataProp = [],
|
|
2847
|
+
drawDistance = 250,
|
|
2848
|
+
enableAverages = true,
|
|
2153
2849
|
estimatedItemSize: estimatedItemSizeProp,
|
|
2850
|
+
estimatedListSize,
|
|
2851
|
+
extraData,
|
|
2154
2852
|
getEstimatedItemSize,
|
|
2155
|
-
|
|
2156
|
-
|
|
2853
|
+
getFixedItemSize,
|
|
2854
|
+
getItemType,
|
|
2855
|
+
horizontal,
|
|
2856
|
+
initialContainerPoolRatio = 2,
|
|
2857
|
+
initialScrollIndex: initialScrollIndexProp,
|
|
2858
|
+
initialScrollOffset: initialScrollOffsetProp,
|
|
2859
|
+
itemsAreEqual,
|
|
2860
|
+
keyExtractor: keyExtractorProp,
|
|
2157
2861
|
ListEmptyComponent,
|
|
2862
|
+
ListHeaderComponent,
|
|
2863
|
+
maintainScrollAtEnd = false,
|
|
2864
|
+
maintainScrollAtEndThreshold = 0.1,
|
|
2865
|
+
maintainVisibleContentPosition = true,
|
|
2866
|
+
numColumns: numColumnsProp = 1,
|
|
2867
|
+
onEndReached,
|
|
2868
|
+
onEndReachedThreshold = 0.5,
|
|
2158
2869
|
onItemSizeChanged,
|
|
2159
|
-
refScrollView,
|
|
2160
|
-
waitForInitialLayout = true,
|
|
2161
|
-
extraData,
|
|
2162
|
-
contentContainerStyle: contentContainerStyleProp,
|
|
2163
|
-
style: styleProp,
|
|
2164
2870
|
onLayout: onLayoutProp,
|
|
2871
|
+
onLoad,
|
|
2872
|
+
onMomentumScrollEnd,
|
|
2165
2873
|
onRefresh,
|
|
2166
|
-
|
|
2874
|
+
onScroll: onScrollProp,
|
|
2875
|
+
onStartReached,
|
|
2876
|
+
onStartReachedThreshold = 0.5,
|
|
2167
2877
|
progressViewOffset,
|
|
2878
|
+
recycleItems = false,
|
|
2168
2879
|
refreshControl,
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2880
|
+
refreshing,
|
|
2881
|
+
refScrollView,
|
|
2882
|
+
renderItem,
|
|
2883
|
+
scrollEventThrottle,
|
|
2172
2884
|
snapToIndices,
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2885
|
+
stickyIndices,
|
|
2886
|
+
style: styleProp,
|
|
2887
|
+
suggestEstimatedItemSize,
|
|
2888
|
+
waitForInitialLayout = true,
|
|
2177
2889
|
...rest
|
|
2178
2890
|
} = props;
|
|
2179
|
-
const [renderNum, setRenderNum] =
|
|
2180
|
-
const initialScroll = typeof initialScrollIndexProp === "
|
|
2181
|
-
const
|
|
2182
|
-
const
|
|
2183
|
-
const
|
|
2184
|
-
const style = { ...reactNative.StyleSheet.flatten(styleProp) };
|
|
2891
|
+
const [renderNum, setRenderNum] = React4.useState(0);
|
|
2892
|
+
const initialScroll = initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
|
|
2893
|
+
const [canRender, setCanRender] = React4__namespace.useState(!IsNewArchitecture);
|
|
2894
|
+
const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
|
|
2895
|
+
const style = { ...StyleSheet.flatten(styleProp) };
|
|
2185
2896
|
const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
|
|
2186
2897
|
const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
|
|
2187
2898
|
const ctx = useStateContext();
|
|
2188
2899
|
ctx.columnWrapperStyle = columnWrapperStyle || (contentContainerStyle ? createColumnWrapperStyle(contentContainerStyle) : void 0);
|
|
2189
|
-
const refScroller =
|
|
2900
|
+
const refScroller = React4.useRef(null);
|
|
2190
2901
|
const combinedRef = useCombinedRef(refScroller, refScrollView);
|
|
2191
2902
|
const estimatedItemSize = estimatedItemSizeProp != null ? estimatedItemSizeProp : DEFAULT_ITEM_SIZE;
|
|
2192
2903
|
const scrollBuffer = (drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE) || 1;
|
|
2193
2904
|
const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (_item, index) => index.toString();
|
|
2194
|
-
const refState =
|
|
2905
|
+
const refState = React4.useRef();
|
|
2195
2906
|
if (!refState.current) {
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2907
|
+
if (!ctx.internalState) {
|
|
2908
|
+
const initialScrollLength = (estimatedListSize != null ? estimatedListSize : { height: 0, width: 0 } )[horizontal ? "width" : "height"];
|
|
2909
|
+
ctx.internalState = {
|
|
2910
|
+
activeStickyIndex: void 0,
|
|
2911
|
+
averageSizes: {},
|
|
2912
|
+
columns: /* @__PURE__ */ new Map(),
|
|
2913
|
+
containerItemKeys: /* @__PURE__ */ new Set(),
|
|
2914
|
+
containerItemTypes: /* @__PURE__ */ new Map(),
|
|
2915
|
+
enableScrollForNextCalculateItemsInView: true,
|
|
2916
|
+
endBuffered: -1,
|
|
2917
|
+
endNoBuffer: -1,
|
|
2918
|
+
endReachedBlockedByTimer: false,
|
|
2919
|
+
firstFullyOnScreenIndex: -1,
|
|
2920
|
+
idCache: /* @__PURE__ */ new Map(),
|
|
2921
|
+
idsInView: [],
|
|
2922
|
+
indexByKey: /* @__PURE__ */ new Map(),
|
|
2923
|
+
initialScroll,
|
|
2924
|
+
isAtEnd: false,
|
|
2925
|
+
isAtStart: false,
|
|
2926
|
+
isEndReached: false,
|
|
2927
|
+
isStartReached: false,
|
|
2928
|
+
lastBatchingAction: Date.now(),
|
|
2929
|
+
lastLayout: void 0,
|
|
2930
|
+
loadStartTime: Date.now(),
|
|
2931
|
+
minIndexSizeChanged: 0,
|
|
2932
|
+
nativeMarginTop: 0,
|
|
2933
|
+
positions: /* @__PURE__ */ new Map(),
|
|
2934
|
+
props: {},
|
|
2935
|
+
queuedCalculateItemsInView: 0,
|
|
2936
|
+
refScroller: void 0,
|
|
2937
|
+
scroll: 0,
|
|
2938
|
+
scrollAdjustHandler: new ScrollAdjustHandler(ctx),
|
|
2939
|
+
scrollForNextCalculateItemsInView: void 0,
|
|
2940
|
+
scrollHistory: [],
|
|
2941
|
+
scrollLength: initialScrollLength,
|
|
2942
|
+
scrollPending: 0,
|
|
2943
|
+
scrollPrev: 0,
|
|
2944
|
+
scrollPrevTime: 0,
|
|
2945
|
+
scrollProcessingEnabled: true,
|
|
2946
|
+
scrollTime: 0,
|
|
2947
|
+
sizes: /* @__PURE__ */ new Map(),
|
|
2948
|
+
sizesKnown: /* @__PURE__ */ new Map(),
|
|
2949
|
+
startBuffered: -1,
|
|
2950
|
+
startNoBuffer: -1,
|
|
2951
|
+
startReachedBlockedByTimer: false,
|
|
2952
|
+
stickyContainerPool: /* @__PURE__ */ new Set(),
|
|
2953
|
+
stickyContainers: /* @__PURE__ */ new Map(),
|
|
2954
|
+
timeoutSizeMessage: 0,
|
|
2955
|
+
timeouts: /* @__PURE__ */ new Set(),
|
|
2956
|
+
totalSize: 0,
|
|
2957
|
+
viewabilityConfigCallbackPairs: void 0
|
|
2958
|
+
};
|
|
2959
|
+
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
|
|
2960
|
+
set$(ctx, "extraData", extraData);
|
|
2961
|
+
}
|
|
2962
|
+
refState.current = ctx.internalState;
|
|
2246
2963
|
}
|
|
2247
2964
|
const state = refState.current;
|
|
2248
2965
|
const isFirst = !state.props.renderItem;
|
|
2249
2966
|
const didDataChange = state.props.data !== dataProp;
|
|
2967
|
+
const throttleScrollFn = (
|
|
2968
|
+
// @ts-expect-error TODO Fix this
|
|
2969
|
+
scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp
|
|
2970
|
+
);
|
|
2250
2971
|
state.props = {
|
|
2251
2972
|
alignItemsAtEnd,
|
|
2252
2973
|
data: dataProp,
|
|
2974
|
+
enableAverages,
|
|
2253
2975
|
estimatedItemSize,
|
|
2254
2976
|
getEstimatedItemSize,
|
|
2977
|
+
getFixedItemSize,
|
|
2978
|
+
getItemType,
|
|
2255
2979
|
horizontal: !!horizontal,
|
|
2256
2980
|
initialContainerPoolRatio,
|
|
2257
2981
|
initialScroll,
|
|
2982
|
+
itemsAreEqual,
|
|
2258
2983
|
keyExtractor,
|
|
2259
2984
|
maintainScrollAtEnd,
|
|
2260
2985
|
maintainScrollAtEndThreshold,
|
|
@@ -2264,12 +2989,15 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2264
2989
|
onEndReachedThreshold,
|
|
2265
2990
|
onItemSizeChanged,
|
|
2266
2991
|
onLoad,
|
|
2267
|
-
onScroll:
|
|
2992
|
+
onScroll: throttleScrollFn,
|
|
2268
2993
|
onStartReached,
|
|
2269
2994
|
onStartReachedThreshold,
|
|
2270
|
-
|
|
2995
|
+
recycleItems: !!recycleItems,
|
|
2996
|
+
renderItem,
|
|
2271
2997
|
scrollBuffer,
|
|
2272
2998
|
snapToIndices,
|
|
2999
|
+
stickyIndicesArr: stickyIndices != null ? stickyIndices : [],
|
|
3000
|
+
stickyIndicesSet: React4.useMemo(() => new Set(stickyIndices != null ? stickyIndices : []), [stickyIndices == null ? void 0 : stickyIndices.join(",")]),
|
|
2273
3001
|
stylePaddingBottom: stylePaddingBottomState,
|
|
2274
3002
|
stylePaddingTop: stylePaddingTopState,
|
|
2275
3003
|
suggestEstimatedItemSize: !!suggestEstimatedItemSize
|
|
@@ -2278,6 +3006,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2278
3006
|
const checkResetContainers = (isFirst2) => {
|
|
2279
3007
|
const state2 = refState.current;
|
|
2280
3008
|
if (state2) {
|
|
3009
|
+
if (!isFirst2 && state2.props.data !== dataProp) {
|
|
3010
|
+
updateAveragesOnDataChange(state2, state2.props.data, dataProp);
|
|
3011
|
+
}
|
|
2281
3012
|
state2.props.data = dataProp;
|
|
2282
3013
|
if (!isFirst2) {
|
|
2283
3014
|
calculateItemsInView(ctx, state2, { dataChanged: true, doMVCP: true });
|
|
@@ -2293,7 +3024,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2293
3024
|
}
|
|
2294
3025
|
}
|
|
2295
3026
|
};
|
|
2296
|
-
const memoizedLastItemKeys =
|
|
3027
|
+
const memoizedLastItemKeys = React4.useMemo(() => {
|
|
2297
3028
|
if (!dataProp.length) return [];
|
|
2298
3029
|
return Array.from(
|
|
2299
3030
|
{ length: Math.min(numColumnsProp, dataProp.length) },
|
|
@@ -2307,7 +3038,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2307
3038
|
setPaddingTop(ctx, state, { stylePaddingTop: stylePaddingTopState });
|
|
2308
3039
|
refState.current.props.stylePaddingBottom = stylePaddingBottomState;
|
|
2309
3040
|
let paddingDiff = stylePaddingTopState - prevPaddingTop;
|
|
2310
|
-
if (maintainVisibleContentPosition && paddingDiff && prevPaddingTop !== void 0 &&
|
|
3041
|
+
if (maintainVisibleContentPosition && paddingDiff && prevPaddingTop !== void 0 && Platform.OS === "ios") {
|
|
2311
3042
|
if (state.scroll < 0) {
|
|
2312
3043
|
paddingDiff += state.scroll;
|
|
2313
3044
|
}
|
|
@@ -2318,64 +3049,50 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2318
3049
|
initializeStateVars();
|
|
2319
3050
|
updateAllPositions(ctx, state);
|
|
2320
3051
|
}
|
|
2321
|
-
const initialContentOffset =
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
3052
|
+
const initialContentOffset = React4.useMemo(() => {
|
|
3053
|
+
if (initialScroll) {
|
|
3054
|
+
const { index, viewOffset } = initialScroll;
|
|
3055
|
+
let initialContentOffset2 = viewOffset || 0;
|
|
3056
|
+
if (index !== void 0) {
|
|
3057
|
+
initialContentOffset2 += calculateOffsetForIndex(ctx, state, index);
|
|
3058
|
+
}
|
|
3059
|
+
refState.current.isStartReached = initialContentOffset2 < refState.current.scrollLength * onStartReachedThreshold;
|
|
3060
|
+
if (initialContentOffset2 > 0) {
|
|
3061
|
+
scrollTo(state, { animated: false, index, offset: initialContentOffset2 });
|
|
3062
|
+
}
|
|
3063
|
+
return initialContentOffset2;
|
|
2326
3064
|
}
|
|
2327
|
-
return
|
|
3065
|
+
return 0;
|
|
2328
3066
|
}, [renderNum]);
|
|
2329
3067
|
if (isFirst || didDataChange || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
2330
|
-
|
|
3068
|
+
state.lastBatchingAction = Date.now();
|
|
2331
3069
|
if (!keyExtractorProp && !isFirst && didDataChange) {
|
|
2332
3070
|
__DEV__ && warnDevOnce(
|
|
2333
3071
|
"keyExtractor",
|
|
2334
3072
|
"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."
|
|
2335
3073
|
);
|
|
2336
|
-
|
|
2337
|
-
|
|
3074
|
+
state.sizes.clear();
|
|
3075
|
+
state.positions.clear();
|
|
2338
3076
|
}
|
|
2339
3077
|
}
|
|
2340
|
-
|
|
2341
|
-
if (IsNewArchitecture) {
|
|
2342
|
-
let measured;
|
|
2343
|
-
refScroller.current.measure((x, y, width, height) => {
|
|
2344
|
-
measured = { height, width, x, y };
|
|
2345
|
-
});
|
|
2346
|
-
if (measured) {
|
|
2347
|
-
const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
|
|
2348
|
-
if (size) {
|
|
2349
|
-
handleLayout(ctx, state, measured, setCanRender);
|
|
2350
|
-
}
|
|
2351
|
-
}
|
|
2352
|
-
}
|
|
2353
|
-
if (!isFirst) {
|
|
2354
|
-
calculateItemsInView(ctx, state, { doMVCP: true });
|
|
2355
|
-
}
|
|
2356
|
-
}, [dataProp]);
|
|
2357
|
-
const onLayoutHeader = React3.useCallback((rect, fromLayoutEffect) => {
|
|
3078
|
+
const onLayoutHeader = React4.useCallback((rect, fromLayoutEffect) => {
|
|
2358
3079
|
const size = rect[horizontal ? "width" : "height"];
|
|
2359
3080
|
set$(ctx, "headerSize", size);
|
|
2360
|
-
if (initialScroll) {
|
|
2361
|
-
|
|
3081
|
+
if ((initialScroll == null ? void 0 : initialScroll.index) !== void 0) {
|
|
3082
|
+
{
|
|
2362
3083
|
if (fromLayoutEffect) {
|
|
2363
3084
|
setRenderNum((v) => v + 1);
|
|
2364
3085
|
}
|
|
2365
|
-
} else {
|
|
2366
|
-
setTimeout(() => {
|
|
2367
|
-
scrollToIndex(ctx, state, { ...initialScroll, animated: false });
|
|
2368
|
-
}, 17);
|
|
2369
3086
|
}
|
|
2370
3087
|
}
|
|
2371
3088
|
}, []);
|
|
2372
|
-
|
|
3089
|
+
React4.useLayoutEffect(() => {
|
|
2373
3090
|
if (snapToIndices) {
|
|
2374
3091
|
updateSnapToOffsets(ctx, state);
|
|
2375
3092
|
}
|
|
2376
3093
|
}, [snapToIndices]);
|
|
2377
|
-
|
|
2378
|
-
const didAllocateContainers = doInitialAllocateContainersCallback();
|
|
3094
|
+
React4.useLayoutEffect(() => {
|
|
3095
|
+
const didAllocateContainers = dataProp.length > 0 && doInitialAllocateContainersCallback();
|
|
2379
3096
|
if (!didAllocateContainers) {
|
|
2380
3097
|
checkResetContainers(
|
|
2381
3098
|
/*isFirst*/
|
|
@@ -2383,10 +3100,20 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2383
3100
|
);
|
|
2384
3101
|
}
|
|
2385
3102
|
}, [dataProp, numColumnsProp]);
|
|
2386
|
-
|
|
3103
|
+
React4.useLayoutEffect(() => {
|
|
2387
3104
|
set$(ctx, "extraData", extraData);
|
|
2388
3105
|
}, [extraData]);
|
|
2389
|
-
|
|
3106
|
+
const { onLayout } = useSyncLayout({
|
|
3107
|
+
onLayout: onLayoutProp,
|
|
3108
|
+
onLayoutChange: React4.useCallback(
|
|
3109
|
+
(rectangle) => {
|
|
3110
|
+
handleLayout(ctx, state, rectangle, setCanRender);
|
|
3111
|
+
},
|
|
3112
|
+
[ctx, state, setCanRender]
|
|
3113
|
+
),
|
|
3114
|
+
ref: refScroller
|
|
3115
|
+
});
|
|
3116
|
+
React4.useLayoutEffect(initializeStateVars, [
|
|
2390
3117
|
memoizedLastItemKeys.join(","),
|
|
2391
3118
|
numColumnsProp,
|
|
2392
3119
|
stylePaddingTopState,
|
|
@@ -2395,28 +3122,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2395
3122
|
const doInitialAllocateContainersCallback = () => {
|
|
2396
3123
|
return doInitialAllocateContainers(ctx, state);
|
|
2397
3124
|
};
|
|
2398
|
-
|
|
2399
|
-
const viewability = setupViewability({
|
|
2400
|
-
onViewableItemsChanged,
|
|
2401
|
-
viewabilityConfig,
|
|
2402
|
-
viewabilityConfigCallbackPairs
|
|
2403
|
-
});
|
|
2404
|
-
state.viewabilityConfigCallbackPairs = viewability;
|
|
2405
|
-
state.enableScrollForNextCalculateItemsInView = !viewability;
|
|
2406
|
-
}, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
|
|
2407
|
-
if (!IsNewArchitecture) {
|
|
2408
|
-
useInit(() => {
|
|
2409
|
-
doInitialAllocateContainersCallback();
|
|
2410
|
-
});
|
|
2411
|
-
}
|
|
2412
|
-
const onLayout = React3.useCallback((event) => {
|
|
2413
|
-
const layout = event.nativeEvent.layout;
|
|
2414
|
-
handleLayout(ctx, state, layout, setCanRender);
|
|
2415
|
-
if (onLayoutProp) {
|
|
2416
|
-
onLayoutProp(event);
|
|
2417
|
-
}
|
|
2418
|
-
}, []);
|
|
2419
|
-
React3.useImperativeHandle(forwardedRef, () => {
|
|
3125
|
+
React4.useImperativeHandle(forwardedRef, () => {
|
|
2420
3126
|
const scrollIndexIntoView = (options) => {
|
|
2421
3127
|
const state2 = refState.current;
|
|
2422
3128
|
if (state2) {
|
|
@@ -2433,18 +3139,23 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2433
3139
|
}
|
|
2434
3140
|
};
|
|
2435
3141
|
return {
|
|
2436
|
-
flashScrollIndicators: () =>
|
|
3142
|
+
flashScrollIndicators: () => {
|
|
3143
|
+
var _a, _b;
|
|
3144
|
+
return (_b = (_a = refScroller.current) == null ? void 0 : _a.flashScrollIndicators) == null ? void 0 : _b.call(_a);
|
|
3145
|
+
},
|
|
2437
3146
|
getNativeScrollRef: () => refScroller.current,
|
|
2438
|
-
getScrollableNode: () => refScroller.current
|
|
2439
|
-
getScrollResponder: () => refScroller.current
|
|
3147
|
+
getScrollableNode: () => refScroller.current,
|
|
3148
|
+
getScrollResponder: () => refScroller.current,
|
|
2440
3149
|
getState: () => {
|
|
2441
3150
|
const state2 = refState.current;
|
|
2442
3151
|
return state2 ? {
|
|
2443
3152
|
contentLength: state2.totalSize,
|
|
3153
|
+
data: state2.props.data,
|
|
2444
3154
|
end: state2.endNoBuffer,
|
|
2445
3155
|
endBuffered: state2.endBuffered,
|
|
2446
3156
|
isAtEnd: state2.isAtEnd,
|
|
2447
3157
|
isAtStart: state2.isAtStart,
|
|
3158
|
+
positionAtIndex: (index) => state2.positions.get(getId(state2, index)),
|
|
2448
3159
|
positions: state2.positions,
|
|
2449
3160
|
scroll: state2.scroll,
|
|
2450
3161
|
scrollLength: state2.scrollLength,
|
|
@@ -2471,7 +3182,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2471
3182
|
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
2472
3183
|
scrollToIndex(ctx, state, {
|
|
2473
3184
|
index,
|
|
2474
|
-
viewOffset: -paddingBottom - footerSize,
|
|
3185
|
+
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
2475
3186
|
viewPosition: 1,
|
|
2476
3187
|
...options
|
|
2477
3188
|
});
|
|
@@ -2486,20 +3197,23 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2486
3197
|
}
|
|
2487
3198
|
},
|
|
2488
3199
|
scrollToOffset: (params) => scrollTo(state, params),
|
|
3200
|
+
setScrollProcessingEnabled: (enabled) => {
|
|
3201
|
+
refState.current.scrollProcessingEnabled = enabled;
|
|
3202
|
+
},
|
|
2489
3203
|
setVisibleContentAnchorOffset: (value) => {
|
|
2490
3204
|
const val = typeof value === "function" ? value(peek$(ctx, "scrollAdjustUserOffset") || 0) : value;
|
|
2491
3205
|
set$(ctx, "scrollAdjustUserOffset", val);
|
|
2492
3206
|
}
|
|
2493
3207
|
};
|
|
2494
3208
|
}, []);
|
|
2495
|
-
|
|
2496
|
-
|
|
3209
|
+
{
|
|
3210
|
+
React4.useEffect(() => {
|
|
2497
3211
|
if (initialContentOffset) {
|
|
2498
3212
|
scrollTo(state, { animated: false, offset: initialContentOffset });
|
|
2499
3213
|
}
|
|
2500
3214
|
}, []);
|
|
2501
3215
|
}
|
|
2502
|
-
const fns =
|
|
3216
|
+
const fns = React4.useMemo(
|
|
2503
3217
|
() => ({
|
|
2504
3218
|
getRenderedItem: (key) => getRenderedItem(ctx, state, key),
|
|
2505
3219
|
onScroll: (event) => onScroll(ctx, state, event),
|
|
@@ -2507,7 +3221,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2507
3221
|
}),
|
|
2508
3222
|
[]
|
|
2509
3223
|
);
|
|
2510
|
-
|
|
3224
|
+
const onScrollHandler = useStickyScrollHandler(stickyIndices, horizontal, ctx, fns.onScroll);
|
|
3225
|
+
return /* @__PURE__ */ React4__namespace.createElement(React4__namespace.Fragment, null, /* @__PURE__ */ React4__namespace.createElement(
|
|
2511
3226
|
ListComponent,
|
|
2512
3227
|
{
|
|
2513
3228
|
...rest,
|
|
@@ -2523,19 +3238,21 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2523
3238
|
onLayout,
|
|
2524
3239
|
onLayoutHeader,
|
|
2525
3240
|
onMomentumScrollEnd: (event) => {
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
3241
|
+
{
|
|
3242
|
+
requestAnimationFrame(() => {
|
|
3243
|
+
finishScrollTo(refState.current);
|
|
3244
|
+
});
|
|
3245
|
+
}
|
|
2529
3246
|
if (onMomentumScrollEnd) {
|
|
2530
3247
|
onMomentumScrollEnd(event);
|
|
2531
3248
|
}
|
|
2532
3249
|
},
|
|
2533
|
-
onScroll:
|
|
3250
|
+
onScroll: onScrollHandler,
|
|
2534
3251
|
recycleItems,
|
|
2535
|
-
refreshControl: refreshControl ? stylePaddingTopState > 0 ?
|
|
3252
|
+
refreshControl: refreshControl ? stylePaddingTopState > 0 ? React4__namespace.cloneElement(refreshControl, {
|
|
2536
3253
|
progressViewOffset: (refreshControl.props.progressViewOffset || 0) + stylePaddingTopState
|
|
2537
|
-
}) : refreshControl : onRefresh && /* @__PURE__ */
|
|
2538
|
-
|
|
3254
|
+
}) : refreshControl : onRefresh && /* @__PURE__ */ React4__namespace.createElement(
|
|
3255
|
+
RefreshControl,
|
|
2539
3256
|
{
|
|
2540
3257
|
onRefresh,
|
|
2541
3258
|
progressViewOffset: (progressViewOffset || 0) + stylePaddingTopState,
|
|
@@ -2543,34 +3260,21 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2543
3260
|
}
|
|
2544
3261
|
),
|
|
2545
3262
|
refScrollView: combinedRef,
|
|
2546
|
-
scrollAdjustHandler:
|
|
2547
|
-
scrollEventThrottle: reactNative.Platform.OS === "web" ? 16 : void 0,
|
|
3263
|
+
scrollAdjustHandler: state.scrollAdjustHandler,
|
|
2548
3264
|
snapToIndices,
|
|
3265
|
+
stickyIndices,
|
|
2549
3266
|
style,
|
|
2550
3267
|
updateItemSize: fns.updateItemSize,
|
|
2551
3268
|
waitForInitialLayout
|
|
2552
3269
|
}
|
|
2553
|
-
), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */
|
|
2554
|
-
});
|
|
2555
|
-
|
|
2556
|
-
// src/components/LazyLegendList.tsx
|
|
2557
|
-
var typedForwardRef2 = React3.forwardRef;
|
|
2558
|
-
var renderItem = ({ item }) => item;
|
|
2559
|
-
var LazyLegendList = typedForwardRef2(function LazyLegendList2(props, forwardedRef) {
|
|
2560
|
-
const { LegendList: LegendListProp, children, ...rest } = props;
|
|
2561
|
-
const LegendListComponent = LegendListProp != null ? LegendListProp : LegendList;
|
|
2562
|
-
const data = (isArray(children) ? children : React3__namespace.Children.toArray(children)).flat(1);
|
|
2563
|
-
return (
|
|
2564
|
-
// @ts-expect-error TODO: Fix this type
|
|
2565
|
-
/* @__PURE__ */ React3__namespace.createElement(LegendListComponent, { ...rest, data, ref: forwardedRef, renderItem })
|
|
2566
|
-
);
|
|
3270
|
+
), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React4__namespace.createElement(DebugView, { state: refState.current }));
|
|
2567
3271
|
});
|
|
2568
3272
|
|
|
2569
|
-
exports.LazyLegendList = LazyLegendList;
|
|
2570
3273
|
exports.LegendList = LegendList;
|
|
2571
3274
|
exports.useIsLastItem = useIsLastItem;
|
|
2572
3275
|
exports.useListScrollSize = useListScrollSize;
|
|
2573
3276
|
exports.useRecyclingEffect = useRecyclingEffect;
|
|
2574
3277
|
exports.useRecyclingState = useRecyclingState;
|
|
3278
|
+
exports.useSyncLayout = useSyncLayout2;
|
|
2575
3279
|
exports.useViewability = useViewability;
|
|
2576
3280
|
exports.useViewabilityAmount = useViewabilityAmount;
|