@legendapp/list 2.0.9 → 2.0.10

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 React2 = require('react');
3
+ var React3 = require('react');
4
4
  var reactNative = require('react-native');
5
5
  var shim = require('use-sync-external-store/shim');
6
6
 
@@ -22,12 +22,12 @@ function _interopNamespace(e) {
22
22
  return Object.freeze(n);
23
23
  }
24
24
 
25
- var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
25
+ var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
26
26
 
27
27
  // src/components/LegendList.tsx
28
- var ContextState = React2__namespace.createContext(null);
28
+ var ContextState = React3__namespace.createContext(null);
29
29
  function StateProvider({ children }) {
30
- const [value] = React2__namespace.useState(() => ({
30
+ const [value] = React3__namespace.useState(() => ({
31
31
  animatedScrollY: new reactNative.Animated.Value(0),
32
32
  columnWrapperStyle: void 0,
33
33
  internalState: void 0,
@@ -46,10 +46,10 @@ function StateProvider({ children }) {
46
46
  ]),
47
47
  viewRefs: /* @__PURE__ */ new Map()
48
48
  }));
49
- return /* @__PURE__ */ React2__namespace.createElement(ContextState.Provider, { value }, children);
49
+ return /* @__PURE__ */ React3__namespace.createElement(ContextState.Provider, { value }, children);
50
50
  }
51
51
  function useStateContext() {
52
- return React2__namespace.useContext(ContextState);
52
+ return React3__namespace.useContext(ContextState);
53
53
  }
54
54
  function createSelectorFunctionsArr(ctx, signalNames) {
55
55
  let lastValues = [];
@@ -119,23 +119,23 @@ function getContentSize(ctx) {
119
119
  return headerSize + footerSize + totalSize + stylePaddingTop;
120
120
  }
121
121
  function useArr$(signalNames) {
122
- const ctx = React2__namespace.useContext(ContextState);
123
- const { subscribe, get } = React2__namespace.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
122
+ const ctx = React3__namespace.useContext(ContextState);
123
+ const { subscribe, get } = React3__namespace.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
124
124
  const value = shim.useSyncExternalStore(subscribe, get);
125
125
  return value;
126
126
  }
127
127
  function useSelector$(signalName, selector) {
128
- const ctx = React2__namespace.useContext(ContextState);
129
- const { subscribe, get } = React2__namespace.useMemo(() => createSelectorFunctionsArr(ctx, [signalName]), [ctx, signalName]);
128
+ const ctx = React3__namespace.useContext(ContextState);
129
+ const { subscribe, get } = React3__namespace.useMemo(() => createSelectorFunctionsArr(ctx, [signalName]), [ctx, signalName]);
130
130
  const value = shim.useSyncExternalStore(subscribe, () => selector(get()[0]));
131
131
  return value;
132
132
  }
133
133
 
134
134
  // src/components/DebugView.tsx
135
135
  var DebugRow = ({ children }) => {
136
- return /* @__PURE__ */ React2__namespace.createElement(reactNative.View, { style: { alignItems: "center", flexDirection: "row", justifyContent: "space-between" } }, children);
136
+ return /* @__PURE__ */ React3__namespace.createElement(reactNative.View, { style: { alignItems: "center", flexDirection: "row", justifyContent: "space-between" } }, children);
137
137
  };
138
- var DebugView = React2__namespace.memo(function DebugView2({ state }) {
138
+ var DebugView = React3__namespace.memo(function DebugView2({ state }) {
139
139
  const ctx = useStateContext();
140
140
  const [totalSize = 0, scrollAdjust = 0, rawScroll = 0, scroll = 0, _numContainers = 0, _numContainersPooled = 0] = useArr$([
141
141
  "totalSize",
@@ -146,11 +146,11 @@ var DebugView = React2__namespace.memo(function DebugView2({ state }) {
146
146
  "numContainersPooled"
147
147
  ]);
148
148
  const contentSize = getContentSize(ctx);
149
- const [, forceUpdate] = React2.useReducer((x) => x + 1, 0);
149
+ const [, forceUpdate] = React3.useReducer((x) => x + 1, 0);
150
150
  useInterval(() => {
151
151
  forceUpdate();
152
152
  }, 100);
153
- return /* @__PURE__ */ React2__namespace.createElement(
153
+ return /* @__PURE__ */ React3__namespace.createElement(
154
154
  reactNative.View,
155
155
  {
156
156
  pointerEvents: "none",
@@ -166,27 +166,22 @@ var DebugView = React2__namespace.memo(function DebugView2({ state }) {
166
166
  top: 0
167
167
  }
168
168
  },
169
- /* @__PURE__ */ React2__namespace.createElement(DebugRow, null, /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, "TotalSize:"), /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, totalSize.toFixed(2))),
170
- /* @__PURE__ */ React2__namespace.createElement(DebugRow, null, /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, "ContentSize:"), /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, contentSize.toFixed(2))),
171
- /* @__PURE__ */ React2__namespace.createElement(DebugRow, null, /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, "At end:"), /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, String(state.isAtEnd))),
172
- /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null),
173
- /* @__PURE__ */ React2__namespace.createElement(DebugRow, null, /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, "ScrollAdjust:"), /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, scrollAdjust.toFixed(2))),
174
- /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null),
175
- /* @__PURE__ */ React2__namespace.createElement(DebugRow, null, /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, "RawScroll: "), /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, rawScroll.toFixed(2))),
176
- /* @__PURE__ */ React2__namespace.createElement(DebugRow, null, /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, "ComputedScroll: "), /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, scroll.toFixed(2)))
169
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "TotalSize:"), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, totalSize.toFixed(2))),
170
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "ContentSize:"), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, contentSize.toFixed(2))),
171
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "At end:"), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, String(state.isAtEnd))),
172
+ /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null),
173
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "ScrollAdjust:"), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, scrollAdjust.toFixed(2))),
174
+ /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null),
175
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "RawScroll: "), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, rawScroll.toFixed(2))),
176
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "ComputedScroll: "), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, scroll.toFixed(2)))
177
177
  );
178
178
  });
