@legendapp/list 1.0.0-beta.3 → 1.0.0-beta.30

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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React5 = require('react');
3
+ var React6 = require('react');
4
4
  var reactNative = require('react-native');
5
5
 
6
6
  function _interopNamespace(e) {
@@ -21,23 +21,24 @@ function _interopNamespace(e) {
21
21
  return Object.freeze(n);
22
22
  }
23
23
 
24
- var React5__namespace = /*#__PURE__*/_interopNamespace(React5);
24
+ var React6__namespace = /*#__PURE__*/_interopNamespace(React6);
25
25
 
26
26
  // src/LegendList.tsx
27
- var ContextState = React5__namespace.createContext(null);
27
+ var ContextState = React6__namespace.createContext(null);
28
28
  function StateProvider({ children }) {
29
- const [value] = React5__namespace.useState(() => ({
29
+ const [value] = React6__namespace.useState(() => ({
30
30
  listeners: /* @__PURE__ */ new Map(),
31
31
  values: /* @__PURE__ */ new Map(),
32
32
  mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
33
33
  mapViewabilityValues: /* @__PURE__ */ new Map(),
34
34
  mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
35
- mapViewabilityAmountValues: /* @__PURE__ */ new Map()
35
+ mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
36
+ columnWrapperStyle: void 0
36
37
  }));
37
- return /* @__PURE__ */ React5__namespace.createElement(ContextState.Provider, { value }, children);
38
+ return /* @__PURE__ */ React6__namespace.createElement(ContextState.Provider, { value }, children);
38
39
  }
39
40
  function useStateContext() {
40
- return React5__namespace.useContext(ContextState);
41
+ return React6__namespace.useContext(ContextState);
41
42
  }
42
43
  function createSelectorFunctions(ctx, signalName) {
43
44
  return {
@@ -46,9 +47,9 @@ function createSelectorFunctions(ctx, signalName) {
46
47
  };
47
48
  }
48
49
  function use$(signalName) {
49
- const ctx = React5__namespace.useContext(ContextState);
50
- const { subscribe, get } = React5__namespace.useMemo(() => createSelectorFunctions(ctx, signalName), []);
51
- const value = React5.useSyncExternalStore(subscribe, get);
50
+ const ctx = React6__namespace.useContext(ContextState);
51
+ const { subscribe, get } = React6__namespace.useMemo(() => createSelectorFunctions(ctx, signalName), []);
52
+ const value = React6.useSyncExternalStore(subscribe, get);
52
53
  return value;
53
54
  }
54
55
  function listen$(ctx, signalName, cb) {
@@ -77,9 +78,17 @@ function set$(ctx, signalName, value) {
77
78
  }
78
79
  }
79
80
  }
81
+ function getContentSize(ctx) {
82
+ const { values } = ctx;
83
+ const stylePaddingTop = values.get("stylePaddingTop") || 0;
84
+ const headerSize = values.get("headerSize") || 0;
85
+ const footerSize = values.get("footerSize") || 0;
86
+ const totalSize = values.get("totalSize") || 0;
87
+ return headerSize + footerSize + totalSize + stylePaddingTop;
88
+ }
80
89
  var symbolFirst = Symbol();
81
90
  function useInit(cb) {
82
- const refValue = React5.useRef(symbolFirst);
91
+ const refValue = React6.useRef(symbolFirst);
83
92
  if (refValue.current === symbolFirst) {
84
93
  refValue.current = cb();
85
94
  }
@@ -87,10 +96,10 @@ function useInit(cb) {
87
96
  }
88
97
 
89
98
  // src/ContextContainer.ts
90
- var ContextContainer = React5.createContext(null);
99
+ var ContextContainer = React6.createContext(null);
91
100
  function useViewability(configId, callback) {
92
101
  const ctx = useStateContext();
93
- const { containerId } = React5.useContext(ContextContainer);
102
+ const { containerId } = React6.useContext(ContextContainer);
94
103
  const key = containerId + configId;
95
104
  useInit(() => {
96
105
  const value = ctx.mapViewabilityValues.get(key);
@@ -99,7 +108,7 @@ function useViewability(configId, callback) {
99
108
  }
100
109
  });
101
110
  ctx.mapViewabilityCallbacks.set(key, callback);
102
- React5.useEffect(
111
+ React6.useEffect(
103
112
  () => () => {
104
113
  ctx.mapViewabilityCallbacks.delete(key);
105
114
  },
@@ -108,7 +117,7 @@ function useViewability(configId, callback) {
108
117
  }
109
118
  function useViewabilityAmount(callback) {
110
119
  const ctx = useStateContext();
111
- const { containerId } = React5.useContext(ContextContainer);
120
+ const { containerId } = React6.useContext(ContextContainer);
112
121
  useInit(() => {
113
122
  const value = ctx.mapViewabilityAmountValues.get(containerId);
114
123
  if (value) {
@@ -116,7 +125,7 @@ function useViewabilityAmount(callback) {
116
125
  }
117
126
  });
118
127
  ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
119
- React5.useEffect(
128
+ React6.useEffect(
120
129
  () => () => {
121
130
  ctx.mapViewabilityAmountCallbacks.delete(containerId);
122
131
  },
@@ -124,12 +133,12 @@ function useViewabilityAmount(callback) {
124
133
  );
125
134
  }
126
135
  function useRecyclingEffect(effect) {
127
- const { index, value } = React5.useContext(ContextContainer);
128
- const prevValues = React5.useRef({
136
+ const { index, value } = React6.useContext(ContextContainer);
137
+ const prevValues = React6.useRef({
129
138
  prevIndex: void 0,
130
139
  prevItem: void 0
131
140
  });
132
- React5.useEffect(() => {
141
+ React6.useEffect(() => {
133
142
  let ret = void 0;
134
143
  if (prevValues.current.prevIndex !== void 0 && prevValues.current.prevItem !== void 0) {
135
144
  ret = effect({
@@ -147,8 +156,8 @@ function useRecyclingEffect(effect) {
147
156
  }, [index, value]);
148
157
  }
149
158
  function useRecyclingState(valueOrFun) {
150
- const { index, value } = React5.useContext(ContextContainer);
151
- const stateInfo = React5.useState(
159
+ const { index, value } = React6.useContext(ContextContainer);
160
+ const stateInfo = React6.useState(
152
161
  () => typeof valueOrFun === "function" ? valueOrFun({
153
162
  index,
154
163
  item: value,
@@ -162,10 +171,61 @@ function useRecyclingState(valueOrFun) {
162
171
  });
163
172
  return stateInfo;
164
173
  }
165
- var LeanView = React5__namespace.forwardRef((props, ref) => {
166
- return React5__namespace.createElement("RCTView", { ...props, ref });
174
+ var DebugRow = ({ children }) => {
175
+ return /* @__PURE__ */ React.createElement(reactNative.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" } }, children);
176
+ };
177
+ var DebugView = React6.memo(function DebugView2({ state }) {
178
+ const ctx = useStateContext();
179
+ const totalSize = use$("totalSize") || 0;
180
+ const totalSizeWithScrollAdjust = use$("totalSizeWithScrollAdjust") || 0;
181
+ const scrollAdjust = use$("scrollAdjust") || 0;
182
+ const rawScroll = use$("debugRawScroll") || 0;
183
+ const scroll = use$("debugComputedScroll") || 0;
184
+ const contentSize = getContentSize(ctx);
185
+ const [, forceUpdate] = React6.useReducer((x) => x + 1, 0);
186
+ use$("numContainers");
187
+ use$("numContainersPooled");
188
+ useInterval(() => {
189
+ forceUpdate();
190
+ }, 100);
191
+ return /* @__PURE__ */ React.createElement(
192
+ reactNative.View,
193
+ {
194
+ style: {
195
+ position: "absolute",
196
+ top: 0,
197
+ right: 0,
198
+ paddingLeft: 4,
199
+ paddingBottom: 4,
200
+ // height: 100,
201
+ backgroundColor: "#FFFFFFCC",
202
+ padding: 4,
203
+ borderRadius: 4
204
+ },
205
+ pointerEvents: "none"
206
+ },
207
+ /* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(reactNative.Text, null, "TotalSize:"), /* @__PURE__ */ React.createElement(reactNative.Text, null, totalSize.toFixed(2))),
208
+ /* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(reactNative.Text, null, "ContentSize:"), /* @__PURE__ */ React.createElement(reactNative.Text, null, contentSize.toFixed(2))),
209
+ /* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(reactNative.Text, null, "At end:"), /* @__PURE__ */ React.createElement(reactNative.Text, null, String(state.isAtBottom))),
210
+ /* @__PURE__ */ React.createElement(reactNative.Text, null),
211
+ /* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(reactNative.Text, null, "ScrollAdjust:"), /* @__PURE__ */ React.createElement(reactNative.Text, null, scrollAdjust.toFixed(2))),
212
+ /* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(reactNative.Text, null, "TotalSizeReal: "), /* @__PURE__ */ React.createElement(reactNative.Text, null, totalSizeWithScrollAdjust.toFixed(2))),
213
+ /* @__PURE__ */ React.createElement(reactNative.Text, null),
214
+ /* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(reactNative.Text, null, "RawScroll: "), /* @__PURE__ */ React.createElement(reactNative.Text, null, rawScroll.toFixed(2))),
215
+ /* @__PURE__ */ React.createElement(DebugRow, null, /* @__PURE__ */ React.createElement(reactNative.Text, null, "ComputedScroll: "), /* @__PURE__ */ React.createElement(reactNative.Text, null, scroll.toFixed(2)))
216
+ );
217
+ });
218
+ function useInterval(callback, delay) {
219
+ React6.useEffect(() => {
220
+ const interval = setInterval(callback, delay);
221
+ return () => clearInterval(interval);
222
+ }, [delay]);
223
+ }
224
+ var LeanViewComponent = React6__namespace.forwardRef((props, ref) => {
225
+ return React6__namespace.createElement("RCTView", { ...props, ref });
167
226
  });
168
- LeanView.displayName = "RCTView";
227
+ LeanViewComponent.displayName = "RCTView";
228
+ var LeanView = reactNative.Platform.OS === "android" || reactNative.Platform.OS === "ios" ? LeanViewComponent : reactNative.View;
169
229
 
170
230
  // src/constants.ts
171
231
  var POSITION_OUT_OF_VIEW = -1e7;
@@ -174,8 +234,11 @@ var ANCHORED_POSITION_OUT_OF_VIEW = {
174
234
  relativeCoordinate: POSITION_OUT_OF_VIEW,
175
235
  top: POSITION_OUT_OF_VIEW
176
236
  };
237
+ var ENABLE_DEVMODE = __DEV__ && false;
238
+ var ENABLE_DEBUG_VIEW = __DEV__ && false;
177
239
 
178
240
  // src/Container.tsx
241
+ var isNewArchitecture = global.nativeFabricUIManager != null;
179
242
  var Container = ({
180
243
  id,
181
244
  recycleItems,
@@ -185,12 +248,26 @@ var Container = ({
185
248
  ItemSeparatorComponent
186
249
  }) => {
187
250
  const ctx = useStateContext();
251
+ const columnWrapperStyle = ctx.columnWrapperStyle;
188
252
  const maintainVisibleContentPosition = use$("maintainVisibleContentPosition");
189
253
  const position = use$(`containerPosition${id}`) || ANCHORED_POSITION_OUT_OF_VIEW;
190
254
  const column = use$(`containerColumn${id}`) || 0;
191
255
  const numColumns = use$("numColumns");
256
+ const lastItemKeys = use$("lastItemKeys");
257
+ const itemKey = use$(`containerItemKey${id}`);
258
+ const data = use$(`containerItemData${id}`);
259
+ const extraData = use$("extraData");
260
+ const refLastSize = React6.useRef();
192
261
  const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
193
262
  const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
263
+ let verticalPaddingStyles;
264
+ if (columnWrapperStyle && !horizontal && numColumns > 1) {
265
+ const { columnGap, rowGap, gap } = columnWrapperStyle;
266
+ verticalPaddingStyles = {
267
+ paddingBottom: !lastItemKeys.has(itemKey) ? rowGap || gap || void 0 : void 0,
268
+ paddingHorizontal: (columnGap || gap || 0) / 2
269
+ };
270
+ }
194
271
  const style = horizontal ? {
195
272
  flexDirection: ItemSeparatorComponent ? "row" : void 0,
196
273
  position: "absolute",
@@ -203,76 +280,96 @@ var Container = ({
203
280
  left: otherAxisPos,
204
281
  right: numColumns > 1 ? null : 0,
205
282
  width: otherAxisSize,
206
- top: position.relativeCoordinate
283
+ top: position.relativeCoordinate,
284
+ ...verticalPaddingStyles || {}
207
285
  };
208
- const lastItemKey = use$("lastItemKey");
209
- const itemKey = use$(`containerItemKey${id}`);
210
- const data = use$(`containerItemData${id}`);
211
- const extraData = use$("extraData");
212
- const refLastSize = React5.useRef();
213
- const renderedItemInfo = React5.useMemo(
214
- () => itemKey !== void 0 && getRenderedItem(itemKey),
286
+ const renderedItemInfo = React6.useMemo(
287
+ () => itemKey !== void 0 ? getRenderedItem(itemKey) : null,
215
288
  [itemKey, data, extraData]
216
289
  );
217
290
  const { index, renderedItem } = renderedItemInfo || {};
218
- React5.useEffect(() => {
219
- if (itemKey) {
220
- const timeout = setTimeout(() => {
221
- if (refLastSize.current) {
222
- updateItemSize(id, itemKey, refLastSize.current);
223
- }
224
- }, 16);
225
- return () => {
226
- clearTimeout(timeout);
227
- };
228
- }
229
- }, [itemKey]);
230
291
  const onLayout = (event) => {
231
- const key = peek$(ctx, `containerItemKey${id}`);
232
- if (key !== void 0) {
233
- const size = Math.floor(event.nativeEvent.layout[horizontal ? "width" : "height"] * 8) / 8;
234
- updateItemSize(id, key, size);
292
+ if (itemKey !== void 0) {
293
+ const layout = event.nativeEvent.layout;
294
+ const size = Math.floor(layout[horizontal ? "width" : "height"] * 8) / 8;
295
+ refLastSize.current = size;
296
+ updateItemSize(itemKey, size);
235
297
  }
236
298
  };
237
- const ref = React5.useRef(null);
238
- React5.useLayoutEffect(() => {
239
- var _a, _b;
240
- if (itemKey) {
241
- const measured = (_b = (_a = ref.current) == null ? void 0 : _a.unstable_getBoundingClientRect) == null ? void 0 : _b.call(_a);
242
- if (measured) {
243
- const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
244
- if (size) {
245
- updateItemSize(id, itemKey, size);
299
+ const ref = React6.useRef(null);
300
+ if (isNewArchitecture) {
301
+ React6.useLayoutEffect(() => {
302
+ var _a, _b;
303
+ if (itemKey !== void 0) {
304
+ const measured = (_b = (_a = ref.current) == null ? void 0 : _a.unstable_getBoundingClientRect) == null ? void 0 : _b.call(_a);
305
+ if (measured) {
306
+ const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
307
+ if (size) {
308
+ updateItemSize(itemKey, size);
309
+ }
246
310
  }
247
311
  }
248
- }
249
- }, [itemKey]);
250
- const contextValue = React5.useMemo(
312
+ }, [itemKey]);
313
+ } else {
314
+ React6.useEffect(() => {
315
+ if (itemKey) {
316
+ const timeout = setTimeout(() => {
317
+ if (refLastSize.current) {
318
+ updateItemSize(itemKey, refLastSize.current);
319
+ }
320
+ }, 16);
321
+ return () => {
322
+ clearTimeout(timeout);
323
+ };
324
+ }
325
+ }, [itemKey]);
326
+ }
327
+ const contextValue = React6.useMemo(
251
328
  () => ({ containerId: id, itemKey, index, value: data }),
252
329
  [id, itemKey, index, data]
253
330
  );
254
- const contentFragment = /* @__PURE__ */ React5__namespace.default.createElement(React5__namespace.default.Fragment, { key: recycleItems ? void 0 : itemKey }, /* @__PURE__ */ React5__namespace.default.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItem && ItemSeparatorComponent && itemKey !== lastItemKey && ItemSeparatorComponent));
331
+ const contentFragment = /* @__PURE__ */ React6__namespace.default.createElement(React6__namespace.default.Fragment, { key: recycleItems ? void 0 : itemKey }, /* @__PURE__ */ React6__namespace.default.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && !lastItemKeys.has(itemKey) && /* @__PURE__ */ React6__namespace.default.createElement(ItemSeparatorComponent, { leadingItem: renderedItemInfo.item })));
255
332
  if (maintainVisibleContentPosition) {
256
333
  const anchorStyle = position.type === "top" ? { position: "absolute", top: 0, left: 0, right: 0 } : { position: "absolute", bottom: 0, left: 0, right: 0 };
257
- return /* @__PURE__ */ React5__namespace.default.createElement(LeanView, { style, ref }, /* @__PURE__ */ React5__namespace.default.createElement(LeanView, { style: anchorStyle, onLayout }, contentFragment));
334
+ if (ENABLE_DEVMODE) {
335
+ anchorStyle.borderColor = position.type === "top" ? "red" : "blue";
336
+ anchorStyle.borderWidth = 1;
337
+ }
338
+ return /* @__PURE__ */ React6__namespace.default.createElement(LeanView, { style }, /* @__PURE__ */ React6__namespace.default.createElement(LeanView, { style: anchorStyle, onLayout, ref }, contentFragment, ENABLE_DEVMODE && /* @__PURE__ */ React6__namespace.default.createElement(reactNative.Text, { style: { position: "absolute", top: 0, left: 0, zIndex: 1e3 } }, position.top)));
258
339
  }
259
- return /* @__PURE__ */ React5__namespace.default.createElement(LeanView, { style, onLayout, ref }, contentFragment);
340
+ return /* @__PURE__ */ React6__namespace.default.createElement(LeanView, { style, onLayout, ref }, contentFragment);
260
341
  };
261
- var useAnimatedValue = reactNative.useAnimatedValue || ((initialValue) => {
262
- return React5.useRef(new reactNative.Animated.Value(initialValue)).current;
263
- });
264
- function useValue$(key, getValue, key2) {
342
+ var typedForwardRef = React6.forwardRef;
343
+ var typedMemo = React6.memo;
344
+ var useAnimatedValue = (initialValue) => {
345
+ return React6.useRef(new reactNative.Animated.Value(initialValue)).current;
346
+ };
347
+
348
+ // src/useValue$.ts
349
+ function useValue$(key, getValue, useMicrotask) {
265
350
  var _a;
266
351
  const ctx = useStateContext();
267
352
  const animValue = useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
268
- React5.useMemo(() => {
269
- listen$(ctx, key, (v) => animValue.setValue(getValue ? getValue(v) : v));
353
+ React6.useMemo(() => {
354
+ let newValue = void 0;
355
+ listen$(ctx, key, (v) => {
356
+ if (useMicrotask && newValue === void 0) {
357
+ queueMicrotask(() => {
358
+ animValue.setValue(newValue);
359
+ newValue = void 0;
360
+ });
361
+ }
362
+ newValue = getValue ? getValue(v) : v;
363
+ if (!useMicrotask) {
364
+ animValue.setValue(newValue);
365
+ }
366
+ });
270
367
  }, []);
271
368
  return animValue;
272
369
  }
273
370
 
274
371
  // src/Containers.tsx
275
- var Containers = React5__namespace.memo(function Containers2({
372
+ var Containers = typedMemo(function Containers2({
276
373
  horizontal,
277
374
  recycleItems,
278
375
  ItemSeparatorComponent,
@@ -280,13 +377,21 @@ var Containers = React5__namespace.memo(function Containers2({
280
377
  updateItemSize,
281
378
  getRenderedItem
282
379
  }) {
380
+ const ctx = useStateContext();
381
+ const columnWrapperStyle = ctx.columnWrapperStyle;
382
+ const numColumns = use$("numColumns");
283
383
  const numContainers = use$("numContainersPooled");
284
- const animSize = useValue$("totalSize");
384
+ const animSize = useValue$(
385
+ "totalSizeWithScrollAdjust",
386
+ void 0,
387
+ /*useMicrotask*/
388
+ true
389
+ );
285
390
  const animOpacity = waitForInitialLayout ? useValue$("containersDidLayout", (value) => value ? 1 : 0) : void 0;
286
391
  const containers = [];
287
392
  for (let i = 0; i < numContainers; i++) {
288
393
  containers.push(
289
- /* @__PURE__ */ React5__namespace.createElement(
394
+ /* @__PURE__ */ React6__namespace.createElement(
290
395
  Container,
291
396
  {
292
397
  id: i,
@@ -301,20 +406,78 @@ var Containers = React5__namespace.memo(function Containers2({
301
406
  );
302
407
  }
303
408
  const style = horizontal ? { width: animSize, opacity: animOpacity } : { height: animSize, opacity: animOpacity };
304
- return /* @__PURE__ */ React5__namespace.createElement(reactNative.Animated.View, { style }, containers);
409
+ if (columnWrapperStyle && !horizontal && numColumns > 1) {
410
+ const { columnGap, rowGap, gap } = columnWrapperStyle;
411
+ const mx = (columnGap || gap || 0) / 2;
412
+ if (mx) {
413
+ style.marginHorizontal = -mx;
414
+ }
415
+ }
416
+ return /* @__PURE__ */ React6__namespace.createElement(reactNative.Animated.View, { style }, containers);
305
417
  });
306
418
 
307
419
  // src/ListComponent.tsx
308
420
  var getComponent = (Component) => {
309
- if (React5__namespace.isValidElement(Component)) {
421
+ if (React6__namespace.isValidElement(Component)) {
310
422
  return Component;
311
423
  }
312
424
  if (Component) {
313
- return /* @__PURE__ */ React5__namespace.createElement(Component, null);
425
+ return /* @__PURE__ */ React6__namespace.createElement(Component, null);
314
426
  }
315
427
  return null;
316
428
  };
317
- var ListComponent = React5__namespace.memo(function ListComponent2({
429
+ var PaddingAndAdjust = () => {
430
+ const animPaddingTop = useValue$("paddingTop", (v) => v, true);
431
+ const animScrollAdjust = useValue$("scrollAdjust", (v) => v, true);
432
+ const additionalSize = { marginTop: animScrollAdjust, paddingTop: animPaddingTop };
433
+ return /* @__PURE__ */ React6__namespace.createElement(reactNative.Animated.View, { style: additionalSize });
434
+ };
435
+ var PaddingAndAdjustDevMode = () => {
436
+ const animPaddingTop = useValue$("paddingTop", (v) => v, true);
437
+ const animScrollAdjust = useValue$("scrollAdjust", (v) => v, true);
438
+ return /* @__PURE__ */ React6__namespace.createElement(React6__namespace.Fragment, null, /* @__PURE__ */ React6__namespace.createElement(reactNative.Animated.View, { style: { marginTop: animScrollAdjust } }), /* @__PURE__ */ React6__namespace.createElement(reactNative.Animated.View, { style: { paddingTop: animPaddingTop } }), /* @__PURE__ */ React6__namespace.createElement(
439
+ reactNative.Animated.View,
440
+ {
441
+ style: {
442
+ position: "absolute",
443
+ top: reactNative.Animated.add(animScrollAdjust, reactNative.Animated.multiply(animScrollAdjust, -1)),
444
+ height: animPaddingTop,
445
+ left: 0,
446
+ right: 0,
447
+ backgroundColor: "green"
448
+ }
449
+ }
450
+ ), /* @__PURE__ */ React6__namespace.createElement(
451
+ reactNative.Animated.View,
452
+ {
453
+ style: {
454
+ position: "absolute",
455
+ top: animPaddingTop,
456
+ height: animScrollAdjust,
457
+ left: -16,
458
+ right: -16,
459
+ backgroundColor: "lightblue"
460
+ }
461
+ }
462
+ ), /* @__PURE__ */ React6__namespace.createElement(
463
+ reactNative.Animated.View,
464
+ {
465
+ style: {
466
+ position: "absolute",
467
+ top: animPaddingTop,
468
+ height: reactNative.Animated.multiply(animScrollAdjust, -1),
469
+ width: 8,
470
+ right: 4,
471
+ borderStyle: "dashed",
472
+ borderColor: "blue",
473
+ borderWidth: 1,
474
+ backgroundColor: "lightblue"
475
+ //backgroundColor: "blue",
476
+ }
477
+ }
478
+ ));
479
+ };
480
+ var ListComponent = typedMemo(function ListComponent2({
318
481
  style,
319
482
  contentContainerStyle,
320
483
  horizontal,
@@ -330,28 +493,27 @@ var ListComponent = React5__namespace.memo(function ListComponent2({
330
493
  ListFooterComponent,
331
494
  ListFooterComponentStyle,
332
495
  ListEmptyComponent,
333
- ListEmptyComponentStyle,
334
496
  getRenderedItem,
335
497
  updateItemSize,
336
498
  refScrollView,
337
499
  maintainVisibleContentPosition,
338
500
  renderScrollComponent,
501
+ onRefresh,
502
+ refreshing,
503
+ progressViewOffset,
339
504
  ...rest
340
505
  }) {
341
506
  const ctx = useStateContext();
342
- const animPaddingTop = useValue$("paddingTop");
343
- const animScrollAdjust = useValue$("scrollAdjust");
344
- const ScrollComponent = renderScrollComponent ? React5.useMemo(
345
- () => React5__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
507
+ const ScrollComponent = renderScrollComponent ? React6.useMemo(
508
+ () => React6__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
346
509
  [renderScrollComponent]
347
510
  ) : reactNative.ScrollView;
348
- const additionalSize = { marginTop: animScrollAdjust, paddingTop: animPaddingTop };
349
- return /* @__PURE__ */ React5__namespace.createElement(
511
+ return /* @__PURE__ */ React6__namespace.createElement(
350
512
  ScrollComponent,
351
513
  {
352
514
  ...rest,
353
515
  style,
354
- maintainVisibleContentPosition: maintainVisibleContentPosition ? { minIndexForVisible: 0 } : void 0,
516
+ maintainVisibleContentPosition: maintainVisibleContentPosition && !ListEmptyComponent ? { minIndexForVisible: 0 } : void 0,
355
517
  contentContainerStyle: [
356
518
  contentContainerStyle,
357
519
  horizontal ? {
@@ -364,34 +526,41 @@ var ListComponent = React5__namespace.memo(function ListComponent2({
364
526
  contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
365
527
  ref: refScrollView
366
528
  },
367
- /* @__PURE__ */ React5__namespace.createElement(reactNative.Animated.View, { style: additionalSize }),
368
- ListHeaderComponent && /* @__PURE__ */ React5__namespace.createElement(
369
- reactNative.Animated.View,
529
+ ENABLE_DEVMODE ? /* @__PURE__ */ React6__namespace.createElement(PaddingAndAdjustDevMode, null) : /* @__PURE__ */ React6__namespace.createElement(PaddingAndAdjust, null),
530
+ ListHeaderComponent && /* @__PURE__ */ React6__namespace.createElement(
531
+ reactNative.View,
370
532
  {
371
533
  style: ListHeaderComponentStyle,
372
534
  onLayout: (event) => {
373
535
  const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
374
- const prevSize = peek$(ctx, "headerSize") || 0;
375
- if (size !== prevSize) {
376
- set$(ctx, "headerSize", size);
377
- }
536
+ set$(ctx, "headerSize", size);
378
537
  }
379
538
  },
380
539
  getComponent(ListHeaderComponent)
381
540
  ),
382
- ListEmptyComponent && /* @__PURE__ */ React5__namespace.createElement(reactNative.Animated.View, { style: ListEmptyComponentStyle }, getComponent(ListEmptyComponent)),
383
- /* @__PURE__ */ React5__namespace.createElement(
541
+ ListEmptyComponent && getComponent(ListEmptyComponent),
542
+ /* @__PURE__ */ React6__namespace.createElement(
384
543
  Containers,
385
544
  {
386
545
  horizontal,
387
546
  recycleItems,
388
547
  waitForInitialLayout,
389
548
  getRenderedItem,
390
- ItemSeparatorComponent: ItemSeparatorComponent && getComponent(ItemSeparatorComponent),
549
+ ItemSeparatorComponent,
391
550
  updateItemSize
392
551
  }
393
552
  ),
394
- ListFooterComponent && /* @__PURE__ */ React5__namespace.createElement(reactNative.View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
553
+ ListFooterComponent && /* @__PURE__ */ React6__namespace.createElement(
554
+ reactNative.View,
555
+ {
556
+ style: ListFooterComponentStyle,
557
+ onLayout: (event) => {
558
+ const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
559
+ set$(ctx, "footerSize", size);
560
+ }
561
+ },
562
+ getComponent(ListFooterComponent)
563
+ )
395
564
  );
396
565
  });
397
566
 
@@ -400,36 +569,63 @@ var ScrollAdjustHandler = class {
400
569
  constructor(ctx) {
401
570
  this.ctx = ctx;
402
571
  this.appliedAdjust = 0;
403
- this.pendingAdjust = 0;
404
572
  this.busy = false;
405
- this.firstAdjust = true;
573
+ this.isPaused = false;
574
+ this.isDisabled = false;
406
575
  this.context = ctx;
407
576
  }
577
+ doAjdust() {
578
+ set$(this.context, "scrollAdjust", this.appliedAdjust);
579
+ this.busy = false;
580
+ }
408
581
  requestAdjust(adjust, onAdjusted) {
582
+ if (this.isDisabled) {
583
+ return;
584
+ }
409
585
  const oldAdjustTop = peek$(this.context, "scrollAdjust");
410
586
  if (oldAdjustTop === adjust) {
411
587
  return;
412
588
  }
413
589
  this.appliedAdjust = adjust;
414
- this.pendingAdjust = adjust;
415
- const doAjdust = () => {
416
- set$(this.context, "scrollAdjust", this.pendingAdjust);
417
- onAdjusted(oldAdjustTop - this.pendingAdjust);
418
- this.busy = false;
419
- };
420
- if (!this.busy) {
590
+ if (!this.busy && !this.isPaused) {
421
591
  this.busy = true;
422
- if (this.firstAdjust) {
423
- this.firstAdjust = false;
424
- setTimeout(doAjdust, 50);
425
- } else {
426
- doAjdust();
427
- }
592
+ this.doAjdust();
593
+ onAdjusted(oldAdjustTop - adjust);
428
594
  }
429
595
  }
430
596
  getAppliedAdjust() {
431
597
  return this.appliedAdjust;
432
598
  }
599
+ pauseAdjust() {
600
+ this.isPaused = true;
601
+ }
602
+ setDisableAdjust(disable) {
603
+ this.isDisabled = disable;
604
+ }
605
+ // return true if it was paused
606
+ unPauseAdjust() {
607
+ if (this.isPaused) {
608
+ this.isPaused = false;
609
+ this.doAjdust();
610
+ return true;
611
+ }
612
+ return false;
613
+ }
614
+ };
615
+ var useCombinedRef = (...refs) => {
616
+ const callback = React6.useCallback((element) => {
617
+ for (const ref of refs) {
618
+ if (!ref) {
619
+ continue;
620
+ }
621
+ if (typeof ref === "function") {
622
+ ref(element);
623
+ } else {
624
+ ref.current = element;
625
+ }
626
+ }
627
+ }, refs);
628
+ return callback;
433
629
  };
434
630
 
435
631
  // src/viewability.ts
@@ -528,11 +724,13 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
528
724
  }
529
725
  }
530
726
  function isViewable(state, ctx, viewabilityConfig, key, scrollSize, item, index) {
531
- const { sizes, positions, scroll } = state;
727
+ const { sizes, positions, scroll: scrollState, scrollAdjustHandler } = state;
532
728
  const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
533
729
  const { itemVisiblePercentThreshold, viewAreaCoveragePercentThreshold } = viewabilityConfig;
534
730
  const viewAreaMode = viewAreaCoveragePercentThreshold != null;
535
731
  const viewablePercentThreshold = viewAreaMode ? viewAreaCoveragePercentThreshold : itemVisiblePercentThreshold;
732
+ const previousScrollAdjust = scrollAdjustHandler.getAppliedAdjust();
733
+ const scroll = scrollState - previousScrollAdjust - topPad;
536
734
  const top = positions.get(key) - scroll + topPad;
537
735
  const size = sizes.get(key) || 0;
538
736
  const bottom = top + size;
@@ -582,13 +780,13 @@ function maybeUpdateViewabilityCallback(ctx, configId, viewToken) {
582
780
  // src/LegendList.tsx
583
781
  var DEFAULT_DRAW_DISTANCE = 250;
584
782
  var DEFAULT_ITEM_SIZE = 100;
585
- var LegendList = React5.forwardRef(function LegendList2(props, forwardedRef) {
586
- return /* @__PURE__ */ React5__namespace.createElement(StateProvider, null, /* @__PURE__ */ React5__namespace.createElement(LegendListInner, { ...props, ref: forwardedRef }));
783
+ var LegendList = typedForwardRef(function LegendList2(props, forwardedRef) {
784
+ return /* @__PURE__ */ React6__namespace.createElement(StateProvider, null, /* @__PURE__ */ React6__namespace.createElement(LegendListInner, { ...props, ref: forwardedRef }));
587
785
  });
588
- var LegendListInner = React5.forwardRef(function LegendListInner2(props, forwardedRef) {
589
- var _a, _b, _c, _d, _e;
786
+ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
787
+ var _a, _b, _c, _d;
590
788
  const {
591
- data,
789
+ data: dataProp,
592
790
  initialScrollIndex,
593
791
  initialScrollOffset,
594
792
  horizontal,
@@ -601,52 +799,77 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
601
799
  alignItemsAtEnd = false,
602
800
  maintainVisibleContentPosition = false,
603
801
  onScroll: onScrollProp,
802
+ onMomentumScrollEnd,
604
803
  numColumns: numColumnsProp = 1,
804
+ columnWrapperStyle,
605
805
  keyExtractor: keyExtractorProp,
606
806
  renderItem,
607
807
  estimatedItemSize,
608
808
  getEstimatedItemSize,
609
- onEndReached,
610
- onStartReached,
611
809
  ListEmptyComponent,
612
810
  onItemSizeChanged,
613
811
  scrollEventThrottle,
614
812
  refScrollView,
615
813
  waitForInitialLayout = true,
616
814
  extraData,
815
+ onLayout: onLayoutProp,
816
+ onRefresh,
817
+ refreshing,
818
+ progressViewOffset,
819
+ refreshControl,
820
+ initialContainerPoolRatio = 2,
821
+ viewabilityConfig,
822
+ viewabilityConfigCallbackPairs,
823
+ onViewableItemsChanged,
617
824
  ...rest
618
825
  } = props;
619
826
  const { style, contentContainerStyle } = props;
827
+ const callbacks = React6.useRef({
828
+ onStartReached: rest.onStartReached,
829
+ onEndReached: rest.onEndReached
830
+ });
831
+ callbacks.current.onStartReached = rest.onStartReached;
832
+ callbacks.current.onEndReached = rest.onEndReached;
620
833
  const ctx = useStateContext();
621
- const refScroller = React5.useRef(null);
622
- const scrollBuffer = drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE;
834
+ ctx.columnWrapperStyle = columnWrapperStyle;
835
+ const refScroller = React6.useRef(null);
836
+ const combinedRef = useCombinedRef(refScroller, refScrollView);
837
+ const scrollBuffer = (drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE) || 1;
623
838
  const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (item, index) => index.toString();
624
- const refState = React5.useRef();
839
+ const refState = React6.useRef();
625
840
  const getId = (index) => {
626
841
  var _a2;
627
- const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
628
- if (!data2) {
842
+ const data = (_a2 = refState.current) == null ? void 0 : _a2.data;
843
+ if (!data) {
629
844
  return "";
630
845
  }
631
- const ret = index < data2.length ? keyExtractor ? keyExtractor(data2[index], index) : index : null;
846
+ const ret = index < data.length ? keyExtractor ? keyExtractor(data[index], index) : index : null;
632
847
  return `${ret}`;
633
848
  };
634
- const getItemSize = (key, index, data2) => {
849
+ const getItemSize = (key, index, data) => {
635
850
  var _a2;
636
851
  const sizeKnown = refState.current.sizes.get(key);
637
852
  if (sizeKnown !== void 0) {
638
853
  return sizeKnown;
639
854
  }
640
- const size = (_a2 = getEstimatedItemSize ? getEstimatedItemSize(index, data2) : estimatedItemSize) != null ? _a2 : DEFAULT_ITEM_SIZE;
855
+ const size = (_a2 = getEstimatedItemSize ? getEstimatedItemSize(index, data) : estimatedItemSize) != null ? _a2 : DEFAULT_ITEM_SIZE;
641
856
  refState.current.sizes.set(key, size);
642
857
  return size;
643
858
  };
644
- const calculateInitialOffset = (index = initialScrollIndex) => {
859
+ const calculateOffsetForIndex = (index = initialScrollIndex) => {
860
+ const data = dataProp;
645
861
  if (index) {
646
862
  let offset = 0;
647
- if (getEstimatedItemSize) {
863
+ const canGetSize = !!refState.current;
864
+ if (canGetSize || getEstimatedItemSize) {
865
+ const sizeFn = (index2) => {
866
+ if (canGetSize) {
867
+ return getItemSize(getId(index2), index2, data[index2]);
868
+ }
869
+ return getEstimatedItemSize(index2, data[index2]);
870
+ };
648
871
  for (let i = 0; i < index; i++) {
649
- offset += getEstimatedItemSize(i, data[i]);
872
+ offset += sizeFn(i);
650
873
  }
651
874
  } else if (estimatedItemSize) {
652
875
  offset = index * estimatedItemSize;
@@ -655,7 +878,7 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
655
878
  }
656
879
  return 0;
657
880
  };
658
- const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : React5.useMemo(calculateInitialOffset, []);
881
+ const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : React6.useMemo(calculateOffsetForIndex, []);
659
882
  if (!refState.current) {
660
883
  const initialScrollLength = reactNative.Dimensions.get("window")[horizontal ? "width" : "height"];
661
884
  refState.current = {
@@ -663,14 +886,11 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
663
886
  positions: /* @__PURE__ */ new Map(),
664
887
  columns: /* @__PURE__ */ new Map(),
665
888
  pendingAdjust: 0,
666
- waitingForMicrotask: false,
667
889
  isStartReached: initialContentOffset < initialScrollLength * onStartReachedThreshold,
668
890
  isEndReached: false,
669
891
  isAtBottom: false,
670
892
  isAtTop: false,
671
- data,
672
- idsInFirstRender: void 0,
673
- hasScrolled: false,
893
+ data: dataProp,
674
894
  scrollLength: initialScrollLength,
675
895
  startBuffered: 0,
676
896
  startNoBuffer: 0,
@@ -696,17 +916,22 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
696
916
  belowAnchorElementPositions: void 0,
697
917
  rowHeights: /* @__PURE__ */ new Map(),
698
918
  startReachedBlockedByTimer: false,
919
+ endReachedBlockedByTimer: false,
699
920
  scrollForNextCalculateItemsInView: void 0,
700
- enableScrollForNextCalculateItemsInView: true
921
+ enableScrollForNextCalculateItemsInView: true,
922
+ minIndexSizeChanged: 0,
923
+ numPendingInitialLayout: 0,
924
+ queuedCalculateItemsInView: 0,
925
+ lastBatchingAction: Date.now(),
926
+ onScroll: onScrollProp
701
927
  };
702
- refState.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
703
928
  if (maintainVisibleContentPosition) {
704
929
  if (initialScrollIndex) {
705
930
  refState.current.anchorElement = {
706
931
  coordinate: initialContentOffset,
707
932
  id: getId(initialScrollIndex)
708
933
  };
709
- } else if (data.length) {
934
+ } else if (dataProp.length) {
710
935
  refState.current.anchorElement = {
711
936
  coordinate: initialContentOffset,
712
937
  id: getId(0)
@@ -719,6 +944,9 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
719
944
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
720
945
  set$(ctx, "extraData", extraData);
721
946
  }
947
+ const didDataChange = refState.current.data !== dataProp;
948
+ refState.current.data = dataProp;
949
+ refState.current.onScroll = onScrollProp;
722
950
  const getAnchorElementIndex = () => {
723
951
  const state = refState.current;
724
952
  if (state.anchorElement) {
@@ -727,16 +955,16 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
727
955
  }
728
956
  return void 0;
729
957
  };
730
- const addTotalSize = React5.useCallback((key, add, totalSizeBelowAnchor) => {
958
+ const addTotalSize = React6.useCallback((key, add, totalSizeBelowAnchor) => {
731
959
  const state = refState.current;
732
- const index = key === null ? 0 : state.indexByKey.get(key);
960
+ const { indexByKey, anchorElement } = state;
961
+ const index = key === null ? 0 : indexByKey.get(key);
733
962
  let isAboveAnchor = false;
734
963
  if (maintainVisibleContentPosition) {
735
- if (state.anchorElement && index < getAnchorElementIndex()) {
964
+ if (anchorElement && index < getAnchorElementIndex()) {
736
965
  isAboveAnchor = true;
737
966
  }
738
967
  }
739
- state.totalSize;
740
968
  if (key === null) {
741
969
  state.totalSize = add;
742
970
  state.totalSizeBelowAnchor = totalSizeBelowAnchor;
@@ -746,29 +974,30 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
746
974
  state.totalSizeBelowAnchor += add;
747
975
  }
748
976
  }
749
- let applyAdjustValue = void 0;
750
- if (maintainVisibleContentPosition) {
751
- const newAdjust = state.anchorElement.coordinate - state.totalSizeBelowAnchor;
977
+ let applyAdjustValue = 0;
978
+ let resultSize = state.totalSize;
979
+ if (maintainVisibleContentPosition && anchorElement !== void 0) {
980
+ const newAdjust = anchorElement.coordinate - state.totalSizeBelowAnchor;
752
981
  applyAdjustValue = -newAdjust;
753
982
  state.belowAnchorElementPositions = buildElementPositionsBelowAnchor();
754
983
  state.rowHeights.clear();
984
+ if (applyAdjustValue !== void 0) {
985
+ resultSize -= applyAdjustValue;
986
+ refState.current.scrollAdjustHandler.requestAdjust(applyAdjustValue, (diff) => {
987
+ state.scroll -= diff;
988
+ });
989
+ }
755
990
  }
756
- const totalSize = state.totalSize;
757
- let resultSize = totalSize;
758
- if (applyAdjustValue !== void 0) {
759
- resultSize -= applyAdjustValue;
760
- refState.current.scrollAdjustHandler.requestAdjust(applyAdjustValue, (diff) => {
761
- state.scroll -= diff;
762
- });
763
- }
764
- set$(ctx, "totalSize", resultSize);
991
+ set$(ctx, "totalSize", state.totalSize);
992
+ set$(ctx, "totalSizeWithScrollAdjust", resultSize);
765
993
  if (alignItemsAtEnd) {
766
994
  doUpdatePaddingTop();
767
995
  }
768
996
  }, []);
769
997
  const getRowHeight = (n) => {
770
- const { rowHeights } = refState.current;
771
- if (numColumnsProp === 1) {
998
+ const { rowHeights, data } = refState.current;
999
+ const numColumns = peek$(ctx, "numColumns");
1000
+ if (numColumns === 1) {
772
1001
  const id = getId(n);
773
1002
  return getItemSize(id, n, data[n]);
774
1003
  }
@@ -776,8 +1005,8 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
776
1005
  return rowHeights.get(n) || 0;
777
1006
  }
778
1007
  let rowHeight = 0;
779
- const startEl = n * numColumnsProp;
780
- for (let i = startEl; i < startEl + numColumnsProp && i < data.length; i++) {
1008
+ const startEl = n * numColumns;
1009
+ for (let i = startEl; i < startEl + numColumns && i < data.length; i++) {
781
1010
  const id = getId(i);
782
1011
  const size = getItemSize(id, i, data[i]);
783
1012
  rowHeight = Math.max(rowHeight, size);
@@ -796,10 +1025,11 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
796
1025
  return /* @__PURE__ */ new Map();
797
1026
  }
798
1027
  const map = state.belowAnchorElementPositions || /* @__PURE__ */ new Map();
1028
+ const numColumns = peek$(ctx, "numColumns");
799
1029
  for (let i = anchorIndex - 1; i >= 0; i--) {
800
1030
  const id = getId(i);
801
- const rowNumber = Math.floor(i / numColumnsProp);
802
- if (i % numColumnsProp === 0) {
1031
+ const rowNumber = Math.floor(i / numColumns);
1032
+ if (i % numColumns === 0) {
803
1033
  top -= getRowHeight(rowNumber);
804
1034
  }
805
1035
  map.set(id, top);
@@ -807,37 +1037,53 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
807
1037
  return map;
808
1038
  };
809
1039
  const getElementPositionBelowAchor = (id) => {
1040
+ var _a2;
810
1041
  const state = refState.current;
811
1042
  if (!refState.current.belowAnchorElementPositions) {
812
1043
  state.belowAnchorElementPositions = buildElementPositionsBelowAnchor();
813
1044
  }
814
1045
  const res = state.belowAnchorElementPositions.get(id);
815
1046
  if (res === void 0) {
816
- throw new Error("Undefined position below achor");
1047
+ console.warn(`Undefined position below achor ${id} ${(_a2 = state.anchorElement) == null ? void 0 : _a2.id}`);
1048
+ return 0;
817
1049
  }
818
1050
  return res;
819
1051
  };
820
- const calculateItemsInView = React5.useCallback((speed) => {
1052
+ const calculateItemsInView = React6.useCallback(() => {
1053
+ var _a2;
821
1054
  const state = refState.current;
822
1055
  const {
823
- data: data2,
1056
+ data,
824
1057
  scrollLength,
825
1058
  scroll: scrollState,
826
1059
  startBufferedId: startBufferedIdOrig,
827
1060
  positions,
828
1061
  columns,
829
- scrollAdjustHandler
1062
+ scrollAdjustHandler,
1063
+ scrollVelocity: speed
830
1064
  } = state;
831
- if (state.waitingForMicrotask) {
832
- state.waitingForMicrotask = false;
833
- }
834
- if (!data2) {
1065
+ if (!data || scrollLength === 0) {
835
1066
  return;
836
1067
  }
837
1068
  const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
1069
+ const numColumns = peek$(ctx, "numColumns");
838
1070
  const previousScrollAdjust = scrollAdjustHandler.getAppliedAdjust();
839
1071
  const scrollExtra = Math.max(-16, Math.min(16, speed)) * 16;
840
- const scroll = scrollState - previousScrollAdjust - topPad - scrollExtra;
1072
+ const scroll = scrollState - previousScrollAdjust - topPad;
1073
+ if (ENABLE_DEBUG_VIEW) {
1074
+ set$(ctx, "debugRawScroll", scrollState);
1075
+ set$(ctx, "debugComputedScroll", scroll);
1076
+ }
1077
+ let scrollBufferTop = scrollBuffer;
1078
+ let scrollBufferBottom = scrollBuffer;
1079
+ if (scrollExtra > 8) {
1080
+ scrollBufferTop = 0;
1081
+ scrollBufferBottom = scrollBuffer + scrollExtra;
1082
+ }
1083
+ if (scrollExtra < -8) {
1084
+ scrollBufferTop = scrollBuffer - scrollExtra;
1085
+ scrollBufferBottom = 0;
1086
+ }
841
1087
  if (state.scrollForNextCalculateItemsInView) {
842
1088
  const { top: top2, bottom } = state.scrollForNextCalculateItemsInView;
843
1089
  if (scroll > top2 && scroll < bottom) {
@@ -850,8 +1096,11 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
850
1096
  let startBufferedId = null;
851
1097
  let endNoBuffer = null;
852
1098
  let endBuffered = null;
853
- const originalStartId = startBufferedIdOrig && state.indexByKey.get(startBufferedIdOrig);
854
- let loopStart = originalStartId || 0;
1099
+ let loopStart = startBufferedIdOrig ? state.indexByKey.get(startBufferedIdOrig) || 0 : 0;
1100
+ if (state.minIndexSizeChanged !== void 0) {
1101
+ loopStart = Math.min(state.minIndexSizeChanged, loopStart);
1102
+ state.minIndexSizeChanged = void 0;
1103
+ }
855
1104
  const anchorElementIndex = getAnchorElementIndex();
856
1105
  for (let i = loopStart; i >= 0; i--) {
857
1106
  const id = getId(i);
@@ -864,7 +1113,7 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
864
1113
  }
865
1114
  const top2 = newPosition || positions.get(id);
866
1115
  if (top2 !== void 0) {
867
- const size = getItemSize(id, i, data2[i]);
1116
+ const size = getItemSize(id, i, data[i]);
868
1117
  const bottom = top2 + size;
869
1118
  if (bottom > scroll - scrollBuffer) {
870
1119
  loopStart = i;
@@ -873,7 +1122,6 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
873
1122
  }
874
1123
  }
875
1124
  }
876
- const numColumns = peek$(ctx, "numColumns");
877
1125
  const loopStartMod = loopStart % numColumns;
878
1126
  if (loopStartMod > 0) {
879
1127
  loopStart -= loopStartMod;
@@ -882,22 +1130,22 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
882
1130
  let column = 1;
883
1131
  let maxSizeInRow = 0;
884
1132
  const getInitialTop = (i) => {
885
- var _a2;
1133
+ var _a3;
886
1134
  const id = getId(i);
887
1135
  let topOffset = 0;
888
1136
  if (positions.get(id)) {
889
1137
  topOffset = positions.get(id);
890
1138
  }
891
- if (id === ((_a2 = state.anchorElement) == null ? void 0 : _a2.id)) {
892
- topOffset = initialContentOffset || 0;
1139
+ if (id === ((_a3 = state.anchorElement) == null ? void 0 : _a3.id)) {
1140
+ topOffset = state.anchorElement.coordinate;
893
1141
  }
894
1142
  return topOffset;
895
1143
  };
896
- for (let i = loopStart; i < data2.length; i++) {
1144
+ for (let i = loopStart; i < data.length; i++) {
897
1145
  const id = getId(i);
898
- const size = getItemSize(id, i, data2[i]);
1146
+ const size = getItemSize(id, i, data[i]);
899
1147
  maxSizeInRow = Math.max(maxSizeInRow, size);
900
- if (top === void 0) {
1148
+ if (top === void 0 || id === ((_a2 = state.anchorElement) == null ? void 0 : _a2.id)) {
901
1149
  top = getInitialTop(i);
902
1150
  }
903
1151
  if (positions.get(id) !== top) {
@@ -909,7 +1157,7 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
909
1157
  if (startNoBuffer === null && top + size > scroll) {
910
1158
  startNoBuffer = i;
911
1159
  }
912
- if (startBuffered === null && top + size > scroll - scrollBuffer) {
1160
+ if (startBuffered === null && top + size > scroll - scrollBufferTop) {
913
1161
  startBuffered = i;
914
1162
  startBufferedId = id;
915
1163
  }
@@ -917,7 +1165,7 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
917
1165
  if (top <= scrollBottom) {
918
1166
  endNoBuffer = i;
919
1167
  }
920
- if (top <= scrollBottom + scrollBuffer) {
1168
+ if (top <= scrollBottom + scrollBufferBottom) {
921
1169
  endBuffered = i;
922
1170
  } else {
923
1171
  break;
@@ -950,6 +1198,7 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
950
1198
  if (startBuffered !== null && endBuffered !== null) {
951
1199
  const prevNumContainers = ctx.values.get("numContainers");
952
1200
  let numContainers = prevNumContainers;
1201
+ let didWarnMoreContainers = false;
953
1202
  for (let i = startBuffered; i <= endBuffered; i++) {
954
1203
  let isContained = false;
955
1204
  const id = getId(i);
@@ -983,18 +1232,19 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
983
1232
  if (furthestIndex >= 0) {
984
1233
  set$(ctx, `containerItemKey${furthestIndex}`, id);
985
1234
  const index = state.indexByKey.get(id);
986
- set$(ctx, `containerItemData${furthestIndex}`, data2[index]);
1235
+ set$(ctx, `containerItemData${furthestIndex}`, data[index]);
987
1236
  } else {
988
1237
  const containerId = numContainers;
989
1238
  numContainers++;
990
1239
  set$(ctx, `containerItemKey${containerId}`, id);
991
1240
  const index = state.indexByKey.get(id);
992
- set$(ctx, `containerItemData${containerId}`, data2[index]);
1241
+ set$(ctx, `containerItemData${containerId}`, data[index]);
993
1242
  set$(ctx, `containerPosition${containerId}`, ANCHORED_POSITION_OUT_OF_VIEW);
994
1243
  set$(ctx, `containerColumn${containerId}`, -1);
995
- if (__DEV__ && numContainers > peek$(ctx, "numContainersPooled")) {
1244
+ if (__DEV__ && !didWarnMoreContainers && numContainers > peek$(ctx, "numContainersPooled")) {
1245
+ didWarnMoreContainers = true;
996
1246
  console.warn(
997
- "[legend-list] No container to recycle, so creating one on demand. This can be a performance issue and is likely caused by the estimatedItemSize being too small. Consider increasing estimatedItemSize. numContainers:",
1247
+ "[legend-list] No container to recycle, so creating one on demand. This can be a minor performance issue and is likely caused by the estimatedItemSize being too large. Consider decreasing estimatedItemSize. numContainers:",
998
1248
  numContainers
999
1249
  );
1000
1250
  }
@@ -1004,19 +1254,19 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
1004
1254
  if (numContainers !== prevNumContainers) {
1005
1255
  set$(ctx, "numContainers", numContainers);
1006
1256
  if (numContainers > peek$(ctx, "numContainersPooled")) {
1007
- set$(ctx, "numContainersPooled", numContainers);
1257
+ set$(ctx, "numContainersPooled", Math.ceil(numContainers * 1.5));
1008
1258
  }
1009
1259
  }
1010
1260
  for (let i = 0; i < numContainers; i++) {
1011
1261
  const itemKey = peek$(ctx, `containerItemKey${i}`);
1012
1262
  const itemIndex = state.indexByKey.get(itemKey);
1013
- const item = data2[itemIndex];
1014
- if (item) {
1263
+ const item = data[itemIndex];
1264
+ if (item !== void 0) {
1015
1265
  const id = getId(itemIndex);
1016
1266
  if (itemKey !== id || itemIndex < startBuffered || itemIndex > endBuffered) {
1017
1267
  const prevPos = peek$(ctx, `containerPosition${i}`).top;
1018
1268
  const pos = positions.get(id) || 0;
1019
- const size = getItemSize(id, itemIndex, data2[i]);
1269
+ const size = getItemSize(id, itemIndex, data[i]);
1020
1270
  if (pos + size >= scroll && pos <= scrollBottom || prevPos + size >= scroll && prevPos <= scrollBottom) {
1021
1271
  set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
1022
1272
  }
@@ -1028,9 +1278,9 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
1028
1278
  };
1029
1279
  const column2 = columns.get(id) || 1;
1030
1280
  if (maintainVisibleContentPosition && itemIndex < anchorElementIndex) {
1031
- const currentRow = Math.floor(itemIndex / numColumnsProp);
1281
+ const currentRow = Math.floor(itemIndex / numColumns);
1032
1282
  const rowHeight = getRowHeight(currentRow);
1033
- const elementHeight = getItemSize(id, itemIndex, data2[i]);
1283
+ const elementHeight = getItemSize(id, itemIndex, data[i]);
1034
1284
  const diff = rowHeight - elementHeight;
1035
1285
  pos.relativeCoordinate = pos.top + getRowHeight(currentRow) - diff;
1036
1286
  pos.type = "bottom";
@@ -1045,13 +1295,15 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
1045
1295
  set$(ctx, `containerColumn${i}`, column2);
1046
1296
  }
1047
1297
  if (prevData !== item) {
1048
- set$(ctx, `containerItemData${i}`, data2[itemIndex]);
1298
+ set$(ctx, `containerItemData${i}`, data[itemIndex]);
1049
1299
  }
1050
1300
  }
1051
1301
  }
1052
1302
  }
1053
1303
  }
1054
- set$(ctx, "containersDidLayout", true);
1304
+ if (state.numPendingInitialLayout === 0) {
1305
+ state.numPendingInitialLayout = state.endBuffered - state.startBuffered + 1;
1306
+ }
1055
1307
  if (state.viewabilityConfigCallbackPairs) {
1056
1308
  updateViewableItems(
1057
1309
  state,
@@ -1066,16 +1318,27 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
1066
1318
  }, []);
1067
1319
  const doUpdatePaddingTop = () => {
1068
1320
  if (alignItemsAtEnd) {
1069
- const { scrollLength, totalSize } = refState.current;
1070
- const listPaddingTop = peek$(ctx, "stylePaddingTop") || 0;
1071
- const paddingTop = Math.max(0, Math.floor(scrollLength - totalSize - listPaddingTop));
1321
+ const { scrollLength } = refState.current;
1322
+ const contentSize = getContentSize(ctx);
1323
+ const paddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
1072
1324
  set$(ctx, "paddingTop", paddingTop);
1073
1325
  }
1074
1326
  };
1327
+ const scrollTo = (offset, animated) => {
1328
+ var _a2;
1329
+ (_a2 = refScroller.current) == null ? void 0 : _a2.scrollTo({
1330
+ x: horizontal ? offset : 0,
1331
+ y: horizontal ? 0 : offset,
1332
+ animated: !!animated
1333
+ });
1334
+ };
1075
1335
  const doMaintainScrollAtEnd = (animated) => {
1076
1336
  const state = refState.current;
1077
1337
  if ((state == null ? void 0 : state.isAtBottom) && maintainScrollAtEnd) {
1078
- state.scroll = state.totalSize - state.scrollLength + peek$(ctx, "paddingTop");
1338
+ const paddingTop = peek$(ctx, "paddingTop") || 0;
1339
+ if (paddingTop > 0) {
1340
+ state.scroll = 0;
1341
+ }
1079
1342
  requestAnimationFrame(() => {
1080
1343
  var _a2;
1081
1344
  (_a2 = refScroller.current) == null ? void 0 : _a2.scrollToEnd({
@@ -1085,28 +1348,48 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
1085
1348
  return true;
1086
1349
  }
1087
1350
  };
1351
+ const checkThreshold = (distance, threshold, isReached, isBlockedByTimer, onReached, blockTimer) => {
1352
+ const distanceAbs = Math.abs(distance);
1353
+ const isAtThreshold = distanceAbs < threshold;
1354
+ if (!isReached && !isBlockedByTimer) {
1355
+ if (isAtThreshold) {
1356
+ onReached == null ? void 0 : onReached(distance);
1357
+ blockTimer == null ? void 0 : blockTimer(true);
1358
+ setTimeout(() => {
1359
+ blockTimer == null ? void 0 : blockTimer(false);
1360
+ }, 700);
1361
+ return true;
1362
+ }
1363
+ } else {
1364
+ if (distance >= 1.3 * threshold) {
1365
+ return false;
1366
+ }
1367
+ }
1368
+ return isReached;
1369
+ };
1088
1370
  const checkAtBottom = () => {
1089
1371
  if (!refState.current) {
1090
1372
  return;
1091
1373
  }
1092
- const { scrollLength, scroll, totalSize } = refState.current;
1093
- if (totalSize > 0) {
1094
- const distanceFromEnd = totalSize - scroll - scrollLength;
1095
- if (refState.current) {
1096
- refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
1097
- }
1098
- if (onEndReached) {
1099
- if (!refState.current.isEndReached) {
1100
- if (distanceFromEnd < onEndReachedThreshold * scrollLength) {
1101
- refState.current.isEndReached = true;
1102
- onEndReached({ distanceFromEnd });
1103
- }
1104
- } else {
1105
- if (distanceFromEnd >= onEndReachedThreshold * scrollLength) {
1106
- refState.current.isEndReached = false;
1107
- }
1374
+ const { scrollLength, scroll, hasScrolled } = refState.current;
1375
+ const contentSize = getContentSize(ctx);
1376
+ if (contentSize > 0 && hasScrolled) {
1377
+ const distanceFromEnd = contentSize - scroll - scrollLength;
1378
+ const distanceFromEndAbs = Math.abs(distanceFromEnd);
1379
+ refState.current.isAtBottom = distanceFromEndAbs < scrollLength * maintainScrollAtEndThreshold;
1380
+ refState.current.isEndReached = checkThreshold(
1381
+ distanceFromEnd,
1382
+ onEndReachedThreshold * scrollLength,
1383
+ refState.current.isEndReached,
1384
+ refState.current.endReachedBlockedByTimer,
1385
+ (distance) => {
1386
+ var _a2, _b2;
1387
+ return (_b2 = (_a2 = callbacks.current).onEndReached) == null ? void 0 : _b2.call(_a2, { distanceFromEnd: distance });
1388
+ },
1389
+ (block) => {
1390
+ refState.current.endReachedBlockedByTimer = block;
1108
1391
  }
1109
- }
1392
+ );
1110
1393
  }
1111
1394
  };
1112
1395
  const checkAtTop = () => {
@@ -1115,112 +1398,118 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
1115
1398
  }
1116
1399
  const { scrollLength, scroll } = refState.current;
1117
1400
  const distanceFromTop = scroll;
1118
- refState.current.isAtTop = distanceFromTop < 0;
1119
- if (onStartReached) {
1120
- if (!refState.current.isStartReached && !refState.current.startReachedBlockedByTimer) {
1121
- if (distanceFromTop < onStartReachedThreshold * scrollLength) {
1122
- refState.current.isStartReached = true;
1123
- onStartReached({ distanceFromStart: scroll });
1124
- refState.current.startReachedBlockedByTimer = true;
1125
- setTimeout(() => {
1126
- refState.current.startReachedBlockedByTimer = false;
1127
- }, 700);
1128
- }
1129
- } else {
1130
- if (distanceFromTop >= 1.3 * onStartReachedThreshold * scrollLength) {
1131
- refState.current.isStartReached = false;
1132
- }
1401
+ const distanceFromTopAbs = Math.abs(distanceFromTop);
1402
+ refState.current.isAtTop = distanceFromTopAbs < 0;
1403
+ refState.current.isStartReached = checkThreshold(
1404
+ distanceFromTop,
1405
+ onStartReachedThreshold * scrollLength,
1406
+ refState.current.isStartReached,
1407
+ refState.current.startReachedBlockedByTimer,
1408
+ (distance) => {
1409
+ var _a2, _b2;
1410
+ return (_b2 = (_a2 = callbacks.current).onStartReached) == null ? void 0 : _b2.call(_a2, { distanceFromStart: distance });
1411
+ },
1412
+ (block) => {
1413
+ refState.current.startReachedBlockedByTimer = block;
1133
1414
  }
1134
- }
1415
+ );
1135
1416
  };
1136
- const checkResetContainers = (reset) => {
1417
+ const checkResetContainers = (isFirst2) => {
1137
1418
  const state = refState.current;
1138
1419
  if (state) {
1139
- state.data = data;
1140
- if (reset) {
1420
+ state.data = dataProp;
1421
+ if (!isFirst2) {
1141
1422
  refState.current.scrollForNextCalculateItemsInView = void 0;
1142
1423
  const numContainers = peek$(ctx, "numContainers");
1143
1424
  for (let i = 0; i < numContainers; i++) {
1144
1425
  const itemKey = peek$(ctx, `containerItemKey${i}`);
1145
1426
  if (!keyExtractorProp || itemKey && state.indexByKey.get(itemKey) === void 0) {
1146
1427
  set$(ctx, `containerItemKey${i}`, void 0);
1428
+ set$(ctx, `containerItemData${i}`, void 0);
1147
1429
  set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
1148
1430
  set$(ctx, `containerColumn${i}`, -1);
1149
1431
  }
1150
1432
  }
1151
1433
  if (!keyExtractorProp) {
1152
- state.sizes.clear();
1153
1434
  state.positions.clear();
1154
1435
  }
1155
- calculateItemsInView(state.scrollVelocity);
1156
- }
1157
- const didMaintainScrollAtEnd = doMaintainScrollAtEnd(false);
1158
- if (!didMaintainScrollAtEnd && data.length > state.data.length) {
1159
- state.isEndReached = false;
1436
+ calculateItemsInView();
1437
+ const didMaintainScrollAtEnd = doMaintainScrollAtEnd(false);
1438
+ if (!didMaintainScrollAtEnd && dataProp.length > state.data.length) {
1439
+ state.isEndReached = false;
1440
+ }
1441
+ checkAtTop();
1442
+ checkAtBottom();
1160
1443
  }
1161
- checkAtTop();
1162
- checkAtBottom();
1163
1444
  }
1164
1445
  };
1165
- const isFirst = !refState.current.renderItem;
1166
- if (isFirst || data !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
1167
- if (!keyExtractorProp && !isFirst && data !== refState.current.data) {
1168
- refState.current.sizes.clear();
1169
- refState.current.positions.clear();
1170
- }
1171
- refState.current.data = data;
1446
+ const calcTotalSizesAndPositions = ({ forgetPositions = false }) => {
1447
+ var _a2, _b2;
1172
1448
  let totalSize = 0;
1173
1449
  let totalSizeBelowIndex = 0;
1174
1450
  const indexByKey = /* @__PURE__ */ new Map();
1175
1451
  const newPositions = /* @__PURE__ */ new Map();
1176
1452
  let column = 1;
1177
1453
  let maxSizeInRow = 0;
1178
- for (let i = 0; i < data.length; i++) {
1454
+ const numColumns = (_a2 = peek$(ctx, "numColumns")) != null ? _a2 : numColumnsProp;
1455
+ if (!refState.current) {
1456
+ return;
1457
+ }
1458
+ for (let i = 0; i < dataProp.length; i++) {
1179
1459
  const key = getId(i);
1460
+ if (__DEV__) {
1461
+ if (indexByKey.has(key)) {
1462
+ console.error(
1463
+ `[legend-list] Error: Detected overlapping key (${key}) which causes missing items and gaps and other terrrible things. Check that keyExtractor returns unique values.`
1464
+ );
1465
+ }
1466
+ }
1180
1467
  indexByKey.set(key, i);
1181
- if (refState.current.positions.get(key) != null && refState.current.indexByKey.get(key) === i) {
1468
+ if (!forgetPositions && refState.current.positions.get(key) != null && refState.current.indexByKey.get(key) === i) {
1182
1469
  newPositions.set(key, refState.current.positions.get(key));
1183
1470
  }
1184
1471
  }
1185
1472
  refState.current.indexByKey = indexByKey;
1186
1473
  refState.current.positions = newPositions;
1187
- if (maintainVisibleContentPosition) {
1188
- if (refState.current.anchorElement == null || indexByKey.get(refState.current.anchorElement.id) == null) {
1189
- if (data.length) {
1190
- const newAnchorElement = {
1191
- coordinate: 0,
1192
- id: getId(0)
1193
- };
1194
- refState.current.anchorElement = newAnchorElement;
1195
- (_a = refState.current.belowAnchorElementPositions) == null ? void 0 : _a.clear();
1196
- refScroller.current.scrollTo({ x: 0, y: 0, animated: false });
1474
+ if (!forgetPositions && !isFirst) {
1475
+ if (maintainVisibleContentPosition) {
1476
+ if (refState.current.anchorElement == null || indexByKey.get(refState.current.anchorElement.id) == null) {
1477
+ if (dataProp.length) {
1478
+ const newAnchorElement = {
1479
+ coordinate: 0,
1480
+ id: getId(0)
1481
+ };
1482
+ refState.current.anchorElement = newAnchorElement;
1483
+ (_b2 = refState.current.belowAnchorElementPositions) == null ? void 0 : _b2.clear();
1484
+ scrollTo(0, false);
1485
+ setTimeout(() => {
1486
+ calculateItemsInView();
1487
+ }, 0);
1488
+ } else {
1489
+ refState.current.startBufferedId = void 0;
1490
+ }
1491
+ }
1492
+ } else {
1493
+ if (refState.current.startBufferedId != null && newPositions.get(refState.current.startBufferedId) == null) {
1494
+ if (dataProp.length) {
1495
+ refState.current.startBufferedId = getId(0);
1496
+ } else {
1497
+ refState.current.startBufferedId = void 0;
1498
+ }
1499
+ scrollTo(0, false);
1197
1500
  setTimeout(() => {
1198
- calculateItemsInView(0);
1501
+ calculateItemsInView();
1199
1502
  }, 0);
1200
- } else {
1201
- refState.current.startBufferedId = void 0;
1202
- }
1203
- }
1204
- } else {
1205
- if (refState.current.startBufferedId != null && newPositions.get(refState.current.startBufferedId) == null) {
1206
- if (data.length) {
1207
- refState.current.startBufferedId = getId(0);
1208
- } else {
1209
- refState.current.startBufferedId = void 0;
1210
1503
  }
1211
- refScroller.current.scrollTo({ x: 0, y: 0, animated: false });
1212
- setTimeout(() => {
1213
- calculateItemsInView(0);
1214
- }, 0);
1215
1504
  }
1216
1505
  }
1217
1506
  const anchorElementIndex = getAnchorElementIndex();
1218
- for (let i = 0; i < data.length; i++) {
1507
+ for (let i = 0; i < dataProp.length; i++) {
1219
1508
  const key = getId(i);
1220
- const size = getItemSize(key, i, data[i]);
1509
+ const size = getItemSize(key, i, dataProp[i]);
1221
1510
  maxSizeInRow = Math.max(maxSizeInRow, size);
1222
1511
  column++;
1223
- if (column > numColumnsProp) {
1512
+ if (column > numColumns) {
1224
1513
  if (maintainVisibleContentPosition && anchorElementIndex !== void 0 && i < anchorElementIndex) {
1225
1514
  totalSizeBelowIndex += maxSizeInRow;
1226
1515
  }
@@ -1232,36 +1521,58 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
1232
1521
  if (maxSizeInRow > 0) {
1233
1522
  totalSize += maxSizeInRow;
1234
1523
  }
1524
+ const state = refState.current;
1525
+ state.ignoreScrollFromCalcTotal = true;
1526
+ requestAnimationFrame(() => {
1527
+ state.ignoreScrollFromCalcTotal = false;
1528
+ });
1235
1529
  addTotalSize(null, totalSize, totalSizeBelowIndex);
1236
- }
1237
- React5.useEffect(() => {
1238
- checkResetContainers(
1239
- /*reset*/
1240
- !isFirst
1530
+ };
1531
+ const isFirst = !refState.current.renderItem;
1532
+ const memoizedLastItemKeys = React6.useMemo(() => {
1533
+ if (!dataProp.length) return /* @__PURE__ */ new Set();
1534
+ return new Set(
1535
+ Array.from({ length: Math.min(numColumnsProp, dataProp.length) }, (_, i) => getId(dataProp.length - 1 - i))
1241
1536
  );
1242
- }, [isFirst, data, numColumnsProp]);
1243
- React5.useEffect(() => {
1244
- set$(ctx, "extraData", extraData);
1245
- }, [extraData]);
1246
- refState.current.renderItem = renderItem;
1247
- const lastItemKey = getId(data[data.length - 1]);
1248
- const stylePaddingTop = (_e = (_d = (_b = reactNative.StyleSheet.flatten(style)) == null ? void 0 : _b.paddingTop) != null ? _d : (_c = reactNative.StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _c.paddingTop) != null ? _e : 0;
1537
+ }, [dataProp.length, numColumnsProp, dataProp.slice(-numColumnsProp).toString()]);
1249
1538
  const initalizeStateVars = () => {
1250
- set$(ctx, "lastItemKey", lastItemKey);
1539
+ set$(ctx, "lastItemKeys", memoizedLastItemKeys);
1251
1540
  set$(ctx, "numColumns", numColumnsProp);
1252
1541
  set$(ctx, "stylePaddingTop", stylePaddingTop);
1253
1542
  };
1254
1543
  if (isFirst) {
1255
1544
  initalizeStateVars();
1256
1545
  }
1257
- React5.useEffect(initalizeStateVars, [lastItemKey, numColumnsProp, stylePaddingTop]);
1258
- const getRenderedItem = React5.useCallback((key) => {
1546
+ if (isFirst || didDataChange || numColumnsProp !== peek$(ctx, "numColumns")) {
1547
+ refState.current.lastBatchingAction = Date.now();
1548
+ if (!keyExtractorProp && !isFirst && didDataChange) {
1549
+ refState.current.sizes.clear();
1550
+ refState.current.positions.clear();
1551
+ }
1552
+ calcTotalSizesAndPositions({ forgetPositions: false });
1553
+ }
1554
+ React6.useEffect(() => {
1555
+ const didAllocateContainers = doInitialAllocateContainers();
1556
+ if (!didAllocateContainers) {
1557
+ checkResetContainers(
1558
+ /*isFirst*/
1559
+ isFirst
1560
+ );
1561
+ }
1562
+ }, [isFirst, dataProp, numColumnsProp]);
1563
+ React6.useEffect(() => {
1564
+ set$(ctx, "extraData", extraData);
1565
+ }, [extraData]);
1566
+ refState.current.renderItem = renderItem;
1567
+ const stylePaddingTop = (_d = (_c = (_a = reactNative.StyleSheet.flatten(style)) == null ? void 0 : _a.paddingTop) != null ? _c : (_b = reactNative.StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _b.paddingTop) != null ? _d : 0;
1568
+ React6.useEffect(initalizeStateVars, [memoizedLastItemKeys, numColumnsProp, stylePaddingTop]);
1569
+ const getRenderedItem = React6.useCallback((key) => {
1259
1570
  var _a2, _b2;
1260
1571
  const state = refState.current;
1261
1572
  if (!state) {
1262
1573
  return null;
1263
1574
  }
1264
- const { data: data2, indexByKey } = state;
1575
+ const { data, indexByKey } = state;
1265
1576
  const index = indexByKey.get(key);
1266
1577
  if (index === void 0) {
1267
1578
  return null;
@@ -1279,58 +1590,82 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
1279
1590
  return useRecyclingState(valueOrFun);
1280
1591
  };
1281
1592
  const renderedItem = (_b2 = (_a2 = refState.current).renderItem) == null ? void 0 : _b2.call(_a2, {
1282
- item: data2[index],
1593
+ item: data[index],
1283
1594
  index,
1595
+ extraData: peek$(ctx, "extraData"),
1284
1596
  useViewability: useViewability2,
1285
1597
  useViewabilityAmount: useViewabilityAmount2,
1286
1598
  useRecyclingEffect: useRecyclingEffect2,
1287
1599
  useRecyclingState: useRecyclingState2
1288
1600
  });
1289
- return { index, renderedItem };
1601
+ return { index, item: data[index], renderedItem };
1290
1602
  }, []);
1291
- useInit(() => {
1603
+ const doInitialAllocateContainers = () => {
1292
1604
  var _a2;
1293
1605
  const state = refState.current;
1294
- const viewability = setupViewability(props);
1606
+ const { scrollLength, data } = state;
1607
+ if (scrollLength > 0 && data.length > 0 && !peek$(ctx, "numContainers")) {
1608
+ const averageItemSize = (_a2 = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, data[0])) != null ? _a2 : DEFAULT_ITEM_SIZE;
1609
+ const numContainers = Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize) * numColumnsProp;
1610
+ for (let i = 0; i < numContainers; i++) {
1611
+ set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
1612
+ set$(ctx, `containerColumn${i}`, -1);
1613
+ }
1614
+ set$(ctx, "numContainers", numContainers);
1615
+ set$(ctx, "numContainersPooled", numContainers * initialContainerPoolRatio);
1616
+ if (initialScrollIndex) {
1617
+ requestAnimationFrame(() => {
1618
+ calculateItemsInView();
1619
+ });
1620
+ } else {
1621
+ calculateItemsInView();
1622
+ }
1623
+ return true;
1624
+ }
1625
+ };
1626
+ React6.useEffect(() => {
1627
+ const state = refState.current;
1628
+ const viewability = setupViewability({
1629
+ viewabilityConfig,
1630
+ viewabilityConfigCallbackPairs,
1631
+ onViewableItemsChanged
1632
+ });
1295
1633
  state.viewabilityConfigCallbackPairs = viewability;
1296
1634
  state.enableScrollForNextCalculateItemsInView = !viewability;
1297
- const scrollLength = state.scrollLength;
1298
- const averageItemSize = (_a2 = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, data[0])) != null ? _a2 : DEFAULT_ITEM_SIZE;
1299
- const numContainers = Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize) * numColumnsProp;
1300
- for (let i = 0; i < numContainers; i++) {
1301
- set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
1302
- set$(ctx, `containerColumn${i}`, -1);
1303
- }
1304
- set$(ctx, "numContainers", numContainers);
1305
- set$(ctx, "numContainersPooled", numContainers * 2);
1306
- calculateItemsInView(state.scrollVelocity);
1635
+ }, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
1636
+ useInit(() => {
1637
+ doInitialAllocateContainers();
1307
1638
  });
1308
- const updateItemSize = React5.useCallback((containerId, itemKey, size) => {
1309
- var _a2;
1310
- const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
1311
- if (!data2) {
1639
+ const updateItemSize = React6.useCallback((itemKey, size) => {
1640
+ const state = refState.current;
1641
+ const { sizes, indexByKey, sizesLaidOut, data, rowHeights } = state;
1642
+ if (!data) {
1312
1643
  return;
1313
1644
  }
1314
- const state = refState.current;
1315
- const { sizes, indexByKey, columns, sizesLaidOut } = state;
1316
1645
  const index = indexByKey.get(itemKey);
1317
1646
  const numColumns = peek$(ctx, "numColumns");
1318
- const row = Math.floor(index / numColumns);
1319
- const prevSize = getRowHeight(row);
1647
+ state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, index) : index;
1648
+ const prevSize = getItemSize(itemKey, index, data);
1649
+ let needsCalculate = false;
1650
+ let needsUpdateContainersDidLayout = false;
1651
+ if (state.numPendingInitialLayout > 0) {
1652
+ state.numPendingInitialLayout--;
1653
+ if (state.numPendingInitialLayout === 0) {
1654
+ needsCalculate = true;
1655
+ state.numPendingInitialLayout = -1;
1656
+ needsUpdateContainersDidLayout = true;
1657
+ }
1658
+ }
1320
1659
  if (!prevSize || Math.abs(prevSize - size) > 0.5) {
1321
1660
  let diff;
1661
+ needsCalculate = true;
1322
1662
  if (numColumns > 1) {
1323
- const prevMaxSizeInRow = getRowHeight(row);
1663
+ const rowNumber = Math.floor(index / numColumnsProp);
1664
+ const prevSizeInRow = getRowHeight(rowNumber);
1324
1665
  sizes.set(itemKey, size);
1325
- const column = columns.get(itemKey);
1326
- const loopStart = index - (column - 1);
1327
- let nextMaxSizeInRow = 0;
1328
- for (let i = loopStart; i < loopStart + numColumns && i < data2.length; i++) {
1329
- const id = getId(i);
1330
- const size2 = getItemSize(id, i, data2[i]);
1331
- nextMaxSizeInRow = Math.max(nextMaxSizeInRow, size2);
1332
- }
1333
- diff = nextMaxSizeInRow - prevMaxSizeInRow;
1666
+ rowHeights.delete(rowNumber);
1667
+ const sizeInRow = getRowHeight(rowNumber);
1668
+ diff = sizeInRow - prevSizeInRow;
1334
1669
  } else {
1335
1670
  sizes.set(itemKey, size);
1336
1671
  diff = size - prevSize;
@@ -1356,38 +1691,77 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
1356
1691
  }
1357
1692
  refState.current.scrollForNextCalculateItemsInView = void 0;
1358
1693
  addTotalSize(itemKey, diff, 0);
1359
- doMaintainScrollAtEnd(true);
1694
+ doMaintainScrollAtEnd(false);
1695
+ if (onItemSizeChanged) {
1696
+ onItemSizeChanged({
1697
+ size,
1698
+ previous: prevSize,
1699
+ index,
1700
+ itemKey,
1701
+ itemData: data[index]
1702
+ });
1703
+ }
1704
+ }
1705
+ if (needsCalculate) {
1706
+ let fixingScroll = false;
1707
+ if (needsUpdateContainersDidLayout && initialScrollIndex && !state.didInitialScroll) {
1708
+ const updatedOffset = calculateOffsetForIndex(initialScrollIndex);
1709
+ state.didInitialScroll = true;
1710
+ if (updatedOffset !== initialContentOffset) {
1711
+ fixingScroll = true;
1712
+ scrollTo(updatedOffset, false);
1713
+ requestAnimationFrame(() => {
1714
+ const updatedOffset2 = calculateOffsetForIndex(initialScrollIndex);
1715
+ scrollTo(updatedOffset2, false);
1716
+ });
1717
+ }
1718
+ }
1360
1719
  const scrollVelocity = state.scrollVelocity;
1361
- if (!state.waitingForMicrotask && (Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1)) {
1362
- if (!peek$(ctx, "containersDidLayout")) {
1363
- state.waitingForMicrotask = true;
1364
- queueMicrotask(() => {
1365
- if (state.waitingForMicrotask) {
1366
- state.waitingForMicrotask = false;
1367
- calculateItemsInView(state.scrollVelocity);
1720
+ if ((Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1) && (!waitForInitialLayout || state.numPendingInitialLayout < 0)) {
1721
+ const setDidLayout = () => {
1722
+ set$(ctx, "containersDidLayout", true);
1723
+ if (reactNative.Platform.OS === "web") {
1724
+ setTimeout(() => {
1725
+ state.scrollAdjustHandler.setDisableAdjust(false);
1726
+ }, 32);
1727
+ }
1728
+ };
1729
+ if (Date.now() - state.lastBatchingAction < 500) {
1730
+ state.queuedCalculateItemsInView = requestAnimationFrame(() => {
1731
+ state.queuedCalculateItemsInView = void 0;
1732
+ calculateItemsInView();
1733
+ if (needsUpdateContainersDidLayout) {
1734
+ setDidLayout();
1368
1735
  }
1369
1736
  });
1370
1737
  } else {
1371
- calculateItemsInView(state.scrollVelocity);
1738
+ calculateItemsInView();
1739
+ if (needsUpdateContainersDidLayout) {
1740
+ if (fixingScroll) {
1741
+ requestAnimationFrame(setDidLayout);
1742
+ } else {
1743
+ queueMicrotask(setDidLayout);
1744
+ }
1745
+ }
1372
1746
  }
1373
1747
  }
1374
- if (onItemSizeChanged) {
1375
- onItemSizeChanged({ size, previous: prevSize, index, itemKey, itemData: data2[index] });
1376
- }
1377
1748
  }
1378
1749
  }, []);
1379
- const handleScrollDebounced = React5.useCallback((velocity) => {
1380
- calculateItemsInView(velocity);
1381
- checkAtBottom();
1382
- checkAtTop();
1383
- }, []);
1384
- const onLayout = React5.useCallback((event) => {
1750
+ const onLayout = React6.useCallback((event) => {
1751
+ const state = refState.current;
1385
1752
  const scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
1386
- refState.current.scrollLength = scrollLength;
1753
+ const didChange = scrollLength !== state.scrollLength;
1754
+ state.scrollLength = scrollLength;
1755
+ state.lastBatchingAction = Date.now();
1756
+ state.scrollForNextCalculateItemsInView = void 0;
1757
+ doInitialAllocateContainers();
1387
1758
  doMaintainScrollAtEnd(false);
1388
1759
  doUpdatePaddingTop();
1389
1760
  checkAtBottom();
1390
1761
  checkAtTop();
1762
+ if (didChange) {
1763
+ calculateItemsInView();
1764
+ }
1391
1765
  if (__DEV__) {
1392
1766
  const isWidthZero = event.nativeEvent.layout.width === 0;
1393
1767
  const isHeightZero = event.nativeEvent.layout.height === 0;
@@ -1397,17 +1771,24 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
1397
1771
  );
1398
1772
  }
1399
1773
  }
1774
+ if (onLayoutProp) {
1775
+ onLayoutProp(event);
1776
+ }
1400
1777
  }, []);
1401
- const handleScroll = React5.useCallback(
1778
+ const handleScroll = React6.useCallback(
1402
1779
  (event, fromSelf) => {
1403
- var _a2, _b2, _c2;
1780
+ var _a2, _b2, _c2, _d2;
1404
1781
  if (((_b2 = (_a2 = event.nativeEvent) == null ? void 0 : _a2.contentSize) == null ? void 0 : _b2.height) === 0 && ((_c2 = event.nativeEvent.contentSize) == null ? void 0 : _c2.width) === 0) {
1405
1782
  return;
1406
1783
  }
1407
1784
  const state = refState.current;
1785
+ const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
1786
+ if (state.ignoreScrollFromCalcTotal && newScroll !== 0) {
1787
+ return;
1788
+ }
1408
1789
  state.hasScrolled = true;
1790
+ state.lastBatchingAction = Date.now();
1409
1791
  const currentTime = performance.now();
1410
- const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
1411
1792
  if (!(state.scrollHistory.length === 0 && newScroll === initialContentOffset)) {
1412
1793
  state.scrollHistory.push({ scroll: newScroll, time: currentTime });
1413
1794
  }
@@ -1433,71 +1814,173 @@ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forward
1433
1814
  state.scroll = newScroll;
1434
1815
  state.scrollTime = currentTime;
1435
1816
  state.scrollVelocity = velocity;
1436
- handleScrollDebounced(velocity);
1817
+ calculateItemsInView();
1818
+ checkAtBottom();
1819
+ checkAtTop();
1437
1820
  if (!fromSelf) {
1438
- onScrollProp == null ? void 0 : onScrollProp(event);
1821
+ (_d2 = state.onScroll) == null ? void 0 : _d2.call(state, event);
1439
1822
  }
1440
1823
  },
1441
1824
  []
1442
1825
  );
1443
- React5.useImperativeHandle(
1826
+ React6.useImperativeHandle(
1444
1827
  forwardedRef,
1445
1828
  () => {
1446
- const scrollToIndex = ({ index, animated }) => {
1447
- const offsetObj = calculateInitialOffset(index);
1448
- const offset = horizontal ? { x: offsetObj, y: 0 } : { x: 0, y: offsetObj };
1449
- refScroller.current.scrollTo({ ...offset, animated });
1829
+ const scrollToIndex = ({
1830
+ index,
1831
+ viewOffset = 0,
1832
+ animated = true,
1833
+ viewPosition = 0
1834
+ }) => {
1835
+ var _a2;
1836
+ const state = refState.current;
1837
+ const firstIndexOffset = calculateOffsetForIndex(index);
1838
+ let firstIndexScrollPostion = firstIndexOffset - viewOffset;
1839
+ const diff = Math.abs(state.scroll - firstIndexScrollPostion);
1840
+ const needsReanchoring = maintainVisibleContentPosition && diff > 100;
1841
+ state.scrollForNextCalculateItemsInView = void 0;
1842
+ if (needsReanchoring) {
1843
+ const id = getId(index);
1844
+ state.anchorElement = { id, coordinate: firstIndexOffset };
1845
+ (_a2 = state.belowAnchorElementPositions) == null ? void 0 : _a2.clear();
1846
+ state.positions.clear();
1847
+ calcTotalSizesAndPositions({ forgetPositions: true });
1848
+ state.startBufferedId = id;
1849
+ state.minIndexSizeChanged = index;
1850
+ firstIndexScrollPostion = firstIndexOffset - viewOffset + state.scrollAdjustHandler.getAppliedAdjust();
1851
+ }
1852
+ state.scrollAdjustHandler.setDisableAdjust(true);
1853
+ setTimeout(
1854
+ () => {
1855
+ state.scrollAdjustHandler.setDisableAdjust(false);
1856
+ calculateItemsInView();
1857
+ },
1858
+ animated ? 150 : 50
1859
+ );
1860
+ if (viewPosition) {
1861
+ firstIndexScrollPostion -= viewPosition * (state.scrollLength - getItemSize(getId(index), index, state.data[index]));
1862
+ }
1863
+ scrollTo(firstIndexScrollPostion, animated);
1864
+ const totalSizeWithScrollAdjust = peek$(ctx, "totalSizeWithScrollAdjust");
1865
+ if (maintainVisibleContentPosition && totalSizeWithScrollAdjust - firstIndexScrollPostion < state.scrollLength) {
1866
+ const doScrollTo = () => {
1867
+ scrollTo(firstIndexScrollPostion, animated);
1868
+ };
1869
+ setTimeout(doScrollTo, animated ? 150 : 50);
1870
+ if (animated) {
1871
+ setTimeout(doScrollTo, 350);
1872
+ }
1873
+ }
1874
+ };
1875
+ const scrollIndexIntoView = (options) => {
1876
+ if (refState.current) {
1877
+ const { index, ...rest2 } = options;
1878
+ const { startNoBuffer, endNoBuffer } = refState.current;
1879
+ if (index < startNoBuffer || index > endNoBuffer) {
1880
+ const viewPosition = index < startNoBuffer ? 0 : 1;
1881
+ scrollToIndex({
1882
+ ...rest2,
1883
+ viewPosition,
1884
+ index
1885
+ });
1886
+ }
1887
+ }
1450
1888
  };
1451
1889
  return {
1890
+ flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
1452
1891
  getNativeScrollRef: () => refScroller.current,
1453
- getScrollableNode: refScroller.current.getScrollableNode,
1454
- getScrollResponder: refScroller.current.getScrollResponder,
1455
- flashScrollIndicators: refScroller.current.flashScrollIndicators,
1456
- scrollToIndex,
1457
- scrollToOffset: ({ offset, animated }) => {
1458
- const offsetObj = horizontal ? { x: offset, y: 0 } : { x: 0, y: offset };
1459
- refScroller.current.scrollTo({ ...offsetObj, animated });
1892
+ getScrollableNode: () => refScroller.current.getScrollableNode(),
1893
+ getScrollResponder: () => refScroller.current.getScrollResponder(),
1894
+ getState: () => {
1895
+ const state = refState.current;
1896
+ return state ? {
1897
+ contentLength: state.totalSize,
1898
+ end: state.endNoBuffer,
1899
+ endBuffered: state.endBuffered,
1900
+ isAtEnd: state.isAtBottom,
1901
+ isAtStart: state.isAtTop,
1902
+ scroll: state.scroll,
1903
+ scrollLength: state.scrollLength,
1904
+ start: state.startNoBuffer,
1905
+ startBuffered: state.startBuffered
1906
+ } : {};
1907
+ },
1908
+ scrollIndexIntoView,
1909
+ scrollItemIntoView: ({ item, ...props2 }) => {
1910
+ const { data } = refState.current;
1911
+ const index = data.indexOf(item);
1912
+ if (index !== -1) {
1913
+ scrollIndexIntoView({ index, ...props2 });
1914
+ }
1460
1915
  },
1461
- scrollToItem: ({ item, animated }) => {
1916
+ scrollToIndex,
1917
+ scrollToItem: ({ item, ...props2 }) => {
1918
+ const { data } = refState.current;
1462
1919
  const index = data.indexOf(item);
1463
1920
  if (index !== -1) {
1464
- scrollToIndex({ index, animated });
1921
+ scrollToIndex({ index, ...props2 });
1465
1922
  }
1466
1923
  },
1467
- scrollToEnd: refScroller.current.scrollToEnd
1924
+ scrollToOffset: ({ offset, animated }) => {
1925
+ scrollTo(offset, animated);
1926
+ },
1927
+ scrollToEnd: (options) => refScroller.current.scrollToEnd(options)
1468
1928
  };
1469
1929
  },
1470
1930
  []
1471
1931
  );
1472
- return /* @__PURE__ */ React5__namespace.createElement(
1932
+ if (reactNative.Platform.OS === "web") {
1933
+ React6.useEffect(() => {
1934
+ var _a2;
1935
+ if (initialContentOffset) {
1936
+ (_a2 = refState.current) == null ? void 0 : _a2.scrollAdjustHandler.setDisableAdjust(true);
1937
+ scrollTo(initialContentOffset, false);
1938
+ setTimeout(() => {
1939
+ var _a3;
1940
+ (_a3 = refState.current) == null ? void 0 : _a3.scrollAdjustHandler.setDisableAdjust(false);
1941
+ }, 0);
1942
+ }
1943
+ }, []);
1944
+ }
1945
+ return /* @__PURE__ */ React6__namespace.createElement(React6__namespace.Fragment, null, /* @__PURE__ */ React6__namespace.createElement(
1473
1946
  ListComponent,
1474
1947
  {
1475
1948
  ...rest,
1476
1949
  horizontal,
1477
- refScrollView: (r) => {
1478
- refScroller.current = r;
1479
- if (refScrollView) {
1480
- if (typeof refScrollView === "function") {
1481
- refScrollView(r);
1482
- } else {
1483
- refScrollView.current = r;
1484
- }
1485
- }
1486
- },
1950
+ refScrollView: combinedRef,
1487
1951
  initialContentOffset,
1488
1952
  getRenderedItem,
1489
1953
  updateItemSize,
1490
1954
  handleScroll,
1955
+ onMomentumScrollEnd: (event) => {
1956
+ const wasPaused = refState.current.scrollAdjustHandler.unPauseAdjust();
1957
+ if (wasPaused) {
1958
+ refState.current.scrollVelocity = 0;
1959
+ refState.current.scrollHistory = [];
1960
+ calculateItemsInView();
1961
+ }
1962
+ if (onMomentumScrollEnd) {
1963
+ onMomentumScrollEnd(event);
1964
+ }
1965
+ },
1491
1966
  onLayout,
1492
1967
  recycleItems,
1493
1968
  alignItemsAtEnd,
1494
- ListEmptyComponent: data.length === 0 ? ListEmptyComponent : void 0,
1969
+ ListEmptyComponent: dataProp.length === 0 ? ListEmptyComponent : void 0,
1495
1970
  maintainVisibleContentPosition,
1496
1971
  scrollEventThrottle: scrollEventThrottle != null ? scrollEventThrottle : reactNative.Platform.OS === "web" ? 16 : void 0,
1497
1972
  waitForInitialLayout,
1973
+ refreshControl: refreshControl != null ? refreshControl : onRefresh && /* @__PURE__ */ React6__namespace.createElement(
1974
+ reactNative.RefreshControl,
1975
+ {
1976
+ refreshing: !!refreshing,
1977
+ onRefresh,
1978
+ progressViewOffset
1979
+ }
1980
+ ),
1498
1981
  style
1499
1982
  }
1500
- );
1983
+ ), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React6__namespace.createElement(DebugView, { state: refState.current }));
1501
1984
  });
1502
1985
 
1503
1986
  exports.LegendList = LegendList;