@legendapp/list 2.0.0 → 2.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.mjs CHANGED
@@ -1,14 +1,27 @@
1
- import * as React3 from 'react';
2
- import React3__default, { useReducer, useEffect, createContext, useRef, useState, useMemo, useLayoutEffect, useCallback, useImperativeHandle, forwardRef, memo, useContext } from 'react';
3
- import { View, Text, Platform, Animated, StyleSheet, Dimensions, RefreshControl, unstable_batchedUpdates } from 'react-native';
1
+ import * as React4 from 'react';
2
+ import React4__default, { forwardRef, useReducer, useEffect, createContext, useRef, useState, useMemo, useImperativeHandle, useCallback, useLayoutEffect, memo, useContext } from 'react';
4
3
  import { useSyncExternalStore } from 'use-sync-external-store/shim';
4
+ import { unstable_batchedUpdates } from 'react-dom';
5
5
 
6
6
  // src/components/LegendList.tsx
7
- var ContextState = React3.createContext(null);
7
+ var AnimatedView = forwardRef(function AnimatedView2(props, ref) {
8
+ return /* @__PURE__ */ React4.createElement("div", { ref, ...props });
9
+ });
10
+ var View = forwardRef(function View2(props, ref) {
11
+ return /* @__PURE__ */ React4.createElement("div", { ref, ...props });
12
+ });
13
+ var Text = View;
14
+
15
+ // src/platform/Animated.tsx
16
+ var createAnimatedValue = (value) => value;
17
+
18
+ // src/state/state.tsx
19
+ var ContextState = React4.createContext(null);
8
20
  function StateProvider({ children }) {
9
- const [value] = React3.useState(() => ({
10
- animatedScrollY: new Animated.Value(0),
21
+ const [value] = React4.useState(() => ({
22
+ animatedScrollY: createAnimatedValue(0),
11
23
  columnWrapperStyle: void 0,
24
+ internalState: void 0,
12
25
  listeners: /* @__PURE__ */ new Map(),
13
26
  mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
14
27
  mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
@@ -24,10 +37,10 @@ function StateProvider({ children }) {
24
37
  ]),
25
38
  viewRefs: /* @__PURE__ */ new Map()
26
39
  }));
27
- return /* @__PURE__ */ React3.createElement(ContextState.Provider, { value }, children);
40
+ return /* @__PURE__ */ React4.createElement(ContextState.Provider, { value }, children);
28
41
  }
29
42
  function useStateContext() {
30
- return React3.useContext(ContextState);
43
+ return React4.useContext(ContextState);
31
44
  }
32
45
  function createSelectorFunctionsArr(ctx, signalNames) {
33
46
  let lastValues = [];
@@ -97,23 +110,23 @@ function getContentSize(ctx) {
97
110
  return headerSize + footerSize + totalSize + stylePaddingTop;
98
111
  }
99
112
  function useArr$(signalNames) {
100
- const ctx = React3.useContext(ContextState);
101
- const { subscribe, get } = React3.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
113
+ const ctx = React4.useContext(ContextState);
114
+ const { subscribe, get } = React4.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
102
115
  const value = useSyncExternalStore(subscribe, get);
103
116
  return value;
104
117
  }
105
118
  function useSelector$(signalName, selector) {
106
- const ctx = React3.useContext(ContextState);
107
- const { subscribe, get } = React3.useMemo(() => createSelectorFunctionsArr(ctx, [signalName]), [ctx, signalName]);
119
+ const ctx = React4.useContext(ContextState);
120
+ const { subscribe, get } = React4.useMemo(() => createSelectorFunctionsArr(ctx, [signalName]), [ctx, signalName]);
108
121
  const value = useSyncExternalStore(subscribe, () => selector(get()[0]));
109
122
  return value;
110
123
  }
111
124
 
112
125
  // src/components/DebugView.tsx
113
126
  var DebugRow = ({ children }) => {
114
- return /* @__PURE__ */ React3.createElement(View, { style: { alignItems: "center", flexDirection: "row", justifyContent: "space-between" } }, children);
127
+ return /* @__PURE__ */ React4.createElement(View, { style: { alignItems: "center", flexDirection: "row", justifyContent: "space-between" } }, children);
115
128
  };
116
- var DebugView = React3.memo(function DebugView2({ state }) {
129
+ var DebugView = React4.memo(function DebugView2({ state }) {
117
130
  const ctx = useStateContext();
118
131
  const [totalSize = 0, scrollAdjust = 0, rawScroll = 0, scroll = 0, _numContainers = 0, _numContainersPooled = 0] = useArr$([
119
132
  "totalSize",
@@ -128,7 +141,7 @@ var DebugView = React3.memo(function DebugView2({ state }) {
128
141
  useInterval(() => {
129
142
  forceUpdate();
130
143
  }, 100);
131
- return /* @__PURE__ */ React3.createElement(
144
+ return /* @__PURE__ */ React4.createElement(
132
145
  View,
133
146
  {
134
147
  pointerEvents: "none",
@@ -144,14 +157,12 @@ var DebugView = React3.memo(function DebugView2({ state }) {
144
157
  top: 0
145
158
  }
146
159
  },
147
- /* @__PURE__ */ React3.createElement(DebugRow, null, /* @__PURE__ */ React3.createElement(Text, null, "TotalSize:"), /* @__PURE__ */ React3.createElement(Text, null, totalSize.toFixed(2))),
148
- /* @__PURE__ */ React3.createElement(DebugRow, null, /* @__PURE__ */ React3.createElement(Text, null, "ContentSize:"), /* @__PURE__ */ React3.createElement(Text, null, contentSize.toFixed(2))),
149
- /* @__PURE__ */ React3.createElement(DebugRow, null, /* @__PURE__ */ React3.createElement(Text, null, "At end:"), /* @__PURE__ */ React3.createElement(Text, null, String(state.isAtEnd))),
150
- /* @__PURE__ */ React3.createElement(Text, null),
151
- /* @__PURE__ */ React3.createElement(DebugRow, null, /* @__PURE__ */ React3.createElement(Text, null, "ScrollAdjust:"), /* @__PURE__ */ React3.createElement(Text, null, scrollAdjust.toFixed(2))),
152
- /* @__PURE__ */ React3.createElement(Text, null),
153
- /* @__PURE__ */ React3.createElement(DebugRow, null, /* @__PURE__ */ React3.createElement(Text, null, "RawScroll: "), /* @__PURE__ */ React3.createElement(Text, null, rawScroll.toFixed(2))),
154
- /* @__PURE__ */ React3.createElement(DebugRow, null, /* @__PURE__ */ React3.createElement(Text, null, "ComputedScroll: "), /* @__PURE__ */ React3.createElement(Text, null, scroll.toFixed(2)))
160
+ /* @__PURE__ */ React4.createElement(DebugRow, null, /* @__PURE__ */ React4.createElement(Text, null, "TotalSize:"), /* @__PURE__ */ React4.createElement(Text, null, totalSize.toFixed(2))),
161
+ /* @__PURE__ */ React4.createElement(DebugRow, null, /* @__PURE__ */ React4.createElement(Text, null, "ContentSize:"), /* @__PURE__ */ React4.createElement(Text, null, contentSize.toFixed(2))),
162
+ /* @__PURE__ */ React4.createElement(DebugRow, null, /* @__PURE__ */ React4.createElement(Text, null, "At end:"), /* @__PURE__ */ React4.createElement(Text, null, String(state.isAtEnd))),
163
+ /* @__PURE__ */ React4.createElement(DebugRow, null, /* @__PURE__ */ React4.createElement(Text, null, "ScrollAdjust:"), /* @__PURE__ */ React4.createElement(Text, null, scrollAdjust.toFixed(2))),
164
+ /* @__PURE__ */ React4.createElement(DebugRow, null, /* @__PURE__ */ React4.createElement(Text, null, "RawScroll: "), /* @__PURE__ */ React4.createElement(Text, null, rawScroll.toFixed(2))),
165
+ /* @__PURE__ */ React4.createElement(DebugRow, null, /* @__PURE__ */ React4.createElement(Text, null, "ComputedScroll: "), /* @__PURE__ */ React4.createElement(Text, null, scroll.toFixed(2)))
155
166
  );
156
167
  });
157
168
  function useInterval(callback, delay) {
@@ -160,57 +171,90 @@ function useInterval(callback, delay) {
160
171
  return () => clearInterval(interval);
161
172
  }, [delay]);
162
173
  }
163
- var LeanViewComponent = React3.forwardRef((props, ref) => {
164
- return React3.createElement("RCTView", { ...props, ref });
165
- });
166
- LeanViewComponent.displayName = "RCTView";
167
- var LeanView = Platform.OS === "android" || Platform.OS === "ios" ? LeanViewComponent : View;
168
-
169
- // src/constants.ts
170
- var POSITION_OUT_OF_VIEW = -1e7;
171
- var ENABLE_DEVMODE = __DEV__ && false;
172
- var ENABLE_DEBUG_VIEW = __DEV__ && false;
173
- var IsNewArchitecture = global.nativeFabricUIManager != null;
174
- var useAnimatedValue = (initialValue) => {
175
- return useRef(new Animated.Value(initialValue)).current;
176
- };
177
-
178
- // src/hooks/useValue$.ts
179
- function useValue$(key, params) {
180
- var _a;
181
- const { getValue, delay } = params || {};
182
- const ctx = useStateContext();
183
- const animValue = useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
184
- useMemo(() => {
185
- let newValue;
186
- let prevValue;
187
- let didQueueTask = false;
188
- listen$(ctx, key, (v) => {
189
- newValue = getValue ? getValue(v) : v;
190
- if (delay !== void 0) {
191
- const fn = () => {
192
- didQueueTask = false;
193
- if (newValue !== void 0) {
194
- animValue.setValue(newValue);
195
- }
196
- };
197
- const delayValue = typeof delay === "function" ? delay(newValue, prevValue) : delay;
198
- prevValue = newValue;
199
- if (!didQueueTask) {
200
- didQueueTask = true;
201
- if (delayValue === 0) {
202
- queueMicrotask(fn);
203
- } else {
204
- setTimeout(fn, delayValue);
174
+ var globalResizeObserver = null;
175
+ function getGlobalResizeObserver() {
176
+ if (!globalResizeObserver) {
177
+ globalResizeObserver = new ResizeObserver((entries) => {
178
+ for (const entry of entries) {
179
+ const callbacks = callbackMap.get(entry.target);
180
+ if (callbacks) {
181
+ for (const callback of callbacks) {
182
+ callback(entry);
205
183
  }
206
184
  }
207
- } else {
208
- animValue.setValue(newValue);
209
185
  }
210
186
  });
187
+ }
188
+ return globalResizeObserver;
189
+ }
190
+ var callbackMap = /* @__PURE__ */ new WeakMap();
191
+ function useResizeObserver(element, callback) {
192
+ useEffect(() => {
193
+ if (!element) return;
194
+ const observer = getGlobalResizeObserver();
195
+ let callbacks = callbackMap.get(element);
196
+ if (!callbacks) {
197
+ callbacks = /* @__PURE__ */ new Set();
198
+ callbackMap.set(element, callbacks);
199
+ observer.observe(element);
200
+ }
201
+ callbacks.add(callback);
202
+ return () => {
203
+ const callbacks2 = callbackMap.get(element);
204
+ if (callbacks2) {
205
+ callbacks2.delete(callback);
206
+ if (callbacks2.size === 0) {
207
+ callbackMap.delete(element);
208
+ observer.unobserve(element);
209
+ }
210
+ }
211
+ };
212
+ }, [element, callback]);
213
+ }
214
+
215
+ // src/hooks/useSyncLayout.tsx
216
+ function useSyncLayout({
217
+ ref,
218
+ onLayoutChange
219
+ }) {
220
+ var _a, _b;
221
+ useResizeObserver(
222
+ ((_b = (_a = ref.current) == null ? void 0 : _a.getScrollableNode) == null ? void 0 : _b.call(_a)) || ref.current,
223
+ useCallback(
224
+ (entry) => {
225
+ onLayoutChange(entry.contentRect, false);
226
+ },
227
+ [onLayoutChange]
228
+ )
229
+ );
230
+ useLayoutEffect(() => {
231
+ if (ref.current) {
232
+ const rect = ref.current.getBoundingClientRect();
233
+ onLayoutChange(
234
+ {
235
+ height: rect.height,
236
+ width: rect.width,
237
+ x: rect.left,
238
+ y: rect.top
239
+ },
240
+ true
241
+ );
242
+ }
211
243
  }, []);
212
- return animValue;
244
+ return {};
213
245
  }
246
+
247
+ // src/components/LayoutView.tsx
248
+ var LayoutView = ({ onLayoutChange, refView, children, ...rest }) => {
249
+ const ref = refView != null ? refView : useRef();
250
+ useSyncLayout({ onLayoutChange, ref });
251
+ return /* @__PURE__ */ React4.createElement("div", { ...rest, ref }, children);
252
+ };
253
+
254
+ // src/constants.ts
255
+ var POSITION_OUT_OF_VIEW = -1e7;
256
+ var ENABLE_DEVMODE = __DEV__ && false;
257
+ var ENABLE_DEBUG_VIEW = __DEV__ && false;
214
258
  var typedForwardRef = forwardRef;
215
259
  var typedMemo = memo;
216
260
 
@@ -223,70 +267,45 @@ var PositionViewState = typedMemo(function PositionView({
223
267
  ...rest
224
268
  }) {
225
269
  const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
226
- return /* @__PURE__ */ React3.createElement(
227
- LeanView,
228
- {
229
- ref: refView,
230
- style: [
231
- style,
232
- horizontal ? { transform: [{ translateX: position }] } : { transform: [{ translateY: position }] }
233
- ],
234
- ...rest
235
- }
236
- );
237
- });
238
- var PositionViewAnimated = typedMemo(function PositionView2({
239
- id,
240
- horizontal,
241
- style,
242
- refView,
243
- ...rest
244
- }) {
245
- const position$ = useValue$(`containerPosition${id}`, {
246
- getValue: (v) => v != null ? v : POSITION_OUT_OF_VIEW
247
- });
248
- return /* @__PURE__ */ React3.createElement(
249
- Animated.View,
250
- {
251
- ref: refView,
252
- style: [
253
- style,
254
- horizontal ? { transform: [{ translateX: position$ }] } : { transform: [{ translateY: position$ }] }
255
- ],
256
- ...rest
257
- }
258
- );
270
+ const base = Array.isArray(style) ? Object.assign({}, ...style) : style;
271
+ const combinedStyle = horizontal ? { ...base, left: position } : { ...base, top: position };
272
+ return /* @__PURE__ */ React4.createElement(LayoutView, { refView, style: combinedStyle, ...rest });
259
273
  });
260
274
  var PositionViewSticky = typedMemo(function PositionViewSticky2({
261
275
  id,
262
276
  horizontal,
263
277
  style,
264
278
  refView,
265
- animatedScrollY,
266
- stickyOffset,
267
279
  index,
268
280
  ...rest
269
281
  }) {
270
- const [position = POSITION_OUT_OF_VIEW, headerSize] = useArr$([`containerPosition${id}`, "headerSize"]);
271
- const transform = React3.useMemo(() => {
272
- if (animatedScrollY && stickyOffset) {
273
- const stickyPosition = animatedScrollY.interpolate({
274
- extrapolate: "clamp",
275
- inputRange: [position + headerSize, position + 5e3 + headerSize],
276
- outputRange: [position, position + 5e3]
277
- });
278
- return horizontal ? [{ translateX: stickyPosition }] : [{ translateY: stickyPosition }];
279
- }
280
- }, [animatedScrollY, headerSize, horizontal, stickyOffset, position]);
281
- const viewStyle = React3.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
282
- return /* @__PURE__ */ React3.createElement(Animated.View, { ref: refView, style: viewStyle, ...rest });
282
+ const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
283
+ const viewStyle = React4.useMemo(() => {
284
+ const base = Array.isArray(style) ? Object.assign({}, ...style) : style;
285
+ const axisStyle = horizontal ? { transform: `translateX(${position}px)` } : { top: position };
286
+ return {
287
+ ...base,
288
+ zIndex: index + 1e3,
289
+ ...axisStyle
290
+ };
291
+ }, [style, position, horizontal, index]);
292
+ return /* @__PURE__ */ React4.createElement(LayoutView, { refView, style: viewStyle, ...rest });
283
293
  });
284
- var PositionView3 = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
294
+ var PositionView2 = PositionViewState;
285
295
  function Separator({ ItemSeparatorComponent, itemKey, leadingItem }) {
286
296
  const [lastItemKeys] = useArr$(["lastItemKeys"]);
287
297
  const isALastItem = lastItemKeys.includes(itemKey);
288
- return isALastItem ? null : /* @__PURE__ */ React3.createElement(ItemSeparatorComponent, { leadingItem });
298
+ return isALastItem ? null : /* @__PURE__ */ React4.createElement(ItemSeparatorComponent, { leadingItem });
289
299
  }
300
+
301
+ // src/constants-platform.ts
302
+ var IsNewArchitecture = true;
303
+
304
+ // src/platform/Platform.ts
305
+ var Platform = {
306
+ // Widen the type to avoid unreachable-branch lints in cross-platform code that compares against other OSes
307
+ OS: "web"
308
+ };
290
309
  var symbolFirst = Symbol();
291
310
  function useInit(cb) {
292
311
  const refValue = useRef(symbolFirst);
@@ -423,14 +442,10 @@ function useListScrollSize() {
423
442
  const [scrollSize] = useArr$(["scrollSize"]);
424
443
  return scrollSize;
425
444
  }
426
- var noop = () => {
427
- };
428
- function useSyncLayout() {
429
- if (IsNewArchitecture) {
445
+ function useSyncLayout2() {
446
+ {
430
447
  const { triggerLayout: syncLayout } = useContext(ContextContainer);
431
448
  return syncLayout;
432
- } else {
433
- return noop;
434
449
  }
435
450
  }
436
451
 
@@ -444,35 +459,37 @@ var Container = typedMemo(function Container2({
444
459
  ItemSeparatorComponent
445
460
  }) {
446
461
  const ctx = useStateContext();
447
- const { columnWrapperStyle, animatedScrollY } = ctx;
448
- const [column = 0, data, itemKey, numColumns, extraData, isSticky, stickyOffset] = useArr$([
462
+ const { columnWrapperStyle } = ctx;
463
+ const [column = 0, data, itemKey, numColumns, extraData, isSticky] = useArr$([
449
464
  `containerColumn${id}`,
450
465
  `containerItemData${id}`,
451
466
  `containerItemKey${id}`,
452
467
  "numColumns",
453
468
  "extraData",
454
- `containerSticky${id}`,
455
- `containerStickyOffset${id}`
469
+ `containerSticky${id}`
456
470
  ]);
457
471
  const refLastSize = useRef();
458
472
  const ref = useRef(null);
459
- const [layoutRenderCount, forceLayoutRender] = useState(0);
473
+ const [_, forceLayoutRender] = useState(0);
460
474
  const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
461
475
  const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
462
- let didLayout = false;
463
476
  const style = useMemo(() => {
464
477
  let paddingStyles;
465
478
  if (columnWrapperStyle) {
466
479
  const { columnGap, rowGap, gap } = columnWrapperStyle;
467
480
  if (horizontal) {
481
+ const py = numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0;
468
482
  paddingStyles = {
483
+ paddingBottom: py,
469
484
  paddingRight: columnGap || gap || void 0,
470
- paddingVertical: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
485
+ paddingTop: py
471
486
  };
472
487
  } else {
488
+ const px = numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0;
473
489
  paddingStyles = {
474
490
  paddingBottom: rowGap || gap || void 0,
475
- paddingHorizontal: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
491
+ paddingLeft: px,
492
+ paddingRight: px
476
493
  };
477
494
  }
478
495
  }
@@ -486,7 +503,7 @@ var Container = typedMemo(function Container2({
486
503
  } : {
487
504
  left: otherAxisPos,
488
505
  position: "absolute",
489
- right: numColumns > 1 ? null : 0,
506
+ right: numColumns > 1 ? void 0 : 0,
490
507
  top: 0,
491
508
  width: otherAxisSize,
492
509
  ...paddingStyles || {}
@@ -509,79 +526,183 @@ var Container = typedMemo(function Container2({
509
526
  value: data
510
527
  };
511
528
  }, [id, itemKey, index, data]);
512
- const onLayout = (event) => {
513
- var _a, _b;
529
+ const onLayoutChange = (rectangle) => {
514
530
  if (!isNullOrUndefined(itemKey)) {
515
- didLayout = true;
516
- let layout = event.nativeEvent.layout;
517
- const size = layout[horizontal ? "width" : "height"];
531
+ let layout = rectangle;
532
+ layout[horizontal ? "width" : "height"];
518
533
  const doUpdate = () => {
519
534
  refLastSize.current = { height: layout.height, width: layout.width };
520
535
  updateItemSize2(itemKey, layout);
521
536
  };
522
- if (IsNewArchitecture || size > 0) {
537
+ {
523
538
  doUpdate();
524
- } else {
525
- (_b = (_a = ref.current) == null ? void 0 : _a.measure) == null ? void 0 : _b.call(_a, (_x, _y, width, height) => {
526
- layout = { height, width };
527
- doUpdate();
528
- });
529
539
  }
530
540
  }
531
541
  };
532
- if (IsNewArchitecture) {
533
- useLayoutEffect(() => {
534
- var _a, _b;
535
- if (!isNullOrUndefined(itemKey)) {
536
- const measured = (_b = (_a = ref.current) == null ? void 0 : _a.unstable_getBoundingClientRect) == null ? void 0 : _b.call(_a);
537
- if (measured) {
538
- const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
539
- if (size) {
540
- updateItemSize2(itemKey, measured);
541
- }
542
- }
543
- }
544
- }, [itemKey, layoutRenderCount]);
545
- } else {
546
- useEffect(() => {
547
- if (!isNullOrUndefined(itemKey)) {
548
- const timeout = setTimeout(() => {
549
- if (!didLayout && refLastSize.current) {
550
- updateItemSize2(itemKey, refLastSize.current);
551
- }
552
- }, 16);
553
- return () => {
554
- clearTimeout(timeout);
555
- };
556
- }
557
- }, [itemKey]);
558
- }
559
- const PositionComponent = isSticky ? PositionViewSticky : PositionView3;
560
- return /* @__PURE__ */ React3.createElement(
542
+ const PositionComponent = isSticky ? PositionViewSticky : PositionView2;
543
+ return /* @__PURE__ */ React4.createElement(ContextContainer.Provider, { value: contextValue }, /* @__PURE__ */ React4.createElement(
561
544
  PositionComponent,
562
545
  {
563
- animatedScrollY: isSticky ? animatedScrollY : void 0,
564
546
  horizontal,
565
547
  id,
566
548
  index,
567
549
  key: recycleItems ? void 0 : itemKey,
568
- onLayout,
550
+ onLayoutChange,
569
551
  refView: ref,
570
- stickyOffset: isSticky ? stickyOffset : void 0,
571
552
  style
572
553
  },
573
- /* @__PURE__ */ React3.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React3.createElement(
554
+ renderedItem,
555
+ renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React4.createElement(
574
556
  Separator,
575
557
  {
576
558
  ItemSeparatorComponent,
577
559
  itemKey,
578
560
  leadingItem: renderedItemInfo.item
579
561
  }
580
- ))
581
- );
562
+ )
563
+ ));
582
564
  });
583
565
 
566
+ // src/utils/reordering.ts
567
+ var mapFn = (element) => {
568
+ const indexStr = element.getAttribute("index");
569
+ return [element, indexStr === null ? null : parseInt(indexStr)];
570
+ };
571
+ function sortDOMElementsPatience(container) {
572
+ const elements = Array.from(container.children);
573
+ if (elements.length <= 1) return elements;
574
+ const items = elements.map(mapFn);
575
+ items.sort((a, b) => {
576
+ const aKey = a[1];
577
+ const bKey = b[1];
578
+ if (aKey === null) {
579
+ return 1;
580
+ }
581
+ if (bKey === null) {
582
+ return -1;
583
+ }
584
+ return aKey - bKey;
585
+ });
586
+ const targetPositions = /* @__PURE__ */ new Map();
587
+ items.forEach((item, index) => {
588
+ targetPositions.set(item[0], index);
589
+ });
590
+ const currentPositions = elements.map((el) => targetPositions.get(el));
591
+ const lis = findLIS(currentPositions);
592
+ const stableIndices = new Set(lis);
593
+ for (let targetPos = 0; targetPos < items.length; targetPos++) {
594
+ const element = items[targetPos][0];
595
+ const currentPos = elements.indexOf(element);
596
+ if (!stableIndices.has(currentPos)) {
597
+ let nextStableElement = null;
598
+ for (let i = targetPos + 1; i < items.length; i++) {
599
+ const nextEl = items[i][0];
600
+ const nextCurrentPos = elements.indexOf(nextEl);
601
+ if (stableIndices.has(nextCurrentPos)) {
602
+ nextStableElement = nextEl;
603
+ break;
604
+ }
605
+ }
606
+ if (nextStableElement) {
607
+ container.insertBefore(element, nextStableElement);
608
+ } else {
609
+ container.appendChild(element);
610
+ }
611
+ }
612
+ }
613
+ }
614
+ function findLIS(arr) {
615
+ const n = arr.length;
616
+ const tails = [];
617
+ const predecessors = new Array(n).fill(-1);
618
+ const indices = [];
619
+ for (let i = 0; i < n; i++) {
620
+ const num = arr[i];
621
+ let left = 0, right = tails.length;
622
+ while (left < right) {
623
+ const mid = Math.floor((left + right) / 2);
624
+ if (arr[indices[mid]] < num) {
625
+ left = mid + 1;
626
+ } else {
627
+ right = mid;
628
+ }
629
+ }
630
+ if (left === tails.length) {
631
+ tails.push(num);
632
+ indices.push(i);
633
+ } else {
634
+ tails[left] = num;
635
+ indices[left] = i;
636
+ }
637
+ if (left > 0) {
638
+ predecessors[i] = indices[left - 1];
639
+ }
640
+ }
641
+ const result = [];
642
+ let k = indices[indices.length - 1];
643
+ while (k !== -1) {
644
+ result.unshift(k);
645
+ k = predecessors[k];
646
+ }
647
+ return result;
648
+ }
649
+
650
+ // src/hooks/useDOMOrder.ts
651
+ function useDOMOrder(ref) {
652
+ const ctx = useStateContext();
653
+ const debounceRef = useRef(void 0);
654
+ useEffect(() => {
655
+ const unsubscribe = listen$(ctx, "lastPositionUpdate", () => {
656
+ if (debounceRef.current !== void 0) {
657
+ clearTimeout(debounceRef.current);
658
+ }
659
+ debounceRef.current = setTimeout(() => {
660
+ const parent = ref.current;
661
+ if (parent) {
662
+ sortDOMElementsPatience(parent);
663
+ }
664
+ debounceRef.current = void 0;
665
+ }, 500);
666
+ });
667
+ return () => {
668
+ unsubscribe();
669
+ if (debounceRef.current !== void 0) {
670
+ clearTimeout(debounceRef.current);
671
+ }
672
+ };
673
+ }, [ctx]);
674
+ }
675
+
584
676
  // src/components/Containers.tsx
677
+ var ContainersInner = typedMemo(function ContainersInner2({ horizontal, numColumns, children }) {
678
+ const ref = useRef(null);
679
+ const ctx = useStateContext();
680
+ const columnWrapperStyle = ctx.columnWrapperStyle;
681
+ const [totalSize, otherAxisSize] = useArr$(["totalSize", "otherAxisSize"]);
682
+ useDOMOrder(ref);
683
+ const style = horizontal ? { minHeight: otherAxisSize, width: totalSize } : { height: totalSize, minWidth: otherAxisSize };
684
+ if (columnWrapperStyle && numColumns > 1) {
685
+ const { columnGap, rowGap, gap } = columnWrapperStyle;
686
+ const gapX = columnGap || gap || 0;
687
+ const gapY = rowGap || gap || 0;
688
+ if (horizontal) {
689
+ if (gapY) {
690
+ style.marginTop = style.marginBottom = -gapY / 2;
691
+ }
692
+ if (gapX) {
693
+ style.marginRight = -gapX;
694
+ }
695
+ } else {
696
+ if (gapX) {
697
+ style.marginLeft = style.marginRight = -gapX;
698
+ }
699
+ if (gapY) {
700
+ style.marginBottom = -gapY;
701
+ }
702
+ }
703
+ }
704
+ return /* @__PURE__ */ React4.createElement("div", { ref, style }, children);
705
+ });
585
706
  var Containers = typedMemo(function Containers2({
586
707
  horizontal,
587
708
  recycleItems,
@@ -590,19 +711,11 @@ var Containers = typedMemo(function Containers2({
590
711
  updateItemSize: updateItemSize2,
591
712
  getRenderedItem: getRenderedItem2
592
713
  }) {
593
- const ctx = useStateContext();
594
- const columnWrapperStyle = ctx.columnWrapperStyle;
595
714
  const [numContainers, numColumns] = useArr$(["numContainersPooled", "numColumns"]);
596
- const animSize = useValue$("totalSize", {
597
- // Use a microtask if increasing the size significantly, otherwise use a timeout
598
- delay: (value, prevValue) => !prevValue || value - prevValue > 20 ? 0 : 200
599
- });
600
- const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("containersDidLayout", { getValue: (value) => value ? 1 : 0 }) : void 0;
601
- const otherAxisSize = useValue$("otherAxisSize", { delay: 0 });
602
715
  const containers = [];
603
716
  for (let i = 0; i < numContainers; i++) {
604
717
  containers.push(
605
- /* @__PURE__ */ React3.createElement(
718
+ /* @__PURE__ */ React4.createElement(
606
719
  Container,
607
720
  {
608
721
  getRenderedItem: getRenderedItem2,
@@ -616,45 +729,209 @@ var Containers = typedMemo(function Containers2({
616
729
  )
617
730
  );
618
731
  }
619
- const style = horizontal ? { minHeight: otherAxisSize, opacity: animOpacity, width: animSize } : { height: animSize, minWidth: otherAxisSize, opacity: animOpacity };
620
- if (columnWrapperStyle && numColumns > 1) {
621
- const { columnGap, rowGap, gap } = columnWrapperStyle;
622
- const gapX = columnGap || gap || 0;
623
- const gapY = rowGap || gap || 0;
624
- if (horizontal) {
625
- if (gapY) {
626
- style.marginVertical = -gapY / 2;
732
+ return /* @__PURE__ */ React4.createElement(ContainersInner, { horizontal, numColumns, waitForInitialLayout }, containers);
733
+ });
734
+ var DevNumbers = __DEV__ && React4.memo(function DevNumbers2() {
735
+ return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React4.createElement(
736
+ View,
737
+ {
738
+ key: index,
739
+ style: {
740
+ height: 100,
741
+ pointerEvents: "none",
742
+ position: "absolute",
743
+ top: index * 100,
744
+ width: "100%"
627
745
  }
628
- if (gapX) {
629
- style.marginRight = -gapX;
746
+ },
747
+ /* @__PURE__ */ React4.createElement(Text, { style: { color: "red" } }, index * 100)
748
+ ));
749
+ });
750
+ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
751
+ children,
752
+ style,
753
+ contentContainerStyle,
754
+ horizontal = false,
755
+ contentOffset,
756
+ maintainVisibleContentPosition,
757
+ onScroll: onScroll2,
758
+ onMomentumScrollEnd,
759
+ showsHorizontalScrollIndicator = true,
760
+ showsVerticalScrollIndicator = true,
761
+ refreshControl,
762
+ onLayout,
763
+ ScrollComponent,
764
+ ...props
765
+ }, ref) {
766
+ const scrollRef = useRef(null);
767
+ const contentRef = useRef(null);
768
+ const momentumTimeout = useRef(null);
769
+ useImperativeHandle(ref, () => {
770
+ const api = {
771
+ getBoundingClientRect: () => {
772
+ var _a;
773
+ return (_a = scrollRef.current) == null ? void 0 : _a.getBoundingClientRect();
774
+ },
775
+ getScrollableNode: () => scrollRef.current,
776
+ getScrollResponder: () => scrollRef.current,
777
+ scrollBy: (options) => {
778
+ const el = scrollRef.current;
779
+ if (!el) return;
780
+ const { x = 0, y = 0, animated = true } = options;
781
+ el.scrollBy({ behavior: animated ? "smooth" : "auto", left: x, top: y });
782
+ },
783
+ scrollTo: (options) => {
784
+ const el = scrollRef.current;
785
+ if (!el) return;
786
+ const { x = 0, y = 0, animated = true } = options;
787
+ el.scrollTo({ behavior: animated ? "smooth" : "auto", left: x, top: y });
788
+ },
789
+ scrollToEnd: (options = {}) => {
790
+ const el = scrollRef.current;
791
+ if (!el) return;
792
+ const { animated = true } = options;
793
+ if (horizontal) {
794
+ el.scrollTo({ behavior: animated ? "smooth" : "auto", left: el.scrollWidth });
795
+ } else {
796
+ el.scrollTo({ behavior: animated ? "smooth" : "auto", top: el.scrollHeight });
797
+ }
798
+ },
799
+ scrollToOffset: (params) => {
800
+ const el = scrollRef.current;
801
+ if (!el) return;
802
+ const { offset, animated = true } = params;
803
+ if (horizontal) {
804
+ el.scrollTo({ behavior: animated ? "smooth" : "auto", left: offset });
805
+ } else {
806
+ el.scrollTo({ behavior: animated ? "smooth" : "auto", top: offset });
807
+ }
630
808
  }
631
- } else {
632
- if (gapX) {
633
- style.marginHorizontal = -gapX;
809
+ };
810
+ return api;
811
+ }, [horizontal]);
812
+ const handleScroll = useCallback(
813
+ (event) => {
814
+ if (!onScroll2 || !(event == null ? void 0 : event.target)) {
815
+ return;
634
816
  }
635
- if (gapY) {
636
- style.marginBottom = -gapY;
817
+ const target = event.target;
818
+ const scrollEvent = {
819
+ nativeEvent: {
820
+ contentOffset: {
821
+ x: target.scrollLeft,
822
+ y: target.scrollTop
823
+ },
824
+ contentSize: {
825
+ height: target.scrollHeight,
826
+ width: target.scrollWidth
827
+ },
828
+ layoutMeasurement: {
829
+ height: target.clientHeight,
830
+ width: target.clientWidth
831
+ }
832
+ }
833
+ };
834
+ onScroll2(scrollEvent);
835
+ if (onMomentumScrollEnd) {
836
+ if (momentumTimeout.current != null) clearTimeout(momentumTimeout.current);
837
+ momentumTimeout.current = setTimeout(() => {
838
+ onMomentumScrollEnd({
839
+ nativeEvent: {
840
+ contentOffset: scrollEvent.nativeEvent.contentOffset
841
+ }
842
+ });
843
+ }, 100);
637
844
  }
845
+ },
846
+ [onScroll2, onMomentumScrollEnd]
847
+ );
848
+ useLayoutEffect(() => {
849
+ const element = scrollRef.current;
850
+ if (!element) return;
851
+ element.addEventListener("scroll", handleScroll, { passive: true });
852
+ return () => {
853
+ element.removeEventListener("scroll", handleScroll);
854
+ };
855
+ }, [handleScroll]);
856
+ useLayoutEffect(() => {
857
+ if (contentOffset && scrollRef.current) {
858
+ scrollRef.current.scrollLeft = contentOffset.x || 0;
859
+ scrollRef.current.scrollTop = contentOffset.y || 0;
638
860
  }
639
- }
640
- return /* @__PURE__ */ React3.createElement(Animated.View, { style }, containers);
861
+ }, [contentOffset]);
862
+ useLayoutEffect(() => {
863
+ if (!onLayout || !scrollRef.current) return;
864
+ const element = scrollRef.current;
865
+ const fireLayout = () => {
866
+ const rect = element.getBoundingClientRect();
867
+ onLayout({
868
+ nativeEvent: {
869
+ layout: {
870
+ height: rect.height,
871
+ width: rect.width,
872
+ x: rect.left,
873
+ y: rect.top
874
+ }
875
+ }
876
+ });
877
+ };
878
+ fireLayout();
879
+ const resizeObserver = new ResizeObserver(() => {
880
+ fireLayout();
881
+ });
882
+ resizeObserver.observe(element);
883
+ return () => resizeObserver.disconnect();
884
+ }, [onLayout]);
885
+ const scrollViewStyle = {
886
+ overflow: "auto",
887
+ overflowX: horizontal ? "auto" : showsHorizontalScrollIndicator ? "auto" : "hidden",
888
+ overflowY: horizontal ? showsVerticalScrollIndicator ? "auto" : "hidden" : "auto",
889
+ position: "relative",
890
+ // Ensure proper positioning context
891
+ WebkitOverflowScrolling: "touch",
892
+ // iOS momentum scrolling
893
+ ...style
894
+ };
895
+ const contentStyle = {
896
+ display: horizontal ? "flex" : "block",
897
+ flexDirection: horizontal ? "row" : void 0,
898
+ minHeight: horizontal ? void 0 : "100%",
899
+ minWidth: horizontal ? "100%" : void 0,
900
+ ...contentContainerStyle
901
+ };
902
+ return /* @__PURE__ */ React4.createElement("div", { ref: scrollRef, style: scrollViewStyle, ...props }, refreshControl, /* @__PURE__ */ React4.createElement("div", { ref: contentRef, style: contentStyle }, children));
641
903
  });
904
+ function useValueListener$(key, callback) {
905
+ const ctx = useStateContext();
906
+ useLayoutEffect(() => {
907
+ listen$(ctx, key, (value) => {
908
+ callback(value);
909
+ });
910
+ }, []);
911
+ }
912
+
913
+ // src/components/ScrollAdjust.tsx
642
914
  function ScrollAdjust() {
643
- const bias = 1e7;
644
- const [scrollAdjust, scrollAdjustUserOffset] = useArr$(["scrollAdjust", "scrollAdjustUserOffset"]);
645
- const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0) + bias;
646
- return /* @__PURE__ */ React3.createElement(
647
- View,
648
- {
649
- style: {
650
- height: 0,
651
- left: 0,
652
- position: "absolute",
653
- top: scrollOffset,
654
- width: 0
655
- }
915
+ const ctx = useStateContext();
916
+ const lastScrollOffsetRef = React4.useRef(0);
917
+ const callback = React4.useCallback(() => {
918
+ var _a;
919
+ const scrollAdjust = peek$(ctx, "scrollAdjust");
920
+ const scrollAdjustUserOffset = peek$(ctx, "scrollAdjustUserOffset");
921
+ const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0);
922
+ const scrollView = (_a = ctx.internalState) == null ? void 0 : _a.refScroller.current;
923
+ if (scrollView && scrollOffset !== lastScrollOffsetRef.current) {
924
+ const scrollDelta = scrollOffset - lastScrollOffsetRef.current;
925
+ if (scrollDelta !== 0) {
926
+ scrollView.scrollBy(0, scrollDelta);
927
+ console.log("ScrollAdjust (web scrollBy)", scrollDelta, "total offset:", scrollOffset);
928
+ }
929
+ lastScrollOffsetRef.current = scrollOffset;
656
930
  }
657
- );
931
+ }, []);
932
+ useValueListener$("scrollAdjust", callback);
933
+ useValueListener$("scrollAdjustUserOffset", callback);
934
+ return null;
658
935
  }
659
936
 
660
937
  // src/components/SnapWrapper.tsx
@@ -662,87 +939,31 @@ function SnapWrapper({ ScrollComponent, ...props }) {
662
939
  const [snapToOffsets] = useArr$(["snapToOffsets"]);
663
940
  return /* @__PURE__ */ React.createElement(ScrollComponent, { ...props, snapToOffsets });
664
941
  }
665
- function useThrottleDebounce(mode) {
666
- const timeoutRef = useRef(null);
667
- const lastCallTimeRef = useRef(0);
668
- const lastArgsRef = useRef(null);
669
- const clearTimeoutRef = () => {
670
- if (timeoutRef.current) {
671
- clearTimeout(timeoutRef.current);
672
- timeoutRef.current = null;
673
- }
674
- };
675
- const execute = useCallback(
676
- (callback, delay, ...args) => {
677
- {
678
- const now = Date.now();
679
- lastArgsRef.current = args;
680
- if (now - lastCallTimeRef.current >= delay) {
681
- lastCallTimeRef.current = now;
682
- callback(...args);
683
- clearTimeoutRef();
684
- } else {
685
- clearTimeoutRef();
686
- timeoutRef.current = setTimeout(
687
- () => {
688
- if (lastArgsRef.current) {
689
- lastCallTimeRef.current = Date.now();
690
- callback(...lastArgsRef.current);
691
- timeoutRef.current = null;
692
- lastArgsRef.current = null;
693
- }
694
- },
695
- delay - (now - lastCallTimeRef.current)
696
- );
697
- }
698
- }
699
- },
700
- [mode]
701
- );
702
- return execute;
703
- }
704
942
 
705
- // src/hooks/useSyncLayout.tsx
706
- function useSyncLayout2({
707
- onChange
708
- }) {
709
- const ref = useRef(null);
710
- const onLayout = useCallback(
711
- (event) => {
712
- onChange(event.nativeEvent.layout, false);
713
- },
714
- [onChange]
715
- );
716
- if (IsNewArchitecture) {
717
- useLayoutEffect(() => {
718
- if (ref.current) {
719
- ref.current.measure((x, y, width, height) => {
720
- onChange({ height, width, x, y }, true);
721
- });
722
- }
723
- }, []);
724
- }
725
- return { onLayout, ref };
943
+ // src/hooks/useValue$.ts
944
+ function useValue$(key, params) {
945
+ const [value] = useArr$([key]);
946
+ return value;
726
947
  }
727
948
 
728
949
  // src/components/ListComponent.tsx
729
950
  var getComponent = (Component) => {
730
- if (React3.isValidElement(Component)) {
951
+ if (React4.isValidElement(Component)) {
731
952
  return Component;
732
953
  }
733
954
  if (Component) {
734
- return /* @__PURE__ */ React3.createElement(Component, null);
955
+ return /* @__PURE__ */ React4.createElement(Component, null);
735
956
  }
736
957
  return null;
737
958
  };
738
959
  var Padding = () => {
739
- const animPaddingTop = useValue$("alignItemsPaddingTop", { delay: 0 });
740
- return /* @__PURE__ */ React3.createElement(Animated.View, { style: { paddingTop: animPaddingTop } });
960
+ const animPaddingTop = useValue$("alignItemsPaddingTop");
961
+ return /* @__PURE__ */ React4.createElement(AnimatedView, { style: { paddingTop: animPaddingTop } });
741
962
  };
742
963
  var PaddingDevMode = () => {
743
- const animPaddingTop = useValue$("alignItemsPaddingTop", { delay: 0 });
744
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(Animated.View, { style: { paddingTop: animPaddingTop } }), /* @__PURE__ */ React3.createElement(
745
- Animated.View,
964
+ const animPaddingTop = useValue$("alignItemsPaddingTop");
965
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(AnimatedView, { style: { paddingTop: animPaddingTop } }), /* @__PURE__ */ React4.createElement(
966
+ AnimatedView,
746
967
  {
747
968
  style: {
748
969
  backgroundColor: "green",
@@ -784,14 +1005,12 @@ var ListComponent = typedMemo(function ListComponent2({
784
1005
  ...rest
785
1006
  }) {
786
1007
  const ctx = useStateContext();
787
- const { onLayout: onLayoutHeaderSync, ref: refHeader } = useSyncLayout2({
788
- onChange: onLayoutHeader
789
- });
1008
+ const refHeader = React4.useRef(null);
790
1009
  const ScrollComponent = renderScrollComponent ? useMemo(
791
- () => React3.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
1010
+ () => React4.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
792
1011
  [renderScrollComponent]
793
- ) : Animated.ScrollView;
794
- React3.useEffect(() => {
1012
+ ) : ListComponentScrollView;
1013
+ React4.useEffect(() => {
795
1014
  if (canRender) {
796
1015
  setTimeout(() => {
797
1016
  scrollAdjustHandler.setMounted();
@@ -799,16 +1018,17 @@ var ListComponent = typedMemo(function ListComponent2({
799
1018
  }
800
1019
  }, [canRender]);
801
1020
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
802
- return /* @__PURE__ */ React3.createElement(
1021
+ const contentContainerStyleWeb = useMemo(() => {
1022
+ const base = contentContainerStyle || void 0;
1023
+ if (!horizontal) return base;
1024
+ if (base && base.height === "100%") return base;
1025
+ return { ...base || {}, height: "100%" };
1026
+ }, [horizontal, (contentContainerStyle == null ? void 0 : contentContainerStyle.height) === "100%" ? 1 : 0]);
1027
+ return /* @__PURE__ */ React4.createElement(
803
1028
  SnapOrScroll,
804
1029
  {
805
1030
  ...rest,
806
- contentContainerStyle: [
807
- contentContainerStyle,
808
- horizontal ? {
809
- height: "100%"
810
- } : {}
811
- ],
1031
+ contentContainerStyle: contentContainerStyleWeb,
812
1032
  contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
813
1033
  horizontal,
814
1034
  maintainVisibleContentPosition: maintainVisibleContentPosition && !ListEmptyComponent ? { minIndexForVisible: 0 } : void 0,
@@ -818,11 +1038,19 @@ var ListComponent = typedMemo(function ListComponent2({
818
1038
  ScrollComponent: snapToIndices ? ScrollComponent : void 0,
819
1039
  style
820
1040
  },
821
- maintainVisibleContentPosition && /* @__PURE__ */ React3.createElement(ScrollAdjust, null),
822
- ENABLE_DEVMODE ? /* @__PURE__ */ React3.createElement(PaddingDevMode, null) : /* @__PURE__ */ React3.createElement(Padding, null),
823
- ListHeaderComponent && /* @__PURE__ */ React3.createElement(View, { onLayout: onLayoutHeaderSync, ref: refHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
1041
+ maintainVisibleContentPosition && /* @__PURE__ */ React4.createElement(ScrollAdjust, null),
1042
+ ENABLE_DEVMODE ? /* @__PURE__ */ React4.createElement(PaddingDevMode, null) : /* @__PURE__ */ React4.createElement(Padding, null),
1043
+ ListHeaderComponent && /* @__PURE__ */ React4.createElement(
1044
+ LayoutView,
1045
+ {
1046
+ onLayoutChange: onLayoutHeader,
1047
+ refView: refHeader,
1048
+ style: ListHeaderComponentStyle
1049
+ },
1050
+ getComponent(ListHeaderComponent)
1051
+ ),
824
1052
  ListEmptyComponent && getComponent(ListEmptyComponent),
825
- canRender && /* @__PURE__ */ React3.createElement(
1053
+ canRender && /* @__PURE__ */ React4.createElement(
826
1054
  Containers,
827
1055
  {
828
1056
  getRenderedItem: getRenderedItem2,
@@ -833,36 +1061,20 @@ var ListComponent = typedMemo(function ListComponent2({
833
1061
  waitForInitialLayout
834
1062
  }
835
1063
  ),
836
- ListFooterComponent && /* @__PURE__ */ React3.createElement(
837
- View,
1064
+ ListFooterComponent && /* @__PURE__ */ React4.createElement(
1065
+ LayoutView,
838
1066
  {
839
- onLayout: (event) => {
840
- const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
1067
+ onLayoutChange: (layout) => {
1068
+ const size = layout[horizontal ? "width" : "height"];
841
1069
  set$(ctx, "footerSize", size);
842
1070
  },
843
1071
  style: ListFooterComponentStyle
844
1072
  },
845
1073
  getComponent(ListFooterComponent)
846
1074
  ),
847
- __DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React3.createElement(DevNumbers, null)
1075
+ __DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React4.createElement(DevNumbers, null)
848
1076
  );
849
1077
  });
850
- var DevNumbers = __DEV__ && React3.memo(function DevNumbers2() {
851
- return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React3.createElement(
852
- View,
853
- {
854
- key: index,
855
- style: {
856
- height: 100,
857
- pointerEvents: "none",
858
- position: "absolute",
859
- top: index * 100,
860
- width: "100%"
861
- }
862
- },
863
- /* @__PURE__ */ React3.createElement(Text, { style: { color: "red" } }, index * 100)
864
- ));
865
- });
866
1078
 
867
1079
  // src/utils/getId.ts
868
1080
  function getId(state, index) {
@@ -983,14 +1195,8 @@ function scrollTo(state, params = {}) {
983
1195
  // src/utils/requestAdjust.ts
984
1196
  function requestAdjust(ctx, state, positionDiff, dataChanged) {
985
1197
  if (Math.abs(positionDiff) > 0.1) {
986
- const needsScrollWorkaround = Platform.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff;
987
1198
  const doit = () => {
988
- if (needsScrollWorkaround) {
989
- scrollTo(state, {
990
- noScrollingTo: true,
991
- offset: state.scroll
992
- });
993
- } else {
1199
+ {
994
1200
  state.scrollAdjustHandler.requestAdjust(positionDiff);
995
1201
  }
996
1202
  };
@@ -1015,7 +1221,7 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1015
1221
  () => {
1016
1222
  state.ignoreScrollFromMVCP = void 0;
1017
1223
  },
1018
- needsScrollWorkaround ? 250 : 100
1224
+ 100
1019
1225
  );
1020
1226
  } else {
1021
1227
  requestAnimationFrame(doit);
@@ -1075,7 +1281,7 @@ function prepareMVCP(ctx, state, dataChanged) {
1075
1281
  }
1076
1282
  }
1077
1283
  if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
1078
- requestAdjust(ctx, state, positionDiff, dataChanged);
1284
+ requestAdjust(ctx, state, positionDiff);
1079
1285
  }
1080
1286
  };
1081
1287
  }
@@ -1251,21 +1457,6 @@ function ensureViewabilityState(ctx, configId) {
1251
1457
  }
1252
1458
  return state;
1253
1459
  }
1254
- function setupViewability(props) {
1255
- let { viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged } = props;
1256
- if (viewabilityConfig || onViewableItemsChanged) {
1257
- viewabilityConfigCallbackPairs = [
1258
- ...viewabilityConfigCallbackPairs || [],
1259
- {
1260
- onViewableItemsChanged,
1261
- viewabilityConfig: viewabilityConfig || {
1262
- viewAreaCoveragePercentThreshold: 0
1263
- }
1264
- }
1265
- ];
1266
- }
1267
- return viewabilityConfigCallbackPairs;
1268
- }
1269
1460
  function updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollSize, start, end) {
1270
1461
  const {
1271
1462
  timeouts,
@@ -1435,12 +1626,11 @@ function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
1435
1626
  const cb = ctx.mapViewabilityCallbacks.get(key);
1436
1627
  cb == null ? void 0 : cb(viewToken);
1437
1628
  }
1438
- var batchedUpdates = unstable_batchedUpdates || ((callback) => callback());
1439
1629
 
1440
1630
  // src/utils/checkAllSizesKnown.ts
1441
1631
  function checkAllSizesKnown(state) {
1442
1632
  const { startBuffered, endBuffered, sizesKnown } = state;
1443
- if (endBuffered !== null) {
1633
+ if (endBuffered !== null && startBuffered >= 0 && endBuffered >= 0) {
1444
1634
  let areAllKnown = true;
1445
1635
  for (let i = startBuffered; areAllKnown && i <= endBuffered; i++) {
1446
1636
  const key = getId(state, i);
@@ -1698,19 +1888,7 @@ function setDidLayout(ctx, state) {
1698
1888
  onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
1699
1889
  }
1700
1890
  };
1701
- if (Platform.OS === "android" || !IsNewArchitecture) {
1702
- if (initialScroll) {
1703
- queueMicrotask(() => {
1704
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
1705
- requestAnimationFrame(() => {
1706
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
1707
- setIt();
1708
- });
1709
- });
1710
- } else {
1711
- queueMicrotask(setIt);
1712
- }
1713
- } else {
1891
+ {
1714
1892
  setIt();
1715
1893
  }
1716
1894
  }
@@ -1779,7 +1957,7 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, pe
1779
1957
  }
1780
1958
  }
1781
1959
  function calculateItemsInView(ctx, state, params = {}) {
1782
- batchedUpdates(() => {
1960
+ unstable_batchedUpdates(() => {
1783
1961
  var _a, _b, _c, _d, _e, _f, _g, _h;
1784
1962
  const {
1785
1963
  columns,
@@ -2007,10 +2185,9 @@ function calculateItemsInView(ctx, state, params = {}) {
2007
2185
  if (stickyIndicesSet.has(i)) {
2008
2186
  set$(ctx, `containerSticky${containerIndex}`, true);
2009
2187
  const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
2010
- set$(ctx, `containerStickyOffset${containerIndex}`, new Animated.Value(topPadding));
2188
+ set$(ctx, `containerStickyOffset${containerIndex}`, createAnimatedValue(topPadding));
2011
2189
  state.stickyContainerPool.add(containerIndex);
2012
2190
  } else {
2013
- set$(ctx, `containerSticky${containerIndex}`, false);
2014
2191
  state.stickyContainerPool.delete(containerIndex);
2015
2192
  }
2016
2193
  if (containerIndex >= numContainers2) {
@@ -2028,6 +2205,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2028
2205
  if (stickyIndicesArr.length > 0) {
2029
2206
  handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, pendingRemoval);
2030
2207
  }
2208
+ let didChangePositions = false;
2031
2209
  for (let i = 0; i < numContainers; i++) {
2032
2210
  const itemKey = peek$(ctx, `containerItemKey${i}`);
2033
2211
  if (pendingRemoval.includes(i)) {
@@ -2059,6 +2237,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2059
2237
  const prevData = peek$(ctx, `containerItemData${i}`);
2060
2238
  if (position > POSITION_OUT_OF_VIEW && position !== prevPos) {
2061
2239
  set$(ctx, `containerPosition${i}`, position);
2240
+ didChangePositions = true;
2062
2241
  }
2063
2242
  if (column >= 0 && column !== prevColumn) {
2064
2243
  set$(ctx, `containerColumn${i}`, column);
@@ -2070,6 +2249,9 @@ function calculateItemsInView(ctx, state, params = {}) {
2070
2249
  }
2071
2250
  }
2072
2251
  }
2252
+ if (didChangePositions) {
2253
+ set$(ctx, "lastPositionUpdate", Date.now());
2254
+ }
2073
2255
  if (!queuedInitialLayout && endBuffered !== null) {
2074
2256
  if (checkAllSizesKnown(state)) {
2075
2257
  setDidLayout(ctx, state);
@@ -2117,7 +2299,7 @@ function doInitialAllocateContainers(ctx, state) {
2117
2299
  }
2118
2300
  set$(ctx, "numContainers", numContainers);
2119
2301
  set$(ctx, "numContainersPooled", numContainers * state.props.initialContainerPoolRatio);
2120
- if (!IsNewArchitecture || state.lastLayout) {
2302
+ if (state.lastLayout) {
2121
2303
  if (state.props.initialScroll) {
2122
2304
  requestAnimationFrame(() => {
2123
2305
  calculateItemsInView(ctx, state, { dataChanged: true });
@@ -2191,7 +2373,9 @@ function checkAtTop(state) {
2191
2373
  // src/core/handleLayout.ts
2192
2374
  function handleLayout(ctx, state, layout, setCanRender) {
2193
2375
  const { maintainScrollAtEnd } = state.props;
2194
- const scrollLength = layout[state.props.horizontal ? "width" : "height"];
2376
+ const measuredLength = layout[state.props.horizontal ? "width" : "height"];
2377
+ const previousLength = state.scrollLength;
2378
+ const scrollLength = measuredLength > 0 ? measuredLength : previousLength;
2195
2379
  const otherAxisSize = layout[state.props.horizontal ? "height" : "width"];
2196
2380
  const needsCalculate = !state.lastLayout || scrollLength > state.scrollLength || state.lastLayout.x !== layout.x || state.lastLayout.y !== layout.y;
2197
2381
  state.lastLayout = layout;
@@ -2202,7 +2386,9 @@ function handleLayout(ctx, state, layout, setCanRender) {
2202
2386
  state.otherAxisSize = otherAxisSize;
2203
2387
  state.lastBatchingAction = Date.now();
2204
2388
  state.scrollForNextCalculateItemsInView = void 0;
2205
- doInitialAllocateContainers(ctx, state);
2389
+ if (scrollLength > 0) {
2390
+ doInitialAllocateContainers(ctx, state);
2391
+ }
2206
2392
  if (needsCalculate) {
2207
2393
  calculateItemsInView(ctx, state, { doMVCP: true });
2208
2394
  }
@@ -2218,7 +2404,7 @@ function handleLayout(ctx, state, layout, setCanRender) {
2218
2404
  if (state) {
2219
2405
  state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
2220
2406
  }
2221
- if (__DEV__ && scrollLength === 0) {
2407
+ if (__DEV__ && measuredLength === 0) {
2222
2408
  warnDevOnce(
2223
2409
  "height0",
2224
2410
  `List ${state.props.horizontal ? "width" : "height"} is 0. You may need to set a style or \`flex: \` for the list, because children are absolutely positioned.`
@@ -2250,7 +2436,15 @@ function onScroll(ctx, state, event) {
2250
2436
  }
2251
2437
  }
2252
2438
  state.scrollPending = newScroll;
2253
- updateScroll(ctx, state, newScroll);
2439
+ {
2440
+ if (!state.onScrollRafScheduled) {
2441
+ state.onScrollRafScheduled = true;
2442
+ requestAnimationFrame(() => {
2443
+ state.onScrollRafScheduled = false;
2444
+ updateScroll(ctx, state, newScroll);
2445
+ });
2446
+ }
2447
+ }
2254
2448
  onScrollProp == null ? void 0 : onScrollProp(event);
2255
2449
  }
2256
2450
  function updateScroll(ctx, state, newScroll) {
@@ -2416,7 +2610,8 @@ function updateOneItemSize(state, itemKey, sizeObj) {
2416
2610
  if (!data) return 0;
2417
2611
  const index = indexByKey.get(itemKey);
2418
2612
  const prevSize = getItemSize(state, itemKey, index, data);
2419
- const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
2613
+ const rawSize = horizontal ? sizeObj.width : sizeObj.height;
2614
+ const size = Math.round(rawSize) ;
2420
2615
  sizesKnown.set(itemKey, size);
2421
2616
  if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
2422
2617
  const itemType = getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : "";
@@ -2449,6 +2644,28 @@ var useCombinedRef = (...refs) => {
2449
2644
  return callback;
2450
2645
  };
2451
2646
 
2647
+ // src/platform/RefreshControl.tsx
2648
+ function RefreshControl(props) {
2649
+ return null;
2650
+ }
2651
+
2652
+ // src/platform/StyleSheet.tsx
2653
+ function flattenStyles(styles) {
2654
+ if (Array.isArray(styles)) {
2655
+ return Object.assign({}, ...styles.filter(Boolean));
2656
+ }
2657
+ return styles;
2658
+ }
2659
+ var StyleSheet = {
2660
+ create: (styles) => styles,
2661
+ flatten: (style) => flattenStyles(style)
2662
+ };
2663
+
2664
+ // src/platform/useStickyScrollHandler.ts
2665
+ function useStickyScrollHandler(stickyIndices, horizontal, ctx, onScroll2) {
2666
+ return onScroll2;
2667
+ }
2668
+
2452
2669
  // src/utils/createColumnWrapperStyle.ts
2453
2670
  function createColumnWrapperStyle(contentContainerStyle) {
2454
2671
  const { gap, columnGap, rowGap } = contentContainerStyle;
@@ -2485,10 +2702,49 @@ function getRenderedItem(ctx, state, key) {
2485
2702
  item: data[index],
2486
2703
  type: getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : ""
2487
2704
  };
2488
- renderedItem = isFunction(renderItem) ? renderItem(itemProps) : React3__default.createElement(renderItem, itemProps);
2705
+ renderedItem = isFunction(renderItem) ? renderItem(itemProps) : React4__default.createElement(renderItem, itemProps);
2489
2706
  }
2490
2707
  return { index, item: data[index], renderedItem };
2491
2708
  }
2709
+ function useThrottleDebounce(mode) {
2710
+ const timeoutRef = useRef(null);
2711
+ const lastCallTimeRef = useRef(0);
2712
+ const lastArgsRef = useRef(null);
2713
+ const clearTimeoutRef = () => {
2714
+ if (timeoutRef.current) {
2715
+ clearTimeout(timeoutRef.current);
2716
+ timeoutRef.current = null;
2717
+ }
2718
+ };
2719
+ const execute = useCallback(
2720
+ (callback, delay, ...args) => {
2721
+ {
2722
+ const now = Date.now();
2723
+ lastArgsRef.current = args;
2724
+ if (now - lastCallTimeRef.current >= delay) {
2725
+ lastCallTimeRef.current = now;
2726
+ callback(...args);
2727
+ clearTimeoutRef();
2728
+ } else {
2729
+ clearTimeoutRef();
2730
+ timeoutRef.current = setTimeout(
2731
+ () => {
2732
+ if (lastArgsRef.current) {
2733
+ lastCallTimeRef.current = Date.now();
2734
+ callback(...lastArgsRef.current);
2735
+ timeoutRef.current = null;
2736
+ lastArgsRef.current = null;
2737
+ }
2738
+ },
2739
+ delay - (now - lastCallTimeRef.current)
2740
+ );
2741
+ }
2742
+ }
2743
+ },
2744
+ [mode]
2745
+ );
2746
+ return execute;
2747
+ }
2492
2748
 
2493
2749
  // src/utils/throttledOnScroll.ts
2494
2750
  function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
@@ -2557,18 +2813,17 @@ var LegendList = typedMemo(
2557
2813
  const isChildrenMode = children !== void 0 && dataProp === void 0;
2558
2814
  const processedProps = isChildrenMode ? {
2559
2815
  ...restProps,
2560
- data: (isArray(children) ? children : React3.Children.toArray(children)).flat(1),
2816
+ data: (isArray(children) ? children : React4.Children.toArray(children)).flat(1),
2561
2817
  renderItem: ({ item }) => item
2562
2818
  } : {
2563
2819
  ...restProps,
2564
2820
  data: dataProp || [],
2565
2821
  renderItem: renderItemProp
2566
2822
  };
2567
- return /* @__PURE__ */ React3.createElement(StateProvider, null, /* @__PURE__ */ React3.createElement(LegendListInner, { ...processedProps, ref: forwardedRef }));
2823
+ return /* @__PURE__ */ React4.createElement(StateProvider, null, /* @__PURE__ */ React4.createElement(LegendListInner, { ...processedProps, ref: forwardedRef }));
2568
2824
  })
2569
2825
  );
2570
2826
  var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
2571
- var _a;
2572
2827
  const {
2573
2828
  alignItemsAtEnd = false,
2574
2829
  columnWrapperStyle,
@@ -2604,7 +2859,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2604
2859
  onScroll: onScrollProp,
2605
2860
  onStartReached,
2606
2861
  onStartReachedThreshold = 0.5,
2607
- onViewableItemsChanged,
2608
2862
  progressViewOffset,
2609
2863
  recycleItems = false,
2610
2864
  refreshControl,
@@ -2616,14 +2870,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2616
2870
  stickyIndices,
2617
2871
  style: styleProp,
2618
2872
  suggestEstimatedItemSize,
2619
- viewabilityConfig,
2620
- viewabilityConfigCallbackPairs,
2621
2873
  waitForInitialLayout = true,
2622
2874
  ...rest
2623
2875
  } = props;
2624
2876
  const [renderNum, setRenderNum] = useState(0);
2625
2877
  const initialScroll = initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
2626
- const [canRender, setCanRender] = React3.useState(!IsNewArchitecture);
2878
+ const [canRender, setCanRender] = React4.useState(!IsNewArchitecture);
2627
2879
  const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
2628
2880
  const style = { ...StyleSheet.flatten(styleProp) };
2629
2881
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
@@ -2637,64 +2889,70 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2637
2889
  const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (_item, index) => index.toString();
2638
2890
  const refState = useRef();
2639
2891
  if (!refState.current) {
2640
- const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { height: 0, width: 0 } : Dimensions.get("window"))[horizontal ? "width" : "height"];
2641
- refState.current = {
2642
- activeStickyIndex: void 0,
2643
- averageSizes: {},
2644
- columns: /* @__PURE__ */ new Map(),
2645
- containerItemKeys: /* @__PURE__ */ new Set(),
2646
- containerItemTypes: /* @__PURE__ */ new Map(),
2647
- enableScrollForNextCalculateItemsInView: true,
2648
- endBuffered: -1,
2649
- endNoBuffer: -1,
2650
- endReachedBlockedByTimer: false,
2651
- firstFullyOnScreenIndex: -1,
2652
- idCache: /* @__PURE__ */ new Map(),
2653
- idsInView: [],
2654
- indexByKey: /* @__PURE__ */ new Map(),
2655
- initialScroll,
2656
- isAtEnd: false,
2657
- isAtStart: false,
2658
- isEndReached: false,
2659
- isStartReached: false,
2660
- lastBatchingAction: Date.now(),
2661
- lastLayout: void 0,
2662
- loadStartTime: Date.now(),
2663
- minIndexSizeChanged: 0,
2664
- nativeMarginTop: 0,
2665
- positions: /* @__PURE__ */ new Map(),
2666
- props: {},
2667
- queuedCalculateItemsInView: 0,
2668
- refScroller: void 0,
2669
- scroll: 0,
2670
- scrollAdjustHandler: new ScrollAdjustHandler(ctx),
2671
- scrollForNextCalculateItemsInView: void 0,
2672
- scrollHistory: [],
2673
- scrollLength: initialScrollLength,
2674
- scrollPending: 0,
2675
- scrollPrev: 0,
2676
- scrollPrevTime: 0,
2677
- scrollProcessingEnabled: true,
2678
- scrollTime: 0,
2679
- sizes: /* @__PURE__ */ new Map(),
2680
- sizesKnown: /* @__PURE__ */ new Map(),
2681
- startBuffered: -1,
2682
- startNoBuffer: -1,
2683
- startReachedBlockedByTimer: false,
2684
- stickyContainerPool: /* @__PURE__ */ new Set(),
2685
- stickyContainers: /* @__PURE__ */ new Map(),
2686
- timeoutSizeMessage: 0,
2687
- timeouts: /* @__PURE__ */ new Set(),
2688
- totalSize: 0,
2689
- viewabilityConfigCallbackPairs: void 0
2690
- };
2691
- set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
2692
- set$(ctx, "extraData", extraData);
2892
+ if (!ctx.internalState) {
2893
+ const initialScrollLength = (estimatedListSize != null ? estimatedListSize : { height: 0, width: 0 } )[horizontal ? "width" : "height"];
2894
+ ctx.internalState = {
2895
+ activeStickyIndex: void 0,
2896
+ averageSizes: {},
2897
+ columns: /* @__PURE__ */ new Map(),
2898
+ containerItemKeys: /* @__PURE__ */ new Set(),
2899
+ containerItemTypes: /* @__PURE__ */ new Map(),
2900
+ enableScrollForNextCalculateItemsInView: true,
2901
+ endBuffered: -1,
2902
+ endNoBuffer: -1,
2903
+ endReachedBlockedByTimer: false,
2904
+ firstFullyOnScreenIndex: -1,
2905
+ idCache: /* @__PURE__ */ new Map(),
2906
+ idsInView: [],
2907
+ indexByKey: /* @__PURE__ */ new Map(),
2908
+ initialScroll,
2909
+ isAtEnd: false,
2910
+ isAtStart: false,
2911
+ isEndReached: false,
2912
+ isStartReached: false,
2913
+ lastBatchingAction: Date.now(),
2914
+ lastLayout: void 0,
2915
+ loadStartTime: Date.now(),
2916
+ minIndexSizeChanged: 0,
2917
+ nativeMarginTop: 0,
2918
+ positions: /* @__PURE__ */ new Map(),
2919
+ props: {},
2920
+ queuedCalculateItemsInView: 0,
2921
+ refScroller: void 0,
2922
+ scroll: 0,
2923
+ scrollAdjustHandler: new ScrollAdjustHandler(ctx),
2924
+ scrollForNextCalculateItemsInView: void 0,
2925
+ scrollHistory: [],
2926
+ scrollLength: initialScrollLength,
2927
+ scrollPending: 0,
2928
+ scrollPrev: 0,
2929
+ scrollPrevTime: 0,
2930
+ scrollProcessingEnabled: true,
2931
+ scrollTime: 0,
2932
+ sizes: /* @__PURE__ */ new Map(),
2933
+ sizesKnown: /* @__PURE__ */ new Map(),
2934
+ startBuffered: -1,
2935
+ startNoBuffer: -1,
2936
+ startReachedBlockedByTimer: false,
2937
+ stickyContainerPool: /* @__PURE__ */ new Set(),
2938
+ stickyContainers: /* @__PURE__ */ new Map(),
2939
+ timeoutSizeMessage: 0,
2940
+ timeouts: /* @__PURE__ */ new Set(),
2941
+ totalSize: 0,
2942
+ viewabilityConfigCallbackPairs: void 0
2943
+ };
2944
+ set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
2945
+ set$(ctx, "extraData", extraData);
2946
+ }
2947
+ refState.current = ctx.internalState;
2693
2948
  }
2694
2949
  const state = refState.current;
2695
2950
  const isFirst = !state.props.renderItem;
2696
2951
  const didDataChange = state.props.data !== dataProp;
2697
- const throttleScrollFn = scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp;
2952
+ const throttleScrollFn = (
2953
+ // @ts-expect-error TODO Fix this
2954
+ scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp
2955
+ );
2698
2956
  state.props = {
2699
2957
  alignItemsAtEnd,
2700
2958
  data: dataProp,
@@ -2792,28 +3050,24 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2792
3050
  return 0;
2793
3051
  }, [renderNum]);
2794
3052
  if (isFirst || didDataChange || numColumnsProp !== peek$(ctx, "numColumns")) {
2795
- refState.current.lastBatchingAction = Date.now();
3053
+ state.lastBatchingAction = Date.now();
2796
3054
  if (!keyExtractorProp && !isFirst && didDataChange) {
2797
3055
  __DEV__ && warnDevOnce(
2798
3056
  "keyExtractor",
2799
3057
  "Changing data without a keyExtractor can cause slow performance and resetting scroll. If your list data can change you should use a keyExtractor with a unique id for best performance and behavior."
2800
3058
  );
2801
- refState.current.sizes.clear();
2802
- refState.current.positions.clear();
3059
+ state.sizes.clear();
3060
+ state.positions.clear();
2803
3061
  }
2804
3062
  }
2805
3063
  const onLayoutHeader = useCallback((rect, fromLayoutEffect) => {
2806
3064
  const size = rect[horizontal ? "width" : "height"];
2807
3065
  set$(ctx, "headerSize", size);
2808
3066
  if ((initialScroll == null ? void 0 : initialScroll.index) !== void 0) {
2809
- if (IsNewArchitecture && Platform.OS !== "android") {
3067
+ {
2810
3068
  if (fromLayoutEffect) {
2811
3069
  setRenderNum((v) => v + 1);
2812
3070
  }
2813
- } else {
2814
- setTimeout(() => {
2815
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2816
- }, 17);
2817
3071
  }
2818
3072
  }
2819
3073
  }, []);
@@ -2834,20 +3088,16 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2834
3088
  useLayoutEffect(() => {
2835
3089
  set$(ctx, "extraData", extraData);
2836
3090
  }, [extraData]);
2837
- useLayoutEffect(() => {
2838
- if (IsNewArchitecture) {
2839
- let measured;
2840
- refScroller.current.measure((x, y, width, height) => {
2841
- measured = { height, width, x, y };
2842
- });
2843
- if (measured) {
2844
- const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
2845
- if (size) {
2846
- handleLayout(ctx, state, measured, setCanRender);
2847
- }
2848
- }
2849
- }
2850
- }, []);
3091
+ const { onLayout } = useSyncLayout({
3092
+ onLayout: onLayoutProp,
3093
+ onLayoutChange: useCallback(
3094
+ (rectangle) => {
3095
+ handleLayout(ctx, state, rectangle, setCanRender);
3096
+ },
3097
+ [ctx, state, setCanRender]
3098
+ ),
3099
+ ref: refScroller
3100
+ });
2851
3101
  useLayoutEffect(initializeStateVars, [
2852
3102
  memoizedLastItemKeys.join(","),
2853
3103
  numColumnsProp,
@@ -2857,27 +3107,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2857
3107
  const doInitialAllocateContainersCallback = () => {
2858
3108
  return doInitialAllocateContainers(ctx, state);
2859
3109
  };
2860
- useEffect(() => {
2861
- const viewability = setupViewability({
2862
- onViewableItemsChanged,
2863
- viewabilityConfig,
2864
- viewabilityConfigCallbackPairs
2865
- });
2866
- state.viewabilityConfigCallbackPairs = viewability;
2867
- state.enableScrollForNextCalculateItemsInView = !viewability;
2868
- }, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
2869
- if (!IsNewArchitecture) {
2870
- useInit(() => {
2871
- doInitialAllocateContainersCallback();
2872
- });
2873
- }
2874
- const onLayout = useCallback((event) => {
2875
- const layout = event.nativeEvent.layout;
2876
- handleLayout(ctx, state, layout, setCanRender);
2877
- if (onLayoutProp) {
2878
- onLayoutProp(event);
2879
- }
2880
- }, []);
2881
3110
  useImperativeHandle(forwardedRef, () => {
2882
3111
  const scrollIndexIntoView = (options) => {
2883
3112
  const state2 = refState.current;
@@ -2895,10 +3124,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2895
3124
  }
2896
3125
  };
2897
3126
  return {
2898
- flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
3127
+ flashScrollIndicators: () => {
3128
+ var _a, _b;
3129
+ return (_b = (_a = refScroller.current) == null ? void 0 : _a.flashScrollIndicators) == null ? void 0 : _b.call(_a);
3130
+ },
2899
3131
  getNativeScrollRef: () => refScroller.current,
2900
- getScrollableNode: () => refScroller.current.getScrollableNode(),
2901
- getScrollResponder: () => refScroller.current.getScrollResponder(),
3132
+ getScrollableNode: () => refScroller.current,
3133
+ getScrollResponder: () => refScroller.current,
2902
3134
  getState: () => {
2903
3135
  const state2 = refState.current;
2904
3136
  return state2 ? {
@@ -2959,7 +3191,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2959
3191
  }
2960
3192
  };
2961
3193
  }, []);
2962
- if (Platform.OS === "web") {
3194
+ {
2963
3195
  useEffect(() => {
2964
3196
  if (initialContentOffset) {
2965
3197
  scrollTo(state, { animated: false, offset: initialContentOffset });
@@ -2974,18 +3206,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2974
3206
  }),
2975
3207
  []
2976
3208
  );
2977
- const onScrollHandler = useMemo(() => {
2978
- const onScrollFn = fns.onScroll;
2979
- if (stickyIndices == null ? void 0 : stickyIndices.length) {
2980
- const { animatedScrollY } = ctx;
2981
- return Animated.event([{ nativeEvent: { contentOffset: { [horizontal ? "x" : "y"]: animatedScrollY } } }], {
2982
- listener: onScrollFn,
2983
- useNativeDriver: true
2984
- });
2985
- }
2986
- return onScrollFn;
2987
- }, [stickyIndices == null ? void 0 : stickyIndices.length, horizontal, scrollEventThrottle]);
2988
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(
3209
+ const onScrollHandler = useStickyScrollHandler(stickyIndices, horizontal, ctx, fns.onScroll);
3210
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(
2989
3211
  ListComponent,
2990
3212
  {
2991
3213
  ...rest,
@@ -3001,14 +3223,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3001
3223
  onLayout,
3002
3224
  onLayoutHeader,
3003
3225
  onMomentumScrollEnd: (event) => {
3004
- if (IsNewArchitecture) {
3226
+ {
3005
3227
  requestAnimationFrame(() => {
3006
3228
  finishScrollTo(refState.current);
3007
3229
  });
3008
- } else {
3009
- setTimeout(() => {
3010
- finishScrollTo(refState.current);
3011
- }, 1e3);
3012
3230
  }
3013
3231
  if (onMomentumScrollEnd) {
3014
3232
  onMomentumScrollEnd(event);
@@ -3016,9 +3234,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3016
3234
  },
3017
3235
  onScroll: onScrollHandler,
3018
3236
  recycleItems,
3019
- refreshControl: refreshControl ? stylePaddingTopState > 0 ? React3.cloneElement(refreshControl, {
3237
+ refreshControl: refreshControl ? stylePaddingTopState > 0 ? React4.cloneElement(refreshControl, {
3020
3238
  progressViewOffset: (refreshControl.props.progressViewOffset || 0) + stylePaddingTopState
3021
- }) : refreshControl : onRefresh && /* @__PURE__ */ React3.createElement(
3239
+ }) : refreshControl : onRefresh && /* @__PURE__ */ React4.createElement(
3022
3240
  RefreshControl,
3023
3241
  {
3024
3242
  onRefresh,
@@ -3027,15 +3245,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3027
3245
  }
3028
3246
  ),
3029
3247
  refScrollView: combinedRef,
3030
- scrollAdjustHandler: (_a = refState.current) == null ? void 0 : _a.scrollAdjustHandler,
3031
- scrollEventThrottle: Platform.OS === "web" ? 16 : void 0,
3248
+ scrollAdjustHandler: state.scrollAdjustHandler,
3032
3249
  snapToIndices,
3033
3250
  stickyIndices,
3034
3251
  style,
3035
3252
  updateItemSize: fns.updateItemSize,
3036
3253
  waitForInitialLayout
3037
3254
  }
3038
- ), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React3.createElement(DebugView, { state: refState.current }));
3255
+ ), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React4.createElement(DebugView, { state: refState.current }));
3039
3256
  });
3040
3257
 
3041
- export { LegendList, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useSyncLayout, useViewability, useViewabilityAmount };
3258
+ export { LegendList, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useSyncLayout2 as useSyncLayout, useViewability, useViewabilityAmount };