@legendapp/list 2.1.0-next.1 → 3.0.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.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React4 = require('react');
3
+ var React3 = require('react');
4
4
  var shim = require('use-sync-external-store/shim');
5
5
  var reactDom = require('react-dom');
6
6
 
@@ -22,14 +22,14 @@ function _interopNamespace(e) {
22
22
  return Object.freeze(n);
23
23
  }
24
24
 
25
- var React4__namespace = /*#__PURE__*/_interopNamespace(React4);
25
+ var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
26
26
 
27
27
  // src/components/LegendList.tsx
28
- var AnimatedView = React4.forwardRef(function AnimatedView2(props, ref) {
29
- return /* @__PURE__ */ React4__namespace.createElement("div", { ref, ...props });
28
+ React3.forwardRef(function AnimatedView2(props, ref) {
29
+ return /* @__PURE__ */ React3__namespace.createElement("div", { ref, ...props });
30
30
  });
31
- var View = React4.forwardRef(function View2(props, ref) {
32
- return /* @__PURE__ */ React4__namespace.createElement("div", { ref, ...props });
31
+ var View = React3.forwardRef(function View2(props, ref) {
32
+ return /* @__PURE__ */ React3__namespace.createElement("div", { ref, ...props });
33
33
  });
34
34
  var Text = View;
35
35
 
@@ -37,9 +37,9 @@ var Text = View;
37
37
  var createAnimatedValue = (value) => value;
38
38
 
39
39
  // src/state/state.tsx
40
- var ContextState = React4__namespace.createContext(null);
40
+ var ContextState = React3__namespace.createContext(null);
41
41
  function StateProvider({ children }) {
42
- const [value] = React4__namespace.useState(() => ({
42
+ const [value] = React3__namespace.useState(() => ({
43
43
  animatedScrollY: createAnimatedValue(0),
44
44
  columnWrapperStyle: void 0,
45
45
  internalState: void 0,
@@ -54,14 +54,17 @@ function StateProvider({ children }) {
54
54
  ["stylePaddingTop", 0],
55
55
  ["headerSize", 0],
56
56
  ["numContainers", 0],
57
- ["totalSize", 0]
57
+ ["activeStickyIndex", void 0],
58
+ ["totalSize", 0],
59
+ ["scrollAdjustPending", 0],
60
+ ["scrollingTo", void 0]
58
61
  ]),
59
62
  viewRefs: /* @__PURE__ */ new Map()
60
63
  }));
61
- return /* @__PURE__ */ React4__namespace.createElement(ContextState.Provider, { value }, children);
64
+ return /* @__PURE__ */ React3__namespace.createElement(ContextState.Provider, { value }, children);
62
65
  }
63
66
  function useStateContext() {
64
- return React4__namespace.useContext(ContextState);
67
+ return React3__namespace.useContext(ContextState);
65
68
  }
66
69
  function createSelectorFunctionsArr(ctx, signalNames) {
67
70
  let lastValues = [];
@@ -123,31 +126,32 @@ function set$(ctx, signalName, value) {
123
126
  }
124
127
  }
125
128
  function getContentSize(ctx) {
129
+ var _a3, _b;
126
130
  const { values } = ctx;
127
131
  const stylePaddingTop = values.get("stylePaddingTop") || 0;
128
132
  const headerSize = values.get("headerSize") || 0;
129
133
  const footerSize = values.get("footerSize") || 0;
130
- const totalSize = values.get("totalSize");
134
+ const totalSize = (_b = (_a3 = ctx.internalState) == null ? void 0 : _a3.pendingTotalSize) != null ? _b : values.get("totalSize");
131
135
  return headerSize + footerSize + totalSize + stylePaddingTop;
132
136
  }
133
137
  function useArr$(signalNames) {
134
- const ctx = React4__namespace.useContext(ContextState);
135
- const { subscribe, get } = React4__namespace.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
138
+ const ctx = React3__namespace.useContext(ContextState);
139
+ const { subscribe, get } = React3__namespace.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
136
140
  const value = shim.useSyncExternalStore(subscribe, get);
137
141
  return value;
138
142
  }
139
143
  function useSelector$(signalName, selector) {
140
- const ctx = React4__namespace.useContext(ContextState);
141
- const { subscribe, get } = React4__namespace.useMemo(() => createSelectorFunctionsArr(ctx, [signalName]), [ctx, signalName]);
144
+ const ctx = React3__namespace.useContext(ContextState);
145
+ const { subscribe, get } = React3__namespace.useMemo(() => createSelectorFunctionsArr(ctx, [signalName]), [ctx, signalName]);
142
146
  const value = shim.useSyncExternalStore(subscribe, () => selector(get()[0]));
143
147
  return value;
144
148
  }
145
149
 
146
150
  // src/components/DebugView.tsx
147
151
  var DebugRow = ({ children }) => {
148
- return /* @__PURE__ */ React4__namespace.createElement(View, { style: { alignItems: "center", flexDirection: "row", justifyContent: "space-between" } }, children);
152
+ return /* @__PURE__ */ React3__namespace.createElement(View, { style: { alignItems: "center", flexDirection: "row", justifyContent: "space-between" } }, children);
149
153
  };
150
- var DebugView = React4__namespace.memo(function DebugView2({ state }) {
154
+ var DebugView = React3__namespace.memo(function DebugView2({ state }) {
151
155
  const ctx = useStateContext();
152
156
  const [totalSize = 0, scrollAdjust = 0, rawScroll = 0, scroll = 0, _numContainers = 0, _numContainersPooled = 0] = useArr$([
153
157
  "totalSize",
@@ -158,11 +162,11 @@ var DebugView = React4__namespace.memo(function DebugView2({ state }) {
158
162
  "numContainersPooled"
159
163
  ]);
160
164
  const contentSize = getContentSize(ctx);
161
- const [, forceUpdate] = React4.useReducer((x) => x + 1, 0);
165
+ const [, forceUpdate] = React3.useReducer((x) => x + 1, 0);
162
166
  useInterval(() => {
163
167
  forceUpdate();
164
168
  }, 100);
165
- return /* @__PURE__ */ React4__namespace.createElement(
169
+ return /* @__PURE__ */ React3__namespace.createElement(
166
170
  View,
167
171
  {
168
172
  pointerEvents: "none",
@@ -178,107 +182,77 @@ var DebugView = React4__namespace.memo(function DebugView2({ state }) {
178
182
  top: 0
179
183
  }
180
184
  },
181
- /* @__PURE__ */ React4__namespace.createElement(DebugRow, null, /* @__PURE__ */ React4__namespace.createElement(Text, null, "TotalSize:"), /* @__PURE__ */ React4__namespace.createElement(Text, null, totalSize.toFixed(2))),
182
- /* @__PURE__ */ React4__namespace.createElement(DebugRow, null, /* @__PURE__ */ React4__namespace.createElement(Text, null, "ContentSize:"), /* @__PURE__ */ React4__namespace.createElement(Text, null, contentSize.toFixed(2))),
183
- /* @__PURE__ */ React4__namespace.createElement(DebugRow, null, /* @__PURE__ */ React4__namespace.createElement(Text, null, "At end:"), /* @__PURE__ */ React4__namespace.createElement(Text, null, String(state.isAtEnd))),
184
- /* @__PURE__ */ React4__namespace.createElement(DebugRow, null, /* @__PURE__ */ React4__namespace.createElement(Text, null, "ScrollAdjust:"), /* @__PURE__ */ React4__namespace.createElement(Text, null, scrollAdjust.toFixed(2))),
185
- /* @__PURE__ */ React4__namespace.createElement(DebugRow, null, /* @__PURE__ */ React4__namespace.createElement(Text, null, "RawScroll: "), /* @__PURE__ */ React4__namespace.createElement(Text, null, rawScroll.toFixed(2))),
186
- /* @__PURE__ */ React4__namespace.createElement(DebugRow, null, /* @__PURE__ */ React4__namespace.createElement(Text, null, "ComputedScroll: "), /* @__PURE__ */ React4__namespace.createElement(Text, null, scroll.toFixed(2)))
185
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(Text, null, "TotalSize:"), /* @__PURE__ */ React3__namespace.createElement(Text, null, totalSize.toFixed(2))),
186
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(Text, null, "ContentSize:"), /* @__PURE__ */ React3__namespace.createElement(Text, null, contentSize.toFixed(2))),
187
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(Text, null, "At end:"), /* @__PURE__ */ React3__namespace.createElement(Text, null, String(state.isAtEnd))),
188
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(Text, null, "ScrollAdjust:"), /* @__PURE__ */ React3__namespace.createElement(Text, null, scrollAdjust.toFixed(2))),
189
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(Text, null, "RawScroll: "), /* @__PURE__ */ React3__namespace.createElement(Text, null, rawScroll.toFixed(2))),
190
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(Text, null, "ComputedScroll: "), /* @__PURE__ */ React3__namespace.createElement(Text, null, scroll.toFixed(2)))
187
191
  );
188
192
  });
189
193
  function useInterval(callback, delay) {
190
- React4.useEffect(() => {
194
+ React3.useEffect(() => {
191
195
  const interval = setInterval(callback, delay);
192
196
  return () => clearInterval(interval);
193
197
  }, [delay]);
194
198
  }
195
- var globalResizeObserver = null;
196
- function getGlobalResizeObserver() {
197
- if (!globalResizeObserver) {
198
- globalResizeObserver = new ResizeObserver((entries) => {
199
- for (const entry of entries) {
200
- const callbacks = callbackMap.get(entry.target);
201
- if (callbacks) {
202
- for (const callback of callbacks) {
203
- callback(entry);
204
- }
205
- }
206
- }
207
- });
199
+
200
+ // src/utils/devEnvironment.ts
201
+ var metroDev = typeof __DEV__ !== "undefined" ? __DEV__ : void 0;
202
+ var _a;
203
+ var envMode = typeof process !== "undefined" && typeof process.env === "object" && process.env ? (_a = process.env.NODE_ENV) != null ? _a : process.env.MODE : void 0;
204
+ var processDev = typeof envMode === "string" ? envMode.toLowerCase() !== "production" : void 0;
205
+ var _a2;
206
+ var IS_DEV = (_a2 = metroDev != null ? metroDev : processDev) != null ? _a2 : false;
207
+
208
+ // src/constants.ts
209
+ var POSITION_OUT_OF_VIEW = -1e7;
210
+ var ENABLE_DEVMODE = IS_DEV && false;
211
+ var ENABLE_DEBUG_VIEW = IS_DEV && false;
212
+ var typedForwardRef = React3.forwardRef;
213
+ var typedMemo = React3.memo;
214
+
215
+ // src/utils/helpers.ts
216
+ function isFunction(obj) {
217
+ return typeof obj === "function";
218
+ }
219
+ function isArray(obj) {
220
+ return Array.isArray(obj);
221
+ }
222
+ var warned = /* @__PURE__ */ new Set();
223
+ function warnDevOnce(id, text) {
224
+ if (IS_DEV && !warned.has(id)) {
225
+ warned.add(id);
226
+ console.warn(`[legend-list] ${text}`);
208
227
  }
209
- return globalResizeObserver;
210
228
  }
211
- var callbackMap = /* @__PURE__ */ new WeakMap();
212
- function useResizeObserver(element, callback) {
213
- React4.useEffect(() => {
214
- if (!element) return;
215
- const observer = getGlobalResizeObserver();
216
- let callbacks = callbackMap.get(element);
217
- if (!callbacks) {
218
- callbacks = /* @__PURE__ */ new Set();
219
- callbackMap.set(element, callbacks);
220
- observer.observe(element);
221
- }
222
- callbacks.add(callback);
223
- return () => {
224
- const callbacks2 = callbackMap.get(element);
225
- if (callbacks2) {
226
- callbacks2.delete(callback);
227
- if (callbacks2.size === 0) {
228
- callbackMap.delete(element);
229
- observer.unobserve(element);
230
- }
231
- }
232
- };
233
- }, [element, callback]);
229
+ function roundSize(size) {
230
+ return Math.floor(size * 8) / 8;
234
231
  }
235
-
236
- // src/hooks/useSyncLayout.tsx
237
- function useSyncLayout({
238
- ref,
239
- onLayoutChange
240
- }) {
241
- var _a, _b;
242
- useResizeObserver(
243
- ((_b = (_a = ref.current) == null ? void 0 : _a.getScrollableNode) == null ? void 0 : _b.call(_a)) || ref.current,
244
- React4.useCallback(
245
- (entry) => {
246
- onLayoutChange(entry.contentRect, false);
247
- },
248
- [onLayoutChange]
249
- )
250
- );
251
- React4.useLayoutEffect(() => {
252
- if (ref.current) {
253
- const rect = ref.current.getBoundingClientRect();
254
- onLayoutChange(
255
- {
256
- height: rect.height,
257
- width: rect.width,
258
- x: rect.left,
259
- y: rect.top
260
- },
261
- true
262
- );
232
+ function isNullOrUndefined(value) {
233
+ return value === null || value === void 0;
234
+ }
235
+ function comparatorDefault(a, b) {
236
+ return a - b;
237
+ }
238
+ function getPadding(s, type) {
239
+ var _a3, _b, _c;
240
+ return (_c = (_b = (_a3 = s[`padding${type}`]) != null ? _a3 : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
241
+ }
242
+ function extractPadding(style, contentContainerStyle, type) {
243
+ return getPadding(style, type) + getPadding(contentContainerStyle, type);
244
+ }
245
+ function findContainerId(ctx, key) {
246
+ const numContainers = peek$(ctx, "numContainers");
247
+ for (let i = 0; i < numContainers; i++) {
248
+ const itemKey = peek$(ctx, `containerItemKey${i}`);
249
+ if (itemKey === key) {
250
+ return i;
263
251
  }
264
- }, []);
265
- return {};
252
+ }
253
+ return -1;
266
254
  }
267
255
 
268
- // src/components/LayoutView.tsx
269
- var LayoutView = ({ onLayoutChange, refView, children, ...rest }) => {
270
- const ref = refView != null ? refView : React4.useRef();
271
- useSyncLayout({ onLayoutChange, ref });
272
- return /* @__PURE__ */ React4__namespace.createElement("div", { ...rest, ref }, children);
273
- };
274
-
275
- // src/constants.ts
276
- var POSITION_OUT_OF_VIEW = -1e7;
277
- var ENABLE_DEVMODE = __DEV__ && false;
278
- var ENABLE_DEBUG_VIEW = __DEV__ && false;
279
- var typedForwardRef = React4.forwardRef;
280
- var typedMemo = React4.memo;
281
-
282
256
  // src/components/PositionView.tsx
283
257
  var PositionViewState = typedMemo(function PositionView({
284
258
  id,
@@ -288,9 +262,12 @@ var PositionViewState = typedMemo(function PositionView({
288
262
  ...rest
289
263
  }) {
290
264
  const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
291
- const base = Array.isArray(style) ? Object.assign({}, ...style) : style;
292
- const combinedStyle = horizontal ? { ...base, left: position } : { ...base, top: position };
293
- return /* @__PURE__ */ React4__namespace.createElement(LayoutView, { refView, style: combinedStyle, ...rest });
265
+ const base = {
266
+ contain: "paint layout style"
267
+ };
268
+ const composed = isArray(style) ? Object.assign({}, ...style) : style;
269
+ const combinedStyle = horizontal ? { ...base, ...composed, left: position } : { ...base, ...composed, top: position };
270
+ return /* @__PURE__ */ React3__namespace.createElement("div", { ref: refView, style: combinedStyle, ...rest });
294
271
  });
295
272
  var PositionViewSticky = typedMemo(function PositionViewSticky2({
296
273
  id,
@@ -298,80 +275,61 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
298
275
  style,
299
276
  refView,
300
277
  index,
278
+ stickyOffset,
279
+ animatedScrollY: _animatedScrollY,
280
+ children,
301
281
  ...rest
302
282
  }) {
303
- const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
304
- const viewStyle = React4__namespace.useMemo(() => {
305
- const base = Array.isArray(style) ? Object.assign({}, ...style) : style;
306
- const axisStyle = horizontal ? { transform: `translateX(${position}px)` } : { top: position };
307
- return {
308
- ...base,
309
- zIndex: index + 1e3,
310
- ...axisStyle
311
- };
312
- }, [style, position, horizontal, index]);
313
- return /* @__PURE__ */ React4__namespace.createElement(LayoutView, { refView, style: viewStyle, ...rest });
283
+ const [position = POSITION_OUT_OF_VIEW, headerSize = 0, activeStickyIndex] = useArr$([
284
+ `containerPosition${id}`,
285
+ "headerSize",
286
+ "activeStickyIndex"
287
+ ]);
288
+ const base = {
289
+ contain: "paint layout style"
290
+ };
291
+ const composed = React3__namespace.useMemo(
292
+ () => {
293
+ var _a3;
294
+ return (_a3 = isArray(style) ? Object.assign({}, ...style) : style) != null ? _a3 : {};
295
+ },
296
+ [style]
297
+ );
298
+ const viewStyle = React3__namespace.useMemo(() => {
299
+ var _a3;
300
+ const styleBase = { ...base, ...composed };
301
+ delete styleBase.transform;
302
+ const offset = (_a3 = stickyOffset != null ? stickyOffset : headerSize) != null ? _a3 : 0;
303
+ const isActive = activeStickyIndex === index;
304
+ styleBase.position = isActive ? "sticky" : "absolute";
305
+ styleBase.zIndex = index + 1e3;
306
+ if (horizontal) {
307
+ styleBase.left = isActive ? offset : position;
308
+ } else {
309
+ styleBase.top = isActive ? offset : position;
310
+ }
311
+ return styleBase;
312
+ }, [composed, horizontal, position, index, stickyOffset, headerSize, activeStickyIndex]);
313
+ return /* @__PURE__ */ React3__namespace.createElement("div", { ref: refView, style: viewStyle, ...rest }, children);
314
314
  });
315
315
  var PositionView2 = PositionViewState;
316
- function Separator({ ItemSeparatorComponent, itemKey, leadingItem }) {
317
- const [lastItemKeys] = useArr$(["lastItemKeys"]);
318
- const isALastItem = lastItemKeys.includes(itemKey);
319
- return isALastItem ? null : /* @__PURE__ */ React4__namespace.createElement(ItemSeparatorComponent, { leadingItem });
320
- }
321
316
 
322
317
  // src/constants-platform.ts
323
318
  var IsNewArchitecture = true;
324
-
325
- // src/platform/Platform.ts
326
- var Platform = {
327
- // Widen the type to avoid unreachable-branch lints in cross-platform code that compares against other OSes
328
- OS: "web"
329
- };
330
319
  var symbolFirst = Symbol();
331
320
  function useInit(cb) {
332
- const refValue = React4.useRef(symbolFirst);
321
+ const refValue = React3.useRef(symbolFirst);
333
322
  if (refValue.current === symbolFirst) {
334
323
  refValue.current = cb();
335
324
  }
336
325
  return refValue.current;
337
326
  }
338
327
 
339
- // src/utils/helpers.ts
340
- function isFunction(obj) {
341
- return typeof obj === "function";
342
- }
343
- function isArray(obj) {
344
- return Array.isArray(obj);
345
- }
346
- var warned = /* @__PURE__ */ new Set();
347
- function warnDevOnce(id, text) {
348
- if (__DEV__ && !warned.has(id)) {
349
- warned.add(id);
350
- console.warn(`[legend-list] ${text}`);
351
- }
352
- }
353
- function roundSize(size) {
354
- return Math.floor(size * 8) / 8;
355
- }
356
- function isNullOrUndefined(value) {
357
- return value === null || value === void 0;
358
- }
359
- function comparatorDefault(a, b) {
360
- return a - b;
361
- }
362
- function getPadding(s, type) {
363
- var _a, _b, _c;
364
- return (_c = (_b = (_a = s[`padding${type}`]) != null ? _a : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
365
- }
366
- function extractPadding(style, contentContainerStyle, type) {
367
- return getPadding(style, type) + getPadding(contentContainerStyle, type);
368
- }
369
-
370
328
  // src/state/ContextContainer.ts
371
- var ContextContainer = React4.createContext(null);
329
+ var ContextContainer = React3.createContext(null);
372
330
  function useViewability(callback, configId) {
373
331
  const ctx = useStateContext();
374
- const { containerId } = React4.useContext(ContextContainer);
332
+ const { containerId } = React3.useContext(ContextContainer);
375
333
  const key = containerId + (configId != null ? configId : "");
376
334
  useInit(() => {
377
335
  const value = ctx.mapViewabilityValues.get(key);
@@ -380,7 +338,7 @@ function useViewability(callback, configId) {
380
338
  }
381
339
  });
382
340
  ctx.mapViewabilityCallbacks.set(key, callback);
383
- React4.useEffect(
341
+ React3.useEffect(
384
342
  () => () => {
385
343
  ctx.mapViewabilityCallbacks.delete(key);
386
344
  },
@@ -389,7 +347,7 @@ function useViewability(callback, configId) {
389
347
  }
390
348
  function useViewabilityAmount(callback) {
391
349
  const ctx = useStateContext();
392
- const { containerId } = React4.useContext(ContextContainer);
350
+ const { containerId } = React3.useContext(ContextContainer);
393
351
  useInit(() => {
394
352
  const value = ctx.mapViewabilityAmountValues.get(containerId);
395
353
  if (value) {
@@ -397,7 +355,7 @@ function useViewabilityAmount(callback) {
397
355
  }
398
356
  });
399
357
  ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
400
- React4.useEffect(
358
+ React3.useEffect(
401
359
  () => () => {
402
360
  ctx.mapViewabilityAmountCallbacks.delete(containerId);
403
361
  },
@@ -405,12 +363,12 @@ function useViewabilityAmount(callback) {
405
363
  );
406
364
  }
407
365
  function useRecyclingEffect(effect) {
408
- const { index, value } = React4.useContext(ContextContainer);
409
- const prevValues = React4.useRef({
366
+ const { index, value } = React3.useContext(ContextContainer);
367
+ const prevValues = React3.useRef({
410
368
  prevIndex: void 0,
411
369
  prevItem: void 0
412
370
  });
413
- React4.useEffect(() => {
371
+ React3.useEffect(() => {
414
372
  let ret;
415
373
  if (prevValues.current.prevIndex !== void 0 && prevValues.current.prevItem !== void 0) {
416
374
  ret = effect({
@@ -428,12 +386,12 @@ function useRecyclingEffect(effect) {
428
386
  }, [index, value, effect]);
429
387
  }
430
388
  function useRecyclingState(valueOrFun) {
431
- const { index, value, itemKey, triggerLayout } = React4.useContext(ContextContainer);
432
- const refState = React4.useRef({
389
+ const { index, value, itemKey, triggerLayout } = React3.useContext(ContextContainer);
390
+ const refState = React3.useRef({
433
391
  itemKey: null,
434
392
  value: null
435
393
  });
436
- const [_, setRenderNum] = React4.useState(0);
394
+ const [_, setRenderNum] = React3.useState(0);
437
395
  const state = refState.current;
438
396
  if (state.itemKey !== itemKey) {
439
397
  state.itemKey = itemKey;
@@ -444,7 +402,7 @@ function useRecyclingState(valueOrFun) {
444
402
  prevItem: void 0
445
403
  }) : valueOrFun;
446
404
  }
447
- const setState = React4.useCallback(
405
+ const setState = React3.useCallback(
448
406
  (newState) => {
449
407
  state.value = isFunction(newState) ? newState(state.value) : newState;
450
408
  setRenderNum((v) => v + 1);
@@ -455,7 +413,7 @@ function useRecyclingState(valueOrFun) {
455
413
  return [state.value, setState];
456
414
  }
457
415
  function useIsLastItem() {
458
- const { itemKey } = React4.useContext(ContextContainer);
416
+ const { itemKey } = React3.useContext(ContextContainer);
459
417
  const isLast = useSelector$("lastItemKeys", (lastItemKeys) => (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false);
460
418
  return isLast;
461
419
  }
@@ -463,13 +421,114 @@ function useListScrollSize() {
463
421
  const [scrollSize] = useArr$(["scrollSize"]);
464
422
  return scrollSize;
465
423
  }
466
- function useSyncLayout2() {
424
+ function useSyncLayout() {
467
425
  {
468
- const { triggerLayout: syncLayout } = React4.useContext(ContextContainer);
426
+ const { triggerLayout: syncLayout } = React3.useContext(ContextContainer);
469
427
  return syncLayout;
470
428
  }
471
429
  }
472
430
 
431
+ // src/components/Separator.tsx
432
+ function Separator({ ItemSeparatorComponent, leadingItem }) {
433
+ const isLastItem = useIsLastItem();
434
+ return isLastItem ? null : /* @__PURE__ */ React3__namespace.createElement(ItemSeparatorComponent, { leadingItem });
435
+ }
436
+
437
+ // src/hooks/createResizeObserver.ts
438
+ var globalResizeObserver = null;
439
+ function getGlobalResizeObserver() {
440
+ if (!globalResizeObserver) {
441
+ globalResizeObserver = new ResizeObserver((entries) => {
442
+ for (const entry of entries) {
443
+ const callbacks = callbackMap.get(entry.target);
444
+ if (callbacks) {
445
+ for (const callback of callbacks) {
446
+ callback(entry);
447
+ }
448
+ }
449
+ }
450
+ });
451
+ }
452
+ return globalResizeObserver;
453
+ }
454
+ var callbackMap = /* @__PURE__ */ new WeakMap();
455
+ function createResizeObserver(element, callback) {
456
+ if (typeof ResizeObserver === "undefined") {
457
+ return () => {
458
+ };
459
+ }
460
+ if (!element) {
461
+ return () => {
462
+ };
463
+ }
464
+ const observer = getGlobalResizeObserver();
465
+ let callbacks = callbackMap.get(element);
466
+ if (!callbacks) {
467
+ callbacks = /* @__PURE__ */ new Set();
468
+ callbackMap.set(element, callbacks);
469
+ observer.observe(element);
470
+ }
471
+ callbacks.add(callback);
472
+ return () => {
473
+ const callbacks2 = callbackMap.get(element);
474
+ if (callbacks2) {
475
+ callbacks2.delete(callback);
476
+ if (callbacks2.size === 0) {
477
+ callbackMap.delete(element);
478
+ observer.unobserve(element);
479
+ }
480
+ }
481
+ };
482
+ }
483
+
484
+ // src/hooks/useOnLayoutSync.tsx
485
+ function useOnLayoutSync({
486
+ ref,
487
+ onLayoutProp,
488
+ onLayoutChange
489
+ }, deps) {
490
+ React3.useLayoutEffect(() => {
491
+ var _a3, _b;
492
+ const current = ref.current;
493
+ const scrollableNode = (_b = (_a3 = current == null ? void 0 : current.getScrollableNode) == null ? void 0 : _a3.call(current)) != null ? _b : null;
494
+ const element = scrollableNode || current;
495
+ if (!element) {
496
+ return;
497
+ }
498
+ const emit = (layout, fromLayoutEffect) => {
499
+ if (layout.height === 0 && layout.width === 0) {
500
+ return;
501
+ }
502
+ onLayoutChange(layout, fromLayoutEffect);
503
+ onLayoutProp == null ? void 0 : onLayoutProp({ nativeEvent: { layout } });
504
+ };
505
+ const rect = element.getBoundingClientRect();
506
+ emit(toLayout(rect), true);
507
+ let prevRect = rect;
508
+ return createResizeObserver(element, (entry) => {
509
+ var _a4;
510
+ const target = entry.target instanceof HTMLElement ? entry.target : void 0;
511
+ const rect2 = (_a4 = entry.contentRect) != null ? _a4 : target == null ? void 0 : target.getBoundingClientRect();
512
+ if (rect2.width !== prevRect.width || rect2.height !== prevRect.height) {
513
+ prevRect = rect2;
514
+ emit(toLayout(rect2), false);
515
+ }
516
+ });
517
+ }, deps || []);
518
+ return {};
519
+ }
520
+ function toLayout(rect) {
521
+ if (!rect) {
522
+ return { height: 0, width: 0, x: 0, y: 0 };
523
+ }
524
+ return {
525
+ height: rect.height,
526
+ width: rect.width,
527
+ x: rect.left,
528
+ y: rect.top
529
+ };
530
+ }
531
+
473
532
  // src/components/Container.tsx
474
533
  var Container = typedMemo(function Container2({
475
534
  id,
@@ -480,37 +539,42 @@ var Container = typedMemo(function Container2({
480
539
  ItemSeparatorComponent
481
540
  }) {
482
541
  const ctx = useStateContext();
483
- const { columnWrapperStyle } = ctx;
484
- const [column = 0, data, itemKey, numColumns, extraData, isSticky] = useArr$([
542
+ const { columnWrapperStyle, animatedScrollY } = ctx;
543
+ const [column = 0, data, itemKey, numColumns, extraData, isSticky, stickyOffset] = useArr$([
485
544
  `containerColumn${id}`,
486
545
  `containerItemData${id}`,
487
546
  `containerItemKey${id}`,
488
547
  "numColumns",
489
548
  "extraData",
490
- `containerSticky${id}`
549
+ `containerSticky${id}`,
550
+ `containerStickyOffset${id}`
491
551
  ]);
492
- const refLastSize = React4.useRef();
493
- const ref = React4.useRef(null);
494
- const [_, forceLayoutRender] = React4.useState(0);
552
+ const itemLayoutRef = React3.useRef({
553
+ horizontal,
554
+ itemKey,
555
+ updateItemSize: updateItemSize2
556
+ });
557
+ itemLayoutRef.current.horizontal = horizontal;
558
+ itemLayoutRef.current.itemKey = itemKey;
559
+ itemLayoutRef.current.updateItemSize = updateItemSize2;
560
+ const ref = React3.useRef(null);
561
+ const [layoutRenderCount, forceLayoutRender] = React3.useState(0);
495
562
  const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
496
563
  const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
497
- const style = React4.useMemo(() => {
564
+ const didLayoutRef = React3.useRef(false);
565
+ const style = React3.useMemo(() => {
498
566
  let paddingStyles;
499
567
  if (columnWrapperStyle) {
500
568
  const { columnGap, rowGap, gap } = columnWrapperStyle;
501
569
  if (horizontal) {
502
- const py = numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0;
503
570
  paddingStyles = {
504
- paddingBottom: py,
505
571
  paddingRight: columnGap || gap || void 0,
506
- paddingTop: py
572
+ paddingVertical: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
507
573
  };
508
574
  } else {
509
- const px = numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0;
510
575
  paddingStyles = {
511
576
  paddingBottom: rowGap || gap || void 0,
512
- paddingLeft: px,
513
- paddingRight: px
577
+ paddingHorizontal: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
514
578
  };
515
579
  }
516
580
  }
@@ -524,18 +588,18 @@ var Container = typedMemo(function Container2({
524
588
  } : {
525
589
  left: otherAxisPos,
526
590
  position: "absolute",
527
- right: numColumns > 1 ? void 0 : 0,
591
+ right: numColumns > 1 ? null : 0,
528
592
  top: 0,
529
593
  width: otherAxisSize,
530
594
  ...paddingStyles || {}
531
595
  };
532
596
  }, [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns]);
533
- const renderedItemInfo = React4.useMemo(
597
+ const renderedItemInfo = React3.useMemo(
534
598
  () => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
535
599
  [itemKey, data, extraData]
536
600
  );
537
601
  const { index, renderedItem } = renderedItemInfo || {};
538
- const contextValue = React4.useMemo(() => {
602
+ const contextValue = React3.useMemo(() => {
539
603
  ctx.viewRefs.set(id, ref);
540
604
  return {
541
605
  containerId: id,
@@ -547,49 +611,64 @@ var Container = typedMemo(function Container2({
547
611
  value: data
548
612
  };
549
613
  }, [id, itemKey, index, data]);
550
- const onLayoutChange = (rectangle) => {
551
- if (!isNullOrUndefined(itemKey)) {
552
- let layout = rectangle;
553
- layout[horizontal ? "width" : "height"];
554
- const doUpdate = () => {
555
- refLastSize.current = { height: layout.height, width: layout.width };
556
- updateItemSize2(itemKey, layout);
557
- };
558
- {
559
- doUpdate();
560
- }
614
+ const onLayoutChange = React3.useCallback((rectangle) => {
615
+ const {
616
+ horizontal: currentHorizontal,
617
+ itemKey: currentItemKey,
618
+ updateItemSize: updateItemSizeFn
619
+ } = itemLayoutRef.current;
620
+ if (isNullOrUndefined(currentItemKey)) {
621
+ return;
561
622
  }
562
- };
623
+ didLayoutRef.current = true;
624
+ let layout = rectangle;
625
+ roundSize(rectangle[currentHorizontal ? "width" : "height"]);
626
+ const doUpdate = () => {
627
+ itemLayoutRef.current.lastSize = { height: layout.height, width: layout.width };
628
+ updateItemSizeFn(currentItemKey, layout);
629
+ didLayoutRef.current = true;
630
+ };
631
+ {
632
+ doUpdate();
633
+ }
634
+ }, []);
635
+ const { onLayout } = useOnLayoutSync(
636
+ {
637
+ onLayoutChange,
638
+ ref
639
+ },
640
+ [itemKey, layoutRenderCount]
641
+ );
563
642
  const PositionComponent = isSticky ? PositionViewSticky : PositionView2;
564
- return /* @__PURE__ */ React4__namespace.createElement(ContextContainer.Provider, { value: contextValue }, /* @__PURE__ */ React4__namespace.createElement(
643
+ return /* @__PURE__ */ React3__namespace.createElement(
565
644
  PositionComponent,
566
645
  {
646
+ animatedScrollY: isSticky ? animatedScrollY : void 0,
567
647
  horizontal,
568
648
  id,
569
649
  index,
570
650
  key: recycleItems ? void 0 : itemKey,
571
- onLayoutChange,
651
+ onLayout,
572
652
  refView: ref,
653
+ stickyOffset: isSticky ? stickyOffset : void 0,
573
654
  style
574
655
  },
575
- renderedItem,
576
- renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React4__namespace.createElement(
577
- Separator,
578
- {
579
- ItemSeparatorComponent,
580
- itemKey,
581
- leadingItem: renderedItemInfo.item
582
- }
583
- )
584
- ));
656
+ /* @__PURE__ */ React3__namespace.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React3__namespace.createElement(Separator, { ItemSeparatorComponent, leadingItem: renderedItemInfo.item }))
657
+ );
585
658
  });
586
659
 
660
+ // src/platform/Platform.ts
661
+ var Platform = {
662
+ // Widen the type to avoid unreachable-branch lints in cross-platform code that compares against other OSes
663
+ OS: "web"
664
+ };
665
+
587
666
  // src/utils/reordering.ts
588
667
  var mapFn = (element) => {
589
668
  const indexStr = element.getAttribute("index");
590
669
  return [element, indexStr === null ? null : parseInt(indexStr)];
591
670
  };
592
- function sortDOMElementsPatience(container) {
671
+ function sortDOMElements(container) {
593
672
  const elements = Array.from(container.children);
594
673
  if (elements.length <= 1) return elements;
595
674
  const items = elements.map(mapFn);
@@ -671,8 +750,8 @@ function findLIS(arr) {
671
750
  // src/hooks/useDOMOrder.ts
672
751
  function useDOMOrder(ref) {
673
752
  const ctx = useStateContext();
674
- const debounceRef = React4.useRef(void 0);
675
- React4.useEffect(() => {
753
+ const debounceRef = React3.useRef(void 0);
754
+ React3.useEffect(() => {
676
755
  const unsubscribe = listen$(ctx, "lastPositionUpdate", () => {
677
756
  if (debounceRef.current !== void 0) {
678
757
  clearTimeout(debounceRef.current);
@@ -680,7 +759,7 @@ function useDOMOrder(ref) {
680
759
  debounceRef.current = setTimeout(() => {
681
760
  const parent = ref.current;
682
761
  if (parent) {
683
- sortDOMElementsPatience(parent);
762
+ sortDOMElements(parent);
684
763
  }
685
764
  debounceRef.current = void 0;
686
765
  }, 500);
@@ -696,12 +775,12 @@ function useDOMOrder(ref) {
696
775
 
697
776
  // src/components/Containers.tsx
698
777
  var ContainersInner = typedMemo(function ContainersInner2({ horizontal, numColumns, children }) {
699
- const ref = React4.useRef(null);
778
+ const ref = React3.useRef(null);
700
779
  const ctx = useStateContext();
701
780
  const columnWrapperStyle = ctx.columnWrapperStyle;
702
781
  const [totalSize, otherAxisSize] = useArr$(["totalSize", "otherAxisSize"]);
703
782
  useDOMOrder(ref);
704
- const style = horizontal ? { minHeight: otherAxisSize, width: totalSize } : { height: totalSize, minWidth: otherAxisSize };
783
+ const style = horizontal ? { minHeight: otherAxisSize, position: "relative", width: totalSize } : { height: totalSize, minWidth: otherAxisSize, position: "relative" };
705
784
  if (columnWrapperStyle && numColumns > 1) {
706
785
  const { columnGap, rowGap, gap } = columnWrapperStyle;
707
786
  const gapX = columnGap || gap || 0;
@@ -722,7 +801,7 @@ var ContainersInner = typedMemo(function ContainersInner2({ horizontal, numColum
722
801
  }
723
802
  }
724
803
  }
725
- return /* @__PURE__ */ React4__namespace.createElement("div", { ref, style }, children);
804
+ return /* @__PURE__ */ React3__namespace.createElement("div", { ref, style }, children);
726
805
  });
727
806
  var Containers = typedMemo(function Containers2({
728
807
  horizontal,
@@ -736,7 +815,7 @@ var Containers = typedMemo(function Containers2({
736
815
  const containers = [];
737
816
  for (let i = 0; i < numContainers; i++) {
738
817
  containers.push(
739
- /* @__PURE__ */ React4__namespace.createElement(
818
+ /* @__PURE__ */ React3__namespace.createElement(
740
819
  Container,
741
820
  {
742
821
  getRenderedItem: getRenderedItem2,
@@ -750,25 +829,41 @@ var Containers = typedMemo(function Containers2({
750
829
  )
751
830
  );
752
831
  }
753
- return /* @__PURE__ */ React4__namespace.createElement(ContainersInner, { horizontal, numColumns, waitForInitialLayout }, containers);
754
- });
755
- var DevNumbers = __DEV__ && React4__namespace.memo(function DevNumbers2() {
756
- return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React4__namespace.createElement(
757
- View,
758
- {
759
- key: index,
760
- style: {
761
- height: 100,
762
- pointerEvents: "none",
763
- position: "absolute",
764
- top: index * 100,
765
- width: "100%"
766
- }
767
- },
768
- /* @__PURE__ */ React4__namespace.createElement(Text, { style: { color: "red" } }, index * 100)
769
- ));
832
+ return /* @__PURE__ */ React3__namespace.createElement(ContainersInner, { horizontal, numColumns, waitForInitialLayout }, containers);
770
833
  });
771
- var ListComponentScrollView = React4.forwardRef(function ListComponentScrollView2({
834
+ function DevNumbers() {
835
+ return IS_DEV && React3__namespace.memo(function DevNumbers2() {
836
+ return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React3__namespace.createElement(
837
+ "div",
838
+ {
839
+ key: index,
840
+ style: {
841
+ height: 100,
842
+ pointerEvents: "none",
843
+ position: "absolute",
844
+ top: index * 100,
845
+ width: "100%"
846
+ }
847
+ },
848
+ /* @__PURE__ */ React3__namespace.createElement("div", { style: { color: "red" } }, index * 100)
849
+ ));
850
+ });
851
+ }
852
+
853
+ // src/platform/StyleSheet.tsx
854
+ function flattenStyles(styles) {
855
+ if (isArray(styles)) {
856
+ return Object.assign({}, ...styles.filter(Boolean));
857
+ }
858
+ return styles;
859
+ }
860
+ var StyleSheet = {
861
+ create: (styles) => styles,
862
+ flatten: (style) => flattenStyles(style)
863
+ };
864
+
865
+ // src/components/ListComponentScrollView.tsx
866
+ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView2({
772
867
  children,
773
868
  style,
774
869
  contentContainerStyle,
@@ -781,25 +876,23 @@ var ListComponentScrollView = React4.forwardRef(function ListComponentScrollView
781
876
  showsVerticalScrollIndicator = true,
782
877
  refreshControl,
783
878
  onLayout,
784
- ScrollComponent,
785
879
  ...props
786
880
  }, ref) {
787
- const scrollRef = React4.useRef(null);
788
- const contentRef = React4.useRef(null);
789
- const momentumTimeout = React4.useRef(null);
790
- React4.useImperativeHandle(ref, () => {
881
+ const scrollRef = React3.useRef(null);
882
+ const contentRef = React3.useRef(null);
883
+ const momentumTimeout = React3.useRef(null);
884
+ React3.useImperativeHandle(ref, () => {
791
885
  const api = {
792
886
  getBoundingClientRect: () => {
793
- var _a;
794
- return (_a = scrollRef.current) == null ? void 0 : _a.getBoundingClientRect();
887
+ var _a3;
888
+ return (_a3 = scrollRef.current) == null ? void 0 : _a3.getBoundingClientRect();
795
889
  },
796
890
  getScrollableNode: () => scrollRef.current,
797
891
  getScrollResponder: () => scrollRef.current,
798
- scrollBy: (options) => {
892
+ scrollBy: (x, y) => {
799
893
  const el = scrollRef.current;
800
894
  if (!el) return;
801
- const { x = 0, y = 0, animated = true } = options;
802
- el.scrollBy({ behavior: animated ? "smooth" : "auto", left: x, top: y });
895
+ el.scrollBy(x, y);
803
896
  },
804
897
  scrollTo: (options) => {
805
898
  const el = scrollRef.current;
@@ -830,7 +923,7 @@ var ListComponentScrollView = React4.forwardRef(function ListComponentScrollView
830
923
  };
831
924
  return api;
832
925
  }, [horizontal]);
833
- const handleScroll = React4.useCallback(
926
+ const handleScroll = React3.useCallback(
834
927
  (event) => {
835
928
  if (!onScroll2 || !(event == null ? void 0 : event.target)) {
836
929
  return;
@@ -866,21 +959,25 @@ var ListComponentScrollView = React4.forwardRef(function ListComponentScrollView
866
959
  },
867
960
  [onScroll2, onMomentumScrollEnd]
868
961
  );
869
- React4.useLayoutEffect(() => {
962
+ React3.useLayoutEffect(() => {
870
963
  const element = scrollRef.current;
871
964
  if (!element) return;
872
- element.addEventListener("scroll", handleScroll, { passive: true });
965
+ element.addEventListener("scroll", handleScroll);
873
966
  return () => {
874
967
  element.removeEventListener("scroll", handleScroll);
875
968
  };
876
969
  }, [handleScroll]);
877
- React4.useLayoutEffect(() => {
878
- if (contentOffset && scrollRef.current) {
879
- scrollRef.current.scrollLeft = contentOffset.x || 0;
880
- scrollRef.current.scrollTop = contentOffset.y || 0;
881
- }
882
- }, [contentOffset]);
883
- React4.useLayoutEffect(() => {
970
+ React3.useEffect(() => {
971
+ const doScroll = () => {
972
+ if (contentOffset && scrollRef.current) {
973
+ scrollRef.current.scrollLeft = contentOffset.x || 0;
974
+ scrollRef.current.scrollTop = contentOffset.y || 0;
975
+ }
976
+ };
977
+ doScroll();
978
+ requestAnimationFrame(doScroll);
979
+ }, [contentOffset == null ? void 0 : contentOffset.x, contentOffset == null ? void 0 : contentOffset.y]);
980
+ React3.useLayoutEffect(() => {
884
981
  if (!onLayout || !scrollRef.current) return;
885
982
  const element = scrollRef.current;
886
983
  const fireLayout = () => {
@@ -911,41 +1008,80 @@ var ListComponentScrollView = React4.forwardRef(function ListComponentScrollView
911
1008
  // Ensure proper positioning context
912
1009
  WebkitOverflowScrolling: "touch",
913
1010
  // iOS momentum scrolling
914
- ...style
1011
+ ...StyleSheet.flatten(style)
915
1012
  };
916
1013
  const contentStyle = {
917
1014
  display: horizontal ? "flex" : "block",
918
1015
  flexDirection: horizontal ? "row" : void 0,
919
1016
  minHeight: horizontal ? void 0 : "100%",
920
1017
  minWidth: horizontal ? "100%" : void 0,
921
- ...contentContainerStyle
1018
+ ...StyleSheet.flatten(contentContainerStyle)
922
1019
  };
923
- return /* @__PURE__ */ React4__namespace.createElement("div", { ref: scrollRef, style: scrollViewStyle, ...props }, refreshControl, /* @__PURE__ */ React4__namespace.createElement("div", { ref: contentRef, style: contentStyle }, children));
1020
+ return /* @__PURE__ */ React3__namespace.createElement("div", { ref: scrollRef, style: scrollViewStyle, ...props }, refreshControl, /* @__PURE__ */ React3__namespace.createElement("div", { ref: contentRef, style: contentStyle }, children));
924
1021
  });
1022
+ function Padding() {
1023
+ const [paddingTop] = useArr$(["alignItemsPaddingTop"]);
1024
+ return /* @__PURE__ */ React3__namespace.createElement("div", { style: { paddingTop } });
1025
+ }
1026
+ function PaddingDevMode() {
1027
+ const [paddingTop] = useArr$(["alignItemsPaddingTop"]);
1028
+ return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement("div", { style: { paddingTop } }), /* @__PURE__ */ React3__namespace.createElement(
1029
+ "div",
1030
+ {
1031
+ style: {
1032
+ backgroundColor: "green",
1033
+ height: paddingTop,
1034
+ left: 0,
1035
+ position: "absolute",
1036
+ right: 0,
1037
+ top: 0
1038
+ }
1039
+ }
1040
+ ));
1041
+ }
925
1042
  function useValueListener$(key, callback) {
926
1043
  const ctx = useStateContext();
927
- React4.useLayoutEffect(() => {
928
- listen$(ctx, key, (value) => {
1044
+ React3.useLayoutEffect(() => {
1045
+ const unsubscribe = listen$(ctx, key, (value) => {
929
1046
  callback(value);
930
1047
  });
931
- }, []);
1048
+ return unsubscribe;
1049
+ }, [callback, ctx, key]);
932
1050
  }
933
1051
 
934
1052
  // src/components/ScrollAdjust.tsx
935
1053
  function ScrollAdjust() {
936
1054
  const ctx = useStateContext();
937
- const lastScrollOffsetRef = React4__namespace.useRef(0);
938
- const callback = React4__namespace.useCallback(() => {
939
- var _a;
1055
+ const lastScrollOffsetRef = React3__namespace.useRef(0);
1056
+ const callback = React3__namespace.useCallback(() => {
1057
+ var _a3;
940
1058
  const scrollAdjust = peek$(ctx, "scrollAdjust");
941
1059
  const scrollAdjustUserOffset = peek$(ctx, "scrollAdjustUserOffset");
942
1060
  const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0);
943
- const scrollView = (_a = ctx.internalState) == null ? void 0 : _a.refScroller.current;
1061
+ const scrollView = (_a3 = ctx.internalState) == null ? void 0 : _a3.refScroller.current;
944
1062
  if (scrollView && scrollOffset !== lastScrollOffsetRef.current) {
945
1063
  const scrollDelta = scrollOffset - lastScrollOffsetRef.current;
946
1064
  if (scrollDelta !== 0) {
947
- scrollView.scrollBy(0, scrollDelta);
948
- console.log("ScrollAdjust (web scrollBy)", scrollDelta, "total offset:", scrollOffset);
1065
+ const el = scrollView.getScrollableNode();
1066
+ const prevScroll = el.scrollTop;
1067
+ const nextScroll = prevScroll + scrollDelta;
1068
+ const totalSize = el.scrollHeight;
1069
+ if (scrollDelta > 0 && !ctx.internalState.adjustingFromInitialMount && totalSize < nextScroll + el.clientHeight) {
1070
+ const child = el.firstElementChild;
1071
+ const prevPaddingBottom = child.style.paddingBottom;
1072
+ const pad = (nextScroll + el.clientHeight - totalSize) * 2;
1073
+ child.style.paddingBottom = `${pad}px`;
1074
+ void el.offsetHeight;
1075
+ scrollView.scrollBy(0, scrollDelta);
1076
+ setTimeout(() => {
1077
+ child.style.paddingBottom = prevPaddingBottom;
1078
+ }, 100);
1079
+ } else {
1080
+ scrollView.scrollBy(0, scrollDelta);
1081
+ }
1082
+ if (IS_DEV) {
1083
+ console.log("ScrollAdjust (web scrollBy)", scrollDelta, "total offset:", scrollOffset);
1084
+ }
949
1085
  }
950
1086
  lastScrollOffsetRef.current = scrollOffset;
951
1087
  }
@@ -954,49 +1090,26 @@ function ScrollAdjust() {
954
1090
  useValueListener$("scrollAdjustUserOffset", callback);
955
1091
  return null;
956
1092
  }
957
-
958
- // src/components/SnapWrapper.tsx
959
1093
  function SnapWrapper({ ScrollComponent, ...props }) {
960
1094
  const [snapToOffsets] = useArr$(["snapToOffsets"]);
961
- return /* @__PURE__ */ React.createElement(ScrollComponent, { ...props, snapToOffsets });
962
- }
963
-
964
- // src/hooks/useValue$.ts
965
- function useValue$(key, params) {
966
- const [value] = useArr$([key]);
967
- return value;
1095
+ return /* @__PURE__ */ React3__namespace.createElement(ScrollComponent, { ...props, snapToOffsets });
968
1096
  }
1097
+ var LayoutView = ({ onLayoutChange, refView, children, ...rest }) => {
1098
+ const ref = refView != null ? refView : React3.useRef();
1099
+ useOnLayoutSync({ onLayoutChange, ref });
1100
+ return /* @__PURE__ */ React3__namespace.createElement("div", { ...rest, ref }, children);
1101
+ };
969
1102
 
970
1103
  // src/components/ListComponent.tsx
971
1104
  var getComponent = (Component) => {
972
- if (React4__namespace.isValidElement(Component)) {
1105
+ if (React3__namespace.isValidElement(Component)) {
973
1106
  return Component;
974
1107
  }
975
1108
  if (Component) {
976
- return /* @__PURE__ */ React4__namespace.createElement(Component, null);
1109
+ return /* @__PURE__ */ React3__namespace.createElement(Component, null);
977
1110
  }
978
1111
  return null;
979
1112
  };
980
- var Padding = () => {
981
- const animPaddingTop = useValue$("alignItemsPaddingTop");
982
- return /* @__PURE__ */ React4__namespace.createElement(AnimatedView, { style: { paddingTop: animPaddingTop } });
983
- };
984
- var PaddingDevMode = () => {
985
- const animPaddingTop = useValue$("alignItemsPaddingTop");
986
- return /* @__PURE__ */ React4__namespace.createElement(React4__namespace.Fragment, null, /* @__PURE__ */ React4__namespace.createElement(AnimatedView, { style: { paddingTop: animPaddingTop } }), /* @__PURE__ */ React4__namespace.createElement(
987
- AnimatedView,
988
- {
989
- style: {
990
- backgroundColor: "green",
991
- height: animPaddingTop,
992
- left: 0,
993
- position: "absolute",
994
- right: 0,
995
- top: 0
996
- }
997
- }
998
- ));
999
- };
1000
1113
  var ListComponent = typedMemo(function ListComponent2({
1001
1114
  canRender,
1002
1115
  style,
@@ -1022,16 +1135,15 @@ var ListComponent = typedMemo(function ListComponent2({
1022
1135
  scrollAdjustHandler,
1023
1136
  onLayoutHeader,
1024
1137
  snapToIndices,
1025
- stickyIndices,
1138
+ stickyHeaderIndices,
1026
1139
  ...rest
1027
1140
  }) {
1028
1141
  const ctx = useStateContext();
1029
- const refHeader = React4__namespace.useRef(null);
1030
- const ScrollComponent = renderScrollComponent ? React4.useMemo(
1031
- () => React4__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
1142
+ const ScrollComponent = renderScrollComponent ? React3.useMemo(
1143
+ () => React3__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
1032
1144
  [renderScrollComponent]
1033
1145
  ) : ListComponentScrollView;
1034
- React4__namespace.useEffect(() => {
1146
+ React3__namespace.useEffect(() => {
1035
1147
  if (canRender) {
1036
1148
  setTimeout(() => {
1037
1149
  scrollAdjustHandler.setMounted();
@@ -1039,39 +1151,30 @@ var ListComponent = typedMemo(function ListComponent2({
1039
1151
  }
1040
1152
  }, [canRender]);
1041
1153
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
1042
- const contentContainerStyleWeb = React4.useMemo(() => {
1043
- const base = contentContainerStyle || void 0;
1044
- if (!horizontal) return base;
1045
- if (base && base.height === "100%") return base;
1046
- return { ...base || {}, height: "100%" };
1047
- }, [horizontal, (contentContainerStyle == null ? void 0 : contentContainerStyle.height) === "100%" ? 1 : 0]);
1048
- return /* @__PURE__ */ React4__namespace.createElement(
1154
+ return /* @__PURE__ */ React3__namespace.createElement(
1049
1155
  SnapOrScroll,
1050
1156
  {
1051
1157
  ...rest,
1052
- contentContainerStyle: contentContainerStyleWeb,
1158
+ contentContainerStyle: [
1159
+ contentContainerStyle,
1160
+ horizontal ? {
1161
+ height: "100%"
1162
+ } : {}
1163
+ ],
1053
1164
  contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
1054
1165
  horizontal,
1055
- maintainVisibleContentPosition: maintainVisibleContentPosition && !ListEmptyComponent ? { minIndexForVisible: 0 } : void 0,
1166
+ maintainVisibleContentPosition: maintainVisibleContentPosition ? { minIndexForVisible: 0 } : void 0,
1056
1167
  onLayout,
1057
1168
  onScroll: onScroll2,
1058
1169
  ref: refScrollView,
1059
1170
  ScrollComponent: snapToIndices ? ScrollComponent : void 0,
1060
1171
  style
1061
1172
  },
1062
- maintainVisibleContentPosition && /* @__PURE__ */ React4__namespace.createElement(ScrollAdjust, null),
1063
- ENABLE_DEVMODE ? /* @__PURE__ */ React4__namespace.createElement(PaddingDevMode, null) : /* @__PURE__ */ React4__namespace.createElement(Padding, null),
1064
- ListHeaderComponent && /* @__PURE__ */ React4__namespace.createElement(
1065
- LayoutView,
1066
- {
1067
- onLayoutChange: onLayoutHeader,
1068
- refView: refHeader,
1069
- style: ListHeaderComponentStyle
1070
- },
1071
- getComponent(ListHeaderComponent)
1072
- ),
1173
+ /* @__PURE__ */ React3__namespace.createElement(ScrollAdjust, null),
1174
+ ENABLE_DEVMODE ? /* @__PURE__ */ React3__namespace.createElement(PaddingDevMode, null) : /* @__PURE__ */ React3__namespace.createElement(Padding, null),
1175
+ ListHeaderComponent && /* @__PURE__ */ React3__namespace.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
1073
1176
  ListEmptyComponent && getComponent(ListEmptyComponent),
1074
- canRender && /* @__PURE__ */ React4__namespace.createElement(
1177
+ canRender && !ListEmptyComponent && /* @__PURE__ */ React3__namespace.createElement(
1075
1178
  Containers,
1076
1179
  {
1077
1180
  getRenderedItem: getRenderedItem2,
@@ -1082,7 +1185,7 @@ var ListComponent = typedMemo(function ListComponent2({
1082
1185
  waitForInitialLayout
1083
1186
  }
1084
1187
  ),
1085
- ListFooterComponent && /* @__PURE__ */ React4__namespace.createElement(
1188
+ ListFooterComponent && /* @__PURE__ */ React3__namespace.createElement(
1086
1189
  LayoutView,
1087
1190
  {
1088
1191
  onLayoutChange: (layout) => {
@@ -1093,7 +1196,7 @@ var ListComponent = typedMemo(function ListComponent2({
1093
1196
  },
1094
1197
  getComponent(ListFooterComponent)
1095
1198
  ),
1096
- __DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React4__namespace.createElement(DevNumbers, null)
1199
+ IS_DEV && ENABLE_DEVMODE && /* @__PURE__ */ React3__namespace.createElement(DevNumbers, null)
1097
1200
  );
1098
1201
  });
1099
1202
 
@@ -1105,7 +1208,7 @@ function getId(state, index) {
1105
1208
  }
1106
1209
  const ret = index < data.length ? keyExtractor ? keyExtractor(data[index], index) : index : null;
1107
1210
  const id = ret;
1108
- state.idCache.set(index, id);
1211
+ state.idCache[index] = id;
1109
1212
  return id;
1110
1213
  }
1111
1214
 
@@ -1126,13 +1229,84 @@ function calculateOffsetForIndex(ctx, state, index) {
1126
1229
  return position;
1127
1230
  }
1128
1231
 
1232
+ // src/utils/setPaddingTop.ts
1233
+ function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
1234
+ if (stylePaddingTop !== void 0) {
1235
+ const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
1236
+ if (stylePaddingTop < prevStylePaddingTop) {
1237
+ let prevTotalSize = peek$(ctx, "totalSize") || 0;
1238
+ set$(ctx, "totalSize", prevTotalSize + prevStylePaddingTop);
1239
+ state.timeoutSetPaddingTop = setTimeout(() => {
1240
+ prevTotalSize = peek$(ctx, "totalSize") || 0;
1241
+ set$(ctx, "totalSize", prevTotalSize - prevStylePaddingTop);
1242
+ }, 16);
1243
+ }
1244
+ set$(ctx, "stylePaddingTop", stylePaddingTop);
1245
+ }
1246
+ if (alignItemsPaddingTop !== void 0) {
1247
+ set$(ctx, "alignItemsPaddingTop", alignItemsPaddingTop);
1248
+ }
1249
+ }
1250
+
1251
+ // src/utils/updateAlignItemsPaddingTop.ts
1252
+ function updateAlignItemsPaddingTop(ctx, state) {
1253
+ const {
1254
+ scrollLength,
1255
+ props: { alignItemsAtEnd, data }
1256
+ } = state;
1257
+ if (alignItemsAtEnd) {
1258
+ let alignItemsPaddingTop = 0;
1259
+ if ((data == null ? void 0 : data.length) > 0) {
1260
+ const contentSize = getContentSize(ctx);
1261
+ alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
1262
+ }
1263
+ setPaddingTop(ctx, state, { alignItemsPaddingTop });
1264
+ }
1265
+ }
1266
+
1267
+ // src/core/addTotalSize.ts
1268
+ function addTotalSize(ctx, state, key, add) {
1269
+ const { alignItemsAtEnd } = state.props;
1270
+ const prevTotalSize = state.totalSize;
1271
+ let totalSize = state.totalSize;
1272
+ if (key === null) {
1273
+ totalSize = add;
1274
+ if (state.timeoutSetPaddingTop) {
1275
+ clearTimeout(state.timeoutSetPaddingTop);
1276
+ state.timeoutSetPaddingTop = void 0;
1277
+ }
1278
+ } else {
1279
+ totalSize += add;
1280
+ }
1281
+ if (prevTotalSize !== totalSize) {
1282
+ {
1283
+ state.pendingTotalSize = void 0;
1284
+ state.totalSize = totalSize;
1285
+ set$(ctx, "totalSize", totalSize);
1286
+ if (alignItemsAtEnd) {
1287
+ updateAlignItemsPaddingTop(ctx, state);
1288
+ }
1289
+ }
1290
+ }
1291
+ }
1292
+
1293
+ // src/core/setSize.ts
1294
+ function setSize(ctx, state, itemKey, size) {
1295
+ const { sizes } = state;
1296
+ const previousSize = sizes.get(itemKey);
1297
+ const diff = previousSize !== void 0 ? size - previousSize : size;
1298
+ if (diff !== 0) {
1299
+ addTotalSize(ctx, state, itemKey, diff);
1300
+ }
1301
+ sizes.set(itemKey, size);
1302
+ }
1303
+
1129
1304
  // src/utils/getItemSize.ts
1130
- function getItemSize(state, key, index, data, useAverageSize) {
1131
- var _a, _b;
1305
+ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedSize) {
1306
+ var _a3, _b;
1132
1307
  const {
1133
1308
  sizesKnown,
1134
1309
  sizes,
1135
- scrollingTo,
1136
1310
  averageSizes,
1137
1311
  props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
1138
1312
  } = state;
@@ -1141,7 +1315,14 @@ function getItemSize(state, key, index, data, useAverageSize) {
1141
1315
  return sizeKnown;
1142
1316
  }
1143
1317
  let size;
1144
- const itemType = getItemType ? (_a = getItemType(data, index)) != null ? _a : "" : "";
1318
+ const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
1319
+ const scrollingTo = peek$(ctx, "scrollingTo");
1320
+ if (preferCachedSize) {
1321
+ const cachedSize = sizes.get(key);
1322
+ if (cachedSize !== void 0) {
1323
+ return cachedSize;
1324
+ }
1325
+ }
1145
1326
  if (getFixedItemSize) {
1146
1327
  size = getFixedItemSize(index, data, itemType);
1147
1328
  if (size !== void 0) {
@@ -1163,53 +1344,234 @@ function getItemSize(state, key, index, data, useAverageSize) {
1163
1344
  if (size === void 0) {
1164
1345
  size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
1165
1346
  }
1166
- sizes.set(key, size);
1347
+ setSize(ctx, state, key, size);
1167
1348
  return size;
1168
1349
  }
1169
1350
 
1170
1351
  // src/core/calculateOffsetWithOffsetPosition.ts
1171
- function calculateOffsetWithOffsetPosition(state, offsetParam, params) {
1352
+ function calculateOffsetWithOffsetPosition(ctx, state, offsetParam, params) {
1172
1353
  const { index, viewOffset, viewPosition } = params;
1173
1354
  let offset = offsetParam;
1174
1355
  if (viewOffset) {
1175
1356
  offset -= viewOffset;
1176
1357
  }
1177
1358
  if (viewPosition !== void 0 && index !== void 0) {
1178
- offset -= viewPosition * (state.scrollLength - getItemSize(state, getId(state, index), index, state.props.data[index]));
1359
+ offset -= viewPosition * (state.scrollLength - getItemSize(ctx, state, getId(state, index), index, state.props.data[index]));
1179
1360
  }
1180
1361
  return offset;
1181
1362
  }
1182
1363
 
1183
1364
  // src/core/finishScrollTo.ts
1184
- var finishScrollTo = (state) => {
1365
+ function finishScrollTo(ctx, state) {
1366
+ var _a3, _b;
1185
1367
  if (state) {
1186
- state.scrollingTo = void 0;
1187
1368
  state.scrollHistory.length = 0;
1369
+ state.initialScroll = void 0;
1370
+ state.initialAnchor = void 0;
1371
+ set$(ctx, "scrollingTo", void 0);
1372
+ if (state.pendingTotalSize !== void 0) {
1373
+ addTotalSize(ctx, state, null, state.pendingTotalSize);
1374
+ }
1375
+ if ((_a3 = state.props) == null ? void 0 : _a3.data) {
1376
+ (_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
1377
+ }
1188
1378
  }
1189
- };
1379
+ }
1190
1380
 
1191
1381
  // src/core/scrollTo.ts
1192
- function scrollTo(state, params = {}) {
1193
- var _a;
1194
- const { animated, noScrollingTo } = params;
1382
+ function scrollTo(ctx, state, params) {
1383
+ var _a3;
1384
+ const { noScrollingTo, ...scrollTarget } = params;
1385
+ const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
1195
1386
  const {
1196
1387
  refScroller,
1197
1388
  props: { horizontal }
1198
1389
  } = state;
1199
- const offset = calculateOffsetWithOffsetPosition(state, params.offset, params);
1390
+ let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
1391
+ if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
1392
+ const maxOffset = Math.max(0, getContentSize(ctx) - state.scrollLength);
1393
+ offset = Math.min(offset, maxOffset);
1394
+ }
1200
1395
  state.scrollHistory.length = 0;
1201
1396
  if (!noScrollingTo) {
1202
- state.scrollingTo = params;
1397
+ set$(ctx, "scrollingTo", scrollTarget);
1203
1398
  }
1204
1399
  state.scrollPending = offset;
1205
- (_a = refScroller.current) == null ? void 0 : _a.scrollTo({
1206
- animated: !!animated,
1207
- x: horizontal ? offset : 0,
1208
- y: horizontal ? 0 : offset
1209
- });
1400
+ if (!isInitialScroll || Platform.OS === "android") {
1401
+ (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1402
+ animated: !!animated,
1403
+ x: horizontal ? offset : 0,
1404
+ y: horizontal ? 0 : offset
1405
+ });
1406
+ }
1210
1407
  if (!animated) {
1211
1408
  state.scroll = offset;
1212
- setTimeout(() => finishScrollTo(state), 100);
1409
+ {
1410
+ const unlisten = listen$(ctx, "containersDidLayout", (value) => {
1411
+ if (value && peek$(ctx, "scrollingTo")) {
1412
+ finishScrollTo(ctx, state);
1413
+ unlisten();
1414
+ }
1415
+ });
1416
+ }
1417
+ if (isInitialScroll) {
1418
+ setTimeout(() => {
1419
+ state.initialScroll = void 0;
1420
+ }, 500);
1421
+ }
1422
+ }
1423
+ }
1424
+
1425
+ // src/utils/checkThreshold.ts
1426
+ var HYSTERESIS_MULTIPLIER = 1.3;
1427
+ var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
1428
+ const absDistance = Math.abs(distance);
1429
+ const within = atThreshold || threshold > 0 && absDistance <= threshold;
1430
+ const updateSnapshot = () => {
1431
+ setSnapshot == null ? void 0 : setSnapshot({
1432
+ atThreshold,
1433
+ contentSize: context.contentSize,
1434
+ dataLength: context.dataLength,
1435
+ scrollPosition: context.scrollPosition
1436
+ });
1437
+ };
1438
+ if (!wasReached) {
1439
+ if (!within) {
1440
+ return false;
1441
+ }
1442
+ onReached == null ? void 0 : onReached(distance);
1443
+ updateSnapshot();
1444
+ return true;
1445
+ }
1446
+ const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
1447
+ if (reset) {
1448
+ setSnapshot == null ? void 0 : setSnapshot(void 0);
1449
+ return false;
1450
+ }
1451
+ if (within) {
1452
+ const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
1453
+ if (changed) {
1454
+ onReached == null ? void 0 : onReached(distance);
1455
+ updateSnapshot();
1456
+ }
1457
+ }
1458
+ return true;
1459
+ };
1460
+
1461
+ // src/utils/checkAtBottom.ts
1462
+ function checkAtBottom(ctx, state) {
1463
+ var _a3;
1464
+ if (!state) {
1465
+ return;
1466
+ }
1467
+ const {
1468
+ queuedInitialLayout,
1469
+ scrollLength,
1470
+ scroll,
1471
+ maintainingScrollAtEnd,
1472
+ props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
1473
+ } = state;
1474
+ const contentSize = getContentSize(ctx);
1475
+ if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
1476
+ const distanceFromEnd = contentSize - scroll - scrollLength;
1477
+ const isContentLess = contentSize < scrollLength;
1478
+ state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
1479
+ state.isEndReached = checkThreshold(
1480
+ distanceFromEnd,
1481
+ isContentLess,
1482
+ onEndReachedThreshold * scrollLength,
1483
+ state.isEndReached,
1484
+ state.endReachedSnapshot,
1485
+ {
1486
+ contentSize,
1487
+ dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
1488
+ scrollPosition: scroll
1489
+ },
1490
+ (distance) => {
1491
+ var _a4, _b;
1492
+ return (_b = (_a4 = state.props).onEndReached) == null ? void 0 : _b.call(_a4, { distanceFromEnd: distance });
1493
+ },
1494
+ (snapshot) => {
1495
+ state.endReachedSnapshot = snapshot;
1496
+ }
1497
+ );
1498
+ }
1499
+ }
1500
+
1501
+ // src/utils/checkAtTop.ts
1502
+ function checkAtTop(state) {
1503
+ var _a3;
1504
+ if (!state) {
1505
+ return;
1506
+ }
1507
+ const {
1508
+ scrollLength,
1509
+ scroll,
1510
+ props: { onStartReachedThreshold }
1511
+ } = state;
1512
+ const distanceFromTop = scroll;
1513
+ state.isAtStart = distanceFromTop <= 0;
1514
+ state.isStartReached = checkThreshold(
1515
+ distanceFromTop,
1516
+ false,
1517
+ onStartReachedThreshold * scrollLength,
1518
+ state.isStartReached,
1519
+ state.startReachedSnapshot,
1520
+ {
1521
+ contentSize: state.totalSize,
1522
+ dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
1523
+ scrollPosition: scroll
1524
+ },
1525
+ (distance) => {
1526
+ var _a4, _b;
1527
+ return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
1528
+ },
1529
+ (snapshot) => {
1530
+ state.startReachedSnapshot = snapshot;
1531
+ }
1532
+ );
1533
+ }
1534
+
1535
+ // src/core/updateScroll.ts
1536
+ function updateScroll(ctx, state, newScroll, forceUpdate) {
1537
+ var _a3;
1538
+ const scrollingTo = peek$(ctx, "scrollingTo");
1539
+ state.hasScrolled = true;
1540
+ state.lastBatchingAction = Date.now();
1541
+ const currentTime = Date.now();
1542
+ const adjust = state.scrollAdjustHandler.getAdjust();
1543
+ const lastHistoryAdjust = state.lastScrollAdjustForHistory;
1544
+ const adjustChanged = lastHistoryAdjust !== void 0 && Math.abs(adjust - lastHistoryAdjust) > 0.1;
1545
+ if (adjustChanged) {
1546
+ state.scrollHistory.length = 0;
1547
+ }
1548
+ state.lastScrollAdjustForHistory = adjust;
1549
+ if (scrollingTo === void 0 && !(state.scrollHistory.length === 0 && newScroll === state.scroll)) {
1550
+ if (!adjustChanged) {
1551
+ state.scrollHistory.push({ scroll: newScroll, time: currentTime });
1552
+ }
1553
+ }
1554
+ if (state.scrollHistory.length > 5) {
1555
+ state.scrollHistory.shift();
1556
+ }
1557
+ state.scrollPrev = state.scroll;
1558
+ state.scrollPrevTime = state.scrollTime;
1559
+ state.scroll = newScroll;
1560
+ state.scrollTime = currentTime;
1561
+ const ignoreScrollFromMVCP = state.ignoreScrollFromMVCP;
1562
+ if (ignoreScrollFromMVCP && !scrollingTo) {
1563
+ const { lt, gt } = ignoreScrollFromMVCP;
1564
+ if (lt && newScroll < lt || gt && newScroll > gt) {
1565
+ state.ignoreScrollFromMVCPIgnored = true;
1566
+ return;
1567
+ }
1568
+ }
1569
+ if (state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollPrev) > 2) {
1570
+ state.ignoreScrollFromMVCPIgnored = false;
1571
+ (_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
1572
+ checkAtBottom(ctx, state);
1573
+ checkAtTop(state);
1574
+ state.dataChangeNeedsScrollUpdate = false;
1213
1575
  }
1214
1576
  }
1215
1577
 
@@ -1219,6 +1581,9 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1219
1581
  const doit = () => {
1220
1582
  {
1221
1583
  state.scrollAdjustHandler.requestAdjust(positionDiff);
1584
+ if (state.adjustingFromInitialMount) {
1585
+ state.adjustingFromInitialMount--;
1586
+ }
1222
1587
  }
1223
1588
  };
1224
1589
  state.scroll += positionDiff;
@@ -1226,44 +1591,77 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1226
1591
  const didLayout = peek$(ctx, "containersDidLayout");
1227
1592
  if (didLayout) {
1228
1593
  doit();
1229
- const threshold = state.scroll - positionDiff / 2;
1230
- if (!state.ignoreScrollFromMVCP) {
1231
- state.ignoreScrollFromMVCP = {};
1232
- }
1233
- if (positionDiff > 0) {
1234
- state.ignoreScrollFromMVCP.lt = threshold;
1235
- } else {
1236
- state.ignoreScrollFromMVCP.gt = threshold;
1237
- }
1238
- if (state.ignoreScrollFromMVCPTimeout) {
1239
- clearTimeout(state.ignoreScrollFromMVCPTimeout);
1240
- }
1241
- state.ignoreScrollFromMVCPTimeout = setTimeout(
1242
- () => {
1243
- state.ignoreScrollFromMVCP = void 0;
1244
- },
1245
- 100
1246
- );
1247
1594
  } else {
1595
+ state.adjustingFromInitialMount = (state.adjustingFromInitialMount || 0) + 1;
1248
1596
  requestAnimationFrame(doit);
1249
1597
  }
1250
1598
  }
1251
1599
  }
1252
1600
 
1601
+ // src/core/ensureInitialAnchor.ts
1602
+ var INITIAL_ANCHOR_TOLERANCE = 0.5;
1603
+ var INITIAL_ANCHOR_MAX_ATTEMPTS = 4;
1604
+ var INITIAL_ANCHOR_SETTLED_TICKS = 2;
1605
+ function ensureInitialAnchor(ctx, state) {
1606
+ var _a3, _b, _c, _d, _e;
1607
+ const anchor = state.initialAnchor;
1608
+ const item = state.props.data[anchor.index];
1609
+ const containersDidLayout = peek$(ctx, "containersDidLayout");
1610
+ if (!containersDidLayout) {
1611
+ return;
1612
+ }
1613
+ const id = getId(state, anchor.index);
1614
+ if (state.positions.get(id) === void 0) {
1615
+ return;
1616
+ }
1617
+ const size = getItemSize(ctx, state, id, anchor.index, item, true, true);
1618
+ if (size === void 0) {
1619
+ return;
1620
+ }
1621
+ const availableSpace = Math.max(0, state.scrollLength - size);
1622
+ const desiredOffset = calculateOffsetForIndex(ctx, state, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1623
+ const contentSize = getContentSize(ctx);
1624
+ const maxOffset = Math.max(0, contentSize - state.scrollLength);
1625
+ const clampedDesiredOffset = Math.max(0, Math.min(desiredOffset, maxOffset));
1626
+ const delta = clampedDesiredOffset - state.scroll;
1627
+ if (Math.abs(delta) <= INITIAL_ANCHOR_TOLERANCE) {
1628
+ const settledTicks = ((_c = anchor.settledTicks) != null ? _c : 0) + 1;
1629
+ if (settledTicks >= INITIAL_ANCHOR_SETTLED_TICKS) {
1630
+ state.initialAnchor = void 0;
1631
+ } else {
1632
+ anchor.settledTicks = settledTicks;
1633
+ }
1634
+ return;
1635
+ }
1636
+ if (((_d = anchor.attempts) != null ? _d : 0) >= INITIAL_ANCHOR_MAX_ATTEMPTS) {
1637
+ state.initialAnchor = void 0;
1638
+ return;
1639
+ }
1640
+ const lastDelta = anchor.lastDelta;
1641
+ if (lastDelta !== void 0 && Math.abs(delta) >= Math.abs(lastDelta)) {
1642
+ state.initialAnchor = void 0;
1643
+ return;
1644
+ }
1645
+ Object.assign(anchor, {
1646
+ attempts: ((_e = anchor.attempts) != null ? _e : 0) + 1,
1647
+ lastDelta: delta,
1648
+ settledTicks: 0
1649
+ });
1650
+ requestAdjust(ctx, state, delta);
1651
+ }
1652
+
1253
1653
  // src/core/mvcp.ts
1254
1654
  function prepareMVCP(ctx, state, dataChanged) {
1255
- const {
1256
- idsInView,
1257
- positions,
1258
- scrollingTo,
1259
- props: { maintainVisibleContentPosition }
1260
- } = state;
1655
+ const { idsInView, positions, props } = state;
1656
+ const { maintainVisibleContentPosition } = props;
1657
+ const scrollingTo = peek$(ctx, "scrollingTo");
1261
1658
  let prevPosition;
1262
1659
  let targetId;
1263
1660
  const idsInViewWithPositions = [];
1264
1661
  const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
1265
- if (maintainVisibleContentPosition) {
1266
- const indexByKey = state.indexByKey;
1662
+ const shouldMVCP = !dataChanged || maintainVisibleContentPosition;
1663
+ const indexByKey = state.indexByKey;
1664
+ if (shouldMVCP) {
1267
1665
  if (scrollTarget !== void 0) {
1268
1666
  targetId = getId(state, scrollTarget);
1269
1667
  } else if (idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
@@ -1276,70 +1674,106 @@ function prepareMVCP(ctx, state, dataChanged) {
1276
1674
  }
1277
1675
  }
1278
1676
  } else {
1279
- targetId = state.idsInView.find((id) => indexByKey.get(id) !== void 0);
1677
+ targetId = idsInView.find((id) => indexByKey.get(id) !== void 0);
1280
1678
  }
1281
1679
  }
1282
1680
  if (targetId !== void 0) {
1283
1681
  prevPosition = positions.get(targetId);
1284
1682
  }
1285
- }
1286
- return () => {
1287
- let positionDiff;
1288
- if (dataChanged && targetId === void 0) {
1289
- for (let i = 0; i < idsInViewWithPositions.length; i++) {
1290
- const { id, position } = idsInViewWithPositions[i];
1291
- const newPosition = positions.get(id);
1683
+ return () => {
1684
+ let positionDiff;
1685
+ if (dataChanged && targetId === void 0 && maintainVisibleContentPosition) {
1686
+ for (let i = 0; i < idsInViewWithPositions.length; i++) {
1687
+ const { id, position } = idsInViewWithPositions[i];
1688
+ const newPosition = positions.get(id);
1689
+ if (newPosition !== void 0) {
1690
+ positionDiff = newPosition - position;
1691
+ break;
1692
+ }
1693
+ }
1694
+ }
1695
+ if (targetId !== void 0 && prevPosition !== void 0) {
1696
+ const newPosition = positions.get(targetId);
1292
1697
  if (newPosition !== void 0) {
1293
- positionDiff = newPosition - position;
1294
- break;
1698
+ const totalSize = getContentSize(ctx);
1699
+ let diff = newPosition - prevPosition;
1700
+ if (diff !== 0 && state.scroll + state.scrollLength > totalSize) {
1701
+ if (diff > 0) {
1702
+ diff = Math.max(0, totalSize - state.scroll - state.scrollLength);
1703
+ } else {
1704
+ diff = 0;
1705
+ }
1706
+ }
1707
+ positionDiff = diff;
1295
1708
  }
1296
1709
  }
1297
- }
1298
- if (targetId !== void 0 && prevPosition !== void 0) {
1299
- const newPosition = positions.get(targetId);
1300
- if (newPosition !== void 0) {
1301
- positionDiff = newPosition - prevPosition;
1710
+ if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
1711
+ requestAdjust(ctx, state, positionDiff);
1302
1712
  }
1303
- }
1304
- if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
1305
- requestAdjust(ctx, state, positionDiff);
1306
- }
1307
- };
1713
+ };
1714
+ }
1308
1715
  }
1309
1716
 
1310
- // src/utils/setPaddingTop.ts
1311
- function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
1312
- if (stylePaddingTop !== void 0) {
1313
- const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
1314
- if (stylePaddingTop < prevStylePaddingTop) {
1315
- let prevTotalSize = peek$(ctx, "totalSize") || 0;
1316
- set$(ctx, "totalSize", prevTotalSize + prevStylePaddingTop);
1317
- state.timeoutSetPaddingTop = setTimeout(() => {
1318
- prevTotalSize = peek$(ctx, "totalSize") || 0;
1319
- set$(ctx, "totalSize", prevTotalSize - prevStylePaddingTop);
1320
- }, 16);
1321
- }
1322
- set$(ctx, "stylePaddingTop", stylePaddingTop);
1717
+ // src/core/prepareColumnStartState.ts
1718
+ function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1719
+ var _a3;
1720
+ const numColumns = peek$(ctx, "numColumns");
1721
+ let rowStartIndex = startIndex;
1722
+ const columnAtStart = state.columns.get(state.idCache[startIndex]);
1723
+ if (columnAtStart !== 1) {
1724
+ rowStartIndex = findRowStartIndex(state, numColumns, startIndex);
1323
1725
  }
1324
- if (alignItemsPaddingTop !== void 0) {
1325
- set$(ctx, "alignItemsPaddingTop", alignItemsPaddingTop);
1726
+ let currentRowTop = 0;
1727
+ const curId = state.idCache[rowStartIndex];
1728
+ const column = state.columns.get(curId);
1729
+ if (rowStartIndex > 0) {
1730
+ const prevIndex = rowStartIndex - 1;
1731
+ const prevId = state.idCache[prevIndex];
1732
+ const prevPosition = (_a3 = state.positions.get(prevId)) != null ? _a3 : 0;
1733
+ const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
1734
+ const prevRowHeight = calculateRowMaxSize(ctx, state, prevRowStart, prevIndex, useAverageSize);
1735
+ currentRowTop = prevPosition + prevRowHeight;
1326
1736
  }
1737
+ return {
1738
+ column,
1739
+ currentRowTop,
1740
+ startIndex: rowStartIndex
1741
+ };
1327
1742
  }
1328
-
1329
- // src/utils/updateAlignItemsPaddingTop.ts
1330
- function updateAlignItemsPaddingTop(ctx, state) {
1331
- const {
1332
- scrollLength,
1333
- props: { alignItemsAtEnd, data }
1334
- } = state;
1335
- if (alignItemsAtEnd) {
1336
- let alignItemsPaddingTop = 0;
1337
- if ((data == null ? void 0 : data.length) > 0) {
1338
- const contentSize = getContentSize(ctx);
1339
- alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
1743
+ function findRowStartIndex(state, numColumns, index) {
1744
+ if (numColumns <= 1) {
1745
+ return Math.max(0, index);
1746
+ }
1747
+ let rowStart = Math.max(0, index);
1748
+ while (rowStart > 0) {
1749
+ const columnForIndex = state.columns.get(state.idCache[rowStart]);
1750
+ if (columnForIndex === 1) {
1751
+ break;
1752
+ }
1753
+ rowStart--;
1754
+ }
1755
+ return rowStart;
1756
+ }
1757
+ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1758
+ if (endIndex < startIndex) {
1759
+ return 0;
1760
+ }
1761
+ const { data } = state.props;
1762
+ if (!data) {
1763
+ return 0;
1764
+ }
1765
+ let maxSize = 0;
1766
+ for (let i = startIndex; i <= endIndex; i++) {
1767
+ if (i < 0 || i >= data.length) {
1768
+ continue;
1769
+ }
1770
+ const id = state.idCache[i];
1771
+ const size = getItemSize(ctx, state, id, i, data[i], useAverageSize);
1772
+ if (size > maxSize) {
1773
+ maxSize = size;
1340
1774
  }
1341
- setPaddingTop(ctx, state, { alignItemsPaddingTop });
1342
1775
  }
1776
+ return maxSize;
1343
1777
  }
1344
1778
 
1345
1779
  // src/core/updateTotalSize.ts
@@ -1355,7 +1789,7 @@ function updateTotalSize(ctx, state) {
1355
1789
  if (lastId !== void 0) {
1356
1790
  const lastPosition = positions.get(lastId);
1357
1791
  if (lastPosition !== void 0) {
1358
- const lastSize = getItemSize(state, lastId, data.length - 1, data[data.length - 1]);
1792
+ const lastSize = getItemSize(ctx, state, lastId, data.length - 1, data[data.length - 1]);
1359
1793
  if (lastSize !== void 0) {
1360
1794
  const totalSize = lastPosition + lastSize;
1361
1795
  addTotalSize(ctx, state, null, totalSize);
@@ -1364,20 +1798,44 @@ function updateTotalSize(ctx, state) {
1364
1798
  }
1365
1799
  }
1366
1800
  }
1367
- function addTotalSize(ctx, state, key, add) {
1368
- const { alignItemsAtEnd } = state.props;
1369
- {
1370
- state.totalSize = add;
1371
- if (state.timeoutSetPaddingTop) {
1372
- clearTimeout(state.timeoutSetPaddingTop);
1373
- state.timeoutSetPaddingTop = void 0;
1801
+
1802
+ // src/utils/getScrollVelocity.ts
1803
+ var getScrollVelocity = (state) => {
1804
+ const { scrollHistory } = state;
1805
+ let velocity = 0;
1806
+ if (scrollHistory.length >= 1) {
1807
+ const newest = scrollHistory[scrollHistory.length - 1];
1808
+ let oldest;
1809
+ let start = 0;
1810
+ const now = Date.now();
1811
+ for (let i = 0; i < scrollHistory.length - 1; i++) {
1812
+ const entry = scrollHistory[i];
1813
+ const nextEntry = scrollHistory[i + 1];
1814
+ if (i > 0) {
1815
+ const prevEntry = scrollHistory[i - 1];
1816
+ const prevDirection = entry.scroll - prevEntry.scroll;
1817
+ const currentDirection = nextEntry.scroll - entry.scroll;
1818
+ if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
1819
+ start = i;
1820
+ break;
1821
+ }
1822
+ }
1823
+ }
1824
+ for (let i = start; i < scrollHistory.length - 1; i++) {
1825
+ const entry = scrollHistory[i];
1826
+ if (now - entry.time <= 1e3) {
1827
+ oldest = entry;
1828
+ break;
1829
+ }
1830
+ }
1831
+ if (oldest && oldest !== newest) {
1832
+ const scrollDiff = newest.scroll - oldest.scroll;
1833
+ const timeDiff = newest.time - oldest.time;
1834
+ velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
1374
1835
  }
1375
1836
  }
1376
- set$(ctx, "totalSize", state.totalSize);
1377
- if (alignItemsAtEnd) {
1378
- updateAlignItemsPaddingTop(ctx, state);
1379
- }
1380
- }
1837
+ return velocity;
1838
+ };
1381
1839
 
1382
1840
  // src/utils/updateSnapToOffsets.ts
1383
1841
  function updateSnapToOffsets(ctx, state) {
@@ -1394,9 +1852,14 @@ function updateSnapToOffsets(ctx, state) {
1394
1852
  set$(ctx, "snapToOffsets", snapToOffsets);
1395
1853
  }
1396
1854
 
1397
- // src/core/updateAllPositions.ts
1398
- function updateAllPositions(ctx, state, dataChanged, startIndex = 0) {
1399
- var _a, _b, _c, _d, _e, _f;
1855
+ // src/core/updateItemPositions.ts
1856
+ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
1857
+ doMVCP: false,
1858
+ forceFullUpdate: false,
1859
+ scrollBottomBuffered: -1,
1860
+ startIndex: 0
1861
+ }) {
1862
+ var _a3, _b, _c, _d, _e;
1400
1863
  const {
1401
1864
  columns,
1402
1865
  indexByKey,
@@ -1406,32 +1869,51 @@ function updateAllPositions(ctx, state, dataChanged, startIndex = 0) {
1406
1869
  props: { getEstimatedItemSize, snapToIndices, enableAverages }
1407
1870
  } = state;
1408
1871
  const data = state.props.data;
1872
+ const dataLength = data.length;
1409
1873
  const numColumns = peek$(ctx, "numColumns");
1410
- const indexByKeyForChecking = __DEV__ ? /* @__PURE__ */ new Map() : void 0;
1874
+ const scrollingTo = peek$(ctx, "scrollingTo");
1875
+ const hasColumns = numColumns > 1;
1876
+ const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
1877
+ const shouldOptimize = !forceFullUpdate && !dataChanged && Math.abs(getScrollVelocity(state)) > 0;
1878
+ const maxVisibleArea = scrollBottomBuffered + 1e3;
1411
1879
  const useAverageSize = enableAverages && !getEstimatedItemSize;
1880
+ const preferCachedSize = !doMVCP || dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0) !== 0;
1412
1881
  let currentRowTop = 0;
1413
1882
  let column = 1;
1414
1883
  let maxSizeInRow = 0;
1415
- const hasColumns = numColumns > 1;
1416
1884
  if (startIndex > 0) {
1417
- const prevIndex = startIndex - 1;
1418
- const prevId = (_a = idCache.get(prevIndex)) != null ? _a : getId(state, prevIndex);
1419
- const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
1420
1885
  if (hasColumns) {
1421
- const prevColumn = (_c = columns.get(prevId)) != null ? _c : 1;
1422
- currentRowTop = prevPosition;
1423
- column = prevColumn % numColumns + 1;
1424
- } else {
1425
- const prevSize = (_d = sizesKnown.get(prevId)) != null ? _d : getItemSize(state, prevId, prevIndex, data[prevIndex], useAverageSize);
1886
+ const { startIndex: processedStartIndex, currentRowTop: initialRowTop } = prepareColumnStartState(
1887
+ ctx,
1888
+ state,
1889
+ startIndex,
1890
+ useAverageSize
1891
+ );
1892
+ startIndex = processedStartIndex;
1893
+ currentRowTop = initialRowTop;
1894
+ } else if (startIndex < dataLength) {
1895
+ const prevIndex = startIndex - 1;
1896
+ const prevId = getId(state, prevIndex);
1897
+ const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
1898
+ const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, state, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
1426
1899
  currentRowTop = prevPosition + prevSize;
1427
1900
  }
1428
1901
  }
1429
1902
  const needsIndexByKey = dataChanged || indexByKey.size === 0;
1430
- const dataLength = data.length;
1903
+ let didBreakEarly = false;
1904
+ let breakAt;
1431
1905
  for (let i = startIndex; i < dataLength; i++) {
1432
- const id = (_e = idCache.get(i)) != null ? _e : getId(state, i);
1433
- const size = (_f = sizesKnown.get(id)) != null ? _f : getItemSize(state, id, i, data[i], useAverageSize);
1434
- if (__DEV__ && needsIndexByKey) {
1906
+ if (shouldOptimize && breakAt !== void 0 && i > breakAt) {
1907
+ didBreakEarly = true;
1908
+ break;
1909
+ }
1910
+ if (shouldOptimize && breakAt === void 0 && !scrollingTo && !dataChanged && currentRowTop > maxVisibleArea) {
1911
+ const itemsPerRow = hasColumns ? numColumns : 1;
1912
+ breakAt = i + itemsPerRow + 10;
1913
+ }
1914
+ const id = (_d = idCache[i]) != null ? _d : getId(state, i);
1915
+ const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, state, id, i, data[i], useAverageSize, preferCachedSize);
1916
+ if (IS_DEV && needsIndexByKey) {
1435
1917
  if (indexByKeyForChecking.has(id)) {
1436
1918
  console.error(
1437
1919
  `[legend-list] Error: Detected overlapping key (${id}) which causes missing items and gaps and other terrrible things. Check that keyExtractor returns unique values.`
@@ -1458,7 +1940,9 @@ function updateAllPositions(ctx, state, dataChanged, startIndex = 0) {
1458
1940
  currentRowTop += size;
1459
1941
  }
1460
1942
  }
1461
- updateTotalSize(ctx, state);
1943
+ if (!didBreakEarly) {
1944
+ updateTotalSize(ctx, state);
1945
+ }
1462
1946
  if (snapToIndices) {
1463
1947
  updateSnapToOffsets(ctx, state);
1464
1948
  }
@@ -1478,6 +1962,21 @@ function ensureViewabilityState(ctx, configId) {
1478
1962
  }
1479
1963
  return state;
1480
1964
  }
1965
+ function setupViewability(props) {
1966
+ let { viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged } = props;
1967
+ if (viewabilityConfig || onViewableItemsChanged) {
1968
+ viewabilityConfigCallbackPairs = [
1969
+ ...viewabilityConfigCallbackPairs || [],
1970
+ {
1971
+ onViewableItemsChanged,
1972
+ viewabilityConfig: viewabilityConfig || {
1973
+ viewAreaCoveragePercentThreshold: 0
1974
+ }
1975
+ }
1976
+ ];
1977
+ }
1978
+ return viewabilityConfigCallbackPairs;
1979
+ }
1481
1980
  function updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollSize, start, end) {
1482
1981
  const {
1483
1982
  timeouts,
@@ -1631,16 +2130,6 @@ function isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize,
1631
2130
  const value = ctx.mapViewabilityAmountValues.get(containerId) || computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
1632
2131
  return value.isViewable;
1633
2132
  }
1634
- function findContainerId(ctx, key) {
1635
- const numContainers = peek$(ctx, "numContainers");
1636
- for (let i = 0; i < numContainers; i++) {
1637
- const itemKey = peek$(ctx, `containerItemKey${i}`);
1638
- if (itemKey === key) {
1639
- return i;
1640
- }
1641
- }
1642
- return -1;
1643
- }
1644
2133
  function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
1645
2134
  const key = containerId + configId;
1646
2135
  ctx.mapViewabilityValues.set(key, viewToken);
@@ -1649,9 +2138,12 @@ function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
1649
2138
  }
1650
2139
 
1651
2140
  // src/utils/checkAllSizesKnown.ts
2141
+ function isNullOrUndefined2(value) {
2142
+ return value === null || value === void 0;
2143
+ }
1652
2144
  function checkAllSizesKnown(state) {
1653
2145
  const { startBuffered, endBuffered, sizesKnown } = state;
1654
- if (endBuffered !== null && startBuffered >= 0 && endBuffered >= 0) {
2146
+ if (!isNullOrUndefined2(endBuffered) && !isNullOrUndefined2(startBuffered) && startBuffered >= 0 && endBuffered >= 0) {
1655
2147
  let areAllKnown = true;
1656
2148
  for (let i = startBuffered; areAllKnown && i <= endBuffered; i++) {
1657
2149
  const key = getId(state, i);
@@ -1668,6 +2160,8 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1668
2160
  const { stickyContainerPool, containerItemTypes } = state;
1669
2161
  const result = [];
1670
2162
  const availableContainers = [];
2163
+ const pendingRemovalSet = new Set(pendingRemoval);
2164
+ let pendingRemovalChanged = false;
1671
2165
  const stickyIndicesSet = state.props.stickyIndicesSet;
1672
2166
  const stickyItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => stickyIndicesSet.has(index))) || [];
1673
2167
  const canReuseContainer = (containerIndex, requiredType) => {
@@ -1683,12 +2177,11 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1683
2177
  let foundContainer = false;
1684
2178
  for (const containerIndex of stickyContainerPool) {
1685
2179
  const key = peek$(ctx, `containerItemKey${containerIndex}`);
1686
- const isPendingRemoval = pendingRemoval.includes(containerIndex);
1687
- if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType)) {
2180
+ const isPendingRemoval = pendingRemovalSet.has(containerIndex);
2181
+ if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType) && !result.includes(containerIndex)) {
1688
2182
  result.push(containerIndex);
1689
- if (isPendingRemoval) {
1690
- const index = pendingRemoval.indexOf(containerIndex);
1691
- pendingRemoval.splice(index, 1);
2183
+ if (isPendingRemoval && pendingRemovalSet.delete(containerIndex)) {
2184
+ pendingRemovalChanged = true;
1692
2185
  }
1693
2186
  foundContainer = true;
1694
2187
  if (requiredItemTypes) typeIndex++;
@@ -1708,13 +2201,11 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1708
2201
  }
1709
2202
  const key = peek$(ctx, `containerItemKey${u}`);
1710
2203
  let isOk = key === void 0;
1711
- if (!isOk) {
1712
- const index = pendingRemoval.indexOf(u);
1713
- if (index !== -1) {
1714
- pendingRemoval.splice(index, 1);
1715
- const requiredType = neededTypes[typeIndex];
1716
- isOk = canReuseContainer(u, requiredType);
1717
- }
2204
+ if (!isOk && pendingRemovalSet.has(u)) {
2205
+ pendingRemovalSet.delete(u);
2206
+ pendingRemovalChanged = true;
2207
+ const requiredType = neededTypes[typeIndex];
2208
+ isOk = canReuseContainer(u, requiredType);
1718
2209
  }
1719
2210
  if (isOk) {
1720
2211
  result.push(u);
@@ -1757,7 +2248,7 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1757
2248
  for (let i = 0; i < stillNeeded; i++) {
1758
2249
  result.push(numContainers + i);
1759
2250
  }
1760
- if (__DEV__ && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
2251
+ if (IS_DEV && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
1761
2252
  console.warn(
1762
2253
  "[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.",
1763
2254
  {
@@ -1772,50 +2263,18 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1772
2263
  }
1773
2264
  }
1774
2265
  }
2266
+ if (pendingRemovalChanged) {
2267
+ pendingRemoval.length = 0;
2268
+ for (const value of pendingRemovalSet) {
2269
+ pendingRemoval.push(value);
2270
+ }
2271
+ }
1775
2272
  return result.sort(comparatorDefault);
1776
2273
  }
1777
2274
  function comparatorByDistance(a, b) {
1778
2275
  return b.distance - a.distance;
1779
2276
  }
1780
2277
 
1781
- // src/utils/getScrollVelocity.ts
1782
- var getScrollVelocity = (state) => {
1783
- const { scrollHistory } = state;
1784
- let velocity = 0;
1785
- if (scrollHistory.length >= 1) {
1786
- const newest = scrollHistory[scrollHistory.length - 1];
1787
- let oldest;
1788
- let start = 0;
1789
- const now = Date.now();
1790
- for (let i = 0; i < scrollHistory.length - 1; i++) {
1791
- const entry = scrollHistory[i];
1792
- const nextEntry = scrollHistory[i + 1];
1793
- if (i > 0) {
1794
- const prevEntry = scrollHistory[i - 1];
1795
- const prevDirection = entry.scroll - prevEntry.scroll;
1796
- const currentDirection = nextEntry.scroll - entry.scroll;
1797
- if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
1798
- start = i;
1799
- break;
1800
- }
1801
- }
1802
- }
1803
- for (let i = start; i < scrollHistory.length - 1; i++) {
1804
- const entry = scrollHistory[i];
1805
- if (now - entry.time <= 1e3) {
1806
- oldest = entry;
1807
- break;
1808
- }
1809
- }
1810
- if (oldest && oldest !== newest) {
1811
- const scrollDiff = newest.scroll - oldest.scroll;
1812
- const timeDiff = newest.time - oldest.time;
1813
- velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
1814
- }
1815
- }
1816
- return velocity;
1817
- };
1818
-
1819
2278
  // src/core/scrollToIndex.ts
1820
2279
  function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
1821
2280
  if (index >= state.props.data.length) {
@@ -1828,72 +2287,16 @@ function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, vie
1828
2287
  if (isLast && viewPosition === void 0) {
1829
2288
  viewPosition = 1;
1830
2289
  }
1831
- const firstIndexScrollPostion = firstIndexOffset - viewOffset;
1832
2290
  state.scrollForNextCalculateItemsInView = void 0;
1833
- scrollTo(state, {
2291
+ scrollTo(ctx, state, {
1834
2292
  animated,
1835
2293
  index,
1836
- offset: firstIndexScrollPostion,
2294
+ offset: firstIndexOffset,
1837
2295
  viewOffset,
1838
2296
  viewPosition: viewPosition != null ? viewPosition : 0
1839
2297
  });
1840
2298
  }
1841
2299
 
1842
- // src/utils/checkThreshold.ts
1843
- var checkThreshold = (distance, atThreshold, threshold, isReached, isBlockedByTimer, onReached, blockTimer) => {
1844
- const distanceAbs = Math.abs(distance);
1845
- const isAtThreshold = atThreshold || distanceAbs < threshold;
1846
- if (!isReached && !isBlockedByTimer) {
1847
- if (isAtThreshold) {
1848
- onReached == null ? void 0 : onReached(distance);
1849
- blockTimer == null ? void 0 : blockTimer(true);
1850
- setTimeout(() => {
1851
- blockTimer == null ? void 0 : blockTimer(false);
1852
- }, 700);
1853
- return true;
1854
- }
1855
- } else {
1856
- if (distance >= 1.3 * threshold) {
1857
- return false;
1858
- }
1859
- }
1860
- return isReached;
1861
- };
1862
-
1863
- // src/utils/checkAtBottom.ts
1864
- function checkAtBottom(ctx, state) {
1865
- if (!state) {
1866
- return;
1867
- }
1868
- const {
1869
- queuedInitialLayout,
1870
- scrollLength,
1871
- scroll,
1872
- maintainingScrollAtEnd,
1873
- props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
1874
- } = state;
1875
- const contentSize = getContentSize(ctx);
1876
- if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
1877
- const distanceFromEnd = contentSize - scroll - scrollLength;
1878
- const isContentLess = contentSize < scrollLength;
1879
- state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
1880
- state.isEndReached = checkThreshold(
1881
- distanceFromEnd,
1882
- isContentLess,
1883
- onEndReachedThreshold * scrollLength,
1884
- state.isEndReached,
1885
- state.endReachedBlockedByTimer,
1886
- (distance) => {
1887
- var _a, _b;
1888
- return (_b = (_a = state.props).onEndReached) == null ? void 0 : _b.call(_a, { distanceFromEnd: distance });
1889
- },
1890
- (block) => {
1891
- state.endReachedBlockedByTimer = block;
1892
- }
1893
- );
1894
- }
1895
- }
1896
-
1897
2300
  // src/utils/setDidLayout.ts
1898
2301
  function setDidLayout(ctx, state) {
1899
2302
  const {
@@ -1916,11 +2319,12 @@ function setDidLayout(ctx, state) {
1916
2319
 
1917
2320
  // src/core/calculateItemsInView.ts
1918
2321
  function findCurrentStickyIndex(stickyArray, scroll, state) {
1919
- var _a;
2322
+ var _a3;
1920
2323
  const idCache = state.idCache;
1921
2324
  const positions = state.positions;
1922
2325
  for (let i = stickyArray.length - 1; i >= 0; i--) {
1923
- const stickyId = (_a = idCache.get(stickyArray[i])) != null ? _a : getId(state, stickyArray[i]);
2326
+ const stickyIndex = stickyArray[i];
2327
+ const stickyId = (_a3 = idCache[stickyIndex]) != null ? _a3 : getId(state, stickyIndex);
1924
2328
  const stickyPos = stickyId ? positions.get(stickyId) : void 0;
1925
2329
  if (stickyPos !== void 0 && scroll >= stickyPos) {
1926
2330
  return i;
@@ -1928,47 +2332,51 @@ function findCurrentStickyIndex(stickyArray, scroll, state) {
1928
2332
  }
1929
2333
  return -1;
1930
2334
  }
1931
- function getActiveStickyIndices(ctx, state, stickyIndices) {
2335
+ function getActiveStickyIndices(ctx, state, stickyHeaderIndices) {
1932
2336
  return new Set(
1933
- Array.from(state.stickyContainerPool).map((i) => peek$(ctx, `containerItemKey${i}`)).map((key) => key ? state.indexByKey.get(key) : void 0).filter((idx) => idx !== void 0 && stickyIndices.has(idx))
2337
+ Array.from(state.stickyContainerPool).map((i) => peek$(ctx, `containerItemKey${i}`)).map((key) => key ? state.indexByKey.get(key) : void 0).filter((idx) => idx !== void 0 && stickyHeaderIndices.has(idx))
1934
2338
  );
1935
2339
  }
1936
- function handleStickyActivation(ctx, state, stickyIndices, stickyArray, scroll, needNewContainers, startBuffered, endBuffered) {
1937
- var _a;
1938
- const activeIndices = getActiveStickyIndices(ctx, state, stickyIndices);
1939
- const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
2340
+ function handleStickyActivation(ctx, state, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
2341
+ var _a3;
2342
+ const activeIndices = getActiveStickyIndices(ctx, state, stickyHeaderIndices);
2343
+ state.activeStickyIndex = currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : void 0;
1940
2344
  for (let offset = 0; offset <= 1; offset++) {
1941
2345
  const idx = currentStickyIdx - offset;
1942
2346
  if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
1943
2347
  const stickyIndex = stickyArray[idx];
1944
- const stickyId = (_a = state.idCache.get(stickyIndex)) != null ? _a : getId(state, stickyIndex);
2348
+ const stickyId = (_a3 = state.idCache[stickyIndex]) != null ? _a3 : getId(state, stickyIndex);
1945
2349
  if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered)) {
1946
2350
  needNewContainers.push(stickyIndex);
1947
2351
  }
1948
2352
  }
1949
2353
  }
1950
- function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, pendingRemoval) {
1951
- var _a, _b, _c;
1952
- const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
2354
+ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
2355
+ var _a3, _b, _c;
1953
2356
  for (const containerIndex of state.stickyContainerPool) {
1954
2357
  const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
1955
2358
  const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
1956
2359
  if (itemIndex === void 0) continue;
1957
2360
  const arrayIdx = stickyArray.indexOf(itemIndex);
1958
- if (arrayIdx === -1) continue;
2361
+ if (arrayIdx === -1) {
2362
+ state.stickyContainerPool.delete(containerIndex);
2363
+ set$(ctx, `containerSticky${containerIndex}`, false);
2364
+ set$(ctx, `containerStickyOffset${containerIndex}`, void 0);
2365
+ continue;
2366
+ }
1959
2367
  const isRecentSticky = arrayIdx >= currentStickyIdx - 1 && arrayIdx <= currentStickyIdx + 1;
1960
2368
  if (isRecentSticky) continue;
1961
2369
  const nextIndex = stickyArray[arrayIdx + 1];
1962
2370
  let shouldRecycle = false;
1963
2371
  if (nextIndex) {
1964
- const nextId = (_a = state.idCache.get(nextIndex)) != null ? _a : getId(state, nextIndex);
2372
+ const nextId = (_a3 = state.idCache[nextIndex]) != null ? _a3 : getId(state, nextIndex);
1965
2373
  const nextPos = nextId ? state.positions.get(nextId) : void 0;
1966
2374
  shouldRecycle = nextPos !== void 0 && scroll > nextPos + scrollBuffer * 2;
1967
2375
  } else {
1968
- const currentId = (_b = state.idCache.get(itemIndex)) != null ? _b : getId(state, itemIndex);
2376
+ const currentId = (_b = state.idCache[itemIndex]) != null ? _b : getId(state, itemIndex);
1969
2377
  if (currentId) {
1970
2378
  const currentPos = state.positions.get(currentId);
1971
- const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(state, currentId, itemIndex, state.props.data[itemIndex]);
2379
+ const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, state, currentId, itemIndex, state.props.data[itemIndex]);
1972
2380
  shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
1973
2381
  }
1974
2382
  }
@@ -1979,61 +2387,52 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, pe
1979
2387
  }
1980
2388
  function calculateItemsInView(ctx, state, params = {}) {
1981
2389
  reactDom.unstable_batchedUpdates(() => {
1982
- var _a, _b, _c, _d, _e, _f, _g, _h;
2390
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1983
2391
  const {
1984
2392
  columns,
1985
2393
  containerItemKeys,
1986
2394
  enableScrollForNextCalculateItemsInView,
1987
2395
  idCache,
1988
2396
  indexByKey,
2397
+ initialScroll,
1989
2398
  minIndexSizeChanged,
1990
2399
  positions,
2400
+ props: { getItemType, itemsAreEqual, keyExtractor, onStickyHeaderChange, scrollBuffer },
1991
2401
  scrollForNextCalculateItemsInView,
1992
2402
  scrollLength,
1993
2403
  sizes,
1994
2404
  startBufferedId: startBufferedIdOrig,
1995
- viewabilityConfigCallbackPairs,
1996
- props: { getItemType, initialScroll, itemsAreEqual, keyExtractor, scrollBuffer }
2405
+ viewabilityConfigCallbackPairs
1997
2406
  } = state;
1998
2407
  const { data } = state.props;
1999
2408
  const stickyIndicesArr = state.props.stickyIndicesArr || [];
2000
2409
  const stickyIndicesSet = state.props.stickyIndicesSet || /* @__PURE__ */ new Set();
2001
2410
  const prevNumContainers = peek$(ctx, "numContainers");
2002
2411
  if (!data || scrollLength === 0 || !prevNumContainers) {
2412
+ if (state.initialAnchor) {
2413
+ ensureInitialAnchor(ctx, state);
2414
+ }
2003
2415
  return;
2004
2416
  }
2005
- const totalSize = peek$(ctx, "totalSize");
2417
+ const totalSize = getContentSize(ctx);
2006
2418
  const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
2007
2419
  const numColumns = peek$(ctx, "numColumns");
2008
- const previousScrollAdjust = 0;
2009
- const { dataChanged, doMVCP } = params;
2420
+ const { dataChanged, doMVCP, forceFullItemPositions } = params;
2010
2421
  const speed = getScrollVelocity(state);
2011
- if (doMVCP || dataChanged) {
2012
- const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
2013
- if (dataChanged) {
2014
- indexByKey.clear();
2015
- idCache.clear();
2016
- positions.clear();
2017
- }
2018
- const startIndex = dataChanged ? 0 : minIndexSizeChanged != null ? minIndexSizeChanged : 0;
2019
- updateAllPositions(ctx, state, dataChanged, startIndex);
2020
- if (minIndexSizeChanged !== void 0) {
2021
- state.minIndexSizeChanged = void 0;
2022
- }
2023
- checkMVCP == null ? void 0 : checkMVCP();
2024
- }
2025
2422
  const scrollExtra = 0;
2026
2423
  const { queuedInitialLayout } = state;
2027
2424
  let { scroll: scrollState } = state;
2028
2425
  if (!queuedInitialLayout && initialScroll) {
2029
2426
  const updatedOffset = calculateOffsetWithOffsetPosition(
2427
+ ctx,
2030
2428
  state,
2031
2429
  calculateOffsetForIndex(ctx, state, initialScroll.index),
2032
2430
  initialScroll
2033
2431
  );
2034
2432
  scrollState = updatedOffset;
2035
2433
  }
2036
- const scrollAdjustPad = -previousScrollAdjust - topPad;
2434
+ const scrollAdjustPending = (_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0;
2435
+ const scrollAdjustPad = scrollAdjustPending - topPad;
2037
2436
  let scroll = scrollState + scrollExtra + scrollAdjustPad;
2038
2437
  if (scroll + scrollLength > totalSize) {
2039
2438
  scroll = Math.max(0, totalSize - scrollLength);
@@ -2042,6 +2441,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2042
2441
  set$(ctx, "debugRawScroll", scrollState);
2043
2442
  set$(ctx, "debugComputedScroll", scroll);
2044
2443
  }
2444
+ const previousStickyIndex = state.activeStickyIndex;
2445
+ const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
2446
+ const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : void 0;
2447
+ state.activeStickyIndex = nextActiveStickyIndex;
2448
+ set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
2045
2449
  let scrollBufferTop = scrollBuffer;
2046
2450
  let scrollBufferBottom = scrollBuffer;
2047
2451
  if (speed > 0 || speed === 0 && scroll < Math.max(50, scrollBuffer)) {
@@ -2054,22 +2458,42 @@ function calculateItemsInView(ctx, state, params = {}) {
2054
2458
  const scrollTopBuffered = scroll - scrollBufferTop;
2055
2459
  const scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
2056
2460
  const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
2057
- if (scrollForNextCalculateItemsInView) {
2461
+ if (!dataChanged && scrollForNextCalculateItemsInView) {
2058
2462
  const { top, bottom } = scrollForNextCalculateItemsInView;
2059
2463
  if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
2464
+ if (state.initialAnchor) {
2465
+ ensureInitialAnchor(ctx, state);
2466
+ }
2060
2467
  return;
2061
2468
  }
2062
2469
  }
2470
+ const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
2471
+ if (dataChanged) {
2472
+ indexByKey.clear();
2473
+ idCache.length = 0;
2474
+ positions.clear();
2475
+ }
2476
+ const startIndex = dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
2477
+ updateItemPositions(ctx, state, dataChanged, {
2478
+ doMVCP,
2479
+ forceFullUpdate: !!forceFullItemPositions,
2480
+ scrollBottomBuffered,
2481
+ startIndex
2482
+ });
2483
+ if (minIndexSizeChanged !== void 0) {
2484
+ state.minIndexSizeChanged = void 0;
2485
+ }
2486
+ checkMVCP == null ? void 0 : checkMVCP();
2063
2487
  let startNoBuffer = null;
2064
2488
  let startBuffered = null;
2065
2489
  let startBufferedId = null;
2066
2490
  let endNoBuffer = null;
2067
2491
  let endBuffered = null;
2068
- let loopStart = startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
2492
+ let loopStart = !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
2069
2493
  for (let i = loopStart; i >= 0; i--) {
2070
- const id = (_a = idCache.get(i)) != null ? _a : getId(state, i);
2494
+ const id = (_c = idCache[i]) != null ? _c : getId(state, i);
2071
2495
  const top = positions.get(id);
2072
- const size = (_b = sizes.get(id)) != null ? _b : getItemSize(state, id, i, data[i]);
2496
+ const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, state, id, i, data[i]);
2073
2497
  const bottom = top + size;
2074
2498
  if (bottom > scroll - scrollBuffer) {
2075
2499
  loopStart = i;
@@ -2095,8 +2519,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2095
2519
  let firstFullyOnScreenIndex;
2096
2520
  const dataLength = data.length;
2097
2521
  for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
2098
- const id = (_c = idCache.get(i)) != null ? _c : getId(state, i);
2099
- const size = (_d = sizes.get(id)) != null ? _d : getItemSize(state, id, i, data[i]);
2522
+ const id = (_e = idCache[i]) != null ? _e : getId(state, i);
2523
+ const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, state, id, i, data[i]);
2100
2524
  const top = positions.get(id);
2101
2525
  if (!foundEnd) {
2102
2526
  if (startNoBuffer === null && top + size > scroll) {
@@ -2125,7 +2549,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2125
2549
  }
2126
2550
  const idsInView = [];
2127
2551
  for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
2128
- const id = (_e = idCache.get(i)) != null ? _e : getId(state, i);
2552
+ const id = (_g = idCache[i]) != null ? _g : getId(state, i);
2129
2553
  idsInView.push(id);
2130
2554
  }
2131
2555
  Object.assign(state, {
@@ -2157,7 +2581,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2157
2581
  let numContainers2 = prevNumContainers;
2158
2582
  const needNewContainers = [];
2159
2583
  for (let i = startBuffered; i <= endBuffered; i++) {
2160
- const id = (_f = idCache.get(i)) != null ? _f : getId(state, i);
2584
+ const id = (_h = idCache[i]) != null ? _h : getId(state, i);
2161
2585
  if (!containerItemKeys.has(id)) {
2162
2586
  needNewContainers.push(i);
2163
2587
  }
@@ -2168,11 +2592,14 @@ function calculateItemsInView(ctx, state, params = {}) {
2168
2592
  state,
2169
2593
  stickyIndicesSet,
2170
2594
  stickyIndicesArr,
2171
- scroll,
2595
+ currentStickyIdx,
2172
2596
  needNewContainers,
2173
2597
  startBuffered,
2174
2598
  endBuffered
2175
2599
  );
2600
+ } else {
2601
+ state.activeStickyIndex = void 0;
2602
+ set$(ctx, "activeStickyIndex", void 0);
2176
2603
  }
2177
2604
  if (needNewContainers.length > 0) {
2178
2605
  const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
@@ -2192,7 +2619,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2192
2619
  for (let idx = 0; idx < needNewContainers.length; idx++) {
2193
2620
  const i = needNewContainers[idx];
2194
2621
  const containerIndex = availableContainers[idx];
2195
- const id = (_g = idCache.get(i)) != null ? _g : getId(state, i);
2622
+ const id = (_i = idCache[i]) != null ? _i : getId(state, i);
2196
2623
  const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
2197
2624
  if (oldKey && oldKey !== id) {
2198
2625
  containerItemKeys.delete(oldKey);
@@ -2206,9 +2633,10 @@ function calculateItemsInView(ctx, state, params = {}) {
2206
2633
  if (stickyIndicesSet.has(i)) {
2207
2634
  set$(ctx, `containerSticky${containerIndex}`, true);
2208
2635
  const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
2209
- set$(ctx, `containerStickyOffset${containerIndex}`, createAnimatedValue(topPadding));
2636
+ set$(ctx, `containerStickyOffset${containerIndex}`, topPadding);
2210
2637
  state.stickyContainerPool.add(containerIndex);
2211
2638
  } else {
2639
+ set$(ctx, `containerSticky${containerIndex}`, false);
2212
2640
  state.stickyContainerPool.delete(containerIndex);
2213
2641
  }
2214
2642
  if (containerIndex >= numContainers2) {
@@ -2224,13 +2652,13 @@ function calculateItemsInView(ctx, state, params = {}) {
2224
2652
  }
2225
2653
  }
2226
2654
  if (stickyIndicesArr.length > 0) {
2227
- handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, pendingRemoval);
2655
+ handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2228
2656
  }
2229
2657
  let didChangePositions = false;
2230
2658
  for (let i = 0; i < numContainers; i++) {
2231
2659
  const itemKey = peek$(ctx, `containerItemKey${i}`);
2232
2660
  if (pendingRemoval.includes(i)) {
2233
- if (itemKey) {
2661
+ if (itemKey !== void 0) {
2234
2662
  containerItemKeys.delete(itemKey);
2235
2663
  }
2236
2664
  state.containerItemTypes.delete(i);
@@ -2247,11 +2675,12 @@ function calculateItemsInView(ctx, state, params = {}) {
2247
2675
  const itemIndex = indexByKey.get(itemKey);
2248
2676
  const item = data[itemIndex];
2249
2677
  if (item !== void 0) {
2250
- const id = (_h = idCache.get(itemIndex)) != null ? _h : getId(state, itemIndex);
2251
- const position = positions.get(id);
2252
- if (position === void 0) {
2678
+ const id = (_j = idCache[itemIndex]) != null ? _j : getId(state, itemIndex);
2679
+ const positionValue = positions.get(id);
2680
+ if (positionValue === void 0) {
2253
2681
  set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
2254
2682
  } else {
2683
+ const position = (positionValue || 0) - scrollAdjustPending;
2255
2684
  const column = columns.get(id) || 1;
2256
2685
  const prevPos = peek$(ctx, `containerPosition${i}`);
2257
2686
  const prevColumn = peek$(ctx, `containerColumn${i}`);
@@ -2264,29 +2693,161 @@ function calculateItemsInView(ctx, state, params = {}) {
2264
2693
  set$(ctx, `containerColumn${i}`, column);
2265
2694
  }
2266
2695
  if (prevData !== item && (itemsAreEqual ? !itemsAreEqual(prevData, item, itemIndex, data) : true)) {
2267
- set$(ctx, `containerItemData${i}`, data[itemIndex]);
2696
+ set$(ctx, `containerItemData${i}`, item);
2268
2697
  }
2269
2698
  }
2270
2699
  }
2271
2700
  }
2272
2701
  }
2273
- if (didChangePositions) {
2274
- set$(ctx, "lastPositionUpdate", Date.now());
2275
- }
2276
- if (!queuedInitialLayout && endBuffered !== null) {
2277
- if (checkAllSizesKnown(state)) {
2278
- setDidLayout(ctx, state);
2279
- }
2280
- }
2281
- if (viewabilityConfigCallbackPairs) {
2282
- updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollLength, startNoBuffer, endNoBuffer);
2702
+ if (didChangePositions) {
2703
+ set$(ctx, "lastPositionUpdate", Date.now());
2704
+ }
2705
+ if (!queuedInitialLayout && endBuffered !== null) {
2706
+ if (checkAllSizesKnown(state)) {
2707
+ setDidLayout(ctx, state);
2708
+ }
2709
+ }
2710
+ if (viewabilityConfigCallbackPairs) {
2711
+ updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollLength, startNoBuffer, endNoBuffer);
2712
+ }
2713
+ if (onStickyHeaderChange && stickyIndicesArr.length > 0 && nextActiveStickyIndex !== void 0 && nextActiveStickyIndex !== previousStickyIndex) {
2714
+ const item = data[nextActiveStickyIndex];
2715
+ if (item !== void 0) {
2716
+ onStickyHeaderChange({ index: nextActiveStickyIndex, item });
2717
+ }
2718
+ }
2719
+ });
2720
+ if (state.initialAnchor) {
2721
+ ensureInitialAnchor(ctx, state);
2722
+ }
2723
+ }
2724
+
2725
+ // src/core/checkActualChange.ts
2726
+ function checkActualChange(state, dataProp, previousData) {
2727
+ if (!previousData || !dataProp || dataProp.length !== previousData.length) {
2728
+ return true;
2729
+ }
2730
+ const {
2731
+ idCache,
2732
+ props: { keyExtractor }
2733
+ } = state;
2734
+ for (let i = 0; i < dataProp.length; i++) {
2735
+ if (dataProp[i] !== previousData[i]) {
2736
+ return true;
2737
+ }
2738
+ if (keyExtractor ? idCache[i] !== keyExtractor(previousData[i], i) : dataProp[i] !== previousData[i]) {
2739
+ return true;
2740
+ }
2741
+ }
2742
+ return false;
2743
+ }
2744
+
2745
+ // src/core/doMaintainScrollAtEnd.ts
2746
+ function doMaintainScrollAtEnd(ctx, state, animated) {
2747
+ const {
2748
+ refScroller,
2749
+ props: { maintainScrollAtEnd }
2750
+ } = state;
2751
+ if ((state == null ? void 0 : state.isAtEnd) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
2752
+ const paddingTop = peek$(ctx, "alignItemsPaddingTop");
2753
+ if (paddingTop > 0) {
2754
+ state.scroll = 0;
2755
+ }
2756
+ requestAnimationFrame(() => {
2757
+ var _a3;
2758
+ if (state == null ? void 0 : state.isAtEnd) {
2759
+ state.maintainingScrollAtEnd = true;
2760
+ (_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
2761
+ animated
2762
+ });
2763
+ setTimeout(
2764
+ () => {
2765
+ state.maintainingScrollAtEnd = false;
2766
+ },
2767
+ 0
2768
+ );
2769
+ }
2770
+ });
2771
+ return true;
2772
+ }
2773
+ return false;
2774
+ }
2775
+
2776
+ // src/utils/updateAveragesOnDataChange.ts
2777
+ function updateAveragesOnDataChange(state, oldData, newData) {
2778
+ var _a3;
2779
+ const {
2780
+ averageSizes,
2781
+ sizesKnown,
2782
+ indexByKey,
2783
+ props: { itemsAreEqual, getItemType, keyExtractor }
2784
+ } = state;
2785
+ if (!itemsAreEqual || !oldData.length || !newData.length) {
2786
+ for (const key in averageSizes) {
2787
+ delete averageSizes[key];
2788
+ }
2789
+ return;
2790
+ }
2791
+ const itemTypesToPreserve = {};
2792
+ const newDataLength = newData.length;
2793
+ const oldDataLength = oldData.length;
2794
+ for (let newIndex = 0; newIndex < newDataLength; newIndex++) {
2795
+ const newItem = newData[newIndex];
2796
+ const id = keyExtractor ? keyExtractor(newItem, newIndex) : String(newIndex);
2797
+ const oldIndex = indexByKey.get(id);
2798
+ if (oldIndex !== void 0 && oldIndex < oldDataLength) {
2799
+ const knownSize = sizesKnown.get(id);
2800
+ if (knownSize === void 0) continue;
2801
+ const oldItem = oldData[oldIndex];
2802
+ const areEqual = itemsAreEqual(oldItem, newItem, newIndex, newData);
2803
+ if (areEqual) {
2804
+ const itemType = getItemType ? (_a3 = getItemType(newItem, newIndex)) != null ? _a3 : "" : "";
2805
+ let typeData = itemTypesToPreserve[itemType];
2806
+ if (!typeData) {
2807
+ typeData = itemTypesToPreserve[itemType] = { count: 0, totalSize: 0 };
2808
+ }
2809
+ typeData.totalSize += knownSize;
2810
+ typeData.count++;
2811
+ }
2812
+ }
2813
+ }
2814
+ for (const key in averageSizes) {
2815
+ delete averageSizes[key];
2816
+ }
2817
+ for (const itemType in itemTypesToPreserve) {
2818
+ const { totalSize, count } = itemTypesToPreserve[itemType];
2819
+ if (count > 0) {
2820
+ averageSizes[itemType] = {
2821
+ avg: totalSize / count,
2822
+ num: count
2823
+ };
2283
2824
  }
2284
- });
2825
+ }
2826
+ }
2827
+
2828
+ // src/core/checkResetContainers.ts
2829
+ function checkResetContainers(ctx, state, dataProp) {
2830
+ const { previousData } = state;
2831
+ if (previousData) {
2832
+ updateAveragesOnDataChange(state, previousData, dataProp);
2833
+ }
2834
+ const { maintainScrollAtEnd } = state.props;
2835
+ calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2836
+ const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
2837
+ const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state, false);
2838
+ if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
2839
+ state.isEndReached = false;
2840
+ }
2841
+ if (!didMaintainScrollAtEnd) {
2842
+ checkAtTop(state);
2843
+ checkAtBottom(ctx, state);
2844
+ }
2845
+ delete state.previousData;
2285
2846
  }
2286
2847
 
2287
2848
  // src/core/doInitialAllocateContainers.ts
2288
2849
  function doInitialAllocateContainers(ctx, state) {
2289
- var _a;
2850
+ var _a3, _b, _c;
2290
2851
  const {
2291
2852
  scrollLength,
2292
2853
  props: {
@@ -2302,12 +2863,13 @@ function doInitialAllocateContainers(ctx, state) {
2302
2863
  const hasContainers = peek$(ctx, "numContainers");
2303
2864
  if (scrollLength > 0 && data.length > 0 && !hasContainers) {
2304
2865
  let averageItemSize;
2305
- const fn = getFixedItemSize || getEstimatedItemSize;
2306
- if (fn) {
2866
+ if (getFixedItemSize || getEstimatedItemSize) {
2307
2867
  let totalSize = 0;
2308
2868
  const num = Math.min(20, data.length);
2309
2869
  for (let i = 0; i < num; i++) {
2310
- totalSize += fn(0, data[0], getItemType ? (_a = getItemType(data[0], 0)) != null ? _a : "" : "");
2870
+ const item = data[i];
2871
+ const itemType = getItemType ? (_a3 = getItemType(item, i)) != null ? _a3 : "" : "";
2872
+ 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
2873
  }
2312
2874
  averageItemSize = totalSize / num;
2313
2875
  } else {
@@ -2321,76 +2883,18 @@ function doInitialAllocateContainers(ctx, state) {
2321
2883
  set$(ctx, "numContainers", numContainers);
2322
2884
  set$(ctx, "numContainersPooled", numContainers * state.props.initialContainerPoolRatio);
2323
2885
  if (state.lastLayout) {
2324
- if (state.props.initialScroll) {
2886
+ if (state.initialScroll) {
2325
2887
  requestAnimationFrame(() => {
2326
- calculateItemsInView(ctx, state, { dataChanged: true });
2888
+ calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2327
2889
  });
2328
2890
  } else {
2329
- calculateItemsInView(ctx, state, { dataChanged: true });
2891
+ calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2330
2892
  }
2331
2893
  }
2332
2894
  return true;
2333
2895
  }
2334
2896
  }
2335
2897
 
2336
- // src/core/doMaintainScrollAtEnd.ts
2337
- function doMaintainScrollAtEnd(ctx, state, animated) {
2338
- const {
2339
- refScroller,
2340
- props: { maintainScrollAtEnd }
2341
- } = state;
2342
- if ((state == null ? void 0 : state.isAtEnd) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
2343
- const paddingTop = peek$(ctx, "alignItemsPaddingTop");
2344
- if (paddingTop > 0) {
2345
- state.scroll = 0;
2346
- }
2347
- requestAnimationFrame(() => {
2348
- var _a;
2349
- if (state == null ? void 0 : state.isAtEnd) {
2350
- state.maintainingScrollAtEnd = true;
2351
- (_a = refScroller.current) == null ? void 0 : _a.scrollToEnd({
2352
- animated
2353
- });
2354
- setTimeout(
2355
- () => {
2356
- state.maintainingScrollAtEnd = false;
2357
- },
2358
- 0
2359
- );
2360
- }
2361
- });
2362
- return true;
2363
- }
2364
- }
2365
-
2366
- // src/utils/checkAtTop.ts
2367
- function checkAtTop(state) {
2368
- if (!state) {
2369
- return;
2370
- }
2371
- const {
2372
- scrollLength,
2373
- scroll,
2374
- props: { onStartReachedThreshold }
2375
- } = state;
2376
- const distanceFromTop = scroll;
2377
- state.isAtStart = distanceFromTop <= 0;
2378
- state.isStartReached = checkThreshold(
2379
- distanceFromTop,
2380
- false,
2381
- onStartReachedThreshold * scrollLength,
2382
- state.isStartReached,
2383
- state.startReachedBlockedByTimer,
2384
- (distance) => {
2385
- var _a, _b;
2386
- return (_b = (_a = state.props).onStartReached) == null ? void 0 : _b.call(_a, { distanceFromStart: distance });
2387
- },
2388
- (block) => {
2389
- state.startReachedBlockedByTimer = block;
2390
- }
2391
- );
2392
- }
2393
-
2394
2898
  // src/core/handleLayout.ts
2395
2899
  function handleLayout(ctx, state, layout, setCanRender) {
2396
2900
  const { maintainScrollAtEnd } = state.props;
@@ -2425,19 +2929,19 @@ function handleLayout(ctx, state, layout, setCanRender) {
2425
2929
  if (state) {
2426
2930
  state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
2427
2931
  }
2428
- if (__DEV__ && measuredLength === 0) {
2932
+ if (IS_DEV && measuredLength === 0) {
2429
2933
  warnDevOnce(
2430
2934
  "height0",
2431
2935
  `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.`
2432
2936
  );
2433
2937
  }
2434
- setCanRender(true);
2435
2938
  }
2939
+ setCanRender(true);
2436
2940
  }
2437
2941
 
2438
2942
  // src/core/onScroll.ts
2439
2943
  function onScroll(ctx, state, event) {
2440
- var _a, _b, _c;
2944
+ var _a3, _b, _c;
2441
2945
  const {
2442
2946
  scrollProcessingEnabled,
2443
2947
  props: { onScroll: onScrollProp }
@@ -2445,67 +2949,51 @@ function onScroll(ctx, state, event) {
2445
2949
  if (scrollProcessingEnabled === false) {
2446
2950
  return;
2447
2951
  }
2448
- 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) {
2952
+ 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) {
2449
2953
  return;
2450
2954
  }
2451
2955
  const newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2452
- const ignoreScrollFromMVCP = state.ignoreScrollFromMVCP;
2453
- if (ignoreScrollFromMVCP && !state.scrollingTo) {
2454
- const { lt, gt } = ignoreScrollFromMVCP;
2455
- if (lt && newScroll < lt || gt && newScroll > gt) {
2456
- return;
2457
- }
2458
- }
2459
2956
  state.scrollPending = newScroll;
2460
- {
2461
- if (!state.onScrollRafScheduled) {
2462
- state.onScrollRafScheduled = true;
2463
- requestAnimationFrame(() => {
2464
- state.onScrollRafScheduled = false;
2465
- updateScroll(ctx, state, newScroll);
2466
- });
2467
- }
2468
- }
2957
+ updateScroll(ctx, state, newScroll);
2469
2958
  onScrollProp == null ? void 0 : onScrollProp(event);
2470
2959
  }
2471
- function updateScroll(ctx, state, newScroll) {
2472
- const scrollingTo = state.scrollingTo;
2473
- state.hasScrolled = true;
2474
- state.lastBatchingAction = Date.now();
2475
- const currentTime = Date.now();
2476
- if (scrollingTo === void 0 && !(state.scrollHistory.length === 0 && newScroll === state.scroll)) {
2477
- const adjust = state.scrollAdjustHandler.getAdjust();
2478
- state.scrollHistory.push({ scroll: newScroll - adjust, time: currentTime });
2479
- }
2480
- if (state.scrollHistory.length > 5) {
2481
- state.scrollHistory.shift();
2482
- }
2483
- state.scrollPrev = state.scroll;
2484
- state.scrollPrevTime = state.scrollTime;
2485
- state.scroll = newScroll;
2486
- state.scrollTime = currentTime;
2487
- if (Math.abs(state.scroll - state.scrollPrev) > 2) {
2488
- calculateItemsInView(ctx, state);
2489
- checkAtBottom(ctx, state);
2490
- checkAtTop(state);
2491
- }
2492
- }
2493
2960
 
2494
2961
  // src/core/ScrollAdjustHandler.ts
2495
2962
  var ScrollAdjustHandler = class {
2496
2963
  constructor(ctx) {
2497
2964
  this.appliedAdjust = 0;
2965
+ this.pendingAdjust = 0;
2498
2966
  this.mounted = false;
2499
2967
  this.context = ctx;
2968
+ {
2969
+ const commitPendingAdjust = () => {
2970
+ const state = this.context.internalState;
2971
+ const pending = this.pendingAdjust;
2972
+ if (pending !== 0) {
2973
+ this.pendingAdjust = 0;
2974
+ this.appliedAdjust += pending;
2975
+ state.scroll += pending;
2976
+ state.scrollForNextCalculateItemsInView = void 0;
2977
+ set$(this.context, "scrollAdjustPending", 0);
2978
+ set$(this.context, "scrollAdjust", this.appliedAdjust);
2979
+ calculateItemsInView(this.context, this.context.internalState);
2980
+ }
2981
+ };
2982
+ listen$(this.context, "scrollingTo", (value) => {
2983
+ if (value === void 0) {
2984
+ commitPendingAdjust();
2985
+ }
2986
+ });
2987
+ }
2500
2988
  }
2501
2989
  requestAdjust(add) {
2502
- const oldAdjustTop = peek$(this.context, "scrollAdjust") || 0;
2503
- this.appliedAdjust = add + oldAdjustTop;
2504
- const set = () => set$(this.context, "scrollAdjust", this.appliedAdjust);
2505
- if (this.mounted) {
2506
- set();
2990
+ const scrollingTo = peek$(this.context, "scrollingTo");
2991
+ if ((scrollingTo == null ? void 0 : scrollingTo.animated) && !scrollingTo.isInitialScroll) {
2992
+ this.pendingAdjust += add;
2993
+ set$(this.context, "scrollAdjustPending", this.pendingAdjust);
2507
2994
  } else {
2508
- requestAnimationFrame(set);
2995
+ this.appliedAdjust += add;
2996
+ set$(this.context, "scrollAdjust", this.appliedAdjust);
2509
2997
  }
2510
2998
  }
2511
2999
  setMounted() {
@@ -2518,14 +3006,13 @@ var ScrollAdjustHandler = class {
2518
3006
 
2519
3007
  // src/core/updateItemSize.ts
2520
3008
  function updateItemSize(ctx, state, itemKey, sizeObj) {
2521
- var _a, _b;
3009
+ var _a3;
2522
3010
  const {
2523
3011
  sizesKnown,
2524
3012
  props: {
2525
3013
  getFixedItemSize,
2526
3014
  getItemType,
2527
3015
  horizontal,
2528
- maintainVisibleContentPosition,
2529
3016
  suggestEstimatedItemSize,
2530
3017
  onItemSizeChanged,
2531
3018
  data,
@@ -2533,17 +3020,17 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2533
3020
  }
2534
3021
  } = state;
2535
3022
  if (!data) return;
3023
+ const index = state.indexByKey.get(itemKey);
2536
3024
  if (getFixedItemSize) {
2537
- const index2 = state.indexByKey.get(itemKey);
2538
- if (index2 === void 0) {
3025
+ if (index === void 0) {
2539
3026
  return;
2540
3027
  }
2541
- const itemData = state.props.data[index2];
3028
+ const itemData = state.props.data[index];
2542
3029
  if (itemData === void 0) {
2543
3030
  return;
2544
3031
  }
2545
- const type = getItemType ? (_a = getItemType(itemData, index2)) != null ? _a : "" : "";
2546
- const size2 = getFixedItemSize(index2, itemData, type);
3032
+ const type = getItemType ? (_a3 = getItemType(itemData, index)) != null ? _a3 : "" : "";
3033
+ const size2 = getFixedItemSize(index, itemData, type);
2547
3034
  if (size2 !== void 0 && size2 === sizesKnown.get(itemKey)) {
2548
3035
  return;
2549
3036
  }
@@ -2553,15 +3040,11 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2553
3040
  let shouldMaintainScrollAtEnd = false;
2554
3041
  let minIndexSizeChanged;
2555
3042
  let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
2556
- const index = state.indexByKey.get(itemKey);
2557
3043
  const prevSizeKnown = state.sizesKnown.get(itemKey);
2558
- const diff = updateOneItemSize(state, itemKey, sizeObj);
2559
- const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
3044
+ const diff = updateOneItemSize(ctx, state, itemKey, sizeObj);
3045
+ const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
2560
3046
  if (diff !== 0) {
2561
3047
  minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
2562
- if (((_b = state.scrollingTo) == null ? void 0 : _b.viewPosition) && maintainVisibleContentPosition && index === state.scrollingTo.index && diff > 0) {
2563
- requestAdjust(ctx, state, diff * state.scrollingTo.viewPosition);
2564
- }
2565
3048
  const { startBuffered, endBuffered } = state;
2566
3049
  needsRecalculate || (needsRecalculate = index >= startBuffered && index <= endBuffered);
2567
3050
  if (!needsRecalculate) {
@@ -2591,13 +3074,13 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2591
3074
  if (minIndexSizeChanged !== void 0) {
2592
3075
  state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, minIndexSizeChanged) : minIndexSizeChanged;
2593
3076
  }
2594
- if (__DEV__ && suggestEstimatedItemSize && minIndexSizeChanged !== void 0) {
3077
+ if (IS_DEV && suggestEstimatedItemSize && minIndexSizeChanged !== void 0) {
2595
3078
  if (state.timeoutSizeMessage) clearTimeout(state.timeoutSizeMessage);
2596
3079
  state.timeoutSizeMessage = setTimeout(() => {
2597
- var _a2;
3080
+ var _a4;
2598
3081
  state.timeoutSizeMessage = void 0;
2599
3082
  const num = state.sizesKnown.size;
2600
- const avg = (_a2 = state.averageSizes[""]) == null ? void 0 : _a2.avg;
3083
+ const avg = (_a4 = state.averageSizes[""]) == null ? void 0 : _a4.avg;
2601
3084
  console.warn(
2602
3085
  `[legend-list] Based on the ${num} items rendered so far, the optimal estimated size is ${avg}.`
2603
3086
  );
@@ -2619,8 +3102,8 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2619
3102
  }
2620
3103
  }
2621
3104
  }
2622
- function updateOneItemSize(state, itemKey, sizeObj) {
2623
- var _a;
3105
+ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
3106
+ var _a3;
2624
3107
  const {
2625
3108
  sizes,
2626
3109
  indexByKey,
@@ -2630,12 +3113,12 @@ function updateOneItemSize(state, itemKey, sizeObj) {
2630
3113
  } = state;
2631
3114
  if (!data) return 0;
2632
3115
  const index = indexByKey.get(itemKey);
2633
- const prevSize = getItemSize(state, itemKey, index, data);
3116
+ const prevSize = getItemSize(ctx, state, itemKey, index, data[index]);
2634
3117
  const rawSize = horizontal ? sizeObj.width : sizeObj.height;
2635
3118
  const size = Math.round(rawSize) ;
2636
3119
  sizesKnown.set(itemKey, size);
2637
3120
  if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
2638
- const itemType = getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : "";
3121
+ const itemType = getItemType ? (_a3 = getItemType(data[index], index)) != null ? _a3 : "" : "";
2639
3122
  let averages = averageSizes[itemType];
2640
3123
  if (!averages) {
2641
3124
  averages = averageSizes[itemType] = { avg: 0, num: 0 };
@@ -2644,13 +3127,13 @@ function updateOneItemSize(state, itemKey, sizeObj) {
2644
3127
  averages.num++;
2645
3128
  }
2646
3129
  if (!prevSize || Math.abs(prevSize - size) > 0.1) {
2647
- sizes.set(itemKey, size);
3130
+ setSize(ctx, state, itemKey, size);
2648
3131
  return size - prevSize;
2649
3132
  }
2650
3133
  return 0;
2651
3134
  }
2652
3135
  var useCombinedRef = (...refs) => {
2653
- const callback = React4.useCallback((element) => {
3136
+ const callback = React3.useCallback((element) => {
2654
3137
  for (const ref of refs) {
2655
3138
  if (!ref) {
2656
3139
  continue;
@@ -2666,18 +3149,12 @@ var useCombinedRef = (...refs) => {
2666
3149
  };
2667
3150
 
2668
3151
  // src/platform/RefreshControl.tsx
2669
- function RefreshControl(props) {
3152
+ function RefreshControl(_props) {
2670
3153
  return null;
2671
3154
  }
2672
3155
 
2673
- // src/platform/StyleSheet.tsx
2674
- var StyleSheet = {
2675
- create: (styles) => styles,
2676
- flatten: (style) => style
2677
- };
2678
-
2679
3156
  // src/platform/useStickyScrollHandler.ts
2680
- function useStickyScrollHandler(stickyIndices, horizontal, ctx, onScroll2) {
3157
+ function useStickyScrollHandler(_stickyHeaderIndices, _horizontal, _ctx, onScroll2) {
2681
3158
  return onScroll2;
2682
3159
  }
2683
3160
 
@@ -2695,8 +3172,93 @@ function createColumnWrapperStyle(contentContainerStyle) {
2695
3172
  };
2696
3173
  }
2697
3174
  }
3175
+
3176
+ // src/utils/createImperativeHandle.ts
3177
+ function createImperativeHandle(ctx, state) {
3178
+ const scrollIndexIntoView = (options) => {
3179
+ if (state) {
3180
+ const { index, ...rest } = options;
3181
+ const { startNoBuffer, endNoBuffer } = state;
3182
+ if (index < startNoBuffer || index > endNoBuffer) {
3183
+ const viewPosition = index < startNoBuffer ? 0 : 1;
3184
+ scrollToIndex(ctx, state, {
3185
+ ...rest,
3186
+ index,
3187
+ viewPosition
3188
+ });
3189
+ }
3190
+ }
3191
+ };
3192
+ const refScroller = state.refScroller;
3193
+ return {
3194
+ flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
3195
+ getNativeScrollRef: () => refScroller.current,
3196
+ getScrollableNode: () => refScroller.current.getScrollableNode(),
3197
+ getScrollResponder: () => refScroller.current.getScrollResponder(),
3198
+ getState: () => ({
3199
+ activeStickyIndex: state.activeStickyIndex,
3200
+ contentLength: state.totalSize,
3201
+ data: state.props.data,
3202
+ elementAtIndex: (index) => {
3203
+ var _a3;
3204
+ return (_a3 = ctx.viewRefs.get(findContainerId(ctx, getId(state, index)))) == null ? void 0 : _a3.current;
3205
+ },
3206
+ end: state.endNoBuffer,
3207
+ endBuffered: state.endBuffered,
3208
+ isAtEnd: state.isAtEnd,
3209
+ isAtStart: state.isAtStart,
3210
+ positionAtIndex: (index) => state.positions.get(getId(state, index)),
3211
+ positions: state.positions,
3212
+ scroll: state.scroll,
3213
+ scrollLength: state.scrollLength,
3214
+ sizeAtIndex: (index) => state.sizesKnown.get(getId(state, index)),
3215
+ sizes: state.sizesKnown,
3216
+ start: state.startNoBuffer,
3217
+ startBuffered: state.startBuffered
3218
+ }),
3219
+ scrollIndexIntoView,
3220
+ scrollItemIntoView: ({ item, ...props }) => {
3221
+ const data = state.props.data;
3222
+ const index = data.indexOf(item);
3223
+ if (index !== -1) {
3224
+ scrollIndexIntoView({ index, ...props });
3225
+ }
3226
+ },
3227
+ scrollToEnd: (options) => {
3228
+ const data = state.props.data;
3229
+ const stylePaddingBottom = state.props.stylePaddingBottom;
3230
+ const index = data.length - 1;
3231
+ if (index !== -1) {
3232
+ const paddingBottom = stylePaddingBottom || 0;
3233
+ const footerSize = peek$(ctx, "footerSize") || 0;
3234
+ scrollToIndex(ctx, state, {
3235
+ index,
3236
+ viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
3237
+ viewPosition: 1,
3238
+ ...options
3239
+ });
3240
+ }
3241
+ },
3242
+ scrollToIndex: (params) => scrollToIndex(ctx, state, params),
3243
+ scrollToItem: ({ item, ...props }) => {
3244
+ const data = state.props.data;
3245
+ const index = data.indexOf(item);
3246
+ if (index !== -1) {
3247
+ scrollToIndex(ctx, state, { index, ...props });
3248
+ }
3249
+ },
3250
+ scrollToOffset: (params) => scrollTo(ctx, state, params),
3251
+ setScrollProcessingEnabled: (enabled) => {
3252
+ state.scrollProcessingEnabled = enabled;
3253
+ },
3254
+ setVisibleContentAnchorOffset: (value) => {
3255
+ const val = isFunction(value) ? value(peek$(ctx, "scrollAdjustUserOffset") || 0) : value;
3256
+ set$(ctx, "scrollAdjustUserOffset", val);
3257
+ }
3258
+ };
3259
+ }
2698
3260
  function getRenderedItem(ctx, state, key) {
2699
- var _a;
3261
+ var _a3;
2700
3262
  if (!state) {
2701
3263
  return null;
2702
3264
  }
@@ -2709,29 +3271,31 @@ function getRenderedItem(ctx, state, key) {
2709
3271
  return null;
2710
3272
  }
2711
3273
  let renderedItem = null;
2712
- if (renderItem && data[index]) {
3274
+ const extraData = peek$(ctx, "extraData");
3275
+ const item = data[index];
3276
+ if (renderItem && !isNullOrUndefined(item)) {
2713
3277
  const itemProps = {
2714
3278
  data,
2715
- extraData: peek$(ctx, "extraData"),
3279
+ extraData,
2716
3280
  index,
2717
- item: data[index],
2718
- type: getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : ""
3281
+ item,
3282
+ type: getItemType ? (_a3 = getItemType(item, index)) != null ? _a3 : "" : ""
2719
3283
  };
2720
- renderedItem = isFunction(renderItem) ? renderItem(itemProps) : React4__namespace.default.createElement(renderItem, itemProps);
3284
+ renderedItem = isFunction(renderItem) ? renderItem(itemProps) : React3__namespace.default.createElement(renderItem, itemProps);
2721
3285
  }
2722
3286
  return { index, item: data[index], renderedItem };
2723
3287
  }
2724
3288
  function useThrottleDebounce(mode) {
2725
- const timeoutRef = React4.useRef(null);
2726
- const lastCallTimeRef = React4.useRef(0);
2727
- const lastArgsRef = React4.useRef(null);
3289
+ const timeoutRef = React3.useRef(null);
3290
+ const lastCallTimeRef = React3.useRef(0);
3291
+ const lastArgsRef = React3.useRef(null);
2728
3292
  const clearTimeoutRef = () => {
2729
3293
  if (timeoutRef.current) {
2730
3294
  clearTimeout(timeoutRef.current);
2731
3295
  timeoutRef.current = null;
2732
3296
  }
2733
3297
  };
2734
- const execute = React4.useCallback(
3298
+ const execute = React3.useCallback(
2735
3299
  (callback, delay, ...args) => {
2736
3300
  {
2737
3301
  const now = Date.now();
@@ -2767,58 +3331,6 @@ function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
2767
3331
  return (event) => throttle(originalHandler, scrollEventThrottle, { nativeEvent: event.nativeEvent });
2768
3332
  }
2769
3333
 
2770
- // src/utils/updateAveragesOnDataChange.ts
2771
- function updateAveragesOnDataChange(state, oldData, newData) {
2772
- var _a;
2773
- const {
2774
- averageSizes,
2775
- sizesKnown,
2776
- indexByKey,
2777
- props: { itemsAreEqual, getItemType, keyExtractor }
2778
- } = state;
2779
- if (!itemsAreEqual || !oldData.length || !newData.length) {
2780
- for (const key in averageSizes) {
2781
- delete averageSizes[key];
2782
- }
2783
- return;
2784
- }
2785
- const itemTypesToPreserve = {};
2786
- const newDataLength = newData.length;
2787
- const oldDataLength = oldData.length;
2788
- for (let newIndex = 0; newIndex < newDataLength; newIndex++) {
2789
- const newItem = newData[newIndex];
2790
- const id = keyExtractor ? keyExtractor(newItem, newIndex) : String(newIndex);
2791
- const oldIndex = indexByKey.get(id);
2792
- if (oldIndex !== void 0 && oldIndex < oldDataLength) {
2793
- const knownSize = sizesKnown.get(id);
2794
- if (knownSize === void 0) continue;
2795
- const oldItem = oldData[oldIndex];
2796
- const areEqual = itemsAreEqual(oldItem, newItem, newIndex, newData);
2797
- if (areEqual) {
2798
- const itemType = getItemType ? (_a = getItemType(newItem, newIndex)) != null ? _a : "" : "";
2799
- let typeData = itemTypesToPreserve[itemType];
2800
- if (!typeData) {
2801
- typeData = itemTypesToPreserve[itemType] = { count: 0, totalSize: 0 };
2802
- }
2803
- typeData.totalSize += knownSize;
2804
- typeData.count++;
2805
- }
2806
- }
2807
- }
2808
- for (const key in averageSizes) {
2809
- delete averageSizes[key];
2810
- }
2811
- for (const itemType in itemTypesToPreserve) {
2812
- const { totalSize, count } = itemTypesToPreserve[itemType];
2813
- if (count > 0) {
2814
- averageSizes[itemType] = {
2815
- avg: totalSize / count,
2816
- num: count
2817
- };
2818
- }
2819
- }
2820
- }
2821
-
2822
3334
  // src/components/LegendList.tsx
2823
3335
  var DEFAULT_DRAW_DISTANCE = 250;
2824
3336
  var DEFAULT_ITEM_SIZE = 100;
@@ -2828,22 +3340,24 @@ var LegendList = typedMemo(
2828
3340
  const isChildrenMode = children !== void 0 && dataProp === void 0;
2829
3341
  const processedProps = isChildrenMode ? {
2830
3342
  ...restProps,
2831
- data: (isArray(children) ? children : React4__namespace.Children.toArray(children)).flat(1),
3343
+ data: (isArray(children) ? children : React3__namespace.Children.toArray(children)).flat(1),
2832
3344
  renderItem: ({ item }) => item
2833
3345
  } : {
2834
3346
  ...restProps,
2835
3347
  data: dataProp || [],
2836
3348
  renderItem: renderItemProp
2837
3349
  };
2838
- return /* @__PURE__ */ React4__namespace.createElement(StateProvider, null, /* @__PURE__ */ React4__namespace.createElement(LegendListInner, { ...processedProps, ref: forwardedRef }));
3350
+ return /* @__PURE__ */ React3__namespace.createElement(StateProvider, null, /* @__PURE__ */ React3__namespace.createElement(LegendListInner, { ...processedProps, ref: forwardedRef }));
2839
3351
  })
2840
3352
  );
2841
3353
  var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
3354
+ var _a3, _b;
2842
3355
  const {
2843
3356
  alignItemsAtEnd = false,
2844
3357
  columnWrapperStyle,
2845
3358
  contentContainerStyle: contentContainerStyleProp,
2846
3359
  data: dataProp = [],
3360
+ dataVersion,
2847
3361
  drawDistance = 250,
2848
3362
  enableAverages = true,
2849
3363
  estimatedItemSize: estimatedItemSizeProp,
@@ -2854,6 +3368,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2854
3368
  getItemType,
2855
3369
  horizontal,
2856
3370
  initialContainerPoolRatio = 2,
3371
+ initialScrollAtEnd = false,
2857
3372
  initialScrollIndex: initialScrollIndexProp,
2858
3373
  initialScrollOffset: initialScrollOffsetProp,
2859
3374
  itemsAreEqual,
@@ -2862,7 +3377,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2862
3377
  ListHeaderComponent,
2863
3378
  maintainScrollAtEnd = false,
2864
3379
  maintainScrollAtEndThreshold = 0.1,
2865
- maintainVisibleContentPosition = true,
3380
+ maintainVisibleContentPosition = false,
2866
3381
  numColumns: numColumnsProp = 1,
2867
3382
  onEndReached,
2868
3383
  onEndReachedThreshold = 0.5,
@@ -2874,6 +3389,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2874
3389
  onScroll: onScrollProp,
2875
3390
  onStartReached,
2876
3391
  onStartReachedThreshold = 0.5,
3392
+ onStickyHeaderChange,
3393
+ onViewableItemsChanged,
2877
3394
  progressViewOffset,
2878
3395
  recycleItems = false,
2879
3396
  refreshControl,
@@ -2882,27 +3399,37 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2882
3399
  renderItem,
2883
3400
  scrollEventThrottle,
2884
3401
  snapToIndices,
2885
- stickyIndices,
3402
+ stickyHeaderIndices: stickyHeaderIndicesProp,
3403
+ stickyIndices: stickyIndicesDeprecated,
2886
3404
  style: styleProp,
2887
3405
  suggestEstimatedItemSize,
3406
+ viewabilityConfig,
3407
+ viewabilityConfigCallbackPairs,
2888
3408
  waitForInitialLayout = true,
2889
3409
  ...rest
2890
3410
  } = props;
2891
- const [renderNum, setRenderNum] = React4.useState(0);
2892
- const initialScroll = initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
2893
- const [canRender, setCanRender] = React4__namespace.useState(!IsNewArchitecture);
2894
3411
  const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
2895
3412
  const style = { ...StyleSheet.flatten(styleProp) };
2896
3413
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
2897
3414
  const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
3415
+ const [renderNum, setRenderNum] = React3.useState(0);
3416
+ const initialScrollProp = initialScrollAtEnd ? { index: Math.max(0, dataProp.length - 1), viewOffset: -stylePaddingBottomState } : initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
3417
+ const [canRender, setCanRender] = React3__namespace.useState(!IsNewArchitecture);
2898
3418
  const ctx = useStateContext();
2899
3419
  ctx.columnWrapperStyle = columnWrapperStyle || (contentContainerStyle ? createColumnWrapperStyle(contentContainerStyle) : void 0);
2900
- const refScroller = React4.useRef(null);
3420
+ const refScroller = React3.useRef(null);
2901
3421
  const combinedRef = useCombinedRef(refScroller, refScrollView);
2902
3422
  const estimatedItemSize = estimatedItemSizeProp != null ? estimatedItemSizeProp : DEFAULT_ITEM_SIZE;
2903
3423
  const scrollBuffer = (drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE) || 1;
2904
3424
  const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (_item, index) => index.toString();
2905
- const refState = React4.useRef();
3425
+ const stickyHeaderIndices = stickyHeaderIndicesProp != null ? stickyHeaderIndicesProp : stickyIndicesDeprecated;
3426
+ if (IS_DEV && stickyIndicesDeprecated && !stickyHeaderIndicesProp) {
3427
+ warnDevOnce(
3428
+ "stickyIndices",
3429
+ "stickyIndices has been renamed to stickyHeaderIndices. Please update your props to use stickyHeaderIndices."
3430
+ );
3431
+ }
3432
+ const refState = React3.useRef();
2906
3433
  if (!refState.current) {
2907
3434
  if (!ctx.internalState) {
2908
3435
  const initialScrollLength = (estimatedListSize != null ? estimatedListSize : { height: 0, width: 0 } )[horizontal ? "width" : "height"];
@@ -2912,18 +3439,29 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2912
3439
  columns: /* @__PURE__ */ new Map(),
2913
3440
  containerItemKeys: /* @__PURE__ */ new Set(),
2914
3441
  containerItemTypes: /* @__PURE__ */ new Map(),
3442
+ dataChangeNeedsScrollUpdate: false,
3443
+ didColumnsChange: false,
3444
+ didDataChange: false,
2915
3445
  enableScrollForNextCalculateItemsInView: true,
2916
3446
  endBuffered: -1,
2917
3447
  endNoBuffer: -1,
2918
- endReachedBlockedByTimer: false,
3448
+ endReachedSnapshot: void 0,
2919
3449
  firstFullyOnScreenIndex: -1,
2920
- idCache: /* @__PURE__ */ new Map(),
3450
+ idCache: [],
2921
3451
  idsInView: [],
2922
3452
  indexByKey: /* @__PURE__ */ new Map(),
2923
- initialScroll,
3453
+ initialAnchor: (initialScrollProp == null ? void 0 : initialScrollProp.index) !== void 0 && (initialScrollProp == null ? void 0 : initialScrollProp.viewPosition) !== void 0 ? {
3454
+ attempts: 0,
3455
+ index: initialScrollProp.index,
3456
+ settledTicks: 0,
3457
+ viewOffset: (_a3 = initialScrollProp.viewOffset) != null ? _a3 : 0,
3458
+ viewPosition: initialScrollProp.viewPosition
3459
+ } : void 0,
3460
+ initialScroll: initialScrollProp,
2924
3461
  isAtEnd: false,
2925
3462
  isAtStart: false,
2926
3463
  isEndReached: false,
3464
+ isFirst: true,
2927
3465
  isStartReached: false,
2928
3466
  lastBatchingAction: Date.now(),
2929
3467
  lastLayout: void 0,
@@ -2948,7 +3486,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2948
3486
  sizesKnown: /* @__PURE__ */ new Map(),
2949
3487
  startBuffered: -1,
2950
3488
  startNoBuffer: -1,
2951
- startReachedBlockedByTimer: false,
3489
+ startReachedSnapshot: void 0,
2952
3490
  stickyContainerPool: /* @__PURE__ */ new Set(),
2953
3491
  stickyContainers: /* @__PURE__ */ new Map(),
2954
3492
  timeoutSizeMessage: 0,
@@ -2956,21 +3494,27 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2956
3494
  totalSize: 0,
2957
3495
  viewabilityConfigCallbackPairs: void 0
2958
3496
  };
3497
+ const internalState = ctx.internalState;
3498
+ internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, internalState, params);
2959
3499
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
2960
3500
  set$(ctx, "extraData", extraData);
2961
3501
  }
2962
3502
  refState.current = ctx.internalState;
2963
3503
  }
2964
3504
  const state = refState.current;
2965
- const isFirst = !state.props.renderItem;
2966
- const didDataChange = state.props.data !== dataProp;
2967
- const throttleScrollFn = (
2968
- // @ts-expect-error TODO Fix this
2969
- scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp
2970
- );
3505
+ const isFirstLocal = state.isFirst;
3506
+ state.didColumnsChange = numColumnsProp !== state.props.numColumns;
3507
+ const didDataChangeLocal = state.props.dataVersion !== dataVersion || state.props.data !== dataProp && checkActualChange(state, dataProp, state.props.data);
3508
+ if (didDataChangeLocal) {
3509
+ state.dataChangeNeedsScrollUpdate = true;
3510
+ state.didDataChange = true;
3511
+ state.previousData = state.props.data;
3512
+ }
3513
+ const throttleScrollFn = scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp;
2971
3514
  state.props = {
2972
3515
  alignItemsAtEnd,
2973
3516
  data: dataProp,
3517
+ dataVersion,
2974
3518
  enableAverages,
2975
3519
  estimatedItemSize,
2976
3520
  getEstimatedItemSize,
@@ -2978,7 +3522,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2978
3522
  getItemType,
2979
3523
  horizontal: !!horizontal,
2980
3524
  initialContainerPoolRatio,
2981
- initialScroll,
2982
3525
  itemsAreEqual,
2983
3526
  keyExtractor,
2984
3527
  maintainScrollAtEnd,
@@ -2992,45 +3535,25 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2992
3535
  onScroll: throttleScrollFn,
2993
3536
  onStartReached,
2994
3537
  onStartReachedThreshold,
3538
+ onStickyHeaderChange,
2995
3539
  recycleItems: !!recycleItems,
2996
3540
  renderItem,
2997
3541
  scrollBuffer,
2998
3542
  snapToIndices,
2999
- stickyIndicesArr: stickyIndices != null ? stickyIndices : [],
3000
- stickyIndicesSet: React4.useMemo(() => new Set(stickyIndices != null ? stickyIndices : []), [stickyIndices == null ? void 0 : stickyIndices.join(",")]),
3543
+ stickyIndicesArr: stickyHeaderIndices != null ? stickyHeaderIndices : [],
3544
+ stickyIndicesSet: React3.useMemo(() => new Set(stickyHeaderIndices != null ? stickyHeaderIndices : []), [stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.join(",")]),
3001
3545
  stylePaddingBottom: stylePaddingBottomState,
3002
3546
  stylePaddingTop: stylePaddingTopState,
3003
3547
  suggestEstimatedItemSize: !!suggestEstimatedItemSize
3004
3548
  };
3005
3549
  state.refScroller = refScroller;
3006
- const checkResetContainers = (isFirst2) => {
3007
- const state2 = refState.current;
3008
- if (state2) {
3009
- if (!isFirst2 && state2.props.data !== dataProp) {
3010
- updateAveragesOnDataChange(state2, state2.props.data, dataProp);
3011
- }
3012
- state2.props.data = dataProp;
3013
- if (!isFirst2) {
3014
- calculateItemsInView(ctx, state2, { dataChanged: true, doMVCP: true });
3015
- const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
3016
- const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state2, false);
3017
- if (!didMaintainScrollAtEnd && dataProp.length > state2.props.data.length) {
3018
- state2.isEndReached = false;
3019
- }
3020
- if (!didMaintainScrollAtEnd) {
3021
- checkAtTop(state2);
3022
- checkAtBottom(ctx, state2);
3023
- }
3024
- }
3025
- }
3026
- };
3027
- const memoizedLastItemKeys = React4.useMemo(() => {
3550
+ const memoizedLastItemKeys = React3.useMemo(() => {
3028
3551
  if (!dataProp.length) return [];
3029
3552
  return Array.from(
3030
3553
  { length: Math.min(numColumnsProp, dataProp.length) },
3031
3554
  (_, i) => getId(state, dataProp.length - 1 - i)
3032
3555
  );
3033
- }, [dataProp, numColumnsProp]);
3556
+ }, [dataProp, dataVersion, numColumnsProp]);
3034
3557
  const initializeStateVars = () => {
3035
3558
  set$(ctx, "lastItemKeys", memoizedLastItemKeys);
3036
3559
  set$(ctx, "numColumns", numColumnsProp);
@@ -3038,44 +3561,70 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3038
3561
  setPaddingTop(ctx, state, { stylePaddingTop: stylePaddingTopState });
3039
3562
  refState.current.props.stylePaddingBottom = stylePaddingBottomState;
3040
3563
  let paddingDiff = stylePaddingTopState - prevPaddingTop;
3041
- if (maintainVisibleContentPosition && paddingDiff && prevPaddingTop !== void 0 && Platform.OS === "ios") {
3564
+ if (paddingDiff && prevPaddingTop !== void 0 && Platform.OS === "ios") {
3042
3565
  if (state.scroll < 0) {
3043
3566
  paddingDiff += state.scroll;
3044
3567
  }
3045
3568
  requestAdjust(ctx, state, paddingDiff);
3046
3569
  }
3047
3570
  };
3048
- if (isFirst) {
3571
+ if (isFirstLocal) {
3049
3572
  initializeStateVars();
3050
- updateAllPositions(ctx, state);
3573
+ updateItemPositions(
3574
+ ctx,
3575
+ state,
3576
+ /*dataChanged*/
3577
+ true
3578
+ );
3051
3579
  }
3052
- const initialContentOffset = React4.useMemo(() => {
3053
- if (initialScroll) {
3054
- const { index, viewOffset } = initialScroll;
3055
- let initialContentOffset2 = viewOffset || 0;
3056
- if (index !== void 0) {
3057
- initialContentOffset2 += calculateOffsetForIndex(ctx, state, index);
3058
- }
3059
- refState.current.isStartReached = initialContentOffset2 < refState.current.scrollLength * onStartReachedThreshold;
3060
- if (initialContentOffset2 > 0) {
3061
- scrollTo(state, { animated: false, index, offset: initialContentOffset2 });
3062
- }
3063
- return initialContentOffset2;
3580
+ const initialContentOffset = React3.useMemo(() => {
3581
+ var _a4, _b2;
3582
+ const { initialScroll } = refState.current;
3583
+ if (!initialScroll) {
3584
+ refState.current.initialAnchor = void 0;
3585
+ return 0;
3586
+ }
3587
+ if (initialScroll.index !== void 0 && (!refState.current.initialAnchor || ((_a4 = refState.current.initialAnchor) == null ? void 0 : _a4.index) !== initialScroll.index)) {
3588
+ refState.current.initialAnchor = {
3589
+ attempts: 0,
3590
+ index: initialScroll.index,
3591
+ settledTicks: 0,
3592
+ viewOffset: (_b2 = initialScroll.viewOffset) != null ? _b2 : 0,
3593
+ viewPosition: initialScroll.viewPosition
3594
+ };
3064
3595
  }
3065
- return 0;
3596
+ if (initialScroll.contentOffset !== void 0) {
3597
+ return initialScroll.contentOffset;
3598
+ }
3599
+ const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, state, initialScroll.index) : 0;
3600
+ const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, state, baseOffset, initialScroll);
3601
+ let clampedOffset = resolvedOffset;
3602
+ if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
3603
+ const maxOffset = Math.max(0, state.totalSize - state.scrollLength);
3604
+ clampedOffset = Math.min(clampedOffset, maxOffset);
3605
+ }
3606
+ clampedOffset = Math.max(0, clampedOffset);
3607
+ const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
3608
+ refState.current.initialScroll = updatedInitialScroll;
3609
+ state.initialScroll = updatedInitialScroll;
3610
+ refState.current.isStartReached = clampedOffset < refState.current.scrollLength * onStartReachedThreshold;
3611
+ return clampedOffset;
3066
3612
  }, [renderNum]);
3067
- if (isFirst || didDataChange || numColumnsProp !== peek$(ctx, "numColumns")) {
3068
- state.lastBatchingAction = Date.now();
3069
- if (!keyExtractorProp && !isFirst && didDataChange) {
3070
- __DEV__ && warnDevOnce(
3613
+ if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
3614
+ refState.current.lastBatchingAction = Date.now();
3615
+ if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
3616
+ IS_DEV && warnDevOnce(
3071
3617
  "keyExtractor",
3072
3618
  "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."
3073
3619
  );
3074
- state.sizes.clear();
3075
- state.positions.clear();
3620
+ refState.current.sizes.clear();
3621
+ refState.current.positions.clear();
3622
+ refState.current.totalSize = 0;
3623
+ set$(ctx, "totalSize", 0);
3076
3624
  }
3077
3625
  }
3078
- const onLayoutHeader = React4.useCallback((rect, fromLayoutEffect) => {
3626
+ const onLayoutHeader = React3.useCallback((rect, fromLayoutEffect) => {
3627
+ const { initialScroll } = refState.current;
3079
3628
  const size = rect[horizontal ? "width" : "height"];
3080
3629
  set$(ctx, "headerSize", size);
3081
3630
  if ((initialScroll == null ? void 0 : initialScroll.index) !== void 0) {
@@ -3086,134 +3635,73 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3086
3635
  }
3087
3636
  }
3088
3637
  }, []);
3089
- React4.useLayoutEffect(() => {
3638
+ const doInitialScroll = React3.useCallback(() => {
3639
+ var _a4;
3640
+ const initialScroll = state.initialScroll;
3641
+ if (initialScroll) {
3642
+ scrollTo(ctx, state, {
3643
+ animated: false,
3644
+ index: (_a4 = state.initialScroll) == null ? void 0 : _a4.index,
3645
+ isInitialScroll: true,
3646
+ offset: initialContentOffset,
3647
+ precomputedWithViewOffset: true
3648
+ });
3649
+ }
3650
+ }, [initialContentOffset]);
3651
+ const onLayoutChange = React3.useCallback((layout) => {
3652
+ doInitialScroll();
3653
+ handleLayout(ctx, state, layout, setCanRender);
3654
+ }, []);
3655
+ const { onLayout } = useOnLayoutSync({
3656
+ onLayoutChange,
3657
+ onLayoutProp,
3658
+ ref: refScroller
3659
+ // the type of ScrollView doesn't include measure?
3660
+ });
3661
+ React3.useLayoutEffect(() => {
3090
3662
  if (snapToIndices) {
3091
3663
  updateSnapToOffsets(ctx, state);
3092
3664
  }
3093
3665
  }, [snapToIndices]);
3094
- React4.useLayoutEffect(() => {
3095
- const didAllocateContainers = dataProp.length > 0 && doInitialAllocateContainersCallback();
3096
- if (!didAllocateContainers) {
3097
- checkResetContainers(
3098
- /*isFirst*/
3099
- isFirst
3100
- );
3101
- }
3102
- }, [dataProp, numColumnsProp]);
3103
- React4.useLayoutEffect(() => {
3666
+ React3.useLayoutEffect(() => {
3667
+ const {
3668
+ didColumnsChange,
3669
+ didDataChange,
3670
+ isFirst,
3671
+ props: { data }
3672
+ } = state;
3673
+ const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx, state);
3674
+ if (!didAllocateContainers && !isFirst && (didDataChange || didColumnsChange)) {
3675
+ checkResetContainers(ctx, state, data);
3676
+ }
3677
+ state.didColumnsChange = false;
3678
+ state.didDataChange = false;
3679
+ state.isFirst = false;
3680
+ }, [dataProp, dataVersion, numColumnsProp]);
3681
+ React3.useLayoutEffect(() => {
3104
3682
  set$(ctx, "extraData", extraData);
3105
3683
  }, [extraData]);
3106
- const { onLayout } = useSyncLayout({
3107
- onLayout: onLayoutProp,
3108
- onLayoutChange: React4.useCallback(
3109
- (rectangle) => {
3110
- handleLayout(ctx, state, rectangle, setCanRender);
3111
- },
3112
- [ctx, state, setCanRender]
3113
- ),
3114
- ref: refScroller
3115
- });
3116
- React4.useLayoutEffect(initializeStateVars, [
3684
+ React3.useLayoutEffect(initializeStateVars, [
3685
+ dataVersion,
3117
3686
  memoizedLastItemKeys.join(","),
3118
3687
  numColumnsProp,
3119
- stylePaddingTopState,
3120
- stylePaddingBottomState
3688
+ stylePaddingBottomState,
3689
+ stylePaddingTopState
3121
3690
  ]);
3122
- const doInitialAllocateContainersCallback = () => {
3123
- return doInitialAllocateContainers(ctx, state);
3124
- };
3125
- React4.useImperativeHandle(forwardedRef, () => {
3126
- const scrollIndexIntoView = (options) => {
3127
- const state2 = refState.current;
3128
- if (state2) {
3129
- const { index, ...rest2 } = options;
3130
- const { startNoBuffer, endNoBuffer } = state2;
3131
- if (index < startNoBuffer || index > endNoBuffer) {
3132
- const viewPosition = index < startNoBuffer ? 0 : 1;
3133
- scrollToIndex(ctx, state2, {
3134
- ...rest2,
3135
- index,
3136
- viewPosition
3137
- });
3138
- }
3139
- }
3140
- };
3141
- return {
3142
- flashScrollIndicators: () => {
3143
- var _a, _b;
3144
- return (_b = (_a = refScroller.current) == null ? void 0 : _a.flashScrollIndicators) == null ? void 0 : _b.call(_a);
3145
- },
3146
- getNativeScrollRef: () => refScroller.current,
3147
- getScrollableNode: () => refScroller.current,
3148
- getScrollResponder: () => refScroller.current,
3149
- getState: () => {
3150
- const state2 = refState.current;
3151
- return state2 ? {
3152
- contentLength: state2.totalSize,
3153
- data: state2.props.data,
3154
- end: state2.endNoBuffer,
3155
- endBuffered: state2.endBuffered,
3156
- isAtEnd: state2.isAtEnd,
3157
- isAtStart: state2.isAtStart,
3158
- positionAtIndex: (index) => state2.positions.get(getId(state2, index)),
3159
- positions: state2.positions,
3160
- scroll: state2.scroll,
3161
- scrollLength: state2.scrollLength,
3162
- sizeAtIndex: (index) => state2.sizesKnown.get(getId(state2, index)),
3163
- sizes: state2.sizesKnown,
3164
- start: state2.startNoBuffer,
3165
- startBuffered: state2.startBuffered
3166
- } : {};
3167
- },
3168
- scrollIndexIntoView,
3169
- scrollItemIntoView: ({ item, ...props2 }) => {
3170
- const data = refState.current.props.data;
3171
- const index = data.indexOf(item);
3172
- if (index !== -1) {
3173
- scrollIndexIntoView({ index, ...props2 });
3174
- }
3175
- },
3176
- scrollToEnd: (options) => {
3177
- const data = refState.current.props.data;
3178
- const stylePaddingBottom = refState.current.props.stylePaddingBottom;
3179
- const index = data.length - 1;
3180
- if (index !== -1) {
3181
- const paddingBottom = stylePaddingBottom || 0;
3182
- const footerSize = peek$(ctx, "footerSize") || 0;
3183
- scrollToIndex(ctx, state, {
3184
- index,
3185
- viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
3186
- viewPosition: 1,
3187
- ...options
3188
- });
3189
- }
3190
- },
3191
- scrollToIndex: (params) => scrollToIndex(ctx, state, params),
3192
- scrollToItem: ({ item, ...props2 }) => {
3193
- const data = refState.current.props.data;
3194
- const index = data.indexOf(item);
3195
- if (index !== -1) {
3196
- scrollToIndex(ctx, state, { index, ...props2 });
3197
- }
3198
- },
3199
- scrollToOffset: (params) => scrollTo(state, params),
3200
- setScrollProcessingEnabled: (enabled) => {
3201
- refState.current.scrollProcessingEnabled = enabled;
3202
- },
3203
- setVisibleContentAnchorOffset: (value) => {
3204
- const val = typeof value === "function" ? value(peek$(ctx, "scrollAdjustUserOffset") || 0) : value;
3205
- set$(ctx, "scrollAdjustUserOffset", val);
3206
- }
3207
- };
3208
- }, []);
3691
+ React3.useEffect(() => {
3692
+ const viewability = setupViewability({
3693
+ onViewableItemsChanged,
3694
+ viewabilityConfig,
3695
+ viewabilityConfigCallbackPairs
3696
+ });
3697
+ state.viewabilityConfigCallbackPairs = viewability;
3698
+ state.enableScrollForNextCalculateItemsInView = !viewability;
3699
+ }, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
3700
+ React3.useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx, state), []);
3209
3701
  {
3210
- React4.useEffect(() => {
3211
- if (initialContentOffset) {
3212
- scrollTo(state, { animated: false, offset: initialContentOffset });
3213
- }
3214
- }, []);
3702
+ React3.useEffect(doInitialScroll, []);
3215
3703
  }
3216
- const fns = React4.useMemo(
3704
+ const fns = React3.useMemo(
3217
3705
  () => ({
3218
3706
  getRenderedItem: (key) => getRenderedItem(ctx, state, key),
3219
3707
  onScroll: (event) => onScroll(ctx, state, event),
@@ -3221,8 +3709,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3221
3709
  }),
3222
3710
  []
3223
3711
  );
3224
- const onScrollHandler = useStickyScrollHandler(stickyIndices, horizontal, ctx, fns.onScroll);
3225
- return /* @__PURE__ */ React4__namespace.createElement(React4__namespace.Fragment, null, /* @__PURE__ */ React4__namespace.createElement(
3712
+ const onScrollHandler = useStickyScrollHandler(stickyHeaderIndices, horizontal, ctx, fns.onScroll);
3713
+ return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement(
3226
3714
  ListComponent,
3227
3715
  {
3228
3716
  ...rest,
@@ -3240,7 +3728,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3240
3728
  onMomentumScrollEnd: (event) => {
3241
3729
  {
3242
3730
  requestAnimationFrame(() => {
3243
- finishScrollTo(refState.current);
3731
+ finishScrollTo(ctx, refState.current);
3244
3732
  });
3245
3733
  }
3246
3734
  if (onMomentumScrollEnd) {
@@ -3249,9 +3737,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3249
3737
  },
3250
3738
  onScroll: onScrollHandler,
3251
3739
  recycleItems,
3252
- refreshControl: refreshControl ? stylePaddingTopState > 0 ? React4__namespace.cloneElement(refreshControl, {
3740
+ refreshControl: refreshControl ? stylePaddingTopState > 0 ? React3__namespace.cloneElement(refreshControl, {
3253
3741
  progressViewOffset: (refreshControl.props.progressViewOffset || 0) + stylePaddingTopState
3254
- }) : refreshControl : onRefresh && /* @__PURE__ */ React4__namespace.createElement(
3742
+ }) : refreshControl : onRefresh && /* @__PURE__ */ React3__namespace.createElement(
3255
3743
  RefreshControl,
3256
3744
  {
3257
3745
  onRefresh,
@@ -3260,14 +3748,15 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3260
3748
  }
3261
3749
  ),
3262
3750
  refScrollView: combinedRef,
3263
- scrollAdjustHandler: state.scrollAdjustHandler,
3751
+ scrollAdjustHandler: (_b = refState.current) == null ? void 0 : _b.scrollAdjustHandler,
3752
+ scrollEventThrottle: 16 ,
3264
3753
  snapToIndices,
3265
- stickyIndices,
3754
+ stickyHeaderIndices,
3266
3755
  style,
3267
3756
  updateItemSize: fns.updateItemSize,
3268
3757
  waitForInitialLayout
3269
3758
  }
3270
- ), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React4__namespace.createElement(DebugView, { state: refState.current }));
3759
+ ), IS_DEV && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React3__namespace.createElement(DebugView, { state: refState.current }));
3271
3760
  });
3272
3761
 
3273
3762
  exports.LegendList = LegendList;
@@ -3275,6 +3764,6 @@ exports.useIsLastItem = useIsLastItem;
3275
3764
  exports.useListScrollSize = useListScrollSize;
3276
3765
  exports.useRecyclingEffect = useRecyclingEffect;
3277
3766
  exports.useRecyclingState = useRecyclingState;
3278
- exports.useSyncLayout = useSyncLayout2;
3767
+ exports.useSyncLayout = useSyncLayout;
3279
3768
  exports.useViewability = useViewability;
3280
3769
  exports.useViewabilityAmount = useViewabilityAmount;