@legendapp/list 1.0.0-beta.0 → 1.0.0-beta.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.mjs CHANGED
@@ -1,11 +1,11 @@
1
- import * as React4 from 'react';
2
- import React4__default, { useMemo, forwardRef, useRef, useCallback, useEffect, useImperativeHandle, useSyncExternalStore, useState } from 'react';
1
+ import * as React5 from 'react';
2
+ import React5__default, { createContext, useMemo, forwardRef, useRef, useCallback, useEffect, useImperativeHandle, useSyncExternalStore, useContext, useState, useLayoutEffect } from 'react';
3
3
  import { Animated, ScrollView, View, Dimensions, StyleSheet, Platform, useAnimatedValue as useAnimatedValue$1 } from 'react-native';
4
4
 
5
5
  // src/LegendList.tsx
6
- var ContextState = React4.createContext(null);
6
+ var ContextState = React5.createContext(null);
7
7
  function StateProvider({ children }) {
8
- const [value] = React4.useState(() => ({
8
+ const [value] = React5.useState(() => ({
9
9
  listeners: /* @__PURE__ */ new Map(),
10
10
  values: /* @__PURE__ */ new Map(),
11
11
  mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
@@ -13,10 +13,10 @@ function StateProvider({ children }) {
13
13
  mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
14
14
  mapViewabilityAmountValues: /* @__PURE__ */ new Map()
15
15
  }));
16
- return /* @__PURE__ */ React4.createElement(ContextState.Provider, { value }, children);
16
+ return /* @__PURE__ */ React5.createElement(ContextState.Provider, { value }, children);
17
17
  }
18
18
  function useStateContext() {
19
- return React4.useContext(ContextState);
19
+ return React5.useContext(ContextState);
20
20
  }
21
21
  function createSelectorFunctions(ctx, signalName) {
22
22
  return {
@@ -25,8 +25,8 @@ function createSelectorFunctions(ctx, signalName) {
25
25
  };
26
26
  }
27
27
  function use$(signalName) {
28
- const ctx = React4.useContext(ContextState);
29
- const { subscribe, get } = React4.useMemo(() => createSelectorFunctions(ctx, signalName), []);
28
+ const ctx = React5.useContext(ContextState);
29
+ const { subscribe, get } = React5.useMemo(() => createSelectorFunctions(ctx, signalName), []);
30
30
  const value = useSyncExternalStore(subscribe, get);
31
31
  return value;
32
32
  }
@@ -56,75 +56,207 @@ function set$(ctx, signalName, value) {
56
56
  }
57
57
  }
58
58
  }
59
+ var symbolFirst = Symbol();
60
+ function useInit(cb) {
61
+ const refValue = useRef(symbolFirst);
62
+ if (refValue.current === symbolFirst) {
63
+ refValue.current = cb();
64
+ }
65
+ return refValue.current;
66
+ }
67
+
68
+ // src/ContextContainer.ts
69
+ var ContextContainer = createContext(null);
70
+ function useViewability(configId, callback) {
71
+ const ctx = useStateContext();
72
+ const { containerId } = useContext(ContextContainer);
73
+ const key = containerId + configId;
74
+ useInit(() => {
75
+ const value = ctx.mapViewabilityValues.get(key);
76
+ if (value) {
77
+ callback(value);
78
+ }
79
+ });
80
+ ctx.mapViewabilityCallbacks.set(key, callback);
81
+ useEffect(
82
+ () => () => {
83
+ ctx.mapViewabilityCallbacks.delete(key);
84
+ },
85
+ []
86
+ );
87
+ }
88
+ function useViewabilityAmount(callback) {
89
+ const ctx = useStateContext();
90
+ const { containerId } = useContext(ContextContainer);
91
+ useInit(() => {
92
+ const value = ctx.mapViewabilityAmountValues.get(containerId);
93
+ if (value) {
94
+ callback(value);
95
+ }
96
+ });
97
+ ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
98
+ useEffect(
99
+ () => () => {
100
+ ctx.mapViewabilityAmountCallbacks.delete(containerId);
101
+ },
102
+ []
103
+ );
104
+ }
105
+ function useRecyclingEffect(effect) {
106
+ const { index, value } = useContext(ContextContainer);
107
+ const prevValues = useRef({
108
+ prevIndex: void 0,
109
+ prevItem: void 0
110
+ });
111
+ useEffect(() => {
112
+ let ret = void 0;
113
+ if (prevValues.current.prevIndex !== void 0 && prevValues.current.prevItem !== void 0) {
114
+ ret = effect({
115
+ index,
116
+ item: value,
117
+ prevIndex: prevValues.current.prevIndex,
118
+ prevItem: prevValues.current.prevItem
119
+ });
120
+ }
121
+ prevValues.current = {
122
+ prevIndex: index,
123
+ prevItem: value
124
+ };
125
+ return ret;
126
+ }, [index, value]);
127
+ }
128
+ function useRecyclingState(valueOrFun) {
129
+ const { index, value } = useContext(ContextContainer);
130
+ const stateInfo = useState(
131
+ () => typeof valueOrFun === "function" ? valueOrFun({
132
+ index,
133
+ item: value,
134
+ prevIndex: void 0,
135
+ prevItem: void 0
136
+ }) : valueOrFun
137
+ );
138
+ useRecyclingEffect((state) => {
139
+ const newState = typeof valueOrFun === "function" ? valueOrFun(state) : valueOrFun;
140
+ stateInfo[1](newState);
141
+ });
142
+ return stateInfo;
143
+ }
144
+ var LeanView = React5.forwardRef((props, ref) => {
145
+ return React5.createElement("RCTView", { ...props, ref });
146
+ });
147
+ LeanView.displayName = "RCTView";
148
+
149
+ // src/constants.ts
150
+ var POSITION_OUT_OF_VIEW = -1e7;
151
+ var ANCHORED_POSITION_OUT_OF_VIEW = {
152
+ type: "top",
153
+ relativeCoordinate: POSITION_OUT_OF_VIEW,
154
+ top: POSITION_OUT_OF_VIEW
155
+ };
59
156
 
60
157
  // src/Container.tsx
158
+ var isNewArchitecture = global.nativeFabricUIManager != null;
61
159
  var Container = ({
62
160
  id,
63
161
  recycleItems,
64
162
  horizontal,
65
- waitForInitialLayout,
66
163
  getRenderedItem,
67
164
  updateItemSize,
68
165
  ItemSeparatorComponent
69
166
  }) => {
70
- const ctx = useStateContext();
71
- const position = use$(`containerPosition${id}`);
167
+ useStateContext();
168
+ const maintainVisibleContentPosition = use$("maintainVisibleContentPosition");
169
+ const position = use$(`containerPosition${id}`) || ANCHORED_POSITION_OUT_OF_VIEW;
72
170
  const column = use$(`containerColumn${id}`) || 0;
73
171
  const numColumns = use$("numColumns");
74
172
  const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
75
173
  const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
76
174
  const style = horizontal ? {
77
- flexDirection: "row",
175
+ flexDirection: ItemSeparatorComponent ? "row" : void 0,
78
176
  position: "absolute",
79
177
  top: otherAxisPos,
80
178
  bottom: numColumns > 1 ? null : 0,
81
179
  height: otherAxisSize,
82
- left: position
180
+ left: position.relativeCoordinate
83
181
  } : {
84
182
  position: "absolute",
85
183
  left: otherAxisPos,
86
184
  right: numColumns > 1 ? null : 0,
87
185
  width: otherAxisSize,
88
- top: position
186
+ top: position.relativeCoordinate
89
187
  };
90
- if (waitForInitialLayout) {
91
- const visible = use$(`containerDidLayout${id}`);
92
- style.opacity = visible ? 1 : 0;
93
- }
94
188
  const lastItemKey = use$("lastItemKey");
95
189
  const itemKey = use$(`containerItemKey${id}`);
96
190
  const data = use$(`containerItemData${id}`);
97
- const renderedItem = useMemo(() => itemKey !== void 0 && getRenderedItem(itemKey, id), [itemKey, data]);
98
- return /* @__PURE__ */ React4__default.createElement(
99
- View,
100
- {
101
- style,
102
- onLayout: (event) => {
103
- const key = peek$(ctx, `containerItemKey${id}`);
104
- if (key !== void 0) {
105
- const size = Math.floor(event.nativeEvent.layout[horizontal ? "width" : "height"] * 8) / 8;
106
- updateItemSize(id, key, size);
191
+ const extraData = use$("extraData");
192
+ const renderedItemInfo = useMemo(
193
+ () => itemKey !== void 0 && getRenderedItem(itemKey),
194
+ [itemKey, data, extraData]
195
+ );
196
+ const { index, renderedItem } = renderedItemInfo || {};
197
+ const onLayout = (event) => {
198
+ if (itemKey !== void 0) {
199
+ const size = Math.floor(event.nativeEvent.layout[horizontal ? "width" : "height"] * 8) / 8;
200
+ if (size === 0) {
201
+ console.log("[WARN] Container 0 height reported, possible bug in LegendList", id, itemKey);
202
+ return;
203
+ }
204
+ updateItemSize(id, itemKey, size);
205
+ }
206
+ };
207
+ const ref = useRef(null);
208
+ if (isNewArchitecture) {
209
+ useLayoutEffect(() => {
210
+ var _a, _b;
211
+ if (itemKey !== void 0) {
212
+ const measured = (_b = (_a = ref.current) == null ? void 0 : _a.unstable_getBoundingClientRect) == null ? void 0 : _b.call(_a);
213
+ if (measured) {
214
+ const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
215
+ if (size) {
216
+ updateItemSize(id, itemKey, size);
217
+ }
107
218
  }
108
219
  }
109
- },
110
- /* @__PURE__ */ React4__default.createElement(React4__default.Fragment, { key: recycleItems ? void 0 : itemKey }, renderedItem, renderedItem && ItemSeparatorComponent && itemKey !== lastItemKey && ItemSeparatorComponent)
220
+ }, [itemKey]);
221
+ }
222
+ const contextValue = useMemo(
223
+ () => ({ containerId: id, itemKey, index, value: data }),
224
+ [id, itemKey, index, data]
111
225
  );
226
+ const contentFragment = /* @__PURE__ */ React5__default.createElement(React5__default.Fragment, { key: recycleItems ? void 0 : itemKey }, /* @__PURE__ */ React5__default.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItem && ItemSeparatorComponent && itemKey !== lastItemKey && ItemSeparatorComponent));
227
+ if (maintainVisibleContentPosition) {
228
+ const anchorStyle = position.type === "top" ? { position: "absolute", top: 0, left: 0, right: 0 } : { position: "absolute", bottom: 0, left: 0, right: 0 };
229
+ return /* @__PURE__ */ React5__default.createElement(LeanView, { style }, /* @__PURE__ */ React5__default.createElement(LeanView, { style: anchorStyle, onLayout, ref }, contentFragment));
230
+ }
231
+ return /* @__PURE__ */ React5__default.createElement(LeanView, { style, onLayout, ref }, contentFragment);
112
232
  };
113
233
  var useAnimatedValue = useAnimatedValue$1 || ((initialValue) => {
114
234
  return useRef(new Animated.Value(initialValue)).current;
115
235
  });
116
- function useValue$(key, getValue, key2) {
236
+ function useValue$(key, getValue, useMicrotask) {
117
237
  var _a;
118
238
  const ctx = useStateContext();
119
- const animValue = useAnimatedValue((_a = peek$(ctx, key)) != null ? _a : 0);
239
+ const animValue = useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
120
240
  useMemo(() => {
121
- listen$(ctx, key, (v) => animValue.setValue(v));
241
+ let newValue = void 0;
242
+ listen$(ctx, key, (v) => {
243
+ if (useMicrotask && newValue === void 0) {
244
+ queueMicrotask(() => {
245
+ animValue.setValue(newValue);
246
+ newValue = void 0;
247
+ });
248
+ }
249
+ newValue = getValue ? getValue(v) : v;
250
+ if (!useMicrotask) {
251
+ animValue.setValue(newValue);
252
+ }
253
+ });
122
254
  }, []);
123
255
  return animValue;
124
256
  }
125
257
 
126
258
  // src/Containers.tsx
127
- var Containers = React4.memo(function Containers2({
259
+ var Containers = React5.memo(function Containers2({
128
260
  horizontal,
129
261
  recycleItems,
130
262
  ItemSeparatorComponent,
@@ -133,18 +265,23 @@ var Containers = React4.memo(function Containers2({
133
265
  getRenderedItem
134
266
  }) {
135
267
  const numContainers = use$("numContainersPooled");
136
- const animSize = useValue$("totalSize");
268
+ const animSize = useValue$(
269
+ "totalSize",
270
+ void 0,
271
+ /*useMicrotask*/
272
+ true
273
+ );
274
+ const animOpacity = waitForInitialLayout ? useValue$("containersDidLayout", (value) => value ? 1 : 0) : void 0;
137
275
  const containers = [];
138
276
  for (let i = 0; i < numContainers; i++) {
139
277
  containers.push(
140
- /* @__PURE__ */ React4.createElement(
278
+ /* @__PURE__ */ React5.createElement(
141
279
  Container,
142
280
  {
143
281
  id: i,
144
282
  key: i,
145
283
  recycleItems,
146
284
  horizontal,
147
- waitForInitialLayout,
148
285
  getRenderedItem,
149
286
  updateItemSize,
150
287
  ItemSeparatorComponent
@@ -152,21 +289,21 @@ var Containers = React4.memo(function Containers2({
152
289
  )
153
290
  );
154
291
  }
155
- const style = horizontal ? { width: animSize } : { height: animSize };
156
- return /* @__PURE__ */ React4.createElement(Animated.View, { style }, containers);
292
+ const style = horizontal ? { width: animSize, opacity: animOpacity } : { height: animSize, opacity: animOpacity };
293
+ return /* @__PURE__ */ React5.createElement(Animated.View, { style }, containers);
157
294
  });
158
295
 
159
296
  // src/ListComponent.tsx
160
297
  var getComponent = (Component) => {
161
- if (React4.isValidElement(Component)) {
298
+ if (React5.isValidElement(Component)) {
162
299
  return Component;
163
300
  }
164
301
  if (Component) {
165
- return /* @__PURE__ */ React4.createElement(Component, null);
302
+ return /* @__PURE__ */ React5.createElement(Component, null);
166
303
  }
167
304
  return null;
168
305
  };
169
- var ListComponent = React4.memo(function ListComponent2({
306
+ var ListComponent = React5.memo(function ListComponent2({
170
307
  style,
171
308
  contentContainerStyle,
172
309
  horizontal,
@@ -182,7 +319,6 @@ var ListComponent = React4.memo(function ListComponent2({
182
319
  ListFooterComponent,
183
320
  ListFooterComponentStyle,
184
321
  ListEmptyComponent,
185
- ListEmptyComponentStyle,
186
322
  getRenderedItem,
187
323
  updateItemSize,
188
324
  refScrollView,
@@ -194,16 +330,16 @@ var ListComponent = React4.memo(function ListComponent2({
194
330
  const animPaddingTop = useValue$("paddingTop");
195
331
  const animScrollAdjust = useValue$("scrollAdjust");
196
332
  const ScrollComponent = renderScrollComponent ? useMemo(
197
- () => React4.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
333
+ () => React5.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
198
334
  [renderScrollComponent]
199
335
  ) : ScrollView;
200
336
  const additionalSize = { marginTop: animScrollAdjust, paddingTop: animPaddingTop };
201
- return /* @__PURE__ */ React4.createElement(
337
+ return /* @__PURE__ */ React5.createElement(
202
338
  ScrollComponent,
203
339
  {
204
340
  ...rest,
205
341
  style,
206
- maintainVisibleContentPosition: maintainVisibleContentPosition ? { minIndexForVisible: 0 } : void 0,
342
+ maintainVisibleContentPosition: maintainVisibleContentPosition && !ListEmptyComponent ? { minIndexForVisible: 0 } : void 0,
207
343
  contentContainerStyle: [
208
344
  contentContainerStyle,
209
345
  horizontal ? {
@@ -216,8 +352,8 @@ var ListComponent = React4.memo(function ListComponent2({
216
352
  contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
217
353
  ref: refScrollView
218
354
  },
219
- /* @__PURE__ */ React4.createElement(Animated.View, { style: additionalSize }),
220
- ListHeaderComponent && /* @__PURE__ */ React4.createElement(
355
+ /* @__PURE__ */ React5.createElement(Animated.View, { style: additionalSize }),
356
+ ListHeaderComponent && /* @__PURE__ */ React5.createElement(
221
357
  Animated.View,
222
358
  {
223
359
  style: ListHeaderComponentStyle,
@@ -231,8 +367,8 @@ var ListComponent = React4.memo(function ListComponent2({
231
367
  },
232
368
  getComponent(ListHeaderComponent)
233
369
  ),
234
- ListEmptyComponent && /* @__PURE__ */ React4.createElement(Animated.View, { style: ListEmptyComponentStyle }, getComponent(ListEmptyComponent)),
235
- /* @__PURE__ */ React4.createElement(
370
+ ListEmptyComponent && getComponent(ListEmptyComponent),
371
+ /* @__PURE__ */ React5.createElement(
236
372
  Containers,
237
373
  {
238
374
  horizontal,
@@ -243,7 +379,7 @@ var ListComponent = React4.memo(function ListComponent2({
243
379
  updateItemSize
244
380
  }
245
381
  ),
246
- ListFooterComponent && /* @__PURE__ */ React4.createElement(View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
382
+ ListFooterComponent && /* @__PURE__ */ React5.createElement(View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
247
383
  );
248
384
  });
249
385
 
@@ -283,14 +419,6 @@ var ScrollAdjustHandler = class {
283
419
  return this.appliedAdjust;
284
420
  }
285
421
  };
286
- var symbolFirst = Symbol();
287
- function useInit(cb) {
288
- const refValue = useRef(symbolFirst);
289
- if (refValue.current === symbolFirst) {
290
- refValue.current = cb();
291
- }
292
- return refValue.current;
293
- }
294
422
 
295
423
  // src/viewability.ts
296
424
  var mapViewabilityConfigCallbackPairs = /* @__PURE__ */ new Map();
@@ -441,13 +569,12 @@ function maybeUpdateViewabilityCallback(ctx, configId, viewToken) {
441
569
 
442
570
  // src/LegendList.tsx
443
571
  var DEFAULT_DRAW_DISTANCE = 250;
444
- var POSITION_OUT_OF_VIEW = -1e7;
445
572
  var DEFAULT_ITEM_SIZE = 100;
446
573
  var LegendList = forwardRef(function LegendList2(props, forwardedRef) {
447
- return /* @__PURE__ */ React4.createElement(StateProvider, null, /* @__PURE__ */ React4.createElement(LegendListInner, { ...props, ref: forwardedRef }));
574
+ return /* @__PURE__ */ React5.createElement(StateProvider, null, /* @__PURE__ */ React5.createElement(LegendListInner, { ...props, ref: forwardedRef }));
448
575
  });
449
576
  var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef) {
450
- var _a, _b, _c, _d;
577
+ var _a, _b, _c, _d, _e, _f, _g;
451
578
  const {
452
579
  data,
453
580
  initialScrollIndex,
@@ -467,15 +594,22 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
467
594
  renderItem,
468
595
  estimatedItemSize,
469
596
  getEstimatedItemSize,
470
- onEndReached,
471
- onStartReached,
472
597
  ListEmptyComponent,
473
598
  onItemSizeChanged,
474
599
  scrollEventThrottle,
475
600
  refScrollView,
601
+ waitForInitialLayout = true,
602
+ extraData,
603
+ onLayout: onLayoutProp,
476
604
  ...rest
477
605
  } = props;
478
606
  const { style, contentContainerStyle } = props;
607
+ const callbacks = useRef({
608
+ onStartReached: rest.onStartReached,
609
+ onEndReached: rest.onEndReached
610
+ });
611
+ callbacks.current.onStartReached = rest.onStartReached;
612
+ callbacks.current.onEndReached = rest.onEndReached;
479
613
  const ctx = useStateContext();
480
614
  const refScroller = useRef(null);
481
615
  const scrollBuffer = drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE;
@@ -522,7 +656,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
522
656
  positions: /* @__PURE__ */ new Map(),
523
657
  columns: /* @__PURE__ */ new Map(),
524
658
  pendingAdjust: 0,
525
- animFrameLayout: null,
659
+ waitingForMicrotask: false,
526
660
  isStartReached: initialContentOffset < initialScrollLength * onStartReachedThreshold,
527
661
  isEndReached: false,
528
662
  isAtBottom: false,
@@ -555,8 +689,9 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
555
689
  belowAnchorElementPositions: void 0,
556
690
  rowHeights: /* @__PURE__ */ new Map(),
557
691
  startReachedBlockedByTimer: false,
558
- layoutsPending: /* @__PURE__ */ new Set(),
559
- scrollForNextCalculateItemsInView: void 0
692
+ scrollForNextCalculateItemsInView: void 0,
693
+ enableScrollForNextCalculateItemsInView: true,
694
+ minIndexSizeChanged: 0
560
695
  };
561
696
  refState.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
562
697
  if (maintainVisibleContentPosition) {
@@ -575,6 +710,8 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
575
710
  }
576
711
  }
577
712
  set$(ctx, "scrollAdjust", 0);
713
+ set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
714
+ set$(ctx, "extraData", extraData);
578
715
  }
579
716
  const getAnchorElementIndex = () => {
580
717
  const state = refState.current;
@@ -586,14 +723,14 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
586
723
  };
587
724
  const addTotalSize = useCallback((key, add, totalSizeBelowAnchor) => {
588
725
  const state = refState.current;
589
- const index = key === null ? 0 : state.indexByKey.get(key);
726
+ const { scrollLength, indexByKey, anchorElement } = state;
727
+ const index = key === null ? 0 : indexByKey.get(key);
590
728
  let isAboveAnchor = false;
591
729
  if (maintainVisibleContentPosition) {
592
- if (state.anchorElement && index < getAnchorElementIndex()) {
730
+ if (anchorElement && index < getAnchorElementIndex()) {
593
731
  isAboveAnchor = true;
594
732
  }
595
733
  }
596
- state.totalSize;
597
734
  if (key === null) {
598
735
  state.totalSize = add;
599
736
  state.totalSizeBelowAnchor = totalSizeBelowAnchor;
@@ -604,19 +741,19 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
604
741
  }
605
742
  }
606
743
  let applyAdjustValue = void 0;
607
- if (maintainVisibleContentPosition) {
608
- const newAdjust = state.anchorElement.coordinate - state.totalSizeBelowAnchor;
744
+ const totalSize = state.totalSize;
745
+ let resultSize = totalSize;
746
+ if (maintainVisibleContentPosition && totalSize > scrollLength) {
747
+ const newAdjust = anchorElement.coordinate - state.totalSizeBelowAnchor;
609
748
  applyAdjustValue = -newAdjust;
610
749
  state.belowAnchorElementPositions = buildElementPositionsBelowAnchor();
611
750
  state.rowHeights.clear();
612
- }
613
- const totalSize = state.totalSize;
614
- let resultSize = totalSize;
615
- if (applyAdjustValue !== void 0) {
616
- resultSize -= applyAdjustValue;
617
- refState.current.scrollAdjustHandler.requestAdjust(applyAdjustValue, (diff) => {
618
- state.scroll -= diff;
619
- });
751
+ if (applyAdjustValue !== void 0) {
752
+ resultSize -= applyAdjustValue;
753
+ refState.current.scrollAdjustHandler.requestAdjust(applyAdjustValue, (diff) => {
754
+ state.scroll -= diff;
755
+ });
756
+ }
620
757
  }
621
758
  set$(ctx, "totalSize", resultSize);
622
759
  if (alignItemsAtEnd) {
@@ -634,7 +771,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
634
771
  }
635
772
  let rowHeight = 0;
636
773
  const startEl = n * numColumnsProp;
637
- for (let i = startEl; i < startEl + numColumnsProp; i++) {
774
+ for (let i = startEl; i < startEl + numColumnsProp && i < data.length; i++) {
638
775
  const id = getId(i);
639
776
  const size = getItemSize(id, i, data[i]);
640
777
  rowHeight = Math.max(rowHeight, size);
@@ -675,7 +812,6 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
675
812
  return res;
676
813
  };
677
814
  const calculateItemsInView = useCallback((speed) => {
678
- var _a2, _b2, _c2, _d2;
679
815
  const state = refState.current;
680
816
  const {
681
817
  data: data2,
@@ -684,12 +820,10 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
684
820
  startBufferedId: startBufferedIdOrig,
685
821
  positions,
686
822
  columns,
687
- scrollAdjustHandler,
688
- layoutsPending
823
+ scrollAdjustHandler
689
824
  } = state;
690
- if (state.animFrameLayout) {
691
- cancelAnimationFrame(state.animFrameLayout);
692
- state.animFrameLayout = null;
825
+ if (state.waitingForMicrotask) {
826
+ state.waitingForMicrotask = false;
693
827
  }
694
828
  if (!data2) {
695
829
  return;
@@ -697,9 +831,19 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
697
831
  const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
698
832
  const previousScrollAdjust = scrollAdjustHandler.getAppliedAdjust();
699
833
  const scrollExtra = Math.max(-16, Math.min(16, speed)) * 16;
700
- const scroll = scrollState - previousScrollAdjust - topPad - scrollExtra;
701
- if (refState.current.scrollForNextCalculateItemsInView) {
702
- const { top: top2, bottom } = refState.current.scrollForNextCalculateItemsInView;
834
+ const scroll = scrollState - previousScrollAdjust - topPad;
835
+ let scrollBufferTop = scrollBuffer;
836
+ let scrollBufferBottom = scrollBuffer;
837
+ if (scrollExtra > 8) {
838
+ scrollBufferTop = 0;
839
+ scrollBufferBottom = scrollBuffer + scrollExtra;
840
+ }
841
+ if (scrollExtra < -8) {
842
+ scrollBufferTop = scrollBuffer - scrollExtra;
843
+ scrollBufferBottom = 0;
844
+ }
845
+ if (state.scrollForNextCalculateItemsInView) {
846
+ const { top: top2, bottom } = state.scrollForNextCalculateItemsInView;
703
847
  if (scroll > top2 && scroll < bottom) {
704
848
  return;
705
849
  }
@@ -710,8 +854,11 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
710
854
  let startBufferedId = null;
711
855
  let endNoBuffer = null;
712
856
  let endBuffered = null;
713
- const originalStartId = startBufferedIdOrig && state.indexByKey.get(startBufferedIdOrig);
714
- let loopStart = originalStartId || 0;
857
+ let loopStart = startBufferedIdOrig ? state.indexByKey.get(startBufferedIdOrig) || 0 : 0;
858
+ if (state.minIndexSizeChanged !== void 0) {
859
+ loopStart = Math.min(state.minIndexSizeChanged, loopStart);
860
+ state.minIndexSizeChanged = void 0;
861
+ }
715
862
  const anchorElementIndex = getAnchorElementIndex();
716
863
  for (let i = loopStart; i >= 0; i--) {
717
864
  const id = getId(i);
@@ -742,13 +889,13 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
742
889
  let column = 1;
743
890
  let maxSizeInRow = 0;
744
891
  const getInitialTop = (i) => {
745
- var _a3;
892
+ var _a2;
746
893
  const id = getId(i);
747
894
  let topOffset = 0;
748
895
  if (positions.get(id)) {
749
896
  topOffset = positions.get(id);
750
897
  }
751
- if (id === ((_a3 = state.anchorElement) == null ? void 0 : _a3.id)) {
898
+ if (id === ((_a2 = state.anchorElement) == null ? void 0 : _a2.id)) {
752
899
  topOffset = initialContentOffset || 0;
753
900
  }
754
901
  return topOffset;
@@ -769,7 +916,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
769
916
  if (startNoBuffer === null && top + size > scroll) {
770
917
  startNoBuffer = i;
771
918
  }
772
- if (startBuffered === null && top + size > scroll - scrollBuffer) {
919
+ if (startBuffered === null && top + size > scroll - scrollBufferTop) {
773
920
  startBuffered = i;
774
921
  startBufferedId = id;
775
922
  }
@@ -777,7 +924,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
777
924
  if (top <= scrollBottom) {
778
925
  endNoBuffer = i;
779
926
  }
780
- if (top <= scrollBottom + scrollBuffer) {
927
+ if (top <= scrollBottom + scrollBufferBottom) {
781
928
  endBuffered = i;
782
929
  } else {
783
930
  break;
@@ -790,21 +937,23 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
790
937
  maxSizeInRow = 0;
791
938
  }
792
939
  }
793
- Object.assign(refState.current, {
940
+ Object.assign(state, {
794
941
  startBuffered,
795
942
  startBufferedId,
796
943
  startNoBuffer,
797
944
  endBuffered,
798
945
  endNoBuffer
799
946
  });
800
- const nextTop = Math.ceil(startBuffered ? positions.get(startBufferedId) + scrollBuffer : 0);
947
+ const nextTop = Math.ceil(startBuffered !== null ? positions.get(startBufferedId) + scrollBuffer : 0);
801
948
  const nextBottom = Math.floor(
802
- endBuffered ? (positions.get(getId(endBuffered + 1)) || 0) - scrollLength - scrollBuffer : 0
949
+ endBuffered !== null ? (positions.get(getId(endBuffered + 1)) || 0) - scrollLength - scrollBuffer : 0
803
950
  );
804
- refState.current.scrollForNextCalculateItemsInView = nextTop >= 0 && nextBottom >= 0 ? {
805
- top: nextTop,
806
- bottom: nextBottom
807
- } : void 0;
951
+ if (state.enableScrollForNextCalculateItemsInView) {
952
+ state.scrollForNextCalculateItemsInView = nextTop >= 0 && nextBottom >= 0 ? {
953
+ top: nextTop,
954
+ bottom: nextBottom
955
+ } : void 0;
956
+ }
808
957
  if (startBuffered !== null && endBuffered !== null) {
809
958
  const prevNumContainers = ctx.values.get("numContainers");
810
959
  let numContainers = prevNumContainers;
@@ -828,8 +977,8 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
828
977
  furthestIndex = u;
829
978
  break;
830
979
  }
831
- const index = (_a2 = refState.current) == null ? void 0 : _a2.indexByKey.get(key);
832
- const pos = peek$(ctx, `containerPosition${u}`);
980
+ const index = state.indexByKey.get(key);
981
+ const pos = peek$(ctx, `containerPosition${u}`).top;
833
982
  if (index < startBuffered || index > endBuffered) {
834
983
  const distance = Math.abs(pos - top2);
835
984
  if (index < 0 || distance > furthestDistance) {
@@ -840,15 +989,15 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
840
989
  }
841
990
  if (furthestIndex >= 0) {
842
991
  set$(ctx, `containerItemKey${furthestIndex}`, id);
843
- const index = (_b2 = refState.current) == null ? void 0 : _b2.indexByKey.get(id);
992
+ const index = state.indexByKey.get(id);
844
993
  set$(ctx, `containerItemData${furthestIndex}`, data2[index]);
845
994
  } else {
846
995
  const containerId = numContainers;
847
996
  numContainers++;
848
997
  set$(ctx, `containerItemKey${containerId}`, id);
849
- const index = (_c2 = refState.current) == null ? void 0 : _c2.indexByKey.get(id);
998
+ const index = state.indexByKey.get(id);
850
999
  set$(ctx, `containerItemData${containerId}`, data2[index]);
851
- set$(ctx, `containerPosition${containerId}`, POSITION_OUT_OF_VIEW);
1000
+ set$(ctx, `containerPosition${containerId}`, ANCHORED_POSITION_OUT_OF_VIEW);
852
1001
  set$(ctx, `containerColumn${containerId}`, -1);
853
1002
  if (__DEV__ && numContainers > peek$(ctx, "numContainersPooled")) {
854
1003
  console.warn(
@@ -867,24 +1016,36 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
867
1016
  }
868
1017
  for (let i = 0; i < numContainers; i++) {
869
1018
  const itemKey = peek$(ctx, `containerItemKey${i}`);
870
- const itemIndex = (_d2 = refState.current) == null ? void 0 : _d2.indexByKey.get(itemKey);
1019
+ const itemIndex = state.indexByKey.get(itemKey);
871
1020
  const item = data2[itemIndex];
872
1021
  if (item) {
873
1022
  const id = getId(itemIndex);
874
1023
  if (itemKey !== id || itemIndex < startBuffered || itemIndex > endBuffered) {
875
- const prevPos = peek$(ctx, `containerPosition${i}`);
1024
+ const prevPos = peek$(ctx, `containerPosition${i}`).top;
876
1025
  const pos = positions.get(id) || 0;
877
1026
  const size = getItemSize(id, itemIndex, data2[i]);
878
1027
  if (pos + size >= scroll && pos <= scrollBottom || prevPos + size >= scroll && prevPos <= scrollBottom) {
879
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1028
+ set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
880
1029
  }
881
1030
  } else {
882
- const pos = positions.get(id) || 0;
1031
+ const pos = {
1032
+ type: "top",
1033
+ relativeCoordinate: positions.get(id) || 0,
1034
+ top: positions.get(id) || 0
1035
+ };
883
1036
  const column2 = columns.get(id) || 1;
1037
+ if (maintainVisibleContentPosition && itemIndex < anchorElementIndex) {
1038
+ const currentRow = Math.floor(itemIndex / numColumnsProp);
1039
+ const rowHeight = getRowHeight(currentRow);
1040
+ const elementHeight = getItemSize(id, itemIndex, data2[i]);
1041
+ const diff = rowHeight - elementHeight;
1042
+ pos.relativeCoordinate = pos.top + getRowHeight(currentRow) - diff;
1043
+ pos.type = "bottom";
1044
+ }
884
1045
  const prevPos = peek$(ctx, `containerPosition${i}`);
885
1046
  const prevColumn = peek$(ctx, `containerColumn${i}`);
886
1047
  const prevData = peek$(ctx, `containerItemData${i}`);
887
- if (pos > POSITION_OUT_OF_VIEW && pos !== prevPos) {
1048
+ if (pos.relativeCoordinate > POSITION_OUT_OF_VIEW && pos.top !== prevPos.top) {
888
1049
  set$(ctx, `containerPosition${i}`, pos);
889
1050
  }
890
1051
  if (column2 >= 0 && column2 !== prevColumn) {
@@ -897,17 +1058,12 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
897
1058
  }
898
1059
  }
899
1060
  }
900
- if (layoutsPending.size > 0) {
901
- for (const containerId of layoutsPending) {
902
- set$(ctx, `containerDidLayout${containerId}`, true);
903
- }
904
- layoutsPending.clear();
905
- }
906
- if (refState.current.viewabilityConfigCallbackPairs) {
1061
+ set$(ctx, "containersDidLayout", true);
1062
+ if (state.viewabilityConfigCallbackPairs) {
907
1063
  updateViewableItems(
908
- refState.current,
1064
+ state,
909
1065
  ctx,
910
- refState.current.viewabilityConfigCallbackPairs,
1066
+ state.viewabilityConfigCallbackPairs,
911
1067
  getId,
912
1068
  scrollLength,
913
1069
  startNoBuffer,
@@ -946,6 +1102,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
946
1102
  if (refState.current) {
947
1103
  refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
948
1104
  }
1105
+ const { onEndReached } = callbacks.current;
949
1106
  if (onEndReached) {
950
1107
  if (!refState.current.isEndReached) {
951
1108
  if (distanceFromEnd < onEndReachedThreshold * scrollLength) {
@@ -967,6 +1124,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
967
1124
  const { scrollLength, scroll } = refState.current;
968
1125
  const distanceFromTop = scroll;
969
1126
  refState.current.isAtTop = distanceFromTop < 0;
1127
+ const { onStartReached } = callbacks.current;
970
1128
  if (onStartReached) {
971
1129
  if (!refState.current.isStartReached && !refState.current.startReachedBlockedByTimer) {
972
1130
  if (distanceFromTop < onStartReachedThreshold * scrollLength) {
@@ -995,13 +1153,13 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
995
1153
  const itemKey = peek$(ctx, `containerItemKey${i}`);
996
1154
  if (!keyExtractorProp || itemKey && state.indexByKey.get(itemKey) === void 0) {
997
1155
  set$(ctx, `containerItemKey${i}`, void 0);
998
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1156
+ set$(ctx, `containerItemData${i}`, void 0);
1157
+ set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
999
1158
  set$(ctx, `containerColumn${i}`, -1);
1000
1159
  }
1001
1160
  }
1002
1161
  if (!keyExtractorProp) {
1003
- state.sizes.clear();
1004
- state.positions;
1162
+ state.positions.clear();
1005
1163
  }
1006
1164
  calculateItemsInView(state.scrollVelocity);
1007
1165
  }
@@ -1016,20 +1174,63 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1016
1174
  const isFirst = !refState.current.renderItem;
1017
1175
  if (isFirst || data !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
1018
1176
  if (!keyExtractorProp && !isFirst && data !== refState.current.data) {
1019
- refState.current.sizes.clear();
1020
1177
  refState.current.positions.clear();
1021
1178
  }
1022
1179
  refState.current.data = data;
1023
1180
  let totalSize = 0;
1024
1181
  let totalSizeBelowIndex = 0;
1025
1182
  const indexByKey = /* @__PURE__ */ new Map();
1183
+ const newPositions = /* @__PURE__ */ new Map();
1026
1184
  let column = 1;
1027
1185
  let maxSizeInRow = 0;
1028
1186
  for (let i = 0; i < data.length; i++) {
1029
1187
  const key = getId(i);
1188
+ if (__DEV__) {
1189
+ if (indexByKey.has(key)) {
1190
+ console.error(
1191
+ `[legend-list] Error: Detected overlapping key (${key}) which causes missing items and gaps and other terrrible things. Check that keyExtractor returns unique values.`
1192
+ );
1193
+ }
1194
+ }
1030
1195
  indexByKey.set(key, i);
1196
+ if (refState.current.positions.get(key) != null && refState.current.indexByKey.get(key) === i) {
1197
+ newPositions.set(key, refState.current.positions.get(key));
1198
+ }
1031
1199
  }
1032
1200
  refState.current.indexByKey = indexByKey;
1201
+ refState.current.positions = newPositions;
1202
+ if (!isFirst) {
1203
+ if (maintainVisibleContentPosition) {
1204
+ if (refState.current.anchorElement == null || indexByKey.get(refState.current.anchorElement.id) == null) {
1205
+ if (data.length) {
1206
+ const newAnchorElement = {
1207
+ coordinate: 0,
1208
+ id: getId(0)
1209
+ };
1210
+ refState.current.anchorElement = newAnchorElement;
1211
+ (_a = refState.current.belowAnchorElementPositions) == null ? void 0 : _a.clear();
1212
+ (_b = refScroller.current) == null ? void 0 : _b.scrollTo({ x: 0, y: 0, animated: false });
1213
+ setTimeout(() => {
1214
+ calculateItemsInView(0);
1215
+ }, 0);
1216
+ } else {
1217
+ refState.current.startBufferedId = void 0;
1218
+ }
1219
+ }
1220
+ } else {
1221
+ if (refState.current.startBufferedId != null && newPositions.get(refState.current.startBufferedId) == null) {
1222
+ if (data.length) {
1223
+ refState.current.startBufferedId = getId(0);
1224
+ } else {
1225
+ refState.current.startBufferedId = void 0;
1226
+ }
1227
+ (_c = refScroller.current) == null ? void 0 : _c.scrollTo({ x: 0, y: 0, animated: false });
1228
+ setTimeout(() => {
1229
+ calculateItemsInView(0);
1230
+ }, 0);
1231
+ }
1232
+ }
1233
+ }
1033
1234
  const anchorElementIndex = getAnchorElementIndex();
1034
1235
  for (let i = 0; i < data.length; i++) {
1035
1236
  const key = getId(i);
@@ -1045,6 +1246,9 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1045
1246
  maxSizeInRow = 0;
1046
1247
  }
1047
1248
  }
1249
+ if (maxSizeInRow > 0) {
1250
+ totalSize += maxSizeInRow;
1251
+ }
1048
1252
  addTotalSize(null, totalSize, totalSizeBelowIndex);
1049
1253
  }
1050
1254
  useEffect(() => {
@@ -1053,9 +1257,12 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1053
1257
  !isFirst
1054
1258
  );
1055
1259
  }, [isFirst, data, numColumnsProp]);
1260
+ useEffect(() => {
1261
+ set$(ctx, "extraData", extraData);
1262
+ }, [extraData]);
1056
1263
  refState.current.renderItem = renderItem;
1057
- const lastItemKey = getId(data[data.length - 1]);
1058
- const stylePaddingTop = (_d = (_c = (_a = StyleSheet.flatten(style)) == null ? void 0 : _a.paddingTop) != null ? _c : (_b = StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _b.paddingTop) != null ? _d : 0;
1264
+ const lastItemKey = data.length > 0 ? getId(data.length - 1) : void 0;
1265
+ const stylePaddingTop = (_g = (_f = (_d = StyleSheet.flatten(style)) == null ? void 0 : _d.paddingTop) != null ? _f : (_e = StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _e.paddingTop) != null ? _g : 0;
1059
1266
  const initalizeStateVars = () => {
1060
1267
  set$(ctx, "lastItemKey", lastItemKey);
1061
1268
  set$(ctx, "numColumns", numColumnsProp);
@@ -1065,7 +1272,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1065
1272
  initalizeStateVars();
1066
1273
  }
1067
1274
  useEffect(initalizeStateVars, [lastItemKey, numColumnsProp, stylePaddingTop]);
1068
- const getRenderedItem = useCallback((key, containerId) => {
1275
+ const getRenderedItem = useCallback((key) => {
1069
1276
  var _a2, _b2;
1070
1277
  const state = refState.current;
1071
1278
  if (!state) {
@@ -1076,134 +1283,68 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1076
1283
  if (index === void 0) {
1077
1284
  return null;
1078
1285
  }
1079
- const useViewability = (configId, callback) => {
1080
- const key2 = containerId + configId;
1081
- useInit(() => {
1082
- const value = ctx.mapViewabilityValues.get(key2);
1083
- if (value) {
1084
- callback(value);
1085
- }
1086
- });
1087
- ctx.mapViewabilityCallbacks.set(key2, callback);
1088
- useEffect(
1089
- () => () => {
1090
- ctx.mapViewabilityCallbacks.delete(key2);
1091
- },
1092
- []
1093
- );
1286
+ const useViewability2 = (configId, callback) => {
1287
+ useViewability(configId, callback);
1094
1288
  };
1095
- const useViewabilityAmount = (callback) => {
1096
- useInit(() => {
1097
- const value = ctx.mapViewabilityAmountValues.get(containerId);
1098
- if (value) {
1099
- callback(value);
1100
- }
1101
- });
1102
- ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
1103
- useEffect(
1104
- () => () => {
1105
- ctx.mapViewabilityAmountCallbacks.delete(containerId);
1106
- },
1107
- []
1108
- );
1289
+ const useViewabilityAmount2 = (callback) => {
1290
+ useViewabilityAmount(callback);
1109
1291
  };
1110
- const useRecyclingEffect = (effect) => {
1111
- useEffect(() => {
1112
- const state2 = refState.current;
1113
- let prevIndex = index;
1114
- let prevItem = state2.data[index];
1115
- const signal = `containerItemKey${containerId}`;
1116
- const run = () => {
1117
- const data3 = state2.data;
1118
- if (data3) {
1119
- const newKey = peek$(ctx, signal);
1120
- const newIndex = state2.indexByKey.get(newKey);
1121
- const newItem = data3[newIndex];
1122
- if (newItem) {
1123
- effect({
1124
- index: newIndex,
1125
- item: newItem,
1126
- prevIndex,
1127
- prevItem
1128
- });
1129
- }
1130
- prevIndex = newIndex;
1131
- prevItem = newItem;
1132
- }
1133
- };
1134
- run();
1135
- return listen$(ctx, signal, run);
1136
- }, []);
1292
+ const useRecyclingEffect2 = (effect) => {
1293
+ useRecyclingEffect(effect);
1137
1294
  };
1138
- const useRecyclingState = (valueOrFun) => {
1139
- const stateInfo = useState(
1140
- () => typeof valueOrFun === "function" ? valueOrFun({
1141
- index,
1142
- item: refState.current.data[index],
1143
- prevIndex: void 0,
1144
- prevItem: void 0
1145
- }) : valueOrFun
1146
- );
1147
- useRecyclingEffect((state2) => {
1148
- const newState = typeof valueOrFun === "function" ? valueOrFun(state2) : valueOrFun;
1149
- stateInfo[1](newState);
1150
- });
1151
- return stateInfo;
1295
+ const useRecyclingState2 = (valueOrFun) => {
1296
+ return useRecyclingState(valueOrFun);
1152
1297
  };
1153
1298
  const renderedItem = (_b2 = (_a2 = refState.current).renderItem) == null ? void 0 : _b2.call(_a2, {
1154
1299
  item: data2[index],
1155
1300
  index,
1156
- useViewability,
1157
- useViewabilityAmount,
1158
- useRecyclingEffect,
1159
- useRecyclingState
1301
+ useViewability: useViewability2,
1302
+ useViewabilityAmount: useViewabilityAmount2,
1303
+ useRecyclingEffect: useRecyclingEffect2,
1304
+ useRecyclingState: useRecyclingState2
1160
1305
  });
1161
- return renderedItem;
1306
+ return { index, renderedItem };
1162
1307
  }, []);
1163
1308
  useInit(() => {
1164
1309
  var _a2;
1165
- refState.current.viewabilityConfigCallbackPairs = setupViewability(props);
1166
- const scrollLength = refState.current.scrollLength;
1310
+ const state = refState.current;
1311
+ const viewability = setupViewability(props);
1312
+ state.viewabilityConfigCallbackPairs = viewability;
1313
+ state.enableScrollForNextCalculateItemsInView = !viewability;
1314
+ const scrollLength = state.scrollLength;
1167
1315
  const averageItemSize = (_a2 = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, data[0])) != null ? _a2 : DEFAULT_ITEM_SIZE;
1168
1316
  const numContainers = Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize) * numColumnsProp;
1169
1317
  for (let i = 0; i < numContainers; i++) {
1170
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1318
+ set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
1171
1319
  set$(ctx, `containerColumn${i}`, -1);
1172
1320
  }
1173
1321
  set$(ctx, "numContainers", numContainers);
1174
1322
  set$(ctx, "numContainersPooled", numContainers * 2);
1175
- calculateItemsInView(refState.current.scrollVelocity);
1323
+ calculateItemsInView(state.scrollVelocity);
1176
1324
  });
1177
1325
  const updateItemSize = useCallback((containerId, itemKey, size) => {
1178
- var _a2;
1179
- const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
1326
+ const state = refState.current;
1327
+ const { sizes, indexByKey, columns, sizesLaidOut, data: data2 } = state;
1180
1328
  if (!data2) {
1181
1329
  return;
1182
1330
  }
1183
- const state = refState.current;
1184
- const { sizes, indexByKey, idsInFirstRender, columns, sizesLaidOut } = state;
1185
1331
  const index = indexByKey.get(itemKey);
1186
1332
  const numColumns = peek$(ctx, "numColumns");
1187
- const row = Math.floor(index / numColumns);
1188
- const prevSize = getRowHeight(row);
1189
- const measured = peek$(ctx, `containerDidLayout${containerId}`);
1190
- if (!measured) {
1191
- state.layoutsPending.add(containerId);
1192
- }
1333
+ state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, index) : index;
1334
+ const prevSize = getItemSize(itemKey, index, data2);
1193
1335
  if (!prevSize || Math.abs(prevSize - size) > 0.5) {
1194
1336
  let diff;
1195
1337
  if (numColumns > 1) {
1196
- const prevMaxSizeInRow = getRowHeight(row);
1197
1338
  sizes.set(itemKey, size);
1198
1339
  const column = columns.get(itemKey);
1199
1340
  const loopStart = index - (column - 1);
1200
1341
  let nextMaxSizeInRow = 0;
1201
- for (let i = loopStart; i < loopStart + numColumns; i++) {
1342
+ for (let i = loopStart; i < loopStart + numColumns && i < data2.length; i++) {
1202
1343
  const id = getId(i);
1203
1344
  const size2 = getItemSize(id, i, data2[i]);
1204
1345
  nextMaxSizeInRow = Math.max(nextMaxSizeInRow, size2);
1205
1346
  }
1206
- diff = nextMaxSizeInRow - prevMaxSizeInRow;
1347
+ diff = nextMaxSizeInRow - prevSize;
1207
1348
  } else {
1208
1349
  sizes.set(itemKey, size);
1209
1350
  diff = size - prevSize;
@@ -1231,11 +1372,14 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1231
1372
  addTotalSize(itemKey, diff, 0);
1232
1373
  doMaintainScrollAtEnd(true);
1233
1374
  const scrollVelocity = state.scrollVelocity;
1234
- if (!state.animFrameLayout && (Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1)) {
1235
- if (!peek$(ctx, `containerDidLayout${containerId}`)) {
1236
- state.animFrameLayout = requestAnimationFrame(() => {
1237
- state.animFrameLayout = null;
1238
- calculateItemsInView(state.scrollVelocity);
1375
+ if (!state.waitingForMicrotask && (Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1)) {
1376
+ if (!peek$(ctx, "containersDidLayout")) {
1377
+ state.waitingForMicrotask = true;
1378
+ queueMicrotask(() => {
1379
+ if (state.waitingForMicrotask) {
1380
+ state.waitingForMicrotask = false;
1381
+ calculateItemsInView(state.scrollVelocity);
1382
+ }
1239
1383
  });
1240
1384
  } else {
1241
1385
  calculateItemsInView(state.scrollVelocity);
@@ -1244,8 +1388,6 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1244
1388
  if (onItemSizeChanged) {
1245
1389
  onItemSizeChanged({ size, previous: prevSize, index, itemKey, itemData: data2[index] });
1246
1390
  }
1247
- } else {
1248
- set$(ctx, `containerDidLayout${containerId}`, true);
1249
1391
  }
1250
1392
  }, []);
1251
1393
  const handleScrollDebounced = useCallback((velocity) => {
@@ -1255,11 +1397,15 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1255
1397
  }, []);
1256
1398
  const onLayout = useCallback((event) => {
1257
1399
  const scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
1400
+ const didChange = scrollLength !== refState.current.scrollLength;
1258
1401
  refState.current.scrollLength = scrollLength;
1259
1402
  doMaintainScrollAtEnd(false);
1260
1403
  doUpdatePaddingTop();
1261
1404
  checkAtBottom();
1262
1405
  checkAtTop();
1406
+ if (didChange) {
1407
+ calculateItemsInView(0);
1408
+ }
1263
1409
  if (__DEV__) {
1264
1410
  const isWidthZero = event.nativeEvent.layout.width === 0;
1265
1411
  const isHeightZero = event.nativeEvent.layout.height === 0;
@@ -1269,6 +1415,9 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1269
1415
  );
1270
1416
  }
1271
1417
  }
1418
+ if (onLayoutProp) {
1419
+ onLayoutProp(event);
1420
+ }
1272
1421
  }, []);
1273
1422
  const handleScroll = useCallback(
1274
1423
  (event, fromSelf) => {
@@ -1322,9 +1471,9 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1322
1471
  };
1323
1472
  return {
1324
1473
  getNativeScrollRef: () => refScroller.current,
1325
- getScrollableNode: refScroller.current.getScrollableNode,
1326
- getScrollResponder: refScroller.current.getScrollResponder,
1327
- flashScrollIndicators: refScroller.current.flashScrollIndicators,
1474
+ getScrollableNode: () => refScroller.current.getScrollableNode(),
1475
+ getScrollResponder: () => refScroller.current.getScrollResponder(),
1476
+ flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
1328
1477
  scrollToIndex,
1329
1478
  scrollToOffset: ({ offset, animated }) => {
1330
1479
  const offsetObj = horizontal ? { x: offset, y: 0 } : { x: 0, y: offset };
@@ -1336,12 +1485,12 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1336
1485
  scrollToIndex({ index, animated });
1337
1486
  }
1338
1487
  },
1339
- scrollToEnd: refScroller.current.scrollToEnd
1488
+ scrollToEnd: () => refScroller.current.scrollToEnd()
1340
1489
  };
1341
1490
  },
1342
1491
  []
1343
1492
  );
1344
- return /* @__PURE__ */ React4.createElement(
1493
+ return /* @__PURE__ */ React5.createElement(
1345
1494
  ListComponent,
1346
1495
  {
1347
1496
  ...rest,
@@ -1366,9 +1515,10 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1366
1515
  ListEmptyComponent: data.length === 0 ? ListEmptyComponent : void 0,
1367
1516
  maintainVisibleContentPosition,
1368
1517
  scrollEventThrottle: scrollEventThrottle != null ? scrollEventThrottle : Platform.OS === "web" ? 16 : void 0,
1518
+ waitForInitialLayout,
1369
1519
  style
1370
1520
  }
1371
1521
  );
1372
1522
  });
1373
1523
 
1374
- export { LegendList };
1524
+ export { LegendList, useRecyclingEffect, useRecyclingState, useViewability, useViewabilityAmount };