@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.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React4 = require('react');
3
+ var React5 = require('react');
4
4
  var reactNative = require('react-native');
5
5
 
6
6
  function _interopNamespace(e) {
@@ -21,12 +21,12 @@ function _interopNamespace(e) {
21
21
  return Object.freeze(n);
22
22
  }
23
23
 
24
- var React4__namespace = /*#__PURE__*/_interopNamespace(React4);
24
+ var React5__namespace = /*#__PURE__*/_interopNamespace(React5);
25
25
 
26
26
  // src/LegendList.tsx
27
- var ContextState = React4__namespace.createContext(null);
27
+ var ContextState = React5__namespace.createContext(null);
28
28
  function StateProvider({ children }) {
29
- const [value] = React4__namespace.useState(() => ({
29
+ const [value] = React5__namespace.useState(() => ({
30
30
  listeners: /* @__PURE__ */ new Map(),
31
31
  values: /* @__PURE__ */ new Map(),
32
32
  mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
@@ -34,10 +34,10 @@ function StateProvider({ children }) {
34
34
  mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
35
35
  mapViewabilityAmountValues: /* @__PURE__ */ new Map()
36
36
  }));
37
- return /* @__PURE__ */ React4__namespace.createElement(ContextState.Provider, { value }, children);
37
+ return /* @__PURE__ */ React5__namespace.createElement(ContextState.Provider, { value }, children);
38
38
  }
39
39
  function useStateContext() {
40
- return React4__namespace.useContext(ContextState);
40
+ return React5__namespace.useContext(ContextState);
41
41
  }
42
42
  function createSelectorFunctions(ctx, signalName) {
43
43
  return {
@@ -46,9 +46,9 @@ function createSelectorFunctions(ctx, signalName) {
46
46
  };
47
47
  }
48
48
  function use$(signalName) {
49
- const ctx = React4__namespace.useContext(ContextState);
50
- const { subscribe, get } = React4__namespace.useMemo(() => createSelectorFunctions(ctx, signalName), []);
51
- const value = React4.useSyncExternalStore(subscribe, get);
49
+ const ctx = React5__namespace.useContext(ContextState);
50
+ const { subscribe, get } = React5__namespace.useMemo(() => createSelectorFunctions(ctx, signalName), []);
51
+ const value = React5.useSyncExternalStore(subscribe, get);
52
52
  return value;
53
53
  }
54
54
  function listen$(ctx, signalName, cb) {
@@ -77,75 +77,207 @@ function set$(ctx, signalName, value) {
77
77
  }
78
78
  }
79
79
  }
80
+ var symbolFirst = Symbol();
81
+ function useInit(cb) {
82
+ const refValue = React5.useRef(symbolFirst);
83
+ if (refValue.current === symbolFirst) {
84
+ refValue.current = cb();
85
+ }
86
+ return refValue.current;
87
+ }
88
+
89
+ // src/ContextContainer.ts
90
+ var ContextContainer = React5.createContext(null);
91
+ function useViewability(configId, callback) {
92
+ const ctx = useStateContext();
93
+ const { containerId } = React5.useContext(ContextContainer);
94
+ const key = containerId + configId;
95
+ useInit(() => {
96
+ const value = ctx.mapViewabilityValues.get(key);
97
+ if (value) {
98
+ callback(value);
99
+ }
100
+ });
101
+ ctx.mapViewabilityCallbacks.set(key, callback);
102
+ React5.useEffect(
103
+ () => () => {
104
+ ctx.mapViewabilityCallbacks.delete(key);
105
+ },
106
+ []
107
+ );
108
+ }
109
+ function useViewabilityAmount(callback) {
110
+ const ctx = useStateContext();
111
+ const { containerId } = React5.useContext(ContextContainer);
112
+ useInit(() => {
113
+ const value = ctx.mapViewabilityAmountValues.get(containerId);
114
+ if (value) {
115
+ callback(value);
116
+ }
117
+ });
118
+ ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
119
+ React5.useEffect(
120
+ () => () => {
121
+ ctx.mapViewabilityAmountCallbacks.delete(containerId);
122
+ },
123
+ []
124
+ );
125
+ }
126
+ function useRecyclingEffect(effect) {
127
+ const { index, value } = React5.useContext(ContextContainer);
128
+ const prevValues = React5.useRef({
129
+ prevIndex: void 0,
130
+ prevItem: void 0
131
+ });
132
+ React5.useEffect(() => {
133
+ let ret = void 0;
134
+ if (prevValues.current.prevIndex !== void 0 && prevValues.current.prevItem !== void 0) {
135
+ ret = effect({
136
+ index,
137
+ item: value,
138
+ prevIndex: prevValues.current.prevIndex,
139
+ prevItem: prevValues.current.prevItem
140
+ });
141
+ }
142
+ prevValues.current = {
143
+ prevIndex: index,
144
+ prevItem: value
145
+ };
146
+ return ret;
147
+ }, [index, value]);
148
+ }
149
+ function useRecyclingState(valueOrFun) {
150
+ const { index, value } = React5.useContext(ContextContainer);
151
+ const stateInfo = React5.useState(
152
+ () => typeof valueOrFun === "function" ? valueOrFun({
153
+ index,
154
+ item: value,
155
+ prevIndex: void 0,
156
+ prevItem: void 0
157
+ }) : valueOrFun
158
+ );
159
+ useRecyclingEffect((state) => {
160
+ const newState = typeof valueOrFun === "function" ? valueOrFun(state) : valueOrFun;
161
+ stateInfo[1](newState);
162
+ });
163
+ return stateInfo;
164
+ }
165
+ var LeanView = React5__namespace.forwardRef((props, ref) => {
166
+ return React5__namespace.createElement("RCTView", { ...props, ref });
167
+ });
168
+ LeanView.displayName = "RCTView";
169
+
170
+ // src/constants.ts
171
+ var POSITION_OUT_OF_VIEW = -1e7;
172
+ var ANCHORED_POSITION_OUT_OF_VIEW = {
173
+ type: "top",
174
+ relativeCoordinate: POSITION_OUT_OF_VIEW,
175
+ top: POSITION_OUT_OF_VIEW
176
+ };
80
177
 
81
178
  // src/Container.tsx
179
+ var isNewArchitecture = global.nativeFabricUIManager != null;
82
180
  var Container = ({
83
181
  id,
84
182
  recycleItems,
85
183
  horizontal,
86
- waitForInitialLayout,
87
184
  getRenderedItem,
88
185
  updateItemSize,
89
186
  ItemSeparatorComponent
90
187
  }) => {
91
- const ctx = useStateContext();
92
- const position = use$(`containerPosition${id}`);
188
+ useStateContext();
189
+ const maintainVisibleContentPosition = use$("maintainVisibleContentPosition");
190
+ const position = use$(`containerPosition${id}`) || ANCHORED_POSITION_OUT_OF_VIEW;
93
191
  const column = use$(`containerColumn${id}`) || 0;
94
192
  const numColumns = use$("numColumns");
95
193
  const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
96
194
  const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
97
195
  const style = horizontal ? {
98
- flexDirection: "row",
196
+ flexDirection: ItemSeparatorComponent ? "row" : void 0,
99
197
  position: "absolute",
100
198
  top: otherAxisPos,
101
199
  bottom: numColumns > 1 ? null : 0,
102
200
  height: otherAxisSize,
103
- left: position
201
+ left: position.relativeCoordinate
104
202
  } : {
105
203
  position: "absolute",
106
204
  left: otherAxisPos,
107
205
  right: numColumns > 1 ? null : 0,
108
206
  width: otherAxisSize,
109
- top: position
207
+ top: position.relativeCoordinate
110
208
  };
111
- if (waitForInitialLayout) {
112
- const visible = use$(`containerDidLayout${id}`);
113
- style.opacity = visible ? 1 : 0;
114
- }
115
209
  const lastItemKey = use$("lastItemKey");
116
210
  const itemKey = use$(`containerItemKey${id}`);
117
211
  const data = use$(`containerItemData${id}`);
118
- const renderedItem = React4.useMemo(() => itemKey !== void 0 && getRenderedItem(itemKey, id), [itemKey, data]);
119
- return /* @__PURE__ */ React4__namespace.default.createElement(
120
- reactNative.View,
121
- {
122
- style,
123
- onLayout: (event) => {
124
- const key = peek$(ctx, `containerItemKey${id}`);
125
- if (key !== void 0) {
126
- const size = Math.floor(event.nativeEvent.layout[horizontal ? "width" : "height"] * 8) / 8;
127
- updateItemSize(id, key, size);
212
+ const extraData = use$("extraData");
213
+ const renderedItemInfo = React5.useMemo(
214
+ () => itemKey !== void 0 && getRenderedItem(itemKey),
215
+ [itemKey, data, extraData]
216
+ );
217
+ const { index, renderedItem } = renderedItemInfo || {};
218
+ const onLayout = (event) => {
219
+ if (itemKey !== void 0) {
220
+ const size = Math.floor(event.nativeEvent.layout[horizontal ? "width" : "height"] * 8) / 8;
221
+ if (size === 0) {
222
+ console.log("[WARN] Container 0 height reported, possible bug in LegendList", id, itemKey);
223
+ return;
224
+ }
225
+ updateItemSize(id, itemKey, size);
226
+ }
227
+ };
228
+ const ref = React5.useRef(null);
229
+ if (isNewArchitecture) {
230
+ React5.useLayoutEffect(() => {
231
+ var _a, _b;
232
+ if (itemKey !== void 0) {
233
+ const measured = (_b = (_a = ref.current) == null ? void 0 : _a.unstable_getBoundingClientRect) == null ? void 0 : _b.call(_a);
234
+ if (measured) {
235
+ const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
236
+ if (size) {
237
+ updateItemSize(id, itemKey, size);
238
+ }
128
239
  }
129
240
  }
130
- },
131
- /* @__PURE__ */ React4__namespace.default.createElement(React4__namespace.default.Fragment, { key: recycleItems ? void 0 : itemKey }, renderedItem, renderedItem && ItemSeparatorComponent && itemKey !== lastItemKey && ItemSeparatorComponent)
241
+ }, [itemKey]);
242
+ }
243
+ const contextValue = React5.useMemo(
244
+ () => ({ containerId: id, itemKey, index, value: data }),
245
+ [id, itemKey, index, data]
132
246
  );
247
+ const contentFragment = /* @__PURE__ */ React5__namespace.default.createElement(React5__namespace.default.Fragment, { key: recycleItems ? void 0 : itemKey }, /* @__PURE__ */ React5__namespace.default.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItem && ItemSeparatorComponent && itemKey !== lastItemKey && ItemSeparatorComponent));
248
+ if (maintainVisibleContentPosition) {
249
+ const anchorStyle = position.type === "top" ? { position: "absolute", top: 0, left: 0, right: 0 } : { position: "absolute", bottom: 0, left: 0, right: 0 };
250
+ return /* @__PURE__ */ React5__namespace.default.createElement(LeanView, { style }, /* @__PURE__ */ React5__namespace.default.createElement(LeanView, { style: anchorStyle, onLayout, ref }, contentFragment));
251
+ }
252
+ return /* @__PURE__ */ React5__namespace.default.createElement(LeanView, { style, onLayout, ref }, contentFragment);
133
253
  };
134
254
  var useAnimatedValue = reactNative.useAnimatedValue || ((initialValue) => {
135
- return React4.useRef(new reactNative.Animated.Value(initialValue)).current;
255
+ return React5.useRef(new reactNative.Animated.Value(initialValue)).current;
136
256
  });
137
- function useValue$(key, getValue, key2) {
257
+ function useValue$(key, getValue, useMicrotask) {
138
258
  var _a;
139
259
  const ctx = useStateContext();
140
- const animValue = useAnimatedValue((_a = peek$(ctx, key)) != null ? _a : 0);
141
- React4.useMemo(() => {
142
- listen$(ctx, key, (v) => animValue.setValue(v));
260
+ const animValue = useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
261
+ React5.useMemo(() => {
262
+ let newValue = void 0;
263
+ listen$(ctx, key, (v) => {
264
+ if (useMicrotask && newValue === void 0) {
265
+ queueMicrotask(() => {
266
+ animValue.setValue(newValue);
267
+ newValue = void 0;
268
+ });
269
+ }
270
+ newValue = getValue ? getValue(v) : v;
271
+ if (!useMicrotask) {
272
+ animValue.setValue(newValue);
273
+ }
274
+ });
143
275
  }, []);
144
276
  return animValue;
145
277
  }
146
278
 
147
279
  // src/Containers.tsx
148
- var Containers = React4__namespace.memo(function Containers2({
280
+ var Containers = React5__namespace.memo(function Containers2({
149
281
  horizontal,
150
282
  recycleItems,
151
283
  ItemSeparatorComponent,
@@ -154,18 +286,23 @@ var Containers = React4__namespace.memo(function Containers2({
154
286
  getRenderedItem
155
287
  }) {
156
288
  const numContainers = use$("numContainersPooled");
157
- const animSize = useValue$("totalSize");
289
+ const animSize = useValue$(
290
+ "totalSize",
291
+ void 0,
292
+ /*useMicrotask*/
293
+ true
294
+ );
295
+ const animOpacity = waitForInitialLayout ? useValue$("containersDidLayout", (value) => value ? 1 : 0) : void 0;
158
296
  const containers = [];
159
297
  for (let i = 0; i < numContainers; i++) {
160
298
  containers.push(
161
- /* @__PURE__ */ React4__namespace.createElement(
299
+ /* @__PURE__ */ React5__namespace.createElement(
162
300
  Container,
163
301
  {
164
302
  id: i,
165
303
  key: i,
166
304
  recycleItems,
167
305
  horizontal,
168
- waitForInitialLayout,
169
306
  getRenderedItem,
170
307
  updateItemSize,
171
308
  ItemSeparatorComponent
@@ -173,21 +310,21 @@ var Containers = React4__namespace.memo(function Containers2({
173
310
  )
174
311
  );
175
312
  }
176
- const style = horizontal ? { width: animSize } : { height: animSize };
177
- return /* @__PURE__ */ React4__namespace.createElement(reactNative.Animated.View, { style }, containers);
313
+ const style = horizontal ? { width: animSize, opacity: animOpacity } : { height: animSize, opacity: animOpacity };
314
+ return /* @__PURE__ */ React5__namespace.createElement(reactNative.Animated.View, { style }, containers);
178
315
  });
179
316
 
180
317
  // src/ListComponent.tsx
181
318
  var getComponent = (Component) => {
182
- if (React4__namespace.isValidElement(Component)) {
319
+ if (React5__namespace.isValidElement(Component)) {
183
320
  return Component;
184
321
  }
185
322
  if (Component) {
186
- return /* @__PURE__ */ React4__namespace.createElement(Component, null);
323
+ return /* @__PURE__ */ React5__namespace.createElement(Component, null);
187
324
  }
188
325
  return null;
189
326
  };
190
- var ListComponent = React4__namespace.memo(function ListComponent2({
327
+ var ListComponent = React5__namespace.memo(function ListComponent2({
191
328
  style,
192
329
  contentContainerStyle,
193
330
  horizontal,
@@ -203,7 +340,6 @@ var ListComponent = React4__namespace.memo(function ListComponent2({
203
340
  ListFooterComponent,
204
341
  ListFooterComponentStyle,
205
342
  ListEmptyComponent,
206
- ListEmptyComponentStyle,
207
343
  getRenderedItem,
208
344
  updateItemSize,
209
345
  refScrollView,
@@ -214,17 +350,17 @@ var ListComponent = React4__namespace.memo(function ListComponent2({
214
350
  const ctx = useStateContext();
215
351
  const animPaddingTop = useValue$("paddingTop");
216
352
  const animScrollAdjust = useValue$("scrollAdjust");
217
- const ScrollComponent = renderScrollComponent ? React4.useMemo(
218
- () => React4__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
353
+ const ScrollComponent = renderScrollComponent ? React5.useMemo(
354
+ () => React5__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
219
355
  [renderScrollComponent]
220
356
  ) : reactNative.ScrollView;
221
357
  const additionalSize = { marginTop: animScrollAdjust, paddingTop: animPaddingTop };
222
- return /* @__PURE__ */ React4__namespace.createElement(
358
+ return /* @__PURE__ */ React5__namespace.createElement(
223
359
  ScrollComponent,
224
360
  {
225
361
  ...rest,
226
362
  style,
227
- maintainVisibleContentPosition: maintainVisibleContentPosition ? { minIndexForVisible: 0 } : void 0,
363
+ maintainVisibleContentPosition: maintainVisibleContentPosition && !ListEmptyComponent ? { minIndexForVisible: 0 } : void 0,
228
364
  contentContainerStyle: [
229
365
  contentContainerStyle,
230
366
  horizontal ? {
@@ -237,8 +373,8 @@ var ListComponent = React4__namespace.memo(function ListComponent2({
237
373
  contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
238
374
  ref: refScrollView
239
375
  },
240
- /* @__PURE__ */ React4__namespace.createElement(reactNative.Animated.View, { style: additionalSize }),
241
- ListHeaderComponent && /* @__PURE__ */ React4__namespace.createElement(
376
+ /* @__PURE__ */ React5__namespace.createElement(reactNative.Animated.View, { style: additionalSize }),
377
+ ListHeaderComponent && /* @__PURE__ */ React5__namespace.createElement(
242
378
  reactNative.Animated.View,
243
379
  {
244
380
  style: ListHeaderComponentStyle,
@@ -252,8 +388,8 @@ var ListComponent = React4__namespace.memo(function ListComponent2({
252
388
  },
253
389
  getComponent(ListHeaderComponent)
254
390
  ),
255
- ListEmptyComponent && /* @__PURE__ */ React4__namespace.createElement(reactNative.Animated.View, { style: ListEmptyComponentStyle }, getComponent(ListEmptyComponent)),
256
- /* @__PURE__ */ React4__namespace.createElement(
391
+ ListEmptyComponent && getComponent(ListEmptyComponent),
392
+ /* @__PURE__ */ React5__namespace.createElement(
257
393
  Containers,
258
394
  {
259
395
  horizontal,
@@ -264,7 +400,7 @@ var ListComponent = React4__namespace.memo(function ListComponent2({
264
400
  updateItemSize
265
401
  }
266
402
  ),
267
- ListFooterComponent && /* @__PURE__ */ React4__namespace.createElement(reactNative.View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
403
+ ListFooterComponent && /* @__PURE__ */ React5__namespace.createElement(reactNative.View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
268
404
  );
269
405
  });
270
406
 
@@ -304,14 +440,6 @@ var ScrollAdjustHandler = class {
304
440
  return this.appliedAdjust;
305
441
  }
306
442
  };
307
- var symbolFirst = Symbol();
308
- function useInit(cb) {
309
- const refValue = React4.useRef(symbolFirst);
310
- if (refValue.current === symbolFirst) {
311
- refValue.current = cb();
312
- }
313
- return refValue.current;
314
- }
315
443
 
316
444
  // src/viewability.ts
317
445
  var mapViewabilityConfigCallbackPairs = /* @__PURE__ */ new Map();
@@ -462,13 +590,12 @@ function maybeUpdateViewabilityCallback(ctx, configId, viewToken) {
462
590
 
463
591
  // src/LegendList.tsx
464
592
  var DEFAULT_DRAW_DISTANCE = 250;
465
- var POSITION_OUT_OF_VIEW = -1e7;
466
593
  var DEFAULT_ITEM_SIZE = 100;
467
- var LegendList = React4.forwardRef(function LegendList2(props, forwardedRef) {
468
- return /* @__PURE__ */ React4__namespace.createElement(StateProvider, null, /* @__PURE__ */ React4__namespace.createElement(LegendListInner, { ...props, ref: forwardedRef }));
594
+ var LegendList = React5.forwardRef(function LegendList2(props, forwardedRef) {
595
+ return /* @__PURE__ */ React5__namespace.createElement(StateProvider, null, /* @__PURE__ */ React5__namespace.createElement(LegendListInner, { ...props, ref: forwardedRef }));
469
596
  });
470
- var LegendListInner = React4.forwardRef(function LegendListInner2(props, forwardedRef) {
471
- var _a, _b, _c, _d;
597
+ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forwardedRef) {
598
+ var _a, _b, _c, _d, _e, _f, _g;
472
599
  const {
473
600
  data,
474
601
  initialScrollIndex,
@@ -488,20 +615,27 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
488
615
  renderItem,
489
616
  estimatedItemSize,
490
617
  getEstimatedItemSize,
491
- onEndReached,
492
- onStartReached,
493
618
  ListEmptyComponent,
494
619
  onItemSizeChanged,
495
620
  scrollEventThrottle,
496
621
  refScrollView,
622
+ waitForInitialLayout = true,
623
+ extraData,
624
+ onLayout: onLayoutProp,
497
625
  ...rest
498
626
  } = props;
499
627
  const { style, contentContainerStyle } = props;
628
+ const callbacks = React5.useRef({
629
+ onStartReached: rest.onStartReached,
630
+ onEndReached: rest.onEndReached
631
+ });
632
+ callbacks.current.onStartReached = rest.onStartReached;
633
+ callbacks.current.onEndReached = rest.onEndReached;
500
634
  const ctx = useStateContext();
501
- const refScroller = React4.useRef(null);
635
+ const refScroller = React5.useRef(null);
502
636
  const scrollBuffer = drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE;
503
637
  const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (item, index) => index.toString();
504
- const refState = React4.useRef();
638
+ const refState = React5.useRef();
505
639
  const getId = (index) => {
506
640
  var _a2;
507
641
  const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
@@ -535,7 +669,7 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
535
669
  }
536
670
  return 0;
537
671
  };
538
- const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : React4.useMemo(calculateInitialOffset, []);
672
+ const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : React5.useMemo(calculateInitialOffset, []);
539
673
  if (!refState.current) {
540
674
  const initialScrollLength = reactNative.Dimensions.get("window")[horizontal ? "width" : "height"];
541
675
  refState.current = {
@@ -543,7 +677,7 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
543
677
  positions: /* @__PURE__ */ new Map(),
544
678
  columns: /* @__PURE__ */ new Map(),
545
679
  pendingAdjust: 0,
546
- animFrameLayout: null,
680
+ waitingForMicrotask: false,
547
681
  isStartReached: initialContentOffset < initialScrollLength * onStartReachedThreshold,
548
682
  isEndReached: false,
549
683
  isAtBottom: false,
@@ -576,8 +710,9 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
576
710
  belowAnchorElementPositions: void 0,
577
711
  rowHeights: /* @__PURE__ */ new Map(),
578
712
  startReachedBlockedByTimer: false,
579
- layoutsPending: /* @__PURE__ */ new Set(),
580
- scrollForNextCalculateItemsInView: void 0
713
+ scrollForNextCalculateItemsInView: void 0,
714
+ enableScrollForNextCalculateItemsInView: true,
715
+ minIndexSizeChanged: 0
581
716
  };
582
717
  refState.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
583
718
  if (maintainVisibleContentPosition) {
@@ -596,6 +731,8 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
596
731
  }
597
732
  }
598
733
  set$(ctx, "scrollAdjust", 0);
734
+ set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
735
+ set$(ctx, "extraData", extraData);
599
736
  }
600
737
  const getAnchorElementIndex = () => {
601
738
  const state = refState.current;
@@ -605,16 +742,16 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
605
742
  }
606
743
  return void 0;
607
744
  };
608
- const addTotalSize = React4.useCallback((key, add, totalSizeBelowAnchor) => {
745
+ const addTotalSize = React5.useCallback((key, add, totalSizeBelowAnchor) => {
609
746
  const state = refState.current;
610
- const index = key === null ? 0 : state.indexByKey.get(key);
747
+ const { scrollLength, indexByKey, anchorElement } = state;
748
+ const index = key === null ? 0 : indexByKey.get(key);
611
749
  let isAboveAnchor = false;
612
750
  if (maintainVisibleContentPosition) {
613
- if (state.anchorElement && index < getAnchorElementIndex()) {
751
+ if (anchorElement && index < getAnchorElementIndex()) {
614
752
  isAboveAnchor = true;
615
753
  }
616
754
  }
617
- state.totalSize;
618
755
  if (key === null) {
619
756
  state.totalSize = add;
620
757
  state.totalSizeBelowAnchor = totalSizeBelowAnchor;
@@ -625,19 +762,19 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
625
762
  }
626
763
  }
627
764
  let applyAdjustValue = void 0;
628
- if (maintainVisibleContentPosition) {
629
- const newAdjust = state.anchorElement.coordinate - state.totalSizeBelowAnchor;
765
+ const totalSize = state.totalSize;
766
+ let resultSize = totalSize;
767
+ if (maintainVisibleContentPosition && totalSize > scrollLength) {
768
+ const newAdjust = anchorElement.coordinate - state.totalSizeBelowAnchor;
630
769
  applyAdjustValue = -newAdjust;
631
770
  state.belowAnchorElementPositions = buildElementPositionsBelowAnchor();
632
771
  state.rowHeights.clear();
633
- }
634
- const totalSize = state.totalSize;
635
- let resultSize = totalSize;
636
- if (applyAdjustValue !== void 0) {
637
- resultSize -= applyAdjustValue;
638
- refState.current.scrollAdjustHandler.requestAdjust(applyAdjustValue, (diff) => {
639
- state.scroll -= diff;
640
- });
772
+ if (applyAdjustValue !== void 0) {
773
+ resultSize -= applyAdjustValue;
774
+ refState.current.scrollAdjustHandler.requestAdjust(applyAdjustValue, (diff) => {
775
+ state.scroll -= diff;
776
+ });
777
+ }
641
778
  }
642
779
  set$(ctx, "totalSize", resultSize);
643
780
  if (alignItemsAtEnd) {
@@ -655,7 +792,7 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
655
792
  }
656
793
  let rowHeight = 0;
657
794
  const startEl = n * numColumnsProp;
658
- for (let i = startEl; i < startEl + numColumnsProp; i++) {
795
+ for (let i = startEl; i < startEl + numColumnsProp && i < data.length; i++) {
659
796
  const id = getId(i);
660
797
  const size = getItemSize(id, i, data[i]);
661
798
  rowHeight = Math.max(rowHeight, size);
@@ -695,8 +832,7 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
695
832
  }
696
833
  return res;
697
834
  };
698
- const calculateItemsInView = React4.useCallback((speed) => {
699
- var _a2, _b2, _c2, _d2;
835
+ const calculateItemsInView = React5.useCallback((speed) => {
700
836
  const state = refState.current;
701
837
  const {
702
838
  data: data2,
@@ -705,12 +841,10 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
705
841
  startBufferedId: startBufferedIdOrig,
706
842
  positions,
707
843
  columns,
708
- scrollAdjustHandler,
709
- layoutsPending
844
+ scrollAdjustHandler
710
845
  } = state;
711
- if (state.animFrameLayout) {
712
- cancelAnimationFrame(state.animFrameLayout);
713
- state.animFrameLayout = null;
846
+ if (state.waitingForMicrotask) {
847
+ state.waitingForMicrotask = false;
714
848
  }
715
849
  if (!data2) {
716
850
  return;
@@ -718,9 +852,19 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
718
852
  const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
719
853
  const previousScrollAdjust = scrollAdjustHandler.getAppliedAdjust();
720
854
  const scrollExtra = Math.max(-16, Math.min(16, speed)) * 16;
721
- const scroll = scrollState - previousScrollAdjust - topPad - scrollExtra;
722
- if (refState.current.scrollForNextCalculateItemsInView) {
723
- const { top: top2, bottom } = refState.current.scrollForNextCalculateItemsInView;
855
+ const scroll = scrollState - previousScrollAdjust - topPad;
856
+ let scrollBufferTop = scrollBuffer;
857
+ let scrollBufferBottom = scrollBuffer;
858
+ if (scrollExtra > 8) {
859
+ scrollBufferTop = 0;
860
+ scrollBufferBottom = scrollBuffer + scrollExtra;
861
+ }
862
+ if (scrollExtra < -8) {
863
+ scrollBufferTop = scrollBuffer - scrollExtra;
864
+ scrollBufferBottom = 0;
865
+ }
866
+ if (state.scrollForNextCalculateItemsInView) {
867
+ const { top: top2, bottom } = state.scrollForNextCalculateItemsInView;
724
868
  if (scroll > top2 && scroll < bottom) {
725
869
  return;
726
870
  }
@@ -731,8 +875,11 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
731
875
  let startBufferedId = null;
732
876
  let endNoBuffer = null;
733
877
  let endBuffered = null;
734
- const originalStartId = startBufferedIdOrig && state.indexByKey.get(startBufferedIdOrig);
735
- let loopStart = originalStartId || 0;
878
+ let loopStart = startBufferedIdOrig ? state.indexByKey.get(startBufferedIdOrig) || 0 : 0;
879
+ if (state.minIndexSizeChanged !== void 0) {
880
+ loopStart = Math.min(state.minIndexSizeChanged, loopStart);
881
+ state.minIndexSizeChanged = void 0;
882
+ }
736
883
  const anchorElementIndex = getAnchorElementIndex();
737
884
  for (let i = loopStart; i >= 0; i--) {
738
885
  const id = getId(i);
@@ -763,13 +910,13 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
763
910
  let column = 1;
764
911
  let maxSizeInRow = 0;
765
912
  const getInitialTop = (i) => {
766
- var _a3;
913
+ var _a2;
767
914
  const id = getId(i);
768
915
  let topOffset = 0;
769
916
  if (positions.get(id)) {
770
917
  topOffset = positions.get(id);
771
918
  }
772
- if (id === ((_a3 = state.anchorElement) == null ? void 0 : _a3.id)) {
919
+ if (id === ((_a2 = state.anchorElement) == null ? void 0 : _a2.id)) {
773
920
  topOffset = initialContentOffset || 0;
774
921
  }
775
922
  return topOffset;
@@ -790,7 +937,7 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
790
937
  if (startNoBuffer === null && top + size > scroll) {
791
938
  startNoBuffer = i;
792
939
  }
793
- if (startBuffered === null && top + size > scroll - scrollBuffer) {
940
+ if (startBuffered === null && top + size > scroll - scrollBufferTop) {
794
941
  startBuffered = i;
795
942
  startBufferedId = id;
796
943
  }
@@ -798,7 +945,7 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
798
945
  if (top <= scrollBottom) {
799
946
  endNoBuffer = i;
800
947
  }
801
- if (top <= scrollBottom + scrollBuffer) {
948
+ if (top <= scrollBottom + scrollBufferBottom) {
802
949
  endBuffered = i;
803
950
  } else {
804
951
  break;
@@ -811,21 +958,23 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
811
958
  maxSizeInRow = 0;
812
959
  }
813
960
  }
814
- Object.assign(refState.current, {
961
+ Object.assign(state, {
815
962
  startBuffered,
816
963
  startBufferedId,
817
964
  startNoBuffer,
818
965
  endBuffered,
819
966
  endNoBuffer
820
967
  });
821
- const nextTop = Math.ceil(startBuffered ? positions.get(startBufferedId) + scrollBuffer : 0);
968
+ const nextTop = Math.ceil(startBuffered !== null ? positions.get(startBufferedId) + scrollBuffer : 0);
822
969
  const nextBottom = Math.floor(
823
- endBuffered ? (positions.get(getId(endBuffered + 1)) || 0) - scrollLength - scrollBuffer : 0
970
+ endBuffered !== null ? (positions.get(getId(endBuffered + 1)) || 0) - scrollLength - scrollBuffer : 0
824
971
  );
825
- refState.current.scrollForNextCalculateItemsInView = nextTop >= 0 && nextBottom >= 0 ? {
826
- top: nextTop,
827
- bottom: nextBottom
828
- } : void 0;
972
+ if (state.enableScrollForNextCalculateItemsInView) {
973
+ state.scrollForNextCalculateItemsInView = nextTop >= 0 && nextBottom >= 0 ? {
974
+ top: nextTop,
975
+ bottom: nextBottom
976
+ } : void 0;
977
+ }
829
978
  if (startBuffered !== null && endBuffered !== null) {
830
979
  const prevNumContainers = ctx.values.get("numContainers");
831
980
  let numContainers = prevNumContainers;
@@ -849,8 +998,8 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
849
998
  furthestIndex = u;
850
999
  break;
851
1000
  }
852
- const index = (_a2 = refState.current) == null ? void 0 : _a2.indexByKey.get(key);
853
- const pos = peek$(ctx, `containerPosition${u}`);
1001
+ const index = state.indexByKey.get(key);
1002
+ const pos = peek$(ctx, `containerPosition${u}`).top;
854
1003
  if (index < startBuffered || index > endBuffered) {
855
1004
  const distance = Math.abs(pos - top2);
856
1005
  if (index < 0 || distance > furthestDistance) {
@@ -861,15 +1010,15 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
861
1010
  }
862
1011
  if (furthestIndex >= 0) {
863
1012
  set$(ctx, `containerItemKey${furthestIndex}`, id);
864
- const index = (_b2 = refState.current) == null ? void 0 : _b2.indexByKey.get(id);
1013
+ const index = state.indexByKey.get(id);
865
1014
  set$(ctx, `containerItemData${furthestIndex}`, data2[index]);
866
1015
  } else {
867
1016
  const containerId = numContainers;
868
1017
  numContainers++;
869
1018
  set$(ctx, `containerItemKey${containerId}`, id);
870
- const index = (_c2 = refState.current) == null ? void 0 : _c2.indexByKey.get(id);
1019
+ const index = state.indexByKey.get(id);
871
1020
  set$(ctx, `containerItemData${containerId}`, data2[index]);
872
- set$(ctx, `containerPosition${containerId}`, POSITION_OUT_OF_VIEW);
1021
+ set$(ctx, `containerPosition${containerId}`, ANCHORED_POSITION_OUT_OF_VIEW);
873
1022
  set$(ctx, `containerColumn${containerId}`, -1);
874
1023
  if (__DEV__ && numContainers > peek$(ctx, "numContainersPooled")) {
875
1024
  console.warn(
@@ -888,24 +1037,36 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
888
1037
  }
889
1038
  for (let i = 0; i < numContainers; i++) {
890
1039
  const itemKey = peek$(ctx, `containerItemKey${i}`);
891
- const itemIndex = (_d2 = refState.current) == null ? void 0 : _d2.indexByKey.get(itemKey);
1040
+ const itemIndex = state.indexByKey.get(itemKey);
892
1041
  const item = data2[itemIndex];
893
1042
  if (item) {
894
1043
  const id = getId(itemIndex);
895
1044
  if (itemKey !== id || itemIndex < startBuffered || itemIndex > endBuffered) {
896
- const prevPos = peek$(ctx, `containerPosition${i}`);
1045
+ const prevPos = peek$(ctx, `containerPosition${i}`).top;
897
1046
  const pos = positions.get(id) || 0;
898
1047
  const size = getItemSize(id, itemIndex, data2[i]);
899
1048
  if (pos + size >= scroll && pos <= scrollBottom || prevPos + size >= scroll && prevPos <= scrollBottom) {
900
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1049
+ set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
901
1050
  }
902
1051
  } else {
903
- const pos = positions.get(id) || 0;
1052
+ const pos = {
1053
+ type: "top",
1054
+ relativeCoordinate: positions.get(id) || 0,
1055
+ top: positions.get(id) || 0
1056
+ };
904
1057
  const column2 = columns.get(id) || 1;
1058
+ if (maintainVisibleContentPosition && itemIndex < anchorElementIndex) {
1059
+ const currentRow = Math.floor(itemIndex / numColumnsProp);
1060
+ const rowHeight = getRowHeight(currentRow);
1061
+ const elementHeight = getItemSize(id, itemIndex, data2[i]);
1062
+ const diff = rowHeight - elementHeight;
1063
+ pos.relativeCoordinate = pos.top + getRowHeight(currentRow) - diff;
1064
+ pos.type = "bottom";
1065
+ }
905
1066
  const prevPos = peek$(ctx, `containerPosition${i}`);
906
1067
  const prevColumn = peek$(ctx, `containerColumn${i}`);
907
1068
  const prevData = peek$(ctx, `containerItemData${i}`);
908
- if (pos > POSITION_OUT_OF_VIEW && pos !== prevPos) {
1069
+ if (pos.relativeCoordinate > POSITION_OUT_OF_VIEW && pos.top !== prevPos.top) {
909
1070
  set$(ctx, `containerPosition${i}`, pos);
910
1071
  }
911
1072
  if (column2 >= 0 && column2 !== prevColumn) {
@@ -918,17 +1079,12 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
918
1079
  }
919
1080
  }
920
1081
  }
921
- if (layoutsPending.size > 0) {
922
- for (const containerId of layoutsPending) {
923
- set$(ctx, `containerDidLayout${containerId}`, true);
924
- }
925
- layoutsPending.clear();
926
- }
927
- if (refState.current.viewabilityConfigCallbackPairs) {
1082
+ set$(ctx, "containersDidLayout", true);
1083
+ if (state.viewabilityConfigCallbackPairs) {
928
1084
  updateViewableItems(
929
- refState.current,
1085
+ state,
930
1086
  ctx,
931
- refState.current.viewabilityConfigCallbackPairs,
1087
+ state.viewabilityConfigCallbackPairs,
932
1088
  getId,
933
1089
  scrollLength,
934
1090
  startNoBuffer,
@@ -967,6 +1123,7 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
967
1123
  if (refState.current) {
968
1124
  refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
969
1125
  }
1126
+ const { onEndReached } = callbacks.current;
970
1127
  if (onEndReached) {
971
1128
  if (!refState.current.isEndReached) {
972
1129
  if (distanceFromEnd < onEndReachedThreshold * scrollLength) {
@@ -988,6 +1145,7 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
988
1145
  const { scrollLength, scroll } = refState.current;
989
1146
  const distanceFromTop = scroll;
990
1147
  refState.current.isAtTop = distanceFromTop < 0;
1148
+ const { onStartReached } = callbacks.current;
991
1149
  if (onStartReached) {
992
1150
  if (!refState.current.isStartReached && !refState.current.startReachedBlockedByTimer) {
993
1151
  if (distanceFromTop < onStartReachedThreshold * scrollLength) {
@@ -1016,13 +1174,13 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
1016
1174
  const itemKey = peek$(ctx, `containerItemKey${i}`);
1017
1175
  if (!keyExtractorProp || itemKey && state.indexByKey.get(itemKey) === void 0) {
1018
1176
  set$(ctx, `containerItemKey${i}`, void 0);
1019
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1177
+ set$(ctx, `containerItemData${i}`, void 0);
1178
+ set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
1020
1179
  set$(ctx, `containerColumn${i}`, -1);
1021
1180
  }
1022
1181
  }
1023
1182
  if (!keyExtractorProp) {
1024
- state.sizes.clear();
1025
- state.positions;
1183
+ state.positions.clear();
1026
1184
  }
1027
1185
  calculateItemsInView(state.scrollVelocity);
1028
1186
  }
@@ -1037,20 +1195,63 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
1037
1195
  const isFirst = !refState.current.renderItem;
1038
1196
  if (isFirst || data !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
1039
1197
  if (!keyExtractorProp && !isFirst && data !== refState.current.data) {
1040
- refState.current.sizes.clear();
1041
1198
  refState.current.positions.clear();
1042
1199
  }
1043
1200
  refState.current.data = data;
1044
1201
  let totalSize = 0;
1045
1202
  let totalSizeBelowIndex = 0;
1046
1203
  const indexByKey = /* @__PURE__ */ new Map();
1204
+ const newPositions = /* @__PURE__ */ new Map();
1047
1205
  let column = 1;
1048
1206
  let maxSizeInRow = 0;
1049
1207
  for (let i = 0; i < data.length; i++) {
1050
1208
  const key = getId(i);
1209
+ if (__DEV__) {
1210
+ if (indexByKey.has(key)) {
1211
+ console.error(
1212
+ `[legend-list] Error: Detected overlapping key (${key}) which causes missing items and gaps and other terrrible things. Check that keyExtractor returns unique values.`
1213
+ );
1214
+ }
1215
+ }
1051
1216
  indexByKey.set(key, i);
1217
+ if (refState.current.positions.get(key) != null && refState.current.indexByKey.get(key) === i) {
1218
+ newPositions.set(key, refState.current.positions.get(key));
1219
+ }
1052
1220
  }
1053
1221
  refState.current.indexByKey = indexByKey;
1222
+ refState.current.positions = newPositions;
1223
+ if (!isFirst) {
1224
+ if (maintainVisibleContentPosition) {
1225
+ if (refState.current.anchorElement == null || indexByKey.get(refState.current.anchorElement.id) == null) {
1226
+ if (data.length) {
1227
+ const newAnchorElement = {
1228
+ coordinate: 0,
1229
+ id: getId(0)
1230
+ };
1231
+ refState.current.anchorElement = newAnchorElement;
1232
+ (_a = refState.current.belowAnchorElementPositions) == null ? void 0 : _a.clear();
1233
+ (_b = refScroller.current) == null ? void 0 : _b.scrollTo({ x: 0, y: 0, animated: false });
1234
+ setTimeout(() => {
1235
+ calculateItemsInView(0);
1236
+ }, 0);
1237
+ } else {
1238
+ refState.current.startBufferedId = void 0;
1239
+ }
1240
+ }
1241
+ } else {
1242
+ if (refState.current.startBufferedId != null && newPositions.get(refState.current.startBufferedId) == null) {
1243
+ if (data.length) {
1244
+ refState.current.startBufferedId = getId(0);
1245
+ } else {
1246
+ refState.current.startBufferedId = void 0;
1247
+ }
1248
+ (_c = refScroller.current) == null ? void 0 : _c.scrollTo({ x: 0, y: 0, animated: false });
1249
+ setTimeout(() => {
1250
+ calculateItemsInView(0);
1251
+ }, 0);
1252
+ }
1253
+ }
1254
+ }
1054
1255
  const anchorElementIndex = getAnchorElementIndex();
1055
1256
  for (let i = 0; i < data.length; i++) {
1056
1257
  const key = getId(i);
@@ -1066,17 +1267,23 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
1066
1267
  maxSizeInRow = 0;
1067
1268
  }
1068
1269
  }
1270
+ if (maxSizeInRow > 0) {
1271
+ totalSize += maxSizeInRow;
1272
+ }
1069
1273
  addTotalSize(null, totalSize, totalSizeBelowIndex);
1070
1274
  }
1071
- React4.useEffect(() => {
1275
+ React5.useEffect(() => {
1072
1276
  checkResetContainers(
1073
1277
  /*reset*/
1074
1278
  !isFirst
1075
1279
  );
1076
1280
  }, [isFirst, data, numColumnsProp]);
1281
+ React5.useEffect(() => {
1282
+ set$(ctx, "extraData", extraData);
1283
+ }, [extraData]);
1077
1284
  refState.current.renderItem = renderItem;
1078
- const lastItemKey = getId(data[data.length - 1]);
1079
- const stylePaddingTop = (_d = (_c = (_a = reactNative.StyleSheet.flatten(style)) == null ? void 0 : _a.paddingTop) != null ? _c : (_b = reactNative.StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _b.paddingTop) != null ? _d : 0;
1285
+ const lastItemKey = data.length > 0 ? getId(data.length - 1) : void 0;
1286
+ const stylePaddingTop = (_g = (_f = (_d = reactNative.StyleSheet.flatten(style)) == null ? void 0 : _d.paddingTop) != null ? _f : (_e = reactNative.StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _e.paddingTop) != null ? _g : 0;
1080
1287
  const initalizeStateVars = () => {
1081
1288
  set$(ctx, "lastItemKey", lastItemKey);
1082
1289
  set$(ctx, "numColumns", numColumnsProp);
@@ -1085,8 +1292,8 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
1085
1292
  if (isFirst) {
1086
1293
  initalizeStateVars();
1087
1294
  }
1088
- React4.useEffect(initalizeStateVars, [lastItemKey, numColumnsProp, stylePaddingTop]);
1089
- const getRenderedItem = React4.useCallback((key, containerId) => {
1295
+ React5.useEffect(initalizeStateVars, [lastItemKey, numColumnsProp, stylePaddingTop]);
1296
+ const getRenderedItem = React5.useCallback((key) => {
1090
1297
  var _a2, _b2;
1091
1298
  const state = refState.current;
1092
1299
  if (!state) {
@@ -1097,134 +1304,68 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
1097
1304
  if (index === void 0) {
1098
1305
  return null;
1099
1306
  }
1100
- const useViewability = (configId, callback) => {
1101
- const key2 = containerId + configId;
1102
- useInit(() => {
1103
- const value = ctx.mapViewabilityValues.get(key2);
1104
- if (value) {
1105
- callback(value);
1106
- }
1107
- });
1108
- ctx.mapViewabilityCallbacks.set(key2, callback);
1109
- React4.useEffect(
1110
- () => () => {
1111
- ctx.mapViewabilityCallbacks.delete(key2);
1112
- },
1113
- []
1114
- );
1307
+ const useViewability2 = (configId, callback) => {
1308
+ useViewability(configId, callback);
1115
1309
  };
1116
- const useViewabilityAmount = (callback) => {
1117
- useInit(() => {
1118
- const value = ctx.mapViewabilityAmountValues.get(containerId);
1119
- if (value) {
1120
- callback(value);
1121
- }
1122
- });
1123
- ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
1124
- React4.useEffect(
1125
- () => () => {
1126
- ctx.mapViewabilityAmountCallbacks.delete(containerId);
1127
- },
1128
- []
1129
- );
1310
+ const useViewabilityAmount2 = (callback) => {
1311
+ useViewabilityAmount(callback);
1130
1312
  };
1131
- const useRecyclingEffect = (effect) => {
1132
- React4.useEffect(() => {
1133
- const state2 = refState.current;
1134
- let prevIndex = index;
1135
- let prevItem = state2.data[index];
1136
- const signal = `containerItemKey${containerId}`;
1137
- const run = () => {
1138
- const data3 = state2.data;
1139
- if (data3) {
1140
- const newKey = peek$(ctx, signal);
1141
- const newIndex = state2.indexByKey.get(newKey);
1142
- const newItem = data3[newIndex];
1143
- if (newItem) {
1144
- effect({
1145
- index: newIndex,
1146
- item: newItem,
1147
- prevIndex,
1148
- prevItem
1149
- });
1150
- }
1151
- prevIndex = newIndex;
1152
- prevItem = newItem;
1153
- }
1154
- };
1155
- run();
1156
- return listen$(ctx, signal, run);
1157
- }, []);
1313
+ const useRecyclingEffect2 = (effect) => {
1314
+ useRecyclingEffect(effect);
1158
1315
  };
1159
- const useRecyclingState = (valueOrFun) => {
1160
- const stateInfo = React4.useState(
1161
- () => typeof valueOrFun === "function" ? valueOrFun({
1162
- index,
1163
- item: refState.current.data[index],
1164
- prevIndex: void 0,
1165
- prevItem: void 0
1166
- }) : valueOrFun
1167
- );
1168
- useRecyclingEffect((state2) => {
1169
- const newState = typeof valueOrFun === "function" ? valueOrFun(state2) : valueOrFun;
1170
- stateInfo[1](newState);
1171
- });
1172
- return stateInfo;
1316
+ const useRecyclingState2 = (valueOrFun) => {
1317
+ return useRecyclingState(valueOrFun);
1173
1318
  };
1174
1319
  const renderedItem = (_b2 = (_a2 = refState.current).renderItem) == null ? void 0 : _b2.call(_a2, {
1175
1320
  item: data2[index],
1176
1321
  index,
1177
- useViewability,
1178
- useViewabilityAmount,
1179
- useRecyclingEffect,
1180
- useRecyclingState
1322
+ useViewability: useViewability2,
1323
+ useViewabilityAmount: useViewabilityAmount2,
1324
+ useRecyclingEffect: useRecyclingEffect2,
1325
+ useRecyclingState: useRecyclingState2
1181
1326
  });
1182
- return renderedItem;
1327
+ return { index, renderedItem };
1183
1328
  }, []);
1184
1329
  useInit(() => {
1185
1330
  var _a2;
1186
- refState.current.viewabilityConfigCallbackPairs = setupViewability(props);
1187
- const scrollLength = refState.current.scrollLength;
1331
+ const state = refState.current;
1332
+ const viewability = setupViewability(props);
1333
+ state.viewabilityConfigCallbackPairs = viewability;
1334
+ state.enableScrollForNextCalculateItemsInView = !viewability;
1335
+ const scrollLength = state.scrollLength;
1188
1336
  const averageItemSize = (_a2 = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, data[0])) != null ? _a2 : DEFAULT_ITEM_SIZE;
1189
1337
  const numContainers = Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize) * numColumnsProp;
1190
1338
  for (let i = 0; i < numContainers; i++) {
1191
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1339
+ set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
1192
1340
  set$(ctx, `containerColumn${i}`, -1);
1193
1341
  }
1194
1342
  set$(ctx, "numContainers", numContainers);
1195
1343
  set$(ctx, "numContainersPooled", numContainers * 2);
1196
- calculateItemsInView(refState.current.scrollVelocity);
1344
+ calculateItemsInView(state.scrollVelocity);
1197
1345
  });
1198
- const updateItemSize = React4.useCallback((containerId, itemKey, size) => {
1199
- var _a2;
1200
- const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
1346
+ const updateItemSize = React5.useCallback((containerId, itemKey, size) => {
1347
+ const state = refState.current;
1348
+ const { sizes, indexByKey, columns, sizesLaidOut, data: data2 } = state;
1201
1349
  if (!data2) {
1202
1350
  return;
1203
1351
  }
1204
- const state = refState.current;
1205
- const { sizes, indexByKey, idsInFirstRender, columns, sizesLaidOut } = state;
1206
1352
  const index = indexByKey.get(itemKey);
1207
1353
  const numColumns = peek$(ctx, "numColumns");
1208
- const row = Math.floor(index / numColumns);
1209
- const prevSize = getRowHeight(row);
1210
- const measured = peek$(ctx, `containerDidLayout${containerId}`);
1211
- if (!measured) {
1212
- state.layoutsPending.add(containerId);
1213
- }
1354
+ state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, index) : index;
1355
+ const prevSize = getItemSize(itemKey, index, data2);
1214
1356
  if (!prevSize || Math.abs(prevSize - size) > 0.5) {
1215
1357
  let diff;
1216
1358
  if (numColumns > 1) {
1217
- const prevMaxSizeInRow = getRowHeight(row);
1218
1359
  sizes.set(itemKey, size);
1219
1360
  const column = columns.get(itemKey);
1220
1361
  const loopStart = index - (column - 1);
1221
1362
  let nextMaxSizeInRow = 0;
1222
- for (let i = loopStart; i < loopStart + numColumns; i++) {
1363
+ for (let i = loopStart; i < loopStart + numColumns && i < data2.length; i++) {
1223
1364
  const id = getId(i);
1224
1365
  const size2 = getItemSize(id, i, data2[i]);
1225
1366
  nextMaxSizeInRow = Math.max(nextMaxSizeInRow, size2);
1226
1367
  }
1227
- diff = nextMaxSizeInRow - prevMaxSizeInRow;
1368
+ diff = nextMaxSizeInRow - prevSize;
1228
1369
  } else {
1229
1370
  sizes.set(itemKey, size);
1230
1371
  diff = size - prevSize;
@@ -1252,11 +1393,14 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
1252
1393
  addTotalSize(itemKey, diff, 0);
1253
1394
  doMaintainScrollAtEnd(true);
1254
1395
  const scrollVelocity = state.scrollVelocity;
1255
- if (!state.animFrameLayout && (Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1)) {
1256
- if (!peek$(ctx, `containerDidLayout${containerId}`)) {
1257
- state.animFrameLayout = requestAnimationFrame(() => {
1258
- state.animFrameLayout = null;
1259
- calculateItemsInView(state.scrollVelocity);
1396
+ if (!state.waitingForMicrotask && (Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1)) {
1397
+ if (!peek$(ctx, "containersDidLayout")) {
1398
+ state.waitingForMicrotask = true;
1399
+ queueMicrotask(() => {
1400
+ if (state.waitingForMicrotask) {
1401
+ state.waitingForMicrotask = false;
1402
+ calculateItemsInView(state.scrollVelocity);
1403
+ }
1260
1404
  });
1261
1405
  } else {
1262
1406
  calculateItemsInView(state.scrollVelocity);
@@ -1265,22 +1409,24 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
1265
1409
  if (onItemSizeChanged) {
1266
1410
  onItemSizeChanged({ size, previous: prevSize, index, itemKey, itemData: data2[index] });
1267
1411
  }
1268
- } else {
1269
- set$(ctx, `containerDidLayout${containerId}`, true);
1270
1412
  }
1271
1413
  }, []);
1272
- const handleScrollDebounced = React4.useCallback((velocity) => {
1414
+ const handleScrollDebounced = React5.useCallback((velocity) => {
1273
1415
  calculateItemsInView(velocity);
1274
1416
  checkAtBottom();
1275
1417
  checkAtTop();
1276
1418
  }, []);
1277
- const onLayout = React4.useCallback((event) => {
1419
+ const onLayout = React5.useCallback((event) => {
1278
1420
  const scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
1421
+ const didChange = scrollLength !== refState.current.scrollLength;
1279
1422
  refState.current.scrollLength = scrollLength;
1280
1423
  doMaintainScrollAtEnd(false);
1281
1424
  doUpdatePaddingTop();
1282
1425
  checkAtBottom();
1283
1426
  checkAtTop();
1427
+ if (didChange) {
1428
+ calculateItemsInView(0);
1429
+ }
1284
1430
  if (__DEV__) {
1285
1431
  const isWidthZero = event.nativeEvent.layout.width === 0;
1286
1432
  const isHeightZero = event.nativeEvent.layout.height === 0;
@@ -1290,8 +1436,11 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
1290
1436
  );
1291
1437
  }
1292
1438
  }
1439
+ if (onLayoutProp) {
1440
+ onLayoutProp(event);
1441
+ }
1293
1442
  }, []);
1294
- const handleScroll = React4.useCallback(
1443
+ const handleScroll = React5.useCallback(
1295
1444
  (event, fromSelf) => {
1296
1445
  var _a2, _b2, _c2;
1297
1446
  if (((_b2 = (_a2 = event.nativeEvent) == null ? void 0 : _a2.contentSize) == null ? void 0 : _b2.height) === 0 && ((_c2 = event.nativeEvent.contentSize) == null ? void 0 : _c2.width) === 0) {
@@ -1333,7 +1482,7 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
1333
1482
  },
1334
1483
  []
1335
1484
  );
1336
- React4.useImperativeHandle(
1485
+ React5.useImperativeHandle(
1337
1486
  forwardedRef,
1338
1487
  () => {
1339
1488
  const scrollToIndex = ({ index, animated }) => {
@@ -1343,9 +1492,9 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
1343
1492
  };
1344
1493
  return {
1345
1494
  getNativeScrollRef: () => refScroller.current,
1346
- getScrollableNode: refScroller.current.getScrollableNode,
1347
- getScrollResponder: refScroller.current.getScrollResponder,
1348
- flashScrollIndicators: refScroller.current.flashScrollIndicators,
1495
+ getScrollableNode: () => refScroller.current.getScrollableNode(),
1496
+ getScrollResponder: () => refScroller.current.getScrollResponder(),
1497
+ flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
1349
1498
  scrollToIndex,
1350
1499
  scrollToOffset: ({ offset, animated }) => {
1351
1500
  const offsetObj = horizontal ? { x: offset, y: 0 } : { x: 0, y: offset };
@@ -1357,12 +1506,12 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
1357
1506
  scrollToIndex({ index, animated });
1358
1507
  }
1359
1508
  },
1360
- scrollToEnd: refScroller.current.scrollToEnd
1509
+ scrollToEnd: () => refScroller.current.scrollToEnd()
1361
1510
  };
1362
1511
  },
1363
1512
  []
1364
1513
  );
1365
- return /* @__PURE__ */ React4__namespace.createElement(
1514
+ return /* @__PURE__ */ React5__namespace.createElement(
1366
1515
  ListComponent,
1367
1516
  {
1368
1517
  ...rest,
@@ -1387,9 +1536,14 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
1387
1536
  ListEmptyComponent: data.length === 0 ? ListEmptyComponent : void 0,
1388
1537
  maintainVisibleContentPosition,
1389
1538
  scrollEventThrottle: scrollEventThrottle != null ? scrollEventThrottle : reactNative.Platform.OS === "web" ? 16 : void 0,
1539
+ waitForInitialLayout,
1390
1540
  style
1391
1541
  }
1392
1542
  );
1393
1543
  });
1394
1544
 
1395
1545
  exports.LegendList = LegendList;
1546
+ exports.useRecyclingEffect = useRecyclingEffect;
1547
+ exports.useRecyclingState = useRecyclingState;
1548
+ exports.useViewability = useViewability;
1549
+ exports.useViewabilityAmount = useViewabilityAmount;