179
179
  function useInterval(callback, delay) {
180
- React2.useEffect(() => {
180
+ React3.useEffect(() => {
181
181
  const interval = setInterval(callback, delay);
182
182
  return () => clearInterval(interval);
183
183
  }, [delay]);
184
184
  }
185
- var LeanViewComponent = React2__namespace.forwardRef((props, ref) => {
186
- return React2__namespace.createElement("RCTView", { ...props, ref });
187
- });
188
- LeanViewComponent.displayName = "RCTView";
189
- var LeanView = reactNative.Platform.OS === "android" || reactNative.Platform.OS === "ios" ? LeanViewComponent : reactNative.View;
190
185
 
191
186
  // src/constants.ts
192
187
  var POSITION_OUT_OF_VIEW = -1e7;
@@ -194,7 +189,7 @@ var ENABLE_DEVMODE = __DEV__ && false;
194
189
  var ENABLE_DEBUG_VIEW = __DEV__ && false;
195
190
  var IsNewArchitecture = global.nativeFabricUIManager != null;
196
191
  var useAnimatedValue = (initialValue) => {
197
- return React2.useRef(new reactNative.Animated.Value(initialValue)).current;
192
+ return React3.useRef(new reactNative.Animated.Value(initialValue)).current;
198
193
  };
199
194
 
200
195
  // src/hooks/useValue$.ts
@@ -203,7 +198,7 @@ function useValue$(key, params) {
203
198
  const { getValue, delay } = params || {};
204
199
  const ctx = useStateContext();
205
200
  const animValue = useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
206
- React2.useMemo(() => {
201
+ React3.useMemo(() => {
207
202
  let newValue;
208
203
  let prevValue;
209
204
  let didQueueTask = false;
@@ -235,8 +230,8 @@ function useValue$(key, params) {
235
230
  }, []);
236
231
  return animValue;
237
232
  }
238
- var typedForwardRef = React2.forwardRef;
239
- var typedMemo = React2.memo;
233
+ var typedForwardRef = React3.forwardRef;
234
+ var typedMemo = React3.memo;
240
235
 
241
236
  // src/components/PositionView.tsx
242
237
  var PositionViewState = typedMemo(function PositionView({
@@ -247,8 +242,8 @@ var PositionViewState = typedMemo(function PositionView({
247
242
  ...rest
248
243
  }) {
249
244
  const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
250
- return /* @__PURE__ */ React2__namespace.createElement(
251
- LeanView,
245
+ return /* @__PURE__ */ React3__namespace.createElement(
246
+ reactNative.View,
252
247
  {
253
248
  ref: refView,
254
249
  style: [
@@ -275,7 +270,7 @@ var PositionViewAnimated = typedMemo(function PositionView2({
275
270
  } else {
276
271
  position = horizontal ? { left: position$ } : { top: position$ };
277
272
  }
278
- return /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { ref: refView, style: [style, position], ...rest });
273
+ return /* @__PURE__ */ React3__namespace.createElement(reactNative.Animated.View, { ref: refView, style: [style, position], ...rest });
279
274
  });
280
275
  var PositionViewSticky = typedMemo(function PositionViewSticky2({
281
276
  id,
@@ -288,8 +283,8 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
288
283
  ...rest
289
284
  }) {
290
285
  const [position = POSITION_OUT_OF_VIEW, headerSize] = useArr$([`containerPosition${id}`, "headerSize"]);
291
- const transform = React2__namespace.useMemo(() => {
292
- if (animatedScrollY && stickyOffset) {
286
+ const transform = React3__namespace.useMemo(() => {
287
+ if (animatedScrollY && stickyOffset !== void 0) {
293
288
  const stickyPosition = animatedScrollY.interpolate({
294
289
  extrapolate: "clamp",
295
290
  inputRange: [position + headerSize, position + 5e3 + headerSize],
@@ -298,13 +293,13 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
298
293
  return horizontal ? [{ translateX: stickyPosition }] : [{ translateY: stickyPosition }];
299
294
  }
300
295
  }, [animatedScrollY, headerSize, horizontal, stickyOffset, position]);
301
- const viewStyle = React2__namespace.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
302
- return /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { ref: refView, style: viewStyle, ...rest });
296
+ const viewStyle = React3__namespace.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
297
+ return /* @__PURE__ */ React3__namespace.createElement(reactNative.Animated.View, { ref: refView, style: viewStyle, ...rest });
303
298
  });
304
299
  var PositionView3 = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
305
300
  var symbolFirst = Symbol();
306
301
  function useInit(cb) {
307
- const refValue = React2.useRef(symbolFirst);
302
+ const refValue = React3.useRef(symbolFirst);
308
303
  if (refValue.current === symbolFirst) {
309
304
  refValue.current = cb();
310
305
  }
@@ -343,10 +338,10 @@ function extractPadding(style, contentContainerStyle, type) {
343
338
  }
344
339
 
345
340
  // src/state/ContextContainer.ts
346
- var ContextContainer = React2.createContext(null);
341
+ var ContextContainer = React3.createContext(null);
347
342
  function useViewability(callback, configId) {
348
343
  const ctx = useStateContext();
349
- const { containerId } = React2.useContext(ContextContainer);
344
+ const { containerId } = React3.useContext(ContextContainer);
350
345
  const key = containerId + (configId != null ? configId : "");
351
346
  useInit(() => {
352
347
  const value = ctx.mapViewabilityValues.get(key);
@@ -355,7 +350,7 @@ function useViewability(callback, configId) {
355
350
  }
356
351
  });
357
352
  ctx.mapViewabilityCallbacks.set(key, callback);
358
- React2.useEffect(
353
+ React3.useEffect(
359
354
  () => () => {
360
355
  ctx.mapViewabilityCallbacks.delete(key);
361
356
  },
@@ -364,7 +359,7 @@ function useViewability(callback, configId) {
364
359
  }
365
360
  function useViewabilityAmount(callback) {
366
361
  const ctx = useStateContext();
367
- const { containerId } = React2.useContext(ContextContainer);
362
+ const { containerId } = React3.useContext(ContextContainer);
368
363
  useInit(() => {
369
364
  const value = ctx.mapViewabilityAmountValues.get(containerId);
370
365
  if (value) {
@@ -372,7 +367,7 @@ function useViewabilityAmount(callback) {
372
367
  }
373
368
  });
374
369
  ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
375
- React2.useEffect(
370
+ React3.useEffect(
376
371
  () => () => {
377
372
  ctx.mapViewabilityAmountCallbacks.delete(containerId);
378
373
  },
@@ -380,12 +375,12 @@ function useViewabilityAmount(callback) {
380
375
  );
381
376
  }
382
377
  function useRecyclingEffect(effect) {
383
- const { index, value } = React2.useContext(ContextContainer);
384
- const prevValues = React2.useRef({
378
+ const { index, value } = React3.useContext(ContextContainer);
379
+ const prevValues = React3.useRef({
385
380
  prevIndex: void 0,
386
381
  prevItem: void 0
387
382
  });
388
- React2.useEffect(() => {
383
+ React3.useEffect(() => {
389
384
  let ret;
390
385
  if (prevValues.current.prevIndex !== void 0 && prevValues.current.prevItem !== void 0) {
391
386
  ret = effect({
@@ -403,12 +398,12 @@ function useRecyclingEffect(effect) {
403
398
  }, [index, value, effect]);
404
399
  }
405
400
  function useRecyclingState(valueOrFun) {
406
- const { index, value, itemKey, triggerLayout } = React2.useContext(ContextContainer);
407
- const refState = React2.useRef({
401
+ const { index, value, itemKey, triggerLayout } = React3.useContext(ContextContainer);
402
+ const refState = React3.useRef({
408
403
  itemKey: null,
409
404
  value: null
410
405
  });
411
- const [_, setRenderNum] = React2.useState(0);
406
+ const [_, setRenderNum] = React3.useState(0);
412
407
  const state = refState.current;
413
408
  if (state.itemKey !== itemKey) {
414
409
  state.itemKey = itemKey;
@@ -419,7 +414,7 @@ function useRecyclingState(valueOrFun) {
419
414
  prevItem: void 0
420
415
  }) : valueOrFun;
421
416
  }
422
- const setState = React2.useCallback(
417
+ const setState = React3.useCallback(
423
418
  (newState) => {
424
419
  state.value = isFunction(newState) ? newState(state.value) : newState;
425
420
  setRenderNum((v) => v + 1);
@@ -430,7 +425,7 @@ function useRecyclingState(valueOrFun) {
430
425
  return [state.value, setState];
431
426
  }
432
427
  function useIsLastItem() {
433
- const { itemKey } = React2.useContext(ContextContainer);
428
+ const { itemKey } = React3.useContext(ContextContainer);
434
429
  const isLast = useSelector$("lastItemKeys", (lastItemKeys) => (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false);
435
430
  return isLast;
436
431
  }
@@ -442,7 +437,7 @@ var noop = () => {
442
437
  };
443
438
  function useSyncLayout() {
444
439
  if (IsNewArchitecture) {
445
- const { triggerLayout: syncLayout } = React2.useContext(ContextContainer);
440
+ const { triggerLayout: syncLayout } = React3.useContext(ContextContainer);
446
441
  return syncLayout;
447
442
  } else {
448
443
  return noop;
@@ -452,7 +447,30 @@ function useSyncLayout() {
452
447
  // src/components/Separator.tsx
453
448
  function Separator({ ItemSeparatorComponent, leadingItem }) {
454
449
  const isLastItem = useIsLastItem();
455
- return isLastItem ? null : /* @__PURE__ */ React2__namespace.createElement(ItemSeparatorComponent, { leadingItem });
450
+ return isLastItem ? null : /* @__PURE__ */ React3__namespace.createElement(ItemSeparatorComponent, { leadingItem });
451
+ }
452
+ function useOnLayoutSync({
453
+ ref,
454
+ onLayoutProp,
455
+ onLayoutChange
456
+ }, deps = []) {
457
+ const onLayout = React3.useCallback(
458
+ (event) => {
459
+ onLayoutChange(event.nativeEvent.layout, false);
460
+ onLayoutProp == null ? void 0 : onLayoutProp(event);
461
+ },
462
+ [onLayoutChange]
463
+ );
464
+ if (IsNewArchitecture) {
465
+ React3.useLayoutEffect(() => {
466
+ if (ref.current) {
467
+ ref.current.measure((x, y, width, height) => {
468
+ onLayoutChange({ height, width, x, y }, true);
469
+ });
470
+ }
471
+ }, deps);
472
+ }
473
+ return { onLayout };
456
474
  }
457
475
 
458
476
  // src/components/Container.tsx
@@ -475,13 +493,13 @@ var Container = typedMemo(function Container2({
475
493
  `containerSticky${id}`,
476
494
  `containerStickyOffset${id}`
477
495
  ]);
478
- const refLastSize = React2.useRef();
479
- const ref = React2.useRef(null);
480
- const [layoutRenderCount, forceLayoutRender] = React2.useState(0);
496
+ const refLastSize = React3.useRef();
497
+ const ref = React3.useRef(null);
498
+ const [layoutRenderCount, forceLayoutRender] = React3.useState(0);
481
499
  const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
482
500
  const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
483
- let didLayout = false;
484
- const style = React2.useMemo(() => {
501
+ const didLayoutRef = React3.useRef(false);
502
+ const style = React3.useMemo(() => {
485
503
  let paddingStyles;
486
504
  if (columnWrapperStyle) {
487
505
  const { columnGap, rowGap, gap } = columnWrapperStyle;
@@ -513,12 +531,12 @@ var Container = typedMemo(function Container2({
513
531
  ...paddingStyles || {}
514
532
  };
515
533
  }, [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns]);
516
- const renderedItemInfo = React2.useMemo(
534
+ const renderedItemInfo = React3.useMemo(
517
535
  () => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
518
536
  [itemKey, data, extraData]
519
537
  );
520
538
  const { index, renderedItem } = renderedItemInfo || {};
521
- const contextValue = React2.useMemo(() => {
539
+ const contextValue = React3.useMemo(() => {
522
540
  ctx.viewRefs.set(id, ref);
523
541
  return {
524
542
  containerId: id,
@@ -530,15 +548,16 @@ var Container = typedMemo(function Container2({
530
548
  value: data
531
549
  };
532
550
  }, [id, itemKey, index, data]);
533
- const onLayout = (event) => {
551
+ const onLayoutChange = (rectangle) => {
534
552
  var _a, _b;
535
553
  if (!isNullOrUndefined(itemKey)) {
536
- didLayout = true;
537
- let layout = event.nativeEvent.layout;
538
- const size = layout[horizontal ? "width" : "height"];
554
+ didLayoutRef.current = true;
555
+ let layout = rectangle;
556
+ const size = Math.floor(rectangle[horizontal ? "width" : "height"] * 8) / 8;
539
557
  const doUpdate = () => {
540
558
  refLastSize.current = { height: layout.height, width: layout.width };
541
559
  updateItemSize2(itemKey, layout);
560
+ didLayoutRef.current = true;
542
561
  };
543
562
  if (IsNewArchitecture || size > 0) {
544
563
  doUpdate();
@@ -550,25 +569,20 @@ var Container = typedMemo(function Container2({
550
569
  }
551
570
  }
552
571
  };
553
- if (IsNewArchitecture) {
554
- React2.useLayoutEffect(() => {
555
- var _a, _b;
556
- if (!isNullOrUndefined(itemKey)) {
557
- const measured = (_b = (_a = ref.current) == null ? void 0 : _a.unstable_getBoundingClientRect) == null ? void 0 : _b.call(_a);
558
- if (measured) {
559
- const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
560
- if (size) {
561
- updateItemSize2(itemKey, measured);
562
- }
563
- }
564
- }
565
- }, [itemKey, layoutRenderCount]);
566
- } else {
567
- React2.useEffect(() => {
572
+ const { onLayout } = useOnLayoutSync(
573
+ {
574
+ onLayoutChange,
575
+ ref
576
+ },
577
+ [itemKey, layoutRenderCount]
578
+ );
579
+ if (!IsNewArchitecture) {
580
+ React3.useEffect(() => {
568
581
  if (!isNullOrUndefined(itemKey)) {
569
582
  const timeout = setTimeout(() => {
570
- if (!didLayout && refLastSize.current) {
583
+ if (!didLayoutRef.current && refLastSize.current) {
571
584
  updateItemSize2(itemKey, refLastSize.current);
585
+ didLayoutRef.current = true;
572
586
  }
573
587
  }, 16);
574
588
  return () => {
@@ -578,7 +592,7 @@ var Container = typedMemo(function Container2({
578
592
  }, [itemKey]);
579
593
  }
580
594
  const PositionComponent = isSticky ? PositionViewSticky : PositionView3;
581
- return /* @__PURE__ */ React2__namespace.createElement(
595
+ return /* @__PURE__ */ React3__namespace.createElement(
582
596
  PositionComponent,
583
597
  {
584
598
  animatedScrollY: isSticky ? animatedScrollY : void 0,
@@ -591,7 +605,7 @@ var Container = typedMemo(function Container2({
591
605
  stickyOffset: isSticky ? stickyOffset : void 0,
592
606
  style
593
607
  },
594
- /* @__PURE__ */ React2__namespace.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React2__namespace.createElement(Separator, { ItemSeparatorComponent, leadingItem: renderedItemInfo.item }))
608
+ /* @__PURE__ */ React3__namespace.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React3__namespace.createElement(Separator, { ItemSeparatorComponent, leadingItem: renderedItemInfo.item }))
595
609
  );
596
610
  });
597
611
 
@@ -620,7 +634,7 @@ var Containers = typedMemo(function Containers2({
620
634
  const containers = [];
621
635
  for (let i = 0; i < numContainers; i++) {
622
636
  containers.push(
623
- /* @__PURE__ */ React2__namespace.createElement(
637
+ /* @__PURE__ */ React3__namespace.createElement(
624
638
  Container,
625
639
  {
626
640
  getRenderedItem: getRenderedItem2,
@@ -655,13 +669,18 @@ var Containers = typedMemo(function Containers2({
655
669
  }
656
670
  }
657
671
  }
658
- return /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { style }, containers);
672
+ return /* @__PURE__ */ React3__namespace.createElement(reactNative.Animated.View, { style }, containers);
659
673
  });
674
+ var LayoutView = ({ onLayoutChange, refView, ...rest }) => {
675
+ const ref = refView != null ? refView : React3.useRef();
676
+ const { onLayout } = useOnLayoutSync({ onLayoutChange, ref });
677
+ return /* @__PURE__ */ React.createElement(reactNative.View, { ...rest, onLayout, ref });
678
+ };
660
679
  function ScrollAdjust() {
661
680
  const bias = 1e7;
662
681
  const [scrollAdjust, scrollAdjustUserOffset] = useArr$(["scrollAdjust", "scrollAdjustUserOffset"]);
663
682
  const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0) + bias;
664
- return /* @__PURE__ */ React2__namespace.createElement(
683
+ return /* @__PURE__ */ React3__namespace.createElement(
665
684
  reactNative.View,
666
685
  {
667
686
  style: {
@@ -676,88 +695,26 @@ function ScrollAdjust() {
676
695
  }
677
696
  function SnapWrapper({ ScrollComponent, ...props }) {
678
697
  const [snapToOffsets] = useArr$(["snapToOffsets"]);
679
- return /* @__PURE__ */ React2__namespace.default.createElement(ScrollComponent, { ...props, snapToOffsets });
680
- }
681
- function useThrottleDebounce(mode) {
682
- const timeoutRef = React2.useRef(null);
683
- const lastCallTimeRef = React2.useRef(0);
684
- const lastArgsRef = React2.useRef(null);
685
- const clearTimeoutRef = () => {
686
- if (timeoutRef.current) {
687
- clearTimeout(timeoutRef.current);
688
- timeoutRef.current = null;
689
- }
690
- };
691
- const execute = React2.useCallback(
692
- (callback, delay, ...args) => {
693
- {
694
- const now = Date.now();
695
- lastArgsRef.current = args;
696
- if (now - lastCallTimeRef.current >= delay) {
697
- lastCallTimeRef.current = now;
698
- callback(...args);
699
- clearTimeoutRef();
700
- } else {
701
- clearTimeoutRef();
702
- timeoutRef.current = setTimeout(
703
- () => {
704
- if (lastArgsRef.current) {
705
- lastCallTimeRef.current = Date.now();
706
- callback(...lastArgsRef.current);
707
- timeoutRef.current = null;
708
- lastArgsRef.current = null;
709
- }
710
- },
711
- delay - (now - lastCallTimeRef.current)
712
- );
713
- }
714
- }
715
- },
716
- [mode]
717
- );
718
- return execute;
719
- }
720
-
721
- // src/hooks/useSyncLayout.tsx
722
- function useSyncLayout2({
723
- onChange
724
- }) {
725
- const ref = React2.useRef(null);
726
- const onLayout = React2.useCallback(
727
- (event) => {
728
- onChange(event.nativeEvent.layout, false);
729
- },
730
- [onChange]
731
- );
732
- if (IsNewArchitecture) {
733
- React2.useLayoutEffect(() => {
734
- if (ref.current) {
735
- ref.current.measure((x, y, width, height) => {
736
- onChange({ height, width, x, y }, true);
737
- });
738
- }
739
- }, []);
740
- }
741
- return { onLayout, ref };
698
+ return /* @__PURE__ */ React3__namespace.default.createElement(ScrollComponent, { ...props, snapToOffsets });
742
699
  }
743
700
 
744
701
  // src/components/ListComponent.tsx
745
702
  var getComponent = (Component) => {
746
- if (React2__namespace.isValidElement(Component)) {
703
+ if (React3__namespace.isValidElement(Component)) {
747
704
  return Component;
748
705
  }
749
706
  if (Component) {
750
- return /* @__PURE__ */ React2__namespace.createElement(Component, null);
707
+ return /* @__PURE__ */ React3__namespace.createElement(Component, null);
751
708
  }
752
709
  return null;
753
710
  };
754
711
  var Padding = () => {
755
712
  const animPaddingTop = useValue$("alignItemsPaddingTop", { delay: 0 });
756
- return /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { style: { paddingTop: animPaddingTop } });
713
+ return /* @__PURE__ */ React3__namespace.createElement(reactNative.Animated.View, { style: { paddingTop: animPaddingTop } });
757
714
  };
758
715
  var PaddingDevMode = () => {
759
716
  const animPaddingTop = useValue$("alignItemsPaddingTop", { delay: 0 });
760
- return /* @__PURE__ */ React2__namespace.createElement(React2__namespace.Fragment, null, /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { style: { paddingTop: animPaddingTop } }), /* @__PURE__ */ React2__namespace.createElement(
717
+ return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Animated.View, { style: { paddingTop: animPaddingTop } }), /* @__PURE__ */ React3__namespace.createElement(
761
718
  reactNative.Animated.View,
762
719
  {
763
720
  style: {
@@ -800,14 +757,11 @@ var ListComponent = typedMemo(function ListComponent2({
800
757
  ...rest
801
758
  }) {
802
759
  const ctx = useStateContext();
803
- const { onLayout: onLayoutHeaderSync, ref: refHeader } = useSyncLayout2({
804
- onChange: onLayoutHeader
805
- });
806
- const ScrollComponent = renderScrollComponent ? React2.useMemo(
807
- () => React2__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
760
+ const ScrollComponent = renderScrollComponent ? React3.useMemo(
761
+ () => React3__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
808
762
  [renderScrollComponent]
809
763
  ) : reactNative.Animated.ScrollView;
810
- React2__namespace.useEffect(() => {
764
+ React3__namespace.useEffect(() => {
811
765
  if (canRender) {
812
766
  setTimeout(() => {
813
767
  scrollAdjustHandler.setMounted();
@@ -815,7 +769,7 @@ var ListComponent = typedMemo(function ListComponent2({
815
769
  }
816
770
  }, [canRender]);
817
771
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
818
- return /* @__PURE__ */ React2__namespace.createElement(
772
+ return /* @__PURE__ */ React3__namespace.createElement(
819
773
  SnapOrScroll,
820
774
  {
821
775
  ...rest,
@@ -834,11 +788,11 @@ var ListComponent = typedMemo(function ListComponent2({
834
788
  ScrollComponent: snapToIndices ? ScrollComponent : void 0,
835
789
  style
836
790
  },
837
- maintainVisibleContentPosition && /* @__PURE__ */ React2__namespace.createElement(ScrollAdjust, null),
838
- ENABLE_DEVMODE ? /* @__PURE__ */ React2__namespace.createElement(PaddingDevMode, null) : /* @__PURE__ */ React2__namespace.createElement(Padding, null),
839
- ListHeaderComponent && /* @__PURE__ */ React2__namespace.createElement(reactNative.View, { onLayout: onLayoutHeaderSync, ref: refHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
791
+ maintainVisibleContentPosition && /* @__PURE__ */ React3__namespace.createElement(ScrollAdjust, null),
792
+ ENABLE_DEVMODE ? /* @__PURE__ */ React3__namespace.createElement(PaddingDevMode, null) : /* @__PURE__ */ React3__namespace.createElement(Padding, null),
793
+ ListHeaderComponent && /* @__PURE__ */ React3__namespace.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
840
794
  ListEmptyComponent && getComponent(ListEmptyComponent),
841
- canRender && !ListEmptyComponent && /* @__PURE__ */ React2__namespace.createElement(
795
+ canRender && !ListEmptyComponent && /* @__PURE__ */ React3__namespace.createElement(
842
796
  Containers,
843
797
  {
844
798
  getRenderedItem: getRenderedItem2,
@@ -849,22 +803,22 @@ var ListComponent = typedMemo(function ListComponent2({
849
803
  waitForInitialLayout
850
804
  }
851
805
  ),
852
- ListFooterComponent && /* @__PURE__ */ React2__namespace.createElement(
853
- reactNative.View,
806
+ ListFooterComponent && /* @__PURE__ */ React3__namespace.createElement(
807
+ LayoutView,
854
808
  {
855
- onLayout: (event) => {
856
- const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
809
+ onLayoutChange: (layout) => {
810
+ const size = layout[horizontal ? "width" : "height"];
857
811
  set$(ctx, "footerSize", size);
858
812
  },
859
813
  style: ListFooterComponentStyle
860
814
  },
861
815
  getComponent(ListFooterComponent)
862
816
  ),
863
- __DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React2__namespace.createElement(DevNumbers, null)
817
+ __DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React3__namespace.createElement(DevNumbers, null)
864
818
  );
865
819
  });
866
- var DevNumbers = __DEV__ && React2__namespace.memo(function DevNumbers2() {
867
- return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React2__namespace.createElement(
820
+ var DevNumbers = __DEV__ && React3__namespace.memo(function DevNumbers2() {
821
+ return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React3__namespace.createElement(
868
822
  reactNative.View,
869
823
  {
870
824
  key: index,
@@ -876,7 +830,7 @@ var DevNumbers = __DEV__ && React2__namespace.memo(function DevNumbers2() {
876
830
  width: "100%"
877
831
  }
878
832
  },
879
- /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, { style: { color: "red" } }, index * 100)
833
+ /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, { style: { color: "red" } }, index * 100)
880
834
  ));
881
835
  });
882
836
 
@@ -888,7 +842,7 @@ function getId(state, index) {
888
842
  }
889
843
  const ret = index < data.length ? keyExtractor ? keyExtractor(data[index], index) : index : null;
890
844
  const id = ret;
891
- state.idCache.set(index, id);
845
+ state.idCache[index] = id;
892
846
  return id;
893
847
  }
894
848
 
@@ -1112,6 +1066,68 @@ function prepareMVCP(ctx, state, dataChanged) {
1112
1066
  };
1113
1067
  }
1114
1068
 
1069
+ // src/core/prepareColumnStartState.ts
1070
+ function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1071
+ var _a;
1072
+ const numColumns = peek$(ctx, "numColumns");
1073
+ let rowStartIndex = startIndex;
1074
+ const columnAtStart = state.columns.get(state.idCache[startIndex]);
1075
+ if (columnAtStart !== 1) {
1076
+ rowStartIndex = findRowStartIndex(state, numColumns, startIndex);
1077
+ }
1078
+ let currentRowTop = 0;
1079
+ const curId = state.idCache[rowStartIndex];
1080
+ const column = state.columns.get(curId);
1081
+ if (rowStartIndex > 0) {
1082
+ const prevIndex = rowStartIndex - 1;
1083
+ const prevId = state.idCache[prevIndex];
1084
+ const prevPosition = (_a = state.positions.get(prevId)) != null ? _a : 0;
1085
+ const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
1086
+ const prevRowHeight = calculateRowMaxSize(state, prevRowStart, prevIndex, useAverageSize);
1087
+ currentRowTop = prevPosition + prevRowHeight;
1088
+ }
1089
+ return {
1090
+ column,
1091
+ currentRowTop,
1092
+ startIndex: rowStartIndex
1093
+ };
1094
+ }
1095
+ function findRowStartIndex(state, numColumns, index) {
1096
+ if (numColumns <= 1) {
1097
+ return Math.max(0, index);
1098
+ }
1099
+ let rowStart = Math.max(0, index);
1100
+ while (rowStart > 0) {
1101
+ const columnForIndex = state.columns.get(state.idCache[rowStart]);
1102
+ if (columnForIndex === 1) {
1103
+ break;
1104
+ }
1105
+ rowStart--;
1106
+ }
1107
+ return rowStart;
1108
+ }
1109
+ function calculateRowMaxSize(state, startIndex, endIndex, useAverageSize) {
1110
+ if (endIndex < startIndex) {
1111
+ return 0;
1112
+ }
1113
+ const { data } = state.props;
1114
+ if (!data) {
1115
+ return 0;
1116
+ }
1117
+ let maxSize = 0;
1118
+ for (let i = startIndex; i <= endIndex; i++) {
1119
+ if (i < 0 || i >= data.length) {
1120
+ continue;
1121
+ }
1122
+ const id = state.idCache[i];
1123
+ const size = getItemSize(state, id, i, data[i], useAverageSize);
1124
+ if (size > maxSize) {
1125
+ maxSize = size;
1126
+ }
1127
+ }
1128
+ return maxSize;
1129
+ }
1130
+
1115
1131
  // src/utils/setPaddingTop.ts
1116
1132
  function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
1117
1133
  if (stylePaddingTop !== void 0) {
@@ -1206,7 +1222,7 @@ function updateSnapToOffsets(ctx, state) {
1206
1222
 
1207
1223
  // src/core/updateItemPositions.ts
1208
1224
  function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottomBuffered } = { scrollBottomBuffered: -1, startIndex: 0 }) {
1209
- var _a, _b, _c, _d, _e, _f;
1225
+ var _a, _b, _c, _d;
1210
1226
  const {
1211
1227
  columns,
1212
1228
  indexByKey,
@@ -1216,41 +1232,47 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1216
1232
  props: { getEstimatedItemSize, snapToIndices, enableAverages }
1217
1233
  } = state;
1218
1234
  const data = state.props.data;
1235
+ const dataLength = data.length;
1219
1236
  const numColumns = peek$(ctx, "numColumns");
1237
+ const hasColumns = numColumns > 1;
1220
1238
  const indexByKeyForChecking = __DEV__ ? /* @__PURE__ */ new Map() : void 0;
1221
1239
  const maxVisibleArea = scrollBottomBuffered + 1e3;
1222
1240
  const useAverageSize = enableAverages && !getEstimatedItemSize;
1223
1241
  let currentRowTop = 0;
1224
1242
  let column = 1;
1225
1243
  let maxSizeInRow = 0;
1226
- const hasColumns = numColumns > 1;
1227
1244
  if (startIndex > 0) {
1228
- const prevIndex = startIndex - 1;
1229
- const prevId = (_a = idCache.get(prevIndex)) != null ? _a : getId(state, prevIndex);
1230
- const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
1231
1245
  if (hasColumns) {
1232
- const prevColumn = (_c = columns.get(prevId)) != null ? _c : 1;
1233
- currentRowTop = prevPosition;
1234
- column = prevColumn % numColumns + 1;
1235
- } else {
1236
- const prevSize = (_d = sizesKnown.get(prevId)) != null ? _d : getItemSize(state, prevId, prevIndex, data[prevIndex], useAverageSize);
1246
+ const { startIndex: processedStartIndex, currentRowTop: initialRowTop } = prepareColumnStartState(
1247
+ ctx,
1248
+ state,
1249
+ startIndex,
1250
+ useAverageSize
1251
+ );
1252
+ startIndex = processedStartIndex;
1253
+ currentRowTop = initialRowTop;
1254
+ } else if (startIndex < dataLength) {
1255
+ const prevIndex = startIndex - 1;
1256
+ const prevId = getId(state, prevIndex);
1257
+ const prevPosition = (_a = positions.get(prevId)) != null ? _a : 0;
1258
+ const prevSize = (_b = sizesKnown.get(prevId)) != null ? _b : getItemSize(state, prevId, prevIndex, data[prevIndex], useAverageSize);
1237
1259
  currentRowTop = prevPosition + prevSize;
1238
1260
  }
1239
1261
  }
1240
1262
  const needsIndexByKey = dataChanged || indexByKey.size === 0;
1241
1263
  let didBreakEarly = false;
1242
1264
  let breakAt;
1243
- const dataLength = data.length;
1244
1265
  for (let i = startIndex; i < dataLength; i++) {
1245
1266
  if (breakAt && i > breakAt) {
1246
1267
  didBreakEarly = true;
1247
1268
  break;
1248
1269
  }
1249
- if (!dataChanged && currentRowTop > maxVisibleArea) {
1250
- breakAt = i + 10;
1270
+ if (breakAt === void 0 && !dataChanged && currentRowTop > maxVisibleArea) {
1271
+ const itemsPerRow = hasColumns ? numColumns : 1;
1272
+ breakAt = i + itemsPerRow + 10;
1251
1273
  }
1252
- const id = (_e = idCache.get(i)) != null ? _e : getId(state, i);
1253
- const size = (_f = sizesKnown.get(id)) != null ? _f : getItemSize(state, id, i, data[i], useAverageSize);
1274
+ const id = (_c = idCache[i]) != null ? _c : getId(state, i);
1275
+ const size = (_d = sizesKnown.get(id)) != null ? _d : getItemSize(state, id, i, data[i], useAverageSize);
1254
1276
  if (__DEV__ && needsIndexByKey) {
1255
1277
  if (indexByKeyForChecking.has(id)) {
1256
1278
  console.error(
@@ -1487,9 +1509,12 @@ function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
1487
1509
  var batchedUpdates = reactNative.unstable_batchedUpdates || ((callback) => callback());
1488
1510
 
1489
1511
  // src/utils/checkAllSizesKnown.ts
1512
+ function isNullOrUndefined2(value) {
1513
+ return value === null || value === void 0;
1514
+ }
1490
1515
  function checkAllSizesKnown(state) {
1491
1516
  const { startBuffered, endBuffered, sizesKnown } = state;
1492
- if (endBuffered !== null) {
1517
+ if (!isNullOrUndefined2(endBuffered) && !isNullOrUndefined2(startBuffered) && startBuffered >= 0 && endBuffered >= 0) {
1493
1518
  let areAllKnown = true;
1494
1519
  for (let i = startBuffered; areAllKnown && i <= endBuffered; i++) {
1495
1520
  const key = getId(state, i);
@@ -1506,6 +1531,8 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1506
1531
  const { stickyContainerPool, containerItemTypes } = state;
1507
1532
  const result = [];
1508
1533
  const availableContainers = [];
1534
+ const pendingRemovalSet = new Set(pendingRemoval);
1535
+ let pendingRemovalChanged = false;
1509
1536
  const stickyIndicesSet = state.props.stickyIndicesSet;
1510
1537
  const stickyItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => stickyIndicesSet.has(index))) || [];
1511
1538
  const canReuseContainer = (containerIndex, requiredType) => {
@@ -1521,12 +1548,11 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1521
1548
  let foundContainer = false;
1522
1549
  for (const containerIndex of stickyContainerPool) {
1523
1550
  const key = peek$(ctx, `containerItemKey${containerIndex}`);
1524
- const isPendingRemoval = pendingRemoval.includes(containerIndex);
1551
+ const isPendingRemoval = pendingRemovalSet.has(containerIndex);
1525
1552
  if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType)) {
1526
1553
  result.push(containerIndex);
1527
- if (isPendingRemoval) {
1528
- const index = pendingRemoval.indexOf(containerIndex);
1529
- pendingRemoval.splice(index, 1);
1554
+ if (isPendingRemoval && pendingRemovalSet.delete(containerIndex)) {
1555
+ pendingRemovalChanged = true;
1530
1556
  }
1531
1557
  foundContainer = true;
1532
1558
  if (requiredItemTypes) typeIndex++;
@@ -1546,13 +1572,11 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1546
1572
  }
1547
1573
  const key = peek$(ctx, `containerItemKey${u}`);
1548
1574
  let isOk = key === void 0;
1549
- if (!isOk) {
1550
- const index = pendingRemoval.indexOf(u);
1551
- if (index !== -1) {
1552
- pendingRemoval.splice(index, 1);
1553
- const requiredType = neededTypes[typeIndex];
1554
- isOk = canReuseContainer(u, requiredType);
1555
- }
1575
+ if (!isOk && pendingRemovalSet.has(u)) {
1576
+ pendingRemovalSet.delete(u);
1577
+ pendingRemovalChanged = true;
1578
+ const requiredType = neededTypes[typeIndex];
1579
+ isOk = canReuseContainer(u, requiredType);
1556
1580
  }
1557
1581
  if (isOk) {
1558
1582
  result.push(u);
@@ -1610,6 +1634,12 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1610
1634
  }
1611
1635
  }
1612
1636
  }
1637
+ if (pendingRemovalChanged) {
1638
+ pendingRemoval.length = 0;
1639
+ for (const value of pendingRemovalSet) {
1640
+ pendingRemoval.push(value);
1641
+ }
1642
+ }
1613
1643
  return result.sort(comparatorDefault);
1614
1644
  }
1615
1645
  function comparatorByDistance(a, b) {
@@ -1769,7 +1799,8 @@ function findCurrentStickyIndex(stickyArray, scroll, state) {
1769
1799
  const idCache = state.idCache;
1770
1800
  const positions = state.positions;
1771
1801
  for (let i = stickyArray.length - 1; i >= 0; i--) {
1772
- const stickyId = (_a = idCache.get(stickyArray[i])) != null ? _a : getId(state, stickyArray[i]);
1802
+ const stickyIndex = stickyArray[i];
1803
+ const stickyId = (_a = idCache[stickyIndex]) != null ? _a : getId(state, stickyIndex);
1773
1804
  const stickyPos = stickyId ? positions.get(stickyId) : void 0;
1774
1805
  if (stickyPos !== void 0 && scroll >= stickyPos) {
1775
1806
  return i;
@@ -1782,40 +1813,43 @@ function getActiveStickyIndices(ctx, state, stickyIndices) {
1782
1813
  Array.from(state.stickyContainerPool).map((i) => peek$(ctx, `containerItemKey${i}`)).map((key) => key ? state.indexByKey.get(key) : void 0).filter((idx) => idx !== void 0 && stickyIndices.has(idx))
1783
1814
  );
1784
1815
  }
1785
- function handleStickyActivation(ctx, state, stickyIndices, stickyArray, scroll, needNewContainers, startBuffered, endBuffered) {
1816
+ function handleStickyActivation(ctx, state, stickyIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
1786
1817
  var _a;
1787
1818
  const activeIndices = getActiveStickyIndices(ctx, state, stickyIndices);
1788
- const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
1789
1819
  state.activeStickyIndex = currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : void 0;
1790
1820
  for (let offset = 0; offset <= 1; offset++) {
1791
1821
  const idx = currentStickyIdx - offset;
1792
1822
  if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
1793
1823
  const stickyIndex = stickyArray[idx];
1794
- const stickyId = (_a = state.idCache.get(stickyIndex)) != null ? _a : getId(state, stickyIndex);
1824
+ const stickyId = (_a = state.idCache[stickyIndex]) != null ? _a : getId(state, stickyIndex);
1795
1825
  if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered)) {
1796
1826
  needNewContainers.push(stickyIndex);
1797
1827
  }
1798
1828
  }
1799
1829
  }
1800
- function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, pendingRemoval) {
1830
+ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
1801
1831
  var _a, _b, _c;
1802
- const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
1803
1832
  for (const containerIndex of state.stickyContainerPool) {
1804
1833
  const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
1805
1834
  const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
1806
1835
  if (itemIndex === void 0) continue;
1807
1836
  const arrayIdx = stickyArray.indexOf(itemIndex);
1808
- if (arrayIdx === -1) continue;
1837
+ if (arrayIdx === -1) {
1838
+ state.stickyContainerPool.delete(containerIndex);
1839
+ set$(ctx, `containerSticky${containerIndex}`, false);
1840
+ set$(ctx, `containerStickyOffset${containerIndex}`, void 0);
1841
+ continue;
1842
+ }
1809
1843
  const isRecentSticky = arrayIdx >= currentStickyIdx - 1 && arrayIdx <= currentStickyIdx + 1;
1810
1844
  if (isRecentSticky) continue;
1811
1845
  const nextIndex = stickyArray[arrayIdx + 1];
1812
1846
  let shouldRecycle = false;
1813
1847
  if (nextIndex) {
1814
- const nextId = (_a = state.idCache.get(nextIndex)) != null ? _a : getId(state, nextIndex);
1848
+ const nextId = (_a = state.idCache[nextIndex]) != null ? _a : getId(state, nextIndex);
1815
1849
  const nextPos = nextId ? state.positions.get(nextId) : void 0;
1816
1850
  shouldRecycle = nextPos !== void 0 && scroll > nextPos + scrollBuffer * 2;
1817
1851
  } else {
1818
- const currentId = (_b = state.idCache.get(itemIndex)) != null ? _b : getId(state, itemIndex);
1852
+ const currentId = (_b = state.idCache[itemIndex]) != null ? _b : getId(state, itemIndex);
1819
1853
  if (currentId) {
1820
1854
  const currentPos = state.positions.get(currentId);
1821
1855
  const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(state, currentId, itemIndex, state.props.data[itemIndex]);
@@ -1843,7 +1877,7 @@ function calculateItemsInView(ctx, state, params = {}) {
1843
1877
  sizes,
1844
1878
  startBufferedId: startBufferedIdOrig,
1845
1879
  viewabilityConfigCallbackPairs,
1846
- props: { getItemType, initialScroll, itemsAreEqual, keyExtractor, scrollBuffer }
1880
+ props: { getItemType, initialScroll, itemsAreEqual, keyExtractor, onStickyHeaderChange, scrollBuffer }
1847
1881
  } = state;
1848
1882
  const { data } = state.props;
1849
1883
  const stickyIndicesArr = state.props.stickyIndicesArr || [];
@@ -1878,6 +1912,10 @@ function calculateItemsInView(ctx, state, params = {}) {
1878
1912
  set$(ctx, "debugRawScroll", scrollState);
1879
1913
  set$(ctx, "debugComputedScroll", scroll);
1880
1914
  }
1915
+ const previousStickyIndex = state.activeStickyIndex;
1916
+ const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
1917
+ const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : void 0;
1918
+ state.activeStickyIndex = nextActiveStickyIndex;
1881
1919
  let scrollBufferTop = scrollBuffer;
1882
1920
  let scrollBufferBottom = scrollBuffer;
1883
1921
  if (speed > 0 || speed === 0 && scroll < Math.max(50, scrollBuffer)) {
@@ -1899,7 +1937,7 @@ function calculateItemsInView(ctx, state, params = {}) {
1899
1937
  const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
1900
1938
  if (dataChanged) {
1901
1939
  indexByKey.clear();
1902
- idCache.clear();
1940
+ idCache.length = 0;
1903
1941
  positions.clear();
1904
1942
  }
1905
1943
  const startIndex = dataChanged ? 0 : (_a = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _a : 0;
@@ -1915,7 +1953,7 @@ function calculateItemsInView(ctx, state, params = {}) {
1915
1953
  let endBuffered = null;
1916
1954
  let loopStart = !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
1917
1955
  for (let i = loopStart; i >= 0; i--) {
1918
- const id = (_b = idCache.get(i)) != null ? _b : getId(state, i);
1956
+ const id = (_b = idCache[i]) != null ? _b : getId(state, i);
1919
1957
  const top = positions.get(id);
1920
1958
  const size = (_c = sizes.get(id)) != null ? _c : getItemSize(state, id, i, data[i]);
1921
1959
  const bottom = top + size;
@@ -1943,7 +1981,7 @@ function calculateItemsInView(ctx, state, params = {}) {
1943
1981
  let firstFullyOnScreenIndex;
1944
1982
  const dataLength = data.length;
1945
1983
  for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
1946
- const id = (_d = idCache.get(i)) != null ? _d : getId(state, i);
1984
+ const id = (_d = idCache[i]) != null ? _d : getId(state, i);
1947
1985
  const size = (_e = sizes.get(id)) != null ? _e : getItemSize(state, id, i, data[i]);
1948
1986
  const top = positions.get(id);
1949
1987
  if (!foundEnd) {
@@ -1973,7 +2011,7 @@ function calculateItemsInView(ctx, state, params = {}) {
1973
2011
  }
1974
2012
  const idsInView = [];
1975
2013
  for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
1976
- const id = (_f = idCache.get(i)) != null ? _f : getId(state, i);
2014
+ const id = (_f = idCache[i]) != null ? _f : getId(state, i);
1977
2015
  idsInView.push(id);
1978
2016
  }
1979
2017
  Object.assign(state, {
@@ -2005,7 +2043,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2005
2043
  let numContainers2 = prevNumContainers;
2006
2044
  const needNewContainers = [];
2007
2045
  for (let i = startBuffered; i <= endBuffered; i++) {
2008
- const id = (_g = idCache.get(i)) != null ? _g : getId(state, i);
2046
+ const id = (_g = idCache[i]) != null ? _g : getId(state, i);
2009
2047
  if (!containerItemKeys.has(id)) {
2010
2048
  needNewContainers.push(i);
2011
2049
  }
@@ -2016,7 +2054,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2016
2054
  state,
2017
2055
  stickyIndicesSet,
2018
2056
  stickyIndicesArr,
2019
- scroll,
2057
+ currentStickyIdx,
2020
2058
  needNewContainers,
2021
2059
  startBuffered,
2022
2060
  endBuffered
@@ -2042,7 +2080,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2042
2080
  for (let idx = 0; idx < needNewContainers.length; idx++) {
2043
2081
  const i = needNewContainers[idx];
2044
2082
  const containerIndex = availableContainers[idx];
2045
- const id = (_h = idCache.get(i)) != null ? _h : getId(state, i);
2083
+ const id = (_h = idCache[i]) != null ? _h : getId(state, i);
2046
2084
  const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
2047
2085
  if (oldKey && oldKey !== id) {
2048
2086
  containerItemKeys.delete(oldKey);
@@ -2056,7 +2094,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2056
2094
  if (stickyIndicesSet.has(i)) {
2057
2095
  set$(ctx, `containerSticky${containerIndex}`, true);
2058
2096
  const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
2059
- set$(ctx, `containerStickyOffset${containerIndex}`, new reactNative.Animated.Value(topPadding));
2097
+ set$(ctx, `containerStickyOffset${containerIndex}`, topPadding);
2060
2098
  state.stickyContainerPool.add(containerIndex);
2061
2099
  } else {
2062
2100
  set$(ctx, `containerSticky${containerIndex}`, false);
@@ -2075,7 +2113,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2075
2113
  }
2076
2114
  }
2077
2115
  if (stickyIndicesArr.length > 0) {
2078
- handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, pendingRemoval);
2116
+ handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2079
2117
  }
2080
2118
  for (let i = 0; i < numContainers; i++) {
2081
2119
  const itemKey = peek$(ctx, `containerItemKey${i}`);
@@ -2097,7 +2135,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2097
2135
  const itemIndex = indexByKey.get(itemKey);
2098
2136
  const item = data[itemIndex];
2099
2137
  if (item !== void 0) {
2100
- const id = (_i = idCache.get(itemIndex)) != null ? _i : getId(state, itemIndex);
2138
+ const id = (_i = idCache[itemIndex]) != null ? _i : getId(state, itemIndex);
2101
2139
  const position = positions.get(id);
2102
2140
  if (position === void 0) {
2103
2141
  set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
@@ -2127,6 +2165,12 @@ function calculateItemsInView(ctx, state, params = {}) {
2127
2165
  if (viewabilityConfigCallbackPairs) {
2128
2166
  updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollLength, startNoBuffer, endNoBuffer);
2129
2167
  }
2168
+ if (onStickyHeaderChange && stickyIndicesArr.length > 0 && nextActiveStickyIndex !== void 0 && nextActiveStickyIndex !== previousStickyIndex) {
2169
+ const item = data[nextActiveStickyIndex];
2170
+ if (item !== void 0) {
2171
+ onStickyHeaderChange({ index: nextActiveStickyIndex, item });
2172
+ }
2173
+ }
2130
2174
  });
2131
2175
  }
2132
2176
 
@@ -2285,7 +2329,9 @@ function doInitialAllocateContainers(ctx, state) {
2285
2329
  let totalSize = 0;
2286
2330
  const num = Math.min(20, data.length);
2287
2331
  for (let i = 0; i < num; i++) {
2288
- totalSize += fn(0, data[0], getItemType ? (_a = getItemType(data[0], 0)) != null ? _a : "" : "");
2332
+ const item = data[i];
2333
+ const itemType = getItemType ? (_a = getItemType(item, i)) != null ? _a : "" : "";
2334
+ totalSize += fn(i, item, itemType);
2289
2335
  }
2290
2336
  averageItemSize = totalSize / num;
2291
2337
  } else {
@@ -2314,7 +2360,9 @@ function doInitialAllocateContainers(ctx, state) {
2314
2360
  // src/core/handleLayout.ts
2315
2361
  function handleLayout(ctx, state, layout, setCanRender) {
2316
2362
  const { maintainScrollAtEnd } = state.props;
2317
- const scrollLength = layout[state.props.horizontal ? "width" : "height"];
2363
+ const measuredLength = layout[state.props.horizontal ? "width" : "height"];
2364
+ const previousLength = state.scrollLength;
2365
+ const scrollLength = measuredLength > 0 ? measuredLength : previousLength;
2318
2366
  const otherAxisSize = layout[state.props.horizontal ? "height" : "width"];
2319
2367
  const needsCalculate = !state.lastLayout || scrollLength > state.scrollLength || state.lastLayout.x !== layout.x || state.lastLayout.y !== layout.y;
2320
2368
  state.lastLayout = layout;
@@ -2325,7 +2373,9 @@ function handleLayout(ctx, state, layout, setCanRender) {
2325
2373
  state.otherAxisSize = otherAxisSize;
2326
2374
  state.lastBatchingAction = Date.now();
2327
2375
  state.scrollForNextCalculateItemsInView = void 0;
2328
- doInitialAllocateContainers(ctx, state);
2376
+ if (scrollLength > 0) {
2377
+ doInitialAllocateContainers(ctx, state);
2378
+ }
2329
2379
  if (needsCalculate) {
2330
2380
  calculateItemsInView(ctx, state, { doMVCP: true });
2331
2381
  }
@@ -2341,14 +2391,14 @@ function handleLayout(ctx, state, layout, setCanRender) {
2341
2391
  if (state) {
2342
2392
  state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
2343
2393
  }
2344
- if (__DEV__ && scrollLength === 0) {
2394
+ if (__DEV__ && measuredLength === 0) {
2345
2395
  warnDevOnce(
2346
2396
  "height0",
2347
2397
  `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.`
2348
2398
  );
2349
2399
  }
2350
- setCanRender(true);
2351
2400
  }
2401
+ setCanRender(true);
2352
2402
  }
2353
2403
 
2354
2404
  // src/core/onScroll.ts
@@ -2555,7 +2605,7 @@ function updateOneItemSize(state, itemKey, sizeObj) {
2555
2605
  return 0;
2556
2606
  }
2557
2607
  var useCombinedRef = (...refs) => {
2558
- const callback = React2.useCallback((element) => {
2608
+ const callback = React3.useCallback((element) => {
2559
2609
  for (const ref of refs) {
2560
2610
  if (!ref) {
2561
2611
  continue;
@@ -2598,18 +2648,59 @@ function getRenderedItem(ctx, state, key) {
2598
2648
  return null;
2599
2649
  }
2600
2650
  let renderedItem = null;
2601
- if (renderItem && data[index]) {
2651
+ const extraData = peek$(ctx, "extraData");
2652
+ const item = data[index];
2653
+ if (renderItem && !isNullOrUndefined(item)) {
2602
2654
  const itemProps = {
2603
2655
  data,
2604
- extraData: peek$(ctx, "extraData"),
2656
+ extraData,
2605
2657
  index,
2606
- item: data[index],
2607
- type: getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : ""
2658
+ item,
2659
+ type: getItemType ? (_a = getItemType(item, index)) != null ? _a : "" : ""
2608
2660
  };
2609
- renderedItem = isFunction(renderItem) ? renderItem(itemProps) : React2__namespace.default.createElement(renderItem, itemProps);
2661
+ renderedItem = isFunction(renderItem) ? renderItem(itemProps) : React3__namespace.default.createElement(renderItem, itemProps);
2610
2662
  }
2611
2663
  return { index, item: data[index], renderedItem };
2612
2664
  }
2665
+ function useThrottleDebounce(mode) {
2666
+ const timeoutRef = React3.useRef(null);
2667
+ const lastCallTimeRef = React3.useRef(0);
2668
+ const lastArgsRef = React3.useRef(null);
2669
+ const clearTimeoutRef = () => {
2670
+ if (timeoutRef.current) {
2671
+ clearTimeout(timeoutRef.current);
2672
+ timeoutRef.current = null;
2673
+ }
2674
+ };
2675
+ const execute = React3.useCallback(
2676
+ (callback, delay, ...args) => {
2677
+ {
2678
+ const now = Date.now();
2679
+ lastArgsRef.current = args;
2680
+ if (now - lastCallTimeRef.current >= delay) {
2681
+ lastCallTimeRef.current = now;
2682
+ callback(...args);
2683
+ clearTimeoutRef();
2684
+ } else {
2685
+ clearTimeoutRef();
2686
+ timeoutRef.current = setTimeout(
2687
+ () => {
2688
+ if (lastArgsRef.current) {
2689
+ lastCallTimeRef.current = Date.now();
2690
+ callback(...lastArgsRef.current);
2691
+ timeoutRef.current = null;
2692
+ lastArgsRef.current = null;
2693
+ }
2694
+ },
2695
+ delay - (now - lastCallTimeRef.current)
2696
+ );
2697
+ }
2698
+ }
2699
+ },
2700
+ [mode]
2701
+ );
2702
+ return execute;
2703
+ }
2613
2704
 
2614
2705
  // src/utils/throttledOnScroll.ts
2615
2706
  function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
@@ -2626,14 +2717,14 @@ var LegendList = typedMemo(
2626
2717
  const isChildrenMode = children !== void 0 && dataProp === void 0;
2627
2718
  const processedProps = isChildrenMode ? {
2628
2719
  ...restProps,
2629
- data: (isArray(children) ? children : React2__namespace.Children.toArray(children)).flat(1),
2720
+ data: (isArray(children) ? children : React3__namespace.Children.toArray(children)).flat(1),
2630
2721
  renderItem: ({ item }) => item
2631
2722
  } : {
2632
2723
  ...restProps,
2633
2724
  data: dataProp || [],
2634
2725
  renderItem: renderItemProp
2635
2726
  };
2636
- return /* @__PURE__ */ React2__namespace.createElement(StateProvider, null, /* @__PURE__ */ React2__namespace.createElement(LegendListInner, { ...processedProps, ref: forwardedRef }));
2727
+ return /* @__PURE__ */ React3__namespace.createElement(StateProvider, null, /* @__PURE__ */ React3__namespace.createElement(LegendListInner, { ...processedProps, ref: forwardedRef }));
2637
2728
  })
2638
2729
  );
2639
2730
  var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
@@ -2673,6 +2764,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2673
2764
  onScroll: onScrollProp,
2674
2765
  onStartReached,
2675
2766
  onStartReachedThreshold = 0.5,
2767
+ onStickyHeaderChange,
2676
2768
  onViewableItemsChanged,
2677
2769
  progressViewOffset,
2678
2770
  recycleItems = false,
@@ -2690,21 +2782,21 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2690
2782
  waitForInitialLayout = true,
2691
2783
  ...rest
2692
2784
  } = props;
2693
- const [renderNum, setRenderNum] = React2.useState(0);
2785
+ const [renderNum, setRenderNum] = React3.useState(0);
2694
2786
  const initialScroll = initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
2695
- const [canRender, setCanRender] = React2__namespace.useState(!IsNewArchitecture);
2787
+ const [canRender, setCanRender] = React3__namespace.useState(!IsNewArchitecture);
2696
2788
  const contentContainerStyle = { ...reactNative.StyleSheet.flatten(contentContainerStyleProp) };
2697
2789
  const style = { ...reactNative.StyleSheet.flatten(styleProp) };
2698
2790
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
2699
2791
  const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
2700
2792
  const ctx = useStateContext();
2701
2793
  ctx.columnWrapperStyle = columnWrapperStyle || (contentContainerStyle ? createColumnWrapperStyle(contentContainerStyle) : void 0);
2702
- const refScroller = React2.useRef(null);
2794
+ const refScroller = React3.useRef(null);
2703
2795
  const combinedRef = useCombinedRef(refScroller, refScrollView);
2704
2796
  const estimatedItemSize = estimatedItemSizeProp != null ? estimatedItemSizeProp : DEFAULT_ITEM_SIZE;
2705
2797
  const scrollBuffer = (drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE) || 1;
2706
2798
  const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (_item, index) => index.toString();
2707
- const refState = React2.useRef();
2799
+ const refState = React3.useRef();
2708
2800
  if (!refState.current) {
2709
2801
  if (!ctx.internalState) {
2710
2802
  const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { height: 0, width: 0 } : reactNative.Dimensions.get("window"))[horizontal ? "width" : "height"];
@@ -2720,7 +2812,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2720
2812
  endNoBuffer: -1,
2721
2813
  endReachedBlockedByTimer: false,
2722
2814
  firstFullyOnScreenIndex: -1,
2723
- idCache: /* @__PURE__ */ new Map(),
2815
+ idCache: [],
2724
2816
  idsInView: [],
2725
2817
  indexByKey: /* @__PURE__ */ new Map(),
2726
2818
  initialScroll,
@@ -2795,18 +2887,19 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2795
2887
  onScroll: throttleScrollFn,
2796
2888
  onStartReached,
2797
2889
  onStartReachedThreshold,
2890
+ onStickyHeaderChange,
2798
2891
  recycleItems: !!recycleItems,
2799
2892
  renderItem,
2800
2893
  scrollBuffer,
2801
2894
  snapToIndices,
2802
2895
  stickyIndicesArr: stickyIndices != null ? stickyIndices : [],
2803
- stickyIndicesSet: React2.useMemo(() => new Set(stickyIndices != null ? stickyIndices : []), [stickyIndices == null ? void 0 : stickyIndices.join(",")]),
2896
+ stickyIndicesSet: React3.useMemo(() => new Set(stickyIndices != null ? stickyIndices : []), [stickyIndices == null ? void 0 : stickyIndices.join(",")]),
2804
2897
  stylePaddingBottom: stylePaddingBottomState,
2805
2898
  stylePaddingTop: stylePaddingTopState,
2806
2899
  suggestEstimatedItemSize: !!suggestEstimatedItemSize
2807
2900
  };
2808
2901
  state.refScroller = refScroller;
2809
- const memoizedLastItemKeys = React2.useMemo(() => {
2902
+ const memoizedLastItemKeys = React3.useMemo(() => {
2810
2903
  if (!dataProp.length) return [];
2811
2904
  return Array.from(
2812
2905
  { length: Math.min(numColumnsProp, dataProp.length) },
@@ -2836,7 +2929,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2836
2929
  true
2837
2930
  );
2838
2931
  }
2839
- const initialContentOffset = React2.useMemo(() => {
2932
+ const initialContentOffset = React3.useMemo(() => {
2840
2933
  if (initialScroll) {
2841
2934
  const { index, viewOffset } = initialScroll;
2842
2935
  let initialContentOffset2 = viewOffset || 0;
@@ -2868,7 +2961,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2868
2961
  refState.current.positions.clear();
2869
2962
  }
2870
2963
  }
2871
- const onLayoutHeader = React2.useCallback((rect, fromLayoutEffect) => {
2964
+ const onLayoutHeader = React3.useCallback((rect, fromLayoutEffect) => {
2872
2965
  const size = rect[horizontal ? "width" : "height"];
2873
2966
  set$(ctx, "headerSize", size);
2874
2967
  if ((initialScroll == null ? void 0 : initialScroll.index) !== void 0) {
@@ -2883,13 +2976,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2883
2976
  }
2884
2977
  }
2885
2978
  }, []);
2886
- React2.useLayoutEffect(() => {
2979
+ React3.useLayoutEffect(() => {
2887
2980
  if (snapToIndices) {
2888
2981
  updateSnapToOffsets(ctx, state);
2889
2982
  }
2890
2983
  }, [snapToIndices]);
2891
- React2.useLayoutEffect(() => {
2892
- const didAllocateContainers = dataProp.length > 0 && doInitialAllocateContainersCallback();
2984
+ React3.useLayoutEffect(() => {
2985
+ const didAllocateContainers = dataProp.length > 0 && doInitialAllocateContainers(ctx, state);
2893
2986
  if (!didAllocateContainers) {
2894
2987
  checkResetContainers(
2895
2988
  ctx,
@@ -2900,34 +2993,16 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2900
2993
  );
2901
2994
  }
2902
2995
  }, [dataProp, numColumnsProp]);
2903
- React2.useLayoutEffect(() => {
2996
+ React3.useLayoutEffect(() => {
2904
2997
  set$(ctx, "extraData", extraData);
2905
2998
  }, [extraData]);
2906
- React2.useLayoutEffect(() => {
2907
- var _a2;
2908
- if (IsNewArchitecture) {
2909
- let measured;
2910
- (_a2 = refScroller.current) == null ? void 0 : _a2.measure((x, y, width, height) => {
2911
- measured = { height, width, x, y };
2912
- });
2913
- if (measured) {
2914
- const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
2915
- if (size) {
2916
- handleLayout(ctx, state, measured, setCanRender);
2917
- }
2918
- }
2919
- }
2920
- }, []);
2921
- React2.useLayoutEffect(initializeStateVars, [
2999
+ React3.useLayoutEffect(initializeStateVars, [
2922
3000
  memoizedLastItemKeys.join(","),
2923
3001
  numColumnsProp,
2924
3002
  stylePaddingTopState,
2925
3003
  stylePaddingBottomState
2926
3004
  ]);
2927
- const doInitialAllocateContainersCallback = () => {
2928
- return doInitialAllocateContainers(ctx, state);
2929
- };
2930
- React2.useEffect(() => {
3005
+ React3.useEffect(() => {
2931
3006
  const viewability = setupViewability({
2932
3007
  onViewableItemsChanged,
2933
3008
  viewabilityConfig,
@@ -2938,17 +3013,19 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2938
3013
  }, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
2939
3014
  if (!IsNewArchitecture) {
2940
3015
  useInit(() => {
2941
- doInitialAllocateContainersCallback();
3016
+ doInitialAllocateContainers(ctx, state);
2942
3017
  });
2943
3018
  }
2944
- const onLayout = React2.useCallback((event) => {
2945
- const layout = event.nativeEvent.layout;
3019
+ const onLayoutChange = React3.useCallback((layout) => {
2946
3020
  handleLayout(ctx, state, layout, setCanRender);
2947
- if (onLayoutProp) {
2948
- onLayoutProp(event);
2949
- }
2950
3021
  }, []);
2951
- React2.useImperativeHandle(forwardedRef, () => {
3022
+ const { onLayout } = useOnLayoutSync({
3023
+ onLayoutChange,
3024
+ onLayoutProp,
3025
+ ref: refScroller
3026
+ // the type of ScrollView doesn't include measure?
3027
+ });
3028
+ React3.useImperativeHandle(forwardedRef, () => {
2952
3029
  const scrollIndexIntoView = (options) => {
2953
3030
  const state2 = refState.current;
2954
3031
  if (state2) {
@@ -3031,13 +3108,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3031
3108
  };
3032
3109
  }, []);
3033
3110
  if (reactNative.Platform.OS === "web") {
3034
- React2.useEffect(() => {
3111
+ React3.useEffect(() => {
3035
3112
  if (initialContentOffset) {
3036
3113
  scrollTo(state, { animated: false, offset: initialContentOffset });
3037
3114
  }
3038
3115
  }, []);
3039
3116
  }
3040
- const fns = React2.useMemo(
3117
+ const fns = React3.useMemo(
3041
3118
  () => ({
3042
3119
  getRenderedItem: (key) => getRenderedItem(ctx, state, key),
3043
3120
  onScroll: (event) => onScroll(ctx, state, event),
@@ -3045,7 +3122,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3045
3122
  }),
3046
3123
  []
3047
3124
  );
3048
- const onScrollHandler = React2.useMemo(() => {
3125
+ const onScrollHandler = React3.useMemo(() => {
3049
3126
  const onScrollFn = fns.onScroll;
3050
3127
  if (stickyIndices == null ? void 0 : stickyIndices.length) {
3051
3128
  const { animatedScrollY } = ctx;
@@ -3056,7 +3133,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3056
3133
  }
3057
3134
  return onScrollFn;
3058
3135
  }, [stickyIndices == null ? void 0 : stickyIndices.length, horizontal, scrollEventThrottle]);
3059
- return /* @__PURE__ */ React2__namespace.createElement(React2__namespace.Fragment, null, /* @__PURE__ */ React2__namespace.createElement(
3136
+ return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement(
3060
3137
  ListComponent,
3061
3138
  {
3062
3139
  ...rest,
@@ -3087,9 +3164,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3087
3164
  },
3088
3165
  onScroll: onScrollHandler,
3089
3166
  recycleItems,
3090
- refreshControl: refreshControl ? stylePaddingTopState > 0 ? React2__namespace.cloneElement(refreshControl, {
3167
+ refreshControl: refreshControl ? stylePaddingTopState > 0 ? React3__namespace.cloneElement(refreshControl, {
3091
3168
  progressViewOffset: (refreshControl.props.progressViewOffset || 0) + stylePaddingTopState
3092
- }) : refreshControl : onRefresh && /* @__PURE__ */ React2__namespace.createElement(
3169
+ }) : refreshControl : onRefresh && /* @__PURE__ */ React3__namespace.createElement(
3093
3170
  reactNative.RefreshControl,
3094
3171
  {
3095
3172
  onRefresh,
@@ -3106,7 +3183,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3106
3183
  updateItemSize: fns.updateItemSize,
3107
3184
  waitForInitialLayout
3108
3185
  }
3109
- ), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React2__namespace.createElement(DebugView, { state: refState.current }));
3186
+ ), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React3__namespace.createElement(DebugView, { state: refState.current }));
3110
3187
  });
3111
3188
 
3112
3189
  exports.LegendList = LegendList;