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