@legendapp/list 1.0.0-beta.5 → 1.0.0-beta.51
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/README.md +93 -37
- package/animated.d.mts +54 -4
- package/animated.d.ts +54 -4
- package/index.d.mts +344 -63
- package/index.d.ts +344 -63
- package/index.js +1185 -440
- package/index.mjs +1163 -418
- package/keyboard-controller.d.mts +401 -0
- package/keyboard-controller.d.ts +401 -0
- package/keyboard-controller.js +61 -0
- package/keyboard-controller.mjs +40 -0
- package/package.json +3 -6
- package/reanimated.d.mts +12 -11
- package/reanimated.d.ts +12 -11
- package/reanimated.js +27 -16
- package/reanimated.mjs +28 -17
package/index.mjs
CHANGED
|
@@ -1,22 +1,29 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
1
|
+
import * as React6 from 'react';
|
|
2
|
+
import React6__default, { memo, useReducer, useEffect, createContext, useMemo, useRef, useCallback, useImperativeHandle, useSyncExternalStore, useContext, useState, forwardRef, useLayoutEffect } from 'react';
|
|
3
|
+
import { View, Text, Platform, Animated, ScrollView, StyleSheet, Dimensions, RefreshControl } from 'react-native';
|
|
4
4
|
|
|
5
5
|
// src/LegendList.tsx
|
|
6
|
-
var ContextState =
|
|
6
|
+
var ContextState = React6.createContext(null);
|
|
7
7
|
function StateProvider({ children }) {
|
|
8
|
-
const [value] =
|
|
8
|
+
const [value] = React6.useState(() => ({
|
|
9
9
|
listeners: /* @__PURE__ */ new Map(),
|
|
10
|
-
values: /* @__PURE__ */ new Map(
|
|
10
|
+
values: /* @__PURE__ */ new Map([
|
|
11
|
+
["paddingTop", 0],
|
|
12
|
+
["alignItemsPaddingTop", 0],
|
|
13
|
+
["stylePaddingTop", 0],
|
|
14
|
+
["headerSize", 0]
|
|
15
|
+
]),
|
|
11
16
|
mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
|
|
12
17
|
mapViewabilityValues: /* @__PURE__ */ new Map(),
|
|
13
18
|
mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
|
|
14
|
-
mapViewabilityAmountValues: /* @__PURE__ */ new Map()
|
|
19
|
+
mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
|
|
20
|
+
columnWrapperStyle: void 0,
|
|
21
|
+
viewRefs: /* @__PURE__ */ new Map()
|
|
15
22
|
}));
|
|
16
|
-
return /* @__PURE__ */
|
|
23
|
+
return /* @__PURE__ */ React6.createElement(ContextState.Provider, { value }, children);
|
|
17
24
|
}
|
|
18
25
|
function useStateContext() {
|
|
19
|
-
return
|
|
26
|
+
return React6.useContext(ContextState);
|
|
20
27
|
}
|
|
21
28
|
function createSelectorFunctions(ctx, signalName) {
|
|
22
29
|
return {
|
|
@@ -25,8 +32,8 @@ function createSelectorFunctions(ctx, signalName) {
|
|
|
25
32
|
};
|
|
26
33
|
}
|
|
27
34
|
function use$(signalName) {
|
|
28
|
-
const ctx =
|
|
29
|
-
const { subscribe, get } =
|
|
35
|
+
const ctx = React6.useContext(ContextState);
|
|
36
|
+
const { subscribe, get } = React6.useMemo(() => createSelectorFunctions(ctx, signalName), []);
|
|
30
37
|
const value = useSyncExternalStore(subscribe, get);
|
|
31
38
|
return value;
|
|
32
39
|
}
|
|
@@ -56,6 +63,81 @@ function set$(ctx, signalName, value) {
|
|
|
56
63
|
}
|
|
57
64
|
}
|
|
58
65
|
}
|
|
66
|
+
function getContentSize(ctx) {
|
|
67
|
+
const { values } = ctx;
|
|
68
|
+
const stylePaddingTop = values.get("stylePaddingTop") || 0;
|
|
69
|
+
const headerSize = values.get("headerSize") || 0;
|
|
70
|
+
const footerSize = values.get("footerSize") || 0;
|
|
71
|
+
const totalSize = values.get("totalSize") || 0;
|
|
72
|
+
return headerSize + footerSize + totalSize + stylePaddingTop;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// src/DebugView.tsx
|
|
76
|
+
var DebugRow = ({ children }) => {
|
|
77
|
+
return /* @__PURE__ */ React.createElement(View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" } }, children);
|
|
78
|
+
};
|
|
79
|
+
var DebugView = memo(function DebugView2({ state }) {
|
|
80
|
+
const ctx = useStateContext();
|
|
81
|
+
const totalSize = use$("totalSize") || 0;
|
|
82
|
+
const totalSizeWithScrollAdjust = use$("totalSizeWithScrollAdjust") || 0;
|
|
83
|
+
const scrollAdjust = use$("scrollAdjust") || 0;
|
|
84
|
+
const rawScroll = use$("debugRawScroll") || 0;
|
|
85
|
+
const scroll = use$("debugComputedScroll") || 0;
|
|
86
|
+
const contentSize = getContentSize(ctx);
|
|
87
|
+
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
88
|
+
use$("numContainers");
|
|
89
|
+
use$("numContainersPooled");
|
|
90
|
+
useInterval(() => {
|
|
91
|
+
forceUpdate();
|
|
92
|
+
}, 100);
|
|
93
|
+
return /* @__PURE__ */ React.createElement(
|
|
94
|
+
View,
|
|
95
|
+
{
|
|
96
|
+
style: {
|
|
97
|
+
position: "absolute",
|
|
98
|
+
top: 0,
|
|
99
|
+
right: 0,
|
|
100
|
+
paddingLeft: 4,
|
|
101
|
+
paddingBottom: 4,
|
|
102
|
+
// height: 100,
|
|
103
|
+
backgroundColor: "#FFFFFFCC",
|
|
104
|
+
padding: 4,
|
|
105
|
+
borderRadius: 4
|
|
106
|
+
},
|
|
107
|
+
pointerEvents: "none"
|
|
108
|
+
},
|
|
109
|
+
/* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(Text, null, "TotalSize:"), /* @__PURE__ */ React.createElement(Text, null, totalSize.toFixed(2))),
|
|
110
|
+
/* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(Text, null, "ContentSize:"), /* @__PURE__ */ React.createElement(Text, null, contentSize.toFixed(2))),
|
|
111
|
+
/* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(Text, null, "At end:"), /* @__PURE__ */ React.createElement(Text, null, String(state.isAtBottom))),
|
|
112
|
+
/* @__PURE__ */ React.createElement(Text, null),
|
|
113
|
+
/* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(Text, null, "ScrollAdjust:"), /* @__PURE__ */ React.createElement(Text, null, scrollAdjust.toFixed(2))),
|
|
114
|
+
/* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(Text, null, "TotalSizeReal: "), /* @__PURE__ */ React.createElement(Text, null, totalSizeWithScrollAdjust.toFixed(2))),
|
|
115
|
+
/* @__PURE__ */ React.createElement(Text, null),
|
|
116
|
+
/* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(Text, null, "RawScroll: "), /* @__PURE__ */ React.createElement(Text, null, rawScroll.toFixed(2))),
|
|
117
|
+
/* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(Text, null, "ComputedScroll: "), /* @__PURE__ */ React.createElement(Text, null, scroll.toFixed(2)))
|
|
118
|
+
);
|
|
119
|
+
});
|
|
120
|
+
function useInterval(callback, delay) {
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
const interval = setInterval(callback, delay);
|
|
123
|
+
return () => clearInterval(interval);
|
|
124
|
+
}, [delay]);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/helpers.ts
|
|
128
|
+
function isFunction(obj) {
|
|
129
|
+
return typeof obj === "function";
|
|
130
|
+
}
|
|
131
|
+
var warned = /* @__PURE__ */ new Set();
|
|
132
|
+
function warnDevOnce(id, text) {
|
|
133
|
+
if (__DEV__ && !warned.has(id)) {
|
|
134
|
+
warned.add(id);
|
|
135
|
+
console.warn(`[legend-list] ${text}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function roundSize(size) {
|
|
139
|
+
return Math.floor(size * 8) / 8;
|
|
140
|
+
}
|
|
59
141
|
var symbolFirst = Symbol();
|
|
60
142
|
function useInit(cb) {
|
|
61
143
|
const refValue = useRef(symbolFirst);
|
|
@@ -67,10 +149,10 @@ function useInit(cb) {
|
|
|
67
149
|
|
|
68
150
|
// src/ContextContainer.ts
|
|
69
151
|
var ContextContainer = createContext(null);
|
|
70
|
-
function useViewability(
|
|
152
|
+
function useViewability(callback, configId) {
|
|
71
153
|
const ctx = useStateContext();
|
|
72
154
|
const { containerId } = useContext(ContextContainer);
|
|
73
|
-
const key = containerId + configId;
|
|
155
|
+
const key = containerId + (configId != null ? configId : "");
|
|
74
156
|
useInit(() => {
|
|
75
157
|
const value = ctx.mapViewabilityValues.get(key);
|
|
76
158
|
if (value) {
|
|
@@ -126,25 +208,36 @@ function useRecyclingEffect(effect) {
|
|
|
126
208
|
}, [index, value]);
|
|
127
209
|
}
|
|
128
210
|
function useRecyclingState(valueOrFun) {
|
|
129
|
-
const { index, value } = useContext(ContextContainer);
|
|
130
|
-
const
|
|
131
|
-
|
|
211
|
+
const { index, value, itemKey, triggerLayout } = useContext(ContextContainer);
|
|
212
|
+
const refState = useRef({
|
|
213
|
+
itemKey: null,
|
|
214
|
+
value: null
|
|
215
|
+
});
|
|
216
|
+
const [_, setRenderNum] = useState(0);
|
|
217
|
+
if (refState.current.itemKey !== itemKey) {
|
|
218
|
+
refState.current.itemKey = itemKey;
|
|
219
|
+
refState.current.value = isFunction(valueOrFun) ? valueOrFun({
|
|
132
220
|
index,
|
|
133
221
|
item: value,
|
|
134
222
|
prevIndex: void 0,
|
|
135
223
|
prevItem: void 0
|
|
136
|
-
}) : valueOrFun
|
|
224
|
+
}) : valueOrFun;
|
|
225
|
+
}
|
|
226
|
+
const setState = useCallback(
|
|
227
|
+
(newState) => {
|
|
228
|
+
refState.current.value = isFunction(newState) ? newState(refState.current.value) : newState;
|
|
229
|
+
setRenderNum((v) => v + 1);
|
|
230
|
+
triggerLayout();
|
|
231
|
+
},
|
|
232
|
+
[triggerLayout]
|
|
137
233
|
);
|
|
138
|
-
|
|
139
|
-
const newState = typeof valueOrFun === "function" ? valueOrFun(state) : valueOrFun;
|
|
140
|
-
stateInfo[1](newState);
|
|
141
|
-
});
|
|
142
|
-
return stateInfo;
|
|
234
|
+
return [refState.current.value, setState];
|
|
143
235
|
}
|
|
144
|
-
var
|
|
145
|
-
return
|
|
236
|
+
var LeanViewComponent = React6.forwardRef((props, ref) => {
|
|
237
|
+
return React6.createElement("RCTView", { ...props, ref });
|
|
146
238
|
});
|
|
147
|
-
|
|
239
|
+
LeanViewComponent.displayName = "RCTView";
|
|
240
|
+
var LeanView = Platform.OS === "android" || Platform.OS === "ios" ? LeanViewComponent : View;
|
|
148
241
|
|
|
149
242
|
// src/constants.ts
|
|
150
243
|
var POSITION_OUT_OF_VIEW = -1e7;
|
|
@@ -153,9 +246,11 @@ var ANCHORED_POSITION_OUT_OF_VIEW = {
|
|
|
153
246
|
relativeCoordinate: POSITION_OUT_OF_VIEW,
|
|
154
247
|
top: POSITION_OUT_OF_VIEW
|
|
155
248
|
};
|
|
249
|
+
var ENABLE_DEVMODE = __DEV__ && false;
|
|
250
|
+
var ENABLE_DEBUG_VIEW = __DEV__ && false;
|
|
251
|
+
var IsNewArchitecture = global.nativeFabricUIManager != null;
|
|
156
252
|
|
|
157
253
|
// src/Container.tsx
|
|
158
|
-
var isNewArchitecture = global.nativeFabricUIManager != null;
|
|
159
254
|
var Container = ({
|
|
160
255
|
id,
|
|
161
256
|
recycleItems,
|
|
@@ -164,87 +259,141 @@ var Container = ({
|
|
|
164
259
|
updateItemSize,
|
|
165
260
|
ItemSeparatorComponent
|
|
166
261
|
}) => {
|
|
167
|
-
useStateContext();
|
|
262
|
+
const ctx = useStateContext();
|
|
263
|
+
const columnWrapperStyle = ctx.columnWrapperStyle;
|
|
168
264
|
const maintainVisibleContentPosition = use$("maintainVisibleContentPosition");
|
|
169
265
|
const position = use$(`containerPosition${id}`) || ANCHORED_POSITION_OUT_OF_VIEW;
|
|
170
266
|
const column = use$(`containerColumn${id}`) || 0;
|
|
171
267
|
const numColumns = use$("numColumns");
|
|
268
|
+
const lastItemKeys = use$("lastItemKeys");
|
|
269
|
+
const itemKey = use$(`containerItemKey${id}`);
|
|
270
|
+
const data = use$(`containerItemData${id}`);
|
|
271
|
+
const extraData = use$("extraData");
|
|
272
|
+
const refLastSize = useRef();
|
|
273
|
+
const ref = useRef(null);
|
|
274
|
+
const [layoutRenderCount, forceLayoutRender] = useState(0);
|
|
172
275
|
const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
|
|
173
276
|
const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
|
|
277
|
+
let paddingStyles;
|
|
278
|
+
if (columnWrapperStyle) {
|
|
279
|
+
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
280
|
+
if (horizontal) {
|
|
281
|
+
paddingStyles = {
|
|
282
|
+
paddingRight: !lastItemKeys.includes(itemKey) ? columnGap || gap || void 0 : void 0,
|
|
283
|
+
paddingVertical: (rowGap || gap || 0) / 2
|
|
284
|
+
};
|
|
285
|
+
} else {
|
|
286
|
+
paddingStyles = {
|
|
287
|
+
paddingBottom: !lastItemKeys.includes(itemKey) ? rowGap || gap || void 0 : void 0,
|
|
288
|
+
paddingHorizontal: (columnGap || gap || 0) / 2
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
}
|
|
174
292
|
const style = horizontal ? {
|
|
175
293
|
flexDirection: ItemSeparatorComponent ? "row" : void 0,
|
|
176
294
|
position: "absolute",
|
|
177
295
|
top: otherAxisPos,
|
|
178
296
|
bottom: numColumns > 1 ? null : 0,
|
|
179
297
|
height: otherAxisSize,
|
|
180
|
-
left: position.relativeCoordinate
|
|
298
|
+
left: position.relativeCoordinate,
|
|
299
|
+
...paddingStyles || {}
|
|
181
300
|
} : {
|
|
182
301
|
position: "absolute",
|
|
183
302
|
left: otherAxisPos,
|
|
184
303
|
right: numColumns > 1 ? null : 0,
|
|
185
304
|
width: otherAxisSize,
|
|
186
|
-
top: position.relativeCoordinate
|
|
305
|
+
top: position.relativeCoordinate,
|
|
306
|
+
...paddingStyles || {}
|
|
187
307
|
};
|
|
188
|
-
const lastItemKey = use$("lastItemKey");
|
|
189
|
-
const itemKey = use$(`containerItemKey${id}`);
|
|
190
|
-
const data = use$(`containerItemData${id}`);
|
|
191
|
-
const extraData = use$("extraData");
|
|
192
308
|
const renderedItemInfo = useMemo(
|
|
193
|
-
() => itemKey !== void 0
|
|
309
|
+
() => itemKey !== void 0 ? getRenderedItem(itemKey) : null,
|
|
194
310
|
[itemKey, data, extraData]
|
|
195
311
|
);
|
|
196
312
|
const { index, renderedItem } = renderedItemInfo || {};
|
|
313
|
+
const triggerLayout = useCallback(() => {
|
|
314
|
+
forceLayoutRender((v) => v + 1);
|
|
315
|
+
}, []);
|
|
197
316
|
const onLayout = (event) => {
|
|
198
317
|
if (itemKey !== void 0) {
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
updateItemSize(id, itemKey, size);
|
|
318
|
+
const layout = event.nativeEvent.layout;
|
|
319
|
+
const size = roundSize(layout[horizontal ? "width" : "height"]);
|
|
320
|
+
refLastSize.current = size;
|
|
321
|
+
updateItemSize(itemKey, size);
|
|
205
322
|
}
|
|
206
323
|
};
|
|
207
|
-
|
|
208
|
-
if (isNewArchitecture) {
|
|
324
|
+
if (IsNewArchitecture) {
|
|
209
325
|
useLayoutEffect(() => {
|
|
210
326
|
var _a, _b;
|
|
211
|
-
if (itemKey) {
|
|
327
|
+
if (itemKey !== void 0) {
|
|
212
328
|
const measured = (_b = (_a = ref.current) == null ? void 0 : _a.unstable_getBoundingClientRect) == null ? void 0 : _b.call(_a);
|
|
213
329
|
if (measured) {
|
|
214
330
|
const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
|
|
215
331
|
if (size) {
|
|
216
|
-
updateItemSize(
|
|
332
|
+
updateItemSize(itemKey, size);
|
|
217
333
|
}
|
|
218
334
|
}
|
|
219
335
|
}
|
|
336
|
+
}, [itemKey, layoutRenderCount]);
|
|
337
|
+
} else {
|
|
338
|
+
useEffect(() => {
|
|
339
|
+
if (itemKey) {
|
|
340
|
+
const timeout = setTimeout(() => {
|
|
341
|
+
if (refLastSize.current) {
|
|
342
|
+
updateItemSize(itemKey, refLastSize.current);
|
|
343
|
+
}
|
|
344
|
+
}, 16);
|
|
345
|
+
return () => {
|
|
346
|
+
clearTimeout(timeout);
|
|
347
|
+
};
|
|
348
|
+
}
|
|
220
349
|
}, [itemKey]);
|
|
221
350
|
}
|
|
222
|
-
const contextValue = useMemo(
|
|
223
|
-
(
|
|
224
|
-
|
|
225
|
-
);
|
|
226
|
-
const contentFragment = /* @__PURE__ */
|
|
351
|
+
const contextValue = useMemo(() => {
|
|
352
|
+
ctx.viewRefs.set(id, ref);
|
|
353
|
+
return { containerId: id, itemKey, index, value: data, triggerLayout };
|
|
354
|
+
}, [id, itemKey, index, data]);
|
|
355
|
+
const contentFragment = /* @__PURE__ */ React6__default.createElement(React6__default.Fragment, { key: recycleItems ? void 0 : itemKey }, /* @__PURE__ */ React6__default.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && !lastItemKeys.includes(itemKey) && /* @__PURE__ */ React6__default.createElement(ItemSeparatorComponent, { leadingItem: renderedItemInfo.item })));
|
|
227
356
|
if (maintainVisibleContentPosition) {
|
|
228
357
|
const anchorStyle = position.type === "top" ? { position: "absolute", top: 0, left: 0, right: 0 } : { position: "absolute", bottom: 0, left: 0, right: 0 };
|
|
229
|
-
|
|
358
|
+
if (ENABLE_DEVMODE) {
|
|
359
|
+
anchorStyle.borderColor = position.type === "top" ? "red" : "blue";
|
|
360
|
+
anchorStyle.borderWidth = 1;
|
|
361
|
+
}
|
|
362
|
+
return /* @__PURE__ */ React6__default.createElement(LeanView, { style }, /* @__PURE__ */ React6__default.createElement(LeanView, { style: anchorStyle, onLayout, ref }, contentFragment, ENABLE_DEVMODE && /* @__PURE__ */ React6__default.createElement(Text, { style: { position: "absolute", top: 0, left: 0, zIndex: 1e3 } }, position.top)));
|
|
230
363
|
}
|
|
231
|
-
return /* @__PURE__ */
|
|
364
|
+
return /* @__PURE__ */ React6__default.createElement(LeanView, { style, onLayout, ref }, contentFragment);
|
|
232
365
|
};
|
|
233
|
-
var
|
|
366
|
+
var typedForwardRef = forwardRef;
|
|
367
|
+
var typedMemo = memo;
|
|
368
|
+
var useAnimatedValue = (initialValue) => {
|
|
234
369
|
return useRef(new Animated.Value(initialValue)).current;
|
|
235
|
-
}
|
|
236
|
-
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
// src/useValue$.ts
|
|
373
|
+
function useValue$(key, getValue, useMicrotask) {
|
|
237
374
|
var _a;
|
|
238
375
|
const ctx = useStateContext();
|
|
239
376
|
const animValue = useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
|
|
240
377
|
useMemo(() => {
|
|
241
|
-
|
|
378
|
+
let newValue = void 0;
|
|
379
|
+
listen$(ctx, key, (v) => {
|
|
380
|
+
if (useMicrotask && newValue === void 0) {
|
|
381
|
+
queueMicrotask(() => {
|
|
382
|
+
animValue.setValue(newValue);
|
|
383
|
+
newValue = void 0;
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
newValue = getValue ? getValue(v) : v;
|
|
387
|
+
if (!useMicrotask) {
|
|
388
|
+
animValue.setValue(newValue);
|
|
389
|
+
}
|
|
390
|
+
});
|
|
242
391
|
}, []);
|
|
243
392
|
return animValue;
|
|
244
393
|
}
|
|
245
394
|
|
|
246
395
|
// src/Containers.tsx
|
|
247
|
-
var Containers =
|
|
396
|
+
var Containers = typedMemo(function Containers2({
|
|
248
397
|
horizontal,
|
|
249
398
|
recycleItems,
|
|
250
399
|
ItemSeparatorComponent,
|
|
@@ -252,13 +401,20 @@ var Containers = React5.memo(function Containers2({
|
|
|
252
401
|
updateItemSize,
|
|
253
402
|
getRenderedItem
|
|
254
403
|
}) {
|
|
404
|
+
const ctx = useStateContext();
|
|
405
|
+
const columnWrapperStyle = ctx.columnWrapperStyle;
|
|
255
406
|
const numContainers = use$("numContainersPooled");
|
|
256
|
-
const animSize = useValue$(
|
|
407
|
+
const animSize = useValue$(
|
|
408
|
+
"totalSizeWithScrollAdjust",
|
|
409
|
+
void 0,
|
|
410
|
+
/*useMicrotask*/
|
|
411
|
+
true
|
|
412
|
+
);
|
|
257
413
|
const animOpacity = waitForInitialLayout ? useValue$("containersDidLayout", (value) => value ? 1 : 0) : void 0;
|
|
258
414
|
const containers = [];
|
|
259
415
|
for (let i = 0; i < numContainers; i++) {
|
|
260
416
|
containers.push(
|
|
261
|
-
/* @__PURE__ */
|
|
417
|
+
/* @__PURE__ */ React6.createElement(
|
|
262
418
|
Container,
|
|
263
419
|
{
|
|
264
420
|
id: i,
|
|
@@ -273,20 +429,85 @@ var Containers = React5.memo(function Containers2({
|
|
|
273
429
|
);
|
|
274
430
|
}
|
|
275
431
|
const style = horizontal ? { width: animSize, opacity: animOpacity } : { height: animSize, opacity: animOpacity };
|
|
276
|
-
|
|
432
|
+
if (columnWrapperStyle) {
|
|
433
|
+
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
434
|
+
if (horizontal) {
|
|
435
|
+
const my = (rowGap || gap || 0) / 2;
|
|
436
|
+
if (my) {
|
|
437
|
+
style.marginVertical = -my;
|
|
438
|
+
}
|
|
439
|
+
} else {
|
|
440
|
+
const mx = (columnGap || gap || 0) / 2;
|
|
441
|
+
if (mx) {
|
|
442
|
+
style.marginHorizontal = -mx;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return /* @__PURE__ */ React6.createElement(Animated.View, { style }, containers);
|
|
277
447
|
});
|
|
278
448
|
|
|
279
449
|
// src/ListComponent.tsx
|
|
280
450
|
var getComponent = (Component) => {
|
|
281
|
-
if (
|
|
451
|
+
if (React6.isValidElement(Component)) {
|
|
282
452
|
return Component;
|
|
283
453
|
}
|
|
284
454
|
if (Component) {
|
|
285
|
-
return /* @__PURE__ */
|
|
455
|
+
return /* @__PURE__ */ React6.createElement(Component, null);
|
|
286
456
|
}
|
|
287
457
|
return null;
|
|
288
458
|
};
|
|
289
|
-
var
|
|
459
|
+
var PaddingAndAdjust = () => {
|
|
460
|
+
const animPaddingTop = useValue$("paddingTop", (v) => v, true);
|
|
461
|
+
const animScrollAdjust = useValue$("scrollAdjust", (v) => v, true);
|
|
462
|
+
const additionalSize = { marginTop: animScrollAdjust, paddingTop: animPaddingTop };
|
|
463
|
+
return /* @__PURE__ */ React6.createElement(Animated.View, { style: additionalSize });
|
|
464
|
+
};
|
|
465
|
+
var PaddingAndAdjustDevMode = () => {
|
|
466
|
+
const animPaddingTop = useValue$("paddingTop", (v) => v, true);
|
|
467
|
+
const animScrollAdjust = useValue$("scrollAdjust", (v) => v, true);
|
|
468
|
+
return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Animated.View, { style: { marginTop: animScrollAdjust } }), /* @__PURE__ */ React6.createElement(Animated.View, { style: { paddingTop: animPaddingTop } }), /* @__PURE__ */ React6.createElement(
|
|
469
|
+
Animated.View,
|
|
470
|
+
{
|
|
471
|
+
style: {
|
|
472
|
+
position: "absolute",
|
|
473
|
+
top: Animated.add(animScrollAdjust, Animated.multiply(animScrollAdjust, -1)),
|
|
474
|
+
height: animPaddingTop,
|
|
475
|
+
left: 0,
|
|
476
|
+
right: 0,
|
|
477
|
+
backgroundColor: "green"
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
), /* @__PURE__ */ React6.createElement(
|
|
481
|
+
Animated.View,
|
|
482
|
+
{
|
|
483
|
+
style: {
|
|
484
|
+
position: "absolute",
|
|
485
|
+
top: animPaddingTop,
|
|
486
|
+
height: animScrollAdjust,
|
|
487
|
+
left: -16,
|
|
488
|
+
right: -16,
|
|
489
|
+
backgroundColor: "lightblue"
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
), /* @__PURE__ */ React6.createElement(
|
|
493
|
+
Animated.View,
|
|
494
|
+
{
|
|
495
|
+
style: {
|
|
496
|
+
position: "absolute",
|
|
497
|
+
top: animPaddingTop,
|
|
498
|
+
height: Animated.multiply(animScrollAdjust, -1),
|
|
499
|
+
width: 8,
|
|
500
|
+
right: 4,
|
|
501
|
+
borderStyle: "dashed",
|
|
502
|
+
borderColor: "blue",
|
|
503
|
+
borderWidth: 1,
|
|
504
|
+
backgroundColor: "lightblue"
|
|
505
|
+
//backgroundColor: "blue",
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
));
|
|
509
|
+
};
|
|
510
|
+
var ListComponent = typedMemo(function ListComponent2({
|
|
290
511
|
style,
|
|
291
512
|
contentContainerStyle,
|
|
292
513
|
horizontal,
|
|
@@ -307,22 +528,22 @@ var ListComponent = React5.memo(function ListComponent2({
|
|
|
307
528
|
refScrollView,
|
|
308
529
|
maintainVisibleContentPosition,
|
|
309
530
|
renderScrollComponent,
|
|
531
|
+
onRefresh,
|
|
532
|
+
refreshing,
|
|
533
|
+
progressViewOffset,
|
|
310
534
|
...rest
|
|
311
535
|
}) {
|
|
312
536
|
const ctx = useStateContext();
|
|
313
|
-
const animPaddingTop = useValue$("paddingTop");
|
|
314
|
-
const animScrollAdjust = useValue$("scrollAdjust");
|
|
315
537
|
const ScrollComponent = renderScrollComponent ? useMemo(
|
|
316
|
-
() =>
|
|
538
|
+
() => React6.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
|
|
317
539
|
[renderScrollComponent]
|
|
318
540
|
) : ScrollView;
|
|
319
|
-
|
|
320
|
-
return /* @__PURE__ */ React5.createElement(
|
|
541
|
+
return /* @__PURE__ */ React6.createElement(
|
|
321
542
|
ScrollComponent,
|
|
322
543
|
{
|
|
323
544
|
...rest,
|
|
324
545
|
style,
|
|
325
|
-
maintainVisibleContentPosition: maintainVisibleContentPosition ? { minIndexForVisible: 0 } : void 0,
|
|
546
|
+
maintainVisibleContentPosition: maintainVisibleContentPosition && !ListEmptyComponent ? { minIndexForVisible: 0 } : void 0,
|
|
326
547
|
contentContainerStyle: [
|
|
327
548
|
contentContainerStyle,
|
|
328
549
|
horizontal ? {
|
|
@@ -335,34 +556,41 @@ var ListComponent = React5.memo(function ListComponent2({
|
|
|
335
556
|
contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
|
|
336
557
|
ref: refScrollView
|
|
337
558
|
},
|
|
338
|
-
/* @__PURE__ */
|
|
339
|
-
ListHeaderComponent && /* @__PURE__ */
|
|
340
|
-
|
|
559
|
+
!ListEmptyComponent && (ENABLE_DEVMODE ? /* @__PURE__ */ React6.createElement(PaddingAndAdjustDevMode, null) : /* @__PURE__ */ React6.createElement(PaddingAndAdjust, null)),
|
|
560
|
+
ListHeaderComponent && /* @__PURE__ */ React6.createElement(
|
|
561
|
+
View,
|
|
341
562
|
{
|
|
342
563
|
style: ListHeaderComponentStyle,
|
|
343
564
|
onLayout: (event) => {
|
|
344
565
|
const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
345
|
-
|
|
346
|
-
if (size !== prevSize) {
|
|
347
|
-
set$(ctx, "headerSize", size);
|
|
348
|
-
}
|
|
566
|
+
set$(ctx, "headerSize", size);
|
|
349
567
|
}
|
|
350
568
|
},
|
|
351
569
|
getComponent(ListHeaderComponent)
|
|
352
570
|
),
|
|
353
571
|
ListEmptyComponent && getComponent(ListEmptyComponent),
|
|
354
|
-
/* @__PURE__ */
|
|
572
|
+
/* @__PURE__ */ React6.createElement(
|
|
355
573
|
Containers,
|
|
356
574
|
{
|
|
357
575
|
horizontal,
|
|
358
576
|
recycleItems,
|
|
359
577
|
waitForInitialLayout,
|
|
360
578
|
getRenderedItem,
|
|
361
|
-
ItemSeparatorComponent
|
|
579
|
+
ItemSeparatorComponent,
|
|
362
580
|
updateItemSize
|
|
363
581
|
}
|
|
364
582
|
),
|
|
365
|
-
ListFooterComponent && /* @__PURE__ */
|
|
583
|
+
ListFooterComponent && /* @__PURE__ */ React6.createElement(
|
|
584
|
+
View,
|
|
585
|
+
{
|
|
586
|
+
style: ListFooterComponentStyle,
|
|
587
|
+
onLayout: (event) => {
|
|
588
|
+
const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
589
|
+
set$(ctx, "footerSize", size);
|
|
590
|
+
}
|
|
591
|
+
},
|
|
592
|
+
getComponent(ListFooterComponent)
|
|
593
|
+
)
|
|
366
594
|
);
|
|
367
595
|
});
|
|
368
596
|
|
|
@@ -371,36 +599,63 @@ var ScrollAdjustHandler = class {
|
|
|
371
599
|
constructor(ctx) {
|
|
372
600
|
this.ctx = ctx;
|
|
373
601
|
this.appliedAdjust = 0;
|
|
374
|
-
this.pendingAdjust = 0;
|
|
375
602
|
this.busy = false;
|
|
376
|
-
this.
|
|
603
|
+
this.isPaused = false;
|
|
604
|
+
this.isDisabled = false;
|
|
377
605
|
this.context = ctx;
|
|
378
606
|
}
|
|
607
|
+
doAjdust() {
|
|
608
|
+
set$(this.context, "scrollAdjust", this.appliedAdjust);
|
|
609
|
+
this.busy = false;
|
|
610
|
+
}
|
|
379
611
|
requestAdjust(adjust, onAdjusted) {
|
|
612
|
+
if (this.isDisabled) {
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
380
615
|
const oldAdjustTop = peek$(this.context, "scrollAdjust");
|
|
381
616
|
if (oldAdjustTop === adjust) {
|
|
382
617
|
return;
|
|
383
618
|
}
|
|
384
619
|
this.appliedAdjust = adjust;
|
|
385
|
-
this.
|
|
386
|
-
const doAjdust = () => {
|
|
387
|
-
set$(this.context, "scrollAdjust", this.pendingAdjust);
|
|
388
|
-
onAdjusted(oldAdjustTop - this.pendingAdjust);
|
|
389
|
-
this.busy = false;
|
|
390
|
-
};
|
|
391
|
-
if (!this.busy) {
|
|
620
|
+
if (!this.busy && !this.isPaused) {
|
|
392
621
|
this.busy = true;
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
setTimeout(doAjdust, 50);
|
|
396
|
-
} else {
|
|
397
|
-
doAjdust();
|
|
398
|
-
}
|
|
622
|
+
this.doAjdust();
|
|
623
|
+
onAdjusted(oldAdjustTop - adjust);
|
|
399
624
|
}
|
|
400
625
|
}
|
|
401
626
|
getAppliedAdjust() {
|
|
402
627
|
return this.appliedAdjust;
|
|
403
628
|
}
|
|
629
|
+
pauseAdjust() {
|
|
630
|
+
this.isPaused = true;
|
|
631
|
+
}
|
|
632
|
+
setDisableAdjust(disable) {
|
|
633
|
+
this.isDisabled = disable;
|
|
634
|
+
}
|
|
635
|
+
// return true if it was paused
|
|
636
|
+
unPauseAdjust() {
|
|
637
|
+
if (this.isPaused) {
|
|
638
|
+
this.isPaused = false;
|
|
639
|
+
this.doAjdust();
|
|
640
|
+
return true;
|
|
641
|
+
}
|
|
642
|
+
return false;
|
|
643
|
+
}
|
|
644
|
+
};
|
|
645
|
+
var useCombinedRef = (...refs) => {
|
|
646
|
+
const callback = useCallback((element) => {
|
|
647
|
+
for (const ref of refs) {
|
|
648
|
+
if (!ref) {
|
|
649
|
+
continue;
|
|
650
|
+
}
|
|
651
|
+
if (isFunction(ref)) {
|
|
652
|
+
ref(element);
|
|
653
|
+
} else {
|
|
654
|
+
ref.current = element;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}, refs);
|
|
658
|
+
return callback;
|
|
404
659
|
};
|
|
405
660
|
|
|
406
661
|
// src/viewability.ts
|
|
@@ -453,11 +708,37 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
|
|
|
453
708
|
const { viewabilityConfig, onViewableItemsChanged } = viewabilityConfigCallbackPair;
|
|
454
709
|
const configId = viewabilityConfig.id;
|
|
455
710
|
const viewabilityState = mapViewabilityConfigCallbackPairs.get(configId);
|
|
456
|
-
const { viewableItems: previousViewableItems, start,
|
|
711
|
+
const { viewableItems: previousViewableItems, start, end } = viewabilityState;
|
|
712
|
+
const viewabilityTokens = /* @__PURE__ */ new Map();
|
|
713
|
+
for (const [containerId, value] of ctx.mapViewabilityAmountValues) {
|
|
714
|
+
viewabilityTokens.set(
|
|
715
|
+
containerId,
|
|
716
|
+
computeViewability(
|
|
717
|
+
state,
|
|
718
|
+
ctx,
|
|
719
|
+
viewabilityConfig,
|
|
720
|
+
containerId,
|
|
721
|
+
value.key,
|
|
722
|
+
scrollSize,
|
|
723
|
+
value.item,
|
|
724
|
+
value.index
|
|
725
|
+
)
|
|
726
|
+
);
|
|
727
|
+
}
|
|
457
728
|
const changed = [];
|
|
458
729
|
if (previousViewableItems) {
|
|
459
730
|
for (const viewToken of previousViewableItems) {
|
|
460
|
-
|
|
731
|
+
const containerId = findContainerId(ctx, viewToken.key);
|
|
732
|
+
if (!isViewable(
|
|
733
|
+
state,
|
|
734
|
+
ctx,
|
|
735
|
+
viewabilityConfig,
|
|
736
|
+
containerId,
|
|
737
|
+
viewToken.key,
|
|
738
|
+
scrollSize,
|
|
739
|
+
viewToken.item,
|
|
740
|
+
viewToken.index
|
|
741
|
+
)) {
|
|
461
742
|
viewToken.isViewable = false;
|
|
462
743
|
changed.push(viewToken);
|
|
463
744
|
}
|
|
@@ -468,12 +749,14 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
|
|
|
468
749
|
const item = data[i];
|
|
469
750
|
if (item) {
|
|
470
751
|
const key = getId(i);
|
|
471
|
-
|
|
752
|
+
const containerId = findContainerId(ctx, key);
|
|
753
|
+
if (isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
|
|
472
754
|
const viewToken = {
|
|
473
755
|
item,
|
|
474
756
|
key,
|
|
475
757
|
index: i,
|
|
476
|
-
isViewable: true
|
|
758
|
+
isViewable: true,
|
|
759
|
+
containerId
|
|
477
760
|
};
|
|
478
761
|
viewableItems.push(viewToken);
|
|
479
762
|
if (!(previousViewableItems == null ? void 0 : previousViewableItems.find((v) => v.key === viewToken.key))) {
|
|
@@ -491,20 +774,27 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
|
|
|
491
774
|
viewabilityState.viewableItems = viewableItems;
|
|
492
775
|
for (let i = 0; i < changed.length; i++) {
|
|
493
776
|
const change = changed[i];
|
|
494
|
-
maybeUpdateViewabilityCallback(ctx, configId, change);
|
|
777
|
+
maybeUpdateViewabilityCallback(ctx, configId, change.containerId, change);
|
|
495
778
|
}
|
|
496
779
|
if (onViewableItemsChanged) {
|
|
497
780
|
onViewableItemsChanged({ viewableItems, changed });
|
|
498
781
|
}
|
|
499
782
|
}
|
|
783
|
+
for (const [containerId, value] of ctx.mapViewabilityAmountValues) {
|
|
784
|
+
if (value.sizeVisible < 0) {
|
|
785
|
+
ctx.mapViewabilityAmountValues.delete(containerId);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
500
788
|
}
|
|
501
|
-
function
|
|
502
|
-
const { sizes, positions, scroll } = state;
|
|
789
|
+
function computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
|
|
790
|
+
const { sizes, positions, scroll: scrollState, scrollAdjustHandler } = state;
|
|
503
791
|
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
504
792
|
const { itemVisiblePercentThreshold, viewAreaCoveragePercentThreshold } = viewabilityConfig;
|
|
505
793
|
const viewAreaMode = viewAreaCoveragePercentThreshold != null;
|
|
506
794
|
const viewablePercentThreshold = viewAreaMode ? viewAreaCoveragePercentThreshold : itemVisiblePercentThreshold;
|
|
507
|
-
const
|
|
795
|
+
const previousScrollAdjust = scrollAdjustHandler.getAppliedAdjust();
|
|
796
|
+
const scroll = scrollState - previousScrollAdjust - topPad;
|
|
797
|
+
const top = positions.get(key) - scroll;
|
|
508
798
|
const size = sizes.get(key) || 0;
|
|
509
799
|
const bottom = top + size;
|
|
510
800
|
const isEntirelyVisible = top >= 0 && bottom <= scrollSize && bottom > top;
|
|
@@ -513,7 +803,6 @@ function isViewable(state, ctx, viewabilityConfig, key, scrollSize, item, index)
|
|
|
513
803
|
const percentOfScroller = size ? 100 * (sizeVisible / scrollSize) : 0;
|
|
514
804
|
const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
|
|
515
805
|
const isViewable2 = percent >= viewablePercentThreshold;
|
|
516
|
-
const containerId = findContainerId(ctx, key);
|
|
517
806
|
const value = {
|
|
518
807
|
index,
|
|
519
808
|
isViewable: isViewable2,
|
|
@@ -523,15 +812,21 @@ function isViewable(state, ctx, viewabilityConfig, key, scrollSize, item, index)
|
|
|
523
812
|
percentOfScroller,
|
|
524
813
|
sizeVisible,
|
|
525
814
|
size,
|
|
526
|
-
|
|
527
|
-
|
|
815
|
+
scrollSize,
|
|
816
|
+
containerId
|
|
528
817
|
};
|
|
529
|
-
ctx.mapViewabilityAmountValues.
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
cb
|
|
818
|
+
if (JSON.stringify(value) !== JSON.stringify(ctx.mapViewabilityAmountValues.get(containerId))) {
|
|
819
|
+
ctx.mapViewabilityAmountValues.set(containerId, value);
|
|
820
|
+
const cb = ctx.mapViewabilityAmountCallbacks.get(containerId);
|
|
821
|
+
if (cb) {
|
|
822
|
+
cb(value);
|
|
823
|
+
}
|
|
533
824
|
}
|
|
534
|
-
return
|
|
825
|
+
return value;
|
|
826
|
+
}
|
|
827
|
+
function isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
|
|
828
|
+
const value = ctx.mapViewabilityAmountValues.get(containerId) || computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
|
|
829
|
+
return value.isViewable;
|
|
535
830
|
}
|
|
536
831
|
function findContainerId(ctx, key) {
|
|
537
832
|
const numContainers = peek$(ctx, "numContainers");
|
|
@@ -543,8 +838,8 @@ function findContainerId(ctx, key) {
|
|
|
543
838
|
}
|
|
544
839
|
return -1;
|
|
545
840
|
}
|
|
546
|
-
function maybeUpdateViewabilityCallback(ctx, configId, viewToken) {
|
|
547
|
-
const key =
|
|
841
|
+
function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
|
|
842
|
+
const key = containerId + configId;
|
|
548
843
|
ctx.mapViewabilityValues.set(key, viewToken);
|
|
549
844
|
const cb = ctx.mapViewabilityCallbacks.get(key);
|
|
550
845
|
cb == null ? void 0 : cb(viewToken);
|
|
@@ -553,13 +848,25 @@ function maybeUpdateViewabilityCallback(ctx, configId, viewToken) {
|
|
|
553
848
|
// src/LegendList.tsx
|
|
554
849
|
var DEFAULT_DRAW_DISTANCE = 250;
|
|
555
850
|
var DEFAULT_ITEM_SIZE = 100;
|
|
556
|
-
|
|
557
|
-
|
|
851
|
+
function createColumnWrapperStyle(contentContainerStyle) {
|
|
852
|
+
const { gap, columnGap, rowGap } = contentContainerStyle;
|
|
853
|
+
if (gap || columnGap || rowGap) {
|
|
854
|
+
contentContainerStyle.gap = void 0;
|
|
855
|
+
contentContainerStyle.columnGap = void 0;
|
|
856
|
+
contentContainerStyle.rowGap = void 0;
|
|
857
|
+
return {
|
|
858
|
+
gap,
|
|
859
|
+
columnGap,
|
|
860
|
+
rowGap
|
|
861
|
+
};
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
var LegendList = typedForwardRef(function LegendList2(props, forwardedRef) {
|
|
865
|
+
return /* @__PURE__ */ React6.createElement(StateProvider, null, /* @__PURE__ */ React6.createElement(LegendListInner, { ...props, ref: forwardedRef }));
|
|
558
866
|
});
|
|
559
|
-
var LegendListInner =
|
|
560
|
-
var _a, _b, _c, _d, _e;
|
|
867
|
+
var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
|
|
561
868
|
const {
|
|
562
|
-
data,
|
|
869
|
+
data: dataProp = [],
|
|
563
870
|
initialScrollIndex,
|
|
564
871
|
initialScrollOffset,
|
|
565
872
|
horizontal,
|
|
@@ -572,66 +879,111 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
572
879
|
alignItemsAtEnd = false,
|
|
573
880
|
maintainVisibleContentPosition = false,
|
|
574
881
|
onScroll: onScrollProp,
|
|
882
|
+
onMomentumScrollEnd,
|
|
575
883
|
numColumns: numColumnsProp = 1,
|
|
884
|
+
columnWrapperStyle,
|
|
576
885
|
keyExtractor: keyExtractorProp,
|
|
577
886
|
renderItem,
|
|
578
887
|
estimatedItemSize,
|
|
579
888
|
getEstimatedItemSize,
|
|
889
|
+
suggestEstimatedItemSize,
|
|
580
890
|
ListEmptyComponent,
|
|
581
891
|
onItemSizeChanged,
|
|
582
|
-
scrollEventThrottle,
|
|
583
892
|
refScrollView,
|
|
584
893
|
waitForInitialLayout = true,
|
|
585
894
|
extraData,
|
|
895
|
+
contentContainerStyle: contentContainerStyleProp,
|
|
896
|
+
style: styleProp,
|
|
586
897
|
onLayout: onLayoutProp,
|
|
898
|
+
onRefresh,
|
|
899
|
+
refreshing,
|
|
900
|
+
progressViewOffset,
|
|
901
|
+
refreshControl,
|
|
902
|
+
initialContainerPoolRatio = 2,
|
|
903
|
+
viewabilityConfig,
|
|
904
|
+
viewabilityConfigCallbackPairs,
|
|
905
|
+
onViewableItemsChanged,
|
|
587
906
|
...rest
|
|
588
907
|
} = props;
|
|
589
|
-
const { style, contentContainerStyle } = props;
|
|
590
908
|
const callbacks = useRef({
|
|
591
909
|
onStartReached: rest.onStartReached,
|
|
592
910
|
onEndReached: rest.onEndReached
|
|
593
911
|
});
|
|
594
912
|
callbacks.current.onStartReached = rest.onStartReached;
|
|
595
913
|
callbacks.current.onEndReached = rest.onEndReached;
|
|
914
|
+
const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
|
|
915
|
+
const style = { ...StyleSheet.flatten(styleProp) };
|
|
916
|
+
const stylePaddingTopState = ((style == null ? void 0 : style.paddingTop) || 0) + ((contentContainerStyle == null ? void 0 : contentContainerStyle.paddingTop) || 0);
|
|
917
|
+
if (style == null ? void 0 : style.paddingTop) {
|
|
918
|
+
style.paddingTop = void 0;
|
|
919
|
+
}
|
|
920
|
+
if (contentContainerStyle == null ? void 0 : contentContainerStyle.paddingTop) {
|
|
921
|
+
contentContainerStyle.paddingTop = void 0;
|
|
922
|
+
}
|
|
596
923
|
const ctx = useStateContext();
|
|
924
|
+
ctx.columnWrapperStyle = columnWrapperStyle || (contentContainerStyle ? createColumnWrapperStyle(contentContainerStyle) : void 0);
|
|
597
925
|
const refScroller = useRef(null);
|
|
598
|
-
const
|
|
926
|
+
const combinedRef = useCombinedRef(refScroller, refScrollView);
|
|
927
|
+
const scrollBuffer = (drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE) || 1;
|
|
599
928
|
const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (item, index) => index.toString();
|
|
600
929
|
const refState = useRef();
|
|
601
930
|
const getId = (index) => {
|
|
602
|
-
var
|
|
603
|
-
const
|
|
604
|
-
if (!
|
|
931
|
+
var _a;
|
|
932
|
+
const data = (_a = refState.current) == null ? void 0 : _a.data;
|
|
933
|
+
if (!data) {
|
|
605
934
|
return "";
|
|
606
935
|
}
|
|
607
|
-
const ret = index <
|
|
936
|
+
const ret = index < data.length ? keyExtractor ? keyExtractor(data[index], index) : index : null;
|
|
608
937
|
return `${ret}`;
|
|
609
938
|
};
|
|
610
|
-
const getItemSize = (key, index,
|
|
611
|
-
|
|
612
|
-
const sizeKnown =
|
|
939
|
+
const getItemSize = (key, index, data, useAverageSize = false) => {
|
|
940
|
+
const state = refState.current;
|
|
941
|
+
const sizeKnown = state.sizesKnown.get(key);
|
|
613
942
|
if (sizeKnown !== void 0) {
|
|
614
943
|
return sizeKnown;
|
|
615
944
|
}
|
|
616
|
-
|
|
617
|
-
|
|
945
|
+
let size;
|
|
946
|
+
if (size === void 0 && useAverageSize) {
|
|
947
|
+
const itemType = "";
|
|
948
|
+
const average = state.averageSizes[itemType];
|
|
949
|
+
if (average) {
|
|
950
|
+
size = roundSize(average.avg);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
const sizePrevious = state.sizesKnown.get(key);
|
|
954
|
+
if (sizePrevious !== void 0) {
|
|
955
|
+
return sizePrevious;
|
|
956
|
+
}
|
|
957
|
+
if (size === void 0) {
|
|
958
|
+
size = getEstimatedItemSize ? getEstimatedItemSize(index, data) : estimatedItemSize != null ? estimatedItemSize : DEFAULT_ITEM_SIZE;
|
|
959
|
+
}
|
|
960
|
+
state.sizes.set(key, size);
|
|
618
961
|
return size;
|
|
619
962
|
};
|
|
620
|
-
const
|
|
621
|
-
|
|
963
|
+
const calculateOffsetForIndex = (index = initialScrollIndex) => {
|
|
964
|
+
var _a;
|
|
965
|
+
const data = dataProp;
|
|
966
|
+
if (index !== void 0) {
|
|
622
967
|
let offset = 0;
|
|
623
|
-
|
|
968
|
+
const canGetSize = !!refState.current;
|
|
969
|
+
if (canGetSize || getEstimatedItemSize) {
|
|
970
|
+
const sizeFn = (index2) => {
|
|
971
|
+
if (canGetSize) {
|
|
972
|
+
return getItemSize(getId(index2), index2, data[index2]);
|
|
973
|
+
}
|
|
974
|
+
return getEstimatedItemSize(index2, data[index2]);
|
|
975
|
+
};
|
|
624
976
|
for (let i = 0; i < index; i++) {
|
|
625
|
-
offset +=
|
|
977
|
+
offset += sizeFn(i);
|
|
626
978
|
}
|
|
627
979
|
} else if (estimatedItemSize) {
|
|
628
980
|
offset = index * estimatedItemSize;
|
|
629
981
|
}
|
|
630
|
-
return offset / numColumnsProp;
|
|
982
|
+
return offset / numColumnsProp - (((_a = refState.current) == null ? void 0 : _a.scrollAdjustHandler.getAppliedAdjust()) || 0);
|
|
631
983
|
}
|
|
632
984
|
return 0;
|
|
633
985
|
};
|
|
634
|
-
const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : useMemo(
|
|
986
|
+
const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : useMemo(calculateOffsetForIndex, []);
|
|
635
987
|
if (!refState.current) {
|
|
636
988
|
const initialScrollLength = Dimensions.get("window")[horizontal ? "width" : "height"];
|
|
637
989
|
refState.current = {
|
|
@@ -639,14 +991,11 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
639
991
|
positions: /* @__PURE__ */ new Map(),
|
|
640
992
|
columns: /* @__PURE__ */ new Map(),
|
|
641
993
|
pendingAdjust: 0,
|
|
642
|
-
waitingForMicrotask: false,
|
|
643
994
|
isStartReached: initialContentOffset < initialScrollLength * onStartReachedThreshold,
|
|
644
995
|
isEndReached: false,
|
|
645
996
|
isAtBottom: false,
|
|
646
997
|
isAtTop: false,
|
|
647
|
-
data,
|
|
648
|
-
idsInFirstRender: void 0,
|
|
649
|
-
hasScrolled: false,
|
|
998
|
+
data: dataProp,
|
|
650
999
|
scrollLength: initialScrollLength,
|
|
651
1000
|
startBuffered: 0,
|
|
652
1001
|
startNoBuffer: 0,
|
|
@@ -666,35 +1015,48 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
666
1015
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
667
1016
|
scrollHistory: [],
|
|
668
1017
|
scrollVelocity: 0,
|
|
669
|
-
|
|
1018
|
+
sizesKnown: /* @__PURE__ */ new Map(),
|
|
670
1019
|
timeoutSizeMessage: 0,
|
|
671
1020
|
scrollTimer: void 0,
|
|
672
1021
|
belowAnchorElementPositions: void 0,
|
|
673
1022
|
rowHeights: /* @__PURE__ */ new Map(),
|
|
674
1023
|
startReachedBlockedByTimer: false,
|
|
1024
|
+
endReachedBlockedByTimer: false,
|
|
675
1025
|
scrollForNextCalculateItemsInView: void 0,
|
|
676
|
-
enableScrollForNextCalculateItemsInView: true
|
|
1026
|
+
enableScrollForNextCalculateItemsInView: true,
|
|
1027
|
+
minIndexSizeChanged: 0,
|
|
1028
|
+
numPendingInitialLayout: 0,
|
|
1029
|
+
queuedCalculateItemsInView: 0,
|
|
1030
|
+
lastBatchingAction: Date.now(),
|
|
1031
|
+
averageSizes: {},
|
|
1032
|
+
onScroll: onScrollProp
|
|
677
1033
|
};
|
|
678
|
-
|
|
679
|
-
if (maintainVisibleContentPosition) {
|
|
680
|
-
if (initialScrollIndex) {
|
|
1034
|
+
const dataLength = dataProp.length;
|
|
1035
|
+
if (maintainVisibleContentPosition && dataLength > 0) {
|
|
1036
|
+
if (initialScrollIndex && initialScrollIndex < dataLength) {
|
|
681
1037
|
refState.current.anchorElement = {
|
|
682
1038
|
coordinate: initialContentOffset,
|
|
683
1039
|
id: getId(initialScrollIndex)
|
|
684
1040
|
};
|
|
685
|
-
} else if (
|
|
1041
|
+
} else if (dataLength > 0) {
|
|
686
1042
|
refState.current.anchorElement = {
|
|
687
1043
|
coordinate: initialContentOffset,
|
|
688
1044
|
id: getId(0)
|
|
689
1045
|
};
|
|
690
1046
|
} else {
|
|
691
|
-
|
|
1047
|
+
__DEV__ && warnDevOnce(
|
|
1048
|
+
"maintainVisibleContentPosition",
|
|
1049
|
+
"[legend-list] maintainVisibleContentPosition was not able to find an anchor element"
|
|
1050
|
+
);
|
|
692
1051
|
}
|
|
693
1052
|
}
|
|
694
1053
|
set$(ctx, "scrollAdjust", 0);
|
|
695
1054
|
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
|
|
696
1055
|
set$(ctx, "extraData", extraData);
|
|
697
1056
|
}
|
|
1057
|
+
const didDataChange = refState.current.data !== dataProp;
|
|
1058
|
+
refState.current.data = dataProp;
|
|
1059
|
+
refState.current.onScroll = onScrollProp;
|
|
698
1060
|
const getAnchorElementIndex = () => {
|
|
699
1061
|
const state = refState.current;
|
|
700
1062
|
if (state.anchorElement) {
|
|
@@ -703,12 +1065,59 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
703
1065
|
}
|
|
704
1066
|
return void 0;
|
|
705
1067
|
};
|
|
1068
|
+
const scrollToIndex = ({
|
|
1069
|
+
index,
|
|
1070
|
+
viewOffset = 0,
|
|
1071
|
+
animated = true,
|
|
1072
|
+
viewPosition = 0
|
|
1073
|
+
}) => {
|
|
1074
|
+
var _a;
|
|
1075
|
+
const state = refState.current;
|
|
1076
|
+
const firstIndexOffset = calculateOffsetForIndex(index);
|
|
1077
|
+
let firstIndexScrollPostion = firstIndexOffset - viewOffset;
|
|
1078
|
+
const diff = Math.abs(state.scroll - firstIndexScrollPostion);
|
|
1079
|
+
const needsReanchoring = maintainVisibleContentPosition && diff > 100;
|
|
1080
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
1081
|
+
if (needsReanchoring) {
|
|
1082
|
+
const id = getId(index);
|
|
1083
|
+
state.anchorElement = { id, coordinate: firstIndexOffset };
|
|
1084
|
+
(_a = state.belowAnchorElementPositions) == null ? void 0 : _a.clear();
|
|
1085
|
+
state.positions.clear();
|
|
1086
|
+
calcTotalSizesAndPositions({ forgetPositions: true });
|
|
1087
|
+
state.startBufferedId = id;
|
|
1088
|
+
state.minIndexSizeChanged = index;
|
|
1089
|
+
firstIndexScrollPostion = firstIndexOffset - viewOffset + state.scrollAdjustHandler.getAppliedAdjust();
|
|
1090
|
+
}
|
|
1091
|
+
if (viewPosition) {
|
|
1092
|
+
firstIndexScrollPostion -= viewPosition * (state.scrollLength - getItemSize(getId(index), index, state.data[index]));
|
|
1093
|
+
}
|
|
1094
|
+
state.scrollAdjustHandler.setDisableAdjust(true);
|
|
1095
|
+
state.scrollingToOffset = firstIndexScrollPostion;
|
|
1096
|
+
scrollTo(firstIndexScrollPostion, animated);
|
|
1097
|
+
};
|
|
1098
|
+
const setDidLayout = () => {
|
|
1099
|
+
refState.current.queuedInitialLayout = true;
|
|
1100
|
+
checkAtBottom();
|
|
1101
|
+
if (initialScrollIndex) {
|
|
1102
|
+
queueMicrotask(() => {
|
|
1103
|
+
scrollToIndex({ index: initialScrollIndex, animated: false });
|
|
1104
|
+
requestAnimationFrame(() => {
|
|
1105
|
+
set$(ctx, "containersDidLayout", true);
|
|
1106
|
+
});
|
|
1107
|
+
});
|
|
1108
|
+
} else {
|
|
1109
|
+
queueMicrotask(() => {
|
|
1110
|
+
set$(ctx, "containersDidLayout", true);
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
};
|
|
706
1114
|
const addTotalSize = useCallback((key, add, totalSizeBelowAnchor) => {
|
|
707
1115
|
const state = refState.current;
|
|
708
|
-
const
|
|
1116
|
+
const { indexByKey, anchorElement } = state;
|
|
1117
|
+
const index = key === null ? 0 : indexByKey.get(key);
|
|
709
1118
|
let isAboveAnchor = false;
|
|
710
1119
|
if (maintainVisibleContentPosition) {
|
|
711
|
-
if (
|
|
1120
|
+
if (anchorElement && index < getAnchorElementIndex()) {
|
|
712
1121
|
isAboveAnchor = true;
|
|
713
1122
|
}
|
|
714
1123
|
}
|
|
@@ -721,29 +1130,30 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
721
1130
|
state.totalSizeBelowAnchor += add;
|
|
722
1131
|
}
|
|
723
1132
|
}
|
|
724
|
-
let applyAdjustValue =
|
|
725
|
-
|
|
726
|
-
|
|
1133
|
+
let applyAdjustValue = 0;
|
|
1134
|
+
let resultSize = state.totalSize;
|
|
1135
|
+
if (maintainVisibleContentPosition && anchorElement !== void 0) {
|
|
1136
|
+
const newAdjust = anchorElement.coordinate - state.totalSizeBelowAnchor;
|
|
727
1137
|
applyAdjustValue = -newAdjust;
|
|
728
1138
|
state.belowAnchorElementPositions = buildElementPositionsBelowAnchor();
|
|
729
1139
|
state.rowHeights.clear();
|
|
1140
|
+
if (applyAdjustValue !== void 0) {
|
|
1141
|
+
resultSize -= applyAdjustValue;
|
|
1142
|
+
state.scrollAdjustHandler.requestAdjust(applyAdjustValue, (diff) => {
|
|
1143
|
+
state.scroll -= diff;
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
730
1146
|
}
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
if (applyAdjustValue !== void 0) {
|
|
734
|
-
resultSize -= applyAdjustValue;
|
|
735
|
-
refState.current.scrollAdjustHandler.requestAdjust(applyAdjustValue, (diff) => {
|
|
736
|
-
state.scroll -= diff;
|
|
737
|
-
});
|
|
738
|
-
}
|
|
739
|
-
set$(ctx, "totalSize", resultSize);
|
|
1147
|
+
set$(ctx, "totalSize", state.totalSize);
|
|
1148
|
+
set$(ctx, "totalSizeWithScrollAdjust", resultSize);
|
|
740
1149
|
if (alignItemsAtEnd) {
|
|
741
|
-
|
|
1150
|
+
updateAlignItemsPaddingTop();
|
|
742
1151
|
}
|
|
743
1152
|
}, []);
|
|
744
1153
|
const getRowHeight = (n) => {
|
|
745
|
-
const { rowHeights } = refState.current;
|
|
746
|
-
|
|
1154
|
+
const { rowHeights, data } = refState.current;
|
|
1155
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
1156
|
+
if (numColumns === 1) {
|
|
747
1157
|
const id = getId(n);
|
|
748
1158
|
return getItemSize(id, n, data[n]);
|
|
749
1159
|
}
|
|
@@ -751,8 +1161,8 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
751
1161
|
return rowHeights.get(n) || 0;
|
|
752
1162
|
}
|
|
753
1163
|
let rowHeight = 0;
|
|
754
|
-
const startEl = n *
|
|
755
|
-
for (let i = startEl; i < startEl +
|
|
1164
|
+
const startEl = n * numColumns;
|
|
1165
|
+
for (let i = startEl; i < startEl + numColumns && i < data.length; i++) {
|
|
756
1166
|
const id = getId(i);
|
|
757
1167
|
const size = getItemSize(id, i, data[i]);
|
|
758
1168
|
rowHeight = Math.max(rowHeight, size);
|
|
@@ -765,16 +1175,17 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
765
1175
|
if (!state.anchorElement) {
|
|
766
1176
|
return /* @__PURE__ */ new Map();
|
|
767
1177
|
}
|
|
768
|
-
let top = state.anchorElement.coordinate;
|
|
769
1178
|
const anchorIndex = state.indexByKey.get(state.anchorElement.id);
|
|
770
1179
|
if (anchorIndex === 0) {
|
|
771
1180
|
return /* @__PURE__ */ new Map();
|
|
772
1181
|
}
|
|
773
1182
|
const map = state.belowAnchorElementPositions || /* @__PURE__ */ new Map();
|
|
1183
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
1184
|
+
let top = state.anchorElement.coordinate;
|
|
774
1185
|
for (let i = anchorIndex - 1; i >= 0; i--) {
|
|
775
1186
|
const id = getId(i);
|
|
776
|
-
const rowNumber = Math.floor(i /
|
|
777
|
-
if (i %
|
|
1187
|
+
const rowNumber = Math.floor(i / numColumns);
|
|
1188
|
+
if (i % numColumns === 0) {
|
|
778
1189
|
top -= getRowHeight(rowNumber);
|
|
779
1190
|
}
|
|
780
1191
|
map.set(id, top);
|
|
@@ -782,37 +1193,116 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
782
1193
|
return map;
|
|
783
1194
|
};
|
|
784
1195
|
const getElementPositionBelowAchor = (id) => {
|
|
1196
|
+
var _a;
|
|
785
1197
|
const state = refState.current;
|
|
786
1198
|
if (!refState.current.belowAnchorElementPositions) {
|
|
787
1199
|
state.belowAnchorElementPositions = buildElementPositionsBelowAnchor();
|
|
788
1200
|
}
|
|
789
1201
|
const res = state.belowAnchorElementPositions.get(id);
|
|
790
1202
|
if (res === void 0) {
|
|
791
|
-
|
|
1203
|
+
console.warn(`Undefined position below anchor ${id} ${(_a = state.anchorElement) == null ? void 0 : _a.id}`);
|
|
1204
|
+
return 0;
|
|
792
1205
|
}
|
|
793
1206
|
return res;
|
|
794
1207
|
};
|
|
795
|
-
const
|
|
1208
|
+
const fixGaps = useCallback(() => {
|
|
1209
|
+
var _a;
|
|
1210
|
+
const state = refState.current;
|
|
1211
|
+
const { data, scrollLength, positions, startBuffered, endBuffered } = state;
|
|
1212
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
1213
|
+
if (!data || scrollLength === 0 || numColumns > 1) {
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
const numContainers = ctx.values.get("numContainers");
|
|
1217
|
+
let numMeasurements = 0;
|
|
1218
|
+
for (let i = 0; i < numContainers; i++) {
|
|
1219
|
+
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1220
|
+
const isSizeKnown = state.sizesKnown.get(itemKey);
|
|
1221
|
+
if (itemKey && !isSizeKnown) {
|
|
1222
|
+
const containerRef = ctx.viewRefs.get(i);
|
|
1223
|
+
if (containerRef) {
|
|
1224
|
+
let measured;
|
|
1225
|
+
(_a = containerRef.current) == null ? void 0 : _a.measure((x, y, width, height) => {
|
|
1226
|
+
measured = { width, height };
|
|
1227
|
+
});
|
|
1228
|
+
numMeasurements++;
|
|
1229
|
+
if (measured) {
|
|
1230
|
+
const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
|
|
1231
|
+
updateItemSize(
|
|
1232
|
+
itemKey,
|
|
1233
|
+
size,
|
|
1234
|
+
/*fromFixGaps*/
|
|
1235
|
+
true
|
|
1236
|
+
);
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
if (numMeasurements > 0) {
|
|
1242
|
+
let top;
|
|
1243
|
+
const diffs = /* @__PURE__ */ new Map();
|
|
1244
|
+
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
1245
|
+
const id = getId(i);
|
|
1246
|
+
if (top === void 0) {
|
|
1247
|
+
top = positions.get(id);
|
|
1248
|
+
}
|
|
1249
|
+
if (positions.get(id) !== top) {
|
|
1250
|
+
diffs.set(id, top - positions.get(id));
|
|
1251
|
+
positions.set(id, top);
|
|
1252
|
+
}
|
|
1253
|
+
const size = getItemSize(id, i, data[i]);
|
|
1254
|
+
const bottom = top + size;
|
|
1255
|
+
top = bottom;
|
|
1256
|
+
}
|
|
1257
|
+
for (let i = 0; i < numContainers; i++) {
|
|
1258
|
+
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1259
|
+
const diff = diffs.get(itemKey);
|
|
1260
|
+
if (diff) {
|
|
1261
|
+
const prevPos = peek$(ctx, `containerPosition${i}`);
|
|
1262
|
+
const newPos = prevPos.top + diff;
|
|
1263
|
+
if (prevPos.top !== newPos) {
|
|
1264
|
+
const pos = { ...prevPos };
|
|
1265
|
+
pos.relativeCoordinate += diff;
|
|
1266
|
+
pos.top += diff;
|
|
1267
|
+
set$(ctx, `containerPosition${i}`, pos);
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
}, []);
|
|
1273
|
+
const calculateItemsInView = useCallback(() => {
|
|
1274
|
+
var _a;
|
|
796
1275
|
const state = refState.current;
|
|
797
1276
|
const {
|
|
798
|
-
data
|
|
1277
|
+
data,
|
|
799
1278
|
scrollLength,
|
|
800
|
-
scroll: scrollState,
|
|
801
1279
|
startBufferedId: startBufferedIdOrig,
|
|
802
1280
|
positions,
|
|
803
1281
|
columns,
|
|
804
|
-
scrollAdjustHandler
|
|
1282
|
+
scrollAdjustHandler,
|
|
1283
|
+
scrollVelocity: speed
|
|
805
1284
|
} = state;
|
|
806
|
-
if (
|
|
807
|
-
state.waitingForMicrotask = false;
|
|
808
|
-
}
|
|
809
|
-
if (!data2) {
|
|
1285
|
+
if (!data || scrollLength === 0) {
|
|
810
1286
|
return;
|
|
811
1287
|
}
|
|
812
|
-
const
|
|
1288
|
+
const totalSize = peek$(ctx, "totalSizeWithScrollAdjust");
|
|
1289
|
+
const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
|
|
1290
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
813
1291
|
const previousScrollAdjust = scrollAdjustHandler.getAppliedAdjust();
|
|
814
1292
|
const scrollExtra = Math.max(-16, Math.min(16, speed)) * 16;
|
|
815
|
-
|
|
1293
|
+
let scrollState = state.scroll;
|
|
1294
|
+
if (!state.queuedInitialLayout && initialScrollIndex) {
|
|
1295
|
+
const updatedOffset = calculateOffsetForIndex(initialScrollIndex);
|
|
1296
|
+
scrollState = updatedOffset;
|
|
1297
|
+
}
|
|
1298
|
+
let scroll = scrollState - previousScrollAdjust - topPad;
|
|
1299
|
+
if (scroll + scrollLength > totalSize) {
|
|
1300
|
+
scroll = totalSize - scrollLength;
|
|
1301
|
+
}
|
|
1302
|
+
if (ENABLE_DEBUG_VIEW) {
|
|
1303
|
+
set$(ctx, "debugRawScroll", scrollState);
|
|
1304
|
+
set$(ctx, "debugComputedScroll", scroll);
|
|
1305
|
+
}
|
|
816
1306
|
let scrollBufferTop = scrollBuffer;
|
|
817
1307
|
let scrollBufferBottom = scrollBuffer;
|
|
818
1308
|
if (scrollExtra > 8) {
|
|
@@ -835,8 +1325,11 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
835
1325
|
let startBufferedId = null;
|
|
836
1326
|
let endNoBuffer = null;
|
|
837
1327
|
let endBuffered = null;
|
|
838
|
-
|
|
839
|
-
|
|
1328
|
+
let loopStart = startBufferedIdOrig ? state.indexByKey.get(startBufferedIdOrig) || 0 : 0;
|
|
1329
|
+
if (state.minIndexSizeChanged !== void 0) {
|
|
1330
|
+
loopStart = Math.min(state.minIndexSizeChanged, loopStart);
|
|
1331
|
+
state.minIndexSizeChanged = void 0;
|
|
1332
|
+
}
|
|
840
1333
|
const anchorElementIndex = getAnchorElementIndex();
|
|
841
1334
|
for (let i = loopStart; i >= 0; i--) {
|
|
842
1335
|
const id = getId(i);
|
|
@@ -849,7 +1342,13 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
849
1342
|
}
|
|
850
1343
|
const top2 = newPosition || positions.get(id);
|
|
851
1344
|
if (top2 !== void 0) {
|
|
852
|
-
const size = getItemSize(
|
|
1345
|
+
const size = getItemSize(
|
|
1346
|
+
id,
|
|
1347
|
+
i,
|
|
1348
|
+
data[i],
|
|
1349
|
+
/*useAverageSize*/
|
|
1350
|
+
true
|
|
1351
|
+
);
|
|
853
1352
|
const bottom = top2 + size;
|
|
854
1353
|
if (bottom > scroll - scrollBuffer) {
|
|
855
1354
|
loopStart = i;
|
|
@@ -858,7 +1357,6 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
858
1357
|
}
|
|
859
1358
|
}
|
|
860
1359
|
}
|
|
861
|
-
const numColumns = peek$(ctx, "numColumns");
|
|
862
1360
|
const loopStartMod = loopStart % numColumns;
|
|
863
1361
|
if (loopStartMod > 0) {
|
|
864
1362
|
loopStart -= loopStartMod;
|
|
@@ -874,15 +1372,21 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
874
1372
|
topOffset = positions.get(id);
|
|
875
1373
|
}
|
|
876
1374
|
if (id === ((_a2 = state.anchorElement) == null ? void 0 : _a2.id)) {
|
|
877
|
-
topOffset =
|
|
1375
|
+
topOffset = state.anchorElement.coordinate;
|
|
878
1376
|
}
|
|
879
1377
|
return topOffset;
|
|
880
1378
|
};
|
|
881
|
-
for (let i = loopStart; i <
|
|
1379
|
+
for (let i = Math.max(0, loopStart); i < data.length; i++) {
|
|
882
1380
|
const id = getId(i);
|
|
883
|
-
const size = getItemSize(
|
|
1381
|
+
const size = getItemSize(
|
|
1382
|
+
id,
|
|
1383
|
+
i,
|
|
1384
|
+
data[i],
|
|
1385
|
+
/*useAverageSize*/
|
|
1386
|
+
true
|
|
1387
|
+
);
|
|
884
1388
|
maxSizeInRow = Math.max(maxSizeInRow, size);
|
|
885
|
-
if (top === void 0) {
|
|
1389
|
+
if (top === void 0 || id === ((_a = state.anchorElement) == null ? void 0 : _a.id)) {
|
|
886
1390
|
top = getInitialTop(i);
|
|
887
1391
|
}
|
|
888
1392
|
if (positions.get(id) !== top) {
|
|
@@ -935,6 +1439,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
935
1439
|
if (startBuffered !== null && endBuffered !== null) {
|
|
936
1440
|
const prevNumContainers = ctx.values.get("numContainers");
|
|
937
1441
|
let numContainers = prevNumContainers;
|
|
1442
|
+
let didWarnMoreContainers = false;
|
|
938
1443
|
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
939
1444
|
let isContained = false;
|
|
940
1445
|
const id = getId(i);
|
|
@@ -968,18 +1473,19 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
968
1473
|
if (furthestIndex >= 0) {
|
|
969
1474
|
set$(ctx, `containerItemKey${furthestIndex}`, id);
|
|
970
1475
|
const index = state.indexByKey.get(id);
|
|
971
|
-
set$(ctx, `containerItemData${furthestIndex}`,
|
|
1476
|
+
set$(ctx, `containerItemData${furthestIndex}`, data[index]);
|
|
972
1477
|
} else {
|
|
973
1478
|
const containerId = numContainers;
|
|
974
1479
|
numContainers++;
|
|
975
1480
|
set$(ctx, `containerItemKey${containerId}`, id);
|
|
976
1481
|
const index = state.indexByKey.get(id);
|
|
977
|
-
set$(ctx, `containerItemData${containerId}`,
|
|
1482
|
+
set$(ctx, `containerItemData${containerId}`, data[index]);
|
|
978
1483
|
set$(ctx, `containerPosition${containerId}`, ANCHORED_POSITION_OUT_OF_VIEW);
|
|
979
1484
|
set$(ctx, `containerColumn${containerId}`, -1);
|
|
980
|
-
if (__DEV__ && numContainers > peek$(ctx, "numContainersPooled")) {
|
|
1485
|
+
if (__DEV__ && !didWarnMoreContainers && numContainers > peek$(ctx, "numContainersPooled")) {
|
|
1486
|
+
didWarnMoreContainers = true;
|
|
981
1487
|
console.warn(
|
|
982
|
-
"[legend-list] No container to recycle, so creating one on demand. This can be a performance issue and is likely caused by the estimatedItemSize being too
|
|
1488
|
+
"[legend-list] No container to recycle, so creating one on demand. This can be a minor performance issue and is likely caused by the estimatedItemSize being too large. Consider decreasing estimatedItemSize. numContainers:",
|
|
983
1489
|
numContainers
|
|
984
1490
|
);
|
|
985
1491
|
}
|
|
@@ -989,19 +1495,19 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
989
1495
|
if (numContainers !== prevNumContainers) {
|
|
990
1496
|
set$(ctx, "numContainers", numContainers);
|
|
991
1497
|
if (numContainers > peek$(ctx, "numContainersPooled")) {
|
|
992
|
-
set$(ctx, "numContainersPooled", numContainers);
|
|
1498
|
+
set$(ctx, "numContainersPooled", Math.ceil(numContainers * 1.5));
|
|
993
1499
|
}
|
|
994
1500
|
}
|
|
995
1501
|
for (let i = 0; i < numContainers; i++) {
|
|
996
1502
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
997
1503
|
const itemIndex = state.indexByKey.get(itemKey);
|
|
998
|
-
const item =
|
|
999
|
-
if (item) {
|
|
1504
|
+
const item = data[itemIndex];
|
|
1505
|
+
if (item !== void 0) {
|
|
1000
1506
|
const id = getId(itemIndex);
|
|
1001
1507
|
if (itemKey !== id || itemIndex < startBuffered || itemIndex > endBuffered) {
|
|
1002
1508
|
const prevPos = peek$(ctx, `containerPosition${i}`).top;
|
|
1003
1509
|
const pos = positions.get(id) || 0;
|
|
1004
|
-
const size = getItemSize(id, itemIndex,
|
|
1510
|
+
const size = getItemSize(id, itemIndex, data[i]);
|
|
1005
1511
|
if (pos + size >= scroll && pos <= scrollBottom || prevPos + size >= scroll && prevPos <= scrollBottom) {
|
|
1006
1512
|
set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
|
|
1007
1513
|
}
|
|
@@ -1013,9 +1519,9 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1013
1519
|
};
|
|
1014
1520
|
const column2 = columns.get(id) || 1;
|
|
1015
1521
|
if (maintainVisibleContentPosition && itemIndex < anchorElementIndex) {
|
|
1016
|
-
const currentRow = Math.floor(itemIndex /
|
|
1522
|
+
const currentRow = Math.floor(itemIndex / numColumns);
|
|
1017
1523
|
const rowHeight = getRowHeight(currentRow);
|
|
1018
|
-
const elementHeight = getItemSize(id, itemIndex,
|
|
1524
|
+
const elementHeight = getItemSize(id, itemIndex, data[i]);
|
|
1019
1525
|
const diff = rowHeight - elementHeight;
|
|
1020
1526
|
pos.relativeCoordinate = pos.top + getRowHeight(currentRow) - diff;
|
|
1021
1527
|
pos.type = "bottom";
|
|
@@ -1030,13 +1536,25 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1030
1536
|
set$(ctx, `containerColumn${i}`, column2);
|
|
1031
1537
|
}
|
|
1032
1538
|
if (prevData !== item) {
|
|
1033
|
-
set$(ctx, `containerItemData${i}`,
|
|
1539
|
+
set$(ctx, `containerItemData${i}`, data[itemIndex]);
|
|
1034
1540
|
}
|
|
1035
1541
|
}
|
|
1036
1542
|
}
|
|
1037
1543
|
}
|
|
1038
1544
|
}
|
|
1039
|
-
|
|
1545
|
+
if (state.numPendingInitialLayout === 0) {
|
|
1546
|
+
state.numPendingInitialLayout = state.endBuffered - state.startBuffered + 1;
|
|
1547
|
+
}
|
|
1548
|
+
if (!state.queuedInitialLayout && endBuffered !== null) {
|
|
1549
|
+
let areAllKnown = true;
|
|
1550
|
+
for (let i = startBuffered; areAllKnown && i <= endBuffered; i++) {
|
|
1551
|
+
const key = getId(i);
|
|
1552
|
+
areAllKnown && (areAllKnown = state.sizesKnown.has(key));
|
|
1553
|
+
}
|
|
1554
|
+
if (areAllKnown) {
|
|
1555
|
+
setDidLayout();
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1040
1558
|
if (state.viewabilityConfigCallbackPairs) {
|
|
1041
1559
|
updateViewableItems(
|
|
1042
1560
|
state,
|
|
@@ -1049,50 +1567,105 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1049
1567
|
);
|
|
1050
1568
|
}
|
|
1051
1569
|
}, []);
|
|
1052
|
-
const
|
|
1570
|
+
const setPaddingTop = ({
|
|
1571
|
+
stylePaddingTop,
|
|
1572
|
+
alignItemsPaddingTop
|
|
1573
|
+
}) => {
|
|
1574
|
+
if (stylePaddingTop !== void 0) {
|
|
1575
|
+
set$(ctx, "stylePaddingTop", stylePaddingTop);
|
|
1576
|
+
}
|
|
1577
|
+
if (alignItemsPaddingTop !== void 0) {
|
|
1578
|
+
set$(ctx, "alignItemsPaddingTop", alignItemsPaddingTop);
|
|
1579
|
+
}
|
|
1580
|
+
set$(
|
|
1581
|
+
ctx,
|
|
1582
|
+
"paddingTop",
|
|
1583
|
+
(stylePaddingTop != null ? stylePaddingTop : peek$(ctx, "stylePaddingTop")) + (alignItemsPaddingTop != null ? alignItemsPaddingTop : peek$(ctx, "alignItemsPaddingTop"))
|
|
1584
|
+
);
|
|
1585
|
+
};
|
|
1586
|
+
const updateAlignItemsPaddingTop = () => {
|
|
1053
1587
|
if (alignItemsAtEnd) {
|
|
1054
|
-
const { scrollLength
|
|
1055
|
-
const
|
|
1056
|
-
const paddingTop = Math.max(0, Math.floor(scrollLength -
|
|
1057
|
-
|
|
1588
|
+
const { scrollLength } = refState.current;
|
|
1589
|
+
const contentSize = getContentSize(ctx);
|
|
1590
|
+
const paddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
|
|
1591
|
+
setPaddingTop({ alignItemsPaddingTop: paddingTop });
|
|
1058
1592
|
}
|
|
1059
1593
|
};
|
|
1594
|
+
const scrollTo = (offset, animated) => {
|
|
1595
|
+
var _a;
|
|
1596
|
+
(_a = refScroller.current) == null ? void 0 : _a.scrollTo({
|
|
1597
|
+
x: horizontal ? offset : 0,
|
|
1598
|
+
y: horizontal ? 0 : offset,
|
|
1599
|
+
animated: !!animated
|
|
1600
|
+
});
|
|
1601
|
+
};
|
|
1060
1602
|
const doMaintainScrollAtEnd = (animated) => {
|
|
1061
1603
|
const state = refState.current;
|
|
1062
|
-
if ((state == null ? void 0 : state.isAtBottom) && maintainScrollAtEnd) {
|
|
1063
|
-
|
|
1604
|
+
if ((state == null ? void 0 : state.isAtBottom) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
|
|
1605
|
+
const paddingTop = peek$(ctx, "alignItemsPaddingTop");
|
|
1606
|
+
if (paddingTop > 0) {
|
|
1607
|
+
state.scroll = 0;
|
|
1608
|
+
}
|
|
1064
1609
|
requestAnimationFrame(() => {
|
|
1065
|
-
var
|
|
1066
|
-
|
|
1610
|
+
var _a;
|
|
1611
|
+
state.maintainingScrollAtEnd = true;
|
|
1612
|
+
(_a = refScroller.current) == null ? void 0 : _a.scrollToEnd({
|
|
1067
1613
|
animated
|
|
1068
1614
|
});
|
|
1615
|
+
setTimeout(
|
|
1616
|
+
() => {
|
|
1617
|
+
state.maintainingScrollAtEnd = false;
|
|
1618
|
+
},
|
|
1619
|
+
0
|
|
1620
|
+
);
|
|
1069
1621
|
});
|
|
1070
1622
|
return true;
|
|
1071
1623
|
}
|
|
1072
1624
|
};
|
|
1625
|
+
const checkThreshold = (distance, atThreshold, threshold, isReached, isBlockedByTimer, onReached, blockTimer) => {
|
|
1626
|
+
const distanceAbs = Math.abs(distance);
|
|
1627
|
+
const isAtThreshold = atThreshold || distanceAbs < threshold;
|
|
1628
|
+
if (!isReached && !isBlockedByTimer) {
|
|
1629
|
+
if (isAtThreshold) {
|
|
1630
|
+
onReached == null ? void 0 : onReached(distance);
|
|
1631
|
+
blockTimer == null ? void 0 : blockTimer(true);
|
|
1632
|
+
setTimeout(() => {
|
|
1633
|
+
blockTimer == null ? void 0 : blockTimer(false);
|
|
1634
|
+
}, 700);
|
|
1635
|
+
return true;
|
|
1636
|
+
}
|
|
1637
|
+
} else {
|
|
1638
|
+
if (distance >= 1.3 * threshold) {
|
|
1639
|
+
return false;
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
return isReached;
|
|
1643
|
+
};
|
|
1073
1644
|
const checkAtBottom = () => {
|
|
1074
1645
|
if (!refState.current) {
|
|
1075
1646
|
return;
|
|
1076
1647
|
}
|
|
1077
|
-
const { scrollLength, scroll,
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1648
|
+
const { queuedInitialLayout, scrollLength, scroll, maintainingScrollAtEnd } = refState.current;
|
|
1649
|
+
const contentSize = getContentSize(ctx);
|
|
1650
|
+
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1651
|
+
const distanceFromEnd = contentSize - scroll - scrollLength;
|
|
1652
|
+
const distanceFromEndAbs = Math.abs(distanceFromEnd);
|
|
1653
|
+
const isContentLess = contentSize < scrollLength;
|
|
1654
|
+
refState.current.isAtBottom = isContentLess || distanceFromEndAbs < scrollLength * maintainScrollAtEndThreshold;
|
|
1655
|
+
refState.current.isEndReached = checkThreshold(
|
|
1656
|
+
distanceFromEnd,
|
|
1657
|
+
isContentLess,
|
|
1658
|
+
onEndReachedThreshold * scrollLength,
|
|
1659
|
+
refState.current.isEndReached,
|
|
1660
|
+
refState.current.endReachedBlockedByTimer,
|
|
1661
|
+
(distance) => {
|
|
1662
|
+
var _a, _b;
|
|
1663
|
+
return (_b = (_a = callbacks.current).onEndReached) == null ? void 0 : _b.call(_a, { distanceFromEnd: distance });
|
|
1664
|
+
},
|
|
1665
|
+
(block) => {
|
|
1666
|
+
refState.current.endReachedBlockedByTimer = block;
|
|
1094
1667
|
}
|
|
1095
|
-
|
|
1668
|
+
);
|
|
1096
1669
|
}
|
|
1097
1670
|
};
|
|
1098
1671
|
const checkAtTop = () => {
|
|
@@ -1101,113 +1674,122 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1101
1674
|
}
|
|
1102
1675
|
const { scrollLength, scroll } = refState.current;
|
|
1103
1676
|
const distanceFromTop = scroll;
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
refState.current.isStartReached = false;
|
|
1119
|
-
}
|
|
1677
|
+
const distanceFromTopAbs = Math.abs(distanceFromTop);
|
|
1678
|
+
refState.current.isAtTop = distanceFromTopAbs < 0;
|
|
1679
|
+
refState.current.isStartReached = checkThreshold(
|
|
1680
|
+
distanceFromTop,
|
|
1681
|
+
false,
|
|
1682
|
+
onStartReachedThreshold * scrollLength,
|
|
1683
|
+
refState.current.isStartReached,
|
|
1684
|
+
refState.current.startReachedBlockedByTimer,
|
|
1685
|
+
(distance) => {
|
|
1686
|
+
var _a, _b;
|
|
1687
|
+
return (_b = (_a = callbacks.current).onStartReached) == null ? void 0 : _b.call(_a, { distanceFromStart: distance });
|
|
1688
|
+
},
|
|
1689
|
+
(block) => {
|
|
1690
|
+
refState.current.startReachedBlockedByTimer = block;
|
|
1120
1691
|
}
|
|
1121
|
-
|
|
1692
|
+
);
|
|
1122
1693
|
};
|
|
1123
|
-
const checkResetContainers = (
|
|
1694
|
+
const checkResetContainers = (isFirst2) => {
|
|
1124
1695
|
const state = refState.current;
|
|
1125
1696
|
if (state) {
|
|
1126
|
-
state.data =
|
|
1127
|
-
if (
|
|
1697
|
+
state.data = dataProp;
|
|
1698
|
+
if (!isFirst2) {
|
|
1128
1699
|
refState.current.scrollForNextCalculateItemsInView = void 0;
|
|
1129
1700
|
const numContainers = peek$(ctx, "numContainers");
|
|
1130
1701
|
for (let i = 0; i < numContainers; i++) {
|
|
1131
1702
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1132
1703
|
if (!keyExtractorProp || itemKey && state.indexByKey.get(itemKey) === void 0) {
|
|
1133
1704
|
set$(ctx, `containerItemKey${i}`, void 0);
|
|
1705
|
+
set$(ctx, `containerItemData${i}`, void 0);
|
|
1134
1706
|
set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
|
|
1135
1707
|
set$(ctx, `containerColumn${i}`, -1);
|
|
1136
1708
|
}
|
|
1137
1709
|
}
|
|
1138
1710
|
if (!keyExtractorProp) {
|
|
1139
|
-
state.sizes.clear();
|
|
1140
1711
|
state.positions.clear();
|
|
1141
1712
|
}
|
|
1142
|
-
calculateItemsInView(
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1713
|
+
calculateItemsInView();
|
|
1714
|
+
const didMaintainScrollAtEnd = doMaintainScrollAtEnd(false);
|
|
1715
|
+
if (!didMaintainScrollAtEnd && dataProp.length > state.data.length) {
|
|
1716
|
+
state.isEndReached = false;
|
|
1717
|
+
}
|
|
1718
|
+
if (!didMaintainScrollAtEnd) {
|
|
1719
|
+
checkAtTop();
|
|
1720
|
+
checkAtBottom();
|
|
1721
|
+
}
|
|
1147
1722
|
}
|
|
1148
|
-
checkAtTop();
|
|
1149
|
-
checkAtBottom();
|
|
1150
1723
|
}
|
|
1151
1724
|
};
|
|
1152
|
-
const
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
refState.current.sizes.clear();
|
|
1156
|
-
refState.current.positions.clear();
|
|
1157
|
-
}
|
|
1158
|
-
refState.current.data = data;
|
|
1725
|
+
const calcTotalSizesAndPositions = ({ forgetPositions = false }) => {
|
|
1726
|
+
var _a, _b;
|
|
1727
|
+
const state = refState.current;
|
|
1159
1728
|
let totalSize = 0;
|
|
1160
1729
|
let totalSizeBelowIndex = 0;
|
|
1161
1730
|
const indexByKey = /* @__PURE__ */ new Map();
|
|
1162
1731
|
const newPositions = /* @__PURE__ */ new Map();
|
|
1163
1732
|
let column = 1;
|
|
1164
1733
|
let maxSizeInRow = 0;
|
|
1165
|
-
|
|
1734
|
+
const numColumns = (_a = peek$(ctx, "numColumns")) != null ? _a : numColumnsProp;
|
|
1735
|
+
if (!state) {
|
|
1736
|
+
return;
|
|
1737
|
+
}
|
|
1738
|
+
for (let i = 0; i < dataProp.length; i++) {
|
|
1166
1739
|
const key = getId(i);
|
|
1740
|
+
if (__DEV__) {
|
|
1741
|
+
if (indexByKey.has(key)) {
|
|
1742
|
+
console.error(
|
|
1743
|
+
`[legend-list] Error: Detected overlapping key (${key}) which causes missing items and gaps and other terrrible things. Check that keyExtractor returns unique values.`
|
|
1744
|
+
);
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1167
1747
|
indexByKey.set(key, i);
|
|
1168
|
-
if (
|
|
1169
|
-
newPositions.set(key,
|
|
1748
|
+
if (!forgetPositions && state.positions.get(key) != null && state.indexByKey.get(key) === i) {
|
|
1749
|
+
newPositions.set(key, state.positions.get(key));
|
|
1170
1750
|
}
|
|
1171
1751
|
}
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
if (
|
|
1175
|
-
if (
|
|
1176
|
-
if (
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1752
|
+
state.indexByKey = indexByKey;
|
|
1753
|
+
state.positions = newPositions;
|
|
1754
|
+
if (!forgetPositions && !isFirst) {
|
|
1755
|
+
if (maintainVisibleContentPosition) {
|
|
1756
|
+
if (state.anchorElement == null || indexByKey.get(state.anchorElement.id) == null) {
|
|
1757
|
+
if (dataProp.length) {
|
|
1758
|
+
const newAnchorElement = {
|
|
1759
|
+
coordinate: 0,
|
|
1760
|
+
id: getId(0)
|
|
1761
|
+
};
|
|
1762
|
+
state.anchorElement = newAnchorElement;
|
|
1763
|
+
(_b = state.belowAnchorElementPositions) == null ? void 0 : _b.clear();
|
|
1764
|
+
scrollTo(0, false);
|
|
1765
|
+
setTimeout(() => {
|
|
1766
|
+
calculateItemsInView();
|
|
1767
|
+
}, 0);
|
|
1768
|
+
} else {
|
|
1769
|
+
state.startBufferedId = void 0;
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
} else {
|
|
1773
|
+
if (state.startBufferedId != null && newPositions.get(state.startBufferedId) == null) {
|
|
1774
|
+
if (dataProp.length) {
|
|
1775
|
+
state.startBufferedId = getId(0);
|
|
1776
|
+
} else {
|
|
1777
|
+
state.startBufferedId = void 0;
|
|
1778
|
+
}
|
|
1779
|
+
scrollTo(0, false);
|
|
1184
1780
|
setTimeout(() => {
|
|
1185
|
-
calculateItemsInView(
|
|
1781
|
+
calculateItemsInView();
|
|
1186
1782
|
}, 0);
|
|
1187
|
-
} else {
|
|
1188
|
-
refState.current.startBufferedId = void 0;
|
|
1189
1783
|
}
|
|
1190
1784
|
}
|
|
1191
|
-
} else {
|
|
1192
|
-
if (refState.current.startBufferedId != null && newPositions.get(refState.current.startBufferedId) == null) {
|
|
1193
|
-
if (data.length) {
|
|
1194
|
-
refState.current.startBufferedId = getId(0);
|
|
1195
|
-
} else {
|
|
1196
|
-
refState.current.startBufferedId = void 0;
|
|
1197
|
-
}
|
|
1198
|
-
refScroller.current.scrollTo({ x: 0, y: 0, animated: false });
|
|
1199
|
-
setTimeout(() => {
|
|
1200
|
-
calculateItemsInView(0);
|
|
1201
|
-
}, 0);
|
|
1202
|
-
}
|
|
1203
1785
|
}
|
|
1204
1786
|
const anchorElementIndex = getAnchorElementIndex();
|
|
1205
|
-
for (let i = 0; i <
|
|
1787
|
+
for (let i = 0; i < dataProp.length; i++) {
|
|
1206
1788
|
const key = getId(i);
|
|
1207
|
-
const size = getItemSize(key, i,
|
|
1789
|
+
const size = getItemSize(key, i, dataProp[i]);
|
|
1208
1790
|
maxSizeInRow = Math.max(maxSizeInRow, size);
|
|
1209
1791
|
column++;
|
|
1210
|
-
if (column >
|
|
1792
|
+
if (column > numColumns) {
|
|
1211
1793
|
if (maintainVisibleContentPosition && anchorElementIndex !== void 0 && i < anchorElementIndex) {
|
|
1212
1794
|
totalSizeBelowIndex += maxSizeInRow;
|
|
1213
1795
|
}
|
|
@@ -1219,123 +1801,197 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1219
1801
|
if (maxSizeInRow > 0) {
|
|
1220
1802
|
totalSize += maxSizeInRow;
|
|
1221
1803
|
}
|
|
1804
|
+
state.ignoreScrollFromCalcTotal = true;
|
|
1805
|
+
requestAnimationFrame(() => {
|
|
1806
|
+
state.ignoreScrollFromCalcTotal = false;
|
|
1807
|
+
});
|
|
1222
1808
|
addTotalSize(null, totalSize, totalSizeBelowIndex);
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1809
|
+
};
|
|
1810
|
+
const isFirst = !refState.current.renderItem;
|
|
1811
|
+
const memoizedLastItemKeys = useMemo(() => {
|
|
1812
|
+
if (!dataProp.length) return [];
|
|
1813
|
+
return Array.from(
|
|
1814
|
+
{ length: Math.min(numColumnsProp, dataProp.length) },
|
|
1815
|
+
(_, i) => getId(dataProp.length - 1 - i)
|
|
1228
1816
|
);
|
|
1229
|
-
}, [
|
|
1230
|
-
useEffect(() => {
|
|
1231
|
-
set$(ctx, "extraData", extraData);
|
|
1232
|
-
}, [extraData]);
|
|
1233
|
-
refState.current.renderItem = renderItem;
|
|
1234
|
-
const lastItemKey = data.length > 0 ? getId(data.length - 1) : void 0;
|
|
1235
|
-
const stylePaddingTop = (_e = (_d = (_b = StyleSheet.flatten(style)) == null ? void 0 : _b.paddingTop) != null ? _d : (_c = StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _c.paddingTop) != null ? _e : 0;
|
|
1817
|
+
}, [dataProp, numColumnsProp]);
|
|
1236
1818
|
const initalizeStateVars = () => {
|
|
1237
|
-
set$(ctx, "
|
|
1819
|
+
set$(ctx, "lastItemKeys", memoizedLastItemKeys);
|
|
1238
1820
|
set$(ctx, "numColumns", numColumnsProp);
|
|
1239
|
-
|
|
1821
|
+
const prevPaddingTop = peek$(ctx, "stylePaddingTop");
|
|
1822
|
+
setPaddingTop({ stylePaddingTop: stylePaddingTopState });
|
|
1823
|
+
const paddingDiff = stylePaddingTopState - prevPaddingTop;
|
|
1824
|
+
if (paddingDiff && prevPaddingTop !== void 0 && Platform.OS === "ios") {
|
|
1825
|
+
queueMicrotask(() => {
|
|
1826
|
+
scrollTo(refState.current.scroll + paddingDiff, false);
|
|
1827
|
+
});
|
|
1828
|
+
}
|
|
1240
1829
|
};
|
|
1241
1830
|
if (isFirst) {
|
|
1242
1831
|
initalizeStateVars();
|
|
1243
1832
|
}
|
|
1244
|
-
|
|
1833
|
+
if (isFirst || didDataChange || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
1834
|
+
refState.current.lastBatchingAction = Date.now();
|
|
1835
|
+
if (!keyExtractorProp && !isFirst && didDataChange) {
|
|
1836
|
+
__DEV__ && warnDevOnce(
|
|
1837
|
+
"keyExtractor",
|
|
1838
|
+
"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."
|
|
1839
|
+
);
|
|
1840
|
+
refState.current.sizes.clear();
|
|
1841
|
+
refState.current.positions.clear();
|
|
1842
|
+
}
|
|
1843
|
+
calcTotalSizesAndPositions({ forgetPositions: false });
|
|
1844
|
+
}
|
|
1845
|
+
useEffect(() => {
|
|
1846
|
+
const didAllocateContainers = doInitialAllocateContainers();
|
|
1847
|
+
if (!didAllocateContainers) {
|
|
1848
|
+
checkResetContainers(
|
|
1849
|
+
/*isFirst*/
|
|
1850
|
+
isFirst
|
|
1851
|
+
);
|
|
1852
|
+
}
|
|
1853
|
+
}, [isFirst, dataProp, numColumnsProp]);
|
|
1854
|
+
useEffect(() => {
|
|
1855
|
+
set$(ctx, "extraData", extraData);
|
|
1856
|
+
}, [extraData]);
|
|
1857
|
+
refState.current.renderItem = renderItem;
|
|
1858
|
+
useEffect(initalizeStateVars, [memoizedLastItemKeys.join(","), numColumnsProp, stylePaddingTopState]);
|
|
1245
1859
|
const getRenderedItem = useCallback((key) => {
|
|
1246
|
-
var
|
|
1860
|
+
var _a, _b;
|
|
1247
1861
|
const state = refState.current;
|
|
1248
1862
|
if (!state) {
|
|
1249
1863
|
return null;
|
|
1250
1864
|
}
|
|
1251
|
-
const { data
|
|
1865
|
+
const { data, indexByKey } = state;
|
|
1252
1866
|
const index = indexByKey.get(key);
|
|
1253
1867
|
if (index === void 0) {
|
|
1254
1868
|
return null;
|
|
1255
1869
|
}
|
|
1256
|
-
const useViewability2 = (
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
};
|
|
1262
|
-
const
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
};
|
|
1268
|
-
const
|
|
1269
|
-
|
|
1870
|
+
const useViewability2 = __DEV__ ? () => {
|
|
1871
|
+
warnDevOnce(
|
|
1872
|
+
"useViewability",
|
|
1873
|
+
`useViewability has been moved from a render prop to a regular import: import { useViewability } from "@legendapp/list";`
|
|
1874
|
+
);
|
|
1875
|
+
} : void 0;
|
|
1876
|
+
const useViewabilityAmount2 = __DEV__ ? () => {
|
|
1877
|
+
warnDevOnce(
|
|
1878
|
+
"useViewabilityAmount",
|
|
1879
|
+
`useViewabilityAmount has been moved from a render prop to a regular import: import { useViewabilityAmount } from "@legendapp/list";`
|
|
1880
|
+
);
|
|
1881
|
+
} : void 0;
|
|
1882
|
+
const useRecyclingEffect2 = __DEV__ ? () => {
|
|
1883
|
+
warnDevOnce(
|
|
1884
|
+
"useRecyclingEffect",
|
|
1885
|
+
`useRecyclingEffect has been moved from a render prop to a regular import: import { useRecyclingEffect } from "@legendapp/list";`
|
|
1886
|
+
);
|
|
1887
|
+
} : void 0;
|
|
1888
|
+
const useRecyclingState2 = __DEV__ ? () => {
|
|
1889
|
+
warnDevOnce(
|
|
1890
|
+
"useRecyclingState",
|
|
1891
|
+
`useRecyclingState has been moved from a render prop to a regular import: import { useRecyclingState } from "@legendapp/list";`
|
|
1892
|
+
);
|
|
1893
|
+
} : void 0;
|
|
1894
|
+
const renderedItem = (_b = (_a = refState.current).renderItem) == null ? void 0 : _b.call(_a, {
|
|
1895
|
+
item: data[index],
|
|
1270
1896
|
index,
|
|
1897
|
+
extraData: peek$(ctx, "extraData"),
|
|
1898
|
+
// @ts-expect-error TODO: Remove these before 1.0
|
|
1271
1899
|
useViewability: useViewability2,
|
|
1272
1900
|
useViewabilityAmount: useViewabilityAmount2,
|
|
1273
1901
|
useRecyclingEffect: useRecyclingEffect2,
|
|
1274
1902
|
useRecyclingState: useRecyclingState2
|
|
1275
1903
|
});
|
|
1276
|
-
return { index, renderedItem };
|
|
1904
|
+
return { index, item: data[index], renderedItem };
|
|
1277
1905
|
}, []);
|
|
1278
|
-
|
|
1279
|
-
var
|
|
1906
|
+
const doInitialAllocateContainers = () => {
|
|
1907
|
+
var _a;
|
|
1280
1908
|
const state = refState.current;
|
|
1281
|
-
const
|
|
1909
|
+
const { scrollLength, data } = state;
|
|
1910
|
+
if (scrollLength > 0 && data.length > 0 && !peek$(ctx, "numContainers")) {
|
|
1911
|
+
const averageItemSize = (_a = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, data[0])) != null ? _a : DEFAULT_ITEM_SIZE;
|
|
1912
|
+
const numContainers = Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize) * numColumnsProp;
|
|
1913
|
+
for (let i = 0; i < numContainers; i++) {
|
|
1914
|
+
set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
|
|
1915
|
+
set$(ctx, `containerColumn${i}`, -1);
|
|
1916
|
+
}
|
|
1917
|
+
set$(ctx, "numContainers", numContainers);
|
|
1918
|
+
set$(ctx, "numContainersPooled", numContainers * initialContainerPoolRatio);
|
|
1919
|
+
if (initialScrollIndex) {
|
|
1920
|
+
requestAnimationFrame(() => {
|
|
1921
|
+
calculateItemsInView();
|
|
1922
|
+
});
|
|
1923
|
+
} else {
|
|
1924
|
+
calculateItemsInView();
|
|
1925
|
+
}
|
|
1926
|
+
return true;
|
|
1927
|
+
}
|
|
1928
|
+
};
|
|
1929
|
+
useEffect(() => {
|
|
1930
|
+
const state = refState.current;
|
|
1931
|
+
const viewability = setupViewability({
|
|
1932
|
+
viewabilityConfig,
|
|
1933
|
+
viewabilityConfigCallbackPairs,
|
|
1934
|
+
onViewableItemsChanged
|
|
1935
|
+
});
|
|
1282
1936
|
state.viewabilityConfigCallbackPairs = viewability;
|
|
1283
1937
|
state.enableScrollForNextCalculateItemsInView = !viewability;
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
for (let i = 0; i < numContainers; i++) {
|
|
1288
|
-
set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
|
|
1289
|
-
set$(ctx, `containerColumn${i}`, -1);
|
|
1290
|
-
}
|
|
1291
|
-
set$(ctx, "numContainers", numContainers);
|
|
1292
|
-
set$(ctx, "numContainersPooled", numContainers * 2);
|
|
1293
|
-
calculateItemsInView(state.scrollVelocity);
|
|
1938
|
+
}, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
|
|
1939
|
+
useInit(() => {
|
|
1940
|
+
doInitialAllocateContainers();
|
|
1294
1941
|
});
|
|
1295
|
-
const updateItemSize = useCallback((
|
|
1296
|
-
|
|
1297
|
-
const
|
|
1298
|
-
if (!
|
|
1942
|
+
const updateItemSize = useCallback((itemKey, size, fromFixGaps) => {
|
|
1943
|
+
const state = refState.current;
|
|
1944
|
+
const { sizes, indexByKey, sizesKnown, data, rowHeights, startBuffered, endBuffered, averageSizes } = state;
|
|
1945
|
+
if (!data) {
|
|
1299
1946
|
return;
|
|
1300
1947
|
}
|
|
1301
|
-
const state = refState.current;
|
|
1302
|
-
const { sizes, indexByKey, columns, sizesLaidOut } = state;
|
|
1303
1948
|
const index = indexByKey.get(itemKey);
|
|
1304
1949
|
const numColumns = peek$(ctx, "numColumns");
|
|
1305
|
-
|
|
1306
|
-
const prevSize =
|
|
1950
|
+
state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, index) : index;
|
|
1951
|
+
const prevSize = getItemSize(itemKey, index, data);
|
|
1952
|
+
let needsCalculate = false;
|
|
1953
|
+
let needsUpdateContainersDidLayout = false;
|
|
1954
|
+
if (state.numPendingInitialLayout > 0) {
|
|
1955
|
+
state.numPendingInitialLayout--;
|
|
1956
|
+
if (state.numPendingInitialLayout === 0) {
|
|
1957
|
+
needsCalculate = true;
|
|
1958
|
+
state.numPendingInitialLayout = -1;
|
|
1959
|
+
needsUpdateContainersDidLayout = true;
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
sizesKnown.set(itemKey, size);
|
|
1963
|
+
const itemType = "";
|
|
1964
|
+
let averages = averageSizes[itemType];
|
|
1965
|
+
if (!averages) {
|
|
1966
|
+
averages = averageSizes[itemType] = {
|
|
1967
|
+
num: 0,
|
|
1968
|
+
avg: 0
|
|
1969
|
+
};
|
|
1970
|
+
}
|
|
1971
|
+
averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
|
|
1972
|
+
averages.num++;
|
|
1307
1973
|
if (!prevSize || Math.abs(prevSize - size) > 0.5) {
|
|
1308
1974
|
let diff;
|
|
1975
|
+
needsCalculate = true;
|
|
1309
1976
|
if (numColumns > 1) {
|
|
1310
|
-
const
|
|
1977
|
+
const rowNumber = Math.floor(index / numColumnsProp);
|
|
1978
|
+
const prevSizeInRow = getRowHeight(rowNumber);
|
|
1311
1979
|
sizes.set(itemKey, size);
|
|
1312
|
-
|
|
1313
|
-
const
|
|
1314
|
-
|
|
1315
|
-
for (let i = loopStart; i < loopStart + numColumns && i < data2.length; i++) {
|
|
1316
|
-
const id = getId(i);
|
|
1317
|
-
const size2 = getItemSize(id, i, data2[i]);
|
|
1318
|
-
nextMaxSizeInRow = Math.max(nextMaxSizeInRow, size2);
|
|
1319
|
-
}
|
|
1320
|
-
diff = nextMaxSizeInRow - prevMaxSizeInRow;
|
|
1980
|
+
rowHeights.delete(rowNumber);
|
|
1981
|
+
const sizeInRow = getRowHeight(rowNumber);
|
|
1982
|
+
diff = sizeInRow - prevSizeInRow;
|
|
1321
1983
|
} else {
|
|
1322
1984
|
sizes.set(itemKey, size);
|
|
1323
1985
|
diff = size - prevSize;
|
|
1324
1986
|
}
|
|
1325
|
-
if (__DEV__ &&
|
|
1326
|
-
sizesLaidOut.set(itemKey, size);
|
|
1987
|
+
if (__DEV__ && suggestEstimatedItemSize) {
|
|
1327
1988
|
if (state.timeoutSizeMessage) {
|
|
1328
1989
|
clearTimeout(state.timeoutSizeMessage);
|
|
1329
1990
|
}
|
|
1330
1991
|
state.timeoutSizeMessage = setTimeout(() => {
|
|
1331
1992
|
state.timeoutSizeMessage = void 0;
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
for (const [key, size2] of sizesLaidOut) {
|
|
1335
|
-
num++;
|
|
1336
|
-
total += size2;
|
|
1337
|
-
}
|
|
1338
|
-
const avg = Math.round(total / num);
|
|
1993
|
+
const num = sizesKnown.size;
|
|
1994
|
+
const avg = state.averageSizes[""].avg;
|
|
1339
1995
|
console.warn(
|
|
1340
1996
|
`[legend-list] estimatedItemSize or getEstimatedItemSize are not defined. Based on the ${num} items rendered so far, the optimal estimated size is ${avg}.`
|
|
1341
1997
|
);
|
|
@@ -1343,43 +1999,60 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1343
1999
|
}
|
|
1344
2000
|
refState.current.scrollForNextCalculateItemsInView = void 0;
|
|
1345
2001
|
addTotalSize(itemKey, diff, 0);
|
|
1346
|
-
doMaintainScrollAtEnd(
|
|
2002
|
+
doMaintainScrollAtEnd(false);
|
|
2003
|
+
if (onItemSizeChanged) {
|
|
2004
|
+
onItemSizeChanged({
|
|
2005
|
+
size,
|
|
2006
|
+
previous: prevSize,
|
|
2007
|
+
index,
|
|
2008
|
+
itemKey,
|
|
2009
|
+
itemData: data[index]
|
|
2010
|
+
});
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
const isInView = index >= startBuffered && index <= endBuffered;
|
|
2014
|
+
if (needsUpdateContainersDidLayout || !fromFixGaps && needsCalculate && isInView) {
|
|
1347
2015
|
const scrollVelocity = state.scrollVelocity;
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
state.
|
|
1354
|
-
calculateItemsInView(
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
2016
|
+
let didCalculate = false;
|
|
2017
|
+
if ((Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1) && (!waitForInitialLayout || state.numPendingInitialLayout < 0)) {
|
|
2018
|
+
if (Date.now() - state.lastBatchingAction < 500) {
|
|
2019
|
+
if (!state.queuedCalculateItemsInView) {
|
|
2020
|
+
state.queuedCalculateItemsInView = requestAnimationFrame(() => {
|
|
2021
|
+
state.queuedCalculateItemsInView = void 0;
|
|
2022
|
+
calculateItemsInView();
|
|
2023
|
+
});
|
|
2024
|
+
}
|
|
1357
2025
|
} else {
|
|
1358
|
-
calculateItemsInView(
|
|
2026
|
+
calculateItemsInView();
|
|
2027
|
+
didCalculate = true;
|
|
1359
2028
|
}
|
|
1360
2029
|
}
|
|
1361
|
-
if (
|
|
1362
|
-
|
|
2030
|
+
if (!didCalculate && IsNewArchitecture) {
|
|
2031
|
+
fixGaps();
|
|
1363
2032
|
}
|
|
1364
2033
|
}
|
|
1365
2034
|
}, []);
|
|
1366
|
-
const handleScrollDebounced = useCallback((velocity) => {
|
|
1367
|
-
calculateItemsInView(velocity);
|
|
1368
|
-
checkAtBottom();
|
|
1369
|
-
checkAtTop();
|
|
1370
|
-
}, []);
|
|
1371
2035
|
const onLayout = useCallback((event) => {
|
|
2036
|
+
const state = refState.current;
|
|
1372
2037
|
const scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
1373
|
-
|
|
2038
|
+
const didChange = scrollLength !== state.scrollLength;
|
|
2039
|
+
state.scrollLength = scrollLength;
|
|
2040
|
+
state.lastBatchingAction = Date.now();
|
|
2041
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
2042
|
+
doInitialAllocateContainers();
|
|
1374
2043
|
doMaintainScrollAtEnd(false);
|
|
1375
|
-
|
|
2044
|
+
updateAlignItemsPaddingTop();
|
|
1376
2045
|
checkAtBottom();
|
|
1377
2046
|
checkAtTop();
|
|
2047
|
+
if (didChange) {
|
|
2048
|
+
calculateItemsInView();
|
|
2049
|
+
}
|
|
1378
2050
|
if (__DEV__) {
|
|
1379
2051
|
const isWidthZero = event.nativeEvent.layout.width === 0;
|
|
1380
2052
|
const isHeightZero = event.nativeEvent.layout.height === 0;
|
|
1381
2053
|
if (isWidthZero || isHeightZero) {
|
|
1382
|
-
|
|
2054
|
+
warnDevOnce(
|
|
2055
|
+
"height0",
|
|
1383
2056
|
`[legend-list] List ${isWidthZero ? "width" : "height"} is 0. You may need to set a style or \`flex: \` for the list, because children are absolutely positioned.`
|
|
1384
2057
|
);
|
|
1385
2058
|
}
|
|
@@ -1390,14 +2063,18 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1390
2063
|
}, []);
|
|
1391
2064
|
const handleScroll = useCallback(
|
|
1392
2065
|
(event, fromSelf) => {
|
|
1393
|
-
var
|
|
1394
|
-
if (((
|
|
2066
|
+
var _a, _b, _c, _d;
|
|
2067
|
+
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) {
|
|
1395
2068
|
return;
|
|
1396
2069
|
}
|
|
1397
2070
|
const state = refState.current;
|
|
2071
|
+
const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
|
|
2072
|
+
if (state.ignoreScrollFromCalcTotal && newScroll !== 0) {
|
|
2073
|
+
return;
|
|
2074
|
+
}
|
|
1398
2075
|
state.hasScrolled = true;
|
|
2076
|
+
state.lastBatchingAction = Date.now();
|
|
1399
2077
|
const currentTime = performance.now();
|
|
1400
|
-
const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
|
|
1401
2078
|
if (!(state.scrollHistory.length === 0 && newScroll === initialContentOffset)) {
|
|
1402
2079
|
state.scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
1403
2080
|
}
|
|
@@ -1423,9 +2100,11 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1423
2100
|
state.scroll = newScroll;
|
|
1424
2101
|
state.scrollTime = currentTime;
|
|
1425
2102
|
state.scrollVelocity = velocity;
|
|
1426
|
-
|
|
2103
|
+
calculateItemsInView();
|
|
2104
|
+
checkAtBottom();
|
|
2105
|
+
checkAtTop();
|
|
1427
2106
|
if (!fromSelf) {
|
|
1428
|
-
|
|
2107
|
+
(_d = state.onScroll) == null ? void 0 : _d.call(state, event);
|
|
1429
2108
|
}
|
|
1430
2109
|
},
|
|
1431
2110
|
[]
|
|
@@ -1433,61 +2112,127 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1433
2112
|
useImperativeHandle(
|
|
1434
2113
|
forwardedRef,
|
|
1435
2114
|
() => {
|
|
1436
|
-
const
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
2115
|
+
const scrollIndexIntoView = (options) => {
|
|
2116
|
+
if (refState.current) {
|
|
2117
|
+
const { index, ...rest2 } = options;
|
|
2118
|
+
const { startNoBuffer, endNoBuffer } = refState.current;
|
|
2119
|
+
if (index < startNoBuffer || index > endNoBuffer) {
|
|
2120
|
+
const viewPosition = index < startNoBuffer ? 0 : 1;
|
|
2121
|
+
scrollToIndex({
|
|
2122
|
+
...rest2,
|
|
2123
|
+
viewPosition,
|
|
2124
|
+
index
|
|
2125
|
+
});
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
1440
2128
|
};
|
|
1441
2129
|
return {
|
|
2130
|
+
flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
|
|
1442
2131
|
getNativeScrollRef: () => refScroller.current,
|
|
1443
2132
|
getScrollableNode: () => refScroller.current.getScrollableNode(),
|
|
1444
2133
|
getScrollResponder: () => refScroller.current.getScrollResponder(),
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
2134
|
+
getState: () => {
|
|
2135
|
+
const state = refState.current;
|
|
2136
|
+
return state ? {
|
|
2137
|
+
contentLength: state.totalSize,
|
|
2138
|
+
end: state.endNoBuffer,
|
|
2139
|
+
endBuffered: state.endBuffered,
|
|
2140
|
+
isAtEnd: state.isAtBottom,
|
|
2141
|
+
isAtStart: state.isAtTop,
|
|
2142
|
+
scroll: state.scroll,
|
|
2143
|
+
scrollLength: state.scrollLength,
|
|
2144
|
+
start: state.startNoBuffer,
|
|
2145
|
+
startBuffered: state.startBuffered
|
|
2146
|
+
} : {};
|
|
1450
2147
|
},
|
|
1451
|
-
|
|
2148
|
+
scrollIndexIntoView,
|
|
2149
|
+
scrollItemIntoView: ({ item, ...props2 }) => {
|
|
2150
|
+
const { data } = refState.current;
|
|
1452
2151
|
const index = data.indexOf(item);
|
|
1453
2152
|
if (index !== -1) {
|
|
1454
|
-
|
|
2153
|
+
scrollIndexIntoView({ index, ...props2 });
|
|
1455
2154
|
}
|
|
1456
2155
|
},
|
|
1457
|
-
|
|
2156
|
+
scrollToIndex,
|
|
2157
|
+
scrollToItem: ({ item, ...props2 }) => {
|
|
2158
|
+
const { data } = refState.current;
|
|
2159
|
+
const index = data.indexOf(item);
|
|
2160
|
+
if (index !== -1) {
|
|
2161
|
+
scrollToIndex({ index, ...props2 });
|
|
2162
|
+
}
|
|
2163
|
+
},
|
|
2164
|
+
scrollToOffset: ({ offset, animated }) => {
|
|
2165
|
+
scrollTo(offset, animated);
|
|
2166
|
+
},
|
|
2167
|
+
scrollToEnd: (options) => refScroller.current.scrollToEnd(options)
|
|
1458
2168
|
};
|
|
1459
2169
|
},
|
|
1460
2170
|
[]
|
|
1461
2171
|
);
|
|
1462
|
-
|
|
2172
|
+
if (Platform.OS === "web") {
|
|
2173
|
+
useEffect(() => {
|
|
2174
|
+
var _a;
|
|
2175
|
+
if (initialContentOffset) {
|
|
2176
|
+
(_a = refState.current) == null ? void 0 : _a.scrollAdjustHandler.setDisableAdjust(true);
|
|
2177
|
+
scrollTo(initialContentOffset, false);
|
|
2178
|
+
setTimeout(() => {
|
|
2179
|
+
var _a2;
|
|
2180
|
+
(_a2 = refState.current) == null ? void 0 : _a2.scrollAdjustHandler.setDisableAdjust(false);
|
|
2181
|
+
}, 0);
|
|
2182
|
+
}
|
|
2183
|
+
}, []);
|
|
2184
|
+
}
|
|
2185
|
+
return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(
|
|
1463
2186
|
ListComponent,
|
|
1464
2187
|
{
|
|
1465
2188
|
...rest,
|
|
1466
2189
|
horizontal,
|
|
1467
|
-
refScrollView:
|
|
1468
|
-
refScroller.current = r;
|
|
1469
|
-
if (refScrollView) {
|
|
1470
|
-
if (typeof refScrollView === "function") {
|
|
1471
|
-
refScrollView(r);
|
|
1472
|
-
} else {
|
|
1473
|
-
refScrollView.current = r;
|
|
1474
|
-
}
|
|
1475
|
-
}
|
|
1476
|
-
},
|
|
2190
|
+
refScrollView: combinedRef,
|
|
1477
2191
|
initialContentOffset,
|
|
1478
2192
|
getRenderedItem,
|
|
1479
2193
|
updateItemSize,
|
|
1480
2194
|
handleScroll,
|
|
2195
|
+
onMomentumScrollEnd: (event) => {
|
|
2196
|
+
var _a;
|
|
2197
|
+
const scrollingToOffset = (_a = refState.current) == null ? void 0 : _a.scrollingToOffset;
|
|
2198
|
+
if (scrollingToOffset !== void 0) {
|
|
2199
|
+
requestAnimationFrame(() => {
|
|
2200
|
+
scrollTo(scrollingToOffset, false);
|
|
2201
|
+
refState.current.scrollingToOffset = void 0;
|
|
2202
|
+
requestAnimationFrame(() => {
|
|
2203
|
+
refState.current.scrollAdjustHandler.setDisableAdjust(false);
|
|
2204
|
+
});
|
|
2205
|
+
});
|
|
2206
|
+
}
|
|
2207
|
+
const wasPaused = refState.current.scrollAdjustHandler.unPauseAdjust();
|
|
2208
|
+
if (wasPaused) {
|
|
2209
|
+
refState.current.scrollVelocity = 0;
|
|
2210
|
+
refState.current.scrollHistory = [];
|
|
2211
|
+
calculateItemsInView();
|
|
2212
|
+
}
|
|
2213
|
+
if (onMomentumScrollEnd) {
|
|
2214
|
+
onMomentumScrollEnd(event);
|
|
2215
|
+
}
|
|
2216
|
+
},
|
|
1481
2217
|
onLayout,
|
|
1482
2218
|
recycleItems,
|
|
1483
2219
|
alignItemsAtEnd,
|
|
1484
|
-
ListEmptyComponent:
|
|
2220
|
+
ListEmptyComponent: dataProp.length === 0 ? ListEmptyComponent : void 0,
|
|
1485
2221
|
maintainVisibleContentPosition,
|
|
1486
|
-
scrollEventThrottle:
|
|
2222
|
+
scrollEventThrottle: Platform.OS === "web" ? 16 : void 0,
|
|
1487
2223
|
waitForInitialLayout,
|
|
1488
|
-
|
|
2224
|
+
refreshControl: refreshControl != null ? refreshControl : onRefresh && /* @__PURE__ */ React6.createElement(
|
|
2225
|
+
RefreshControl,
|
|
2226
|
+
{
|
|
2227
|
+
refreshing: !!refreshing,
|
|
2228
|
+
onRefresh,
|
|
2229
|
+
progressViewOffset
|
|
2230
|
+
}
|
|
2231
|
+
),
|
|
2232
|
+
style,
|
|
2233
|
+
contentContainerStyle
|
|
1489
2234
|
}
|
|
1490
|
-
);
|
|
2235
|
+
), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React6.createElement(DebugView, { state: refState.current }));
|
|
1491
2236
|
});
|
|
1492
2237
|
|
|
1493
2238
|
export { LegendList, useRecyclingEffect, useRecyclingState, useViewability, useViewabilityAmount };
|