@legendapp/list 2.0.13 → 2.1.0-beta.1

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.
Files changed (5) hide show
  1. package/index.d.mts +14 -6
  2. package/index.d.ts +14 -6
  3. package/index.js +753 -455
  4. package/index.mjs +700 -402
  5. package/package.json +6 -3
package/index.mjs CHANGED
@@ -1,13 +1,25 @@
1
- import * as React2 from 'react';
2
- import React2__default, { useReducer, useEffect, createContext, useRef, useState, useMemo, useCallback, useLayoutEffect, useImperativeHandle, forwardRef, memo, useContext } from 'react';
3
- import { View, Text, Platform, Animated, StyleSheet, Dimensions, RefreshControl, unstable_batchedUpdates } from 'react-native';
1
+ import * as React3 from 'react';
2
+ import React3__default, { forwardRef, useReducer, useEffect, createContext, useRef, useState, useMemo, useCallback, useImperativeHandle, 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 = React2.createContext(null);
7
+ forwardRef(function AnimatedView2(props, ref) {
8
+ return /* @__PURE__ */ React3.createElement("div", { ref, ...props });
9
+ });
10
+ var View = forwardRef(function View2(props, ref) {
11
+ return /* @__PURE__ */ React3.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 = React3.createContext(null);
8
20
  function StateProvider({ children }) {
9
- const [value] = React2.useState(() => ({
10
- animatedScrollY: new Animated.Value(0),
21
+ const [value] = React3.useState(() => ({
22
+ animatedScrollY: createAnimatedValue(0),
11
23
  columnWrapperStyle: void 0,
12
24
  internalState: void 0,
13
25
  listeners: /* @__PURE__ */ new Map(),
@@ -25,10 +37,10 @@ function StateProvider({ children }) {
25
37
  ]),
26
38
  viewRefs: /* @__PURE__ */ new Map()
27
39
  }));
28
- return /* @__PURE__ */ React2.createElement(ContextState.Provider, { value }, children);
40
+ return /* @__PURE__ */ React3.createElement(ContextState.Provider, { value }, children);
29
41
  }
30
42
  function useStateContext() {
31
- return React2.useContext(ContextState);
43
+ return React3.useContext(ContextState);
32
44
  }
33
45
  function createSelectorFunctionsArr(ctx, signalNames) {
34
46
  let lastValues = [];
@@ -98,23 +110,23 @@ function getContentSize(ctx) {
98
110
  return headerSize + footerSize + totalSize + stylePaddingTop;
99
111
  }
100
112
  function useArr$(signalNames) {
101
- const ctx = React2.useContext(ContextState);
102
- const { subscribe, get } = React2.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
113
+ const ctx = React3.useContext(ContextState);
114
+ const { subscribe, get } = React3.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
103
115
  const value = useSyncExternalStore(subscribe, get);
104
116
  return value;
105
117
  }
106
118
  function useSelector$(signalName, selector) {
107
- const ctx = React2.useContext(ContextState);
108
- const { subscribe, get } = React2.useMemo(() => createSelectorFunctionsArr(ctx, [signalName]), [ctx, signalName]);
119
+ const ctx = React3.useContext(ContextState);
120
+ const { subscribe, get } = React3.useMemo(() => createSelectorFunctionsArr(ctx, [signalName]), [ctx, signalName]);
109
121
  const value = useSyncExternalStore(subscribe, () => selector(get()[0]));
110
122
  return value;
111
123
  }
112
124
 
113
125
  // src/components/DebugView.tsx
114
126
  var DebugRow = ({ children }) => {
115
- return /* @__PURE__ */ React2.createElement(View, { style: { alignItems: "center", flexDirection: "row", justifyContent: "space-between" } }, children);
127
+ return /* @__PURE__ */ React3.createElement(View, { style: { alignItems: "center", flexDirection: "row", justifyContent: "space-between" } }, children);
116
128
  };
117
- var DebugView = React2.memo(function DebugView2({ state }) {
129
+ var DebugView = React3.memo(function DebugView2({ state }) {
118
130
  const ctx = useStateContext();
119
131
  const [totalSize = 0, scrollAdjust = 0, rawScroll = 0, scroll = 0, _numContainers = 0, _numContainersPooled = 0] = useArr$([
120
132
  "totalSize",
@@ -129,7 +141,7 @@ var DebugView = React2.memo(function DebugView2({ state }) {
129
141
  useInterval(() => {
130
142
  forceUpdate();
131
143
  }, 100);
132
- return /* @__PURE__ */ React2.createElement(
144
+ return /* @__PURE__ */ React3.createElement(
133
145
  View,
134
146
  {
135
147
  pointerEvents: "none",
@@ -145,14 +157,12 @@ var DebugView = React2.memo(function DebugView2({ state }) {
145
157
  top: 0
146
158
  }
147
159
  },
148
- /* @__PURE__ */ React2.createElement(DebugRow, null, /* @__PURE__ */ React2.createElement(Text, null, "TotalSize:"), /* @__PURE__ */ React2.createElement(Text, null, totalSize.toFixed(2))),
149
- /* @__PURE__ */ React2.createElement(DebugRow, null, /* @__PURE__ */ React2.createElement(Text, null, "ContentSize:"), /* @__PURE__ */ React2.createElement(Text, null, contentSize.toFixed(2))),
150
- /* @__PURE__ */ React2.createElement(DebugRow, null, /* @__PURE__ */ React2.createElement(Text, null, "At end:"), /* @__PURE__ */ React2.createElement(Text, null, String(state.isAtEnd))),
151
- /* @__PURE__ */ React2.createElement(Text, null),
152
- /* @__PURE__ */ React2.createElement(DebugRow, null, /* @__PURE__ */ React2.createElement(Text, null, "ScrollAdjust:"), /* @__PURE__ */ React2.createElement(Text, null, scrollAdjust.toFixed(2))),
153
- /* @__PURE__ */ React2.createElement(Text, null),
154
- /* @__PURE__ */ React2.createElement(DebugRow, null, /* @__PURE__ */ React2.createElement(Text, null, "RawScroll: "), /* @__PURE__ */ React2.createElement(Text, null, rawScroll.toFixed(2))),
155
- /* @__PURE__ */ React2.createElement(DebugRow, null, /* @__PURE__ */ React2.createElement(Text, null, "ComputedScroll: "), /* @__PURE__ */ React2.createElement(Text, null, scroll.toFixed(2)))
160
+ /* @__PURE__ */ React3.createElement(DebugRow, null, /* @__PURE__ */ React3.createElement(Text, null, "TotalSize:"), /* @__PURE__ */ React3.createElement(Text, null, totalSize.toFixed(2))),
161
+ /* @__PURE__ */ React3.createElement(DebugRow, null, /* @__PURE__ */ React3.createElement(Text, null, "ContentSize:"), /* @__PURE__ */ React3.createElement(Text, null, contentSize.toFixed(2))),
162
+ /* @__PURE__ */ React3.createElement(DebugRow, null, /* @__PURE__ */ React3.createElement(Text, null, "At end:"), /* @__PURE__ */ React3.createElement(Text, null, String(state.isAtEnd))),
163
+ /* @__PURE__ */ React3.createElement(DebugRow, null, /* @__PURE__ */ React3.createElement(Text, null, "ScrollAdjust:"), /* @__PURE__ */ React3.createElement(Text, null, scrollAdjust.toFixed(2))),
164
+ /* @__PURE__ */ React3.createElement(DebugRow, null, /* @__PURE__ */ React3.createElement(Text, null, "RawScroll: "), /* @__PURE__ */ React3.createElement(Text, null, rawScroll.toFixed(2))),
165
+ /* @__PURE__ */ React3.createElement(DebugRow, null, /* @__PURE__ */ React3.createElement(Text, null, "ComputedScroll: "), /* @__PURE__ */ React3.createElement(Text, null, scroll.toFixed(2)))
156
166
  );
157
167
  });
158
168
  function useInterval(callback, delay) {
@@ -162,53 +172,18 @@ function useInterval(callback, delay) {
162
172
  }, [delay]);
163
173
  }
164
174
 
175
+ // src/utils/devEnvironment.ts
176
+ var metroDev = typeof __DEV__ !== "undefined" ? __DEV__ : void 0;
177
+ var _a;
178
+ var envMode = typeof process !== "undefined" && typeof process.env === "object" && process.env ? (_a = process.env.NODE_ENV) != null ? _a : process.env.MODE : void 0;
179
+ var processDev = typeof envMode === "string" ? envMode.toLowerCase() !== "production" : void 0;
180
+ var _a2;
181
+ var IS_DEV = (_a2 = metroDev != null ? metroDev : processDev) != null ? _a2 : false;
182
+
165
183
  // src/constants.ts
166
184
  var POSITION_OUT_OF_VIEW = -1e7;
167
- var ENABLE_DEVMODE = __DEV__ && false;
168
- var ENABLE_DEBUG_VIEW = __DEV__ && false;
169
- var IsNewArchitecture = global.nativeFabricUIManager != null;
170
- var useAnimatedValue = (initialValue) => {
171
- return useRef(new Animated.Value(initialValue)).current;
172
- };
173
-
174
- // src/hooks/useValue$.ts
175
- function useValue$(key, params) {
176
- var _a;
177
- const { getValue, delay } = params || {};
178
- const ctx = useStateContext();
179
- const animValue = useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
180
- useMemo(() => {
181
- let newValue;
182
- let prevValue;
183
- let didQueueTask = false;
184
- listen$(ctx, key, (v) => {
185
- newValue = getValue ? getValue(v) : v;
186
- if (delay !== void 0) {
187
- const fn = () => {
188
- didQueueTask = false;
189
- if (newValue !== void 0) {
190
- animValue.setValue(newValue);
191
- }
192
- };
193
- const delayValue = typeof delay === "function" ? delay(newValue, prevValue) : delay;
194
- prevValue = newValue;
195
- if (!didQueueTask) {
196
- didQueueTask = true;
197
- if (delayValue === void 0) {
198
- fn();
199
- } else if (delayValue === 0) {
200
- queueMicrotask(fn);
201
- } else {
202
- setTimeout(fn, delayValue);
203
- }
204
- }
205
- } else {
206
- animValue.setValue(newValue);
207
- }
208
- });
209
- }, []);
210
- return animValue;
211
- }
185
+ var ENABLE_DEVMODE = IS_DEV && false;
186
+ var ENABLE_DEBUG_VIEW = IS_DEV && false;
212
187
  var typedForwardRef = forwardRef;
213
188
  var typedMemo = memo;
214
189
 
@@ -221,61 +196,34 @@ var PositionViewState = typedMemo(function PositionView({
221
196
  ...rest
222
197
  }) {
223
198
  const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
224
- return /* @__PURE__ */ React2.createElement(
225
- View,
226
- {
227
- ref: refView,
228
- style: [
229
- style,
230
- horizontal ? { transform: [{ translateX: position }] } : { transform: [{ translateY: position }] }
231
- ],
232
- ...rest
233
- }
234
- );
235
- });
236
- var PositionViewAnimated = typedMemo(function PositionView2({
237
- id,
238
- horizontal,
239
- style,
240
- refView,
241
- ...rest
242
- }) {
243
- const position$ = useValue$(`containerPosition${id}`, {
244
- getValue: (v) => v != null ? v : POSITION_OUT_OF_VIEW
245
- });
246
- let position;
247
- if (Platform.OS === "ios" || Platform.OS === "android") {
248
- position = horizontal ? { transform: [{ translateX: position$ }] } : { transform: [{ translateY: position$ }] };
249
- } else {
250
- position = horizontal ? { left: position$ } : { top: position$ };
251
- }
252
- return /* @__PURE__ */ React2.createElement(Animated.View, { ref: refView, style: [style, position], ...rest });
199
+ const base = Array.isArray(style) ? Object.assign({}, ...style) : style;
200
+ const combinedStyle = horizontal ? { ...base, left: position } : { ...base, top: position };
201
+ return /* @__PURE__ */ React3.createElement("div", { ref: refView, style: combinedStyle, ...rest });
253
202
  });
254
203
  var PositionViewSticky = typedMemo(function PositionViewSticky2({
255
204
  id,
256
205
  horizontal,
257
206
  style,
258
207
  refView,
259
- animatedScrollY,
260
- stickyOffset,
261
208
  index,
262
209
  ...rest
263
210
  }) {
264
- const [position = POSITION_OUT_OF_VIEW, headerSize] = useArr$([`containerPosition${id}`, "headerSize"]);
265
- const transform = React2.useMemo(() => {
266
- if (animatedScrollY && stickyOffset !== void 0) {
267
- const stickyPosition = animatedScrollY.interpolate({
268
- extrapolate: "clamp",
269
- inputRange: [position + headerSize, position + 5e3 + headerSize],
270
- outputRange: [position, position + 5e3]
271
- });
272
- return horizontal ? [{ translateX: stickyPosition }] : [{ translateY: stickyPosition }];
273
- }
274
- }, [animatedScrollY, headerSize, horizontal, stickyOffset, position]);
275
- const viewStyle = React2.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
276
- return /* @__PURE__ */ React2.createElement(Animated.View, { ref: refView, style: viewStyle, ...rest });
211
+ const [position = POSITION_OUT_OF_VIEW, _headerSize] = useArr$([`containerPosition${id}`, "headerSize"]);
212
+ const viewStyle = React3.useMemo(() => {
213
+ const base = Array.isArray(style) ? Object.assign({}, ...style) : style;
214
+ const axisStyle = horizontal ? { transform: `translateX(${position}px)` } : { top: position };
215
+ return {
216
+ ...base,
217
+ zIndex: index + 1e3,
218
+ ...axisStyle
219
+ };
220
+ }, [style, position, horizontal, index]);
221
+ return /* @__PURE__ */ React3.createElement("div", { ref: refView, style: viewStyle, ...rest });
277
222
  });
278
- var PositionView3 = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
223
+ var PositionView2 = PositionViewState;
224
+
225
+ // src/constants-platform.ts
226
+ var IsNewArchitecture = true;
279
227
  var symbolFirst = Symbol();
280
228
  function useInit(cb) {
281
229
  const refValue = useRef(symbolFirst);
@@ -294,7 +242,7 @@ function isArray(obj) {
294
242
  }
295
243
  var warned = /* @__PURE__ */ new Set();
296
244
  function warnDevOnce(id, text) {
297
- if (__DEV__ && !warned.has(id)) {
245
+ if (IS_DEV && !warned.has(id)) {
298
246
  warned.add(id);
299
247
  console.warn(`[legend-list] ${text}`);
300
248
  }
@@ -309,8 +257,8 @@ function comparatorDefault(a, b) {
309
257
  return a - b;
310
258
  }
311
259
  function getPadding(s, type) {
312
- var _a, _b, _c;
313
- return (_c = (_b = (_a = s[`padding${type}`]) != null ? _a : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
260
+ var _a3, _b, _c;
261
+ return (_c = (_b = (_a3 = s[`padding${type}`]) != null ? _a3 : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
314
262
  }
315
263
  function extractPadding(style, contentContainerStyle, type) {
316
264
  return getPadding(style, type) + getPadding(contentContainerStyle, type);
@@ -412,44 +360,101 @@ function useListScrollSize() {
412
360
  const [scrollSize] = useArr$(["scrollSize"]);
413
361
  return scrollSize;
414
362
  }
415
- var noop = () => {
416
- };
417
363
  function useSyncLayout() {
418
- if (IsNewArchitecture) {
364
+ {
419
365
  const { triggerLayout: syncLayout } = useContext(ContextContainer);
420
366
  return syncLayout;
421
- } else {
422
- return noop;
423
367
  }
424
368
  }
425
369
 
426
370
  // src/components/Separator.tsx
427
371
  function Separator({ ItemSeparatorComponent, leadingItem }) {
428
372
  const isLastItem = useIsLastItem();
429
- return isLastItem ? null : /* @__PURE__ */ React2.createElement(ItemSeparatorComponent, { leadingItem });
373
+ return isLastItem ? null : /* @__PURE__ */ React3.createElement(ItemSeparatorComponent, { leadingItem });
374
+ }
375
+
376
+ // src/hooks/createResizeObserver.ts
377
+ var globalResizeObserver = null;
378
+ function getGlobalResizeObserver() {
379
+ if (!globalResizeObserver) {
380
+ globalResizeObserver = new ResizeObserver((entries) => {
381
+ for (const entry of entries) {
382
+ const callbacks = callbackMap.get(entry.target);
383
+ if (callbacks) {
384
+ for (const callback of callbacks) {
385
+ callback(entry);
386
+ }
387
+ }
388
+ }
389
+ });
390
+ }
391
+ return globalResizeObserver;
430
392
  }
393
+ var callbackMap = /* @__PURE__ */ new WeakMap();
394
+ function createResizeObserver(element, callback) {
395
+ if (!element) {
396
+ return () => {
397
+ };
398
+ }
399
+ const observer = getGlobalResizeObserver();
400
+ let callbacks = callbackMap.get(element);
401
+ if (!callbacks) {
402
+ callbacks = /* @__PURE__ */ new Set();
403
+ callbackMap.set(element, callbacks);
404
+ observer.observe(element);
405
+ }
406
+ callbacks.add(callback);
407
+ return () => {
408
+ const callbacks2 = callbackMap.get(element);
409
+ if (callbacks2) {
410
+ callbacks2.delete(callback);
411
+ if (callbacks2.size === 0) {
412
+ callbackMap.delete(element);
413
+ observer.unobserve(element);
414
+ }
415
+ }
416
+ };
417
+ }
418
+
419
+ // src/hooks/useOnLayoutSync.tsx
431
420
  function useOnLayoutSync({
432
421
  ref,
433
422
  onLayoutProp,
434
423
  onLayoutChange
435
- }, deps = []) {
436
- const onLayout = useCallback(
437
- (event) => {
438
- onLayoutChange(event.nativeEvent.layout, false);
439
- onLayoutProp == null ? void 0 : onLayoutProp(event);
440
- },
441
- [onLayoutChange]
442
- );
443
- if (IsNewArchitecture) {
444
- useLayoutEffect(() => {
445
- if (ref.current) {
446
- ref.current.measure((x, y, width, height) => {
447
- onLayoutChange({ height, width, x, y }, true);
448
- });
424
+ }, deps) {
425
+ useLayoutEffect(() => {
426
+ var _a3, _b;
427
+ const current = ref.current;
428
+ const scrollableNode = (_b = (_a3 = current == null ? void 0 : current.getScrollableNode) == null ? void 0 : _a3.call(current)) != null ? _b : null;
429
+ const element = scrollableNode || current;
430
+ if (!element || !(element instanceof HTMLElement)) {
431
+ return;
432
+ }
433
+ const emit = (layout, fromLayoutEffect) => {
434
+ if (layout.height === 0 && layout.width === 0) {
435
+ return;
449
436
  }
450
- }, deps);
451
- }
452
- return { onLayout };
437
+ onLayoutChange(layout, fromLayoutEffect);
438
+ onLayoutProp == null ? void 0 : onLayoutProp({ nativeEvent: { layout } });
439
+ };
440
+ const rect = element.getBoundingClientRect();
441
+ emit(toLayout(rect), true);
442
+ return createResizeObserver(element, (entry) => {
443
+ var _a4;
444
+ const target = entry.target instanceof HTMLElement ? entry.target : void 0;
445
+ const rect2 = (_a4 = entry.contentRect) != null ? _a4 : target == null ? void 0 : target.getBoundingClientRect();
446
+ emit(toLayout(rect2), false);
447
+ });
448
+ }, deps);
449
+ return {};
450
+ }
451
+ function toLayout(rect) {
452
+ return {
453
+ height: rect.height,
454
+ width: rect.width,
455
+ x: rect.left,
456
+ y: rect.top
457
+ };
453
458
  }
454
459
 
455
460
  // src/components/Container.tsx
@@ -472,7 +477,14 @@ var Container = typedMemo(function Container2({
472
477
  `containerSticky${id}`,
473
478
  `containerStickyOffset${id}`
474
479
  ]);
475
- const refLastSize = useRef();
480
+ const itemLayoutRef = useRef({
481
+ horizontal,
482
+ itemKey,
483
+ updateItemSize: updateItemSize2
484
+ });
485
+ itemLayoutRef.current.horizontal = horizontal;
486
+ itemLayoutRef.current.itemKey = itemKey;
487
+ itemLayoutRef.current.updateItemSize = updateItemSize2;
476
488
  const ref = useRef(null);
477
489
  const [layoutRenderCount, forceLayoutRender] = useState(0);
478
490
  const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
@@ -527,27 +539,27 @@ var Container = typedMemo(function Container2({
527
539
  value: data
528
540
  };
529
541
  }, [id, itemKey, index, data]);
530
- const onLayoutChange = (rectangle) => {
531
- var _a, _b;
532
- if (!isNullOrUndefined(itemKey)) {
542
+ const onLayoutChange = useCallback((rectangle) => {
543
+ const {
544
+ horizontal: currentHorizontal,
545
+ itemKey: currentItemKey,
546
+ updateItemSize: updateItemSizeFn
547
+ } = itemLayoutRef.current;
548
+ if (isNullOrUndefined(currentItemKey)) {
549
+ return;
550
+ }
551
+ didLayoutRef.current = true;
552
+ let layout = rectangle;
553
+ Math.floor(rectangle[currentHorizontal ? "width" : "height"] * 8) / 8;
554
+ const doUpdate = () => {
555
+ itemLayoutRef.current.lastSize = { height: layout.height, width: layout.width };
556
+ updateItemSizeFn(currentItemKey, layout);
533
557
  didLayoutRef.current = true;
534
- let layout = rectangle;
535
- const size = Math.floor(rectangle[horizontal ? "width" : "height"] * 8) / 8;
536
- const doUpdate = () => {
537
- refLastSize.current = { height: layout.height, width: layout.width };
538
- updateItemSize2(itemKey, layout);
539
- didLayoutRef.current = true;
540
- };
541
- if (IsNewArchitecture || size > 0) {
542
- doUpdate();
543
- } else {
544
- (_b = (_a = ref.current) == null ? void 0 : _a.measure) == null ? void 0 : _b.call(_a, (_x, _y, width, height) => {
545
- layout = { height, width };
546
- doUpdate();
547
- });
548
- }
558
+ };
559
+ {
560
+ doUpdate();
549
561
  }
550
- };
562
+ }, []);
551
563
  const { onLayout } = useOnLayoutSync(
552
564
  {
553
565
  onLayoutChange,
@@ -555,23 +567,8 @@ var Container = typedMemo(function Container2({
555
567
  },
556
568
  [itemKey, layoutRenderCount]
557
569
  );
558
- if (!IsNewArchitecture) {
559
- useEffect(() => {
560
- if (!isNullOrUndefined(itemKey)) {
561
- const timeout = setTimeout(() => {
562
- if (!didLayoutRef.current && refLastSize.current) {
563
- updateItemSize2(itemKey, refLastSize.current);
564
- didLayoutRef.current = true;
565
- }
566
- }, 16);
567
- return () => {
568
- clearTimeout(timeout);
569
- };
570
- }
571
- }, [itemKey]);
572
- }
573
- const PositionComponent = isSticky ? PositionViewSticky : PositionView3;
574
- return /* @__PURE__ */ React2.createElement(
570
+ const PositionComponent = isSticky ? PositionViewSticky : PositionView2;
571
+ return /* @__PURE__ */ React3.createElement(
575
572
  PositionComponent,
576
573
  {
577
574
  animatedScrollY: isSticky ? animatedScrollY : void 0,
@@ -584,11 +581,156 @@ var Container = typedMemo(function Container2({
584
581
  stickyOffset: isSticky ? stickyOffset : void 0,
585
582
  style
586
583
  },
587
- /* @__PURE__ */ React2.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React2.createElement(Separator, { ItemSeparatorComponent, leadingItem: renderedItemInfo.item }))
584
+ /* @__PURE__ */ React3.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React3.createElement(Separator, { ItemSeparatorComponent, leadingItem: renderedItemInfo.item }))
588
585
  );
589
586
  });
590
587
 
588
+ // src/platform/Platform.ts
589
+ var Platform = {
590
+ // Widen the type to avoid unreachable-branch lints in cross-platform code that compares against other OSes
591
+ OS: "web"
592
+ };
593
+
594
+ // src/utils/reordering.ts
595
+ var mapFn = (element) => {
596
+ const indexStr = element.getAttribute("index");
597
+ return [element, indexStr === null ? null : parseInt(indexStr)];
598
+ };
599
+ function sortDOMElements(container) {
600
+ const elements = Array.from(container.children);
601
+ if (elements.length <= 1) return elements;
602
+ const items = elements.map(mapFn);
603
+ items.sort((a, b) => {
604
+ const aKey = a[1];
605
+ const bKey = b[1];
606
+ if (aKey === null) {
607
+ return 1;
608
+ }
609
+ if (bKey === null) {
610
+ return -1;
611
+ }
612
+ return aKey - bKey;
613
+ });
614
+ const targetPositions = /* @__PURE__ */ new Map();
615
+ items.forEach((item, index) => {
616
+ targetPositions.set(item[0], index);
617
+ });
618
+ const currentPositions = elements.map((el) => targetPositions.get(el));
619
+ const lis = findLIS(currentPositions);
620
+ const stableIndices = new Set(lis);
621
+ for (let targetPos = 0; targetPos < items.length; targetPos++) {
622
+ const element = items[targetPos][0];
623
+ const currentPos = elements.indexOf(element);
624
+ if (!stableIndices.has(currentPos)) {
625
+ let nextStableElement = null;
626
+ for (let i = targetPos + 1; i < items.length; i++) {
627
+ const nextEl = items[i][0];
628
+ const nextCurrentPos = elements.indexOf(nextEl);
629
+ if (stableIndices.has(nextCurrentPos)) {
630
+ nextStableElement = nextEl;
631
+ break;
632
+ }
633
+ }
634
+ if (nextStableElement) {
635
+ container.insertBefore(element, nextStableElement);
636
+ } else {
637
+ container.appendChild(element);
638
+ }
639
+ }
640
+ }
641
+ }
642
+ function findLIS(arr) {
643
+ const n = arr.length;
644
+ const tails = [];
645
+ const predecessors = new Array(n).fill(-1);
646
+ const indices = [];
647
+ for (let i = 0; i < n; i++) {
648
+ const num = arr[i];
649
+ let left = 0, right = tails.length;
650
+ while (left < right) {
651
+ const mid = Math.floor((left + right) / 2);
652
+ if (arr[indices[mid]] < num) {
653
+ left = mid + 1;
654
+ } else {
655
+ right = mid;
656
+ }
657
+ }
658
+ if (left === tails.length) {
659
+ tails.push(num);
660
+ indices.push(i);
661
+ } else {
662
+ tails[left] = num;
663
+ indices[left] = i;
664
+ }
665
+ if (left > 0) {
666
+ predecessors[i] = indices[left - 1];
667
+ }
668
+ }
669
+ const result = [];
670
+ let k = indices[indices.length - 1];
671
+ while (k !== -1) {
672
+ result.unshift(k);
673
+ k = predecessors[k];
674
+ }
675
+ return result;
676
+ }
677
+
678
+ // src/hooks/useDOMOrder.ts
679
+ function useDOMOrder(ref) {
680
+ const ctx = useStateContext();
681
+ const debounceRef = useRef(void 0);
682
+ useEffect(() => {
683
+ const unsubscribe = listen$(ctx, "lastPositionUpdate", () => {
684
+ if (debounceRef.current !== void 0) {
685
+ clearTimeout(debounceRef.current);
686
+ }
687
+ debounceRef.current = setTimeout(() => {
688
+ const parent = ref.current;
689
+ if (parent) {
690
+ sortDOMElements(parent);
691
+ }
692
+ debounceRef.current = void 0;
693
+ }, 500);
694
+ });
695
+ return () => {
696
+ unsubscribe();
697
+ if (debounceRef.current !== void 0) {
698
+ clearTimeout(debounceRef.current);
699
+ }
700
+ };
701
+ }, [ctx]);
702
+ }
703
+
591
704
  // src/components/Containers.tsx
705
+ var ContainersInner = typedMemo(function ContainersInner2({ horizontal, numColumns, children }) {
706
+ const ref = useRef(null);
707
+ const ctx = useStateContext();
708
+ const columnWrapperStyle = ctx.columnWrapperStyle;
709
+ const [totalSize, otherAxisSize] = useArr$(["totalSize", "otherAxisSize"]);
710
+ useDOMOrder(ref);
711
+ const style = horizontal ? { minHeight: otherAxisSize, width: totalSize } : { height: totalSize, minWidth: otherAxisSize };
712
+ if (columnWrapperStyle && numColumns > 1) {
713
+ const { columnGap, rowGap, gap } = columnWrapperStyle;
714
+ const gapX = columnGap || gap || 0;
715
+ const gapY = rowGap || gap || 0;
716
+ if (horizontal) {
717
+ if (gapY) {
718
+ style.marginTop = style.marginBottom = -gapY / 2;
719
+ }
720
+ if (gapX) {
721
+ style.marginRight = -gapX;
722
+ }
723
+ } else {
724
+ if (gapX) {
725
+ style.marginLeft = style.marginRight = -gapX;
726
+ }
727
+ if (gapY) {
728
+ style.marginBottom = -gapY;
729
+ }
730
+ }
731
+ }
732
+ return /* @__PURE__ */ React3.createElement("div", { ref, style }, children);
733
+ });
592
734
  var Containers = typedMemo(function Containers2({
593
735
  horizontal,
594
736
  recycleItems,
@@ -597,23 +739,11 @@ var Containers = typedMemo(function Containers2({
597
739
  updateItemSize: updateItemSize2,
598
740
  getRenderedItem: getRenderedItem2
599
741
  }) {
600
- const ctx = useStateContext();
601
- const columnWrapperStyle = ctx.columnWrapperStyle;
602
742
  const [numContainers, numColumns] = useArr$(["numContainersPooled", "numColumns"]);
603
- const animSize = useValue$("totalSize", {
604
- // Use a microtask if increasing the size significantly, otherwise use a timeout
605
- // If this is the initial scroll, we don't want to delay because we want to update the size immediately
606
- delay: (value, prevValue) => {
607
- var _a;
608
- return !((_a = ctx.internalState) == null ? void 0 : _a.initialScroll) ? !prevValue || value - prevValue > 20 ? 0 : 200 : void 0;
609
- }
610
- });
611
- const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("containersDidLayout", { getValue: (value) => value ? 1 : 0 }) : void 0;
612
- const otherAxisSize = useValue$("otherAxisSize", { delay: 0 });
613
743
  const containers = [];
614
744
  for (let i = 0; i < numContainers; i++) {
615
745
  containers.push(
616
- /* @__PURE__ */ React2.createElement(
746
+ /* @__PURE__ */ React3.createElement(
617
747
  Container,
618
748
  {
619
749
  getRenderedItem: getRenderedItem2,
@@ -627,86 +757,268 @@ var Containers = typedMemo(function Containers2({
627
757
  )
628
758
  );
629
759
  }
630
- const style = horizontal ? { minHeight: otherAxisSize, opacity: animOpacity, width: animSize } : { height: animSize, minWidth: otherAxisSize, opacity: animOpacity };
631
- if (columnWrapperStyle && numColumns > 1) {
632
- const { columnGap, rowGap, gap } = columnWrapperStyle;
633
- const gapX = columnGap || gap || 0;
634
- const gapY = rowGap || gap || 0;
635
- if (horizontal) {
636
- if (gapY) {
637
- style.marginVertical = -gapY / 2;
760
+ return /* @__PURE__ */ React3.createElement(ContainersInner, { horizontal, numColumns, waitForInitialLayout }, containers);
761
+ });
762
+ function DevNumbers() {
763
+ return IS_DEV && React3.memo(function DevNumbers2() {
764
+ return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React3.createElement(
765
+ "div",
766
+ {
767
+ key: index,
768
+ style: {
769
+ height: 100,
770
+ pointerEvents: "none",
771
+ position: "absolute",
772
+ top: index * 100,
773
+ width: "100%"
774
+ }
775
+ },
776
+ /* @__PURE__ */ React3.createElement("div", { style: { color: "red" } }, index * 100)
777
+ ));
778
+ });
779
+ }
780
+
781
+ // src/platform/StyleSheet.tsx
782
+ function flattenStyles(styles) {
783
+ if (Array.isArray(styles)) {
784
+ return Object.assign({}, ...styles.filter(Boolean));
785
+ }
786
+ return styles;
787
+ }
788
+ var StyleSheet = {
789
+ create: (styles) => styles,
790
+ flatten: (style) => flattenStyles(style)
791
+ };
792
+
793
+ // src/components/ListComponentScrollView.tsx
794
+ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
795
+ children,
796
+ style,
797
+ contentContainerStyle,
798
+ horizontal = false,
799
+ contentOffset,
800
+ maintainVisibleContentPosition,
801
+ onScroll: onScroll2,
802
+ onMomentumScrollEnd,
803
+ showsHorizontalScrollIndicator = true,
804
+ showsVerticalScrollIndicator = true,
805
+ refreshControl,
806
+ onLayout,
807
+ ...props
808
+ }, ref) {
809
+ const scrollRef = useRef(null);
810
+ const contentRef = useRef(null);
811
+ const momentumTimeout = useRef(null);
812
+ useImperativeHandle(ref, () => {
813
+ const api = {
814
+ getBoundingClientRect: () => {
815
+ var _a3;
816
+ return (_a3 = scrollRef.current) == null ? void 0 : _a3.getBoundingClientRect();
817
+ },
818
+ getScrollableNode: () => scrollRef.current,
819
+ getScrollResponder: () => scrollRef.current,
820
+ scrollBy: (x, y) => {
821
+ const el = scrollRef.current;
822
+ if (!el) return;
823
+ el.scrollBy(x, y);
824
+ },
825
+ scrollTo: (options) => {
826
+ const el = scrollRef.current;
827
+ if (!el) return;
828
+ const { x = 0, y = 0, animated = true } = options;
829
+ el.scrollTo({ behavior: animated ? "smooth" : "auto", left: x, top: y });
830
+ },
831
+ scrollToEnd: (options = {}) => {
832
+ const el = scrollRef.current;
833
+ if (!el) return;
834
+ const { animated = true } = options;
835
+ if (horizontal) {
836
+ el.scrollTo({ behavior: animated ? "smooth" : "auto", left: el.scrollWidth });
837
+ } else {
838
+ el.scrollTo({ behavior: animated ? "smooth" : "auto", top: el.scrollHeight });
839
+ }
840
+ },
841
+ scrollToOffset: (params) => {
842
+ const el = scrollRef.current;
843
+ if (!el) return;
844
+ const { offset, animated = true } = params;
845
+ if (horizontal) {
846
+ el.scrollTo({ behavior: animated ? "smooth" : "auto", left: offset });
847
+ } else {
848
+ el.scrollTo({ behavior: animated ? "smooth" : "auto", top: offset });
849
+ }
638
850
  }
639
- if (gapX) {
640
- style.marginRight = -gapX;
851
+ };
852
+ return api;
853
+ }, [horizontal]);
854
+ const handleScroll = useCallback(
855
+ (event) => {
856
+ if (!onScroll2 || !(event == null ? void 0 : event.target)) {
857
+ return;
641
858
  }
642
- } else {
643
- if (gapX) {
644
- style.marginHorizontal = -gapX;
859
+ const target = event.target;
860
+ const scrollEvent = {
861
+ nativeEvent: {
862
+ contentOffset: {
863
+ x: target.scrollLeft,
864
+ y: target.scrollTop
865
+ },
866
+ contentSize: {
867
+ height: target.scrollHeight,
868
+ width: target.scrollWidth
869
+ },
870
+ layoutMeasurement: {
871
+ height: target.clientHeight,
872
+ width: target.clientWidth
873
+ }
874
+ }
875
+ };
876
+ onScroll2(scrollEvent);
877
+ if (onMomentumScrollEnd) {
878
+ if (momentumTimeout.current != null) clearTimeout(momentumTimeout.current);
879
+ momentumTimeout.current = setTimeout(() => {
880
+ onMomentumScrollEnd({
881
+ nativeEvent: {
882
+ contentOffset: scrollEvent.nativeEvent.contentOffset
883
+ }
884
+ });
885
+ }, 100);
645
886
  }
646
- if (gapY) {
647
- style.marginBottom = -gapY;
887
+ },
888
+ [onScroll2, onMomentumScrollEnd]
889
+ );
890
+ useLayoutEffect(() => {
891
+ const element = scrollRef.current;
892
+ if (!element) return;
893
+ element.addEventListener("scroll", handleScroll);
894
+ return () => {
895
+ element.removeEventListener("scroll", handleScroll);
896
+ };
897
+ }, [handleScroll]);
898
+ useEffect(() => {
899
+ const doScroll = () => {
900
+ if (contentOffset && scrollRef.current) {
901
+ scrollRef.current.scrollLeft = contentOffset.x || 0;
902
+ scrollRef.current.scrollTop = contentOffset.y || 0;
648
903
  }
649
- }
650
- }
651
- return /* @__PURE__ */ React2.createElement(Animated.View, { style }, containers);
904
+ };
905
+ doScroll();
906
+ requestAnimationFrame(doScroll);
907
+ }, [contentOffset == null ? void 0 : contentOffset.x, contentOffset == null ? void 0 : contentOffset.y]);
908
+ useLayoutEffect(() => {
909
+ if (!onLayout || !scrollRef.current) return;
910
+ const element = scrollRef.current;
911
+ const fireLayout = () => {
912
+ const rect = element.getBoundingClientRect();
913
+ onLayout({
914
+ nativeEvent: {
915
+ layout: {
916
+ height: rect.height,
917
+ width: rect.width,
918
+ x: rect.left,
919
+ y: rect.top
920
+ }
921
+ }
922
+ });
923
+ };
924
+ fireLayout();
925
+ const resizeObserver = new ResizeObserver(() => {
926
+ fireLayout();
927
+ });
928
+ resizeObserver.observe(element);
929
+ return () => resizeObserver.disconnect();
930
+ }, [onLayout]);
931
+ const scrollViewStyle = {
932
+ overflow: "auto",
933
+ overflowX: horizontal ? "auto" : showsHorizontalScrollIndicator ? "auto" : "hidden",
934
+ overflowY: horizontal ? showsVerticalScrollIndicator ? "auto" : "hidden" : "auto",
935
+ position: "relative",
936
+ // Ensure proper positioning context
937
+ WebkitOverflowScrolling: "touch",
938
+ // iOS momentum scrolling
939
+ ...StyleSheet.flatten(style)
940
+ };
941
+ const contentStyle = {
942
+ display: horizontal ? "flex" : "block",
943
+ flexDirection: horizontal ? "row" : void 0,
944
+ minHeight: horizontal ? void 0 : "100%",
945
+ minWidth: horizontal ? "100%" : void 0,
946
+ ...StyleSheet.flatten(contentContainerStyle)
947
+ };
948
+ return /* @__PURE__ */ React3.createElement("div", { ref: scrollRef, style: scrollViewStyle, ...props }, refreshControl, /* @__PURE__ */ React3.createElement("div", { ref: contentRef, style: contentStyle }, children));
652
949
  });
653
- var LayoutView = ({ onLayoutChange, refView, ...rest }) => {
654
- const ref = refView != null ? refView : useRef();
655
- const { onLayout } = useOnLayoutSync({ onLayoutChange, ref });
656
- return /* @__PURE__ */ React2.createElement(View, { ...rest, onLayout, ref });
657
- };
658
- function ScrollAdjust() {
659
- const bias = 1e7;
660
- const [scrollAdjust, scrollAdjustUserOffset] = useArr$(["scrollAdjust", "scrollAdjustUserOffset"]);
661
- const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0) + bias;
662
- return /* @__PURE__ */ React2.createElement(
663
- View,
950
+ function Padding() {
951
+ const [paddingTop] = useArr$(["alignItemsPaddingTop"]);
952
+ return /* @__PURE__ */ React3.createElement("div", { style: { paddingTop } });
953
+ }
954
+ function PaddingDevMode() {
955
+ const [paddingTop] = useArr$(["alignItemsPaddingTop"]);
956
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("div", { style: { paddingTop } }), /* @__PURE__ */ React3.createElement(
957
+ "div",
664
958
  {
665
959
  style: {
666
- height: 0,
960
+ backgroundColor: "green",
961
+ height: paddingTop,
667
962
  left: 0,
668
963
  position: "absolute",
669
- top: scrollOffset,
670
- width: 0
964
+ right: 0,
965
+ top: 0
671
966
  }
672
967
  }
673
- );
968
+ ));
969
+ }
970
+ function useValueListener$(key, callback) {
971
+ const ctx = useStateContext();
972
+ useLayoutEffect(() => {
973
+ listen$(ctx, key, (value) => {
974
+ callback(value);
975
+ });
976
+ }, []);
977
+ }
978
+
979
+ // src/components/ScrollAdjust.tsx
980
+ function ScrollAdjust() {
981
+ const ctx = useStateContext();
982
+ const lastScrollOffsetRef = React3.useRef(0);
983
+ const callback = React3.useCallback(() => {
984
+ var _a3;
985
+ const scrollAdjust = peek$(ctx, "scrollAdjust");
986
+ const scrollAdjustUserOffset = peek$(ctx, "scrollAdjustUserOffset");
987
+ const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0);
988
+ const scrollView = (_a3 = ctx.internalState) == null ? void 0 : _a3.refScroller.current;
989
+ if (scrollView && scrollOffset !== lastScrollOffsetRef.current) {
990
+ const scrollDelta = scrollOffset - lastScrollOffsetRef.current;
991
+ if (scrollDelta !== 0) {
992
+ scrollView.scrollBy(0, scrollDelta);
993
+ console.log("ScrollAdjust (web scrollBy)", scrollDelta, "total offset:", scrollOffset);
994
+ }
995
+ lastScrollOffsetRef.current = scrollOffset;
996
+ }
997
+ }, []);
998
+ useValueListener$("scrollAdjust", callback);
999
+ useValueListener$("scrollAdjustUserOffset", callback);
1000
+ return null;
674
1001
  }
675
1002
  function SnapWrapper({ ScrollComponent, ...props }) {
676
1003
  const [snapToOffsets] = useArr$(["snapToOffsets"]);
677
- return /* @__PURE__ */ React2.createElement(ScrollComponent, { ...props, snapToOffsets });
1004
+ return /* @__PURE__ */ React3.createElement(ScrollComponent, { ...props, snapToOffsets });
678
1005
  }
1006
+ var LayoutView = ({ onLayoutChange, refView, children, ...rest }) => {
1007
+ const ref = refView != null ? refView : useRef();
1008
+ useOnLayoutSync({ onLayoutChange, ref });
1009
+ return /* @__PURE__ */ React3.createElement("div", { ...rest, ref }, children);
1010
+ };
679
1011
 
680
1012
  // src/components/ListComponent.tsx
681
1013
  var getComponent = (Component) => {
682
- if (React2.isValidElement(Component)) {
1014
+ if (React3.isValidElement(Component)) {
683
1015
  return Component;
684
1016
  }
685
1017
  if (Component) {
686
- return /* @__PURE__ */ React2.createElement(Component, null);
1018
+ return /* @__PURE__ */ React3.createElement(Component, null);
687
1019
  }
688
1020
  return null;
689
1021
  };
690
- var Padding = () => {
691
- const animPaddingTop = useValue$("alignItemsPaddingTop", { delay: 0 });
692
- return /* @__PURE__ */ React2.createElement(Animated.View, { style: { paddingTop: animPaddingTop } });
693
- };
694
- var PaddingDevMode = () => {
695
- const animPaddingTop = useValue$("alignItemsPaddingTop", { delay: 0 });
696
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Animated.View, { style: { paddingTop: animPaddingTop } }), /* @__PURE__ */ React2.createElement(
697
- Animated.View,
698
- {
699
- style: {
700
- backgroundColor: "green",
701
- height: animPaddingTop,
702
- left: 0,
703
- position: "absolute",
704
- right: 0,
705
- top: 0
706
- }
707
- }
708
- ));
709
- };
710
1022
  var ListComponent = typedMemo(function ListComponent2({
711
1023
  canRender,
712
1024
  style,
@@ -737,10 +1049,10 @@ var ListComponent = typedMemo(function ListComponent2({
737
1049
  }) {
738
1050
  const ctx = useStateContext();
739
1051
  const ScrollComponent = renderScrollComponent ? useMemo(
740
- () => React2.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
1052
+ () => React3.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
741
1053
  [renderScrollComponent]
742
- ) : Animated.ScrollView;
743
- React2.useEffect(() => {
1054
+ ) : ListComponentScrollView;
1055
+ React3.useEffect(() => {
744
1056
  if (canRender) {
745
1057
  setTimeout(() => {
746
1058
  scrollAdjustHandler.setMounted();
@@ -748,7 +1060,7 @@ var ListComponent = typedMemo(function ListComponent2({
748
1060
  }
749
1061
  }, [canRender]);
750
1062
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
751
- return /* @__PURE__ */ React2.createElement(
1063
+ return /* @__PURE__ */ React3.createElement(
752
1064
  SnapOrScroll,
753
1065
  {
754
1066
  ...rest,
@@ -767,11 +1079,11 @@ var ListComponent = typedMemo(function ListComponent2({
767
1079
  ScrollComponent: snapToIndices ? ScrollComponent : void 0,
768
1080
  style
769
1081
  },
770
- maintainVisibleContentPosition && /* @__PURE__ */ React2.createElement(ScrollAdjust, null),
771
- ENABLE_DEVMODE ? /* @__PURE__ */ React2.createElement(PaddingDevMode, null) : /* @__PURE__ */ React2.createElement(Padding, null),
772
- ListHeaderComponent && /* @__PURE__ */ React2.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
1082
+ maintainVisibleContentPosition && /* @__PURE__ */ React3.createElement(ScrollAdjust, null),
1083
+ ENABLE_DEVMODE ? /* @__PURE__ */ React3.createElement(PaddingDevMode, null) : /* @__PURE__ */ React3.createElement(Padding, null),
1084
+ ListHeaderComponent && /* @__PURE__ */ React3.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
773
1085
  ListEmptyComponent && getComponent(ListEmptyComponent),
774
- canRender && !ListEmptyComponent && /* @__PURE__ */ React2.createElement(
1086
+ canRender && !ListEmptyComponent && /* @__PURE__ */ React3.createElement(
775
1087
  Containers,
776
1088
  {
777
1089
  getRenderedItem: getRenderedItem2,
@@ -782,7 +1094,7 @@ var ListComponent = typedMemo(function ListComponent2({
782
1094
  waitForInitialLayout
783
1095
  }
784
1096
  ),
785
- ListFooterComponent && /* @__PURE__ */ React2.createElement(
1097
+ ListFooterComponent && /* @__PURE__ */ React3.createElement(
786
1098
  LayoutView,
787
1099
  {
788
1100
  onLayoutChange: (layout) => {
@@ -793,25 +1105,9 @@ var ListComponent = typedMemo(function ListComponent2({
793
1105
  },
794
1106
  getComponent(ListFooterComponent)
795
1107
  ),
796
- __DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React2.createElement(DevNumbers, null)
1108
+ IS_DEV && ENABLE_DEVMODE && /* @__PURE__ */ React3.createElement(DevNumbers, null)
797
1109
  );
798
1110
  });
799
- var DevNumbers = __DEV__ && React2.memo(function DevNumbers2() {
800
- return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React2.createElement(
801
- View,
802
- {
803
- key: index,
804
- style: {
805
- height: 100,
806
- pointerEvents: "none",
807
- position: "absolute",
808
- top: index * 100,
809
- width: "100%"
810
- }
811
- },
812
- /* @__PURE__ */ React2.createElement(Text, { style: { color: "red" } }, index * 100)
813
- ));
814
- });
815
1111
 
816
1112
  // src/utils/getId.ts
817
1113
  function getId(state, index) {
@@ -844,7 +1140,7 @@ function calculateOffsetForIndex(ctx, state, index) {
844
1140
 
845
1141
  // src/utils/getItemSize.ts
846
1142
  function getItemSize(state, key, index, data, useAverageSize) {
847
- var _a, _b;
1143
+ var _a3, _b;
848
1144
  const {
849
1145
  sizesKnown,
850
1146
  sizes,
@@ -857,7 +1153,7 @@ function getItemSize(state, key, index, data, useAverageSize) {
857
1153
  return sizeKnown;
858
1154
  }
859
1155
  let size;
860
- const itemType = getItemType ? (_a = getItemType(data, index)) != null ? _a : "" : "";
1156
+ const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
861
1157
  if (getFixedItemSize) {
862
1158
  size = getFixedItemSize(index, data, itemType);
863
1159
  if (size !== void 0) {
@@ -906,7 +1202,7 @@ var finishScrollTo = (state) => {
906
1202
 
907
1203
  // src/core/scrollTo.ts
908
1204
  function scrollTo(state, params = {}) {
909
- var _a;
1205
+ var _a3;
910
1206
  const { animated, noScrollingTo, isInitialScroll } = params;
911
1207
  const {
912
1208
  refScroller,
@@ -919,7 +1215,7 @@ function scrollTo(state, params = {}) {
919
1215
  }
920
1216
  state.scrollPending = offset;
921
1217
  if (!params.isInitialScroll || Platform.OS === "android") {
922
- (_a = refScroller.current) == null ? void 0 : _a.scrollTo({
1218
+ (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
923
1219
  animated: !!animated,
924
1220
  x: horizontal ? offset : 0,
925
1221
  y: horizontal ? 0 : offset
@@ -939,14 +1235,8 @@ function scrollTo(state, params = {}) {
939
1235
  // src/utils/requestAdjust.ts
940
1236
  function requestAdjust(ctx, state, positionDiff, dataChanged) {
941
1237
  if (Math.abs(positionDiff) > 0.1) {
942
- const needsScrollWorkaround = Platform.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff;
943
1238
  const doit = () => {
944
- if (needsScrollWorkaround) {
945
- scrollTo(state, {
946
- noScrollingTo: true,
947
- offset: state.scroll
948
- });
949
- } else {
1239
+ {
950
1240
  state.scrollAdjustHandler.requestAdjust(positionDiff);
951
1241
  }
952
1242
  };
@@ -971,7 +1261,7 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
971
1261
  () => {
972
1262
  state.ignoreScrollFromMVCP = void 0;
973
1263
  },
974
- needsScrollWorkaround ? 250 : 100
1264
+ 100
975
1265
  );
976
1266
  } else {
977
1267
  requestAnimationFrame(doit);
@@ -1040,14 +1330,14 @@ function prepareMVCP(ctx, state, dataChanged) {
1040
1330
  }
1041
1331
  }
1042
1332
  if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
1043
- requestAdjust(ctx, state, positionDiff, dataChanged);
1333
+ requestAdjust(ctx, state, positionDiff);
1044
1334
  }
1045
1335
  };
1046
1336
  }
1047
1337
 
1048
1338
  // src/core/prepareColumnStartState.ts
1049
1339
  function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1050
- var _a;
1340
+ var _a3;
1051
1341
  const numColumns = peek$(ctx, "numColumns");
1052
1342
  let rowStartIndex = startIndex;
1053
1343
  const columnAtStart = state.columns.get(state.idCache[startIndex]);
@@ -1060,7 +1350,7 @@ function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1060
1350
  if (rowStartIndex > 0) {
1061
1351
  const prevIndex = rowStartIndex - 1;
1062
1352
  const prevId = state.idCache[prevIndex];
1063
- const prevPosition = (_a = state.positions.get(prevId)) != null ? _a : 0;
1353
+ const prevPosition = (_a3 = state.positions.get(prevId)) != null ? _a3 : 0;
1064
1354
  const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
1065
1355
  const prevRowHeight = calculateRowMaxSize(state, prevRowStart, prevIndex, useAverageSize);
1066
1356
  currentRowTop = prevPosition + prevRowHeight;
@@ -1201,7 +1491,7 @@ function updateSnapToOffsets(ctx, state) {
1201
1491
 
1202
1492
  // src/core/updateItemPositions.ts
1203
1493
  function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottomBuffered } = { scrollBottomBuffered: -1, startIndex: 0 }) {
1204
- var _a, _b, _c, _d;
1494
+ var _a3, _b, _c, _d;
1205
1495
  const {
1206
1496
  columns,
1207
1497
  indexByKey,
@@ -1214,7 +1504,7 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1214
1504
  const dataLength = data.length;
1215
1505
  const numColumns = peek$(ctx, "numColumns");
1216
1506
  const hasColumns = numColumns > 1;
1217
- const indexByKeyForChecking = __DEV__ ? /* @__PURE__ */ new Map() : void 0;
1507
+ const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
1218
1508
  const maxVisibleArea = scrollBottomBuffered + 1e3;
1219
1509
  const useAverageSize = enableAverages && !getEstimatedItemSize;
1220
1510
  let currentRowTop = 0;
@@ -1233,7 +1523,7 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1233
1523
  } else if (startIndex < dataLength) {
1234
1524
  const prevIndex = startIndex - 1;
1235
1525
  const prevId = getId(state, prevIndex);
1236
- const prevPosition = (_a = positions.get(prevId)) != null ? _a : 0;
1526
+ const prevPosition = (_a3 = positions.get(prevId)) != null ? _a3 : 0;
1237
1527
  const prevSize = (_b = sizesKnown.get(prevId)) != null ? _b : getItemSize(state, prevId, prevIndex, data[prevIndex], useAverageSize);
1238
1528
  currentRowTop = prevPosition + prevSize;
1239
1529
  }
@@ -1252,7 +1542,7 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1252
1542
  }
1253
1543
  const id = (_c = idCache[i]) != null ? _c : getId(state, i);
1254
1544
  const size = (_d = sizesKnown.get(id)) != null ? _d : getItemSize(state, id, i, data[i], useAverageSize);
1255
- if (__DEV__ && needsIndexByKey) {
1545
+ if (IS_DEV && needsIndexByKey) {
1256
1546
  if (indexByKeyForChecking.has(id)) {
1257
1547
  console.error(
1258
1548
  `[legend-list] Error: Detected overlapping key (${id}) which causes missing items and gaps and other terrrible things. Check that keyExtractor returns unique values.`
@@ -1485,7 +1775,6 @@ function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
1485
1775
  const cb = ctx.mapViewabilityCallbacks.get(key);
1486
1776
  cb == null ? void 0 : cb(viewToken);
1487
1777
  }
1488
- var batchedUpdates = unstable_batchedUpdates || ((callback) => callback());
1489
1778
 
1490
1779
  // src/utils/checkAllSizesKnown.ts
1491
1780
  function isNullOrUndefined2(value) {
@@ -1598,7 +1887,7 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1598
1887
  for (let i = 0; i < stillNeeded; i++) {
1599
1888
  result.push(numContainers + i);
1600
1889
  }
1601
- if (__DEV__ && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
1890
+ if (IS_DEV && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
1602
1891
  console.warn(
1603
1892
  "[legend-list] No unused container available, so creating one on demand. This can be a minor performance issue and is likely caused by the estimatedItemSize being too large. Consider decreasing estimatedItemSize or increasing initialContainerPoolRatio.",
1604
1893
  {
@@ -1686,28 +1975,44 @@ function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, vie
1686
1975
  }
1687
1976
 
1688
1977
  // src/utils/checkThreshold.ts
1689
- var checkThreshold = (distance, atThreshold, threshold, isReached, isBlockedByTimer, onReached, blockTimer) => {
1690
- const distanceAbs = Math.abs(distance);
1691
- const isAtThreshold = atThreshold || distanceAbs < threshold;
1692
- if (!isReached && !isBlockedByTimer) {
1693
- if (isAtThreshold) {
1694
- onReached == null ? void 0 : onReached(distance);
1695
- blockTimer == null ? void 0 : blockTimer(true);
1696
- setTimeout(() => {
1697
- blockTimer == null ? void 0 : blockTimer(false);
1698
- }, 700);
1699
- return true;
1700
- }
1701
- } else {
1702
- if (distance >= 1.3 * threshold) {
1978
+ var HYSTERESIS_MULTIPLIER = 1.3;
1979
+ var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
1980
+ const absDistance = Math.abs(distance);
1981
+ const within = atThreshold || threshold > 0 && absDistance <= threshold;
1982
+ const updateSnapshot = () => {
1983
+ setSnapshot == null ? void 0 : setSnapshot({
1984
+ atThreshold,
1985
+ contentSize: context.contentSize,
1986
+ dataLength: context.dataLength,
1987
+ scrollPosition: context.scrollPosition
1988
+ });
1989
+ };
1990
+ if (!wasReached) {
1991
+ if (!within) {
1703
1992
  return false;
1704
1993
  }
1994
+ onReached == null ? void 0 : onReached(distance);
1995
+ updateSnapshot();
1996
+ return true;
1997
+ }
1998
+ const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
1999
+ if (reset) {
2000
+ setSnapshot == null ? void 0 : setSnapshot(void 0);
2001
+ return false;
2002
+ }
2003
+ if (within) {
2004
+ const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
2005
+ if (changed) {
2006
+ onReached == null ? void 0 : onReached(distance);
2007
+ updateSnapshot();
2008
+ }
1705
2009
  }
1706
- return isReached;
2010
+ return true;
1707
2011
  };
1708
2012
 
1709
2013
  // src/utils/checkAtBottom.ts
1710
2014
  function checkAtBottom(ctx, state) {
2015
+ var _a3;
1711
2016
  if (!state) {
1712
2017
  return;
1713
2018
  }
@@ -1728,13 +2033,18 @@ function checkAtBottom(ctx, state) {
1728
2033
  isContentLess,
1729
2034
  onEndReachedThreshold * scrollLength,
1730
2035
  state.isEndReached,
1731
- state.endReachedBlockedByTimer,
2036
+ state.endReachedSnapshot,
2037
+ {
2038
+ scrollPosition: scroll,
2039
+ contentSize,
2040
+ dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length
2041
+ },
1732
2042
  (distance) => {
1733
- var _a, _b;
1734
- return (_b = (_a = state.props).onEndReached) == null ? void 0 : _b.call(_a, { distanceFromEnd: distance });
2043
+ var _a4, _b;
2044
+ return (_b = (_a4 = state.props).onEndReached) == null ? void 0 : _b.call(_a4, { distanceFromEnd: distance });
1735
2045
  },
1736
- (block) => {
1737
- state.endReachedBlockedByTimer = block;
2046
+ (snapshot) => {
2047
+ state.endReachedSnapshot = snapshot;
1738
2048
  }
1739
2049
  );
1740
2050
  }
@@ -1755,30 +2065,19 @@ function setDidLayout(ctx, state) {
1755
2065
  onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
1756
2066
  }
1757
2067
  };
1758
- if (Platform.OS === "android" && initialScroll) {
1759
- if (IsNewArchitecture) {
1760
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
1761
- requestAnimationFrame(() => {
1762
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
1763
- setIt();
1764
- });
1765
- } else {
1766
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
1767
- setIt();
1768
- }
1769
- } else {
2068
+ {
1770
2069
  setIt();
1771
2070
  }
1772
2071
  }
1773
2072
 
1774
2073
  // src/core/calculateItemsInView.ts
1775
2074
  function findCurrentStickyIndex(stickyArray, scroll, state) {
1776
- var _a;
2075
+ var _a3;
1777
2076
  const idCache = state.idCache;
1778
2077
  const positions = state.positions;
1779
2078
  for (let i = stickyArray.length - 1; i >= 0; i--) {
1780
2079
  const stickyIndex = stickyArray[i];
1781
- const stickyId = (_a = idCache[stickyIndex]) != null ? _a : getId(state, stickyIndex);
2080
+ const stickyId = (_a3 = idCache[stickyIndex]) != null ? _a3 : getId(state, stickyIndex);
1782
2081
  const stickyPos = stickyId ? positions.get(stickyId) : void 0;
1783
2082
  if (stickyPos !== void 0 && scroll >= stickyPos) {
1784
2083
  return i;
@@ -1792,21 +2091,21 @@ function getActiveStickyIndices(ctx, state, stickyIndices) {
1792
2091
  );
1793
2092
  }
1794
2093
  function handleStickyActivation(ctx, state, stickyIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
1795
- var _a;
2094
+ var _a3;
1796
2095
  const activeIndices = getActiveStickyIndices(ctx, state, stickyIndices);
1797
2096
  state.activeStickyIndex = currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : void 0;
1798
2097
  for (let offset = 0; offset <= 1; offset++) {
1799
2098
  const idx = currentStickyIdx - offset;
1800
2099
  if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
1801
2100
  const stickyIndex = stickyArray[idx];
1802
- const stickyId = (_a = state.idCache[stickyIndex]) != null ? _a : getId(state, stickyIndex);
2101
+ const stickyId = (_a3 = state.idCache[stickyIndex]) != null ? _a3 : getId(state, stickyIndex);
1803
2102
  if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered)) {
1804
2103
  needNewContainers.push(stickyIndex);
1805
2104
  }
1806
2105
  }
1807
2106
  }
1808
2107
  function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
1809
- var _a, _b, _c;
2108
+ var _a3, _b, _c;
1810
2109
  for (const containerIndex of state.stickyContainerPool) {
1811
2110
  const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
1812
2111
  const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
@@ -1823,7 +2122,7 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
1823
2122
  const nextIndex = stickyArray[arrayIdx + 1];
1824
2123
  let shouldRecycle = false;
1825
2124
  if (nextIndex) {
1826
- const nextId = (_a = state.idCache[nextIndex]) != null ? _a : getId(state, nextIndex);
2125
+ const nextId = (_a3 = state.idCache[nextIndex]) != null ? _a3 : getId(state, nextIndex);
1827
2126
  const nextPos = nextId ? state.positions.get(nextId) : void 0;
1828
2127
  shouldRecycle = nextPos !== void 0 && scroll > nextPos + scrollBuffer * 2;
1829
2128
  } else {
@@ -1840,8 +2139,8 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
1840
2139
  }
1841
2140
  }
1842
2141
  function calculateItemsInView(ctx, state, params = {}) {
1843
- batchedUpdates(() => {
1844
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2142
+ unstable_batchedUpdates(() => {
2143
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i;
1845
2144
  const {
1846
2145
  columns,
1847
2146
  containerItemKeys,
@@ -1917,7 +2216,7 @@ function calculateItemsInView(ctx, state, params = {}) {
1917
2216
  idCache.length = 0;
1918
2217
  positions.clear();
1919
2218
  }
1920
- const startIndex = dataChanged ? 0 : (_a = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _a : 0;
2219
+ const startIndex = dataChanged ? 0 : (_a3 = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _a3 : 0;
1921
2220
  updateItemPositions(ctx, state, dataChanged, { scrollBottomBuffered, startIndex });
1922
2221
  if (minIndexSizeChanged !== void 0) {
1923
2222
  state.minIndexSizeChanged = void 0;
@@ -2092,6 +2391,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2092
2391
  if (stickyIndicesArr.length > 0) {
2093
2392
  handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2094
2393
  }
2394
+ let didChangePositions = false;
2095
2395
  for (let i = 0; i < numContainers; i++) {
2096
2396
  const itemKey = peek$(ctx, `containerItemKey${i}`);
2097
2397
  if (pendingRemoval.includes(i)) {
@@ -2123,6 +2423,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2123
2423
  const prevData = peek$(ctx, `containerItemData${i}`);
2124
2424
  if (position > POSITION_OUT_OF_VIEW && position !== prevPos) {
2125
2425
  set$(ctx, `containerPosition${i}`, position);
2426
+ didChangePositions = true;
2126
2427
  }
2127
2428
  if (column >= 0 && column !== prevColumn) {
2128
2429
  set$(ctx, `containerColumn${i}`, column);
@@ -2134,6 +2435,9 @@ function calculateItemsInView(ctx, state, params = {}) {
2134
2435
  }
2135
2436
  }
2136
2437
  }
2438
+ if (didChangePositions) {
2439
+ set$(ctx, "lastPositionUpdate", Date.now());
2440
+ }
2137
2441
  if (!queuedInitialLayout && endBuffered !== null) {
2138
2442
  if (checkAllSizesKnown(state)) {
2139
2443
  setDidLayout(ctx, state);
@@ -2163,10 +2467,10 @@ function doMaintainScrollAtEnd(ctx, state, animated) {
2163
2467
  state.scroll = 0;
2164
2468
  }
2165
2469
  requestAnimationFrame(() => {
2166
- var _a;
2470
+ var _a3;
2167
2471
  if (state == null ? void 0 : state.isAtEnd) {
2168
2472
  state.maintainingScrollAtEnd = true;
2169
- (_a = refScroller.current) == null ? void 0 : _a.scrollToEnd({
2473
+ (_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
2170
2474
  animated
2171
2475
  });
2172
2476
  setTimeout(
@@ -2183,6 +2487,7 @@ function doMaintainScrollAtEnd(ctx, state, animated) {
2183
2487
 
2184
2488
  // src/utils/checkAtTop.ts
2185
2489
  function checkAtTop(state) {
2490
+ var _a3;
2186
2491
  if (!state) {
2187
2492
  return;
2188
2493
  }
@@ -2198,20 +2503,25 @@ function checkAtTop(state) {
2198
2503
  false,
2199
2504
  onStartReachedThreshold * scrollLength,
2200
2505
  state.isStartReached,
2201
- state.startReachedBlockedByTimer,
2506
+ state.startReachedSnapshot,
2507
+ {
2508
+ scrollPosition: scroll,
2509
+ contentSize: state.totalSize,
2510
+ dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length
2511
+ },
2202
2512
  (distance) => {
2203
- var _a, _b;
2204
- return (_b = (_a = state.props).onStartReached) == null ? void 0 : _b.call(_a, { distanceFromStart: distance });
2513
+ var _a4, _b;
2514
+ return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
2205
2515
  },
2206
- (block) => {
2207
- state.startReachedBlockedByTimer = block;
2516
+ (snapshot) => {
2517
+ state.startReachedSnapshot = snapshot;
2208
2518
  }
2209
2519
  );
2210
2520
  }
2211
2521
 
2212
2522
  // src/utils/updateAveragesOnDataChange.ts
2213
2523
  function updateAveragesOnDataChange(state, oldData, newData) {
2214
- var _a;
2524
+ var _a3;
2215
2525
  const {
2216
2526
  averageSizes,
2217
2527
  sizesKnown,
@@ -2237,7 +2547,7 @@ function updateAveragesOnDataChange(state, oldData, newData) {
2237
2547
  const oldItem = oldData[oldIndex];
2238
2548
  const areEqual = itemsAreEqual(oldItem, newItem, newIndex, newData);
2239
2549
  if (areEqual) {
2240
- const itemType = getItemType ? (_a = getItemType(newItem, newIndex)) != null ? _a : "" : "";
2550
+ const itemType = getItemType ? (_a3 = getItemType(newItem, newIndex)) != null ? _a3 : "" : "";
2241
2551
  let typeData = itemTypesToPreserve[itemType];
2242
2552
  if (!typeData) {
2243
2553
  typeData = itemTypesToPreserve[itemType] = { count: 0, totalSize: 0 };
@@ -2285,7 +2595,7 @@ function checkResetContainers(ctx, state, isFirst, dataProp) {
2285
2595
 
2286
2596
  // src/core/doInitialAllocateContainers.ts
2287
2597
  function doInitialAllocateContainers(ctx, state) {
2288
- var _a, _b, _c;
2598
+ var _a3, _b, _c;
2289
2599
  const {
2290
2600
  scrollLength,
2291
2601
  props: {
@@ -2306,7 +2616,7 @@ function doInitialAllocateContainers(ctx, state) {
2306
2616
  const num = Math.min(20, data.length);
2307
2617
  for (let i = 0; i < num; i++) {
2308
2618
  const item = data[i];
2309
- const itemType = getItemType ? (_a = getItemType(item, i)) != null ? _a : "" : "";
2619
+ const itemType = getItemType ? (_a3 = getItemType(item, i)) != null ? _a3 : "" : "";
2310
2620
  totalSize += (_c = (_b = getFixedItemSize == null ? void 0 : getFixedItemSize(i, item, itemType)) != null ? _b : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(i, item, itemType)) != null ? _c : estimatedItemSize;
2311
2621
  }
2312
2622
  averageItemSize = totalSize / num;
@@ -2320,7 +2630,7 @@ function doInitialAllocateContainers(ctx, state) {
2320
2630
  }
2321
2631
  set$(ctx, "numContainers", numContainers);
2322
2632
  set$(ctx, "numContainersPooled", numContainers * state.props.initialContainerPoolRatio);
2323
- if (!IsNewArchitecture || state.lastLayout) {
2633
+ if (state.lastLayout) {
2324
2634
  if (state.props.initialScroll) {
2325
2635
  requestAnimationFrame(() => {
2326
2636
  calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
@@ -2367,7 +2677,7 @@ function handleLayout(ctx, state, layout, setCanRender) {
2367
2677
  if (state) {
2368
2678
  state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
2369
2679
  }
2370
- if (__DEV__ && measuredLength === 0) {
2680
+ if (IS_DEV && measuredLength === 0) {
2371
2681
  warnDevOnce(
2372
2682
  "height0",
2373
2683
  `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.`
@@ -2379,7 +2689,7 @@ function handleLayout(ctx, state, layout, setCanRender) {
2379
2689
 
2380
2690
  // src/core/onScroll.ts
2381
2691
  function onScroll(ctx, state, event) {
2382
- var _a, _b, _c;
2692
+ var _a3, _b, _c;
2383
2693
  const {
2384
2694
  scrollProcessingEnabled,
2385
2695
  props: { onScroll: onScrollProp }
@@ -2387,7 +2697,7 @@ function onScroll(ctx, state, event) {
2387
2697
  if (scrollProcessingEnabled === false) {
2388
2698
  return;
2389
2699
  }
2390
- if (((_b = (_a = event.nativeEvent) == null ? void 0 : _a.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
2700
+ if (((_b = (_a3 = event.nativeEvent) == null ? void 0 : _a3.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
2391
2701
  return;
2392
2702
  }
2393
2703
  const newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
@@ -2461,7 +2771,7 @@ var ScrollAdjustHandler = class {
2461
2771
 
2462
2772
  // src/core/updateItemSize.ts
2463
2773
  function updateItemSize(ctx, state, itemKey, sizeObj) {
2464
- var _a;
2774
+ var _a3;
2465
2775
  const {
2466
2776
  sizesKnown,
2467
2777
  props: {
@@ -2484,7 +2794,7 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2484
2794
  if (itemData === void 0) {
2485
2795
  return;
2486
2796
  }
2487
- const type = getItemType ? (_a = getItemType(itemData, index)) != null ? _a : "" : "";
2797
+ const type = getItemType ? (_a3 = getItemType(itemData, index)) != null ? _a3 : "" : "";
2488
2798
  const size2 = getFixedItemSize(index, itemData, type);
2489
2799
  if (size2 !== void 0 && size2 === sizesKnown.get(itemKey)) {
2490
2800
  return;
@@ -2530,13 +2840,13 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2530
2840
  if (minIndexSizeChanged !== void 0) {
2531
2841
  state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, minIndexSizeChanged) : minIndexSizeChanged;
2532
2842
  }
2533
- if (__DEV__ && suggestEstimatedItemSize && minIndexSizeChanged !== void 0) {
2843
+ if (IS_DEV && suggestEstimatedItemSize && minIndexSizeChanged !== void 0) {
2534
2844
  if (state.timeoutSizeMessage) clearTimeout(state.timeoutSizeMessage);
2535
2845
  state.timeoutSizeMessage = setTimeout(() => {
2536
- var _a2;
2846
+ var _a4;
2537
2847
  state.timeoutSizeMessage = void 0;
2538
2848
  const num = state.sizesKnown.size;
2539
- const avg = (_a2 = state.averageSizes[""]) == null ? void 0 : _a2.avg;
2849
+ const avg = (_a4 = state.averageSizes[""]) == null ? void 0 : _a4.avg;
2540
2850
  console.warn(
2541
2851
  `[legend-list] Based on the ${num} items rendered so far, the optimal estimated size is ${avg}.`
2542
2852
  );
@@ -2559,7 +2869,7 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2559
2869
  }
2560
2870
  }
2561
2871
  function updateOneItemSize(state, itemKey, sizeObj) {
2562
- var _a;
2872
+ var _a3;
2563
2873
  const {
2564
2874
  sizes,
2565
2875
  indexByKey,
@@ -2570,10 +2880,11 @@ function updateOneItemSize(state, itemKey, sizeObj) {
2570
2880
  if (!data) return 0;
2571
2881
  const index = indexByKey.get(itemKey);
2572
2882
  const prevSize = getItemSize(state, itemKey, index, data[index]);
2573
- const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
2883
+ const rawSize = horizontal ? sizeObj.width : sizeObj.height;
2884
+ const size = Math.round(rawSize) ;
2574
2885
  sizesKnown.set(itemKey, size);
2575
2886
  if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
2576
- const itemType = getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : "";
2887
+ const itemType = getItemType ? (_a3 = getItemType(data[index], index)) != null ? _a3 : "" : "";
2577
2888
  let averages = averageSizes[itemType];
2578
2889
  if (!averages) {
2579
2890
  averages = averageSizes[itemType] = { avg: 0, num: 0 };
@@ -2603,6 +2914,16 @@ var useCombinedRef = (...refs) => {
2603
2914
  return callback;
2604
2915
  };
2605
2916
 
2917
+ // src/platform/RefreshControl.tsx
2918
+ function RefreshControl(_props) {
2919
+ return null;
2920
+ }
2921
+
2922
+ // src/platform/useStickyScrollHandler.ts
2923
+ function useStickyScrollHandler(_stickyIndices, _horizontal, _ctx, onScroll2) {
2924
+ return onScroll2;
2925
+ }
2926
+
2606
2927
  // src/utils/createColumnWrapperStyle.ts
2607
2928
  function createColumnWrapperStyle(contentContainerStyle) {
2608
2929
  const { gap, columnGap, rowGap } = contentContainerStyle;
@@ -2618,7 +2939,7 @@ function createColumnWrapperStyle(contentContainerStyle) {
2618
2939
  }
2619
2940
  }
2620
2941
  function getRenderedItem(ctx, state, key) {
2621
- var _a;
2942
+ var _a3;
2622
2943
  if (!state) {
2623
2944
  return null;
2624
2945
  }
@@ -2639,9 +2960,9 @@ function getRenderedItem(ctx, state, key) {
2639
2960
  extraData,
2640
2961
  index,
2641
2962
  item,
2642
- type: getItemType ? (_a = getItemType(item, index)) != null ? _a : "" : ""
2963
+ type: getItemType ? (_a3 = getItemType(item, index)) != null ? _a3 : "" : ""
2643
2964
  };
2644
- renderedItem = isFunction(renderItem) ? renderItem(itemProps) : React2__default.createElement(renderItem, itemProps);
2965
+ renderedItem = isFunction(renderItem) ? renderItem(itemProps) : React3__default.createElement(renderItem, itemProps);
2645
2966
  }
2646
2967
  return { index, item: data[index], renderedItem };
2647
2968
  }
@@ -2700,18 +3021,18 @@ var LegendList = typedMemo(
2700
3021
  const isChildrenMode = children !== void 0 && dataProp === void 0;
2701
3022
  const processedProps = isChildrenMode ? {
2702
3023
  ...restProps,
2703
- data: (isArray(children) ? children : React2.Children.toArray(children)).flat(1),
3024
+ data: (isArray(children) ? children : React3.Children.toArray(children)).flat(1),
2704
3025
  renderItem: ({ item }) => item
2705
3026
  } : {
2706
3027
  ...restProps,
2707
3028
  data: dataProp || [],
2708
3029
  renderItem: renderItemProp
2709
3030
  };
2710
- return /* @__PURE__ */ React2.createElement(StateProvider, null, /* @__PURE__ */ React2.createElement(LegendListInner, { ...processedProps, ref: forwardedRef }));
3031
+ return /* @__PURE__ */ React3.createElement(StateProvider, null, /* @__PURE__ */ React3.createElement(LegendListInner, { ...processedProps, ref: forwardedRef }));
2711
3032
  })
2712
3033
  );
2713
3034
  var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
2714
- var _a;
3035
+ var _a3;
2715
3036
  const {
2716
3037
  alignItemsAtEnd = false,
2717
3038
  columnWrapperStyle,
@@ -2767,7 +3088,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2767
3088
  } = props;
2768
3089
  const [renderNum, setRenderNum] = useState(0);
2769
3090
  const initialScroll = initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
2770
- const [canRender, setCanRender] = React2.useState(!IsNewArchitecture);
3091
+ const [canRender, setCanRender] = React3.useState(!IsNewArchitecture);
2771
3092
  const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
2772
3093
  const style = { ...StyleSheet.flatten(styleProp) };
2773
3094
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
@@ -2782,7 +3103,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2782
3103
  const refState = useRef();
2783
3104
  if (!refState.current) {
2784
3105
  if (!ctx.internalState) {
2785
- const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { height: 0, width: 0 } : Dimensions.get("window"))[horizontal ? "width" : "height"];
3106
+ const initialScrollLength = (estimatedListSize != null ? estimatedListSize : { height: 0, width: 0 } )[horizontal ? "width" : "height"];
2786
3107
  ctx.internalState = {
2787
3108
  activeStickyIndex: void 0,
2788
3109
  averageSizes: {},
@@ -2793,7 +3114,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2793
3114
  enableScrollForNextCalculateItemsInView: true,
2794
3115
  endBuffered: -1,
2795
3116
  endNoBuffer: -1,
2796
- endReachedBlockedByTimer: false,
3117
+ endReachedSnapshot: void 0,
2797
3118
  firstFullyOnScreenIndex: -1,
2798
3119
  idCache: [],
2799
3120
  idsInView: [],
@@ -2826,7 +3147,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2826
3147
  sizesKnown: /* @__PURE__ */ new Map(),
2827
3148
  startBuffered: -1,
2828
3149
  startNoBuffer: -1,
2829
- startReachedBlockedByTimer: false,
3150
+ startReachedSnapshot: void 0,
2830
3151
  stickyContainerPool: /* @__PURE__ */ new Set(),
2831
3152
  stickyContainers: /* @__PURE__ */ new Map(),
2832
3153
  timeoutSizeMessage: 0,
@@ -2936,7 +3257,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2936
3257
  if (isFirst || didDataChange || numColumnsProp !== peek$(ctx, "numColumns")) {
2937
3258
  refState.current.lastBatchingAction = Date.now();
2938
3259
  if (!keyExtractorProp && !isFirst && didDataChange) {
2939
- __DEV__ && warnDevOnce(
3260
+ IS_DEV && warnDevOnce(
2940
3261
  "keyExtractor",
2941
3262
  "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."
2942
3263
  );
@@ -2948,14 +3269,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2948
3269
  const size = rect[horizontal ? "width" : "height"];
2949
3270
  set$(ctx, "headerSize", size);
2950
3271
  if ((initialScroll == null ? void 0 : initialScroll.index) !== void 0) {
2951
- if (IsNewArchitecture && Platform.OS !== "android") {
3272
+ {
2952
3273
  if (fromLayoutEffect) {
2953
3274
  setRenderNum((v) => v + 1);
2954
3275
  }
2955
- } else {
2956
- setTimeout(() => {
2957
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2958
- }, 17);
2959
3276
  }
2960
3277
  }
2961
3278
  }, []);
@@ -2994,11 +3311,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2994
3311
  state.viewabilityConfigCallbackPairs = viewability;
2995
3312
  state.enableScrollForNextCalculateItemsInView = !viewability;
2996
3313
  }, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
2997
- if (!IsNewArchitecture) {
2998
- useInit(() => {
2999
- doInitialAllocateContainers(ctx, state);
3000
- });
3001
- }
3002
3314
  const onLayoutChange = useCallback((layout) => {
3003
3315
  handleLayout(ctx, state, layout, setCanRender);
3004
3316
  }, []);
@@ -3090,10 +3402,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3090
3402
  }
3091
3403
  };
3092
3404
  }, []);
3093
- if (Platform.OS === "web") {
3405
+ {
3094
3406
  useEffect(() => {
3095
3407
  if (initialContentOffset) {
3096
- scrollTo(state, { animated: false, offset: initialContentOffset });
3408
+ scrollTo(state, { animated: false, offset: initialContentOffset, ...initialScroll || {} });
3097
3409
  }
3098
3410
  }, []);
3099
3411
  }
@@ -3105,18 +3417,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3105
3417
  }),
3106
3418
  []
3107
3419
  );
3108
- const onScrollHandler = useMemo(() => {
3109
- const onScrollFn = fns.onScroll;
3110
- if (stickyIndices == null ? void 0 : stickyIndices.length) {
3111
- const { animatedScrollY } = ctx;
3112
- return Animated.event([{ nativeEvent: { contentOffset: { [horizontal ? "x" : "y"]: animatedScrollY } } }], {
3113
- listener: onScrollFn,
3114
- useNativeDriver: true
3115
- });
3116
- }
3117
- return onScrollFn;
3118
- }, [stickyIndices == null ? void 0 : stickyIndices.length, horizontal, scrollEventThrottle]);
3119
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
3420
+ const onScrollHandler = useStickyScrollHandler(stickyIndices, horizontal, ctx, fns.onScroll);
3421
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(
3120
3422
  ListComponent,
3121
3423
  {
3122
3424
  ...rest,
@@ -3132,14 +3434,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3132
3434
  onLayout,
3133
3435
  onLayoutHeader,
3134
3436
  onMomentumScrollEnd: (event) => {
3135
- if (IsNewArchitecture) {
3437
+ {
3136
3438
  requestAnimationFrame(() => {
3137
3439
  finishScrollTo(refState.current);
3138
3440
  });
3139
- } else {
3140
- setTimeout(() => {
3141
- finishScrollTo(refState.current);
3142
- }, 1e3);
3143
3441
  }
3144
3442
  if (onMomentumScrollEnd) {
3145
3443
  onMomentumScrollEnd(event);
@@ -3147,9 +3445,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3147
3445
  },
3148
3446
  onScroll: onScrollHandler,
3149
3447
  recycleItems,
3150
- refreshControl: refreshControl ? stylePaddingTopState > 0 ? React2.cloneElement(refreshControl, {
3448
+ refreshControl: refreshControl ? stylePaddingTopState > 0 ? React3.cloneElement(refreshControl, {
3151
3449
  progressViewOffset: (refreshControl.props.progressViewOffset || 0) + stylePaddingTopState
3152
- }) : refreshControl : onRefresh && /* @__PURE__ */ React2.createElement(
3450
+ }) : refreshControl : onRefresh && /* @__PURE__ */ React3.createElement(
3153
3451
  RefreshControl,
3154
3452
  {
3155
3453
  onRefresh,
@@ -3158,15 +3456,15 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3158
3456
  }
3159
3457
  ),
3160
3458
  refScrollView: combinedRef,
3161
- scrollAdjustHandler: (_a = refState.current) == null ? void 0 : _a.scrollAdjustHandler,
3162
- scrollEventThrottle: Platform.OS === "web" ? 16 : void 0,
3459
+ scrollAdjustHandler: (_a3 = refState.current) == null ? void 0 : _a3.scrollAdjustHandler,
3460
+ scrollEventThrottle: 16 ,
3163
3461
  snapToIndices,
3164
3462
  stickyIndices,
3165
3463
  style,
3166
3464
  updateItemSize: fns.updateItemSize,
3167
3465
  waitForInitialLayout
3168
3466
  }
3169
- ), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React2.createElement(DebugView, { state: refState.current }));
3467
+ ), IS_DEV && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React3.createElement(DebugView, { state: refState.current }));
3170
3468
  });
3171
3469
 
3172
3470
  export { LegendList, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useSyncLayout, useViewability, useViewabilityAmount };