@legendapp/list 3.0.0-beta.9 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.DS_Store +0 -0
- package/CHANGELOG.md +21 -1
- package/README.md +8 -2
- package/animated.d.ts +659 -5
- package/animated.js +2 -2
- package/animated.mjs +1 -1
- package/keyboard-legacy.d.ts +226 -0
- package/keyboard-legacy.js +456 -0
- package/keyboard-legacy.mjs +435 -0
- package/keyboard.d.ts +261 -9
- package/keyboard.js +114 -135
- package/keyboard.mjs +115 -137
- package/package.json +55 -5
- package/{types-1Hgg1rTO.d.mts → react-native.d.ts} +269 -284
- package/react-native.js +6453 -0
- package/react-native.mjs +6424 -0
- package/{types-1Hgg1rTO.d.ts → react-native.web.d.ts} +330 -283
- package/react-native.web.js +7111 -0
- package/react-native.web.mjs +7082 -0
- package/react.d.ts +771 -0
- package/react.js +7111 -0
- package/react.mjs +7082 -0
- package/reanimated.d.ts +681 -8
- package/reanimated.js +225 -38
- package/reanimated.mjs +227 -40
- package/section-list.d.ts +663 -5
- package/section-list.js +39 -3829
- package/section-list.mjs +37 -3828
- package/animated.d.mts +0 -9
- package/index.d.mts +0 -23
- package/index.d.ts +0 -23
- package/index.js +0 -3935
- package/index.mjs +0 -3907
- package/index.native.d.mts +0 -23
- package/index.native.d.ts +0 -23
- package/index.native.js +0 -3739
- package/index.native.mjs +0 -3711
- package/keyboard-controller.d.mts +0 -12
- package/keyboard-controller.d.ts +0 -12
- package/keyboard-controller.js +0 -69
- package/keyboard-controller.mjs +0 -48
- package/keyboard.d.mts +0 -13
- package/reanimated.d.mts +0 -18
- package/section-list.d.mts +0 -113
- package/section-list.native.d.mts +0 -113
- package/section-list.native.d.ts +0 -113
- package/section-list.native.js +0 -3897
- package/section-list.native.mjs +0 -3876
package/section-list.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var reactNative = require('react-native');
|
|
5
|
-
var
|
|
6
|
-
var reactDom = require('react-dom');
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var reactNative$1 = require('react-native');
|
|
5
|
+
var reactNative = require('@legendapp/list/react-native');
|
|
7
6
|
|
|
8
7
|
function _interopNamespace(e) {
|
|
9
8
|
if (e && e.__esModule) return e;
|
|
@@ -23,3820 +22,19 @@ function _interopNamespace(e) {
|
|
|
23
22
|
return Object.freeze(n);
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
var
|
|
25
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
27
26
|
|
|
28
27
|
// src/section-list/SectionList.tsx
|
|
29
|
-
React3.forwardRef(function AnimatedView2(props, ref) {
|
|
30
|
-
return /* @__PURE__ */ React3__namespace.createElement("div", { ref, ...props });
|
|
31
|
-
});
|
|
32
|
-
var View = React3.forwardRef(function View2(props, ref) {
|
|
33
|
-
return /* @__PURE__ */ React3__namespace.createElement("div", { ref, ...props });
|
|
34
|
-
});
|
|
35
|
-
var Text = View;
|
|
36
|
-
|
|
37
|
-
// src/state/getContentInsetEnd.ts
|
|
38
|
-
function getContentInsetEnd(state) {
|
|
39
|
-
var _a3;
|
|
40
|
-
const { props } = state;
|
|
41
|
-
const horizontal = props.horizontal;
|
|
42
|
-
let contentInset = props.contentInset;
|
|
43
|
-
if (!contentInset) {
|
|
44
|
-
const animatedInset = (_a3 = props.animatedProps) == null ? void 0 : _a3.contentInset;
|
|
45
|
-
if (animatedInset) {
|
|
46
|
-
if ("get" in animatedInset) {
|
|
47
|
-
contentInset = animatedInset.get();
|
|
48
|
-
} else {
|
|
49
|
-
contentInset = animatedInset;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return (horizontal ? contentInset == null ? void 0 : contentInset.right : contentInset == null ? void 0 : contentInset.bottom) || 0;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// src/state/getContentSize.ts
|
|
57
|
-
function getContentSize(ctx) {
|
|
58
|
-
var _a3;
|
|
59
|
-
const { values, state } = ctx;
|
|
60
|
-
const stylePaddingTop = values.get("stylePaddingTop") || 0;
|
|
61
|
-
const stylePaddingBottom = state.props.stylePaddingBottom || 0;
|
|
62
|
-
const headerSize = values.get("headerSize") || 0;
|
|
63
|
-
const footerSize = values.get("footerSize") || 0;
|
|
64
|
-
const contentInsetBottom = getContentInsetEnd(state);
|
|
65
|
-
const totalSize = (_a3 = state.pendingTotalSize) != null ? _a3 : values.get("totalSize");
|
|
66
|
-
return headerSize + footerSize + totalSize + stylePaddingTop + stylePaddingBottom + (contentInsetBottom || 0);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// src/platform/Animated.tsx
|
|
70
|
-
var createAnimatedValue = (value) => value;
|
|
71
|
-
|
|
72
|
-
// src/state/state.tsx
|
|
73
|
-
var ContextState = React3__namespace.createContext(null);
|
|
74
|
-
var contextNum = 0;
|
|
75
|
-
function StateProvider({ children }) {
|
|
76
|
-
const [value] = React3__namespace.useState(() => ({
|
|
77
|
-
animatedScrollY: createAnimatedValue(0),
|
|
78
|
-
columnWrapperStyle: void 0,
|
|
79
|
-
contextNum: contextNum++,
|
|
80
|
-
listeners: /* @__PURE__ */ new Map(),
|
|
81
|
-
mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
|
|
82
|
-
mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
|
|
83
|
-
mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
|
|
84
|
-
mapViewabilityConfigStates: /* @__PURE__ */ new Map(),
|
|
85
|
-
mapViewabilityValues: /* @__PURE__ */ new Map(),
|
|
86
|
-
positionListeners: /* @__PURE__ */ new Map(),
|
|
87
|
-
state: void 0,
|
|
88
|
-
values: /* @__PURE__ */ new Map([
|
|
89
|
-
["alignItemsPaddingTop", 0],
|
|
90
|
-
["stylePaddingTop", 0],
|
|
91
|
-
["headerSize", 0],
|
|
92
|
-
["numContainers", 0],
|
|
93
|
-
["activeStickyIndex", -1],
|
|
94
|
-
["totalSize", 0],
|
|
95
|
-
["scrollAdjustPending", 0]
|
|
96
|
-
]),
|
|
97
|
-
viewRefs: /* @__PURE__ */ new Map()
|
|
98
|
-
}));
|
|
99
|
-
return /* @__PURE__ */ React3__namespace.createElement(ContextState.Provider, { value }, children);
|
|
100
|
-
}
|
|
101
|
-
function useStateContext() {
|
|
102
|
-
return React3__namespace.useContext(ContextState);
|
|
103
|
-
}
|
|
104
|
-
function createSelectorFunctionsArr(ctx, signalNames) {
|
|
105
|
-
let lastValues = [];
|
|
106
|
-
let lastSignalValues = [];
|
|
107
|
-
return {
|
|
108
|
-
get: () => {
|
|
109
|
-
const currentValues = [];
|
|
110
|
-
let hasChanged = false;
|
|
111
|
-
for (let i = 0; i < signalNames.length; i++) {
|
|
112
|
-
const value = peek$(ctx, signalNames[i]);
|
|
113
|
-
currentValues.push(value);
|
|
114
|
-
if (value !== lastSignalValues[i]) {
|
|
115
|
-
hasChanged = true;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
lastSignalValues = currentValues;
|
|
119
|
-
if (hasChanged) {
|
|
120
|
-
lastValues = currentValues;
|
|
121
|
-
}
|
|
122
|
-
return lastValues;
|
|
123
|
-
},
|
|
124
|
-
subscribe: (cb) => {
|
|
125
|
-
const listeners = [];
|
|
126
|
-
for (const signalName of signalNames) {
|
|
127
|
-
listeners.push(listen$(ctx, signalName, cb));
|
|
128
|
-
}
|
|
129
|
-
return () => {
|
|
130
|
-
for (const listener of listeners) {
|
|
131
|
-
listener();
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
function listen$(ctx, signalName, cb) {
|
|
138
|
-
const { listeners } = ctx;
|
|
139
|
-
let setListeners = listeners.get(signalName);
|
|
140
|
-
if (!setListeners) {
|
|
141
|
-
setListeners = /* @__PURE__ */ new Set();
|
|
142
|
-
listeners.set(signalName, setListeners);
|
|
143
|
-
}
|
|
144
|
-
setListeners.add(cb);
|
|
145
|
-
return () => setListeners.delete(cb);
|
|
146
|
-
}
|
|
147
|
-
function peek$(ctx, signalName) {
|
|
148
|
-
const { values } = ctx;
|
|
149
|
-
return values.get(signalName);
|
|
150
|
-
}
|
|
151
|
-
function set$(ctx, signalName, value) {
|
|
152
|
-
const { listeners, values } = ctx;
|
|
153
|
-
if (values.get(signalName) !== value) {
|
|
154
|
-
values.set(signalName, value);
|
|
155
|
-
const setListeners = listeners.get(signalName);
|
|
156
|
-
if (setListeners) {
|
|
157
|
-
for (const listener of setListeners) {
|
|
158
|
-
listener(value);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
function listenPosition$(ctx, key, cb) {
|
|
164
|
-
const { positionListeners } = ctx;
|
|
165
|
-
let setListeners = positionListeners.get(key);
|
|
166
|
-
if (!setListeners) {
|
|
167
|
-
setListeners = /* @__PURE__ */ new Set();
|
|
168
|
-
positionListeners.set(key, setListeners);
|
|
169
|
-
}
|
|
170
|
-
setListeners.add(cb);
|
|
171
|
-
return () => setListeners.delete(cb);
|
|
172
|
-
}
|
|
173
|
-
function notifyPosition$(ctx, key, value) {
|
|
174
|
-
const { positionListeners } = ctx;
|
|
175
|
-
const setListeners = positionListeners.get(key);
|
|
176
|
-
if (setListeners) {
|
|
177
|
-
for (const listener of setListeners) {
|
|
178
|
-
listener(value);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
function useArr$(signalNames) {
|
|
183
|
-
const ctx = React3__namespace.useContext(ContextState);
|
|
184
|
-
const { subscribe, get } = React3__namespace.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
|
|
185
|
-
const value = shim.useSyncExternalStore(subscribe, get);
|
|
186
|
-
return value;
|
|
187
|
-
}
|
|
188
|
-
function useSelector$(signalName, selector) {
|
|
189
|
-
const ctx = React3__namespace.useContext(ContextState);
|
|
190
|
-
const { subscribe, get } = React3__namespace.useMemo(() => createSelectorFunctionsArr(ctx, [signalName]), [ctx, signalName]);
|
|
191
|
-
const value = shim.useSyncExternalStore(subscribe, () => selector(get()[0]));
|
|
192
|
-
return value;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// src/components/DebugView.tsx
|
|
196
|
-
var DebugRow = ({ children }) => {
|
|
197
|
-
return /* @__PURE__ */ React3__namespace.createElement(View, { style: { alignItems: "center", flexDirection: "row", justifyContent: "space-between" } }, children);
|
|
198
|
-
};
|
|
199
|
-
var DebugView = React3__namespace.memo(function DebugView2({ state }) {
|
|
200
|
-
const ctx = useStateContext();
|
|
201
|
-
const [totalSize = 0, scrollAdjust = 0, rawScroll = 0, scroll = 0, _numContainers = 0, _numContainersPooled = 0] = useArr$([
|
|
202
|
-
"totalSize",
|
|
203
|
-
"scrollAdjust",
|
|
204
|
-
"debugRawScroll",
|
|
205
|
-
"debugComputedScroll",
|
|
206
|
-
"numContainers",
|
|
207
|
-
"numContainersPooled"
|
|
208
|
-
]);
|
|
209
|
-
const contentSize = getContentSize(ctx);
|
|
210
|
-
const [, forceUpdate] = React3.useReducer((x) => x + 1, 0);
|
|
211
|
-
useInterval(() => {
|
|
212
|
-
forceUpdate();
|
|
213
|
-
}, 100);
|
|
214
|
-
return /* @__PURE__ */ React3__namespace.createElement(
|
|
215
|
-
View,
|
|
216
|
-
{
|
|
217
|
-
pointerEvents: "none",
|
|
218
|
-
style: {
|
|
219
|
-
// height: 100,
|
|
220
|
-
backgroundColor: "#FFFFFFCC",
|
|
221
|
-
borderRadius: 4,
|
|
222
|
-
padding: 4,
|
|
223
|
-
paddingBottom: 4,
|
|
224
|
-
paddingLeft: 4,
|
|
225
|
-
position: "absolute",
|
|
226
|
-
right: 0,
|
|
227
|
-
top: 0
|
|
228
|
-
}
|
|
229
|
-
},
|
|
230
|
-
/* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(Text, null, "TotalSize:"), /* @__PURE__ */ React3__namespace.createElement(Text, null, totalSize.toFixed(2))),
|
|
231
|
-
/* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(Text, null, "ContentSize:"), /* @__PURE__ */ React3__namespace.createElement(Text, null, contentSize.toFixed(2))),
|
|
232
|
-
/* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(Text, null, "At end:"), /* @__PURE__ */ React3__namespace.createElement(Text, null, String(state.isAtEnd))),
|
|
233
|
-
/* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(Text, null, "ScrollAdjust:"), /* @__PURE__ */ React3__namespace.createElement(Text, null, scrollAdjust.toFixed(2))),
|
|
234
|
-
/* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(Text, null, "RawScroll: "), /* @__PURE__ */ React3__namespace.createElement(Text, null, rawScroll.toFixed(2))),
|
|
235
|
-
/* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(Text, null, "ComputedScroll: "), /* @__PURE__ */ React3__namespace.createElement(Text, null, scroll.toFixed(2)))
|
|
236
|
-
);
|
|
237
|
-
});
|
|
238
|
-
function useInterval(callback, delay) {
|
|
239
|
-
React3.useEffect(() => {
|
|
240
|
-
const interval = setInterval(callback, delay);
|
|
241
|
-
return () => clearInterval(interval);
|
|
242
|
-
}, [delay]);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// src/utils/devEnvironment.ts
|
|
246
|
-
var metroDev = typeof __DEV__ !== "undefined" ? __DEV__ : void 0;
|
|
247
|
-
var _a;
|
|
248
|
-
var envMode = typeof process !== "undefined" && typeof process.env === "object" && process.env ? (_a = process.env.NODE_ENV) != null ? _a : process.env.MODE : void 0;
|
|
249
|
-
var processDev = typeof envMode === "string" ? envMode.toLowerCase() !== "production" : void 0;
|
|
250
|
-
var _a2;
|
|
251
|
-
var IS_DEV = (_a2 = metroDev != null ? metroDev : processDev) != null ? _a2 : false;
|
|
252
|
-
|
|
253
|
-
// src/constants.ts
|
|
254
|
-
var POSITION_OUT_OF_VIEW = -1e7;
|
|
255
|
-
var ENABLE_DEVMODE = IS_DEV && false;
|
|
256
|
-
var ENABLE_DEBUG_VIEW = IS_DEV && false;
|
|
257
|
-
var typedForwardRef = React3.forwardRef;
|
|
258
|
-
var typedMemo = React3.memo;
|
|
259
|
-
|
|
260
|
-
// src/utils/helpers.ts
|
|
261
|
-
function isFunction(obj) {
|
|
262
|
-
return typeof obj === "function";
|
|
263
|
-
}
|
|
264
|
-
function isArray(obj) {
|
|
265
|
-
return Array.isArray(obj);
|
|
266
|
-
}
|
|
267
|
-
var warned = /* @__PURE__ */ new Set();
|
|
268
|
-
function warnDevOnce(id, text) {
|
|
269
|
-
if (IS_DEV && !warned.has(id)) {
|
|
270
|
-
warned.add(id);
|
|
271
|
-
console.warn(`[legend-list] ${text}`);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
function roundSize(size) {
|
|
275
|
-
return Math.floor(size * 8) / 8;
|
|
276
|
-
}
|
|
277
|
-
function isNullOrUndefined(value) {
|
|
278
|
-
return value === null || value === void 0;
|
|
279
|
-
}
|
|
280
|
-
function comparatorDefault(a, b) {
|
|
281
|
-
return a - b;
|
|
282
|
-
}
|
|
283
|
-
function getPadding(s, type) {
|
|
284
|
-
var _a3, _b, _c;
|
|
285
|
-
return (_c = (_b = (_a3 = s[`padding${type}`]) != null ? _a3 : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
|
|
286
|
-
}
|
|
287
|
-
function extractPadding(style, contentContainerStyle, type) {
|
|
288
|
-
return getPadding(style, type) + getPadding(contentContainerStyle, type);
|
|
289
|
-
}
|
|
290
|
-
function findContainerId(ctx, key) {
|
|
291
|
-
const numContainers = peek$(ctx, "numContainers");
|
|
292
|
-
for (let i = 0; i < numContainers; i++) {
|
|
293
|
-
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
294
|
-
if (itemKey === key) {
|
|
295
|
-
return i;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
return -1;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// src/components/PositionView.tsx
|
|
302
|
-
var PositionViewState = typedMemo(function PositionViewState2({
|
|
303
|
-
id,
|
|
304
|
-
horizontal,
|
|
305
|
-
style,
|
|
306
|
-
refView,
|
|
307
|
-
...props
|
|
308
|
-
}) {
|
|
309
|
-
const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
|
|
310
|
-
const base = {
|
|
311
|
-
contain: "paint layout style"
|
|
312
|
-
};
|
|
313
|
-
const composed = isArray(style) ? Object.assign({}, ...style) : style;
|
|
314
|
-
const combinedStyle = horizontal ? { ...base, ...composed, left: position } : { ...base, ...composed, top: position };
|
|
315
|
-
const { animatedScrollY, stickyOffset, onLayout, ...webProps } = props;
|
|
316
|
-
return /* @__PURE__ */ React3__namespace.createElement("div", { ref: refView, ...webProps, style: combinedStyle });
|
|
317
|
-
});
|
|
318
|
-
var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
319
|
-
id,
|
|
320
|
-
horizontal,
|
|
321
|
-
style,
|
|
322
|
-
refView,
|
|
323
|
-
index,
|
|
324
|
-
stickyOffset,
|
|
325
|
-
animatedScrollY: _animatedScrollY,
|
|
326
|
-
children,
|
|
327
|
-
...rest
|
|
328
|
-
}) {
|
|
329
|
-
const [position = POSITION_OUT_OF_VIEW, headerSize = 0, activeStickyIndex] = useArr$([
|
|
330
|
-
`containerPosition${id}`,
|
|
331
|
-
"headerSize",
|
|
332
|
-
"activeStickyIndex"
|
|
333
|
-
]);
|
|
334
|
-
const base = {
|
|
335
|
-
contain: "paint layout style"
|
|
336
|
-
};
|
|
337
|
-
const composed = React3__namespace.useMemo(
|
|
338
|
-
() => {
|
|
339
|
-
var _a3;
|
|
340
|
-
return (_a3 = isArray(style) ? Object.assign({}, ...style) : style) != null ? _a3 : {};
|
|
341
|
-
},
|
|
342
|
-
[style]
|
|
343
|
-
);
|
|
344
|
-
const viewStyle = React3__namespace.useMemo(() => {
|
|
345
|
-
var _a3;
|
|
346
|
-
const styleBase = { ...base, ...composed };
|
|
347
|
-
delete styleBase.transform;
|
|
348
|
-
const offset = (_a3 = stickyOffset != null ? stickyOffset : headerSize) != null ? _a3 : 0;
|
|
349
|
-
const isActive = activeStickyIndex === index;
|
|
350
|
-
styleBase.position = isActive ? "sticky" : "absolute";
|
|
351
|
-
styleBase.zIndex = index + 1e3;
|
|
352
|
-
if (horizontal) {
|
|
353
|
-
styleBase.left = isActive ? offset : position;
|
|
354
|
-
} else {
|
|
355
|
-
styleBase.top = isActive ? offset : position;
|
|
356
|
-
}
|
|
357
|
-
return styleBase;
|
|
358
|
-
}, [composed, horizontal, position, index, stickyOffset, headerSize, activeStickyIndex]);
|
|
359
|
-
return /* @__PURE__ */ React3__namespace.createElement("div", { ref: refView, style: viewStyle, ...rest }, children);
|
|
360
|
-
});
|
|
361
|
-
var PositionView = PositionViewState;
|
|
362
|
-
|
|
363
|
-
// src/constants-platform.ts
|
|
364
|
-
var IsNewArchitecture = true;
|
|
365
|
-
|
|
366
|
-
// src/state/ContextContainer.ts
|
|
367
|
-
var ContextContainer = React3.createContext(null);
|
|
368
|
-
function useIsLastItem() {
|
|
369
|
-
const { itemKey } = React3.useContext(ContextContainer);
|
|
370
|
-
const isLast = useSelector$("lastItemKeys", (lastItemKeys) => (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false);
|
|
371
|
-
return isLast;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// src/components/Separator.tsx
|
|
375
|
-
function Separator({ ItemSeparatorComponent, leadingItem }) {
|
|
376
|
-
const isLastItem = useIsLastItem();
|
|
377
|
-
return isLastItem ? null : /* @__PURE__ */ React3__namespace.createElement(ItemSeparatorComponent, { leadingItem });
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
// src/hooks/createResizeObserver.ts
|
|
381
|
-
var globalResizeObserver = null;
|
|
382
|
-
function getGlobalResizeObserver() {
|
|
383
|
-
if (!globalResizeObserver) {
|
|
384
|
-
globalResizeObserver = new ResizeObserver((entries) => {
|
|
385
|
-
for (const entry of entries) {
|
|
386
|
-
const callbacks = callbackMap.get(entry.target);
|
|
387
|
-
if (callbacks) {
|
|
388
|
-
for (const callback of callbacks) {
|
|
389
|
-
callback(entry);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
});
|
|
394
|
-
}
|
|
395
|
-
return globalResizeObserver;
|
|
396
|
-
}
|
|
397
|
-
var callbackMap = /* @__PURE__ */ new WeakMap();
|
|
398
|
-
function createResizeObserver(element, callback) {
|
|
399
|
-
if (typeof ResizeObserver === "undefined") {
|
|
400
|
-
return () => {
|
|
401
|
-
};
|
|
402
|
-
}
|
|
403
|
-
if (!element) {
|
|
404
|
-
return () => {
|
|
405
|
-
};
|
|
406
|
-
}
|
|
407
|
-
const observer = getGlobalResizeObserver();
|
|
408
|
-
let callbacks = callbackMap.get(element);
|
|
409
|
-
if (!callbacks) {
|
|
410
|
-
callbacks = /* @__PURE__ */ new Set();
|
|
411
|
-
callbackMap.set(element, callbacks);
|
|
412
|
-
observer.observe(element);
|
|
413
|
-
}
|
|
414
|
-
callbacks.add(callback);
|
|
415
|
-
return () => {
|
|
416
|
-
if (callbacks) {
|
|
417
|
-
callbacks.delete(callback);
|
|
418
|
-
if (callbacks.size === 0) {
|
|
419
|
-
callbackMap.delete(element);
|
|
420
|
-
observer.unobserve(element);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
};
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
// src/hooks/useOnLayoutSync.tsx
|
|
427
|
-
function useOnLayoutSync({
|
|
428
|
-
ref,
|
|
429
|
-
onLayoutProp,
|
|
430
|
-
onLayoutChange
|
|
431
|
-
}, deps) {
|
|
432
|
-
React3.useLayoutEffect(() => {
|
|
433
|
-
var _a3, _b;
|
|
434
|
-
const current = ref.current;
|
|
435
|
-
const scrollableNode = (_b = (_a3 = current == null ? void 0 : current.getScrollableNode) == null ? void 0 : _a3.call(current)) != null ? _b : null;
|
|
436
|
-
const element = scrollableNode || current;
|
|
437
|
-
if (!element) {
|
|
438
|
-
return;
|
|
439
|
-
}
|
|
440
|
-
const emit = (layout, fromLayoutEffect) => {
|
|
441
|
-
if (layout.height === 0 && layout.width === 0) {
|
|
442
|
-
return;
|
|
443
|
-
}
|
|
444
|
-
onLayoutChange(layout, fromLayoutEffect);
|
|
445
|
-
onLayoutProp == null ? void 0 : onLayoutProp({ nativeEvent: { layout } });
|
|
446
|
-
};
|
|
447
|
-
const rect = element.getBoundingClientRect();
|
|
448
|
-
emit(toLayout(rect), true);
|
|
449
|
-
let prevRect = rect;
|
|
450
|
-
return createResizeObserver(element, (entry) => {
|
|
451
|
-
var _a4;
|
|
452
|
-
const target = entry.target instanceof HTMLElement ? entry.target : void 0;
|
|
453
|
-
const rectObserved = (_a4 = entry.contentRect) != null ? _a4 : target == null ? void 0 : target.getBoundingClientRect();
|
|
454
|
-
if (rectObserved.width !== prevRect.width || rectObserved.height !== prevRect.height) {
|
|
455
|
-
prevRect = rectObserved;
|
|
456
|
-
emit(toLayout(rectObserved), false);
|
|
457
|
-
}
|
|
458
|
-
});
|
|
459
|
-
}, deps || []);
|
|
460
|
-
return {};
|
|
461
|
-
}
|
|
462
|
-
function toLayout(rect) {
|
|
463
|
-
if (!rect) {
|
|
464
|
-
return { height: 0, width: 0, x: 0, y: 0 };
|
|
465
|
-
}
|
|
466
|
-
return {
|
|
467
|
-
height: rect.height,
|
|
468
|
-
width: rect.width,
|
|
469
|
-
x: rect.left,
|
|
470
|
-
y: rect.top
|
|
471
|
-
};
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
// src/components/Container.tsx
|
|
475
|
-
var Container = typedMemo(function Container2({
|
|
476
|
-
id,
|
|
477
|
-
recycleItems,
|
|
478
|
-
horizontal,
|
|
479
|
-
getRenderedItem: getRenderedItem2,
|
|
480
|
-
updateItemSize: updateItemSize2,
|
|
481
|
-
ItemSeparatorComponent
|
|
482
|
-
}) {
|
|
483
|
-
const ctx = useStateContext();
|
|
484
|
-
const { columnWrapperStyle, animatedScrollY } = ctx;
|
|
485
|
-
const [column = 0, data, itemKey, numColumns, extraData, isSticky, stickyOffset] = useArr$([
|
|
486
|
-
`containerColumn${id}`,
|
|
487
|
-
`containerItemData${id}`,
|
|
488
|
-
`containerItemKey${id}`,
|
|
489
|
-
"numColumns",
|
|
490
|
-
"extraData",
|
|
491
|
-
`containerSticky${id}`,
|
|
492
|
-
`containerStickyOffset${id}`
|
|
493
|
-
]);
|
|
494
|
-
const itemLayoutRef = React3.useRef({
|
|
495
|
-
horizontal,
|
|
496
|
-
itemKey,
|
|
497
|
-
updateItemSize: updateItemSize2
|
|
498
|
-
});
|
|
499
|
-
itemLayoutRef.current.horizontal = horizontal;
|
|
500
|
-
itemLayoutRef.current.itemKey = itemKey;
|
|
501
|
-
itemLayoutRef.current.updateItemSize = updateItemSize2;
|
|
502
|
-
const ref = React3.useRef(null);
|
|
503
|
-
const [layoutRenderCount, forceLayoutRender] = React3.useState(0);
|
|
504
|
-
const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
|
|
505
|
-
const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
|
|
506
|
-
const didLayoutRef = React3.useRef(false);
|
|
507
|
-
const style = React3.useMemo(() => {
|
|
508
|
-
let paddingStyles;
|
|
509
|
-
if (columnWrapperStyle) {
|
|
510
|
-
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
511
|
-
if (horizontal) {
|
|
512
|
-
paddingStyles = {
|
|
513
|
-
paddingRight: columnGap || gap || void 0,
|
|
514
|
-
paddingVertical: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
|
|
515
|
-
};
|
|
516
|
-
} else {
|
|
517
|
-
paddingStyles = {
|
|
518
|
-
paddingBottom: rowGap || gap || void 0,
|
|
519
|
-
paddingHorizontal: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
|
|
520
|
-
};
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
return horizontal ? {
|
|
524
|
-
flexDirection: ItemSeparatorComponent ? "row" : void 0,
|
|
525
|
-
height: otherAxisSize,
|
|
526
|
-
left: 0,
|
|
527
|
-
position: "absolute",
|
|
528
|
-
top: otherAxisPos,
|
|
529
|
-
...paddingStyles || {}
|
|
530
|
-
} : {
|
|
531
|
-
left: otherAxisPos,
|
|
532
|
-
position: "absolute",
|
|
533
|
-
right: numColumns > 1 ? null : 0,
|
|
534
|
-
top: 0,
|
|
535
|
-
width: otherAxisSize,
|
|
536
|
-
...paddingStyles || {}
|
|
537
|
-
};
|
|
538
|
-
}, [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns]);
|
|
539
|
-
const renderedItemInfo = React3.useMemo(
|
|
540
|
-
() => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
|
|
541
|
-
[itemKey, data, extraData]
|
|
542
|
-
);
|
|
543
|
-
const { index, renderedItem } = renderedItemInfo || {};
|
|
544
|
-
const contextValue = React3.useMemo(() => {
|
|
545
|
-
ctx.viewRefs.set(id, ref);
|
|
546
|
-
return {
|
|
547
|
-
containerId: id,
|
|
548
|
-
index,
|
|
549
|
-
itemKey,
|
|
550
|
-
triggerLayout: () => {
|
|
551
|
-
forceLayoutRender((v) => v + 1);
|
|
552
|
-
},
|
|
553
|
-
value: data
|
|
554
|
-
};
|
|
555
|
-
}, [id, itemKey, index, data]);
|
|
556
|
-
const onLayoutChange = React3.useCallback((rectangle) => {
|
|
557
|
-
const {
|
|
558
|
-
horizontal: currentHorizontal,
|
|
559
|
-
itemKey: currentItemKey,
|
|
560
|
-
updateItemSize: updateItemSizeFn
|
|
561
|
-
} = itemLayoutRef.current;
|
|
562
|
-
if (isNullOrUndefined(currentItemKey)) {
|
|
563
|
-
return;
|
|
564
|
-
}
|
|
565
|
-
didLayoutRef.current = true;
|
|
566
|
-
let layout = rectangle;
|
|
567
|
-
roundSize(rectangle[currentHorizontal ? "width" : "height"]);
|
|
568
|
-
const doUpdate = () => {
|
|
569
|
-
itemLayoutRef.current.lastSize = { height: layout.height, width: layout.width };
|
|
570
|
-
updateItemSizeFn(currentItemKey, layout);
|
|
571
|
-
didLayoutRef.current = true;
|
|
572
|
-
};
|
|
573
|
-
{
|
|
574
|
-
doUpdate();
|
|
575
|
-
}
|
|
576
|
-
}, []);
|
|
577
|
-
const { onLayout } = useOnLayoutSync(
|
|
578
|
-
{
|
|
579
|
-
onLayoutChange,
|
|
580
|
-
ref
|
|
581
|
-
},
|
|
582
|
-
[itemKey, layoutRenderCount]
|
|
583
|
-
);
|
|
584
|
-
const PositionComponent = isSticky ? PositionViewSticky : PositionView;
|
|
585
|
-
return /* @__PURE__ */ React3__namespace.createElement(
|
|
586
|
-
PositionComponent,
|
|
587
|
-
{
|
|
588
|
-
animatedScrollY: isSticky ? animatedScrollY : void 0,
|
|
589
|
-
horizontal,
|
|
590
|
-
id,
|
|
591
|
-
index,
|
|
592
|
-
key: recycleItems ? void 0 : itemKey,
|
|
593
|
-
onLayout,
|
|
594
|
-
refView: ref,
|
|
595
|
-
stickyOffset: isSticky ? stickyOffset : void 0,
|
|
596
|
-
style
|
|
597
|
-
},
|
|
598
|
-
/* @__PURE__ */ React3__namespace.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React3__namespace.createElement(Separator, { ItemSeparatorComponent, leadingItem: renderedItemInfo.item }))
|
|
599
|
-
);
|
|
600
|
-
});
|
|
601
|
-
|
|
602
|
-
// src/platform/Platform.ts
|
|
603
|
-
var Platform = {
|
|
604
|
-
// Widen the type to avoid unreachable-branch lints in cross-platform code that compares against other OSes
|
|
605
|
-
OS: "web"
|
|
606
|
-
};
|
|
607
|
-
|
|
608
|
-
// src/utils/reordering.ts
|
|
609
|
-
var mapFn = (element) => {
|
|
610
|
-
const indexStr = element.getAttribute("index");
|
|
611
|
-
return [element, indexStr === null ? null : parseInt(indexStr)];
|
|
612
|
-
};
|
|
613
|
-
function sortDOMElements(container) {
|
|
614
|
-
const elements = Array.from(container.children);
|
|
615
|
-
if (elements.length <= 1) return elements;
|
|
616
|
-
const items = elements.map(mapFn);
|
|
617
|
-
items.sort((a, b) => {
|
|
618
|
-
const aKey = a[1];
|
|
619
|
-
const bKey = b[1];
|
|
620
|
-
if (aKey === null) {
|
|
621
|
-
return 1;
|
|
622
|
-
}
|
|
623
|
-
if (bKey === null) {
|
|
624
|
-
return -1;
|
|
625
|
-
}
|
|
626
|
-
return aKey - bKey;
|
|
627
|
-
});
|
|
628
|
-
const targetPositions = /* @__PURE__ */ new Map();
|
|
629
|
-
items.forEach((item, index) => {
|
|
630
|
-
targetPositions.set(item[0], index);
|
|
631
|
-
});
|
|
632
|
-
const currentPositions = elements.map((el) => targetPositions.get(el));
|
|
633
|
-
const lis = findLIS(currentPositions);
|
|
634
|
-
const stableIndices = new Set(lis);
|
|
635
|
-
for (let targetPos = 0; targetPos < items.length; targetPos++) {
|
|
636
|
-
const element = items[targetPos][0];
|
|
637
|
-
const currentPos = elements.indexOf(element);
|
|
638
|
-
if (!stableIndices.has(currentPos)) {
|
|
639
|
-
let nextStableElement = null;
|
|
640
|
-
for (let i = targetPos + 1; i < items.length; i++) {
|
|
641
|
-
const nextEl = items[i][0];
|
|
642
|
-
const nextCurrentPos = elements.indexOf(nextEl);
|
|
643
|
-
if (stableIndices.has(nextCurrentPos)) {
|
|
644
|
-
nextStableElement = nextEl;
|
|
645
|
-
break;
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
if (nextStableElement) {
|
|
649
|
-
container.insertBefore(element, nextStableElement);
|
|
650
|
-
} else {
|
|
651
|
-
container.appendChild(element);
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
function findLIS(arr) {
|
|
657
|
-
const n = arr.length;
|
|
658
|
-
const tails = [];
|
|
659
|
-
const predecessors = new Array(n).fill(-1);
|
|
660
|
-
const indices = [];
|
|
661
|
-
for (let i = 0; i < n; i++) {
|
|
662
|
-
const num = arr[i];
|
|
663
|
-
let left = 0, right = tails.length;
|
|
664
|
-
while (left < right) {
|
|
665
|
-
const mid = Math.floor((left + right) / 2);
|
|
666
|
-
if (arr[indices[mid]] < num) {
|
|
667
|
-
left = mid + 1;
|
|
668
|
-
} else {
|
|
669
|
-
right = mid;
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
if (left === tails.length) {
|
|
673
|
-
tails.push(num);
|
|
674
|
-
indices.push(i);
|
|
675
|
-
} else {
|
|
676
|
-
tails[left] = num;
|
|
677
|
-
indices[left] = i;
|
|
678
|
-
}
|
|
679
|
-
if (left > 0) {
|
|
680
|
-
predecessors[i] = indices[left - 1];
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
const result = [];
|
|
684
|
-
let k = indices[indices.length - 1];
|
|
685
|
-
while (k !== -1) {
|
|
686
|
-
result.unshift(k);
|
|
687
|
-
k = predecessors[k];
|
|
688
|
-
}
|
|
689
|
-
return result;
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
// src/hooks/useDOMOrder.ts
|
|
693
|
-
function useDOMOrder(ref) {
|
|
694
|
-
const ctx = useStateContext();
|
|
695
|
-
const debounceRef = React3.useRef(void 0);
|
|
696
|
-
React3.useEffect(() => {
|
|
697
|
-
const unsubscribe = listen$(ctx, "lastPositionUpdate", () => {
|
|
698
|
-
if (debounceRef.current !== void 0) {
|
|
699
|
-
clearTimeout(debounceRef.current);
|
|
700
|
-
}
|
|
701
|
-
debounceRef.current = setTimeout(() => {
|
|
702
|
-
const parent = ref.current;
|
|
703
|
-
if (parent) {
|
|
704
|
-
sortDOMElements(parent);
|
|
705
|
-
}
|
|
706
|
-
debounceRef.current = void 0;
|
|
707
|
-
}, 500);
|
|
708
|
-
});
|
|
709
|
-
return () => {
|
|
710
|
-
unsubscribe();
|
|
711
|
-
if (debounceRef.current !== void 0) {
|
|
712
|
-
clearTimeout(debounceRef.current);
|
|
713
|
-
}
|
|
714
|
-
};
|
|
715
|
-
}, [ctx]);
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
// src/components/Containers.tsx
|
|
719
|
-
var ContainersInner = typedMemo(function ContainersInner2({ horizontal, numColumns, children }) {
|
|
720
|
-
const ref = React3.useRef(null);
|
|
721
|
-
const ctx = useStateContext();
|
|
722
|
-
const columnWrapperStyle = ctx.columnWrapperStyle;
|
|
723
|
-
const [totalSize, otherAxisSize] = useArr$(["totalSize", "otherAxisSize"]);
|
|
724
|
-
useDOMOrder(ref);
|
|
725
|
-
const style = horizontal ? { minHeight: otherAxisSize, position: "relative", width: totalSize } : { height: totalSize, minWidth: otherAxisSize, position: "relative" };
|
|
726
|
-
if (columnWrapperStyle && numColumns > 1) {
|
|
727
|
-
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
728
|
-
const gapX = columnGap || gap || 0;
|
|
729
|
-
const gapY = rowGap || gap || 0;
|
|
730
|
-
if (horizontal) {
|
|
731
|
-
if (gapY) {
|
|
732
|
-
style.marginTop = style.marginBottom = -gapY / 2;
|
|
733
|
-
}
|
|
734
|
-
if (gapX) {
|
|
735
|
-
style.marginRight = -gapX;
|
|
736
|
-
}
|
|
737
|
-
} else {
|
|
738
|
-
if (gapX) {
|
|
739
|
-
style.marginLeft = style.marginRight = -gapX;
|
|
740
|
-
}
|
|
741
|
-
if (gapY) {
|
|
742
|
-
style.marginBottom = -gapY;
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
return /* @__PURE__ */ React3__namespace.createElement("div", { ref, style }, children);
|
|
747
|
-
});
|
|
748
|
-
var Containers = typedMemo(function Containers2({
|
|
749
|
-
horizontal,
|
|
750
|
-
recycleItems,
|
|
751
|
-
ItemSeparatorComponent,
|
|
752
|
-
waitForInitialLayout,
|
|
753
|
-
updateItemSize: updateItemSize2,
|
|
754
|
-
getRenderedItem: getRenderedItem2
|
|
755
|
-
}) {
|
|
756
|
-
const [numContainers, numColumns] = useArr$(["numContainersPooled", "numColumns"]);
|
|
757
|
-
const containers = [];
|
|
758
|
-
for (let i = 0; i < numContainers; i++) {
|
|
759
|
-
containers.push(
|
|
760
|
-
/* @__PURE__ */ React3__namespace.createElement(
|
|
761
|
-
Container,
|
|
762
|
-
{
|
|
763
|
-
getRenderedItem: getRenderedItem2,
|
|
764
|
-
horizontal,
|
|
765
|
-
ItemSeparatorComponent,
|
|
766
|
-
id: i,
|
|
767
|
-
key: i,
|
|
768
|
-
recycleItems,
|
|
769
|
-
updateItemSize: updateItemSize2
|
|
770
|
-
}
|
|
771
|
-
)
|
|
772
|
-
);
|
|
773
|
-
}
|
|
774
|
-
return /* @__PURE__ */ React3__namespace.createElement(ContainersInner, { horizontal, numColumns, waitForInitialLayout }, containers);
|
|
775
|
-
});
|
|
776
|
-
function DevNumbers() {
|
|
777
|
-
return IS_DEV && // biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
|
|
778
|
-
React3__namespace.memo(function DevNumbers2() {
|
|
779
|
-
return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React3__namespace.createElement(
|
|
780
|
-
"div",
|
|
781
|
-
{
|
|
782
|
-
key: index,
|
|
783
|
-
style: {
|
|
784
|
-
height: 100,
|
|
785
|
-
pointerEvents: "none",
|
|
786
|
-
position: "absolute",
|
|
787
|
-
top: index * 100,
|
|
788
|
-
width: "100%"
|
|
789
|
-
}
|
|
790
|
-
},
|
|
791
|
-
/* @__PURE__ */ React3__namespace.createElement("div", { style: { color: "red" } }, index * 100)
|
|
792
|
-
));
|
|
793
|
-
});
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
// src/platform/StyleSheet.tsx
|
|
797
|
-
function flattenStyles(styles) {
|
|
798
|
-
if (isArray(styles)) {
|
|
799
|
-
return Object.assign({}, ...styles.filter(Boolean));
|
|
800
|
-
}
|
|
801
|
-
return styles;
|
|
802
|
-
}
|
|
803
|
-
var StyleSheet = {
|
|
804
|
-
create: (styles) => styles,
|
|
805
|
-
flatten: (style) => flattenStyles(style)
|
|
806
|
-
};
|
|
807
|
-
|
|
808
|
-
// src/components/ListComponentScrollView.tsx
|
|
809
|
-
var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView2({
|
|
810
|
-
children,
|
|
811
|
-
style,
|
|
812
|
-
contentContainerStyle,
|
|
813
|
-
horizontal = false,
|
|
814
|
-
contentOffset,
|
|
815
|
-
maintainVisibleContentPosition,
|
|
816
|
-
onScroll: onScroll2,
|
|
817
|
-
onMomentumScrollEnd,
|
|
818
|
-
showsHorizontalScrollIndicator = true,
|
|
819
|
-
showsVerticalScrollIndicator = true,
|
|
820
|
-
refreshControl,
|
|
821
|
-
onLayout,
|
|
822
|
-
...props
|
|
823
|
-
}, ref) {
|
|
824
|
-
const scrollRef = React3.useRef(null);
|
|
825
|
-
const contentRef = React3.useRef(null);
|
|
826
|
-
React3.useImperativeHandle(ref, () => {
|
|
827
|
-
const api = {
|
|
828
|
-
getBoundingClientRect: () => {
|
|
829
|
-
var _a3;
|
|
830
|
-
return (_a3 = scrollRef.current) == null ? void 0 : _a3.getBoundingClientRect();
|
|
831
|
-
},
|
|
832
|
-
getScrollableNode: () => scrollRef.current,
|
|
833
|
-
getScrollResponder: () => scrollRef.current,
|
|
834
|
-
scrollBy: (x, y) => {
|
|
835
|
-
const el = scrollRef.current;
|
|
836
|
-
if (!el) return;
|
|
837
|
-
el.scrollBy(x, y);
|
|
838
|
-
},
|
|
839
|
-
scrollTo: (options) => {
|
|
840
|
-
const el = scrollRef.current;
|
|
841
|
-
if (!el) return;
|
|
842
|
-
const { x = 0, y = 0, animated = true } = options;
|
|
843
|
-
el.scrollTo({ behavior: animated ? "smooth" : "auto", left: x, top: y });
|
|
844
|
-
},
|
|
845
|
-
scrollToEnd: (options = {}) => {
|
|
846
|
-
const el = scrollRef.current;
|
|
847
|
-
if (!el) return;
|
|
848
|
-
const { animated = true } = options;
|
|
849
|
-
if (horizontal) {
|
|
850
|
-
el.scrollTo({ behavior: animated ? "smooth" : "auto", left: el.scrollWidth });
|
|
851
|
-
} else {
|
|
852
|
-
el.scrollTo({ behavior: animated ? "smooth" : "auto", top: el.scrollHeight });
|
|
853
|
-
}
|
|
854
|
-
},
|
|
855
|
-
scrollToOffset: (params) => {
|
|
856
|
-
const el = scrollRef.current;
|
|
857
|
-
if (!el) return;
|
|
858
|
-
const { offset, animated = true } = params;
|
|
859
|
-
if (horizontal) {
|
|
860
|
-
el.scrollTo({ behavior: animated ? "smooth" : "auto", left: offset });
|
|
861
|
-
} else {
|
|
862
|
-
el.scrollTo({ behavior: animated ? "smooth" : "auto", top: offset });
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
};
|
|
866
|
-
return api;
|
|
867
|
-
}, [horizontal]);
|
|
868
|
-
const handleScroll = React3.useCallback(
|
|
869
|
-
(event) => {
|
|
870
|
-
if (!onScroll2 || !(event == null ? void 0 : event.target)) {
|
|
871
|
-
return;
|
|
872
|
-
}
|
|
873
|
-
const target = event.target;
|
|
874
|
-
const scrollEvent = {
|
|
875
|
-
nativeEvent: {
|
|
876
|
-
contentOffset: {
|
|
877
|
-
x: target.scrollLeft,
|
|
878
|
-
y: target.scrollTop
|
|
879
|
-
},
|
|
880
|
-
contentSize: {
|
|
881
|
-
height: target.scrollHeight,
|
|
882
|
-
width: target.scrollWidth
|
|
883
|
-
},
|
|
884
|
-
layoutMeasurement: {
|
|
885
|
-
height: target.clientHeight,
|
|
886
|
-
width: target.clientWidth
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
};
|
|
890
|
-
onScroll2(scrollEvent);
|
|
891
|
-
},
|
|
892
|
-
[onScroll2, onMomentumScrollEnd]
|
|
893
|
-
);
|
|
894
|
-
React3.useLayoutEffect(() => {
|
|
895
|
-
const element = scrollRef.current;
|
|
896
|
-
if (!element) return;
|
|
897
|
-
element.addEventListener("scroll", handleScroll);
|
|
898
|
-
return () => {
|
|
899
|
-
element.removeEventListener("scroll", handleScroll);
|
|
900
|
-
};
|
|
901
|
-
}, [handleScroll]);
|
|
902
|
-
React3.useEffect(() => {
|
|
903
|
-
const doScroll = () => {
|
|
904
|
-
if (contentOffset && scrollRef.current) {
|
|
905
|
-
scrollRef.current.scrollLeft = contentOffset.x || 0;
|
|
906
|
-
scrollRef.current.scrollTop = contentOffset.y || 0;
|
|
907
|
-
}
|
|
908
|
-
};
|
|
909
|
-
doScroll();
|
|
910
|
-
requestAnimationFrame(doScroll);
|
|
911
|
-
}, [contentOffset == null ? void 0 : contentOffset.x, contentOffset == null ? void 0 : contentOffset.y]);
|
|
912
|
-
React3.useLayoutEffect(() => {
|
|
913
|
-
if (!onLayout || !scrollRef.current) return;
|
|
914
|
-
const element = scrollRef.current;
|
|
915
|
-
const fireLayout = () => {
|
|
916
|
-
const rect = element.getBoundingClientRect();
|
|
917
|
-
onLayout({
|
|
918
|
-
nativeEvent: {
|
|
919
|
-
layout: {
|
|
920
|
-
height: rect.height,
|
|
921
|
-
width: rect.width,
|
|
922
|
-
x: rect.left,
|
|
923
|
-
y: rect.top
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
});
|
|
927
|
-
};
|
|
928
|
-
fireLayout();
|
|
929
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
930
|
-
fireLayout();
|
|
931
|
-
});
|
|
932
|
-
resizeObserver.observe(element);
|
|
933
|
-
return () => resizeObserver.disconnect();
|
|
934
|
-
}, [onLayout]);
|
|
935
|
-
const scrollViewStyle = {
|
|
936
|
-
overflow: "auto",
|
|
937
|
-
overflowX: horizontal ? "auto" : showsHorizontalScrollIndicator ? "auto" : "hidden",
|
|
938
|
-
overflowY: horizontal ? showsVerticalScrollIndicator ? "auto" : "hidden" : "auto",
|
|
939
|
-
position: "relative",
|
|
940
|
-
// Ensure proper positioning context
|
|
941
|
-
WebkitOverflowScrolling: "touch",
|
|
942
|
-
// iOS momentum scrolling
|
|
943
|
-
...StyleSheet.flatten(style)
|
|
944
|
-
};
|
|
945
|
-
const contentStyle = {
|
|
946
|
-
display: horizontal ? "flex" : "block",
|
|
947
|
-
flexDirection: horizontal ? "row" : void 0,
|
|
948
|
-
minHeight: horizontal ? void 0 : "100%",
|
|
949
|
-
minWidth: horizontal ? "100%" : void 0,
|
|
950
|
-
...StyleSheet.flatten(contentContainerStyle)
|
|
951
|
-
};
|
|
952
|
-
const { contentInset, scrollEventThrottle, ScrollComponent, ...webProps } = props;
|
|
953
|
-
return /* @__PURE__ */ React3__namespace.createElement("div", { ref: scrollRef, ...webProps, style: scrollViewStyle }, refreshControl, /* @__PURE__ */ React3__namespace.createElement("div", { ref: contentRef, style: contentStyle }, children));
|
|
954
|
-
});
|
|
955
|
-
function Padding() {
|
|
956
|
-
const [paddingTop] = useArr$(["alignItemsPaddingTop"]);
|
|
957
|
-
return /* @__PURE__ */ React3__namespace.createElement("div", { style: { paddingTop } });
|
|
958
|
-
}
|
|
959
|
-
function PaddingDevMode() {
|
|
960
|
-
const [paddingTop] = useArr$(["alignItemsPaddingTop"]);
|
|
961
|
-
return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement("div", { style: { paddingTop } }), /* @__PURE__ */ React3__namespace.createElement(
|
|
962
|
-
"div",
|
|
963
|
-
{
|
|
964
|
-
style: {
|
|
965
|
-
backgroundColor: "green",
|
|
966
|
-
height: paddingTop,
|
|
967
|
-
left: 0,
|
|
968
|
-
position: "absolute",
|
|
969
|
-
right: 0,
|
|
970
|
-
top: 0
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
));
|
|
974
|
-
}
|
|
975
|
-
function useValueListener$(key, callback) {
|
|
976
|
-
const ctx = useStateContext();
|
|
977
|
-
React3.useLayoutEffect(() => {
|
|
978
|
-
const unsubscribe = listen$(ctx, key, (value) => {
|
|
979
|
-
callback(value);
|
|
980
|
-
});
|
|
981
|
-
return unsubscribe;
|
|
982
|
-
}, [callback, ctx, key]);
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
// src/components/ScrollAdjust.tsx
|
|
986
|
-
function ScrollAdjust() {
|
|
987
|
-
const ctx = useStateContext();
|
|
988
|
-
const lastScrollOffsetRef = React3__namespace.useRef(0);
|
|
989
|
-
const callback = React3__namespace.useCallback(() => {
|
|
990
|
-
var _a3;
|
|
991
|
-
const scrollAdjust = peek$(ctx, "scrollAdjust");
|
|
992
|
-
const scrollAdjustUserOffset = peek$(ctx, "scrollAdjustUserOffset");
|
|
993
|
-
const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0);
|
|
994
|
-
const scrollView = (_a3 = ctx.state) == null ? void 0 : _a3.refScroller.current;
|
|
995
|
-
if (scrollView && scrollOffset !== lastScrollOffsetRef.current) {
|
|
996
|
-
const scrollDelta = scrollOffset - lastScrollOffsetRef.current;
|
|
997
|
-
if (scrollDelta !== 0) {
|
|
998
|
-
const el = scrollView.getScrollableNode();
|
|
999
|
-
const prevScroll = el.scrollTop;
|
|
1000
|
-
const nextScroll = prevScroll + scrollDelta;
|
|
1001
|
-
const totalSize = el.scrollHeight;
|
|
1002
|
-
if (scrollDelta > 0 && !ctx.state.adjustingFromInitialMount && totalSize < nextScroll + el.clientHeight) {
|
|
1003
|
-
const child = el.firstElementChild;
|
|
1004
|
-
const prevPaddingBottom = child.style.paddingBottom;
|
|
1005
|
-
const pad = (nextScroll + el.clientHeight - totalSize) * 2;
|
|
1006
|
-
child.style.paddingBottom = `${pad}px`;
|
|
1007
|
-
void el.offsetHeight;
|
|
1008
|
-
scrollView.scrollBy(0, scrollDelta);
|
|
1009
|
-
requestAnimationFrame(() => {
|
|
1010
|
-
child.style.paddingBottom = prevPaddingBottom;
|
|
1011
|
-
});
|
|
1012
|
-
} else {
|
|
1013
|
-
scrollView.scrollBy(0, scrollDelta);
|
|
1014
|
-
}
|
|
1015
|
-
if (IS_DEV) {
|
|
1016
|
-
console.log("ScrollAdjust (web scrollBy)", scrollDelta, "total offset:", scrollOffset);
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
lastScrollOffsetRef.current = scrollOffset;
|
|
1020
|
-
}
|
|
1021
|
-
}, [ctx]);
|
|
1022
|
-
useValueListener$("scrollAdjust", callback);
|
|
1023
|
-
useValueListener$("scrollAdjustUserOffset", callback);
|
|
1024
|
-
return null;
|
|
1025
|
-
}
|
|
1026
|
-
function SnapWrapper({ ScrollComponent, ...props }) {
|
|
1027
|
-
const [snapToOffsets] = useArr$(["snapToOffsets"]);
|
|
1028
|
-
return /* @__PURE__ */ React3__namespace.createElement(ScrollComponent, { ...props, snapToOffsets });
|
|
1029
|
-
}
|
|
1030
|
-
var LayoutView = ({ onLayoutChange, refView, children, ...rest }) => {
|
|
1031
|
-
const ref = refView != null ? refView : React3.useRef();
|
|
1032
|
-
useOnLayoutSync({ onLayoutChange, ref });
|
|
1033
|
-
return /* @__PURE__ */ React3__namespace.createElement("div", { ...rest, ref }, children);
|
|
1034
|
-
};
|
|
1035
|
-
|
|
1036
|
-
// src/components/ListComponent.tsx
|
|
1037
|
-
var getComponent = (Component) => {
|
|
1038
|
-
if (React3__namespace.isValidElement(Component)) {
|
|
1039
|
-
return Component;
|
|
1040
|
-
}
|
|
1041
|
-
if (Component) {
|
|
1042
|
-
return /* @__PURE__ */ React3__namespace.createElement(Component, null);
|
|
1043
|
-
}
|
|
1044
|
-
return null;
|
|
1045
|
-
};
|
|
1046
|
-
var ListComponent = typedMemo(function ListComponent2({
|
|
1047
|
-
canRender,
|
|
1048
|
-
style,
|
|
1049
|
-
contentContainerStyle,
|
|
1050
|
-
horizontal,
|
|
1051
|
-
initialContentOffset,
|
|
1052
|
-
recycleItems,
|
|
1053
|
-
ItemSeparatorComponent,
|
|
1054
|
-
alignItemsAtEnd,
|
|
1055
|
-
waitForInitialLayout,
|
|
1056
|
-
onScroll: onScroll2,
|
|
1057
|
-
onLayout,
|
|
1058
|
-
ListHeaderComponent,
|
|
1059
|
-
ListHeaderComponentStyle,
|
|
1060
|
-
ListFooterComponent,
|
|
1061
|
-
ListFooterComponentStyle,
|
|
1062
|
-
ListEmptyComponent,
|
|
1063
|
-
getRenderedItem: getRenderedItem2,
|
|
1064
|
-
updateItemSize: updateItemSize2,
|
|
1065
|
-
refScrollView,
|
|
1066
|
-
maintainVisibleContentPosition,
|
|
1067
|
-
renderScrollComponent,
|
|
1068
|
-
scrollAdjustHandler,
|
|
1069
|
-
onLayoutHeader,
|
|
1070
|
-
snapToIndices,
|
|
1071
|
-
stickyHeaderIndices,
|
|
1072
|
-
...rest
|
|
1073
|
-
}) {
|
|
1074
|
-
const ctx = useStateContext();
|
|
1075
|
-
const ScrollComponent = renderScrollComponent ? React3.useMemo(
|
|
1076
|
-
() => React3__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
|
|
1077
|
-
[renderScrollComponent]
|
|
1078
|
-
) : ListComponentScrollView;
|
|
1079
|
-
const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
|
|
1080
|
-
return /* @__PURE__ */ React3__namespace.createElement(
|
|
1081
|
-
SnapOrScroll,
|
|
1082
|
-
{
|
|
1083
|
-
...rest,
|
|
1084
|
-
contentContainerStyle: [
|
|
1085
|
-
contentContainerStyle,
|
|
1086
|
-
horizontal ? {
|
|
1087
|
-
height: "100%"
|
|
1088
|
-
} : {}
|
|
1089
|
-
],
|
|
1090
|
-
contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
|
|
1091
|
-
horizontal,
|
|
1092
|
-
maintainVisibleContentPosition: maintainVisibleContentPosition ? { minIndexForVisible: 0 } : void 0,
|
|
1093
|
-
onLayout,
|
|
1094
|
-
onScroll: onScroll2,
|
|
1095
|
-
ref: refScrollView,
|
|
1096
|
-
ScrollComponent: snapToIndices ? ScrollComponent : void 0,
|
|
1097
|
-
style
|
|
1098
|
-
},
|
|
1099
|
-
/* @__PURE__ */ React3__namespace.createElement(ScrollAdjust, null),
|
|
1100
|
-
ENABLE_DEVMODE ? /* @__PURE__ */ React3__namespace.createElement(PaddingDevMode, null) : /* @__PURE__ */ React3__namespace.createElement(Padding, null),
|
|
1101
|
-
ListHeaderComponent && /* @__PURE__ */ React3__namespace.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
|
|
1102
|
-
ListEmptyComponent && getComponent(ListEmptyComponent),
|
|
1103
|
-
canRender && !ListEmptyComponent && /* @__PURE__ */ React3__namespace.createElement(
|
|
1104
|
-
Containers,
|
|
1105
|
-
{
|
|
1106
|
-
getRenderedItem: getRenderedItem2,
|
|
1107
|
-
horizontal,
|
|
1108
|
-
ItemSeparatorComponent,
|
|
1109
|
-
recycleItems,
|
|
1110
|
-
updateItemSize: updateItemSize2,
|
|
1111
|
-
waitForInitialLayout
|
|
1112
|
-
}
|
|
1113
|
-
),
|
|
1114
|
-
ListFooterComponent && /* @__PURE__ */ React3__namespace.createElement(
|
|
1115
|
-
LayoutView,
|
|
1116
|
-
{
|
|
1117
|
-
onLayoutChange: (layout) => {
|
|
1118
|
-
const size = layout[horizontal ? "width" : "height"];
|
|
1119
|
-
set$(ctx, "footerSize", size);
|
|
1120
|
-
},
|
|
1121
|
-
style: ListFooterComponentStyle
|
|
1122
|
-
},
|
|
1123
|
-
getComponent(ListFooterComponent)
|
|
1124
|
-
),
|
|
1125
|
-
IS_DEV && ENABLE_DEVMODE && /* @__PURE__ */ React3__namespace.createElement(DevNumbers, null)
|
|
1126
|
-
);
|
|
1127
|
-
});
|
|
1128
|
-
|
|
1129
|
-
// src/utils/getId.ts
|
|
1130
|
-
function getId(state, index) {
|
|
1131
|
-
const { data, keyExtractor } = state.props;
|
|
1132
|
-
if (!data) {
|
|
1133
|
-
return "";
|
|
1134
|
-
}
|
|
1135
|
-
const ret = index < data.length ? keyExtractor ? keyExtractor(data[index], index) : index : null;
|
|
1136
|
-
const id = ret;
|
|
1137
|
-
state.idCache[index] = id;
|
|
1138
|
-
return id;
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
// src/core/calculateOffsetForIndex.ts
|
|
1142
|
-
function calculateOffsetForIndex(ctx, index) {
|
|
1143
|
-
const state = ctx.state;
|
|
1144
|
-
let position = 0;
|
|
1145
|
-
if (index !== void 0) {
|
|
1146
|
-
position = state.positions.get(getId(state, index)) || 0;
|
|
1147
|
-
const paddingTop = peek$(ctx, "stylePaddingTop");
|
|
1148
|
-
if (paddingTop) {
|
|
1149
|
-
position += paddingTop;
|
|
1150
|
-
}
|
|
1151
|
-
const headerSize = peek$(ctx, "headerSize");
|
|
1152
|
-
if (headerSize) {
|
|
1153
|
-
position += headerSize;
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
return position;
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
// src/utils/setPaddingTop.ts
|
|
1160
|
-
function setPaddingTop(ctx, { stylePaddingTop, alignItemsPaddingTop }) {
|
|
1161
|
-
const state = ctx.state;
|
|
1162
|
-
if (stylePaddingTop !== void 0) {
|
|
1163
|
-
const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
|
|
1164
|
-
if (stylePaddingTop < prevStylePaddingTop) {
|
|
1165
|
-
let prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
1166
|
-
set$(ctx, "totalSize", prevTotalSize + prevStylePaddingTop);
|
|
1167
|
-
state.timeoutSetPaddingTop = setTimeout(() => {
|
|
1168
|
-
prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
1169
|
-
set$(ctx, "totalSize", prevTotalSize - prevStylePaddingTop);
|
|
1170
|
-
}, 16);
|
|
1171
|
-
}
|
|
1172
|
-
set$(ctx, "stylePaddingTop", stylePaddingTop);
|
|
1173
|
-
}
|
|
1174
|
-
if (alignItemsPaddingTop !== void 0) {
|
|
1175
|
-
set$(ctx, "alignItemsPaddingTop", alignItemsPaddingTop);
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
|
|
1179
|
-
// src/utils/updateAlignItemsPaddingTop.ts
|
|
1180
|
-
function updateAlignItemsPaddingTop(ctx) {
|
|
1181
|
-
const state = ctx.state;
|
|
1182
|
-
const {
|
|
1183
|
-
scrollLength,
|
|
1184
|
-
props: { alignItemsAtEnd, data }
|
|
1185
|
-
} = state;
|
|
1186
|
-
if (alignItemsAtEnd) {
|
|
1187
|
-
let alignItemsPaddingTop = 0;
|
|
1188
|
-
if ((data == null ? void 0 : data.length) > 0) {
|
|
1189
|
-
const contentSize = getContentSize(ctx);
|
|
1190
|
-
alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
|
|
1191
|
-
}
|
|
1192
|
-
setPaddingTop(ctx, { alignItemsPaddingTop });
|
|
1193
|
-
}
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
// src/core/addTotalSize.ts
|
|
1197
|
-
function addTotalSize(ctx, key, add) {
|
|
1198
|
-
const state = ctx.state;
|
|
1199
|
-
const { alignItemsAtEnd } = state.props;
|
|
1200
|
-
const prevTotalSize = state.totalSize;
|
|
1201
|
-
let totalSize = state.totalSize;
|
|
1202
|
-
if (key === null) {
|
|
1203
|
-
totalSize = add;
|
|
1204
|
-
if (state.timeoutSetPaddingTop) {
|
|
1205
|
-
clearTimeout(state.timeoutSetPaddingTop);
|
|
1206
|
-
state.timeoutSetPaddingTop = void 0;
|
|
1207
|
-
}
|
|
1208
|
-
} else {
|
|
1209
|
-
totalSize += add;
|
|
1210
|
-
}
|
|
1211
|
-
if (prevTotalSize !== totalSize) {
|
|
1212
|
-
{
|
|
1213
|
-
state.pendingTotalSize = void 0;
|
|
1214
|
-
state.totalSize = totalSize;
|
|
1215
|
-
set$(ctx, "totalSize", totalSize);
|
|
1216
|
-
if (alignItemsAtEnd) {
|
|
1217
|
-
updateAlignItemsPaddingTop(ctx);
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
}
|
|
1222
|
-
|
|
1223
|
-
// src/core/setSize.ts
|
|
1224
|
-
function setSize(ctx, itemKey, size) {
|
|
1225
|
-
const state = ctx.state;
|
|
1226
|
-
const { sizes } = state;
|
|
1227
|
-
const previousSize = sizes.get(itemKey);
|
|
1228
|
-
const diff = previousSize !== void 0 ? size - previousSize : size;
|
|
1229
|
-
if (diff !== 0) {
|
|
1230
|
-
addTotalSize(ctx, itemKey, diff);
|
|
1231
|
-
}
|
|
1232
|
-
sizes.set(itemKey, size);
|
|
1233
|
-
}
|
|
1234
|
-
|
|
1235
|
-
// src/utils/getItemSize.ts
|
|
1236
|
-
function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize) {
|
|
1237
|
-
var _a3, _b;
|
|
1238
|
-
const state = ctx.state;
|
|
1239
|
-
const {
|
|
1240
|
-
sizesKnown,
|
|
1241
|
-
sizes,
|
|
1242
|
-
averageSizes,
|
|
1243
|
-
props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType },
|
|
1244
|
-
scrollingTo
|
|
1245
|
-
} = state;
|
|
1246
|
-
const sizeKnown = sizesKnown.get(key);
|
|
1247
|
-
if (sizeKnown !== void 0) {
|
|
1248
|
-
return sizeKnown;
|
|
1249
|
-
}
|
|
1250
|
-
let size;
|
|
1251
|
-
const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
|
|
1252
|
-
if (preferCachedSize) {
|
|
1253
|
-
const cachedSize = sizes.get(key);
|
|
1254
|
-
if (cachedSize !== void 0) {
|
|
1255
|
-
return cachedSize;
|
|
1256
|
-
}
|
|
1257
|
-
}
|
|
1258
|
-
if (getFixedItemSize) {
|
|
1259
|
-
size = getFixedItemSize(index, data, itemType);
|
|
1260
|
-
if (size !== void 0) {
|
|
1261
|
-
sizesKnown.set(key, size);
|
|
1262
|
-
}
|
|
1263
|
-
}
|
|
1264
|
-
if (size === void 0 && useAverageSize && sizeKnown === void 0 && !scrollingTo) {
|
|
1265
|
-
const averageSizeForType = (_b = averageSizes[itemType]) == null ? void 0 : _b.avg;
|
|
1266
|
-
if (averageSizeForType !== void 0) {
|
|
1267
|
-
size = roundSize(averageSizeForType);
|
|
1268
|
-
}
|
|
1269
|
-
}
|
|
1270
|
-
if (size === void 0) {
|
|
1271
|
-
size = sizes.get(key);
|
|
1272
|
-
if (size !== void 0) {
|
|
1273
|
-
return size;
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
if (size === void 0) {
|
|
1277
|
-
size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
|
|
1278
|
-
}
|
|
1279
|
-
setSize(ctx, key, size);
|
|
1280
|
-
return size;
|
|
1281
|
-
}
|
|
1282
|
-
|
|
1283
|
-
// src/core/calculateOffsetWithOffsetPosition.ts
|
|
1284
|
-
function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
|
|
1285
|
-
const state = ctx.state;
|
|
1286
|
-
const { index, viewOffset, viewPosition } = params;
|
|
1287
|
-
let offset = offsetParam;
|
|
1288
|
-
if (viewOffset) {
|
|
1289
|
-
offset -= viewOffset;
|
|
1290
|
-
}
|
|
1291
|
-
if (viewPosition !== void 0 && index !== void 0) {
|
|
1292
|
-
const itemSize = getItemSize(ctx, getId(state, index), index, state.props.data[index]);
|
|
1293
|
-
const trailingInset = getContentInsetEnd(state);
|
|
1294
|
-
offset -= viewPosition * (state.scrollLength - trailingInset - itemSize);
|
|
1295
|
-
}
|
|
1296
|
-
return offset;
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1299
|
-
// src/core/clampScrollOffset.ts
|
|
1300
|
-
function clampScrollOffset(ctx, offset) {
|
|
1301
|
-
const state = ctx.state;
|
|
1302
|
-
const contentSize = getContentSize(ctx);
|
|
1303
|
-
let clampedOffset = offset;
|
|
1304
|
-
if (Number.isFinite(contentSize) && Number.isFinite(state.scrollLength)) {
|
|
1305
|
-
const maxOffset = Math.max(0, contentSize - state.scrollLength);
|
|
1306
|
-
clampedOffset = Math.min(offset, maxOffset);
|
|
1307
|
-
}
|
|
1308
|
-
clampedOffset = Math.max(0, clampedOffset);
|
|
1309
|
-
return clampedOffset;
|
|
1310
|
-
}
|
|
1311
|
-
|
|
1312
|
-
// src/utils/setInitialRenderState.ts
|
|
1313
|
-
function setInitialRenderState(ctx, {
|
|
1314
|
-
didLayout,
|
|
1315
|
-
didInitialScroll
|
|
1316
|
-
}) {
|
|
1317
|
-
const { state } = ctx;
|
|
1318
|
-
if (didLayout) {
|
|
1319
|
-
state.didContainersLayout = true;
|
|
1320
|
-
}
|
|
1321
|
-
if (didInitialScroll) {
|
|
1322
|
-
state.didFinishInitialScroll = true;
|
|
1323
|
-
}
|
|
1324
|
-
if (state.didContainersLayout && state.didFinishInitialScroll) {
|
|
1325
|
-
set$(ctx, "readyToRender", true);
|
|
1326
|
-
}
|
|
1327
|
-
}
|
|
1328
|
-
|
|
1329
|
-
// src/core/finishScrollTo.ts
|
|
1330
|
-
function finishScrollTo(ctx) {
|
|
1331
|
-
var _a3, _b;
|
|
1332
|
-
const state = ctx.state;
|
|
1333
|
-
if (state == null ? void 0 : state.scrollingTo) {
|
|
1334
|
-
state.scrollHistory.length = 0;
|
|
1335
|
-
state.initialScroll = void 0;
|
|
1336
|
-
state.initialAnchor = void 0;
|
|
1337
|
-
state.scrollingTo = void 0;
|
|
1338
|
-
if (state.pendingTotalSize !== void 0) {
|
|
1339
|
-
addTotalSize(ctx, null, state.pendingTotalSize);
|
|
1340
|
-
}
|
|
1341
|
-
if ((_a3 = state.props) == null ? void 0 : _a3.data) {
|
|
1342
|
-
(_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
|
|
1343
|
-
}
|
|
1344
|
-
{
|
|
1345
|
-
state.scrollAdjustHandler.commitPendingAdjust();
|
|
1346
|
-
}
|
|
1347
|
-
setInitialRenderState(ctx, { didInitialScroll: true });
|
|
1348
|
-
}
|
|
1349
|
-
}
|
|
1350
|
-
|
|
1351
|
-
// src/core/doScrollTo.ts
|
|
1352
|
-
var SCROLL_END_IDLE_MS = 80;
|
|
1353
|
-
var SCROLL_END_MAX_MS = 1500;
|
|
1354
|
-
var SMOOTH_SCROLL_DURATION_MS = 320;
|
|
1355
|
-
function doScrollTo(ctx, params) {
|
|
1356
|
-
const state = ctx.state;
|
|
1357
|
-
const { animated, horizontal, offset } = params;
|
|
1358
|
-
const scroller = state.refScroller.current;
|
|
1359
|
-
const node = typeof (scroller == null ? void 0 : scroller.getScrollableNode) === "function" ? scroller.getScrollableNode() : scroller;
|
|
1360
|
-
if (node) {
|
|
1361
|
-
const left = horizontal ? offset : 0;
|
|
1362
|
-
const top = horizontal ? 0 : offset;
|
|
1363
|
-
node.scrollTo({ behavior: animated ? "smooth" : "auto", left, top });
|
|
1364
|
-
if (animated) {
|
|
1365
|
-
listenForScrollEnd(ctx, node);
|
|
1366
|
-
} else {
|
|
1367
|
-
state.scroll = offset;
|
|
1368
|
-
setTimeout(() => {
|
|
1369
|
-
finishScrollTo(ctx);
|
|
1370
|
-
}, 100);
|
|
1371
|
-
}
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
function listenForScrollEnd(ctx, node) {
|
|
1375
|
-
const supportsScrollEnd = "onscrollend" in node;
|
|
1376
|
-
let idleTimeout;
|
|
1377
|
-
let maxTimeout;
|
|
1378
|
-
let settled = false;
|
|
1379
|
-
const targetToken = ctx.state.scrollingTo;
|
|
1380
|
-
const finish = () => {
|
|
1381
|
-
if (settled) return;
|
|
1382
|
-
settled = true;
|
|
1383
|
-
cleanup();
|
|
1384
|
-
if (targetToken === ctx.state.scrollingTo) {
|
|
1385
|
-
finishScrollTo(ctx);
|
|
1386
|
-
}
|
|
1387
|
-
};
|
|
1388
|
-
const onScroll2 = () => {
|
|
1389
|
-
if (idleTimeout) {
|
|
1390
|
-
clearTimeout(idleTimeout);
|
|
1391
|
-
}
|
|
1392
|
-
idleTimeout = setTimeout(finish, SCROLL_END_IDLE_MS);
|
|
1393
|
-
};
|
|
1394
|
-
const cleanup = () => {
|
|
1395
|
-
if (supportsScrollEnd) {
|
|
1396
|
-
node.removeEventListener("scrollend", finish);
|
|
1397
|
-
} else {
|
|
1398
|
-
node.removeEventListener("scroll", onScroll2);
|
|
1399
|
-
}
|
|
1400
|
-
if (idleTimeout) {
|
|
1401
|
-
clearTimeout(idleTimeout);
|
|
1402
|
-
}
|
|
1403
|
-
if (maxTimeout) {
|
|
1404
|
-
clearTimeout(maxTimeout);
|
|
1405
|
-
}
|
|
1406
|
-
};
|
|
1407
|
-
if (supportsScrollEnd) {
|
|
1408
|
-
node.addEventListener("scrollend", finish, { once: true });
|
|
1409
|
-
} else {
|
|
1410
|
-
node.addEventListener("scroll", onScroll2);
|
|
1411
|
-
idleTimeout = setTimeout(finish, SMOOTH_SCROLL_DURATION_MS);
|
|
1412
|
-
maxTimeout = setTimeout(finish, SCROLL_END_MAX_MS);
|
|
1413
|
-
}
|
|
1414
|
-
return cleanup;
|
|
1415
|
-
}
|
|
1416
|
-
|
|
1417
|
-
// src/core/scrollTo.ts
|
|
1418
|
-
function scrollTo(ctx, params) {
|
|
1419
|
-
const state = ctx.state;
|
|
1420
|
-
const { noScrollingTo, forceScroll, ...scrollTarget } = params;
|
|
1421
|
-
const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
|
|
1422
|
-
const {
|
|
1423
|
-
props: { horizontal }
|
|
1424
|
-
} = state;
|
|
1425
|
-
if (state.animFrameCheckFinishedScroll) {
|
|
1426
|
-
cancelAnimationFrame(ctx.state.animFrameCheckFinishedScroll);
|
|
1427
|
-
}
|
|
1428
|
-
if (state.timeoutCheckFinishedScrollFallback) {
|
|
1429
|
-
clearTimeout(ctx.state.timeoutCheckFinishedScrollFallback);
|
|
1430
|
-
}
|
|
1431
|
-
let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, scrollTargetOffset, scrollTarget);
|
|
1432
|
-
offset = clampScrollOffset(ctx, offset);
|
|
1433
|
-
state.scrollHistory.length = 0;
|
|
1434
|
-
if (!noScrollingTo) {
|
|
1435
|
-
state.scrollingTo = scrollTarget;
|
|
1436
|
-
}
|
|
1437
|
-
state.scrollPending = offset;
|
|
1438
|
-
if (forceScroll || !isInitialScroll || Platform.OS === "android") {
|
|
1439
|
-
doScrollTo(ctx, { animated, horizontal, isInitialScroll, offset });
|
|
1440
|
-
} else {
|
|
1441
|
-
state.scroll = offset;
|
|
1442
|
-
}
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1445
|
-
// src/utils/checkThreshold.ts
|
|
1446
|
-
var HYSTERESIS_MULTIPLIER = 1.3;
|
|
1447
|
-
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
|
|
1448
|
-
const absDistance = Math.abs(distance);
|
|
1449
|
-
const within = atThreshold || threshold > 0 && absDistance <= threshold;
|
|
1450
|
-
if (wasReached === null) {
|
|
1451
|
-
if (!within && distance >= 0) {
|
|
1452
|
-
return false;
|
|
1453
|
-
}
|
|
1454
|
-
return null;
|
|
1455
|
-
}
|
|
1456
|
-
const updateSnapshot = () => {
|
|
1457
|
-
setSnapshot == null ? void 0 : setSnapshot({
|
|
1458
|
-
atThreshold,
|
|
1459
|
-
contentSize: context.contentSize,
|
|
1460
|
-
dataLength: context.dataLength,
|
|
1461
|
-
scrollPosition: context.scrollPosition
|
|
1462
|
-
});
|
|
1463
|
-
};
|
|
1464
|
-
if (!wasReached) {
|
|
1465
|
-
if (!within) {
|
|
1466
|
-
return false;
|
|
1467
|
-
}
|
|
1468
|
-
onReached == null ? void 0 : onReached(distance);
|
|
1469
|
-
updateSnapshot();
|
|
1470
|
-
return true;
|
|
1471
|
-
}
|
|
1472
|
-
const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
|
|
1473
|
-
if (reset) {
|
|
1474
|
-
setSnapshot == null ? void 0 : setSnapshot(void 0);
|
|
1475
|
-
return false;
|
|
1476
|
-
}
|
|
1477
|
-
if (within) {
|
|
1478
|
-
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
1479
|
-
if (changed) {
|
|
1480
|
-
onReached == null ? void 0 : onReached(distance);
|
|
1481
|
-
updateSnapshot();
|
|
1482
|
-
}
|
|
1483
|
-
}
|
|
1484
|
-
return true;
|
|
1485
|
-
};
|
|
1486
|
-
|
|
1487
|
-
// src/utils/checkAtBottom.ts
|
|
1488
|
-
function checkAtBottom(ctx) {
|
|
1489
|
-
var _a3;
|
|
1490
|
-
const state = ctx.state;
|
|
1491
|
-
if (!state) {
|
|
1492
|
-
return;
|
|
1493
|
-
}
|
|
1494
|
-
const {
|
|
1495
|
-
queuedInitialLayout,
|
|
1496
|
-
scrollLength,
|
|
1497
|
-
scroll,
|
|
1498
|
-
maintainingScrollAtEnd,
|
|
1499
|
-
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
1500
|
-
} = state;
|
|
1501
|
-
const contentSize = getContentSize(ctx);
|
|
1502
|
-
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1503
|
-
const distanceFromEnd = contentSize - scroll - scrollLength;
|
|
1504
|
-
const isContentLess = contentSize < scrollLength;
|
|
1505
|
-
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
1506
|
-
state.isEndReached = checkThreshold(
|
|
1507
|
-
distanceFromEnd,
|
|
1508
|
-
isContentLess,
|
|
1509
|
-
onEndReachedThreshold * scrollLength,
|
|
1510
|
-
state.isEndReached,
|
|
1511
|
-
state.endReachedSnapshot,
|
|
1512
|
-
{
|
|
1513
|
-
contentSize,
|
|
1514
|
-
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1515
|
-
scrollPosition: scroll
|
|
1516
|
-
},
|
|
1517
|
-
(distance) => {
|
|
1518
|
-
var _a4, _b;
|
|
1519
|
-
return (_b = (_a4 = state.props).onEndReached) == null ? void 0 : _b.call(_a4, { distanceFromEnd: distance });
|
|
1520
|
-
},
|
|
1521
|
-
(snapshot) => {
|
|
1522
|
-
state.endReachedSnapshot = snapshot;
|
|
1523
|
-
}
|
|
1524
|
-
);
|
|
1525
|
-
}
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
// src/utils/checkAtTop.ts
|
|
1529
|
-
function checkAtTop(state) {
|
|
1530
|
-
var _a3;
|
|
1531
|
-
if (!state) {
|
|
1532
|
-
return;
|
|
1533
|
-
}
|
|
1534
|
-
const {
|
|
1535
|
-
scrollLength,
|
|
1536
|
-
scroll,
|
|
1537
|
-
props: { onStartReachedThreshold }
|
|
1538
|
-
} = state;
|
|
1539
|
-
const distanceFromTop = scroll;
|
|
1540
|
-
state.isAtStart = distanceFromTop <= 0;
|
|
1541
|
-
state.isStartReached = checkThreshold(
|
|
1542
|
-
distanceFromTop,
|
|
1543
|
-
false,
|
|
1544
|
-
onStartReachedThreshold * scrollLength,
|
|
1545
|
-
state.isStartReached,
|
|
1546
|
-
state.startReachedSnapshot,
|
|
1547
|
-
{
|
|
1548
|
-
contentSize: state.totalSize,
|
|
1549
|
-
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1550
|
-
scrollPosition: scroll
|
|
1551
|
-
},
|
|
1552
|
-
(distance) => {
|
|
1553
|
-
var _a4, _b;
|
|
1554
|
-
return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
|
|
1555
|
-
},
|
|
1556
|
-
(snapshot) => {
|
|
1557
|
-
state.startReachedSnapshot = snapshot;
|
|
1558
|
-
}
|
|
1559
|
-
);
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
// src/core/updateScroll.ts
|
|
1563
|
-
function updateScroll(ctx, newScroll, forceUpdate) {
|
|
1564
|
-
var _a3;
|
|
1565
|
-
const state = ctx.state;
|
|
1566
|
-
const { scrollingTo, scrollAdjustHandler, lastScrollAdjustForHistory } = state;
|
|
1567
|
-
state.hasScrolled = true;
|
|
1568
|
-
state.lastBatchingAction = Date.now();
|
|
1569
|
-
const currentTime = Date.now();
|
|
1570
|
-
const adjust = scrollAdjustHandler.getAdjust();
|
|
1571
|
-
const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
|
|
1572
|
-
if (adjustChanged) {
|
|
1573
|
-
state.scrollHistory.length = 0;
|
|
1574
|
-
}
|
|
1575
|
-
state.lastScrollAdjustForHistory = adjust;
|
|
1576
|
-
if (scrollingTo === void 0 && !(state.scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
1577
|
-
if (!adjustChanged) {
|
|
1578
|
-
state.scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
1579
|
-
}
|
|
1580
|
-
}
|
|
1581
|
-
if (state.scrollHistory.length > 5) {
|
|
1582
|
-
state.scrollHistory.shift();
|
|
1583
|
-
}
|
|
1584
|
-
state.scrollPrev = state.scroll;
|
|
1585
|
-
state.scrollPrevTime = state.scrollTime;
|
|
1586
|
-
state.scroll = newScroll;
|
|
1587
|
-
state.scrollTime = currentTime;
|
|
1588
|
-
const ignoreScrollFromMVCP = state.ignoreScrollFromMVCP;
|
|
1589
|
-
if (ignoreScrollFromMVCP && !scrollingTo) {
|
|
1590
|
-
const { lt, gt } = ignoreScrollFromMVCP;
|
|
1591
|
-
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
1592
|
-
state.ignoreScrollFromMVCPIgnored = true;
|
|
1593
|
-
return;
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
const lastCalculated = state.scrollLastCalculate;
|
|
1597
|
-
const shouldUpdate = state.dataChangeNeedsScrollUpdate || state.scrollLastCalculate === void 0 || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
1598
|
-
if (shouldUpdate) {
|
|
1599
|
-
state.scrollLastCalculate = state.scroll;
|
|
1600
|
-
state.ignoreScrollFromMVCPIgnored = false;
|
|
1601
|
-
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
|
|
1602
|
-
checkAtBottom(ctx);
|
|
1603
|
-
checkAtTop(state);
|
|
1604
|
-
state.dataChangeNeedsScrollUpdate = false;
|
|
1605
|
-
}
|
|
1606
|
-
}
|
|
1607
|
-
|
|
1608
|
-
// src/utils/requestAdjust.ts
|
|
1609
|
-
function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
1610
|
-
const state = ctx.state;
|
|
1611
|
-
if (Math.abs(positionDiff) > 0.1) {
|
|
1612
|
-
const doit = () => {
|
|
1613
|
-
{
|
|
1614
|
-
state.scrollAdjustHandler.requestAdjust(positionDiff);
|
|
1615
|
-
if (state.adjustingFromInitialMount) {
|
|
1616
|
-
state.adjustingFromInitialMount--;
|
|
1617
|
-
}
|
|
1618
|
-
}
|
|
1619
|
-
};
|
|
1620
|
-
state.scroll += positionDiff;
|
|
1621
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
1622
|
-
const readyToRender = peek$(ctx, "readyToRender");
|
|
1623
|
-
if (readyToRender) {
|
|
1624
|
-
doit();
|
|
1625
|
-
} else {
|
|
1626
|
-
state.adjustingFromInitialMount = (state.adjustingFromInitialMount || 0) + 1;
|
|
1627
|
-
requestAnimationFrame(doit);
|
|
1628
|
-
}
|
|
1629
|
-
}
|
|
1630
|
-
}
|
|
1631
|
-
|
|
1632
|
-
// src/core/mvcp.ts
|
|
1633
|
-
function prepareMVCP(ctx, dataChanged) {
|
|
1634
|
-
const state = ctx.state;
|
|
1635
|
-
const { idsInView, positions, props } = state;
|
|
1636
|
-
const { maintainVisibleContentPosition } = props;
|
|
1637
|
-
const scrollingTo = state.scrollingTo;
|
|
1638
|
-
let prevPosition;
|
|
1639
|
-
let targetId;
|
|
1640
|
-
const idsInViewWithPositions = [];
|
|
1641
|
-
const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
|
|
1642
|
-
const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
|
|
1643
|
-
const shouldMVCP = !dataChanged || maintainVisibleContentPosition;
|
|
1644
|
-
const indexByKey = state.indexByKey;
|
|
1645
|
-
if (shouldMVCP) {
|
|
1646
|
-
if (scrollTarget !== void 0) {
|
|
1647
|
-
targetId = getId(state, scrollTarget);
|
|
1648
|
-
} else if (idsInView.length > 0 && state.didContainersLayout) {
|
|
1649
|
-
if (dataChanged) {
|
|
1650
|
-
for (let i = 0; i < idsInView.length; i++) {
|
|
1651
|
-
const id = idsInView[i];
|
|
1652
|
-
const index = indexByKey.get(id);
|
|
1653
|
-
if (index !== void 0) {
|
|
1654
|
-
idsInViewWithPositions.push({ id, position: positions.get(id) });
|
|
1655
|
-
}
|
|
1656
|
-
}
|
|
1657
|
-
} else {
|
|
1658
|
-
targetId = idsInView.find((id) => indexByKey.get(id) !== void 0);
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1661
|
-
if (targetId !== void 0) {
|
|
1662
|
-
prevPosition = positions.get(targetId);
|
|
1663
|
-
}
|
|
1664
|
-
return () => {
|
|
1665
|
-
let positionDiff = 0;
|
|
1666
|
-
if (dataChanged && targetId === void 0 && maintainVisibleContentPosition) {
|
|
1667
|
-
for (let i = 0; i < idsInViewWithPositions.length; i++) {
|
|
1668
|
-
const { id, position } = idsInViewWithPositions[i];
|
|
1669
|
-
const newPosition = positions.get(id);
|
|
1670
|
-
if (newPosition !== void 0) {
|
|
1671
|
-
positionDiff = newPosition - position;
|
|
1672
|
-
break;
|
|
1673
|
-
}
|
|
1674
|
-
}
|
|
1675
|
-
}
|
|
1676
|
-
if (targetId !== void 0 && prevPosition !== void 0) {
|
|
1677
|
-
const newPosition = positions.get(targetId);
|
|
1678
|
-
if (newPosition !== void 0) {
|
|
1679
|
-
const totalSize = getContentSize(ctx);
|
|
1680
|
-
let diff = newPosition - prevPosition;
|
|
1681
|
-
if (diff !== 0 && state.scroll + state.scrollLength > totalSize) {
|
|
1682
|
-
if (diff > 0) {
|
|
1683
|
-
diff = Math.max(0, totalSize - state.scroll - state.scrollLength);
|
|
1684
|
-
} else {
|
|
1685
|
-
diff = 0;
|
|
1686
|
-
}
|
|
1687
|
-
}
|
|
1688
|
-
positionDiff = diff;
|
|
1689
|
-
}
|
|
1690
|
-
}
|
|
1691
|
-
if (scrollingToViewPosition && scrollingToViewPosition > 0) {
|
|
1692
|
-
const newSize = getItemSize(ctx, targetId, scrollTarget, state.props.data[scrollTarget]);
|
|
1693
|
-
const prevSize = scrollingTo == null ? void 0 : scrollingTo.itemSize;
|
|
1694
|
-
if (newSize !== void 0 && prevSize !== void 0 && newSize !== (scrollingTo == null ? void 0 : scrollingTo.itemSize)) {
|
|
1695
|
-
const diff = newSize - prevSize;
|
|
1696
|
-
if (diff !== 0) {
|
|
1697
|
-
positionDiff += (newSize - prevSize) * scrollingToViewPosition;
|
|
1698
|
-
scrollingTo.itemSize = newSize;
|
|
1699
|
-
}
|
|
1700
|
-
}
|
|
1701
|
-
}
|
|
1702
|
-
if (Math.abs(positionDiff) > 0.1) {
|
|
1703
|
-
requestAdjust(ctx, positionDiff);
|
|
1704
|
-
}
|
|
1705
|
-
};
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
|
|
1709
|
-
// src/core/prepareColumnStartState.ts
|
|
1710
|
-
function prepareColumnStartState(ctx, startIndex, useAverageSize) {
|
|
1711
|
-
var _a3;
|
|
1712
|
-
const state = ctx.state;
|
|
1713
|
-
const numColumns = peek$(ctx, "numColumns");
|
|
1714
|
-
let rowStartIndex = startIndex;
|
|
1715
|
-
const columnAtStart = state.columns.get(state.idCache[startIndex]);
|
|
1716
|
-
if (columnAtStart !== 1) {
|
|
1717
|
-
rowStartIndex = findRowStartIndex(state, numColumns, startIndex);
|
|
1718
|
-
}
|
|
1719
|
-
let currentRowTop = 0;
|
|
1720
|
-
const curId = state.idCache[rowStartIndex];
|
|
1721
|
-
const column = state.columns.get(curId);
|
|
1722
|
-
if (rowStartIndex > 0) {
|
|
1723
|
-
const prevIndex = rowStartIndex - 1;
|
|
1724
|
-
const prevId = state.idCache[prevIndex];
|
|
1725
|
-
const prevPosition = (_a3 = state.positions.get(prevId)) != null ? _a3 : 0;
|
|
1726
|
-
const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
|
|
1727
|
-
const prevRowHeight = calculateRowMaxSize(ctx, prevRowStart, prevIndex, useAverageSize);
|
|
1728
|
-
currentRowTop = prevPosition + prevRowHeight;
|
|
1729
|
-
}
|
|
1730
|
-
return {
|
|
1731
|
-
column,
|
|
1732
|
-
currentRowTop,
|
|
1733
|
-
startIndex: rowStartIndex
|
|
1734
|
-
};
|
|
1735
|
-
}
|
|
1736
|
-
function findRowStartIndex(state, numColumns, index) {
|
|
1737
|
-
if (numColumns <= 1) {
|
|
1738
|
-
return Math.max(0, index);
|
|
1739
|
-
}
|
|
1740
|
-
let rowStart = Math.max(0, index);
|
|
1741
|
-
while (rowStart > 0) {
|
|
1742
|
-
const columnForIndex = state.columns.get(state.idCache[rowStart]);
|
|
1743
|
-
if (columnForIndex === 1) {
|
|
1744
|
-
break;
|
|
1745
|
-
}
|
|
1746
|
-
rowStart--;
|
|
1747
|
-
}
|
|
1748
|
-
return rowStart;
|
|
1749
|
-
}
|
|
1750
|
-
function calculateRowMaxSize(ctx, startIndex, endIndex, useAverageSize) {
|
|
1751
|
-
const state = ctx.state;
|
|
1752
|
-
if (endIndex < startIndex) {
|
|
1753
|
-
return 0;
|
|
1754
|
-
}
|
|
1755
|
-
const { data } = state.props;
|
|
1756
|
-
if (!data) {
|
|
1757
|
-
return 0;
|
|
1758
|
-
}
|
|
1759
|
-
let maxSize = 0;
|
|
1760
|
-
for (let i = startIndex; i <= endIndex; i++) {
|
|
1761
|
-
if (i < 0 || i >= data.length) {
|
|
1762
|
-
continue;
|
|
1763
|
-
}
|
|
1764
|
-
const id = state.idCache[i];
|
|
1765
|
-
const size = getItemSize(ctx, id, i, data[i], useAverageSize);
|
|
1766
|
-
if (size > maxSize) {
|
|
1767
|
-
maxSize = size;
|
|
1768
|
-
}
|
|
1769
|
-
}
|
|
1770
|
-
return maxSize;
|
|
1771
|
-
}
|
|
1772
|
-
|
|
1773
|
-
// src/core/updateTotalSize.ts
|
|
1774
|
-
function updateTotalSize(ctx) {
|
|
1775
|
-
const state = ctx.state;
|
|
1776
|
-
const {
|
|
1777
|
-
positions,
|
|
1778
|
-
props: { data }
|
|
1779
|
-
} = state;
|
|
1780
|
-
if (data.length === 0) {
|
|
1781
|
-
addTotalSize(ctx, null, 0);
|
|
1782
|
-
} else {
|
|
1783
|
-
const lastId = getId(state, data.length - 1);
|
|
1784
|
-
if (lastId !== void 0) {
|
|
1785
|
-
const lastPosition = positions.get(lastId);
|
|
1786
|
-
if (lastPosition !== void 0) {
|
|
1787
|
-
const lastSize = getItemSize(ctx, lastId, data.length - 1, data[data.length - 1]);
|
|
1788
|
-
if (lastSize !== void 0) {
|
|
1789
|
-
const totalSize = lastPosition + lastSize;
|
|
1790
|
-
addTotalSize(ctx, null, totalSize);
|
|
1791
|
-
}
|
|
1792
|
-
}
|
|
1793
|
-
}
|
|
1794
|
-
}
|
|
1795
|
-
}
|
|
1796
|
-
|
|
1797
|
-
// src/utils/getScrollVelocity.ts
|
|
1798
|
-
var getScrollVelocity = (state) => {
|
|
1799
|
-
const { scrollHistory } = state;
|
|
1800
|
-
let velocity = 0;
|
|
1801
|
-
if (scrollHistory.length >= 1) {
|
|
1802
|
-
const newest = scrollHistory[scrollHistory.length - 1];
|
|
1803
|
-
let oldest;
|
|
1804
|
-
let start = 0;
|
|
1805
|
-
const now = Date.now();
|
|
1806
|
-
for (let i = 0; i < scrollHistory.length - 1; i++) {
|
|
1807
|
-
const entry = scrollHistory[i];
|
|
1808
|
-
const nextEntry = scrollHistory[i + 1];
|
|
1809
|
-
if (i > 0) {
|
|
1810
|
-
const prevEntry = scrollHistory[i - 1];
|
|
1811
|
-
const prevDirection = entry.scroll - prevEntry.scroll;
|
|
1812
|
-
const currentDirection = nextEntry.scroll - entry.scroll;
|
|
1813
|
-
if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
|
|
1814
|
-
start = i;
|
|
1815
|
-
break;
|
|
1816
|
-
}
|
|
1817
|
-
}
|
|
1818
|
-
}
|
|
1819
|
-
for (let i = start; i < scrollHistory.length - 1; i++) {
|
|
1820
|
-
const entry = scrollHistory[i];
|
|
1821
|
-
if (now - entry.time <= 1e3) {
|
|
1822
|
-
oldest = entry;
|
|
1823
|
-
break;
|
|
1824
|
-
}
|
|
1825
|
-
}
|
|
1826
|
-
if (oldest && oldest !== newest) {
|
|
1827
|
-
const scrollDiff = newest.scroll - oldest.scroll;
|
|
1828
|
-
const timeDiff = newest.time - oldest.time;
|
|
1829
|
-
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
1830
|
-
}
|
|
1831
|
-
}
|
|
1832
|
-
return velocity;
|
|
1833
|
-
};
|
|
1834
|
-
|
|
1835
|
-
// src/utils/updateSnapToOffsets.ts
|
|
1836
|
-
function updateSnapToOffsets(ctx) {
|
|
1837
|
-
const state = ctx.state;
|
|
1838
|
-
const {
|
|
1839
|
-
positions,
|
|
1840
|
-
props: { snapToIndices }
|
|
1841
|
-
} = state;
|
|
1842
|
-
const snapToOffsets = Array(snapToIndices.length);
|
|
1843
|
-
for (let i = 0; i < snapToIndices.length; i++) {
|
|
1844
|
-
const idx = snapToIndices[i];
|
|
1845
|
-
const key = getId(state, idx);
|
|
1846
|
-
snapToOffsets[i] = positions.get(key);
|
|
1847
|
-
}
|
|
1848
|
-
set$(ctx, "snapToOffsets", snapToOffsets);
|
|
1849
|
-
}
|
|
1850
|
-
|
|
1851
|
-
// src/core/updateItemPositions.ts
|
|
1852
|
-
function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
|
|
1853
|
-
doMVCP: false,
|
|
1854
|
-
forceFullUpdate: false,
|
|
1855
|
-
scrollBottomBuffered: -1,
|
|
1856
|
-
startIndex: 0
|
|
1857
|
-
}) {
|
|
1858
|
-
var _a3, _b, _c, _d, _e;
|
|
1859
|
-
const state = ctx.state;
|
|
1860
|
-
const {
|
|
1861
|
-
columns,
|
|
1862
|
-
indexByKey,
|
|
1863
|
-
positions,
|
|
1864
|
-
idCache,
|
|
1865
|
-
sizesKnown,
|
|
1866
|
-
props: { data, getEstimatedItemSize, snapToIndices },
|
|
1867
|
-
scrollingTo
|
|
1868
|
-
} = state;
|
|
1869
|
-
const dataLength = data.length;
|
|
1870
|
-
const numColumns = peek$(ctx, "numColumns");
|
|
1871
|
-
const hasColumns = numColumns > 1;
|
|
1872
|
-
const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
|
|
1873
|
-
const shouldOptimize = !forceFullUpdate && !dataChanged && Math.abs(getScrollVelocity(state)) > 0;
|
|
1874
|
-
const maxVisibleArea = scrollBottomBuffered + 1e3;
|
|
1875
|
-
const useAverageSize = !getEstimatedItemSize;
|
|
1876
|
-
const preferCachedSize = !doMVCP || dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0) !== 0;
|
|
1877
|
-
let currentRowTop = 0;
|
|
1878
|
-
let column = 1;
|
|
1879
|
-
let maxSizeInRow = 0;
|
|
1880
|
-
if (startIndex > 0) {
|
|
1881
|
-
if (hasColumns) {
|
|
1882
|
-
const { startIndex: processedStartIndex, currentRowTop: initialRowTop } = prepareColumnStartState(
|
|
1883
|
-
ctx,
|
|
1884
|
-
startIndex,
|
|
1885
|
-
useAverageSize
|
|
1886
|
-
);
|
|
1887
|
-
startIndex = processedStartIndex;
|
|
1888
|
-
currentRowTop = initialRowTop;
|
|
1889
|
-
} else if (startIndex < dataLength) {
|
|
1890
|
-
const prevIndex = startIndex - 1;
|
|
1891
|
-
const prevId = getId(state, prevIndex);
|
|
1892
|
-
const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
|
|
1893
|
-
const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
|
|
1894
|
-
currentRowTop = prevPosition + prevSize;
|
|
1895
|
-
}
|
|
1896
|
-
}
|
|
1897
|
-
const needsIndexByKey = dataChanged || indexByKey.size === 0;
|
|
1898
|
-
let didBreakEarly = false;
|
|
1899
|
-
let breakAt;
|
|
1900
|
-
for (let i = startIndex; i < dataLength; i++) {
|
|
1901
|
-
if (shouldOptimize && breakAt !== void 0 && i > breakAt) {
|
|
1902
|
-
didBreakEarly = true;
|
|
1903
|
-
break;
|
|
1904
|
-
}
|
|
1905
|
-
if (shouldOptimize && breakAt === void 0 && !scrollingTo && !dataChanged && currentRowTop > maxVisibleArea) {
|
|
1906
|
-
const itemsPerRow = hasColumns ? numColumns : 1;
|
|
1907
|
-
breakAt = i + itemsPerRow + 10;
|
|
1908
|
-
}
|
|
1909
|
-
const id = (_d = idCache[i]) != null ? _d : getId(state, i);
|
|
1910
|
-
const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, id, i, data[i], useAverageSize, preferCachedSize);
|
|
1911
|
-
if (IS_DEV && needsIndexByKey) {
|
|
1912
|
-
if (indexByKeyForChecking.has(id)) {
|
|
1913
|
-
console.error(
|
|
1914
|
-
`[legend-list] Error: Detected overlapping key (${id}) which causes missing items and gaps and other terrrible things. Check that keyExtractor returns unique values.`
|
|
1915
|
-
);
|
|
1916
|
-
}
|
|
1917
|
-
indexByKeyForChecking.set(id, i);
|
|
1918
|
-
}
|
|
1919
|
-
if (currentRowTop !== positions.get(id)) {
|
|
1920
|
-
positions.set(id, currentRowTop);
|
|
1921
|
-
notifyPosition$(ctx, id, currentRowTop);
|
|
1922
|
-
}
|
|
1923
|
-
if (needsIndexByKey) {
|
|
1924
|
-
indexByKey.set(id, i);
|
|
1925
|
-
}
|
|
1926
|
-
columns.set(id, column);
|
|
1927
|
-
if (hasColumns) {
|
|
1928
|
-
if (size > maxSizeInRow) {
|
|
1929
|
-
maxSizeInRow = size;
|
|
1930
|
-
}
|
|
1931
|
-
column++;
|
|
1932
|
-
if (column > numColumns) {
|
|
1933
|
-
currentRowTop += maxSizeInRow;
|
|
1934
|
-
column = 1;
|
|
1935
|
-
maxSizeInRow = 0;
|
|
1936
|
-
}
|
|
1937
|
-
} else {
|
|
1938
|
-
currentRowTop += size;
|
|
1939
|
-
}
|
|
1940
|
-
}
|
|
1941
|
-
if (!didBreakEarly) {
|
|
1942
|
-
updateTotalSize(ctx);
|
|
1943
|
-
}
|
|
1944
|
-
if (snapToIndices) {
|
|
1945
|
-
updateSnapToOffsets(ctx);
|
|
1946
|
-
}
|
|
1947
|
-
}
|
|
1948
|
-
|
|
1949
|
-
// src/core/viewability.ts
|
|
1950
|
-
function ensureViewabilityState(ctx, configId) {
|
|
1951
|
-
let map = ctx.mapViewabilityConfigStates;
|
|
1952
|
-
if (!map) {
|
|
1953
|
-
map = /* @__PURE__ */ new Map();
|
|
1954
|
-
ctx.mapViewabilityConfigStates = map;
|
|
1955
|
-
}
|
|
1956
|
-
let state = map.get(configId);
|
|
1957
|
-
if (!state) {
|
|
1958
|
-
state = { end: -1, previousEnd: -1, previousStart: -1, start: -1, viewableItems: [] };
|
|
1959
|
-
map.set(configId, state);
|
|
1960
|
-
}
|
|
1961
|
-
return state;
|
|
1962
|
-
}
|
|
1963
|
-
function setupViewability(props) {
|
|
1964
|
-
let { viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged } = props;
|
|
1965
|
-
if (viewabilityConfig || onViewableItemsChanged) {
|
|
1966
|
-
viewabilityConfigCallbackPairs = [
|
|
1967
|
-
...viewabilityConfigCallbackPairs || [],
|
|
1968
|
-
{
|
|
1969
|
-
onViewableItemsChanged,
|
|
1970
|
-
viewabilityConfig: viewabilityConfig || {
|
|
1971
|
-
viewAreaCoveragePercentThreshold: 0
|
|
1972
|
-
}
|
|
1973
|
-
}
|
|
1974
|
-
];
|
|
1975
|
-
}
|
|
1976
|
-
return viewabilityConfigCallbackPairs;
|
|
1977
|
-
}
|
|
1978
|
-
function updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollSize, start, end) {
|
|
1979
|
-
const {
|
|
1980
|
-
timeouts,
|
|
1981
|
-
props: { data }
|
|
1982
|
-
} = state;
|
|
1983
|
-
for (const viewabilityConfigCallbackPair of viewabilityConfigCallbackPairs) {
|
|
1984
|
-
const viewabilityState = ensureViewabilityState(ctx, viewabilityConfigCallbackPair.viewabilityConfig.id);
|
|
1985
|
-
viewabilityState.start = start;
|
|
1986
|
-
viewabilityState.end = end;
|
|
1987
|
-
if (viewabilityConfigCallbackPair.viewabilityConfig.minimumViewTime) {
|
|
1988
|
-
const timer = setTimeout(() => {
|
|
1989
|
-
timeouts.delete(timer);
|
|
1990
|
-
updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, state, ctx, scrollSize);
|
|
1991
|
-
}, viewabilityConfigCallbackPair.viewabilityConfig.minimumViewTime);
|
|
1992
|
-
timeouts.add(timer);
|
|
1993
|
-
} else {
|
|
1994
|
-
updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, state, ctx, scrollSize);
|
|
1995
|
-
}
|
|
1996
|
-
}
|
|
1997
|
-
}
|
|
1998
|
-
function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, state, ctx, scrollSize) {
|
|
1999
|
-
const { viewabilityConfig, onViewableItemsChanged } = viewabilityConfigCallbackPair;
|
|
2000
|
-
const configId = viewabilityConfig.id;
|
|
2001
|
-
const viewabilityState = ensureViewabilityState(ctx, configId);
|
|
2002
|
-
const { viewableItems: previousViewableItems, start, end } = viewabilityState;
|
|
2003
|
-
const viewabilityTokens = /* @__PURE__ */ new Map();
|
|
2004
|
-
for (const [containerId, value] of ctx.mapViewabilityAmountValues) {
|
|
2005
|
-
viewabilityTokens.set(
|
|
2006
|
-
containerId,
|
|
2007
|
-
computeViewability(
|
|
2008
|
-
state,
|
|
2009
|
-
ctx,
|
|
2010
|
-
viewabilityConfig,
|
|
2011
|
-
containerId,
|
|
2012
|
-
value.key,
|
|
2013
|
-
scrollSize,
|
|
2014
|
-
value.item,
|
|
2015
|
-
value.index
|
|
2016
|
-
)
|
|
2017
|
-
);
|
|
2018
|
-
}
|
|
2019
|
-
const changed = [];
|
|
2020
|
-
if (previousViewableItems) {
|
|
2021
|
-
for (const viewToken of previousViewableItems) {
|
|
2022
|
-
const containerId = findContainerId(ctx, viewToken.key);
|
|
2023
|
-
if (!checkIsViewable(
|
|
2024
|
-
state,
|
|
2025
|
-
ctx,
|
|
2026
|
-
viewabilityConfig,
|
|
2027
|
-
containerId,
|
|
2028
|
-
viewToken.key,
|
|
2029
|
-
scrollSize,
|
|
2030
|
-
viewToken.item,
|
|
2031
|
-
viewToken.index
|
|
2032
|
-
)) {
|
|
2033
|
-
viewToken.isViewable = false;
|
|
2034
|
-
changed.push(viewToken);
|
|
2035
|
-
}
|
|
2036
|
-
}
|
|
2037
|
-
}
|
|
2038
|
-
const viewableItems = [];
|
|
2039
|
-
for (let i = start; i <= end; i++) {
|
|
2040
|
-
const item = data[i];
|
|
2041
|
-
if (item) {
|
|
2042
|
-
const key = getId(state, i);
|
|
2043
|
-
const containerId = findContainerId(ctx, key);
|
|
2044
|
-
if (checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
|
|
2045
|
-
const viewToken = {
|
|
2046
|
-
containerId,
|
|
2047
|
-
index: i,
|
|
2048
|
-
isViewable: true,
|
|
2049
|
-
item,
|
|
2050
|
-
key
|
|
2051
|
-
};
|
|
2052
|
-
viewableItems.push(viewToken);
|
|
2053
|
-
if (!(previousViewableItems == null ? void 0 : previousViewableItems.find((v) => v.key === viewToken.key))) {
|
|
2054
|
-
changed.push(viewToken);
|
|
2055
|
-
}
|
|
2056
|
-
}
|
|
2057
|
-
}
|
|
2058
|
-
}
|
|
2059
|
-
Object.assign(viewabilityState, {
|
|
2060
|
-
previousEnd: end,
|
|
2061
|
-
previousStart: start,
|
|
2062
|
-
viewableItems
|
|
2063
|
-
});
|
|
2064
|
-
if (changed.length > 0) {
|
|
2065
|
-
viewabilityState.viewableItems = viewableItems;
|
|
2066
|
-
for (let i = 0; i < changed.length; i++) {
|
|
2067
|
-
const change = changed[i];
|
|
2068
|
-
maybeUpdateViewabilityCallback(ctx, configId, change.containerId, change);
|
|
2069
|
-
}
|
|
2070
|
-
if (onViewableItemsChanged) {
|
|
2071
|
-
onViewableItemsChanged({ changed, viewableItems });
|
|
2072
|
-
}
|
|
2073
|
-
}
|
|
2074
|
-
for (const [containerId, value] of ctx.mapViewabilityAmountValues) {
|
|
2075
|
-
if (value.sizeVisible < 0) {
|
|
2076
|
-
ctx.mapViewabilityAmountValues.delete(containerId);
|
|
2077
|
-
}
|
|
2078
|
-
}
|
|
2079
|
-
}
|
|
2080
|
-
function shallowEqual(prev, next) {
|
|
2081
|
-
if (!prev) return false;
|
|
2082
|
-
const keys = Object.keys(next);
|
|
2083
|
-
for (let i = 0; i < keys.length; i++) {
|
|
2084
|
-
const k = keys[i];
|
|
2085
|
-
if (prev[k] !== next[k]) return false;
|
|
2086
|
-
}
|
|
2087
|
-
return true;
|
|
2088
|
-
}
|
|
2089
|
-
function computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
|
|
2090
|
-
const { sizes, positions, scroll: scrollState } = state;
|
|
2091
|
-
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
2092
|
-
const { itemVisiblePercentThreshold, viewAreaCoveragePercentThreshold } = viewabilityConfig;
|
|
2093
|
-
const viewAreaMode = viewAreaCoveragePercentThreshold != null;
|
|
2094
|
-
const viewablePercentThreshold = viewAreaMode ? viewAreaCoveragePercentThreshold : itemVisiblePercentThreshold;
|
|
2095
|
-
const scroll = scrollState - topPad;
|
|
2096
|
-
const top = positions.get(key) - scroll;
|
|
2097
|
-
const size = sizes.get(key) || 0;
|
|
2098
|
-
const bottom = top + size;
|
|
2099
|
-
const isEntirelyVisible = top >= 0 && bottom <= scrollSize && bottom > top;
|
|
2100
|
-
const sizeVisible = isEntirelyVisible ? size : Math.min(bottom, scrollSize) - Math.max(top, 0);
|
|
2101
|
-
const percentVisible = size ? isEntirelyVisible ? 100 : 100 * (sizeVisible / size) : 0;
|
|
2102
|
-
const percentOfScroller = size ? 100 * (sizeVisible / scrollSize) : 0;
|
|
2103
|
-
const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
|
|
2104
|
-
const isViewable = percent >= viewablePercentThreshold;
|
|
2105
|
-
const value = {
|
|
2106
|
-
containerId,
|
|
2107
|
-
index,
|
|
2108
|
-
isViewable,
|
|
2109
|
-
item,
|
|
2110
|
-
key,
|
|
2111
|
-
percentOfScroller,
|
|
2112
|
-
percentVisible,
|
|
2113
|
-
scrollSize,
|
|
2114
|
-
size,
|
|
2115
|
-
sizeVisible
|
|
2116
|
-
};
|
|
2117
|
-
const prev = ctx.mapViewabilityAmountValues.get(containerId);
|
|
2118
|
-
if (!shallowEqual(prev, value)) {
|
|
2119
|
-
ctx.mapViewabilityAmountValues.set(containerId, value);
|
|
2120
|
-
const cb = ctx.mapViewabilityAmountCallbacks.get(containerId);
|
|
2121
|
-
if (cb) {
|
|
2122
|
-
cb(value);
|
|
2123
|
-
}
|
|
2124
|
-
}
|
|
2125
|
-
return value;
|
|
2126
|
-
}
|
|
2127
|
-
function checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
|
|
2128
|
-
let value = ctx.mapViewabilityAmountValues.get(containerId);
|
|
2129
|
-
if (!value || value.key !== key) {
|
|
2130
|
-
value = computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
|
|
2131
|
-
}
|
|
2132
|
-
return value.isViewable;
|
|
2133
|
-
}
|
|
2134
|
-
function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
|
|
2135
|
-
const key = containerId + configId;
|
|
2136
|
-
ctx.mapViewabilityValues.set(key, viewToken);
|
|
2137
|
-
const cb = ctx.mapViewabilityCallbacks.get(key);
|
|
2138
|
-
cb == null ? void 0 : cb(viewToken);
|
|
2139
|
-
}
|
|
2140
|
-
|
|
2141
|
-
// src/utils/checkAllSizesKnown.ts
|
|
2142
|
-
function isNullOrUndefined2(value) {
|
|
2143
|
-
return value === null || value === void 0;
|
|
2144
|
-
}
|
|
2145
|
-
function checkAllSizesKnown(state) {
|
|
2146
|
-
const { startBuffered, endBuffered, sizesKnown } = state;
|
|
2147
|
-
if (!isNullOrUndefined2(endBuffered) && !isNullOrUndefined2(startBuffered) && startBuffered >= 0 && endBuffered >= 0) {
|
|
2148
|
-
let areAllKnown = true;
|
|
2149
|
-
for (let i = startBuffered; areAllKnown && i <= endBuffered; i++) {
|
|
2150
|
-
const key = getId(state, i);
|
|
2151
|
-
areAllKnown && (areAllKnown = sizesKnown.has(key));
|
|
2152
|
-
}
|
|
2153
|
-
return areAllKnown;
|
|
2154
|
-
}
|
|
2155
|
-
return false;
|
|
2156
|
-
}
|
|
2157
|
-
|
|
2158
|
-
// src/utils/findAvailableContainers.ts
|
|
2159
|
-
function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
|
|
2160
|
-
const numContainers = peek$(ctx, "numContainers");
|
|
2161
|
-
const state = ctx.state;
|
|
2162
|
-
const { stickyContainerPool, containerItemTypes } = state;
|
|
2163
|
-
const result = [];
|
|
2164
|
-
const availableContainers = [];
|
|
2165
|
-
const pendingRemovalSet = new Set(pendingRemoval);
|
|
2166
|
-
let pendingRemovalChanged = false;
|
|
2167
|
-
const stickyIndicesSet = state.props.stickyIndicesSet;
|
|
2168
|
-
const stickyItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => stickyIndicesSet.has(index))) || [];
|
|
2169
|
-
const canReuseContainer = (containerIndex, requiredType) => {
|
|
2170
|
-
if (!requiredType) return true;
|
|
2171
|
-
const existingType = containerItemTypes.get(containerIndex);
|
|
2172
|
-
if (!existingType) return true;
|
|
2173
|
-
return existingType === requiredType;
|
|
2174
|
-
};
|
|
2175
|
-
const neededTypes = requiredItemTypes ? [...requiredItemTypes] : [];
|
|
2176
|
-
let typeIndex = 0;
|
|
2177
|
-
for (let i = 0; i < stickyItemIndices.length; i++) {
|
|
2178
|
-
const requiredType = neededTypes[typeIndex];
|
|
2179
|
-
let foundContainer = false;
|
|
2180
|
-
for (const containerIndex of stickyContainerPool) {
|
|
2181
|
-
const key = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
2182
|
-
const isPendingRemoval = pendingRemovalSet.has(containerIndex);
|
|
2183
|
-
if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType) && !result.includes(containerIndex)) {
|
|
2184
|
-
result.push(containerIndex);
|
|
2185
|
-
if (isPendingRemoval && pendingRemovalSet.delete(containerIndex)) {
|
|
2186
|
-
pendingRemovalChanged = true;
|
|
2187
|
-
}
|
|
2188
|
-
foundContainer = true;
|
|
2189
|
-
if (requiredItemTypes) typeIndex++;
|
|
2190
|
-
break;
|
|
2191
|
-
}
|
|
2192
|
-
}
|
|
2193
|
-
if (!foundContainer) {
|
|
2194
|
-
const newContainerIndex = numContainers + result.filter((index) => index >= numContainers).length;
|
|
2195
|
-
result.push(newContainerIndex);
|
|
2196
|
-
stickyContainerPool.add(newContainerIndex);
|
|
2197
|
-
if (requiredItemTypes) typeIndex++;
|
|
2198
|
-
}
|
|
2199
|
-
}
|
|
2200
|
-
for (let u = 0; u < numContainers && result.length < numNeeded; u++) {
|
|
2201
|
-
if (stickyContainerPool.has(u)) {
|
|
2202
|
-
continue;
|
|
2203
|
-
}
|
|
2204
|
-
const key = peek$(ctx, `containerItemKey${u}`);
|
|
2205
|
-
const requiredType = neededTypes[typeIndex];
|
|
2206
|
-
const isPending = key !== void 0 && pendingRemovalSet.has(u);
|
|
2207
|
-
const canUse = key === void 0 || isPending && canReuseContainer(u, requiredType);
|
|
2208
|
-
if (canUse) {
|
|
2209
|
-
if (isPending) {
|
|
2210
|
-
pendingRemovalSet.delete(u);
|
|
2211
|
-
pendingRemovalChanged = true;
|
|
2212
|
-
}
|
|
2213
|
-
result.push(u);
|
|
2214
|
-
if (requiredItemTypes) {
|
|
2215
|
-
typeIndex++;
|
|
2216
|
-
}
|
|
2217
|
-
}
|
|
2218
|
-
}
|
|
2219
|
-
for (let u = 0; u < numContainers && result.length < numNeeded; u++) {
|
|
2220
|
-
if (stickyContainerPool.has(u)) {
|
|
2221
|
-
continue;
|
|
2222
|
-
}
|
|
2223
|
-
const key = peek$(ctx, `containerItemKey${u}`);
|
|
2224
|
-
if (key === void 0) continue;
|
|
2225
|
-
const index = state.indexByKey.get(key);
|
|
2226
|
-
const isOutOfView = index < startBuffered || index > endBuffered;
|
|
2227
|
-
if (isOutOfView) {
|
|
2228
|
-
const distance = index < startBuffered ? startBuffered - index : index - endBuffered;
|
|
2229
|
-
if (!requiredItemTypes || typeIndex < neededTypes.length && canReuseContainer(u, neededTypes[typeIndex])) {
|
|
2230
|
-
availableContainers.push({ distance, index: u });
|
|
2231
|
-
}
|
|
2232
|
-
}
|
|
2233
|
-
}
|
|
2234
|
-
const remaining = numNeeded - result.length;
|
|
2235
|
-
if (remaining > 0) {
|
|
2236
|
-
if (availableContainers.length > 0) {
|
|
2237
|
-
if (availableContainers.length > remaining) {
|
|
2238
|
-
availableContainers.sort(comparatorByDistance);
|
|
2239
|
-
availableContainers.length = remaining;
|
|
2240
|
-
}
|
|
2241
|
-
for (const container of availableContainers) {
|
|
2242
|
-
result.push(container.index);
|
|
2243
|
-
if (requiredItemTypes) {
|
|
2244
|
-
typeIndex++;
|
|
2245
|
-
}
|
|
2246
|
-
}
|
|
2247
|
-
}
|
|
2248
|
-
const stillNeeded = numNeeded - result.length;
|
|
2249
|
-
if (stillNeeded > 0) {
|
|
2250
|
-
for (let i = 0; i < stillNeeded; i++) {
|
|
2251
|
-
result.push(numContainers + i);
|
|
2252
|
-
}
|
|
2253
|
-
if (IS_DEV && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
|
|
2254
|
-
console.warn(
|
|
2255
|
-
"[legend-list] No unused container available, 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 or increasing initialContainerPoolRatio.",
|
|
2256
|
-
{
|
|
2257
|
-
debugInfo: {
|
|
2258
|
-
numContainers,
|
|
2259
|
-
numContainersPooled: peek$(ctx, "numContainersPooled"),
|
|
2260
|
-
numNeeded,
|
|
2261
|
-
stillNeeded
|
|
2262
|
-
}
|
|
2263
|
-
}
|
|
2264
|
-
);
|
|
2265
|
-
}
|
|
2266
|
-
}
|
|
2267
|
-
}
|
|
2268
|
-
if (pendingRemovalChanged) {
|
|
2269
|
-
pendingRemoval.length = 0;
|
|
2270
|
-
for (const value of pendingRemovalSet) {
|
|
2271
|
-
pendingRemoval.push(value);
|
|
2272
|
-
}
|
|
2273
|
-
}
|
|
2274
|
-
return result.sort(comparatorDefault);
|
|
2275
|
-
}
|
|
2276
|
-
function comparatorByDistance(a, b) {
|
|
2277
|
-
return b.distance - a.distance;
|
|
2278
|
-
}
|
|
2279
|
-
|
|
2280
|
-
// src/core/scrollToIndex.ts
|
|
2281
|
-
function scrollToIndex(ctx, { index, viewOffset = 0, animated = true, viewPosition }) {
|
|
2282
|
-
const state = ctx.state;
|
|
2283
|
-
const { data } = state.props;
|
|
2284
|
-
if (index >= data.length) {
|
|
2285
|
-
index = data.length - 1;
|
|
2286
|
-
} else if (index < 0) {
|
|
2287
|
-
index = 0;
|
|
2288
|
-
}
|
|
2289
|
-
const firstIndexOffset = calculateOffsetForIndex(ctx, index);
|
|
2290
|
-
const isLast = index === data.length - 1;
|
|
2291
|
-
if (isLast && viewPosition === void 0) {
|
|
2292
|
-
viewPosition = 1;
|
|
2293
|
-
}
|
|
2294
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
2295
|
-
const targetId = getId(state, index);
|
|
2296
|
-
const itemSize = getItemSize(ctx, targetId, index, state.props.data[index]);
|
|
2297
|
-
scrollTo(ctx, {
|
|
2298
|
-
animated,
|
|
2299
|
-
index,
|
|
2300
|
-
itemSize,
|
|
2301
|
-
offset: firstIndexOffset,
|
|
2302
|
-
viewOffset,
|
|
2303
|
-
viewPosition: viewPosition != null ? viewPosition : 0
|
|
2304
|
-
});
|
|
2305
|
-
}
|
|
2306
|
-
|
|
2307
|
-
// src/utils/setDidLayout.ts
|
|
2308
|
-
function setDidLayout(ctx) {
|
|
2309
|
-
const state = ctx.state;
|
|
2310
|
-
const {
|
|
2311
|
-
loadStartTime,
|
|
2312
|
-
initialScroll,
|
|
2313
|
-
props: { onLoad }
|
|
2314
|
-
} = state;
|
|
2315
|
-
state.queuedInitialLayout = true;
|
|
2316
|
-
checkAtBottom(ctx);
|
|
2317
|
-
const setIt = () => {
|
|
2318
|
-
setInitialRenderState(ctx, { didLayout: true });
|
|
2319
|
-
if (onLoad) {
|
|
2320
|
-
onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
|
|
2321
|
-
}
|
|
2322
|
-
};
|
|
2323
|
-
{
|
|
2324
|
-
setIt();
|
|
2325
|
-
}
|
|
2326
|
-
}
|
|
2327
|
-
|
|
2328
|
-
// src/core/calculateItemsInView.ts
|
|
2329
|
-
function findCurrentStickyIndex(stickyArray, scroll, state) {
|
|
2330
|
-
var _a3;
|
|
2331
|
-
const idCache = state.idCache;
|
|
2332
|
-
const positions = state.positions;
|
|
2333
|
-
for (let i = stickyArray.length - 1; i >= 0; i--) {
|
|
2334
|
-
const stickyIndex = stickyArray[i];
|
|
2335
|
-
const stickyId = (_a3 = idCache[stickyIndex]) != null ? _a3 : getId(state, stickyIndex);
|
|
2336
|
-
const stickyPos = stickyId ? positions.get(stickyId) : void 0;
|
|
2337
|
-
if (stickyPos !== void 0 && scroll >= stickyPos) {
|
|
2338
|
-
return i;
|
|
2339
|
-
}
|
|
2340
|
-
}
|
|
2341
|
-
return -1;
|
|
2342
|
-
}
|
|
2343
|
-
function getActiveStickyIndices(ctx, stickyHeaderIndices) {
|
|
2344
|
-
const state = ctx.state;
|
|
2345
|
-
return new Set(
|
|
2346
|
-
Array.from(state.stickyContainerPool).map((i) => peek$(ctx, `containerItemKey${i}`)).map((key) => key ? state.indexByKey.get(key) : void 0).filter((idx) => idx !== void 0 && stickyHeaderIndices.has(idx))
|
|
2347
|
-
);
|
|
2348
|
-
}
|
|
2349
|
-
function handleStickyActivation(ctx, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
|
|
2350
|
-
var _a3;
|
|
2351
|
-
const state = ctx.state;
|
|
2352
|
-
const activeIndices = getActiveStickyIndices(ctx, stickyHeaderIndices);
|
|
2353
|
-
set$(ctx, "activeStickyIndex", currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : -1);
|
|
2354
|
-
for (let offset = 0; offset <= 1; offset++) {
|
|
2355
|
-
const idx = currentStickyIdx - offset;
|
|
2356
|
-
if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
|
|
2357
|
-
const stickyIndex = stickyArray[idx];
|
|
2358
|
-
const stickyId = (_a3 = state.idCache[stickyIndex]) != null ? _a3 : getId(state, stickyIndex);
|
|
2359
|
-
if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered)) {
|
|
2360
|
-
needNewContainers.push(stickyIndex);
|
|
2361
|
-
}
|
|
2362
|
-
}
|
|
2363
|
-
}
|
|
2364
|
-
function handleStickyRecycling(ctx, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
|
|
2365
|
-
var _a3, _b, _c;
|
|
2366
|
-
const state = ctx.state;
|
|
2367
|
-
for (const containerIndex of state.stickyContainerPool) {
|
|
2368
|
-
const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
2369
|
-
const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
|
|
2370
|
-
if (itemIndex === void 0) continue;
|
|
2371
|
-
const arrayIdx = stickyArray.indexOf(itemIndex);
|
|
2372
|
-
if (arrayIdx === -1) {
|
|
2373
|
-
state.stickyContainerPool.delete(containerIndex);
|
|
2374
|
-
set$(ctx, `containerSticky${containerIndex}`, false);
|
|
2375
|
-
set$(ctx, `containerStickyOffset${containerIndex}`, void 0);
|
|
2376
|
-
continue;
|
|
2377
|
-
}
|
|
2378
|
-
const isRecentSticky = arrayIdx >= currentStickyIdx - 1 && arrayIdx <= currentStickyIdx + 1;
|
|
2379
|
-
if (isRecentSticky) continue;
|
|
2380
|
-
const nextIndex = stickyArray[arrayIdx + 1];
|
|
2381
|
-
let shouldRecycle = false;
|
|
2382
|
-
if (nextIndex) {
|
|
2383
|
-
const nextId = (_a3 = state.idCache[nextIndex]) != null ? _a3 : getId(state, nextIndex);
|
|
2384
|
-
const nextPos = nextId ? state.positions.get(nextId) : void 0;
|
|
2385
|
-
shouldRecycle = nextPos !== void 0 && scroll > nextPos + scrollBuffer * 2;
|
|
2386
|
-
} else {
|
|
2387
|
-
const currentId = (_b = state.idCache[itemIndex]) != null ? _b : getId(state, itemIndex);
|
|
2388
|
-
if (currentId) {
|
|
2389
|
-
const currentPos = state.positions.get(currentId);
|
|
2390
|
-
const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, currentId, itemIndex, state.props.data[itemIndex]);
|
|
2391
|
-
shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
|
|
2392
|
-
}
|
|
2393
|
-
}
|
|
2394
|
-
if (shouldRecycle) {
|
|
2395
|
-
pendingRemoval.push(containerIndex);
|
|
2396
|
-
}
|
|
2397
|
-
}
|
|
2398
|
-
}
|
|
2399
|
-
function calculateItemsInView(ctx, params = {}) {
|
|
2400
|
-
const state = ctx.state;
|
|
2401
|
-
reactDom.unstable_batchedUpdates(() => {
|
|
2402
|
-
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
2403
|
-
const {
|
|
2404
|
-
columns,
|
|
2405
|
-
containerItemKeys,
|
|
2406
|
-
enableScrollForNextCalculateItemsInView,
|
|
2407
|
-
idCache,
|
|
2408
|
-
indexByKey,
|
|
2409
|
-
initialScroll,
|
|
2410
|
-
minIndexSizeChanged,
|
|
2411
|
-
positions,
|
|
2412
|
-
props: { getItemType, itemsAreEqual, keyExtractor, onStickyHeaderChange, scrollBuffer },
|
|
2413
|
-
scrollForNextCalculateItemsInView,
|
|
2414
|
-
scrollLength,
|
|
2415
|
-
sizes,
|
|
2416
|
-
startBufferedId: startBufferedIdOrig,
|
|
2417
|
-
viewabilityConfigCallbackPairs
|
|
2418
|
-
} = state;
|
|
2419
|
-
const { data } = state.props;
|
|
2420
|
-
const stickyIndicesArr = state.props.stickyIndicesArr || [];
|
|
2421
|
-
const stickyIndicesSet = state.props.stickyIndicesSet || /* @__PURE__ */ new Set();
|
|
2422
|
-
const prevNumContainers = peek$(ctx, "numContainers");
|
|
2423
|
-
if (!data || scrollLength === 0 || !prevNumContainers) {
|
|
2424
|
-
return;
|
|
2425
|
-
}
|
|
2426
|
-
const totalSize = getContentSize(ctx);
|
|
2427
|
-
const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
|
|
2428
|
-
const numColumns = peek$(ctx, "numColumns");
|
|
2429
|
-
const { dataChanged, doMVCP, forceFullItemPositions } = params;
|
|
2430
|
-
const speed = getScrollVelocity(state);
|
|
2431
|
-
const scrollExtra = 0;
|
|
2432
|
-
const { queuedInitialLayout } = state;
|
|
2433
|
-
let { scroll: scrollState } = state;
|
|
2434
|
-
if (!queuedInitialLayout && initialScroll) {
|
|
2435
|
-
const updatedOffset = calculateOffsetWithOffsetPosition(
|
|
2436
|
-
ctx,
|
|
2437
|
-
calculateOffsetForIndex(ctx, initialScroll.index),
|
|
2438
|
-
initialScroll
|
|
2439
|
-
);
|
|
2440
|
-
scrollState = updatedOffset;
|
|
2441
|
-
}
|
|
2442
|
-
const scrollAdjustPending = (_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0;
|
|
2443
|
-
const scrollAdjustPad = scrollAdjustPending - topPad;
|
|
2444
|
-
let scroll = Math.round(scrollState + scrollExtra + scrollAdjustPad);
|
|
2445
|
-
if (scroll + scrollLength > totalSize) {
|
|
2446
|
-
scroll = Math.max(0, totalSize - scrollLength);
|
|
2447
|
-
}
|
|
2448
|
-
if (ENABLE_DEBUG_VIEW) {
|
|
2449
|
-
set$(ctx, "debugRawScroll", scrollState);
|
|
2450
|
-
set$(ctx, "debugComputedScroll", scroll);
|
|
2451
|
-
}
|
|
2452
|
-
const previousStickyIndex = peek$(ctx, "activeStickyIndex");
|
|
2453
|
-
const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
|
|
2454
|
-
const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : -1;
|
|
2455
|
-
if (currentStickyIdx >= 0 || previousStickyIndex >= 0) {
|
|
2456
|
-
set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
|
|
2457
|
-
}
|
|
2458
|
-
let scrollBufferTop = scrollBuffer;
|
|
2459
|
-
let scrollBufferBottom = scrollBuffer;
|
|
2460
|
-
if (speed > 0 || speed === 0 && scroll < Math.max(50, scrollBuffer)) {
|
|
2461
|
-
scrollBufferTop = scrollBuffer * 0.5;
|
|
2462
|
-
scrollBufferBottom = scrollBuffer * 1.5;
|
|
2463
|
-
} else {
|
|
2464
|
-
scrollBufferTop = scrollBuffer * 1.5;
|
|
2465
|
-
scrollBufferBottom = scrollBuffer * 0.5;
|
|
2466
|
-
}
|
|
2467
|
-
const scrollTopBuffered = scroll - scrollBufferTop;
|
|
2468
|
-
const scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
|
|
2469
|
-
const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
|
|
2470
|
-
if (!dataChanged && !forceFullItemPositions && scrollForNextCalculateItemsInView) {
|
|
2471
|
-
const { top, bottom } = scrollForNextCalculateItemsInView;
|
|
2472
|
-
if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
|
|
2473
|
-
return;
|
|
2474
|
-
}
|
|
2475
|
-
}
|
|
2476
|
-
const checkMVCP = doMVCP ? prepareMVCP(ctx, dataChanged) : void 0;
|
|
2477
|
-
if (dataChanged) {
|
|
2478
|
-
indexByKey.clear();
|
|
2479
|
-
idCache.length = 0;
|
|
2480
|
-
positions.clear();
|
|
2481
|
-
}
|
|
2482
|
-
const startIndex = forceFullItemPositions || dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
|
|
2483
|
-
updateItemPositions(ctx, dataChanged, {
|
|
2484
|
-
doMVCP,
|
|
2485
|
-
forceFullUpdate: !!forceFullItemPositions,
|
|
2486
|
-
scrollBottomBuffered,
|
|
2487
|
-
startIndex
|
|
2488
|
-
});
|
|
2489
|
-
if (minIndexSizeChanged !== void 0) {
|
|
2490
|
-
state.minIndexSizeChanged = void 0;
|
|
2491
|
-
}
|
|
2492
|
-
checkMVCP == null ? void 0 : checkMVCP();
|
|
2493
|
-
let startNoBuffer = null;
|
|
2494
|
-
let startBuffered = null;
|
|
2495
|
-
let startBufferedId = null;
|
|
2496
|
-
let endNoBuffer = null;
|
|
2497
|
-
let endBuffered = null;
|
|
2498
|
-
let loopStart = !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
|
|
2499
|
-
for (let i = loopStart; i >= 0; i--) {
|
|
2500
|
-
const id = (_c = idCache[i]) != null ? _c : getId(state, i);
|
|
2501
|
-
const top = positions.get(id);
|
|
2502
|
-
const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, id, i, data[i]);
|
|
2503
|
-
const bottom = top + size;
|
|
2504
|
-
if (bottom > scroll - scrollBufferTop) {
|
|
2505
|
-
loopStart = i;
|
|
2506
|
-
} else {
|
|
2507
|
-
break;
|
|
2508
|
-
}
|
|
2509
|
-
}
|
|
2510
|
-
const loopStartMod = loopStart % numColumns;
|
|
2511
|
-
if (loopStartMod > 0) {
|
|
2512
|
-
loopStart -= loopStartMod;
|
|
2513
|
-
}
|
|
2514
|
-
let foundEnd = false;
|
|
2515
|
-
let nextTop;
|
|
2516
|
-
let nextBottom;
|
|
2517
|
-
let maxIndexRendered = 0;
|
|
2518
|
-
for (let i = 0; i < prevNumContainers; i++) {
|
|
2519
|
-
const key = peek$(ctx, `containerItemKey${i}`);
|
|
2520
|
-
if (key !== void 0) {
|
|
2521
|
-
const index = indexByKey.get(key);
|
|
2522
|
-
maxIndexRendered = Math.max(maxIndexRendered, index);
|
|
2523
|
-
}
|
|
2524
|
-
}
|
|
2525
|
-
let firstFullyOnScreenIndex;
|
|
2526
|
-
const dataLength = data.length;
|
|
2527
|
-
for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
|
|
2528
|
-
const id = (_e = idCache[i]) != null ? _e : getId(state, i);
|
|
2529
|
-
const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, id, i, data[i]);
|
|
2530
|
-
const top = positions.get(id);
|
|
2531
|
-
if (!foundEnd) {
|
|
2532
|
-
if (startNoBuffer === null && top + size > scroll) {
|
|
2533
|
-
startNoBuffer = i;
|
|
2534
|
-
}
|
|
2535
|
-
if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10) {
|
|
2536
|
-
firstFullyOnScreenIndex = i;
|
|
2537
|
-
}
|
|
2538
|
-
if (startBuffered === null && top + size > scrollTopBuffered) {
|
|
2539
|
-
startBuffered = i;
|
|
2540
|
-
startBufferedId = id;
|
|
2541
|
-
if (scrollTopBuffered < 0) {
|
|
2542
|
-
nextTop = null;
|
|
2543
|
-
} else {
|
|
2544
|
-
nextTop = top;
|
|
2545
|
-
}
|
|
2546
|
-
}
|
|
2547
|
-
if (startNoBuffer !== null) {
|
|
2548
|
-
if (top <= scrollBottom) {
|
|
2549
|
-
endNoBuffer = i;
|
|
2550
|
-
}
|
|
2551
|
-
if (top <= scrollBottomBuffered) {
|
|
2552
|
-
endBuffered = i;
|
|
2553
|
-
if (scrollBottomBuffered > totalSize) {
|
|
2554
|
-
nextBottom = null;
|
|
2555
|
-
} else {
|
|
2556
|
-
nextBottom = top + size;
|
|
2557
|
-
}
|
|
2558
|
-
} else {
|
|
2559
|
-
foundEnd = true;
|
|
2560
|
-
}
|
|
2561
|
-
}
|
|
2562
|
-
}
|
|
2563
|
-
}
|
|
2564
|
-
const idsInView = [];
|
|
2565
|
-
for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
|
|
2566
|
-
const id = (_g = idCache[i]) != null ? _g : getId(state, i);
|
|
2567
|
-
idsInView.push(id);
|
|
2568
|
-
}
|
|
2569
|
-
Object.assign(state, {
|
|
2570
|
-
endBuffered,
|
|
2571
|
-
endNoBuffer,
|
|
2572
|
-
firstFullyOnScreenIndex,
|
|
2573
|
-
idsInView,
|
|
2574
|
-
startBuffered,
|
|
2575
|
-
startBufferedId,
|
|
2576
|
-
startNoBuffer
|
|
2577
|
-
});
|
|
2578
|
-
if (enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0) {
|
|
2579
|
-
state.scrollForNextCalculateItemsInView = nextTop !== void 0 && nextBottom !== void 0 ? {
|
|
2580
|
-
bottom: nextBottom,
|
|
2581
|
-
top: nextTop
|
|
2582
|
-
} : void 0;
|
|
2583
|
-
}
|
|
2584
|
-
let numContainers = prevNumContainers;
|
|
2585
|
-
const pendingRemoval = [];
|
|
2586
|
-
if (dataChanged) {
|
|
2587
|
-
for (let i = 0; i < numContainers; i++) {
|
|
2588
|
-
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
2589
|
-
if (!keyExtractor || itemKey && indexByKey.get(itemKey) === void 0) {
|
|
2590
|
-
pendingRemoval.push(i);
|
|
2591
|
-
}
|
|
2592
|
-
}
|
|
2593
|
-
}
|
|
2594
|
-
if (startBuffered !== null && endBuffered !== null) {
|
|
2595
|
-
const needNewContainers = [];
|
|
2596
|
-
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
2597
|
-
const id = (_h = idCache[i]) != null ? _h : getId(state, i);
|
|
2598
|
-
if (!containerItemKeys.has(id)) {
|
|
2599
|
-
needNewContainers.push(i);
|
|
2600
|
-
}
|
|
2601
|
-
}
|
|
2602
|
-
if (stickyIndicesArr.length > 0) {
|
|
2603
|
-
handleStickyActivation(
|
|
2604
|
-
ctx,
|
|
2605
|
-
stickyIndicesSet,
|
|
2606
|
-
stickyIndicesArr,
|
|
2607
|
-
currentStickyIdx,
|
|
2608
|
-
needNewContainers,
|
|
2609
|
-
startBuffered,
|
|
2610
|
-
endBuffered
|
|
2611
|
-
);
|
|
2612
|
-
} else if (previousStickyIndex !== -1) {
|
|
2613
|
-
set$(ctx, "activeStickyIndex", -1);
|
|
2614
|
-
}
|
|
2615
|
-
if (needNewContainers.length > 0) {
|
|
2616
|
-
const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
|
|
2617
|
-
const itemType = getItemType(data[i], i);
|
|
2618
|
-
return itemType ? String(itemType) : "";
|
|
2619
|
-
}) : void 0;
|
|
2620
|
-
const availableContainers = findAvailableContainers(
|
|
2621
|
-
ctx,
|
|
2622
|
-
needNewContainers.length,
|
|
2623
|
-
startBuffered,
|
|
2624
|
-
endBuffered,
|
|
2625
|
-
pendingRemoval,
|
|
2626
|
-
requiredItemTypes,
|
|
2627
|
-
needNewContainers
|
|
2628
|
-
);
|
|
2629
|
-
for (let idx = 0; idx < needNewContainers.length; idx++) {
|
|
2630
|
-
const i = needNewContainers[idx];
|
|
2631
|
-
const containerIndex = availableContainers[idx];
|
|
2632
|
-
const id = (_i = idCache[i]) != null ? _i : getId(state, i);
|
|
2633
|
-
const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
2634
|
-
if (oldKey && oldKey !== id) {
|
|
2635
|
-
containerItemKeys.delete(oldKey);
|
|
2636
|
-
}
|
|
2637
|
-
set$(ctx, `containerItemKey${containerIndex}`, id);
|
|
2638
|
-
set$(ctx, `containerItemData${containerIndex}`, data[i]);
|
|
2639
|
-
if (requiredItemTypes) {
|
|
2640
|
-
state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
|
|
2641
|
-
}
|
|
2642
|
-
containerItemKeys.add(id);
|
|
2643
|
-
const containerSticky = `containerSticky${containerIndex}`;
|
|
2644
|
-
if (stickyIndicesSet.has(i)) {
|
|
2645
|
-
set$(ctx, containerSticky, true);
|
|
2646
|
-
const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
2647
|
-
set$(ctx, `containerStickyOffset${containerIndex}`, topPadding);
|
|
2648
|
-
state.stickyContainerPool.add(containerIndex);
|
|
2649
|
-
} else if (peek$(ctx, containerSticky)) {
|
|
2650
|
-
set$(ctx, containerSticky, false);
|
|
2651
|
-
state.stickyContainerPool.delete(containerIndex);
|
|
2652
|
-
}
|
|
2653
|
-
if (containerIndex >= numContainers) {
|
|
2654
|
-
numContainers = containerIndex + 1;
|
|
2655
|
-
}
|
|
2656
|
-
}
|
|
2657
|
-
if (numContainers !== prevNumContainers) {
|
|
2658
|
-
set$(ctx, "numContainers", numContainers);
|
|
2659
|
-
if (numContainers > peek$(ctx, "numContainersPooled")) {
|
|
2660
|
-
set$(ctx, "numContainersPooled", Math.ceil(numContainers * 1.5));
|
|
2661
|
-
}
|
|
2662
|
-
}
|
|
2663
|
-
}
|
|
2664
|
-
}
|
|
2665
|
-
if (stickyIndicesArr.length > 0) {
|
|
2666
|
-
handleStickyRecycling(ctx, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
|
|
2667
|
-
}
|
|
2668
|
-
let didChangePositions = false;
|
|
2669
|
-
for (let i = 0; i < numContainers; i++) {
|
|
2670
|
-
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
2671
|
-
if (pendingRemoval.includes(i)) {
|
|
2672
|
-
if (itemKey !== void 0) {
|
|
2673
|
-
containerItemKeys.delete(itemKey);
|
|
2674
|
-
}
|
|
2675
|
-
state.containerItemTypes.delete(i);
|
|
2676
|
-
if (state.stickyContainerPool.has(i)) {
|
|
2677
|
-
set$(ctx, `containerSticky${i}`, false);
|
|
2678
|
-
set$(ctx, `containerStickyOffset${i}`, void 0);
|
|
2679
|
-
state.stickyContainerPool.delete(i);
|
|
2680
|
-
}
|
|
2681
|
-
set$(ctx, `containerItemKey${i}`, void 0);
|
|
2682
|
-
set$(ctx, `containerItemData${i}`, void 0);
|
|
2683
|
-
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
2684
|
-
set$(ctx, `containerColumn${i}`, -1);
|
|
2685
|
-
} else {
|
|
2686
|
-
const itemIndex = indexByKey.get(itemKey);
|
|
2687
|
-
const item = data[itemIndex];
|
|
2688
|
-
if (item !== void 0) {
|
|
2689
|
-
const id = (_j = idCache[itemIndex]) != null ? _j : getId(state, itemIndex);
|
|
2690
|
-
const positionValue = positions.get(id);
|
|
2691
|
-
if (positionValue === void 0) {
|
|
2692
|
-
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
2693
|
-
} else {
|
|
2694
|
-
const position = (positionValue || 0) - scrollAdjustPending;
|
|
2695
|
-
const column = columns.get(id) || 1;
|
|
2696
|
-
const prevPos = peek$(ctx, `containerPosition${i}`);
|
|
2697
|
-
const prevColumn = peek$(ctx, `containerColumn${i}`);
|
|
2698
|
-
const prevData = peek$(ctx, `containerItemData${i}`);
|
|
2699
|
-
if (position > POSITION_OUT_OF_VIEW && position !== prevPos) {
|
|
2700
|
-
set$(ctx, `containerPosition${i}`, position);
|
|
2701
|
-
didChangePositions = true;
|
|
2702
|
-
}
|
|
2703
|
-
if (column >= 0 && column !== prevColumn) {
|
|
2704
|
-
set$(ctx, `containerColumn${i}`, column);
|
|
2705
|
-
}
|
|
2706
|
-
if (prevData !== item && (itemsAreEqual ? !itemsAreEqual(prevData, item, itemIndex, data) : true)) {
|
|
2707
|
-
set$(ctx, `containerItemData${i}`, item);
|
|
2708
|
-
}
|
|
2709
|
-
}
|
|
2710
|
-
}
|
|
2711
|
-
}
|
|
2712
|
-
}
|
|
2713
|
-
if (didChangePositions) {
|
|
2714
|
-
set$(ctx, "lastPositionUpdate", Date.now());
|
|
2715
|
-
}
|
|
2716
|
-
if (!queuedInitialLayout && endBuffered !== null) {
|
|
2717
|
-
if (checkAllSizesKnown(state)) {
|
|
2718
|
-
setDidLayout(ctx);
|
|
2719
|
-
}
|
|
2720
|
-
}
|
|
2721
|
-
if (viewabilityConfigCallbackPairs) {
|
|
2722
|
-
updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollLength, startNoBuffer, endNoBuffer);
|
|
2723
|
-
}
|
|
2724
|
-
if (onStickyHeaderChange && stickyIndicesArr.length > 0 && nextActiveStickyIndex !== void 0 && nextActiveStickyIndex !== previousStickyIndex) {
|
|
2725
|
-
const item = data[nextActiveStickyIndex];
|
|
2726
|
-
if (item !== void 0) {
|
|
2727
|
-
onStickyHeaderChange({ index: nextActiveStickyIndex, item });
|
|
2728
|
-
}
|
|
2729
|
-
}
|
|
2730
|
-
});
|
|
2731
|
-
}
|
|
2732
|
-
|
|
2733
|
-
// src/core/checkActualChange.ts
|
|
2734
|
-
function checkActualChange(state, dataProp, previousData) {
|
|
2735
|
-
if (!previousData || !dataProp || dataProp.length !== previousData.length) {
|
|
2736
|
-
return true;
|
|
2737
|
-
}
|
|
2738
|
-
const {
|
|
2739
|
-
idCache,
|
|
2740
|
-
props: { keyExtractor }
|
|
2741
|
-
} = state;
|
|
2742
|
-
for (let i = 0; i < dataProp.length; i++) {
|
|
2743
|
-
if (dataProp[i] !== previousData[i]) {
|
|
2744
|
-
return true;
|
|
2745
|
-
}
|
|
2746
|
-
if (keyExtractor ? idCache[i] !== keyExtractor(previousData[i], i) : dataProp[i] !== previousData[i]) {
|
|
2747
|
-
return true;
|
|
2748
|
-
}
|
|
2749
|
-
}
|
|
2750
|
-
return false;
|
|
2751
|
-
}
|
|
2752
|
-
|
|
2753
|
-
// src/core/checkFinishedScroll.ts
|
|
2754
|
-
function checkFinishedScroll(ctx) {
|
|
2755
|
-
ctx.state.animFrameCheckFinishedScroll = requestAnimationFrame(() => checkFinishedScrollFrame(ctx));
|
|
2756
|
-
}
|
|
2757
|
-
function checkFinishedScrollFrame(ctx) {
|
|
2758
|
-
const scrollingTo = ctx.state.scrollingTo;
|
|
2759
|
-
if (scrollingTo) {
|
|
2760
|
-
const { state } = ctx;
|
|
2761
|
-
state.animFrameCheckFinishedScroll = void 0;
|
|
2762
|
-
const scroll = state.scrollPending;
|
|
2763
|
-
const adjust = state.scrollAdjustHandler.getAdjust();
|
|
2764
|
-
const clampedTargetOffset = clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0));
|
|
2765
|
-
const diff1 = Math.abs(scroll - clampedTargetOffset);
|
|
2766
|
-
const diff2 = Math.abs(diff1 - adjust);
|
|
2767
|
-
if (diff1 < 1 || diff2 < 1) {
|
|
2768
|
-
finishScrollTo(ctx);
|
|
2769
|
-
}
|
|
2770
|
-
}
|
|
2771
|
-
}
|
|
2772
|
-
function checkFinishedScrollFallback(ctx) {
|
|
2773
|
-
const state = ctx.state;
|
|
2774
|
-
const scrollingTo = state.scrollingTo;
|
|
2775
|
-
const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) || !state.didContainersLayout;
|
|
2776
|
-
state.timeoutCheckFinishedScrollFallback = setTimeout(
|
|
2777
|
-
() => {
|
|
2778
|
-
let numChecks = 0;
|
|
2779
|
-
const checkHasScrolled = () => {
|
|
2780
|
-
state.timeoutCheckFinishedScrollFallback = void 0;
|
|
2781
|
-
const isStillScrollingTo = state.scrollingTo;
|
|
2782
|
-
if (isStillScrollingTo) {
|
|
2783
|
-
numChecks++;
|
|
2784
|
-
if (state.hasScrolled || numChecks > 5) {
|
|
2785
|
-
finishScrollTo(ctx);
|
|
2786
|
-
} else {
|
|
2787
|
-
state.timeoutCheckFinishedScrollFallback = setTimeout(checkHasScrolled, 100);
|
|
2788
|
-
}
|
|
2789
|
-
}
|
|
2790
|
-
};
|
|
2791
|
-
checkHasScrolled();
|
|
2792
|
-
},
|
|
2793
|
-
slowTimeout ? 500 : 100
|
|
2794
|
-
);
|
|
2795
|
-
}
|
|
2796
|
-
|
|
2797
|
-
// src/core/doMaintainScrollAtEnd.ts
|
|
2798
|
-
function doMaintainScrollAtEnd(ctx, animated) {
|
|
2799
|
-
const state = ctx.state;
|
|
2800
|
-
const {
|
|
2801
|
-
didContainersLayout,
|
|
2802
|
-
isAtEnd,
|
|
2803
|
-
refScroller,
|
|
2804
|
-
props: { maintainScrollAtEnd }
|
|
2805
|
-
} = state;
|
|
2806
|
-
if (isAtEnd && maintainScrollAtEnd && didContainersLayout) {
|
|
2807
|
-
const paddingTop = peek$(ctx, "alignItemsPaddingTop");
|
|
2808
|
-
if (paddingTop > 0) {
|
|
2809
|
-
state.scroll = 0;
|
|
2810
|
-
}
|
|
2811
|
-
requestAnimationFrame(() => {
|
|
2812
|
-
var _a3;
|
|
2813
|
-
if (state.isAtEnd) {
|
|
2814
|
-
state.maintainingScrollAtEnd = true;
|
|
2815
|
-
(_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
|
|
2816
|
-
animated
|
|
2817
|
-
});
|
|
2818
|
-
setTimeout(
|
|
2819
|
-
() => {
|
|
2820
|
-
state.maintainingScrollAtEnd = false;
|
|
2821
|
-
},
|
|
2822
|
-
0
|
|
2823
|
-
);
|
|
2824
|
-
}
|
|
2825
|
-
});
|
|
2826
|
-
return true;
|
|
2827
|
-
}
|
|
2828
|
-
return false;
|
|
2829
|
-
}
|
|
2830
|
-
|
|
2831
|
-
// src/utils/updateAveragesOnDataChange.ts
|
|
2832
|
-
function updateAveragesOnDataChange(state, oldData, newData) {
|
|
2833
|
-
var _a3;
|
|
2834
|
-
const {
|
|
2835
|
-
averageSizes,
|
|
2836
|
-
sizesKnown,
|
|
2837
|
-
indexByKey,
|
|
2838
|
-
props: { itemsAreEqual, getItemType, keyExtractor }
|
|
2839
|
-
} = state;
|
|
2840
|
-
if (!itemsAreEqual || !oldData.length || !newData.length) {
|
|
2841
|
-
for (const key in averageSizes) {
|
|
2842
|
-
delete averageSizes[key];
|
|
2843
|
-
}
|
|
2844
|
-
return;
|
|
2845
|
-
}
|
|
2846
|
-
const itemTypesToPreserve = {};
|
|
2847
|
-
const newDataLength = newData.length;
|
|
2848
|
-
const oldDataLength = oldData.length;
|
|
2849
|
-
for (let newIndex = 0; newIndex < newDataLength; newIndex++) {
|
|
2850
|
-
const newItem = newData[newIndex];
|
|
2851
|
-
const id = keyExtractor ? keyExtractor(newItem, newIndex) : String(newIndex);
|
|
2852
|
-
const oldIndex = indexByKey.get(id);
|
|
2853
|
-
if (oldIndex !== void 0 && oldIndex < oldDataLength) {
|
|
2854
|
-
const knownSize = sizesKnown.get(id);
|
|
2855
|
-
if (knownSize === void 0) continue;
|
|
2856
|
-
const oldItem = oldData[oldIndex];
|
|
2857
|
-
const areEqual = itemsAreEqual(oldItem, newItem, newIndex, newData);
|
|
2858
|
-
if (areEqual) {
|
|
2859
|
-
const itemType = getItemType ? (_a3 = getItemType(newItem, newIndex)) != null ? _a3 : "" : "";
|
|
2860
|
-
let typeData = itemTypesToPreserve[itemType];
|
|
2861
|
-
if (!typeData) {
|
|
2862
|
-
typeData = itemTypesToPreserve[itemType] = { count: 0, totalSize: 0 };
|
|
2863
|
-
}
|
|
2864
|
-
typeData.totalSize += knownSize;
|
|
2865
|
-
typeData.count++;
|
|
2866
|
-
}
|
|
2867
|
-
}
|
|
2868
|
-
}
|
|
2869
|
-
for (const key in averageSizes) {
|
|
2870
|
-
delete averageSizes[key];
|
|
2871
|
-
}
|
|
2872
|
-
for (const itemType in itemTypesToPreserve) {
|
|
2873
|
-
const { totalSize, count } = itemTypesToPreserve[itemType];
|
|
2874
|
-
if (count > 0) {
|
|
2875
|
-
averageSizes[itemType] = {
|
|
2876
|
-
avg: totalSize / count,
|
|
2877
|
-
num: count
|
|
2878
|
-
};
|
|
2879
|
-
}
|
|
2880
|
-
}
|
|
2881
|
-
}
|
|
2882
|
-
|
|
2883
|
-
// src/core/checkResetContainers.ts
|
|
2884
|
-
function checkResetContainers(ctx, dataProp) {
|
|
2885
|
-
const state = ctx.state;
|
|
2886
|
-
const { previousData } = state;
|
|
2887
|
-
if (previousData) {
|
|
2888
|
-
updateAveragesOnDataChange(state, previousData, dataProp);
|
|
2889
|
-
}
|
|
2890
|
-
const { maintainScrollAtEnd } = state.props;
|
|
2891
|
-
calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
|
|
2892
|
-
const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
|
|
2893
|
-
const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, false);
|
|
2894
|
-
if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
|
|
2895
|
-
state.isEndReached = false;
|
|
2896
|
-
}
|
|
2897
|
-
if (!didMaintainScrollAtEnd) {
|
|
2898
|
-
checkAtTop(state);
|
|
2899
|
-
checkAtBottom(ctx);
|
|
2900
|
-
}
|
|
2901
|
-
delete state.previousData;
|
|
2902
|
-
}
|
|
2903
|
-
|
|
2904
|
-
// src/core/doInitialAllocateContainers.ts
|
|
2905
|
-
function doInitialAllocateContainers(ctx) {
|
|
2906
|
-
var _a3, _b, _c;
|
|
2907
|
-
const state = ctx.state;
|
|
2908
|
-
const {
|
|
2909
|
-
scrollLength,
|
|
2910
|
-
props: {
|
|
2911
|
-
data,
|
|
2912
|
-
getEstimatedItemSize,
|
|
2913
|
-
getFixedItemSize,
|
|
2914
|
-
getItemType,
|
|
2915
|
-
scrollBuffer,
|
|
2916
|
-
numColumns,
|
|
2917
|
-
estimatedItemSize
|
|
2918
|
-
}
|
|
2919
|
-
} = state;
|
|
2920
|
-
const hasContainers = peek$(ctx, "numContainers");
|
|
2921
|
-
if (scrollLength > 0 && data.length > 0 && !hasContainers) {
|
|
2922
|
-
let averageItemSize;
|
|
2923
|
-
if (getFixedItemSize || getEstimatedItemSize) {
|
|
2924
|
-
let totalSize = 0;
|
|
2925
|
-
const num = Math.min(20, data.length);
|
|
2926
|
-
for (let i = 0; i < num; i++) {
|
|
2927
|
-
const item = data[i];
|
|
2928
|
-
const itemType = getItemType ? (_a3 = getItemType(item, i)) != null ? _a3 : "" : "";
|
|
2929
|
-
totalSize += (_c = (_b = getFixedItemSize == null ? void 0 : getFixedItemSize(i, item, itemType)) != null ? _b : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(i, item, itemType)) != null ? _c : estimatedItemSize;
|
|
2930
|
-
}
|
|
2931
|
-
averageItemSize = totalSize / num;
|
|
2932
|
-
} else {
|
|
2933
|
-
averageItemSize = estimatedItemSize;
|
|
2934
|
-
}
|
|
2935
|
-
const numContainers = Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize * numColumns);
|
|
2936
|
-
for (let i = 0; i < numContainers; i++) {
|
|
2937
|
-
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
2938
|
-
set$(ctx, `containerColumn${i}`, -1);
|
|
2939
|
-
}
|
|
2940
|
-
set$(ctx, "numContainers", numContainers);
|
|
2941
|
-
set$(ctx, "numContainersPooled", numContainers * state.props.initialContainerPoolRatio);
|
|
2942
|
-
if (state.lastLayout) {
|
|
2943
|
-
if (state.initialScroll) {
|
|
2944
|
-
requestAnimationFrame(() => {
|
|
2945
|
-
calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
|
|
2946
|
-
});
|
|
2947
|
-
} else {
|
|
2948
|
-
calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
|
|
2949
|
-
}
|
|
2950
|
-
}
|
|
2951
|
-
return true;
|
|
2952
|
-
}
|
|
2953
|
-
}
|
|
2954
|
-
|
|
2955
|
-
// src/core/handleLayout.ts
|
|
2956
|
-
function handleLayout(ctx, layout, setCanRender) {
|
|
2957
|
-
const state = ctx.state;
|
|
2958
|
-
const { maintainScrollAtEnd } = state.props;
|
|
2959
|
-
const measuredLength = layout[state.props.horizontal ? "width" : "height"];
|
|
2960
|
-
const previousLength = state.scrollLength;
|
|
2961
|
-
const scrollLength = measuredLength > 0 ? measuredLength : previousLength;
|
|
2962
|
-
const otherAxisSize = layout[state.props.horizontal ? "height" : "width"];
|
|
2963
|
-
const needsCalculate = !state.lastLayout || scrollLength > state.scrollLength || state.lastLayout.x !== layout.x || state.lastLayout.y !== layout.y;
|
|
2964
|
-
state.lastLayout = layout;
|
|
2965
|
-
const prevOtherAxisSize = state.otherAxisSize;
|
|
2966
|
-
const didChange = scrollLength !== state.scrollLength || otherAxisSize !== prevOtherAxisSize;
|
|
2967
|
-
if (didChange) {
|
|
2968
|
-
state.scrollLength = scrollLength;
|
|
2969
|
-
state.otherAxisSize = otherAxisSize;
|
|
2970
|
-
state.lastBatchingAction = Date.now();
|
|
2971
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
2972
|
-
if (scrollLength > 0) {
|
|
2973
|
-
doInitialAllocateContainers(ctx);
|
|
2974
|
-
}
|
|
2975
|
-
if (needsCalculate) {
|
|
2976
|
-
calculateItemsInView(ctx, { doMVCP: true });
|
|
2977
|
-
}
|
|
2978
|
-
if (didChange || otherAxisSize !== prevOtherAxisSize) {
|
|
2979
|
-
set$(ctx, "scrollSize", { height: layout.height, width: layout.width });
|
|
2980
|
-
}
|
|
2981
|
-
if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
|
|
2982
|
-
doMaintainScrollAtEnd(ctx, false);
|
|
2983
|
-
}
|
|
2984
|
-
updateAlignItemsPaddingTop(ctx);
|
|
2985
|
-
checkAtBottom(ctx);
|
|
2986
|
-
checkAtTop(state);
|
|
2987
|
-
if (state) {
|
|
2988
|
-
state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
|
|
2989
|
-
}
|
|
2990
|
-
if (IS_DEV && measuredLength === 0) {
|
|
2991
|
-
warnDevOnce(
|
|
2992
|
-
"height0",
|
|
2993
|
-
`List ${state.props.horizontal ? "width" : "height"} is 0. You may need to set a style or \`flex: \` for the list, because children are absolutely positioned.`
|
|
2994
|
-
);
|
|
2995
|
-
}
|
|
2996
|
-
}
|
|
2997
|
-
setCanRender(true);
|
|
2998
|
-
}
|
|
2999
|
-
|
|
3000
|
-
// src/core/onScroll.ts
|
|
3001
|
-
function onScroll(ctx, event) {
|
|
3002
|
-
var _a3, _b, _c;
|
|
3003
|
-
const state = ctx.state;
|
|
3004
|
-
const {
|
|
3005
|
-
scrollProcessingEnabled,
|
|
3006
|
-
props: { onScroll: onScrollProp }
|
|
3007
|
-
} = state;
|
|
3008
|
-
if (scrollProcessingEnabled === false) {
|
|
3009
|
-
return;
|
|
3010
|
-
}
|
|
3011
|
-
if (((_b = (_a3 = event.nativeEvent) == null ? void 0 : _a3.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
|
|
3012
|
-
return;
|
|
3013
|
-
}
|
|
3014
|
-
let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
|
|
3015
|
-
state.scrollPending = newScroll;
|
|
3016
|
-
if (state.scrollingTo) {
|
|
3017
|
-
const maxOffset = clampScrollOffset(ctx, newScroll);
|
|
3018
|
-
if (newScroll !== maxOffset) {
|
|
3019
|
-
newScroll = maxOffset;
|
|
3020
|
-
scrollTo(ctx, {
|
|
3021
|
-
forceScroll: true,
|
|
3022
|
-
isInitialScroll: true,
|
|
3023
|
-
noScrollingTo: true,
|
|
3024
|
-
offset: newScroll
|
|
3025
|
-
});
|
|
3026
|
-
}
|
|
3027
|
-
checkFinishedScroll(ctx);
|
|
3028
|
-
}
|
|
3029
|
-
updateScroll(ctx, newScroll);
|
|
3030
|
-
onScrollProp == null ? void 0 : onScrollProp(event);
|
|
3031
|
-
}
|
|
3032
|
-
|
|
3033
|
-
// src/core/ScrollAdjustHandler.ts
|
|
3034
|
-
var ScrollAdjustHandler = class {
|
|
3035
|
-
constructor(ctx) {
|
|
3036
|
-
this.appliedAdjust = 0;
|
|
3037
|
-
this.pendingAdjust = 0;
|
|
3038
|
-
this.ctx = ctx;
|
|
3039
|
-
}
|
|
3040
|
-
requestAdjust(add) {
|
|
3041
|
-
const scrollingTo = this.ctx.state.scrollingTo;
|
|
3042
|
-
if ((scrollingTo == null ? void 0 : scrollingTo.animated) && !scrollingTo.isInitialScroll) {
|
|
3043
|
-
this.pendingAdjust += add;
|
|
3044
|
-
set$(this.ctx, "scrollAdjustPending", this.pendingAdjust);
|
|
3045
|
-
} else {
|
|
3046
|
-
this.appliedAdjust += add;
|
|
3047
|
-
set$(this.ctx, "scrollAdjust", this.appliedAdjust);
|
|
3048
|
-
}
|
|
3049
|
-
if (this.ctx.state.scrollingTo) {
|
|
3050
|
-
checkFinishedScroll(this.ctx);
|
|
3051
|
-
}
|
|
3052
|
-
}
|
|
3053
|
-
getAdjust() {
|
|
3054
|
-
return this.appliedAdjust;
|
|
3055
|
-
}
|
|
3056
|
-
commitPendingAdjust() {
|
|
3057
|
-
{
|
|
3058
|
-
const state = this.ctx.state;
|
|
3059
|
-
const pending = this.pendingAdjust;
|
|
3060
|
-
if (pending !== 0) {
|
|
3061
|
-
this.pendingAdjust = 0;
|
|
3062
|
-
this.appliedAdjust += pending;
|
|
3063
|
-
state.scroll += pending;
|
|
3064
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
3065
|
-
set$(this.ctx, "scrollAdjustPending", 0);
|
|
3066
|
-
set$(this.ctx, "scrollAdjust", this.appliedAdjust);
|
|
3067
|
-
calculateItemsInView(this.ctx);
|
|
3068
|
-
}
|
|
3069
|
-
}
|
|
3070
|
-
}
|
|
3071
|
-
};
|
|
3072
|
-
|
|
3073
|
-
// src/core/updateItemSize.ts
|
|
3074
|
-
function updateItemSize(ctx, itemKey, sizeObj) {
|
|
3075
|
-
var _a3;
|
|
3076
|
-
const state = ctx.state;
|
|
3077
|
-
const {
|
|
3078
|
-
didContainersLayout,
|
|
3079
|
-
sizesKnown,
|
|
3080
|
-
props: {
|
|
3081
|
-
getFixedItemSize,
|
|
3082
|
-
getItemType,
|
|
3083
|
-
horizontal,
|
|
3084
|
-
suggestEstimatedItemSize,
|
|
3085
|
-
onItemSizeChanged,
|
|
3086
|
-
data,
|
|
3087
|
-
maintainScrollAtEnd
|
|
3088
|
-
}
|
|
3089
|
-
} = state;
|
|
3090
|
-
if (!data) return;
|
|
3091
|
-
const index = state.indexByKey.get(itemKey);
|
|
3092
|
-
if (getFixedItemSize) {
|
|
3093
|
-
if (index === void 0) {
|
|
3094
|
-
return;
|
|
3095
|
-
}
|
|
3096
|
-
const itemData = state.props.data[index];
|
|
3097
|
-
if (itemData === void 0) {
|
|
3098
|
-
return;
|
|
3099
|
-
}
|
|
3100
|
-
const type = getItemType ? (_a3 = getItemType(itemData, index)) != null ? _a3 : "" : "";
|
|
3101
|
-
const size2 = getFixedItemSize(index, itemData, type);
|
|
3102
|
-
if (size2 !== void 0 && size2 === sizesKnown.get(itemKey)) {
|
|
3103
|
-
return;
|
|
3104
|
-
}
|
|
3105
|
-
}
|
|
3106
|
-
let needsRecalculate = !didContainersLayout;
|
|
3107
|
-
let shouldMaintainScrollAtEnd = false;
|
|
3108
|
-
let minIndexSizeChanged;
|
|
3109
|
-
let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
|
|
3110
|
-
const prevSizeKnown = state.sizesKnown.get(itemKey);
|
|
3111
|
-
const diff = updateOneItemSize(ctx, itemKey, sizeObj);
|
|
3112
|
-
const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
|
|
3113
|
-
if (diff !== 0) {
|
|
3114
|
-
minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
|
|
3115
|
-
const { startBuffered, endBuffered } = state;
|
|
3116
|
-
needsRecalculate || (needsRecalculate = index >= startBuffered && index <= endBuffered);
|
|
3117
|
-
if (!needsRecalculate) {
|
|
3118
|
-
const numContainers = ctx.values.get("numContainers");
|
|
3119
|
-
for (let i = 0; i < numContainers; i++) {
|
|
3120
|
-
if (peek$(ctx, `containerItemKey${i}`) === itemKey) {
|
|
3121
|
-
needsRecalculate = true;
|
|
3122
|
-
break;
|
|
3123
|
-
}
|
|
3124
|
-
}
|
|
3125
|
-
}
|
|
3126
|
-
if (state.needsOtherAxisSize) {
|
|
3127
|
-
const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
|
|
3128
|
-
maxOtherAxisSize = Math.max(maxOtherAxisSize, otherAxisSize);
|
|
3129
|
-
}
|
|
3130
|
-
if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
|
|
3131
|
-
shouldMaintainScrollAtEnd = true;
|
|
3132
|
-
}
|
|
3133
|
-
onItemSizeChanged == null ? void 0 : onItemSizeChanged({
|
|
3134
|
-
index,
|
|
3135
|
-
itemData: state.props.data[index],
|
|
3136
|
-
itemKey,
|
|
3137
|
-
previous: size - diff,
|
|
3138
|
-
size
|
|
3139
|
-
});
|
|
3140
|
-
}
|
|
3141
|
-
if (minIndexSizeChanged !== void 0) {
|
|
3142
|
-
state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, minIndexSizeChanged) : minIndexSizeChanged;
|
|
3143
|
-
}
|
|
3144
|
-
if (IS_DEV && suggestEstimatedItemSize && minIndexSizeChanged !== void 0) {
|
|
3145
|
-
if (state.timeoutSizeMessage) clearTimeout(state.timeoutSizeMessage);
|
|
3146
|
-
state.timeoutSizeMessage = setTimeout(() => {
|
|
3147
|
-
var _a4;
|
|
3148
|
-
state.timeoutSizeMessage = void 0;
|
|
3149
|
-
const num = state.sizesKnown.size;
|
|
3150
|
-
const avg = (_a4 = state.averageSizes[""]) == null ? void 0 : _a4.avg;
|
|
3151
|
-
console.warn(
|
|
3152
|
-
`[legend-list] Based on the ${num} items rendered so far, the optimal estimated size is ${avg}.`
|
|
3153
|
-
);
|
|
3154
|
-
}, 1e3);
|
|
3155
|
-
}
|
|
3156
|
-
const cur = peek$(ctx, "otherAxisSize");
|
|
3157
|
-
if (!cur || maxOtherAxisSize > cur) {
|
|
3158
|
-
set$(ctx, "otherAxisSize", maxOtherAxisSize);
|
|
3159
|
-
}
|
|
3160
|
-
if (didContainersLayout || checkAllSizesKnown(state)) {
|
|
3161
|
-
if (needsRecalculate) {
|
|
3162
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
3163
|
-
calculateItemsInView(ctx, { doMVCP: true });
|
|
3164
|
-
}
|
|
3165
|
-
if (shouldMaintainScrollAtEnd) {
|
|
3166
|
-
if (maintainScrollAtEnd === true || maintainScrollAtEnd.onItemLayout) {
|
|
3167
|
-
doMaintainScrollAtEnd(ctx, false);
|
|
3168
|
-
}
|
|
3169
|
-
}
|
|
3170
|
-
}
|
|
3171
|
-
}
|
|
3172
|
-
function updateOneItemSize(ctx, itemKey, sizeObj) {
|
|
3173
|
-
var _a3;
|
|
3174
|
-
const state = ctx.state;
|
|
3175
|
-
const {
|
|
3176
|
-
indexByKey,
|
|
3177
|
-
sizesKnown,
|
|
3178
|
-
averageSizes,
|
|
3179
|
-
props: { data, horizontal, getEstimatedItemSize, getItemType, getFixedItemSize }
|
|
3180
|
-
} = state;
|
|
3181
|
-
if (!data) return 0;
|
|
3182
|
-
const index = indexByKey.get(itemKey);
|
|
3183
|
-
const prevSize = getItemSize(ctx, itemKey, index, data[index]);
|
|
3184
|
-
const rawSize = horizontal ? sizeObj.width : sizeObj.height;
|
|
3185
|
-
const size = Math.round(rawSize) ;
|
|
3186
|
-
const prevSizeKnown = sizesKnown.get(itemKey);
|
|
3187
|
-
sizesKnown.set(itemKey, size);
|
|
3188
|
-
if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
|
|
3189
|
-
const itemType = getItemType ? (_a3 = getItemType(data[index], index)) != null ? _a3 : "" : "";
|
|
3190
|
-
let averages = averageSizes[itemType];
|
|
3191
|
-
if (!averages) {
|
|
3192
|
-
averages = averageSizes[itemType] = { avg: 0, num: 0 };
|
|
3193
|
-
}
|
|
3194
|
-
if (prevSizeKnown !== void 0 && prevSizeKnown > 0) {
|
|
3195
|
-
averages.avg += (size - prevSizeKnown) / averages.num;
|
|
3196
|
-
} else {
|
|
3197
|
-
averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
|
|
3198
|
-
averages.num++;
|
|
3199
|
-
}
|
|
3200
|
-
}
|
|
3201
|
-
if (!prevSize || Math.abs(prevSize - size) > 0.1) {
|
|
3202
|
-
setSize(ctx, itemKey, size);
|
|
3203
|
-
return size - prevSize;
|
|
3204
|
-
}
|
|
3205
|
-
return 0;
|
|
3206
|
-
}
|
|
3207
|
-
var useCombinedRef = (...refs) => {
|
|
3208
|
-
const callback = React3.useCallback((element) => {
|
|
3209
|
-
for (const ref of refs) {
|
|
3210
|
-
if (!ref) {
|
|
3211
|
-
continue;
|
|
3212
|
-
}
|
|
3213
|
-
if (isFunction(ref)) {
|
|
3214
|
-
ref(element);
|
|
3215
|
-
} else {
|
|
3216
|
-
ref.current = element;
|
|
3217
|
-
}
|
|
3218
|
-
}
|
|
3219
|
-
}, refs);
|
|
3220
|
-
return callback;
|
|
3221
|
-
};
|
|
3222
|
-
|
|
3223
|
-
// src/platform/RefreshControl.tsx
|
|
3224
|
-
function RefreshControl(_props) {
|
|
3225
|
-
return null;
|
|
3226
|
-
}
|
|
3227
|
-
|
|
3228
|
-
// src/platform/useStickyScrollHandler.ts
|
|
3229
|
-
function useStickyScrollHandler(_stickyHeaderIndices, _horizontal, _ctx, onScroll2) {
|
|
3230
|
-
return onScroll2;
|
|
3231
|
-
}
|
|
3232
|
-
|
|
3233
|
-
// src/utils/createColumnWrapperStyle.ts
|
|
3234
|
-
function createColumnWrapperStyle(contentContainerStyle) {
|
|
3235
|
-
const { gap, columnGap, rowGap } = contentContainerStyle;
|
|
3236
|
-
if (gap || columnGap || rowGap) {
|
|
3237
|
-
contentContainerStyle.gap = void 0;
|
|
3238
|
-
contentContainerStyle.columnGap = void 0;
|
|
3239
|
-
contentContainerStyle.rowGap = void 0;
|
|
3240
|
-
return {
|
|
3241
|
-
columnGap,
|
|
3242
|
-
gap,
|
|
3243
|
-
rowGap
|
|
3244
|
-
};
|
|
3245
|
-
}
|
|
3246
|
-
}
|
|
3247
|
-
|
|
3248
|
-
// src/utils/createImperativeHandle.ts
|
|
3249
|
-
function createImperativeHandle(ctx) {
|
|
3250
|
-
const state = ctx.state;
|
|
3251
|
-
const scrollIndexIntoView = (options) => {
|
|
3252
|
-
if (state) {
|
|
3253
|
-
const { index, ...rest } = options;
|
|
3254
|
-
const { startNoBuffer, endNoBuffer } = state;
|
|
3255
|
-
if (index < startNoBuffer || index > endNoBuffer) {
|
|
3256
|
-
const viewPosition = index < startNoBuffer ? 0 : 1;
|
|
3257
|
-
scrollToIndex(ctx, {
|
|
3258
|
-
...rest,
|
|
3259
|
-
index,
|
|
3260
|
-
viewPosition
|
|
3261
|
-
});
|
|
3262
|
-
}
|
|
3263
|
-
}
|
|
3264
|
-
};
|
|
3265
|
-
const refScroller = state.refScroller;
|
|
3266
|
-
return {
|
|
3267
|
-
flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
|
|
3268
|
-
getNativeScrollRef: () => refScroller.current,
|
|
3269
|
-
getScrollableNode: () => refScroller.current.getScrollableNode(),
|
|
3270
|
-
getScrollResponder: () => refScroller.current.getScrollResponder(),
|
|
3271
|
-
getState: () => ({
|
|
3272
|
-
activeStickyIndex: peek$(ctx, "activeStickyIndex"),
|
|
3273
|
-
contentLength: state.totalSize,
|
|
3274
|
-
data: state.props.data,
|
|
3275
|
-
elementAtIndex: (index) => {
|
|
3276
|
-
var _a3;
|
|
3277
|
-
return (_a3 = ctx.viewRefs.get(findContainerId(ctx, getId(state, index)))) == null ? void 0 : _a3.current;
|
|
3278
|
-
},
|
|
3279
|
-
end: state.endNoBuffer,
|
|
3280
|
-
endBuffered: state.endBuffered,
|
|
3281
|
-
isAtEnd: state.isAtEnd,
|
|
3282
|
-
isAtStart: state.isAtStart,
|
|
3283
|
-
listen: (signalName, cb) => listen$(ctx, signalName, cb),
|
|
3284
|
-
listenToPosition: (key, cb) => listenPosition$(ctx, key, cb),
|
|
3285
|
-
positionAtIndex: (index) => state.positions.get(getId(state, index)),
|
|
3286
|
-
positions: state.positions,
|
|
3287
|
-
scroll: state.scroll,
|
|
3288
|
-
scrollLength: state.scrollLength,
|
|
3289
|
-
sizeAtIndex: (index) => state.sizesKnown.get(getId(state, index)),
|
|
3290
|
-
sizes: state.sizesKnown,
|
|
3291
|
-
start: state.startNoBuffer,
|
|
3292
|
-
startBuffered: state.startBuffered
|
|
3293
|
-
}),
|
|
3294
|
-
scrollIndexIntoView,
|
|
3295
|
-
scrollItemIntoView: ({ item, ...props }) => {
|
|
3296
|
-
const data = state.props.data;
|
|
3297
|
-
const index = data.indexOf(item);
|
|
3298
|
-
if (index !== -1) {
|
|
3299
|
-
scrollIndexIntoView({ index, ...props });
|
|
3300
|
-
}
|
|
3301
|
-
},
|
|
3302
|
-
scrollToEnd: (options) => {
|
|
3303
|
-
const data = state.props.data;
|
|
3304
|
-
const stylePaddingBottom = state.props.stylePaddingBottom;
|
|
3305
|
-
const index = data.length - 1;
|
|
3306
|
-
if (index !== -1) {
|
|
3307
|
-
const paddingBottom = stylePaddingBottom || 0;
|
|
3308
|
-
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
3309
|
-
scrollToIndex(ctx, {
|
|
3310
|
-
...options,
|
|
3311
|
-
index,
|
|
3312
|
-
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
3313
|
-
viewPosition: 1
|
|
3314
|
-
});
|
|
3315
|
-
}
|
|
3316
|
-
},
|
|
3317
|
-
scrollToIndex: (params) => scrollToIndex(ctx, params),
|
|
3318
|
-
scrollToItem: ({ item, ...props }) => {
|
|
3319
|
-
const data = state.props.data;
|
|
3320
|
-
const index = data.indexOf(item);
|
|
3321
|
-
if (index !== -1) {
|
|
3322
|
-
scrollToIndex(ctx, { index, ...props });
|
|
3323
|
-
}
|
|
3324
|
-
},
|
|
3325
|
-
scrollToOffset: (params) => scrollTo(ctx, params),
|
|
3326
|
-
setScrollProcessingEnabled: (enabled) => {
|
|
3327
|
-
state.scrollProcessingEnabled = enabled;
|
|
3328
|
-
},
|
|
3329
|
-
setVisibleContentAnchorOffset: (value) => {
|
|
3330
|
-
const val = isFunction(value) ? value(peek$(ctx, "scrollAdjustUserOffset") || 0) : value;
|
|
3331
|
-
set$(ctx, "scrollAdjustUserOffset", val);
|
|
3332
|
-
}
|
|
3333
|
-
};
|
|
3334
|
-
}
|
|
3335
|
-
function getRenderedItem(ctx, key) {
|
|
3336
|
-
var _a3;
|
|
3337
|
-
const state = ctx.state;
|
|
3338
|
-
if (!state) {
|
|
3339
|
-
return null;
|
|
3340
|
-
}
|
|
3341
|
-
const {
|
|
3342
|
-
indexByKey,
|
|
3343
|
-
props: { data, getItemType, renderItem }
|
|
3344
|
-
} = state;
|
|
3345
|
-
const index = indexByKey.get(key);
|
|
3346
|
-
if (index === void 0) {
|
|
3347
|
-
return null;
|
|
3348
|
-
}
|
|
3349
|
-
let renderedItem = null;
|
|
3350
|
-
const extraData = peek$(ctx, "extraData");
|
|
3351
|
-
const item = data[index];
|
|
3352
|
-
if (renderItem && !isNullOrUndefined(item)) {
|
|
3353
|
-
const itemProps = {
|
|
3354
|
-
data,
|
|
3355
|
-
extraData,
|
|
3356
|
-
index,
|
|
3357
|
-
item,
|
|
3358
|
-
type: getItemType ? (_a3 = getItemType(item, index)) != null ? _a3 : "" : ""
|
|
3359
|
-
};
|
|
3360
|
-
renderedItem = isFunction(renderItem) ? renderItem(itemProps) : React3__namespace.default.createElement(renderItem, itemProps);
|
|
3361
|
-
}
|
|
3362
|
-
return { index, item: data[index], renderedItem };
|
|
3363
|
-
}
|
|
3364
|
-
function useThrottleDebounce(mode) {
|
|
3365
|
-
const timeoutRef = React3.useRef(null);
|
|
3366
|
-
const lastCallTimeRef = React3.useRef(0);
|
|
3367
|
-
const lastArgsRef = React3.useRef(null);
|
|
3368
|
-
const clearTimeoutRef = () => {
|
|
3369
|
-
if (timeoutRef.current) {
|
|
3370
|
-
clearTimeout(timeoutRef.current);
|
|
3371
|
-
timeoutRef.current = null;
|
|
3372
|
-
}
|
|
3373
|
-
};
|
|
3374
|
-
const execute = React3.useCallback(
|
|
3375
|
-
(callback, delay, ...args) => {
|
|
3376
|
-
{
|
|
3377
|
-
const now = Date.now();
|
|
3378
|
-
lastArgsRef.current = args;
|
|
3379
|
-
if (now - lastCallTimeRef.current >= delay) {
|
|
3380
|
-
lastCallTimeRef.current = now;
|
|
3381
|
-
callback(...args);
|
|
3382
|
-
clearTimeoutRef();
|
|
3383
|
-
} else {
|
|
3384
|
-
clearTimeoutRef();
|
|
3385
|
-
timeoutRef.current = setTimeout(
|
|
3386
|
-
() => {
|
|
3387
|
-
if (lastArgsRef.current) {
|
|
3388
|
-
lastCallTimeRef.current = Date.now();
|
|
3389
|
-
callback(...lastArgsRef.current);
|
|
3390
|
-
timeoutRef.current = null;
|
|
3391
|
-
lastArgsRef.current = null;
|
|
3392
|
-
}
|
|
3393
|
-
},
|
|
3394
|
-
delay - (now - lastCallTimeRef.current)
|
|
3395
|
-
);
|
|
3396
|
-
}
|
|
3397
|
-
}
|
|
3398
|
-
},
|
|
3399
|
-
[mode]
|
|
3400
|
-
);
|
|
3401
|
-
return execute;
|
|
3402
|
-
}
|
|
3403
|
-
|
|
3404
|
-
// src/utils/throttledOnScroll.ts
|
|
3405
|
-
function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
|
|
3406
|
-
const throttle = useThrottleDebounce("throttle");
|
|
3407
|
-
return (event) => throttle(originalHandler, scrollEventThrottle, { nativeEvent: event.nativeEvent });
|
|
3408
|
-
}
|
|
3409
|
-
|
|
3410
|
-
// src/components/LegendList.tsx
|
|
3411
|
-
var DEFAULT_DRAW_DISTANCE = 250;
|
|
3412
|
-
var DEFAULT_ITEM_SIZE = 100;
|
|
3413
|
-
var LegendList = typedMemo(
|
|
3414
|
-
// biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
|
|
3415
|
-
typedForwardRef(function LegendList2(props, forwardedRef) {
|
|
3416
|
-
const { children, data: dataProp, renderItem: renderItemProp, ...restProps } = props;
|
|
3417
|
-
const isChildrenMode = children !== void 0 && dataProp === void 0;
|
|
3418
|
-
const processedProps = isChildrenMode ? {
|
|
3419
|
-
...restProps,
|
|
3420
|
-
childrenMode: true,
|
|
3421
|
-
data: (isArray(children) ? children : React3__namespace.Children.toArray(children)).flat(1),
|
|
3422
|
-
renderItem: ({ item }) => item
|
|
3423
|
-
} : {
|
|
3424
|
-
...restProps,
|
|
3425
|
-
data: dataProp || [],
|
|
3426
|
-
renderItem: renderItemProp
|
|
3427
|
-
};
|
|
3428
|
-
return /* @__PURE__ */ React3__namespace.createElement(StateProvider, null, /* @__PURE__ */ React3__namespace.createElement(LegendListInner, { ...processedProps, ref: forwardedRef }));
|
|
3429
|
-
})
|
|
3430
|
-
);
|
|
3431
|
-
var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
|
|
3432
|
-
var _a3, _b;
|
|
3433
|
-
const {
|
|
3434
|
-
alignItemsAtEnd = false,
|
|
3435
|
-
columnWrapperStyle,
|
|
3436
|
-
contentContainerStyle: contentContainerStyleProp,
|
|
3437
|
-
contentInset,
|
|
3438
|
-
data: dataProp = [],
|
|
3439
|
-
dataVersion,
|
|
3440
|
-
drawDistance = 250,
|
|
3441
|
-
estimatedItemSize: estimatedItemSizeProp,
|
|
3442
|
-
estimatedListSize,
|
|
3443
|
-
extraData,
|
|
3444
|
-
getEstimatedItemSize,
|
|
3445
|
-
getFixedItemSize,
|
|
3446
|
-
getItemType,
|
|
3447
|
-
horizontal,
|
|
3448
|
-
initialContainerPoolRatio = 2,
|
|
3449
|
-
initialScrollAtEnd = false,
|
|
3450
|
-
initialScrollIndex: initialScrollIndexProp,
|
|
3451
|
-
initialScrollOffset: initialScrollOffsetProp,
|
|
3452
|
-
itemsAreEqual,
|
|
3453
|
-
keyExtractor: keyExtractorProp,
|
|
3454
|
-
ListEmptyComponent,
|
|
3455
|
-
ListHeaderComponent,
|
|
3456
|
-
maintainScrollAtEnd = false,
|
|
3457
|
-
maintainScrollAtEndThreshold = 0.1,
|
|
3458
|
-
maintainVisibleContentPosition = false,
|
|
3459
|
-
numColumns: numColumnsProp = 1,
|
|
3460
|
-
onEndReached,
|
|
3461
|
-
onEndReachedThreshold = 0.5,
|
|
3462
|
-
onItemSizeChanged,
|
|
3463
|
-
onLayout: onLayoutProp,
|
|
3464
|
-
onLoad,
|
|
3465
|
-
onMomentumScrollEnd,
|
|
3466
|
-
onRefresh,
|
|
3467
|
-
onScroll: onScrollProp,
|
|
3468
|
-
onStartReached,
|
|
3469
|
-
onStartReachedThreshold = 0.5,
|
|
3470
|
-
onStickyHeaderChange,
|
|
3471
|
-
onViewableItemsChanged,
|
|
3472
|
-
progressViewOffset,
|
|
3473
|
-
recycleItems = false,
|
|
3474
|
-
refreshControl,
|
|
3475
|
-
refreshing,
|
|
3476
|
-
refScrollView,
|
|
3477
|
-
renderItem,
|
|
3478
|
-
scrollEventThrottle,
|
|
3479
|
-
snapToIndices,
|
|
3480
|
-
stickyHeaderIndices: stickyHeaderIndicesProp,
|
|
3481
|
-
stickyIndices: stickyIndicesDeprecated,
|
|
3482
|
-
// TODOV3: Remove from v3 release
|
|
3483
|
-
style: styleProp,
|
|
3484
|
-
suggestEstimatedItemSize,
|
|
3485
|
-
viewabilityConfig,
|
|
3486
|
-
viewabilityConfigCallbackPairs,
|
|
3487
|
-
waitForInitialLayout = true,
|
|
3488
|
-
...rest
|
|
3489
|
-
} = props;
|
|
3490
|
-
const animatedPropsInternal = props.animatedPropsInternal;
|
|
3491
|
-
const { childrenMode } = rest;
|
|
3492
|
-
const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
|
|
3493
|
-
const style = { ...StyleSheet.flatten(styleProp) };
|
|
3494
|
-
const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
|
|
3495
|
-
const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
|
|
3496
|
-
const [renderNum, setRenderNum] = React3.useState(0);
|
|
3497
|
-
const initialScrollProp = initialScrollAtEnd ? { index: Math.max(0, dataProp.length - 1), viewOffset: -stylePaddingBottomState } : initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
|
|
3498
|
-
const [canRender, setCanRender] = React3__namespace.useState(!IsNewArchitecture);
|
|
3499
|
-
const ctx = useStateContext();
|
|
3500
|
-
ctx.columnWrapperStyle = columnWrapperStyle || (contentContainerStyle ? createColumnWrapperStyle(contentContainerStyle) : void 0);
|
|
3501
|
-
const refScroller = React3.useRef(null);
|
|
3502
|
-
const combinedRef = useCombinedRef(refScroller, refScrollView);
|
|
3503
|
-
const estimatedItemSize = estimatedItemSizeProp != null ? estimatedItemSizeProp : DEFAULT_ITEM_SIZE;
|
|
3504
|
-
const scrollBuffer = (drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE) || 1;
|
|
3505
|
-
const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (_item, index) => index.toString();
|
|
3506
|
-
const stickyHeaderIndices = stickyHeaderIndicesProp != null ? stickyHeaderIndicesProp : stickyIndicesDeprecated;
|
|
3507
|
-
if (IS_DEV && stickyIndicesDeprecated && !stickyHeaderIndicesProp) {
|
|
3508
|
-
warnDevOnce(
|
|
3509
|
-
"stickyIndices",
|
|
3510
|
-
"stickyIndices has been renamed to stickyHeaderIndices. Please update your props to use stickyHeaderIndices."
|
|
3511
|
-
);
|
|
3512
|
-
}
|
|
3513
|
-
const refState = React3.useRef();
|
|
3514
|
-
if (!refState.current) {
|
|
3515
|
-
if (!ctx.state) {
|
|
3516
|
-
const initialScrollLength = (estimatedListSize != null ? estimatedListSize : { height: 0, width: 0 } )[horizontal ? "width" : "height"];
|
|
3517
|
-
ctx.state = {
|
|
3518
|
-
activeStickyIndex: -1,
|
|
3519
|
-
averageSizes: {},
|
|
3520
|
-
columns: /* @__PURE__ */ new Map(),
|
|
3521
|
-
containerItemKeys: /* @__PURE__ */ new Set(),
|
|
3522
|
-
containerItemTypes: /* @__PURE__ */ new Map(),
|
|
3523
|
-
dataChangeNeedsScrollUpdate: false,
|
|
3524
|
-
didColumnsChange: false,
|
|
3525
|
-
didDataChange: false,
|
|
3526
|
-
enableScrollForNextCalculateItemsInView: true,
|
|
3527
|
-
endBuffered: -1,
|
|
3528
|
-
endNoBuffer: -1,
|
|
3529
|
-
endReachedSnapshot: void 0,
|
|
3530
|
-
firstFullyOnScreenIndex: -1,
|
|
3531
|
-
idCache: [],
|
|
3532
|
-
idsInView: [],
|
|
3533
|
-
indexByKey: /* @__PURE__ */ new Map(),
|
|
3534
|
-
initialAnchor: (initialScrollProp == null ? void 0 : initialScrollProp.index) !== void 0 && (initialScrollProp == null ? void 0 : initialScrollProp.viewPosition) !== void 0 ? {
|
|
3535
|
-
attempts: 0,
|
|
3536
|
-
index: initialScrollProp.index,
|
|
3537
|
-
settledTicks: 0,
|
|
3538
|
-
viewOffset: (_a3 = initialScrollProp.viewOffset) != null ? _a3 : 0,
|
|
3539
|
-
viewPosition: initialScrollProp.viewPosition
|
|
3540
|
-
} : void 0,
|
|
3541
|
-
initialScroll: initialScrollProp,
|
|
3542
|
-
isAtEnd: false,
|
|
3543
|
-
isAtStart: false,
|
|
3544
|
-
isEndReached: null,
|
|
3545
|
-
isFirst: true,
|
|
3546
|
-
isStartReached: null,
|
|
3547
|
-
lastBatchingAction: Date.now(),
|
|
3548
|
-
lastLayout: void 0,
|
|
3549
|
-
loadStartTime: Date.now(),
|
|
3550
|
-
minIndexSizeChanged: 0,
|
|
3551
|
-
nativeMarginTop: 0,
|
|
3552
|
-
positions: /* @__PURE__ */ new Map(),
|
|
3553
|
-
props: {},
|
|
3554
|
-
queuedCalculateItemsInView: 0,
|
|
3555
|
-
refScroller: void 0,
|
|
3556
|
-
scroll: 0,
|
|
3557
|
-
scrollAdjustHandler: new ScrollAdjustHandler(ctx),
|
|
3558
|
-
scrollForNextCalculateItemsInView: void 0,
|
|
3559
|
-
scrollHistory: [],
|
|
3560
|
-
scrollLength: initialScrollLength,
|
|
3561
|
-
scrollPending: 0,
|
|
3562
|
-
scrollPrev: 0,
|
|
3563
|
-
scrollPrevTime: 0,
|
|
3564
|
-
scrollProcessingEnabled: true,
|
|
3565
|
-
scrollTime: 0,
|
|
3566
|
-
sizes: /* @__PURE__ */ new Map(),
|
|
3567
|
-
sizesKnown: /* @__PURE__ */ new Map(),
|
|
3568
|
-
startBuffered: -1,
|
|
3569
|
-
startNoBuffer: -1,
|
|
3570
|
-
startReachedSnapshot: void 0,
|
|
3571
|
-
stickyContainerPool: /* @__PURE__ */ new Set(),
|
|
3572
|
-
stickyContainers: /* @__PURE__ */ new Map(),
|
|
3573
|
-
timeoutSizeMessage: 0,
|
|
3574
|
-
timeouts: /* @__PURE__ */ new Set(),
|
|
3575
|
-
totalSize: 0,
|
|
3576
|
-
viewabilityConfigCallbackPairs: void 0
|
|
3577
|
-
};
|
|
3578
|
-
const internalState = ctx.state;
|
|
3579
|
-
internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
|
|
3580
|
-
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
|
|
3581
|
-
set$(ctx, "extraData", extraData);
|
|
3582
|
-
}
|
|
3583
|
-
refState.current = ctx.state;
|
|
3584
|
-
}
|
|
3585
|
-
const state = refState.current;
|
|
3586
|
-
const isFirstLocal = state.isFirst;
|
|
3587
|
-
state.didColumnsChange = numColumnsProp !== state.props.numColumns;
|
|
3588
|
-
const didDataChangeLocal = state.props.dataVersion !== dataVersion || state.props.data !== dataProp && checkActualChange(state, dataProp, state.props.data);
|
|
3589
|
-
if (didDataChangeLocal) {
|
|
3590
|
-
state.dataChangeNeedsScrollUpdate = true;
|
|
3591
|
-
state.didDataChange = true;
|
|
3592
|
-
state.previousData = state.props.data;
|
|
3593
|
-
}
|
|
3594
|
-
const throttleScrollFn = scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp;
|
|
3595
|
-
state.props = {
|
|
3596
|
-
alignItemsAtEnd,
|
|
3597
|
-
animatedProps: animatedPropsInternal,
|
|
3598
|
-
contentInset,
|
|
3599
|
-
data: dataProp,
|
|
3600
|
-
dataVersion,
|
|
3601
|
-
estimatedItemSize,
|
|
3602
|
-
getEstimatedItemSize,
|
|
3603
|
-
getFixedItemSize,
|
|
3604
|
-
getItemType,
|
|
3605
|
-
horizontal: !!horizontal,
|
|
3606
|
-
initialContainerPoolRatio,
|
|
3607
|
-
itemsAreEqual,
|
|
3608
|
-
keyExtractor,
|
|
3609
|
-
maintainScrollAtEnd,
|
|
3610
|
-
maintainScrollAtEndThreshold,
|
|
3611
|
-
maintainVisibleContentPosition,
|
|
3612
|
-
numColumns: numColumnsProp,
|
|
3613
|
-
onEndReached,
|
|
3614
|
-
onEndReachedThreshold,
|
|
3615
|
-
onItemSizeChanged,
|
|
3616
|
-
onLoad,
|
|
3617
|
-
onScroll: throttleScrollFn,
|
|
3618
|
-
onStartReached,
|
|
3619
|
-
onStartReachedThreshold,
|
|
3620
|
-
onStickyHeaderChange,
|
|
3621
|
-
recycleItems: !!recycleItems,
|
|
3622
|
-
renderItem,
|
|
3623
|
-
scrollBuffer,
|
|
3624
|
-
snapToIndices,
|
|
3625
|
-
stickyIndicesArr: stickyHeaderIndices != null ? stickyHeaderIndices : [],
|
|
3626
|
-
stickyIndicesSet: React3.useMemo(() => new Set(stickyHeaderIndices != null ? stickyHeaderIndices : []), [stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.join(",")]),
|
|
3627
|
-
stylePaddingBottom: stylePaddingBottomState,
|
|
3628
|
-
stylePaddingTop: stylePaddingTopState,
|
|
3629
|
-
suggestEstimatedItemSize: !!suggestEstimatedItemSize
|
|
3630
|
-
};
|
|
3631
|
-
state.refScroller = refScroller;
|
|
3632
|
-
const memoizedLastItemKeys = React3.useMemo(() => {
|
|
3633
|
-
if (!dataProp.length) return [];
|
|
3634
|
-
return Array.from(
|
|
3635
|
-
{ length: Math.min(numColumnsProp, dataProp.length) },
|
|
3636
|
-
(_, i) => getId(state, dataProp.length - 1 - i)
|
|
3637
|
-
);
|
|
3638
|
-
}, [dataProp, dataVersion, numColumnsProp]);
|
|
3639
|
-
const initializeStateVars = () => {
|
|
3640
|
-
set$(ctx, "lastItemKeys", memoizedLastItemKeys);
|
|
3641
|
-
set$(ctx, "numColumns", numColumnsProp);
|
|
3642
|
-
const prevPaddingTop = peek$(ctx, "stylePaddingTop");
|
|
3643
|
-
setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
|
|
3644
|
-
refState.current.props.stylePaddingBottom = stylePaddingBottomState;
|
|
3645
|
-
let paddingDiff = stylePaddingTopState - prevPaddingTop;
|
|
3646
|
-
if (paddingDiff && prevPaddingTop !== void 0 && Platform.OS === "ios") {
|
|
3647
|
-
if (state.scroll < 0) {
|
|
3648
|
-
paddingDiff += state.scroll;
|
|
3649
|
-
}
|
|
3650
|
-
requestAdjust(ctx, paddingDiff);
|
|
3651
|
-
}
|
|
3652
|
-
};
|
|
3653
|
-
if (isFirstLocal) {
|
|
3654
|
-
initializeStateVars();
|
|
3655
|
-
updateItemPositions(
|
|
3656
|
-
ctx,
|
|
3657
|
-
/*dataChanged*/
|
|
3658
|
-
true
|
|
3659
|
-
);
|
|
3660
|
-
}
|
|
3661
|
-
const initialContentOffset = React3.useMemo(() => {
|
|
3662
|
-
let value;
|
|
3663
|
-
const { initialScroll, initialAnchor } = refState.current;
|
|
3664
|
-
if (initialScroll) {
|
|
3665
|
-
if (initialScroll.contentOffset !== void 0) {
|
|
3666
|
-
value = initialScroll.contentOffset;
|
|
3667
|
-
} else {
|
|
3668
|
-
const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
|
|
3669
|
-
const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
|
|
3670
|
-
const clampedOffset = clampScrollOffset(ctx, resolvedOffset);
|
|
3671
|
-
const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
|
|
3672
|
-
refState.current.initialScroll = updatedInitialScroll;
|
|
3673
|
-
state.initialScroll = updatedInitialScroll;
|
|
3674
|
-
value = clampedOffset;
|
|
3675
|
-
}
|
|
3676
|
-
} else {
|
|
3677
|
-
refState.current.initialAnchor = void 0;
|
|
3678
|
-
value = 0;
|
|
3679
|
-
}
|
|
3680
|
-
if (!value) {
|
|
3681
|
-
state.didFinishInitialScroll = true;
|
|
3682
|
-
}
|
|
3683
|
-
return value;
|
|
3684
|
-
}, [renderNum]);
|
|
3685
|
-
if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
3686
|
-
refState.current.lastBatchingAction = Date.now();
|
|
3687
|
-
if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
|
|
3688
|
-
IS_DEV && !childrenMode && warnDevOnce(
|
|
3689
|
-
"keyExtractor",
|
|
3690
|
-
"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."
|
|
3691
|
-
);
|
|
3692
|
-
refState.current.sizes.clear();
|
|
3693
|
-
refState.current.positions.clear();
|
|
3694
|
-
refState.current.totalSize = 0;
|
|
3695
|
-
set$(ctx, "totalSize", 0);
|
|
3696
|
-
}
|
|
3697
|
-
}
|
|
3698
|
-
const onLayoutHeader = React3.useCallback((rect, fromLayoutEffect) => {
|
|
3699
|
-
const { initialScroll } = refState.current;
|
|
3700
|
-
const size = rect[horizontal ? "width" : "height"];
|
|
3701
|
-
set$(ctx, "headerSize", size);
|
|
3702
|
-
if ((initialScroll == null ? void 0 : initialScroll.index) !== void 0) {
|
|
3703
|
-
{
|
|
3704
|
-
if (fromLayoutEffect) {
|
|
3705
|
-
setRenderNum((v) => v + 1);
|
|
3706
|
-
}
|
|
3707
|
-
}
|
|
3708
|
-
}
|
|
3709
|
-
}, []);
|
|
3710
|
-
const doInitialScroll = React3.useCallback(() => {
|
|
3711
|
-
const initialScroll = state.initialScroll;
|
|
3712
|
-
if (initialScroll) {
|
|
3713
|
-
scrollTo(ctx, {
|
|
3714
|
-
animated: false,
|
|
3715
|
-
index: initialScroll == null ? void 0 : initialScroll.index,
|
|
3716
|
-
isInitialScroll: true,
|
|
3717
|
-
offset: initialContentOffset,
|
|
3718
|
-
precomputedWithViewOffset: true
|
|
3719
|
-
});
|
|
3720
|
-
}
|
|
3721
|
-
}, [initialContentOffset]);
|
|
3722
|
-
const onLayoutChange = React3.useCallback((layout) => {
|
|
3723
|
-
doInitialScroll();
|
|
3724
|
-
handleLayout(ctx, layout, setCanRender);
|
|
3725
|
-
}, []);
|
|
3726
|
-
const { onLayout } = useOnLayoutSync({
|
|
3727
|
-
onLayoutChange,
|
|
3728
|
-
onLayoutProp,
|
|
3729
|
-
ref: refScroller
|
|
3730
|
-
// the type of ScrollView doesn't include measure?
|
|
3731
|
-
});
|
|
3732
|
-
React3.useLayoutEffect(() => {
|
|
3733
|
-
if (snapToIndices) {
|
|
3734
|
-
updateSnapToOffsets(ctx);
|
|
3735
|
-
}
|
|
3736
|
-
}, [snapToIndices]);
|
|
3737
|
-
React3.useLayoutEffect(() => {
|
|
3738
|
-
const {
|
|
3739
|
-
didColumnsChange,
|
|
3740
|
-
didDataChange,
|
|
3741
|
-
isFirst,
|
|
3742
|
-
props: { data }
|
|
3743
|
-
} = state;
|
|
3744
|
-
const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx);
|
|
3745
|
-
if (!didAllocateContainers && !isFirst && (didDataChange || didColumnsChange)) {
|
|
3746
|
-
checkResetContainers(ctx, data);
|
|
3747
|
-
}
|
|
3748
|
-
state.didColumnsChange = false;
|
|
3749
|
-
state.didDataChange = false;
|
|
3750
|
-
state.isFirst = false;
|
|
3751
|
-
}, [dataProp, dataVersion, numColumnsProp]);
|
|
3752
|
-
React3.useLayoutEffect(() => {
|
|
3753
|
-
set$(ctx, "extraData", extraData);
|
|
3754
|
-
}, [extraData]);
|
|
3755
|
-
React3.useLayoutEffect(initializeStateVars, [
|
|
3756
|
-
dataVersion,
|
|
3757
|
-
memoizedLastItemKeys.join(","),
|
|
3758
|
-
numColumnsProp,
|
|
3759
|
-
stylePaddingBottomState,
|
|
3760
|
-
stylePaddingTopState
|
|
3761
|
-
]);
|
|
3762
|
-
React3.useEffect(() => {
|
|
3763
|
-
const viewability = setupViewability({
|
|
3764
|
-
onViewableItemsChanged,
|
|
3765
|
-
viewabilityConfig,
|
|
3766
|
-
viewabilityConfigCallbackPairs
|
|
3767
|
-
});
|
|
3768
|
-
state.viewabilityConfigCallbackPairs = viewability;
|
|
3769
|
-
state.enableScrollForNextCalculateItemsInView = !viewability;
|
|
3770
|
-
}, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
|
|
3771
|
-
React3.useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx), []);
|
|
3772
|
-
{
|
|
3773
|
-
React3.useEffect(doInitialScroll, []);
|
|
3774
|
-
}
|
|
3775
|
-
const fns = React3.useMemo(
|
|
3776
|
-
() => ({
|
|
3777
|
-
getRenderedItem: (key) => getRenderedItem(ctx, key),
|
|
3778
|
-
onMomentumScrollEnd: (event) => {
|
|
3779
|
-
checkFinishedScrollFallback(ctx);
|
|
3780
|
-
if (onMomentumScrollEnd) {
|
|
3781
|
-
onMomentumScrollEnd(event);
|
|
3782
|
-
}
|
|
3783
|
-
},
|
|
3784
|
-
onScroll: (event) => onScroll(ctx, event),
|
|
3785
|
-
updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, itemKey, sizeObj)
|
|
3786
|
-
}),
|
|
3787
|
-
[]
|
|
3788
|
-
);
|
|
3789
|
-
const onScrollHandler = useStickyScrollHandler(stickyHeaderIndices, horizontal, ctx, fns.onScroll);
|
|
3790
|
-
return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement(
|
|
3791
|
-
ListComponent,
|
|
3792
|
-
{
|
|
3793
|
-
...rest,
|
|
3794
|
-
alignItemsAtEnd,
|
|
3795
|
-
canRender,
|
|
3796
|
-
contentContainerStyle,
|
|
3797
|
-
contentInset,
|
|
3798
|
-
getRenderedItem: fns.getRenderedItem,
|
|
3799
|
-
horizontal,
|
|
3800
|
-
initialContentOffset,
|
|
3801
|
-
ListEmptyComponent: dataProp.length === 0 ? ListEmptyComponent : void 0,
|
|
3802
|
-
ListHeaderComponent,
|
|
3803
|
-
maintainVisibleContentPosition,
|
|
3804
|
-
onLayout,
|
|
3805
|
-
onLayoutHeader,
|
|
3806
|
-
onMomentumScrollEnd: fns.onMomentumScrollEnd,
|
|
3807
|
-
onScroll: onScrollHandler,
|
|
3808
|
-
recycleItems,
|
|
3809
|
-
refreshControl: refreshControl ? stylePaddingTopState > 0 ? React3__namespace.cloneElement(refreshControl, {
|
|
3810
|
-
progressViewOffset: (refreshControl.props.progressViewOffset || 0) + stylePaddingTopState
|
|
3811
|
-
}) : refreshControl : onRefresh && /* @__PURE__ */ React3__namespace.createElement(
|
|
3812
|
-
RefreshControl,
|
|
3813
|
-
{
|
|
3814
|
-
onRefresh,
|
|
3815
|
-
progressViewOffset: (progressViewOffset || 0) + stylePaddingTopState,
|
|
3816
|
-
refreshing: !!refreshing
|
|
3817
|
-
}
|
|
3818
|
-
),
|
|
3819
|
-
refScrollView: combinedRef,
|
|
3820
|
-
scrollAdjustHandler: (_b = refState.current) == null ? void 0 : _b.scrollAdjustHandler,
|
|
3821
|
-
scrollEventThrottle: 0,
|
|
3822
|
-
snapToIndices,
|
|
3823
|
-
stickyHeaderIndices,
|
|
3824
|
-
style,
|
|
3825
|
-
updateItemSize: fns.updateItemSize,
|
|
3826
|
-
waitForInitialLayout
|
|
3827
|
-
}
|
|
3828
|
-
), IS_DEV && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React3__namespace.createElement(DebugView, { state: refState.current }));
|
|
3829
|
-
});
|
|
3830
28
|
|
|
3831
29
|
// src/section-list/flattenSections.ts
|
|
3832
30
|
var defaultKeyExtractor = (item, index) => {
|
|
3833
|
-
var
|
|
3834
|
-
const key = (
|
|
31
|
+
var _a;
|
|
32
|
+
const key = (_a = item == null ? void 0 : item.key) != null ? _a : item == null ? void 0 : item.id;
|
|
3835
33
|
return key != null ? String(key) : String(index);
|
|
3836
34
|
};
|
|
3837
35
|
var getSectionKey = (section, sectionIndex) => {
|
|
3838
|
-
var
|
|
3839
|
-
return (
|
|
36
|
+
var _a;
|
|
37
|
+
return (_a = section.key) != null ? _a : `section-${sectionIndex}`;
|
|
3840
38
|
};
|
|
3841
39
|
function buildSectionListData({
|
|
3842
40
|
sections,
|
|
@@ -3847,14 +45,14 @@ function buildSectionListData({
|
|
|
3847
45
|
stickySectionHeadersEnabled,
|
|
3848
46
|
keyExtractor = defaultKeyExtractor
|
|
3849
47
|
}) {
|
|
3850
|
-
var
|
|
48
|
+
var _a, _b;
|
|
3851
49
|
const data = [];
|
|
3852
50
|
const sectionMeta = [];
|
|
3853
51
|
const stickyHeaderIndices = [];
|
|
3854
52
|
let absoluteItemIndex = 0;
|
|
3855
53
|
for (let sectionIndex = 0; sectionIndex < sections.length; sectionIndex++) {
|
|
3856
54
|
const section = sections[sectionIndex];
|
|
3857
|
-
const items = (
|
|
55
|
+
const items = (_a = section.data) != null ? _a : [];
|
|
3858
56
|
const meta = { items: [] };
|
|
3859
57
|
const sectionKey = getSectionKey(section, sectionIndex);
|
|
3860
58
|
const hasHeader = typeof renderSectionHeader === "function";
|
|
@@ -3925,6 +123,7 @@ function buildSectionListData({
|
|
|
3925
123
|
}
|
|
3926
124
|
|
|
3927
125
|
// src/section-list/SectionList.tsx
|
|
126
|
+
var { typedForwardRef, typedMemo } = reactNative.internal;
|
|
3928
127
|
var defaultSeparators = {
|
|
3929
128
|
highlight: () => {
|
|
3930
129
|
},
|
|
@@ -3935,11 +134,11 @@ var defaultSeparators = {
|
|
|
3935
134
|
};
|
|
3936
135
|
function resolveSeparatorComponent(component, props) {
|
|
3937
136
|
if (!component) return null;
|
|
3938
|
-
if (
|
|
137
|
+
if (React__namespace.isValidElement(component)) {
|
|
3939
138
|
return component;
|
|
3940
139
|
}
|
|
3941
140
|
const Component = component;
|
|
3942
|
-
return /* @__PURE__ */
|
|
141
|
+
return /* @__PURE__ */ React__namespace.createElement(Component, { ...props });
|
|
3943
142
|
}
|
|
3944
143
|
var SectionList = typedMemo(
|
|
3945
144
|
typedForwardRef(function SectionListInner(props, ref) {
|
|
@@ -3950,15 +149,15 @@ var SectionList = typedMemo(
|
|
|
3950
149
|
renderSectionFooter,
|
|
3951
150
|
ItemSeparatorComponent,
|
|
3952
151
|
SectionSeparatorComponent,
|
|
3953
|
-
stickySectionHeadersEnabled = reactNative.Platform.OS === "ios",
|
|
152
|
+
stickySectionHeadersEnabled = reactNative$1.Platform.OS === "ios",
|
|
3954
153
|
keyExtractor,
|
|
3955
154
|
extraData,
|
|
3956
155
|
onViewableItemsChanged,
|
|
3957
156
|
horizontal,
|
|
3958
157
|
...restProps
|
|
3959
158
|
} = props;
|
|
3960
|
-
const legendListRef =
|
|
3961
|
-
const flattened =
|
|
159
|
+
const legendListRef = React__namespace.useRef(null);
|
|
160
|
+
const flattened = React__namespace.useMemo(
|
|
3962
161
|
() => buildSectionListData({
|
|
3963
162
|
ItemSeparatorComponent,
|
|
3964
163
|
keyExtractor,
|
|
@@ -3981,11 +180,15 @@ var SectionList = typedMemo(
|
|
|
3981
180
|
]
|
|
3982
181
|
);
|
|
3983
182
|
const { data, sectionMeta, stickyHeaderIndices } = flattened;
|
|
3984
|
-
const handleViewableItemsChanged =
|
|
183
|
+
const handleViewableItemsChanged = React__namespace.useMemo(() => {
|
|
3985
184
|
if (!onViewableItemsChanged) return void 0;
|
|
3986
185
|
return ({
|
|
3987
186
|
viewableItems,
|
|
3988
|
-
changed
|
|
187
|
+
changed,
|
|
188
|
+
start,
|
|
189
|
+
end,
|
|
190
|
+
startBuffered,
|
|
191
|
+
endBuffered
|
|
3989
192
|
}) => {
|
|
3990
193
|
const mapToken = (token) => {
|
|
3991
194
|
if (token.item.kind !== "item") return null;
|
|
@@ -3999,19 +202,26 @@ var SectionList = typedMemo(
|
|
|
3999
202
|
};
|
|
4000
203
|
const mappedViewable = viewableItems.map(mapToken).filter(Boolean);
|
|
4001
204
|
const mappedChanged = changed.map(mapToken).filter(Boolean);
|
|
4002
|
-
onViewableItemsChanged({
|
|
205
|
+
onViewableItemsChanged({
|
|
206
|
+
changed: mappedChanged,
|
|
207
|
+
end,
|
|
208
|
+
endBuffered,
|
|
209
|
+
start,
|
|
210
|
+
startBuffered,
|
|
211
|
+
viewableItems: mappedViewable
|
|
212
|
+
});
|
|
4003
213
|
};
|
|
4004
214
|
}, [onViewableItemsChanged]);
|
|
4005
|
-
const renderItem =
|
|
215
|
+
const renderItem = React__namespace.useCallback(
|
|
4006
216
|
({ item }) => {
|
|
4007
|
-
var
|
|
217
|
+
var _a, _b;
|
|
4008
218
|
switch (item.kind) {
|
|
4009
219
|
case "header":
|
|
4010
220
|
return renderSectionHeader ? renderSectionHeader({ section: item.section }) : null;
|
|
4011
221
|
case "footer":
|
|
4012
222
|
return renderSectionFooter ? renderSectionFooter({ section: item.section }) : null;
|
|
4013
223
|
case "item": {
|
|
4014
|
-
const render = (
|
|
224
|
+
const render = (_a = item.section.renderItem) != null ? _a : renderItemProp;
|
|
4015
225
|
if (!render) return null;
|
|
4016
226
|
return render({
|
|
4017
227
|
index: item.itemIndex,
|
|
@@ -4050,12 +260,12 @@ var SectionList = typedMemo(
|
|
|
4050
260
|
renderSectionHeader
|
|
4051
261
|
]
|
|
4052
262
|
);
|
|
4053
|
-
const scrollToLocation =
|
|
263
|
+
const scrollToLocation = React__namespace.useCallback(
|
|
4054
264
|
({ sectionIndex, itemIndex, viewOffset, viewPosition, animated }) => {
|
|
4055
|
-
var
|
|
265
|
+
var _a, _b, _c;
|
|
4056
266
|
const meta = sectionMeta[sectionIndex];
|
|
4057
267
|
if (!meta) return;
|
|
4058
|
-
const target = itemIndex === -1 ? (_b = (
|
|
268
|
+
const target = itemIndex === -1 ? (_b = (_a = meta.header) != null ? _a : meta.items[0]) != null ? _b : meta.footer : meta.items[itemIndex];
|
|
4059
269
|
if (target === void 0) return;
|
|
4060
270
|
(_c = legendListRef.current) == null ? void 0 : _c.scrollToIndex({
|
|
4061
271
|
animated,
|
|
@@ -4066,7 +276,7 @@ var SectionList = typedMemo(
|
|
|
4066
276
|
},
|
|
4067
277
|
[sectionMeta]
|
|
4068
278
|
);
|
|
4069
|
-
|
|
279
|
+
React__namespace.useImperativeHandle(
|
|
4070
280
|
ref,
|
|
4071
281
|
() => ({
|
|
4072
282
|
...legendListRef.current,
|
|
@@ -4074,8 +284,8 @@ var SectionList = typedMemo(
|
|
|
4074
284
|
}),
|
|
4075
285
|
[scrollToLocation]
|
|
4076
286
|
);
|
|
4077
|
-
return /* @__PURE__ */
|
|
4078
|
-
LegendList,
|
|
287
|
+
return /* @__PURE__ */ React__namespace.createElement(
|
|
288
|
+
reactNative.LegendList,
|
|
4079
289
|
{
|
|
4080
290
|
...restProps,
|
|
4081
291
|
columnWrapperStyle: void 0,
|