@legendapp/list 2.1.0-next.0 → 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
@@ -2,6 +2,7 @@
2
2
 
3
3
  var React3 = require('react');
4
4
  var shim = require('use-sync-external-store/shim');
5
+ var reactDom = require('react-dom');
5
6
 
6
7
  function _interopNamespace(e) {
7
8
  if (e && e.__esModule) return e;
@@ -23,458 +24,12 @@ function _interopNamespace(e) {
23
24
 
24
25
  var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
25
26
 
26
- var __create = Object.create;
27
- var __defProp = Object.defineProperty;
28
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
29
- var __getOwnPropNames = Object.getOwnPropertyNames;
30
- var __getProtoOf = Object.getPrototypeOf;
31
- var __hasOwnProp = Object.prototype.hasOwnProperty;
32
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
33
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
34
- }) : x)(function(x) {
35
- if (typeof require !== "undefined") return require.apply(this, arguments);
36
- throw Error('Dynamic require of "' + x + '" is not supported');
37
- });
38
- var __commonJS = (cb, mod) => function __require2() {
39
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
40
- };
41
- var __copyProps = (to, from, except, desc) => {
42
- if (from && typeof from === "object" || typeof from === "function") {
43
- for (let key of __getOwnPropNames(from))
44
- if (!__hasOwnProp.call(to, key) && key !== except)
45
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
46
- }
47
- return to;
48
- };
49
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
50
- // If the importer is in node compatibility mode or this is not an ESM
51
- // file that has been converted to a CommonJS file using a Babel-
52
- // compatible transform (i.e. "__esModule" has not been set), then set
53
- // "default" to the CommonJS "module.exports" for node compatibility.
54
- !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
55
- mod
56
- ));
57
-
58
- // node_modules/react-dom/cjs/react-dom.production.js
59
- var require_react_dom_production = __commonJS({
60
- "node_modules/react-dom/cjs/react-dom.production.js"(exports) {
61
- var React12 = __require("react");
62
- function formatProdErrorMessage(code) {
63
- var url = "https://react.dev/errors/" + code;
64
- if (1 < arguments.length) {
65
- url += "?args[]=" + encodeURIComponent(arguments[1]);
66
- for (var i = 2; i < arguments.length; i++)
67
- url += "&args[]=" + encodeURIComponent(arguments[i]);
68
- }
69
- return "Minified React error #" + code + "; visit " + url + " for the full message or use the non-minified dev environment for full errors and additional helpful warnings.";
70
- }
71
- function noop2() {
72
- }
73
- var Internals = {
74
- d: {
75
- f: noop2,
76
- r: function() {
77
- throw Error(formatProdErrorMessage(522));
78
- },
79
- D: noop2,
80
- C: noop2,
81
- L: noop2,
82
- m: noop2,
83
- X: noop2,
84
- S: noop2,
85
- M: noop2
86
- },
87
- p: 0,
88
- findDOMNode: null
89
- };
90
- var REACT_PORTAL_TYPE = Symbol.for("react.portal");
91
- function createPortal$1(children, containerInfo, implementation) {
92
- var key = 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null;
93
- return {
94
- $$typeof: REACT_PORTAL_TYPE,
95
- key: null == key ? null : "" + key,
96
- children,
97
- containerInfo,
98
- implementation
99
- };
100
- }
101
- var ReactSharedInternals = React12.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
102
- function getCrossOriginStringAs(as, input) {
103
- if ("font" === as) return "";
104
- if ("string" === typeof input)
105
- return "use-credentials" === input ? input : "";
106
- }
107
- exports.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = Internals;
108
- exports.createPortal = function(children, container) {
109
- var key = 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null;
110
- if (!container || 1 !== container.nodeType && 9 !== container.nodeType && 11 !== container.nodeType)
111
- throw Error(formatProdErrorMessage(299));
112
- return createPortal$1(children, container, null, key);
113
- };
114
- exports.flushSync = function(fn) {
115
- var previousTransition = ReactSharedInternals.T, previousUpdatePriority = Internals.p;
116
- try {
117
- if (ReactSharedInternals.T = null, Internals.p = 2, fn) return fn();
118
- } finally {
119
- ReactSharedInternals.T = previousTransition, Internals.p = previousUpdatePriority, Internals.d.f();
120
- }
121
- };
122
- exports.preconnect = function(href, options) {
123
- "string" === typeof href && (options ? (options = options.crossOrigin, options = "string" === typeof options ? "use-credentials" === options ? options : "" : void 0) : options = null, Internals.d.C(href, options));
124
- };
125
- exports.prefetchDNS = function(href) {
126
- "string" === typeof href && Internals.d.D(href);
127
- };
128
- exports.preinit = function(href, options) {
129
- if ("string" === typeof href && options && "string" === typeof options.as) {
130
- var as = options.as, crossOrigin = getCrossOriginStringAs(as, options.crossOrigin), integrity = "string" === typeof options.integrity ? options.integrity : void 0, fetchPriority = "string" === typeof options.fetchPriority ? options.fetchPriority : void 0;
131
- "style" === as ? Internals.d.S(
132
- href,
133
- "string" === typeof options.precedence ? options.precedence : void 0,
134
- {
135
- crossOrigin,
136
- integrity,
137
- fetchPriority
138
- }
139
- ) : "script" === as && Internals.d.X(href, {
140
- crossOrigin,
141
- integrity,
142
- fetchPriority,
143
- nonce: "string" === typeof options.nonce ? options.nonce : void 0
144
- });
145
- }
146
- };
147
- exports.preinitModule = function(href, options) {
148
- if ("string" === typeof href)
149
- if ("object" === typeof options && null !== options) {
150
- if (null == options.as || "script" === options.as) {
151
- var crossOrigin = getCrossOriginStringAs(
152
- options.as,
153
- options.crossOrigin
154
- );
155
- Internals.d.M(href, {
156
- crossOrigin,
157
- integrity: "string" === typeof options.integrity ? options.integrity : void 0,
158
- nonce: "string" === typeof options.nonce ? options.nonce : void 0
159
- });
160
- }
161
- } else null == options && Internals.d.M(href);
162
- };
163
- exports.preload = function(href, options) {
164
- if ("string" === typeof href && "object" === typeof options && null !== options && "string" === typeof options.as) {
165
- var as = options.as, crossOrigin = getCrossOriginStringAs(as, options.crossOrigin);
166
- Internals.d.L(href, as, {
167
- crossOrigin,
168
- integrity: "string" === typeof options.integrity ? options.integrity : void 0,
169
- nonce: "string" === typeof options.nonce ? options.nonce : void 0,
170
- type: "string" === typeof options.type ? options.type : void 0,
171
- fetchPriority: "string" === typeof options.fetchPriority ? options.fetchPriority : void 0,
172
- referrerPolicy: "string" === typeof options.referrerPolicy ? options.referrerPolicy : void 0,
173
- imageSrcSet: "string" === typeof options.imageSrcSet ? options.imageSrcSet : void 0,
174
- imageSizes: "string" === typeof options.imageSizes ? options.imageSizes : void 0,
175
- media: "string" === typeof options.media ? options.media : void 0
176
- });
177
- }
178
- };
179
- exports.preloadModule = function(href, options) {
180
- if ("string" === typeof href)
181
- if (options) {
182
- var crossOrigin = getCrossOriginStringAs(options.as, options.crossOrigin);
183
- Internals.d.m(href, {
184
- as: "string" === typeof options.as && "script" !== options.as ? options.as : void 0,
185
- crossOrigin,
186
- integrity: "string" === typeof options.integrity ? options.integrity : void 0
187
- });
188
- } else Internals.d.m(href);
189
- };
190
- exports.requestFormReset = function(form) {
191
- Internals.d.r(form);
192
- };
193
- exports.unstable_batchedUpdates = function(fn, a) {
194
- return fn(a);
195
- };
196
- exports.useFormState = function(action, initialState, permalink) {
197
- return ReactSharedInternals.H.useFormState(action, initialState, permalink);
198
- };
199
- exports.useFormStatus = function() {
200
- return ReactSharedInternals.H.useHostTransitionStatus();
201
- };
202
- exports.version = "19.1.1";
203
- }
204
- });
205
-
206
- // node_modules/react-dom/cjs/react-dom.development.js
207
- var require_react_dom_development = __commonJS({
208
- "node_modules/react-dom/cjs/react-dom.development.js"(exports) {
209
- "production" !== process.env.NODE_ENV && function() {
210
- function noop2() {
211
- }
212
- function testStringCoercion(value) {
213
- return "" + value;
214
- }
215
- function createPortal$1(children, containerInfo, implementation) {
216
- var key = 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null;
217
- try {
218
- testStringCoercion(key);
219
- var JSCompiler_inline_result = false;
220
- } catch (e) {
221
- JSCompiler_inline_result = true;
222
- }
223
- JSCompiler_inline_result && (console.error(
224
- "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
225
- "function" === typeof Symbol && Symbol.toStringTag && key[Symbol.toStringTag] || key.constructor.name || "Object"
226
- ), testStringCoercion(key));
227
- return {
228
- $$typeof: REACT_PORTAL_TYPE,
229
- key: null == key ? null : "" + key,
230
- children,
231
- containerInfo,
232
- implementation
233
- };
234
- }
235
- function getCrossOriginStringAs(as, input) {
236
- if ("font" === as) return "";
237
- if ("string" === typeof input)
238
- return "use-credentials" === input ? input : "";
239
- }
240
- function getValueDescriptorExpectingObjectForWarning(thing) {
241
- return null === thing ? "`null`" : void 0 === thing ? "`undefined`" : "" === thing ? "an empty string" : 'something with type "' + typeof thing + '"';
242
- }
243
- function getValueDescriptorExpectingEnumForWarning(thing) {
244
- return null === thing ? "`null`" : void 0 === thing ? "`undefined`" : "" === thing ? "an empty string" : "string" === typeof thing ? JSON.stringify(thing) : "number" === typeof thing ? "`" + thing + "`" : 'something with type "' + typeof thing + '"';
245
- }
246
- function resolveDispatcher() {
247
- var dispatcher = ReactSharedInternals.H;
248
- null === dispatcher && console.error(
249
- "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem."
250
- );
251
- return dispatcher;
252
- }
253
- "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
254
- var React12 = __require("react"), Internals = {
255
- d: {
256
- f: noop2,
257
- r: function() {
258
- throw Error(
259
- "Invalid form element. requestFormReset must be passed a form that was rendered by React."
260
- );
261
- },
262
- D: noop2,
263
- C: noop2,
264
- L: noop2,
265
- m: noop2,
266
- X: noop2,
267
- S: noop2,
268
- M: noop2
269
- },
270
- p: 0,
271
- findDOMNode: null
272
- }, REACT_PORTAL_TYPE = Symbol.for("react.portal"), ReactSharedInternals = React12.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
273
- "function" === typeof Map && null != Map.prototype && "function" === typeof Map.prototype.forEach && "function" === typeof Set && null != Set.prototype && "function" === typeof Set.prototype.clear && "function" === typeof Set.prototype.forEach || console.error(
274
- "React depends on Map and Set built-in types. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills"
275
- );
276
- exports.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = Internals;
277
- exports.createPortal = function(children, container) {
278
- var key = 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null;
279
- if (!container || 1 !== container.nodeType && 9 !== container.nodeType && 11 !== container.nodeType)
280
- throw Error("Target container is not a DOM element.");
281
- return createPortal$1(children, container, null, key);
282
- };
283
- exports.flushSync = function(fn) {
284
- var previousTransition = ReactSharedInternals.T, previousUpdatePriority = Internals.p;
285
- try {
286
- if (ReactSharedInternals.T = null, Internals.p = 2, fn)
287
- return fn();
288
- } finally {
289
- ReactSharedInternals.T = previousTransition, Internals.p = previousUpdatePriority, Internals.d.f() && console.error(
290
- "flushSync was called from inside a lifecycle method. React cannot flush when React is already rendering. Consider moving this call to a scheduler task or micro task."
291
- );
292
- }
293
- };
294
- exports.preconnect = function(href, options) {
295
- "string" === typeof href && href ? null != options && "object" !== typeof options ? console.error(
296
- "ReactDOM.preconnect(): Expected the `options` argument (second) to be an object but encountered %s instead. The only supported option at this time is `crossOrigin` which accepts a string.",
297
- getValueDescriptorExpectingEnumForWarning(options)
298
- ) : null != options && "string" !== typeof options.crossOrigin && console.error(
299
- "ReactDOM.preconnect(): Expected the `crossOrigin` option (second argument) to be a string but encountered %s instead. Try removing this option or passing a string value instead.",
300
- getValueDescriptorExpectingObjectForWarning(options.crossOrigin)
301
- ) : console.error(
302
- "ReactDOM.preconnect(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.",
303
- getValueDescriptorExpectingObjectForWarning(href)
304
- );
305
- "string" === typeof href && (options ? (options = options.crossOrigin, options = "string" === typeof options ? "use-credentials" === options ? options : "" : void 0) : options = null, Internals.d.C(href, options));
306
- };
307
- exports.prefetchDNS = function(href) {
308
- if ("string" !== typeof href || !href)
309
- console.error(
310
- "ReactDOM.prefetchDNS(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.",
311
- getValueDescriptorExpectingObjectForWarning(href)
312
- );
313
- else if (1 < arguments.length) {
314
- var options = arguments[1];
315
- "object" === typeof options && options.hasOwnProperty("crossOrigin") ? console.error(
316
- "ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered %s as a second argument instead. This argument is reserved for future options and is currently disallowed. It looks like the you are attempting to set a crossOrigin property for this DNS lookup hint. Browsers do not perform DNS queries using CORS and setting this attribute on the resource hint has no effect. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.",
317
- getValueDescriptorExpectingEnumForWarning(options)
318
- ) : console.error(
319
- "ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered %s as a second argument instead. This argument is reserved for future options and is currently disallowed. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.",
320
- getValueDescriptorExpectingEnumForWarning(options)
321
- );
322
- }
323
- "string" === typeof href && Internals.d.D(href);
324
- };
325
- exports.preinit = function(href, options) {
326
- "string" === typeof href && href ? null == options || "object" !== typeof options ? console.error(
327
- "ReactDOM.preinit(): Expected the `options` argument (second) to be an object with an `as` property describing the type of resource to be preinitialized but encountered %s instead.",
328
- getValueDescriptorExpectingEnumForWarning(options)
329
- ) : "style" !== options.as && "script" !== options.as && console.error(
330
- 'ReactDOM.preinit(): Expected the `as` property in the `options` argument (second) to contain a valid value describing the type of resource to be preinitialized but encountered %s instead. Valid values for `as` are "style" and "script".',
331
- getValueDescriptorExpectingEnumForWarning(options.as)
332
- ) : console.error(
333
- "ReactDOM.preinit(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.",
334
- getValueDescriptorExpectingObjectForWarning(href)
335
- );
336
- if ("string" === typeof href && options && "string" === typeof options.as) {
337
- var as = options.as, crossOrigin = getCrossOriginStringAs(as, options.crossOrigin), integrity = "string" === typeof options.integrity ? options.integrity : void 0, fetchPriority = "string" === typeof options.fetchPriority ? options.fetchPriority : void 0;
338
- "style" === as ? Internals.d.S(
339
- href,
340
- "string" === typeof options.precedence ? options.precedence : void 0,
341
- {
342
- crossOrigin,
343
- integrity,
344
- fetchPriority
345
- }
346
- ) : "script" === as && Internals.d.X(href, {
347
- crossOrigin,
348
- integrity,
349
- fetchPriority,
350
- nonce: "string" === typeof options.nonce ? options.nonce : void 0
351
- });
352
- }
353
- };
354
- exports.preinitModule = function(href, options) {
355
- var encountered = "";
356
- "string" === typeof href && href || (encountered += " The `href` argument encountered was " + getValueDescriptorExpectingObjectForWarning(href) + ".");
357
- void 0 !== options && "object" !== typeof options ? encountered += " The `options` argument encountered was " + getValueDescriptorExpectingObjectForWarning(options) + "." : options && "as" in options && "script" !== options.as && (encountered += " The `as` option encountered was " + getValueDescriptorExpectingEnumForWarning(options.as) + ".");
358
- if (encountered)
359
- console.error(
360
- "ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property.%s",
361
- encountered
362
- );
363
- else
364
- switch (encountered = options && "string" === typeof options.as ? options.as : "script", encountered) {
365
- case "script":
366
- break;
367
- default:
368
- encountered = getValueDescriptorExpectingEnumForWarning(encountered), console.error(
369
- 'ReactDOM.preinitModule(): Currently the only supported "as" type for this function is "script" but received "%s" instead. This warning was generated for `href` "%s". In the future other module types will be supported, aligning with the import-attributes proposal. Learn more here: (https://github.com/tc39/proposal-import-attributes)',
370
- encountered,
371
- href
372
- );
373
- }
374
- if ("string" === typeof href)
375
- if ("object" === typeof options && null !== options) {
376
- if (null == options.as || "script" === options.as)
377
- encountered = getCrossOriginStringAs(
378
- options.as,
379
- options.crossOrigin
380
- ), Internals.d.M(href, {
381
- crossOrigin: encountered,
382
- integrity: "string" === typeof options.integrity ? options.integrity : void 0,
383
- nonce: "string" === typeof options.nonce ? options.nonce : void 0
384
- });
385
- } else null == options && Internals.d.M(href);
386
- };
387
- exports.preload = function(href, options) {
388
- var encountered = "";
389
- "string" === typeof href && href || (encountered += " The `href` argument encountered was " + getValueDescriptorExpectingObjectForWarning(href) + ".");
390
- null == options || "object" !== typeof options ? encountered += " The `options` argument encountered was " + getValueDescriptorExpectingObjectForWarning(options) + "." : "string" === typeof options.as && options.as || (encountered += " The `as` option encountered was " + getValueDescriptorExpectingObjectForWarning(options.as) + ".");
391
- encountered && console.error(
392
- 'ReactDOM.preload(): Expected two arguments, a non-empty `href` string and an `options` object with an `as` property valid for a `<link rel="preload" as="..." />` tag.%s',
393
- encountered
394
- );
395
- if ("string" === typeof href && "object" === typeof options && null !== options && "string" === typeof options.as) {
396
- encountered = options.as;
397
- var crossOrigin = getCrossOriginStringAs(
398
- encountered,
399
- options.crossOrigin
400
- );
401
- Internals.d.L(href, encountered, {
402
- crossOrigin,
403
- integrity: "string" === typeof options.integrity ? options.integrity : void 0,
404
- nonce: "string" === typeof options.nonce ? options.nonce : void 0,
405
- type: "string" === typeof options.type ? options.type : void 0,
406
- fetchPriority: "string" === typeof options.fetchPriority ? options.fetchPriority : void 0,
407
- referrerPolicy: "string" === typeof options.referrerPolicy ? options.referrerPolicy : void 0,
408
- imageSrcSet: "string" === typeof options.imageSrcSet ? options.imageSrcSet : void 0,
409
- imageSizes: "string" === typeof options.imageSizes ? options.imageSizes : void 0,
410
- media: "string" === typeof options.media ? options.media : void 0
411
- });
412
- }
413
- };
414
- exports.preloadModule = function(href, options) {
415
- var encountered = "";
416
- "string" === typeof href && href || (encountered += " The `href` argument encountered was " + getValueDescriptorExpectingObjectForWarning(href) + ".");
417
- void 0 !== options && "object" !== typeof options ? encountered += " The `options` argument encountered was " + getValueDescriptorExpectingObjectForWarning(options) + "." : options && "as" in options && "string" !== typeof options.as && (encountered += " The `as` option encountered was " + getValueDescriptorExpectingObjectForWarning(options.as) + ".");
418
- encountered && console.error(
419
- 'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag.%s',
420
- encountered
421
- );
422
- "string" === typeof href && (options ? (encountered = getCrossOriginStringAs(
423
- options.as,
424
- options.crossOrigin
425
- ), Internals.d.m(href, {
426
- as: "string" === typeof options.as && "script" !== options.as ? options.as : void 0,
427
- crossOrigin: encountered,
428
- integrity: "string" === typeof options.integrity ? options.integrity : void 0
429
- })) : Internals.d.m(href));
430
- };
431
- exports.requestFormReset = function(form) {
432
- Internals.d.r(form);
433
- };
434
- exports.unstable_batchedUpdates = function(fn, a) {
435
- return fn(a);
436
- };
437
- exports.useFormState = function(action, initialState, permalink) {
438
- return resolveDispatcher().useFormState(action, initialState, permalink);
439
- };
440
- exports.useFormStatus = function() {
441
- return resolveDispatcher().useHostTransitionStatus();
442
- };
443
- exports.version = "19.1.1";
444
- "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
445
- }();
446
- }
447
- });
448
-
449
- // node_modules/react-dom/index.js
450
- var require_react_dom = __commonJS({
451
- "node_modules/react-dom/index.js"(exports, module) {
452
- function checkDCE() {
453
- if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined" || typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== "function") {
454
- return;
455
- }
456
- if (process.env.NODE_ENV !== "production") {
457
- throw new Error("^_^");
458
- }
459
- try {
460
- __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE);
461
- } catch (err) {
462
- console.error(err);
463
- }
464
- }
465
- if (process.env.NODE_ENV === "production") {
466
- checkDCE();
467
- module.exports = require_react_dom_production();
468
- } else {
469
- module.exports = require_react_dom_development();
470
- }
471
- }
472
- });
473
- var AnimatedView = React3.forwardRef(function AnimatedView2(props, ref) {
474
- return /* @__PURE__ */ React.createElement("div", { ref, ...props });
27
+ // src/components/LegendList.tsx
28
+ React3.forwardRef(function AnimatedView2(props, ref) {
29
+ return /* @__PURE__ */ React3__namespace.createElement("div", { ref, ...props });
475
30
  });
476
31
  var View = React3.forwardRef(function View2(props, ref) {
477
- return /* @__PURE__ */ React.createElement("div", { ref, ...props });
32
+ return /* @__PURE__ */ React3__namespace.createElement("div", { ref, ...props });
478
33
  });
479
34
  var Text = View;
480
35
 
@@ -499,7 +54,10 @@ function StateProvider({ children }) {
499
54
  ["stylePaddingTop", 0],
500
55
  ["headerSize", 0],
501
56
  ["numContainers", 0],
502
- ["totalSize", 0]
57
+ ["activeStickyIndex", void 0],
58
+ ["totalSize", 0],
59
+ ["scrollAdjustPending", 0],
60
+ ["scrollingTo", void 0]
503
61
  ]),
504
62
  viewRefs: /* @__PURE__ */ new Map()
505
63
  }));
@@ -568,11 +126,12 @@ function set$(ctx, signalName, value) {
568
126
  }
569
127
  }
570
128
  function getContentSize(ctx) {
129
+ var _a3, _b;
571
130
  const { values } = ctx;
572
131
  const stylePaddingTop = values.get("stylePaddingTop") || 0;
573
132
  const headerSize = values.get("headerSize") || 0;
574
133
  const footerSize = values.get("footerSize") || 0;
575
- const totalSize = values.get("totalSize");
134
+ const totalSize = (_b = (_a3 = ctx.internalState) == null ? void 0 : _a3.pendingTotalSize) != null ? _b : values.get("totalSize");
576
135
  return headerSize + footerSize + totalSize + stylePaddingTop;
577
136
  }
578
137
  function useArr$(signalNames) {
@@ -637,93 +196,63 @@ function useInterval(callback, delay) {
637
196
  return () => clearInterval(interval);
638
197
  }, [delay]);
639
198
  }
640
- var globalResizeObserver = null;
641
- function getGlobalResizeObserver() {
642
- if (!globalResizeObserver) {
643
- globalResizeObserver = new ResizeObserver((entries) => {
644
- for (const entry of entries) {
645
- const callbacks = callbackMap.get(entry.target);
646
- if (callbacks) {
647
- for (const callback of callbacks) {
648
- callback(entry);
649
- }
650
- }
651
- }
652
- });
653
- }
654
- return globalResizeObserver;
655
- }
656
- var callbackMap = /* @__PURE__ */ new WeakMap();
657
- function useResizeObserver(element, callback) {
658
- React3.useEffect(() => {
659
- if (!element) return;
660
- const observer = getGlobalResizeObserver();
661
- let callbacks = callbackMap.get(element);
662
- if (!callbacks) {
663
- callbacks = /* @__PURE__ */ new Set();
664
- callbackMap.set(element, callbacks);
665
- observer.observe(element);
666
- }
667
- callbacks.add(callback);
668
- return () => {
669
- const callbacks2 = callbackMap.get(element);
670
- if (callbacks2) {
671
- callbacks2.delete(callback);
672
- if (callbacks2.size === 0) {
673
- callbackMap.delete(element);
674
- observer.unobserve(element);
675
- }
676
- }
677
- };
678
- }, [element, callback]);
679
- }
680
-
681
- // src/hooks/useSyncLayout.tsx
682
- function useSyncLayout({
683
- ref,
684
- onLayoutChange
685
- }) {
686
- var _a, _b;
687
- useResizeObserver(
688
- ((_b = (_a = ref.current) == null ? void 0 : _a.getScrollableNode) == null ? void 0 : _b.call(_a)) || ref.current,
689
- React3.useCallback(
690
- (entry) => {
691
- onLayoutChange(entry.contentRect, false);
692
- },
693
- [onLayoutChange]
694
- )
695
- );
696
- React3.useLayoutEffect(() => {
697
- if (ref.current) {
698
- const rect = ref.current.getBoundingClientRect();
699
- onLayoutChange(
700
- {
701
- height: rect.height,
702
- width: rect.width,
703
- x: rect.left,
704
- y: rect.top
705
- },
706
- true
707
- );
708
- }
709
- }, []);
710
- return {};
711
- }
712
199
 
713
- // src/components/LayoutView.tsx
714
- var LayoutView = ({ onLayoutChange, refView, children, ...rest }) => {
715
- const ref = refView != null ? refView : React3.useRef();
716
- useSyncLayout({ onLayoutChange, ref });
717
- return /* @__PURE__ */ React.createElement("div", { ...rest, ref }, children);
718
- };
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;
719
207
 
720
208
  // src/constants.ts
721
209
  var POSITION_OUT_OF_VIEW = -1e7;
722
- var ENABLE_DEVMODE = __DEV__ && false;
723
- var ENABLE_DEBUG_VIEW = __DEV__ && false;
210
+ var ENABLE_DEVMODE = IS_DEV && false;
211
+ var ENABLE_DEBUG_VIEW = IS_DEV && false;
724
212
  var typedForwardRef = React3.forwardRef;
725
213
  var typedMemo = React3.memo;
726
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}`);
227
+ }
228
+ }
229
+ function roundSize(size) {
230
+ return Math.floor(size * 8) / 8;
231
+ }
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;
251
+ }
252
+ }
253
+ return -1;
254
+ }
255
+
727
256
  // src/components/PositionView.tsx
728
257
  var PositionViewState = typedMemo(function PositionView({
729
258
  id,
@@ -733,9 +262,12 @@ var PositionViewState = typedMemo(function PositionView({
733
262
  ...rest
734
263
  }) {
735
264
  const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
736
- const base = Array.isArray(style) ? Object.assign({}, ...style) : style;
737
- const combinedStyle = horizontal ? { ...base, left: position } : { ...base, top: position };
738
- return /* @__PURE__ */ React3__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 });
739
271
  });
740
272
  var PositionViewSticky = typedMemo(function PositionViewSticky2({
741
273
  id,
@@ -743,35 +275,47 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
743
275
  style,
744
276
  refView,
745
277
  index,
278
+ stickyOffset,
279
+ animatedScrollY: _animatedScrollY,
280
+ children,
746
281
  ...rest
747
282
  }) {
748
- const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
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
+ );
749
298
  const viewStyle = React3__namespace.useMemo(() => {
750
- const base = Array.isArray(style) ? Object.assign({}, ...style) : style;
751
- const axisStyle = horizontal ? { transform: `translateX(${position}px)` } : { top: position };
752
- return {
753
- ...base,
754
- zIndex: index + 1e3,
755
- ...axisStyle
756
- };
757
- }, [style, position, horizontal, index]);
758
- return /* @__PURE__ */ React3__namespace.createElement(LayoutView, { refView, style: viewStyle, ...rest });
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);
759
314
  });
760
315
  var PositionView2 = PositionViewState;
761
- function Separator({ ItemSeparatorComponent, itemKey, leadingItem }) {
762
- const [lastItemKeys] = useArr$(["lastItemKeys"]);
763
- const isALastItem = lastItemKeys.includes(itemKey);
764
- return isALastItem ? null : /* @__PURE__ */ React3__namespace.createElement(ItemSeparatorComponent, { leadingItem });
765
- }
766
316
 
767
317
  // src/constants-platform.ts
768
318
  var IsNewArchitecture = true;
769
-
770
- // src/platform/Platform.ts
771
- var Platform = {
772
- // Widen the type to avoid unreachable-branch lints in cross-platform code that compares against other OSes
773
- OS: "web"
774
- };
775
319
  var symbolFirst = Symbol();
776
320
  function useInit(cb) {
777
321
  const refValue = React3.useRef(symbolFirst);
@@ -781,37 +325,6 @@ function useInit(cb) {
781
325
  return refValue.current;
782
326
  }
783
327
 
784
- // src/utils/helpers.ts
785
- function isFunction(obj) {
786
- return typeof obj === "function";
787
- }
788
- function isArray(obj) {
789
- return Array.isArray(obj);
790
- }
791
- var warned = /* @__PURE__ */ new Set();
792
- function warnDevOnce(id, text) {
793
- if (__DEV__ && !warned.has(id)) {
794
- warned.add(id);
795
- console.warn(`[legend-list] ${text}`);
796
- }
797
- }
798
- function roundSize(size) {
799
- return Math.floor(size * 8) / 8;
800
- }
801
- function isNullOrUndefined(value) {
802
- return value === null || value === void 0;
803
- }
804
- function comparatorDefault(a, b) {
805
- return a - b;
806
- }
807
- function getPadding(s, type) {
808
- var _a, _b, _c;
809
- return (_c = (_b = (_a = s[`padding${type}`]) != null ? _a : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
810
- }
811
- function extractPadding(style, contentContainerStyle, type) {
812
- return getPadding(style, type) + getPadding(contentContainerStyle, type);
813
- }
814
-
815
328
  // src/state/ContextContainer.ts
816
329
  var ContextContainer = React3.createContext(null);
817
330
  function useViewability(callback, configId) {
@@ -908,57 +421,163 @@ function useListScrollSize() {
908
421
  const [scrollSize] = useArr$(["scrollSize"]);
909
422
  return scrollSize;
910
423
  }
911
- function useSyncLayout2() {
424
+ function useSyncLayout() {
912
425
  {
913
426
  const { triggerLayout: syncLayout } = React3.useContext(ContextContainer);
914
427
  return syncLayout;
915
428
  }
916
429
  }
917
430
 
918
- // src/components/Container.tsx
919
- var Container = typedMemo(function Container2({
920
- id,
921
- recycleItems,
922
- horizontal,
923
- getRenderedItem: getRenderedItem2,
924
- updateItemSize: updateItemSize2,
925
- ItemSeparatorComponent
926
- }) {
927
- const ctx = useStateContext();
928
- const { columnWrapperStyle } = ctx;
929
- const [column = 0, data, itemKey, numColumns, extraData, isSticky] = useArr$([
930
- `containerColumn${id}`,
931
- `containerItemData${id}`,
932
- `containerItemKey${id}`,
933
- "numColumns",
934
- "extraData",
935
- `containerSticky${id}`
936
- ]);
937
- const refLastSize = React3.useRef();
938
- const ref = React3.useRef(null);
939
- const [_, forceLayoutRender] = React3.useState(0);
940
- const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
941
- const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
942
- const style = React3.useMemo(() => {
943
- let paddingStyles;
944
- if (columnWrapperStyle) {
945
- const { columnGap, rowGap, gap } = columnWrapperStyle;
946
- if (horizontal) {
947
- const py = numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0;
948
- paddingStyles = {
949
- paddingBottom: py,
950
- paddingRight: columnGap || gap || void 0,
951
- paddingTop: py
952
- };
953
- } else {
954
- const px = numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0;
955
- paddingStyles = {
956
- paddingBottom: rowGap || gap || void 0,
957
- paddingLeft: px,
958
- paddingRight: px
959
- };
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
+ }
960
449
  }
961
- }
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
+
532
+ // src/components/Container.tsx
533
+ var Container = typedMemo(function Container2({
534
+ id,
535
+ recycleItems,
536
+ horizontal,
537
+ getRenderedItem: getRenderedItem2,
538
+ updateItemSize: updateItemSize2,
539
+ ItemSeparatorComponent
540
+ }) {
541
+ const ctx = useStateContext();
542
+ const { columnWrapperStyle, animatedScrollY } = ctx;
543
+ const [column = 0, data, itemKey, numColumns, extraData, isSticky, stickyOffset] = useArr$([
544
+ `containerColumn${id}`,
545
+ `containerItemData${id}`,
546
+ `containerItemKey${id}`,
547
+ "numColumns",
548
+ "extraData",
549
+ `containerSticky${id}`,
550
+ `containerStickyOffset${id}`
551
+ ]);
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);
562
+ const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
563
+ const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
564
+ const didLayoutRef = React3.useRef(false);
565
+ const style = React3.useMemo(() => {
566
+ let paddingStyles;
567
+ if (columnWrapperStyle) {
568
+ const { columnGap, rowGap, gap } = columnWrapperStyle;
569
+ if (horizontal) {
570
+ paddingStyles = {
571
+ paddingRight: columnGap || gap || void 0,
572
+ paddingVertical: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
573
+ };
574
+ } else {
575
+ paddingStyles = {
576
+ paddingBottom: rowGap || gap || void 0,
577
+ paddingHorizontal: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
578
+ };
579
+ }
580
+ }
962
581
  return horizontal ? {
963
582
  flexDirection: ItemSeparatorComponent ? "row" : void 0,
964
583
  height: otherAxisSize,
@@ -969,7 +588,7 @@ var Container = typedMemo(function Container2({
969
588
  } : {
970
589
  left: otherAxisPos,
971
590
  position: "absolute",
972
- right: numColumns > 1 ? void 0 : 0,
591
+ right: numColumns > 1 ? null : 0,
973
592
  top: 0,
974
593
  width: otherAxisSize,
975
594
  ...paddingStyles || {}
@@ -992,49 +611,64 @@ var Container = typedMemo(function Container2({
992
611
  value: data
993
612
  };
994
613
  }, [id, itemKey, index, data]);
995
- const onLayoutChange = (rectangle) => {
996
- if (!isNullOrUndefined(itemKey)) {
997
- let layout = rectangle;
998
- layout[horizontal ? "width" : "height"];
999
- const doUpdate = () => {
1000
- refLastSize.current = { height: layout.height, width: layout.width };
1001
- updateItemSize2(itemKey, layout);
1002
- };
1003
- {
1004
- doUpdate();
1005
- }
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;
1006
622
  }
1007
- };
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
+ );
1008
642
  const PositionComponent = isSticky ? PositionViewSticky : PositionView2;
1009
- return /* @__PURE__ */ React.createElement(ContextContainer.Provider, { value: contextValue }, /* @__PURE__ */ React.createElement(
643
+ return /* @__PURE__ */ React3__namespace.createElement(
1010
644
  PositionComponent,
1011
645
  {
646
+ animatedScrollY: isSticky ? animatedScrollY : void 0,
1012
647
  horizontal,
1013
648
  id,
1014
649
  index,
1015
650
  key: recycleItems ? void 0 : itemKey,
1016
- onLayoutChange,
651
+ onLayout,
1017
652
  refView: ref,
653
+ stickyOffset: isSticky ? stickyOffset : void 0,
1018
654
  style
1019
655
  },
1020
- renderedItem,
1021
- renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React.createElement(
1022
- Separator,
1023
- {
1024
- ItemSeparatorComponent,
1025
- itemKey,
1026
- leadingItem: renderedItemInfo.item
1027
- }
1028
- )
1029
- ));
656
+ /* @__PURE__ */ React3__namespace.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React3__namespace.createElement(Separator, { ItemSeparatorComponent, leadingItem: renderedItemInfo.item }))
657
+ );
1030
658
  });
1031
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
+
1032
666
  // src/utils/reordering.ts
1033
667
  var mapFn = (element) => {
1034
668
  const indexStr = element.getAttribute("index");
1035
669
  return [element, indexStr === null ? null : parseInt(indexStr)];
1036
670
  };
1037
- function sortDOMElementsPatience(container) {
671
+ function sortDOMElements(container) {
1038
672
  const elements = Array.from(container.children);
1039
673
  if (elements.length <= 1) return elements;
1040
674
  const items = elements.map(mapFn);
@@ -1125,7 +759,7 @@ function useDOMOrder(ref) {
1125
759
  debounceRef.current = setTimeout(() => {
1126
760
  const parent = ref.current;
1127
761
  if (parent) {
1128
- sortDOMElementsPatience(parent);
762
+ sortDOMElements(parent);
1129
763
  }
1130
764
  debounceRef.current = void 0;
1131
765
  }, 500);
@@ -1146,7 +780,7 @@ var ContainersInner = typedMemo(function ContainersInner2({ horizontal, numColum
1146
780
  const columnWrapperStyle = ctx.columnWrapperStyle;
1147
781
  const [totalSize, otherAxisSize] = useArr$(["totalSize", "otherAxisSize"]);
1148
782
  useDOMOrder(ref);
1149
- 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" };
1150
784
  if (columnWrapperStyle && numColumns > 1) {
1151
785
  const { columnGap, rowGap, gap } = columnWrapperStyle;
1152
786
  const gapX = columnGap || gap || 0;
@@ -1197,22 +831,38 @@ var Containers = typedMemo(function Containers2({
1197
831
  }
1198
832
  return /* @__PURE__ */ React3__namespace.createElement(ContainersInner, { horizontal, numColumns, waitForInitialLayout }, containers);
1199
833
  });
1200
- var DevNumbers = __DEV__ && React3__namespace.memo(function DevNumbers2() {
1201
- return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React3__namespace.createElement(
1202
- View,
1203
- {
1204
- key: index,
1205
- style: {
1206
- height: 100,
1207
- pointerEvents: "none",
1208
- position: "absolute",
1209
- top: index * 100,
1210
- width: "100%"
1211
- }
1212
- },
1213
- /* @__PURE__ */ React3__namespace.createElement(Text, { style: { color: "red" } }, index * 100)
1214
- ));
1215
- });
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
1216
866
  var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView2({
1217
867
  children,
1218
868
  style,
@@ -1226,7 +876,6 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
1226
876
  showsVerticalScrollIndicator = true,
1227
877
  refreshControl,
1228
878
  onLayout,
1229
- ScrollComponent,
1230
879
  ...props
1231
880
  }, ref) {
1232
881
  const scrollRef = React3.useRef(null);
@@ -1235,16 +884,15 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
1235
884
  React3.useImperativeHandle(ref, () => {
1236
885
  const api = {
1237
886
  getBoundingClientRect: () => {
1238
- var _a;
1239
- return (_a = scrollRef.current) == null ? void 0 : _a.getBoundingClientRect();
887
+ var _a3;
888
+ return (_a3 = scrollRef.current) == null ? void 0 : _a3.getBoundingClientRect();
1240
889
  },
1241
890
  getScrollableNode: () => scrollRef.current,
1242
891
  getScrollResponder: () => scrollRef.current,
1243
- scrollBy: (options) => {
892
+ scrollBy: (x, y) => {
1244
893
  const el = scrollRef.current;
1245
894
  if (!el) return;
1246
- const { x = 0, y = 0, animated = true } = options;
1247
- el.scrollBy({ behavior: animated ? "smooth" : "auto", left: x, top: y });
895
+ el.scrollBy(x, y);
1248
896
  },
1249
897
  scrollTo: (options) => {
1250
898
  const el = scrollRef.current;
@@ -1314,17 +962,21 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
1314
962
  React3.useLayoutEffect(() => {
1315
963
  const element = scrollRef.current;
1316
964
  if (!element) return;
1317
- element.addEventListener("scroll", handleScroll, { passive: true });
965
+ element.addEventListener("scroll", handleScroll);
1318
966
  return () => {
1319
967
  element.removeEventListener("scroll", handleScroll);
1320
968
  };
1321
969
  }, [handleScroll]);
1322
- React3.useLayoutEffect(() => {
1323
- if (contentOffset && scrollRef.current) {
1324
- scrollRef.current.scrollLeft = contentOffset.x || 0;
1325
- scrollRef.current.scrollTop = contentOffset.y || 0;
1326
- }
1327
- }, [contentOffset]);
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]);
1328
980
  React3.useLayoutEffect(() => {
1329
981
  if (!onLayout || !scrollRef.current) return;
1330
982
  const element = scrollRef.current;
@@ -1356,24 +1008,45 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
1356
1008
  // Ensure proper positioning context
1357
1009
  WebkitOverflowScrolling: "touch",
1358
1010
  // iOS momentum scrolling
1359
- ...style
1011
+ ...StyleSheet.flatten(style)
1360
1012
  };
1361
1013
  const contentStyle = {
1362
1014
  display: horizontal ? "flex" : "block",
1363
1015
  flexDirection: horizontal ? "row" : void 0,
1364
1016
  minHeight: horizontal ? void 0 : "100%",
1365
1017
  minWidth: horizontal ? "100%" : void 0,
1366
- ...contentContainerStyle
1018
+ ...StyleSheet.flatten(contentContainerStyle)
1367
1019
  };
1368
- return /* @__PURE__ */ React.createElement("div", { ref: scrollRef, style: scrollViewStyle, ...props }, refreshControl, /* @__PURE__ */ React.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));
1369
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
+ }
1370
1042
  function useValueListener$(key, callback) {
1371
1043
  const ctx = useStateContext();
1372
1044
  React3.useLayoutEffect(() => {
1373
- listen$(ctx, key, (value) => {
1045
+ const unsubscribe = listen$(ctx, key, (value) => {
1374
1046
  callback(value);
1375
1047
  });
1376
- }, []);
1048
+ return unsubscribe;
1049
+ }, [callback, ctx, key]);
1377
1050
  }
1378
1051
 
1379
1052
  // src/components/ScrollAdjust.tsx
@@ -1381,16 +1054,34 @@ function ScrollAdjust() {
1381
1054
  const ctx = useStateContext();
1382
1055
  const lastScrollOffsetRef = React3__namespace.useRef(0);
1383
1056
  const callback = React3__namespace.useCallback(() => {
1384
- var _a;
1057
+ var _a3;
1385
1058
  const scrollAdjust = peek$(ctx, "scrollAdjust");
1386
1059
  const scrollAdjustUserOffset = peek$(ctx, "scrollAdjustUserOffset");
1387
1060
  const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0);
1388
- const scrollView = (_a = ctx.internalState) == null ? void 0 : _a.refScroller.current;
1061
+ const scrollView = (_a3 = ctx.internalState) == null ? void 0 : _a3.refScroller.current;
1389
1062
  if (scrollView && scrollOffset !== lastScrollOffsetRef.current) {
1390
1063
  const scrollDelta = scrollOffset - lastScrollOffsetRef.current;
1391
1064
  if (scrollDelta !== 0) {
1392
- scrollView.scrollBy(0, scrollDelta);
1393
- 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
+ }
1394
1085
  }
1395
1086
  lastScrollOffsetRef.current = scrollOffset;
1396
1087
  }
@@ -1399,18 +1090,15 @@ function ScrollAdjust() {
1399
1090
  useValueListener$("scrollAdjustUserOffset", callback);
1400
1091
  return null;
1401
1092
  }
1402
-
1403
- // src/components/SnapWrapper.tsx
1404
1093
  function SnapWrapper({ ScrollComponent, ...props }) {
1405
1094
  const [snapToOffsets] = useArr$(["snapToOffsets"]);
1406
- return /* @__PURE__ */ React.createElement(ScrollComponent, { ...props, snapToOffsets });
1407
- }
1408
-
1409
- // src/hooks/useValue$.ts
1410
- function useValue$(key, params) {
1411
- const [value] = useArr$([key]);
1412
- return value;
1095
+ return /* @__PURE__ */ React3__namespace.createElement(ScrollComponent, { ...props, snapToOffsets });
1413
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
+ };
1414
1102
 
1415
1103
  // src/components/ListComponent.tsx
1416
1104
  var getComponent = (Component) => {
@@ -1422,26 +1110,6 @@ var getComponent = (Component) => {
1422
1110
  }
1423
1111
  return null;
1424
1112
  };
1425
- var Padding = () => {
1426
- const animPaddingTop = useValue$("alignItemsPaddingTop");
1427
- return /* @__PURE__ */ React3__namespace.createElement(AnimatedView, { style: { paddingTop: animPaddingTop } });
1428
- };
1429
- var PaddingDevMode = () => {
1430
- const animPaddingTop = useValue$("alignItemsPaddingTop");
1431
- return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement(AnimatedView, { style: { paddingTop: animPaddingTop } }), /* @__PURE__ */ React3__namespace.createElement(
1432
- AnimatedView,
1433
- {
1434
- style: {
1435
- backgroundColor: "green",
1436
- height: animPaddingTop,
1437
- left: 0,
1438
- position: "absolute",
1439
- right: 0,
1440
- top: 0
1441
- }
1442
- }
1443
- ));
1444
- };
1445
1113
  var ListComponent = typedMemo(function ListComponent2({
1446
1114
  canRender,
1447
1115
  style,
@@ -1467,11 +1135,10 @@ var ListComponent = typedMemo(function ListComponent2({
1467
1135
  scrollAdjustHandler,
1468
1136
  onLayoutHeader,
1469
1137
  snapToIndices,
1470
- stickyIndices,
1138
+ stickyHeaderIndices,
1471
1139
  ...rest
1472
1140
  }) {
1473
1141
  const ctx = useStateContext();
1474
- const refHeader = React3__namespace.useRef(null);
1475
1142
  const ScrollComponent = renderScrollComponent ? React3.useMemo(
1476
1143
  () => React3__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
1477
1144
  [renderScrollComponent]
@@ -1484,39 +1151,30 @@ var ListComponent = typedMemo(function ListComponent2({
1484
1151
  }
1485
1152
  }, [canRender]);
1486
1153
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
1487
- const contentContainerStyleWeb = React3.useMemo(() => {
1488
- const base = contentContainerStyle || void 0;
1489
- if (!horizontal) return base;
1490
- if (base && base.height === "100%") return base;
1491
- return { ...base || {}, height: "100%" };
1492
- }, [horizontal, (contentContainerStyle == null ? void 0 : contentContainerStyle.height) === "100%" ? 1 : 0]);
1493
1154
  return /* @__PURE__ */ React3__namespace.createElement(
1494
1155
  SnapOrScroll,
1495
1156
  {
1496
1157
  ...rest,
1497
- contentContainerStyle: contentContainerStyleWeb,
1158
+ contentContainerStyle: [
1159
+ contentContainerStyle,
1160
+ horizontal ? {
1161
+ height: "100%"
1162
+ } : {}
1163
+ ],
1498
1164
  contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
1499
1165
  horizontal,
1500
- maintainVisibleContentPosition: maintainVisibleContentPosition && !ListEmptyComponent ? { minIndexForVisible: 0 } : void 0,
1166
+ maintainVisibleContentPosition: maintainVisibleContentPosition ? { minIndexForVisible: 0 } : void 0,
1501
1167
  onLayout,
1502
1168
  onScroll: onScroll2,
1503
1169
  ref: refScrollView,
1504
1170
  ScrollComponent: snapToIndices ? ScrollComponent : void 0,
1505
1171
  style
1506
1172
  },
1507
- maintainVisibleContentPosition && /* @__PURE__ */ React3__namespace.createElement(ScrollAdjust, null),
1173
+ /* @__PURE__ */ React3__namespace.createElement(ScrollAdjust, null),
1508
1174
  ENABLE_DEVMODE ? /* @__PURE__ */ React3__namespace.createElement(PaddingDevMode, null) : /* @__PURE__ */ React3__namespace.createElement(Padding, null),
1509
- ListHeaderComponent && /* @__PURE__ */ React3__namespace.createElement(
1510
- LayoutView,
1511
- {
1512
- onLayoutChange: onLayoutHeader,
1513
- refView: refHeader,
1514
- style: ListHeaderComponentStyle
1515
- },
1516
- getComponent(ListHeaderComponent)
1517
- ),
1175
+ ListHeaderComponent && /* @__PURE__ */ React3__namespace.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
1518
1176
  ListEmptyComponent && getComponent(ListEmptyComponent),
1519
- canRender && /* @__PURE__ */ React3__namespace.createElement(
1177
+ canRender && !ListEmptyComponent && /* @__PURE__ */ React3__namespace.createElement(
1520
1178
  Containers,
1521
1179
  {
1522
1180
  getRenderedItem: getRenderedItem2,
@@ -1538,7 +1196,7 @@ var ListComponent = typedMemo(function ListComponent2({
1538
1196
  },
1539
1197
  getComponent(ListFooterComponent)
1540
1198
  ),
1541
- __DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React3__namespace.createElement(DevNumbers, null)
1199
+ IS_DEV && ENABLE_DEVMODE && /* @__PURE__ */ React3__namespace.createElement(DevNumbers, null)
1542
1200
  );
1543
1201
  });
1544
1202
 
@@ -1550,7 +1208,7 @@ function getId(state, index) {
1550
1208
  }
1551
1209
  const ret = index < data.length ? keyExtractor ? keyExtractor(data[index], index) : index : null;
1552
1210
  const id = ret;
1553
- state.idCache.set(index, id);
1211
+ state.idCache[index] = id;
1554
1212
  return id;
1555
1213
  }
1556
1214
 
@@ -1571,13 +1229,84 @@ function calculateOffsetForIndex(ctx, state, index) {
1571
1229
  return position;
1572
1230
  }
1573
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
+
1574
1304
  // src/utils/getItemSize.ts
1575
- function getItemSize(state, key, index, data, useAverageSize) {
1576
- var _a, _b;
1305
+ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedSize) {
1306
+ var _a3, _b;
1577
1307
  const {
1578
1308
  sizesKnown,
1579
1309
  sizes,
1580
- scrollingTo,
1581
1310
  averageSizes,
1582
1311
  props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
1583
1312
  } = state;
@@ -1586,7 +1315,14 @@ function getItemSize(state, key, index, data, useAverageSize) {
1586
1315
  return sizeKnown;
1587
1316
  }
1588
1317
  let size;
1589
- 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
+ }
1590
1326
  if (getFixedItemSize) {
1591
1327
  size = getFixedItemSize(index, data, itemType);
1592
1328
  if (size !== void 0) {
@@ -1608,53 +1344,234 @@ function getItemSize(state, key, index, data, useAverageSize) {
1608
1344
  if (size === void 0) {
1609
1345
  size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
1610
1346
  }
1611
- sizes.set(key, size);
1347
+ setSize(ctx, state, key, size);
1612
1348
  return size;
1613
1349
  }
1614
1350
 
1615
1351
  // src/core/calculateOffsetWithOffsetPosition.ts
1616
- function calculateOffsetWithOffsetPosition(state, offsetParam, params) {
1352
+ function calculateOffsetWithOffsetPosition(ctx, state, offsetParam, params) {
1617
1353
  const { index, viewOffset, viewPosition } = params;
1618
1354
  let offset = offsetParam;
1619
1355
  if (viewOffset) {
1620
1356
  offset -= viewOffset;
1621
1357
  }
1622
1358
  if (viewPosition !== void 0 && index !== void 0) {
1623
- 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]));
1624
1360
  }
1625
1361
  return offset;
1626
1362
  }
1627
1363
 
1628
1364
  // src/core/finishScrollTo.ts
1629
- var finishScrollTo = (state) => {
1365
+ function finishScrollTo(ctx, state) {
1366
+ var _a3, _b;
1630
1367
  if (state) {
1631
- state.scrollingTo = void 0;
1632
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
+ }
1633
1378
  }
1634
- };
1379
+ }
1635
1380
 
1636
1381
  // src/core/scrollTo.ts
1637
- function scrollTo(state, params = {}) {
1638
- var _a;
1639
- 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;
1640
1386
  const {
1641
1387
  refScroller,
1642
1388
  props: { horizontal }
1643
1389
  } = state;
1644
- 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
+ }
1645
1395
  state.scrollHistory.length = 0;
1646
1396
  if (!noScrollingTo) {
1647
- state.scrollingTo = params;
1397
+ set$(ctx, "scrollingTo", scrollTarget);
1648
1398
  }
1649
1399
  state.scrollPending = offset;
1650
- (_a = refScroller.current) == null ? void 0 : _a.scrollTo({
1651
- animated: !!animated,
1652
- x: horizontal ? offset : 0,
1653
- y: horizontal ? 0 : offset
1654
- });
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
+ }
1655
1407
  if (!animated) {
1656
1408
  state.scroll = offset;
1657
- 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;
1658
1575
  }
1659
1576
  }
1660
1577
 
@@ -1664,6 +1581,9 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1664
1581
  const doit = () => {
1665
1582
  {
1666
1583
  state.scrollAdjustHandler.requestAdjust(positionDiff);
1584
+ if (state.adjustingFromInitialMount) {
1585
+ state.adjustingFromInitialMount--;
1586
+ }
1667
1587
  }
1668
1588
  };
1669
1589
  state.scroll += positionDiff;
@@ -1671,44 +1591,77 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1671
1591
  const didLayout = peek$(ctx, "containersDidLayout");
1672
1592
  if (didLayout) {
1673
1593
  doit();
1674
- const threshold = state.scroll - positionDiff / 2;
1675
- if (!state.ignoreScrollFromMVCP) {
1676
- state.ignoreScrollFromMVCP = {};
1677
- }
1678
- if (positionDiff > 0) {
1679
- state.ignoreScrollFromMVCP.lt = threshold;
1680
- } else {
1681
- state.ignoreScrollFromMVCP.gt = threshold;
1682
- }
1683
- if (state.ignoreScrollFromMVCPTimeout) {
1684
- clearTimeout(state.ignoreScrollFromMVCPTimeout);
1685
- }
1686
- state.ignoreScrollFromMVCPTimeout = setTimeout(
1687
- () => {
1688
- state.ignoreScrollFromMVCP = void 0;
1689
- },
1690
- 100
1691
- );
1692
1594
  } else {
1595
+ state.adjustingFromInitialMount = (state.adjustingFromInitialMount || 0) + 1;
1693
1596
  requestAnimationFrame(doit);
1694
1597
  }
1695
1598
  }
1696
1599
  }
1697
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
+
1698
1653
  // src/core/mvcp.ts
1699
1654
  function prepareMVCP(ctx, state, dataChanged) {
1700
- const {
1701
- idsInView,
1702
- positions,
1703
- scrollingTo,
1704
- props: { maintainVisibleContentPosition }
1705
- } = state;
1655
+ const { idsInView, positions, props } = state;
1656
+ const { maintainVisibleContentPosition } = props;
1657
+ const scrollingTo = peek$(ctx, "scrollingTo");
1706
1658
  let prevPosition;
1707
1659
  let targetId;
1708
1660
  const idsInViewWithPositions = [];
1709
1661
  const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
1710
- if (maintainVisibleContentPosition) {
1711
- const indexByKey = state.indexByKey;
1662
+ const shouldMVCP = !dataChanged || maintainVisibleContentPosition;
1663
+ const indexByKey = state.indexByKey;
1664
+ if (shouldMVCP) {
1712
1665
  if (scrollTarget !== void 0) {
1713
1666
  targetId = getId(state, scrollTarget);
1714
1667
  } else if (idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
@@ -1721,70 +1674,106 @@ function prepareMVCP(ctx, state, dataChanged) {
1721
1674
  }
1722
1675
  }
1723
1676
  } else {
1724
- targetId = state.idsInView.find((id) => indexByKey.get(id) !== void 0);
1677
+ targetId = idsInView.find((id) => indexByKey.get(id) !== void 0);
1725
1678
  }
1726
1679
  }
1727
1680
  if (targetId !== void 0) {
1728
1681
  prevPosition = positions.get(targetId);
1729
1682
  }
1730
- }
1731
- return () => {
1732
- let positionDiff;
1733
- if (dataChanged && targetId === void 0) {
1734
- for (let i = 0; i < idsInViewWithPositions.length; i++) {
1735
- const { id, position } = idsInViewWithPositions[i];
1736
- 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);
1737
1697
  if (newPosition !== void 0) {
1738
- positionDiff = newPosition - position;
1739
- 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;
1740
1708
  }
1741
1709
  }
1742
- }
1743
- if (targetId !== void 0 && prevPosition !== void 0) {
1744
- const newPosition = positions.get(targetId);
1745
- if (newPosition !== void 0) {
1746
- positionDiff = newPosition - prevPosition;
1710
+ if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
1711
+ requestAdjust(ctx, state, positionDiff);
1747
1712
  }
1748
- }
1749
- if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
1750
- requestAdjust(ctx, state, positionDiff);
1751
- }
1752
- };
1713
+ };
1714
+ }
1753
1715
  }
1754
1716
 
1755
- // src/utils/setPaddingTop.ts
1756
- function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
1757
- if (stylePaddingTop !== void 0) {
1758
- const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
1759
- if (stylePaddingTop < prevStylePaddingTop) {
1760
- let prevTotalSize = peek$(ctx, "totalSize") || 0;
1761
- set$(ctx, "totalSize", prevTotalSize + prevStylePaddingTop);
1762
- state.timeoutSetPaddingTop = setTimeout(() => {
1763
- prevTotalSize = peek$(ctx, "totalSize") || 0;
1764
- set$(ctx, "totalSize", prevTotalSize - prevStylePaddingTop);
1765
- }, 16);
1766
- }
1767
- 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);
1768
1725
  }
1769
- if (alignItemsPaddingTop !== void 0) {
1770
- 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;
1771
1736
  }
1737
+ return {
1738
+ column,
1739
+ currentRowTop,
1740
+ startIndex: rowStartIndex
1741
+ };
1772
1742
  }
1773
-
1774
- // src/utils/updateAlignItemsPaddingTop.ts
1775
- function updateAlignItemsPaddingTop(ctx, state) {
1776
- const {
1777
- scrollLength,
1778
- props: { alignItemsAtEnd, data }
1779
- } = state;
1780
- if (alignItemsAtEnd) {
1781
- let alignItemsPaddingTop = 0;
1782
- if ((data == null ? void 0 : data.length) > 0) {
1783
- const contentSize = getContentSize(ctx);
1784
- 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;
1785
1774
  }
1786
- setPaddingTop(ctx, state, { alignItemsPaddingTop });
1787
1775
  }
1776
+ return maxSize;
1788
1777
  }
1789
1778
 
1790
1779
  // src/core/updateTotalSize.ts
@@ -1800,29 +1789,53 @@ function updateTotalSize(ctx, state) {
1800
1789
  if (lastId !== void 0) {
1801
1790
  const lastPosition = positions.get(lastId);
1802
1791
  if (lastPosition !== void 0) {
1803
- 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]);
1804
1793
  if (lastSize !== void 0) {
1805
1794
  const totalSize = lastPosition + lastSize;
1806
1795
  addTotalSize(ctx, state, null, totalSize);
1807
1796
  }
1808
1797
  }
1809
1798
  }
1810
- }
1811
- }
1812
- function addTotalSize(ctx, state, key, add) {
1813
- const { alignItemsAtEnd } = state.props;
1814
- {
1815
- state.totalSize = add;
1816
- if (state.timeoutSetPaddingTop) {
1817
- clearTimeout(state.timeoutSetPaddingTop);
1818
- state.timeoutSetPaddingTop = void 0;
1799
+ }
1800
+ }
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;
1819
1835
  }
1820
1836
  }
1821
- set$(ctx, "totalSize", state.totalSize);
1822
- if (alignItemsAtEnd) {
1823
- updateAlignItemsPaddingTop(ctx, state);
1824
- }
1825
- }
1837
+ return velocity;
1838
+ };
1826
1839
 
1827
1840
  // src/utils/updateSnapToOffsets.ts
1828
1841
  function updateSnapToOffsets(ctx, state) {
@@ -1839,9 +1852,14 @@ function updateSnapToOffsets(ctx, state) {
1839
1852
  set$(ctx, "snapToOffsets", snapToOffsets);
1840
1853
  }
1841
1854
 
1842
- // src/core/updateAllPositions.ts
1843
- function updateAllPositions(ctx, state, dataChanged, startIndex = 0) {
1844
- 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;
1845
1863
  const {
1846
1864
  columns,
1847
1865
  indexByKey,
@@ -1851,32 +1869,51 @@ function updateAllPositions(ctx, state, dataChanged, startIndex = 0) {
1851
1869
  props: { getEstimatedItemSize, snapToIndices, enableAverages }
1852
1870
  } = state;
1853
1871
  const data = state.props.data;
1872
+ const dataLength = data.length;
1854
1873
  const numColumns = peek$(ctx, "numColumns");
1855
- 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;
1856
1879
  const useAverageSize = enableAverages && !getEstimatedItemSize;
1880
+ const preferCachedSize = !doMVCP || dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0) !== 0;
1857
1881
  let currentRowTop = 0;
1858
1882
  let column = 1;
1859
1883
  let maxSizeInRow = 0;
1860
- const hasColumns = numColumns > 1;
1861
1884
  if (startIndex > 0) {
1862
- const prevIndex = startIndex - 1;
1863
- const prevId = (_a = idCache.get(prevIndex)) != null ? _a : getId(state, prevIndex);
1864
- const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
1865
1885
  if (hasColumns) {
1866
- const prevColumn = (_c = columns.get(prevId)) != null ? _c : 1;
1867
- currentRowTop = prevPosition;
1868
- column = prevColumn % numColumns + 1;
1869
- } else {
1870
- 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);
1871
1899
  currentRowTop = prevPosition + prevSize;
1872
1900
  }
1873
1901
  }
1874
1902
  const needsIndexByKey = dataChanged || indexByKey.size === 0;
1875
- const dataLength = data.length;
1903
+ let didBreakEarly = false;
1904
+ let breakAt;
1876
1905
  for (let i = startIndex; i < dataLength; i++) {
1877
- const id = (_e = idCache.get(i)) != null ? _e : getId(state, i);
1878
- const size = (_f = sizesKnown.get(id)) != null ? _f : getItemSize(state, id, i, data[i], useAverageSize);
1879
- 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) {
1880
1917
  if (indexByKeyForChecking.has(id)) {
1881
1918
  console.error(
1882
1919
  `[legend-list] Error: Detected overlapping key (${id}) which causes missing items and gaps and other terrrible things. Check that keyExtractor returns unique values.`
@@ -1903,7 +1940,9 @@ function updateAllPositions(ctx, state, dataChanged, startIndex = 0) {
1903
1940
  currentRowTop += size;
1904
1941
  }
1905
1942
  }
1906
- updateTotalSize(ctx, state);
1943
+ if (!didBreakEarly) {
1944
+ updateTotalSize(ctx, state);
1945
+ }
1907
1946
  if (snapToIndices) {
1908
1947
  updateSnapToOffsets(ctx, state);
1909
1948
  }
@@ -1923,6 +1962,21 @@ function ensureViewabilityState(ctx, configId) {
1923
1962
  }
1924
1963
  return state;
1925
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
+ }
1926
1980
  function updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollSize, start, end) {
1927
1981
  const {
1928
1982
  timeouts,
@@ -2076,16 +2130,6 @@ function isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize,
2076
2130
  const value = ctx.mapViewabilityAmountValues.get(containerId) || computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
2077
2131
  return value.isViewable;
2078
2132
  }
2079
- function findContainerId(ctx, key) {
2080
- const numContainers = peek$(ctx, "numContainers");
2081
- for (let i = 0; i < numContainers; i++) {
2082
- const itemKey = peek$(ctx, `containerItemKey${i}`);
2083
- if (itemKey === key) {
2084
- return i;
2085
- }
2086
- }
2087
- return -1;
2088
- }
2089
2133
  function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
2090
2134
  const key = containerId + configId;
2091
2135
  ctx.mapViewabilityValues.set(key, viewToken);
@@ -2093,13 +2137,13 @@ function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
2093
2137
  cb == null ? void 0 : cb(viewToken);
2094
2138
  }
2095
2139
 
2096
- // src/platform/batchedUpdates.ts
2097
- var import_react_dom = __toESM(require_react_dom());
2098
-
2099
2140
  // src/utils/checkAllSizesKnown.ts
2141
+ function isNullOrUndefined2(value) {
2142
+ return value === null || value === void 0;
2143
+ }
2100
2144
  function checkAllSizesKnown(state) {
2101
2145
  const { startBuffered, endBuffered, sizesKnown } = state;
2102
- if (endBuffered !== null && startBuffered >= 0 && endBuffered >= 0) {
2146
+ if (!isNullOrUndefined2(endBuffered) && !isNullOrUndefined2(startBuffered) && startBuffered >= 0 && endBuffered >= 0) {
2103
2147
  let areAllKnown = true;
2104
2148
  for (let i = startBuffered; areAllKnown && i <= endBuffered; i++) {
2105
2149
  const key = getId(state, i);
@@ -2116,6 +2160,8 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
2116
2160
  const { stickyContainerPool, containerItemTypes } = state;
2117
2161
  const result = [];
2118
2162
  const availableContainers = [];
2163
+ const pendingRemovalSet = new Set(pendingRemoval);
2164
+ let pendingRemovalChanged = false;
2119
2165
  const stickyIndicesSet = state.props.stickyIndicesSet;
2120
2166
  const stickyItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => stickyIndicesSet.has(index))) || [];
2121
2167
  const canReuseContainer = (containerIndex, requiredType) => {
@@ -2131,12 +2177,11 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
2131
2177
  let foundContainer = false;
2132
2178
  for (const containerIndex of stickyContainerPool) {
2133
2179
  const key = peek$(ctx, `containerItemKey${containerIndex}`);
2134
- const isPendingRemoval = pendingRemoval.includes(containerIndex);
2135
- 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)) {
2136
2182
  result.push(containerIndex);
2137
- if (isPendingRemoval) {
2138
- const index = pendingRemoval.indexOf(containerIndex);
2139
- pendingRemoval.splice(index, 1);
2183
+ if (isPendingRemoval && pendingRemovalSet.delete(containerIndex)) {
2184
+ pendingRemovalChanged = true;
2140
2185
  }
2141
2186
  foundContainer = true;
2142
2187
  if (requiredItemTypes) typeIndex++;
@@ -2156,13 +2201,11 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
2156
2201
  }
2157
2202
  const key = peek$(ctx, `containerItemKey${u}`);
2158
2203
  let isOk = key === void 0;
2159
- if (!isOk) {
2160
- const index = pendingRemoval.indexOf(u);
2161
- if (index !== -1) {
2162
- pendingRemoval.splice(index, 1);
2163
- const requiredType = neededTypes[typeIndex];
2164
- isOk = canReuseContainer(u, requiredType);
2165
- }
2204
+ if (!isOk && pendingRemovalSet.has(u)) {
2205
+ pendingRemovalSet.delete(u);
2206
+ pendingRemovalChanged = true;
2207
+ const requiredType = neededTypes[typeIndex];
2208
+ isOk = canReuseContainer(u, requiredType);
2166
2209
  }
2167
2210
  if (isOk) {
2168
2211
  result.push(u);
@@ -2205,7 +2248,7 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
2205
2248
  for (let i = 0; i < stillNeeded; i++) {
2206
2249
  result.push(numContainers + i);
2207
2250
  }
2208
- if (__DEV__ && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
2251
+ if (IS_DEV && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
2209
2252
  console.warn(
2210
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.",
2211
2254
  {
@@ -2220,50 +2263,18 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
2220
2263
  }
2221
2264
  }
2222
2265
  }
2266
+ if (pendingRemovalChanged) {
2267
+ pendingRemoval.length = 0;
2268
+ for (const value of pendingRemovalSet) {
2269
+ pendingRemoval.push(value);
2270
+ }
2271
+ }
2223
2272
  return result.sort(comparatorDefault);
2224
2273
  }
2225
2274
  function comparatorByDistance(a, b) {
2226
2275
  return b.distance - a.distance;
2227
2276
  }
2228
2277
 
2229
- // src/utils/getScrollVelocity.ts
2230
- var getScrollVelocity = (state) => {
2231
- const { scrollHistory } = state;
2232
- let velocity = 0;
2233
- if (scrollHistory.length >= 1) {
2234
- const newest = scrollHistory[scrollHistory.length - 1];
2235
- let oldest;
2236
- let start = 0;
2237
- const now = Date.now();
2238
- for (let i = 0; i < scrollHistory.length - 1; i++) {
2239
- const entry = scrollHistory[i];
2240
- const nextEntry = scrollHistory[i + 1];
2241
- if (i > 0) {
2242
- const prevEntry = scrollHistory[i - 1];
2243
- const prevDirection = entry.scroll - prevEntry.scroll;
2244
- const currentDirection = nextEntry.scroll - entry.scroll;
2245
- if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
2246
- start = i;
2247
- break;
2248
- }
2249
- }
2250
- }
2251
- for (let i = start; i < scrollHistory.length - 1; i++) {
2252
- const entry = scrollHistory[i];
2253
- if (now - entry.time <= 1e3) {
2254
- oldest = entry;
2255
- break;
2256
- }
2257
- }
2258
- if (oldest && oldest !== newest) {
2259
- const scrollDiff = newest.scroll - oldest.scroll;
2260
- const timeDiff = newest.time - oldest.time;
2261
- velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
2262
- }
2263
- }
2264
- return velocity;
2265
- };
2266
-
2267
2278
  // src/core/scrollToIndex.ts
2268
2279
  function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
2269
2280
  if (index >= state.props.data.length) {
@@ -2276,72 +2287,16 @@ function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, vie
2276
2287
  if (isLast && viewPosition === void 0) {
2277
2288
  viewPosition = 1;
2278
2289
  }
2279
- const firstIndexScrollPostion = firstIndexOffset - viewOffset;
2280
2290
  state.scrollForNextCalculateItemsInView = void 0;
2281
- scrollTo(state, {
2291
+ scrollTo(ctx, state, {
2282
2292
  animated,
2283
2293
  index,
2284
- offset: firstIndexScrollPostion,
2294
+ offset: firstIndexOffset,
2285
2295
  viewOffset,
2286
2296
  viewPosition: viewPosition != null ? viewPosition : 0
2287
2297
  });
2288
2298
  }
2289
2299
 
2290
- // src/utils/checkThreshold.ts
2291
- var checkThreshold = (distance, atThreshold, threshold, isReached, isBlockedByTimer, onReached, blockTimer) => {
2292
- const distanceAbs = Math.abs(distance);
2293
- const isAtThreshold = atThreshold || distanceAbs < threshold;
2294
- if (!isReached && !isBlockedByTimer) {
2295
- if (isAtThreshold) {
2296
- onReached == null ? void 0 : onReached(distance);
2297
- blockTimer == null ? void 0 : blockTimer(true);
2298
- setTimeout(() => {
2299
- blockTimer == null ? void 0 : blockTimer(false);
2300
- }, 700);
2301
- return true;
2302
- }
2303
- } else {
2304
- if (distance >= 1.3 * threshold) {
2305
- return false;
2306
- }
2307
- }
2308
- return isReached;
2309
- };
2310
-
2311
- // src/utils/checkAtBottom.ts
2312
- function checkAtBottom(ctx, state) {
2313
- if (!state) {
2314
- return;
2315
- }
2316
- const {
2317
- queuedInitialLayout,
2318
- scrollLength,
2319
- scroll,
2320
- maintainingScrollAtEnd,
2321
- props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
2322
- } = state;
2323
- const contentSize = getContentSize(ctx);
2324
- if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
2325
- const distanceFromEnd = contentSize - scroll - scrollLength;
2326
- const isContentLess = contentSize < scrollLength;
2327
- state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
2328
- state.isEndReached = checkThreshold(
2329
- distanceFromEnd,
2330
- isContentLess,
2331
- onEndReachedThreshold * scrollLength,
2332
- state.isEndReached,
2333
- state.endReachedBlockedByTimer,
2334
- (distance) => {
2335
- var _a, _b;
2336
- return (_b = (_a = state.props).onEndReached) == null ? void 0 : _b.call(_a, { distanceFromEnd: distance });
2337
- },
2338
- (block) => {
2339
- state.endReachedBlockedByTimer = block;
2340
- }
2341
- );
2342
- }
2343
- }
2344
-
2345
2300
  // src/utils/setDidLayout.ts
2346
2301
  function setDidLayout(ctx, state) {
2347
2302
  const {
@@ -2364,11 +2319,12 @@ function setDidLayout(ctx, state) {
2364
2319
 
2365
2320
  // src/core/calculateItemsInView.ts
2366
2321
  function findCurrentStickyIndex(stickyArray, scroll, state) {
2367
- var _a;
2322
+ var _a3;
2368
2323
  const idCache = state.idCache;
2369
2324
  const positions = state.positions;
2370
2325
  for (let i = stickyArray.length - 1; i >= 0; i--) {
2371
- 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);
2372
2328
  const stickyPos = stickyId ? positions.get(stickyId) : void 0;
2373
2329
  if (stickyPos !== void 0 && scroll >= stickyPos) {
2374
2330
  return i;
@@ -2376,47 +2332,51 @@ function findCurrentStickyIndex(stickyArray, scroll, state) {
2376
2332
  }
2377
2333
  return -1;
2378
2334
  }
2379
- function getActiveStickyIndices(ctx, state, stickyIndices) {
2335
+ function getActiveStickyIndices(ctx, state, stickyHeaderIndices) {
2380
2336
  return new Set(
2381
- 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))
2382
2338
  );
2383
2339
  }
2384
- function handleStickyActivation(ctx, state, stickyIndices, stickyArray, scroll, needNewContainers, startBuffered, endBuffered) {
2385
- var _a;
2386
- const activeIndices = getActiveStickyIndices(ctx, state, stickyIndices);
2387
- 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;
2388
2344
  for (let offset = 0; offset <= 1; offset++) {
2389
2345
  const idx = currentStickyIdx - offset;
2390
2346
  if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
2391
2347
  const stickyIndex = stickyArray[idx];
2392
- const stickyId = (_a = state.idCache.get(stickyIndex)) != null ? _a : getId(state, stickyIndex);
2348
+ const stickyId = (_a3 = state.idCache[stickyIndex]) != null ? _a3 : getId(state, stickyIndex);
2393
2349
  if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered)) {
2394
2350
  needNewContainers.push(stickyIndex);
2395
2351
  }
2396
2352
  }
2397
2353
  }
2398
- function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, pendingRemoval) {
2399
- var _a, _b, _c;
2400
- const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
2354
+ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
2355
+ var _a3, _b, _c;
2401
2356
  for (const containerIndex of state.stickyContainerPool) {
2402
2357
  const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
2403
2358
  const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
2404
2359
  if (itemIndex === void 0) continue;
2405
2360
  const arrayIdx = stickyArray.indexOf(itemIndex);
2406
- 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
+ }
2407
2367
  const isRecentSticky = arrayIdx >= currentStickyIdx - 1 && arrayIdx <= currentStickyIdx + 1;
2408
2368
  if (isRecentSticky) continue;
2409
2369
  const nextIndex = stickyArray[arrayIdx + 1];
2410
2370
  let shouldRecycle = false;
2411
2371
  if (nextIndex) {
2412
- const nextId = (_a = state.idCache.get(nextIndex)) != null ? _a : getId(state, nextIndex);
2372
+ const nextId = (_a3 = state.idCache[nextIndex]) != null ? _a3 : getId(state, nextIndex);
2413
2373
  const nextPos = nextId ? state.positions.get(nextId) : void 0;
2414
2374
  shouldRecycle = nextPos !== void 0 && scroll > nextPos + scrollBuffer * 2;
2415
2375
  } else {
2416
- const currentId = (_b = state.idCache.get(itemIndex)) != null ? _b : getId(state, itemIndex);
2376
+ const currentId = (_b = state.idCache[itemIndex]) != null ? _b : getId(state, itemIndex);
2417
2377
  if (currentId) {
2418
2378
  const currentPos = state.positions.get(currentId);
2419
- 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]);
2420
2380
  shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
2421
2381
  }
2422
2382
  }
@@ -2426,62 +2386,53 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, pe
2426
2386
  }
2427
2387
  }
2428
2388
  function calculateItemsInView(ctx, state, params = {}) {
2429
- (0, import_react_dom.unstable_batchedUpdates)(() => {
2430
- var _a, _b, _c, _d, _e, _f, _g, _h;
2389
+ reactDom.unstable_batchedUpdates(() => {
2390
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2431
2391
  const {
2432
2392
  columns,
2433
2393
  containerItemKeys,
2434
2394
  enableScrollForNextCalculateItemsInView,
2435
2395
  idCache,
2436
2396
  indexByKey,
2397
+ initialScroll,
2437
2398
  minIndexSizeChanged,
2438
2399
  positions,
2400
+ props: { getItemType, itemsAreEqual, keyExtractor, onStickyHeaderChange, scrollBuffer },
2439
2401
  scrollForNextCalculateItemsInView,
2440
2402
  scrollLength,
2441
2403
  sizes,
2442
2404
  startBufferedId: startBufferedIdOrig,
2443
- viewabilityConfigCallbackPairs,
2444
- props: { getItemType, initialScroll, itemsAreEqual, keyExtractor, scrollBuffer }
2405
+ viewabilityConfigCallbackPairs
2445
2406
  } = state;
2446
2407
  const { data } = state.props;
2447
2408
  const stickyIndicesArr = state.props.stickyIndicesArr || [];
2448
2409
  const stickyIndicesSet = state.props.stickyIndicesSet || /* @__PURE__ */ new Set();
2449
2410
  const prevNumContainers = peek$(ctx, "numContainers");
2450
2411
  if (!data || scrollLength === 0 || !prevNumContainers) {
2412
+ if (state.initialAnchor) {
2413
+ ensureInitialAnchor(ctx, state);
2414
+ }
2451
2415
  return;
2452
2416
  }
2453
- const totalSize = peek$(ctx, "totalSize");
2417
+ const totalSize = getContentSize(ctx);
2454
2418
  const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
2455
2419
  const numColumns = peek$(ctx, "numColumns");
2456
- const previousScrollAdjust = 0;
2457
- const { dataChanged, doMVCP } = params;
2420
+ const { dataChanged, doMVCP, forceFullItemPositions } = params;
2458
2421
  const speed = getScrollVelocity(state);
2459
- if (doMVCP || dataChanged) {
2460
- const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
2461
- if (dataChanged) {
2462
- indexByKey.clear();
2463
- idCache.clear();
2464
- positions.clear();
2465
- }
2466
- const startIndex = dataChanged ? 0 : minIndexSizeChanged != null ? minIndexSizeChanged : 0;
2467
- updateAllPositions(ctx, state, dataChanged, startIndex);
2468
- if (minIndexSizeChanged !== void 0) {
2469
- state.minIndexSizeChanged = void 0;
2470
- }
2471
- checkMVCP == null ? void 0 : checkMVCP();
2472
- }
2473
2422
  const scrollExtra = 0;
2474
2423
  const { queuedInitialLayout } = state;
2475
2424
  let { scroll: scrollState } = state;
2476
2425
  if (!queuedInitialLayout && initialScroll) {
2477
2426
  const updatedOffset = calculateOffsetWithOffsetPosition(
2427
+ ctx,
2478
2428
  state,
2479
2429
  calculateOffsetForIndex(ctx, state, initialScroll.index),
2480
2430
  initialScroll
2481
2431
  );
2482
2432
  scrollState = updatedOffset;
2483
2433
  }
2484
- const scrollAdjustPad = -previousScrollAdjust - topPad;
2434
+ const scrollAdjustPending = (_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0;
2435
+ const scrollAdjustPad = scrollAdjustPending - topPad;
2485
2436
  let scroll = scrollState + scrollExtra + scrollAdjustPad;
2486
2437
  if (scroll + scrollLength > totalSize) {
2487
2438
  scroll = Math.max(0, totalSize - scrollLength);
@@ -2490,6 +2441,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2490
2441
  set$(ctx, "debugRawScroll", scrollState);
2491
2442
  set$(ctx, "debugComputedScroll", scroll);
2492
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);
2493
2449
  let scrollBufferTop = scrollBuffer;
2494
2450
  let scrollBufferBottom = scrollBuffer;
2495
2451
  if (speed > 0 || speed === 0 && scroll < Math.max(50, scrollBuffer)) {
@@ -2502,22 +2458,42 @@ function calculateItemsInView(ctx, state, params = {}) {
2502
2458
  const scrollTopBuffered = scroll - scrollBufferTop;
2503
2459
  const scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
2504
2460
  const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
2505
- if (scrollForNextCalculateItemsInView) {
2461
+ if (!dataChanged && scrollForNextCalculateItemsInView) {
2506
2462
  const { top, bottom } = scrollForNextCalculateItemsInView;
2507
2463
  if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
2464
+ if (state.initialAnchor) {
2465
+ ensureInitialAnchor(ctx, state);
2466
+ }
2508
2467
  return;
2509
2468
  }
2510
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();
2511
2487
  let startNoBuffer = null;
2512
2488
  let startBuffered = null;
2513
2489
  let startBufferedId = null;
2514
2490
  let endNoBuffer = null;
2515
2491
  let endBuffered = null;
2516
- let loopStart = startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
2492
+ let loopStart = !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
2517
2493
  for (let i = loopStart; i >= 0; i--) {
2518
- const id = (_a = idCache.get(i)) != null ? _a : getId(state, i);
2494
+ const id = (_c = idCache[i]) != null ? _c : getId(state, i);
2519
2495
  const top = positions.get(id);
2520
- 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]);
2521
2497
  const bottom = top + size;
2522
2498
  if (bottom > scroll - scrollBuffer) {
2523
2499
  loopStart = i;
@@ -2543,8 +2519,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2543
2519
  let firstFullyOnScreenIndex;
2544
2520
  const dataLength = data.length;
2545
2521
  for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
2546
- const id = (_c = idCache.get(i)) != null ? _c : getId(state, i);
2547
- 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]);
2548
2524
  const top = positions.get(id);
2549
2525
  if (!foundEnd) {
2550
2526
  if (startNoBuffer === null && top + size > scroll) {
@@ -2573,7 +2549,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2573
2549
  }
2574
2550
  const idsInView = [];
2575
2551
  for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
2576
- const id = (_e = idCache.get(i)) != null ? _e : getId(state, i);
2552
+ const id = (_g = idCache[i]) != null ? _g : getId(state, i);
2577
2553
  idsInView.push(id);
2578
2554
  }
2579
2555
  Object.assign(state, {
@@ -2605,7 +2581,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2605
2581
  let numContainers2 = prevNumContainers;
2606
2582
  const needNewContainers = [];
2607
2583
  for (let i = startBuffered; i <= endBuffered; i++) {
2608
- const id = (_f = idCache.get(i)) != null ? _f : getId(state, i);
2584
+ const id = (_h = idCache[i]) != null ? _h : getId(state, i);
2609
2585
  if (!containerItemKeys.has(id)) {
2610
2586
  needNewContainers.push(i);
2611
2587
  }
@@ -2616,11 +2592,14 @@ function calculateItemsInView(ctx, state, params = {}) {
2616
2592
  state,
2617
2593
  stickyIndicesSet,
2618
2594
  stickyIndicesArr,
2619
- scroll,
2595
+ currentStickyIdx,
2620
2596
  needNewContainers,
2621
2597
  startBuffered,
2622
2598
  endBuffered
2623
2599
  );
2600
+ } else {
2601
+ state.activeStickyIndex = void 0;
2602
+ set$(ctx, "activeStickyIndex", void 0);
2624
2603
  }
2625
2604
  if (needNewContainers.length > 0) {
2626
2605
  const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
@@ -2640,7 +2619,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2640
2619
  for (let idx = 0; idx < needNewContainers.length; idx++) {
2641
2620
  const i = needNewContainers[idx];
2642
2621
  const containerIndex = availableContainers[idx];
2643
- const id = (_g = idCache.get(i)) != null ? _g : getId(state, i);
2622
+ const id = (_i = idCache[i]) != null ? _i : getId(state, i);
2644
2623
  const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
2645
2624
  if (oldKey && oldKey !== id) {
2646
2625
  containerItemKeys.delete(oldKey);
@@ -2654,9 +2633,10 @@ function calculateItemsInView(ctx, state, params = {}) {
2654
2633
  if (stickyIndicesSet.has(i)) {
2655
2634
  set$(ctx, `containerSticky${containerIndex}`, true);
2656
2635
  const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
2657
- set$(ctx, `containerStickyOffset${containerIndex}`, createAnimatedValue(topPadding));
2636
+ set$(ctx, `containerStickyOffset${containerIndex}`, topPadding);
2658
2637
  state.stickyContainerPool.add(containerIndex);
2659
2638
  } else {
2639
+ set$(ctx, `containerSticky${containerIndex}`, false);
2660
2640
  state.stickyContainerPool.delete(containerIndex);
2661
2641
  }
2662
2642
  if (containerIndex >= numContainers2) {
@@ -2672,13 +2652,13 @@ function calculateItemsInView(ctx, state, params = {}) {
2672
2652
  }
2673
2653
  }
2674
2654
  if (stickyIndicesArr.length > 0) {
2675
- handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, pendingRemoval);
2655
+ handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2676
2656
  }
2677
2657
  let didChangePositions = false;
2678
2658
  for (let i = 0; i < numContainers; i++) {
2679
2659
  const itemKey = peek$(ctx, `containerItemKey${i}`);
2680
2660
  if (pendingRemoval.includes(i)) {
2681
- if (itemKey) {
2661
+ if (itemKey !== void 0) {
2682
2662
  containerItemKeys.delete(itemKey);
2683
2663
  }
2684
2664
  state.containerItemTypes.delete(i);
@@ -2695,11 +2675,12 @@ function calculateItemsInView(ctx, state, params = {}) {
2695
2675
  const itemIndex = indexByKey.get(itemKey);
2696
2676
  const item = data[itemIndex];
2697
2677
  if (item !== void 0) {
2698
- const id = (_h = idCache.get(itemIndex)) != null ? _h : getId(state, itemIndex);
2699
- const position = positions.get(id);
2700
- 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) {
2701
2681
  set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
2702
2682
  } else {
2683
+ const position = (positionValue || 0) - scrollAdjustPending;
2703
2684
  const column = columns.get(id) || 1;
2704
2685
  const prevPos = peek$(ctx, `containerPosition${i}`);
2705
2686
  const prevColumn = peek$(ctx, `containerColumn${i}`);
@@ -2712,29 +2693,161 @@ function calculateItemsInView(ctx, state, params = {}) {
2712
2693
  set$(ctx, `containerColumn${i}`, column);
2713
2694
  }
2714
2695
  if (prevData !== item && (itemsAreEqual ? !itemsAreEqual(prevData, item, itemIndex, data) : true)) {
2715
- set$(ctx, `containerItemData${i}`, data[itemIndex]);
2696
+ set$(ctx, `containerItemData${i}`, item);
2716
2697
  }
2717
2698
  }
2718
2699
  }
2719
2700
  }
2720
2701
  }
2721
- if (didChangePositions) {
2722
- set$(ctx, "lastPositionUpdate", Date.now());
2723
- }
2724
- if (!queuedInitialLayout && endBuffered !== null) {
2725
- if (checkAllSizesKnown(state)) {
2726
- setDidLayout(ctx, state);
2727
- }
2728
- }
2729
- if (viewabilityConfigCallbackPairs) {
2730
- 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
+ };
2731
2824
  }
2732
- });
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;
2733
2846
  }
2734
2847
 
2735
2848
  // src/core/doInitialAllocateContainers.ts
2736
2849
  function doInitialAllocateContainers(ctx, state) {
2737
- var _a;
2850
+ var _a3, _b, _c;
2738
2851
  const {
2739
2852
  scrollLength,
2740
2853
  props: {
@@ -2750,12 +2863,13 @@ function doInitialAllocateContainers(ctx, state) {
2750
2863
  const hasContainers = peek$(ctx, "numContainers");
2751
2864
  if (scrollLength > 0 && data.length > 0 && !hasContainers) {
2752
2865
  let averageItemSize;
2753
- const fn = getFixedItemSize || getEstimatedItemSize;
2754
- if (fn) {
2866
+ if (getFixedItemSize || getEstimatedItemSize) {
2755
2867
  let totalSize = 0;
2756
2868
  const num = Math.min(20, data.length);
2757
2869
  for (let i = 0; i < num; i++) {
2758
- 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;
2759
2873
  }
2760
2874
  averageItemSize = totalSize / num;
2761
2875
  } else {
@@ -2769,76 +2883,18 @@ function doInitialAllocateContainers(ctx, state) {
2769
2883
  set$(ctx, "numContainers", numContainers);
2770
2884
  set$(ctx, "numContainersPooled", numContainers * state.props.initialContainerPoolRatio);
2771
2885
  if (state.lastLayout) {
2772
- if (state.props.initialScroll) {
2886
+ if (state.initialScroll) {
2773
2887
  requestAnimationFrame(() => {
2774
- calculateItemsInView(ctx, state, { dataChanged: true });
2888
+ calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2775
2889
  });
2776
2890
  } else {
2777
- calculateItemsInView(ctx, state, { dataChanged: true });
2891
+ calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2778
2892
  }
2779
2893
  }
2780
2894
  return true;
2781
2895
  }
2782
2896
  }
2783
2897
 
2784
- // src/core/doMaintainScrollAtEnd.ts
2785
- function doMaintainScrollAtEnd(ctx, state, animated) {
2786
- const {
2787
- refScroller,
2788
- props: { maintainScrollAtEnd }
2789
- } = state;
2790
- if ((state == null ? void 0 : state.isAtEnd) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
2791
- const paddingTop = peek$(ctx, "alignItemsPaddingTop");
2792
- if (paddingTop > 0) {
2793
- state.scroll = 0;
2794
- }
2795
- requestAnimationFrame(() => {
2796
- var _a;
2797
- if (state == null ? void 0 : state.isAtEnd) {
2798
- state.maintainingScrollAtEnd = true;
2799
- (_a = refScroller.current) == null ? void 0 : _a.scrollToEnd({
2800
- animated
2801
- });
2802
- setTimeout(
2803
- () => {
2804
- state.maintainingScrollAtEnd = false;
2805
- },
2806
- 0
2807
- );
2808
- }
2809
- });
2810
- return true;
2811
- }
2812
- }
2813
-
2814
- // src/utils/checkAtTop.ts
2815
- function checkAtTop(state) {
2816
- if (!state) {
2817
- return;
2818
- }
2819
- const {
2820
- scrollLength,
2821
- scroll,
2822
- props: { onStartReachedThreshold }
2823
- } = state;
2824
- const distanceFromTop = scroll;
2825
- state.isAtStart = distanceFromTop <= 0;
2826
- state.isStartReached = checkThreshold(
2827
- distanceFromTop,
2828
- false,
2829
- onStartReachedThreshold * scrollLength,
2830
- state.isStartReached,
2831
- state.startReachedBlockedByTimer,
2832
- (distance) => {
2833
- var _a, _b;
2834
- return (_b = (_a = state.props).onStartReached) == null ? void 0 : _b.call(_a, { distanceFromStart: distance });
2835
- },
2836
- (block) => {
2837
- state.startReachedBlockedByTimer = block;
2838
- }
2839
- );
2840
- }
2841
-
2842
2898
  // src/core/handleLayout.ts
2843
2899
  function handleLayout(ctx, state, layout, setCanRender) {
2844
2900
  const { maintainScrollAtEnd } = state.props;
@@ -2873,19 +2929,19 @@ function handleLayout(ctx, state, layout, setCanRender) {
2873
2929
  if (state) {
2874
2930
  state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
2875
2931
  }
2876
- if (__DEV__ && measuredLength === 0) {
2932
+ if (IS_DEV && measuredLength === 0) {
2877
2933
  warnDevOnce(
2878
2934
  "height0",
2879
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.`
2880
2936
  );
2881
2937
  }
2882
- setCanRender(true);
2883
2938
  }
2939
+ setCanRender(true);
2884
2940
  }
2885
2941
 
2886
2942
  // src/core/onScroll.ts
2887
2943
  function onScroll(ctx, state, event) {
2888
- var _a, _b, _c;
2944
+ var _a3, _b, _c;
2889
2945
  const {
2890
2946
  scrollProcessingEnabled,
2891
2947
  props: { onScroll: onScrollProp }
@@ -2893,67 +2949,51 @@ function onScroll(ctx, state, event) {
2893
2949
  if (scrollProcessingEnabled === false) {
2894
2950
  return;
2895
2951
  }
2896
- 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) {
2897
2953
  return;
2898
2954
  }
2899
2955
  const newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2900
- const ignoreScrollFromMVCP = state.ignoreScrollFromMVCP;
2901
- if (ignoreScrollFromMVCP && !state.scrollingTo) {
2902
- const { lt, gt } = ignoreScrollFromMVCP;
2903
- if (lt && newScroll < lt || gt && newScroll > gt) {
2904
- return;
2905
- }
2906
- }
2907
2956
  state.scrollPending = newScroll;
2908
- {
2909
- if (!state.onScrollRafScheduled) {
2910
- state.onScrollRafScheduled = true;
2911
- requestAnimationFrame(() => {
2912
- state.onScrollRafScheduled = false;
2913
- updateScroll(ctx, state, newScroll);
2914
- });
2915
- }
2916
- }
2957
+ updateScroll(ctx, state, newScroll);
2917
2958
  onScrollProp == null ? void 0 : onScrollProp(event);
2918
2959
  }
2919
- function updateScroll(ctx, state, newScroll) {
2920
- const scrollingTo = state.scrollingTo;
2921
- state.hasScrolled = true;
2922
- state.lastBatchingAction = Date.now();
2923
- const currentTime = Date.now();
2924
- if (scrollingTo === void 0 && !(state.scrollHistory.length === 0 && newScroll === state.scroll)) {
2925
- const adjust = state.scrollAdjustHandler.getAdjust();
2926
- state.scrollHistory.push({ scroll: newScroll - adjust, time: currentTime });
2927
- }
2928
- if (state.scrollHistory.length > 5) {
2929
- state.scrollHistory.shift();
2930
- }
2931
- state.scrollPrev = state.scroll;
2932
- state.scrollPrevTime = state.scrollTime;
2933
- state.scroll = newScroll;
2934
- state.scrollTime = currentTime;
2935
- if (Math.abs(state.scroll - state.scrollPrev) > 2) {
2936
- calculateItemsInView(ctx, state);
2937
- checkAtBottom(ctx, state);
2938
- checkAtTop(state);
2939
- }
2940
- }
2941
2960
 
2942
2961
  // src/core/ScrollAdjustHandler.ts
2943
2962
  var ScrollAdjustHandler = class {
2944
2963
  constructor(ctx) {
2945
2964
  this.appliedAdjust = 0;
2965
+ this.pendingAdjust = 0;
2946
2966
  this.mounted = false;
2947
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
+ }
2948
2988
  }
2949
2989
  requestAdjust(add) {
2950
- const oldAdjustTop = peek$(this.context, "scrollAdjust") || 0;
2951
- this.appliedAdjust = add + oldAdjustTop;
2952
- const set = () => set$(this.context, "scrollAdjust", this.appliedAdjust);
2953
- if (this.mounted) {
2954
- 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);
2955
2994
  } else {
2956
- requestAnimationFrame(set);
2995
+ this.appliedAdjust += add;
2996
+ set$(this.context, "scrollAdjust", this.appliedAdjust);
2957
2997
  }
2958
2998
  }
2959
2999
  setMounted() {
@@ -2966,14 +3006,13 @@ var ScrollAdjustHandler = class {
2966
3006
 
2967
3007
  // src/core/updateItemSize.ts
2968
3008
  function updateItemSize(ctx, state, itemKey, sizeObj) {
2969
- var _a, _b;
3009
+ var _a3;
2970
3010
  const {
2971
3011
  sizesKnown,
2972
3012
  props: {
2973
3013
  getFixedItemSize,
2974
3014
  getItemType,
2975
3015
  horizontal,
2976
- maintainVisibleContentPosition,
2977
3016
  suggestEstimatedItemSize,
2978
3017
  onItemSizeChanged,
2979
3018
  data,
@@ -2981,17 +3020,17 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2981
3020
  }
2982
3021
  } = state;
2983
3022
  if (!data) return;
3023
+ const index = state.indexByKey.get(itemKey);
2984
3024
  if (getFixedItemSize) {
2985
- const index2 = state.indexByKey.get(itemKey);
2986
- if (index2 === void 0) {
3025
+ if (index === void 0) {
2987
3026
  return;
2988
3027
  }
2989
- const itemData = state.props.data[index2];
3028
+ const itemData = state.props.data[index];
2990
3029
  if (itemData === void 0) {
2991
3030
  return;
2992
3031
  }
2993
- const type = getItemType ? (_a = getItemType(itemData, index2)) != null ? _a : "" : "";
2994
- const size2 = getFixedItemSize(index2, itemData, type);
3032
+ const type = getItemType ? (_a3 = getItemType(itemData, index)) != null ? _a3 : "" : "";
3033
+ const size2 = getFixedItemSize(index, itemData, type);
2995
3034
  if (size2 !== void 0 && size2 === sizesKnown.get(itemKey)) {
2996
3035
  return;
2997
3036
  }
@@ -3001,15 +3040,11 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
3001
3040
  let shouldMaintainScrollAtEnd = false;
3002
3041
  let minIndexSizeChanged;
3003
3042
  let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
3004
- const index = state.indexByKey.get(itemKey);
3005
3043
  const prevSizeKnown = state.sizesKnown.get(itemKey);
3006
- const diff = updateOneItemSize(state, itemKey, sizeObj);
3007
- 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);
3008
3046
  if (diff !== 0) {
3009
3047
  minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
3010
- if (((_b = state.scrollingTo) == null ? void 0 : _b.viewPosition) && maintainVisibleContentPosition && index === state.scrollingTo.index && diff > 0) {
3011
- requestAdjust(ctx, state, diff * state.scrollingTo.viewPosition);
3012
- }
3013
3048
  const { startBuffered, endBuffered } = state;
3014
3049
  needsRecalculate || (needsRecalculate = index >= startBuffered && index <= endBuffered);
3015
3050
  if (!needsRecalculate) {
@@ -3039,13 +3074,13 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
3039
3074
  if (minIndexSizeChanged !== void 0) {
3040
3075
  state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, minIndexSizeChanged) : minIndexSizeChanged;
3041
3076
  }
3042
- if (__DEV__ && suggestEstimatedItemSize && minIndexSizeChanged !== void 0) {
3077
+ if (IS_DEV && suggestEstimatedItemSize && minIndexSizeChanged !== void 0) {
3043
3078
  if (state.timeoutSizeMessage) clearTimeout(state.timeoutSizeMessage);
3044
3079
  state.timeoutSizeMessage = setTimeout(() => {
3045
- var _a2;
3080
+ var _a4;
3046
3081
  state.timeoutSizeMessage = void 0;
3047
3082
  const num = state.sizesKnown.size;
3048
- const avg = (_a2 = state.averageSizes[""]) == null ? void 0 : _a2.avg;
3083
+ const avg = (_a4 = state.averageSizes[""]) == null ? void 0 : _a4.avg;
3049
3084
  console.warn(
3050
3085
  `[legend-list] Based on the ${num} items rendered so far, the optimal estimated size is ${avg}.`
3051
3086
  );
@@ -3067,8 +3102,8 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
3067
3102
  }
3068
3103
  }
3069
3104
  }
3070
- function updateOneItemSize(state, itemKey, sizeObj) {
3071
- var _a;
3105
+ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
3106
+ var _a3;
3072
3107
  const {
3073
3108
  sizes,
3074
3109
  indexByKey,
@@ -3078,12 +3113,12 @@ function updateOneItemSize(state, itemKey, sizeObj) {
3078
3113
  } = state;
3079
3114
  if (!data) return 0;
3080
3115
  const index = indexByKey.get(itemKey);
3081
- const prevSize = getItemSize(state, itemKey, index, data);
3116
+ const prevSize = getItemSize(ctx, state, itemKey, index, data[index]);
3082
3117
  const rawSize = horizontal ? sizeObj.width : sizeObj.height;
3083
3118
  const size = Math.round(rawSize) ;
3084
3119
  sizesKnown.set(itemKey, size);
3085
3120
  if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
3086
- const itemType = getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : "";
3121
+ const itemType = getItemType ? (_a3 = getItemType(data[index], index)) != null ? _a3 : "" : "";
3087
3122
  let averages = averageSizes[itemType];
3088
3123
  if (!averages) {
3089
3124
  averages = averageSizes[itemType] = { avg: 0, num: 0 };
@@ -3092,7 +3127,7 @@ function updateOneItemSize(state, itemKey, sizeObj) {
3092
3127
  averages.num++;
3093
3128
  }
3094
3129
  if (!prevSize || Math.abs(prevSize - size) > 0.1) {
3095
- sizes.set(itemKey, size);
3130
+ setSize(ctx, state, itemKey, size);
3096
3131
  return size - prevSize;
3097
3132
  }
3098
3133
  return 0;
@@ -3114,18 +3149,12 @@ var useCombinedRef = (...refs) => {
3114
3149
  };
3115
3150
 
3116
3151
  // src/platform/RefreshControl.tsx
3117
- function RefreshControl(props) {
3152
+ function RefreshControl(_props) {
3118
3153
  return null;
3119
3154
  }
3120
3155
 
3121
- // src/platform/StyleSheet.tsx
3122
- var StyleSheet = {
3123
- create: (styles) => styles,
3124
- flatten: (style) => style
3125
- };
3126
-
3127
3156
  // src/platform/useStickyScrollHandler.ts
3128
- function useStickyScrollHandler(stickyIndices, horizontal, ctx, onScroll2) {
3157
+ function useStickyScrollHandler(_stickyHeaderIndices, _horizontal, _ctx, onScroll2) {
3129
3158
  return onScroll2;
3130
3159
  }
3131
3160
 
@@ -3143,8 +3172,93 @@ function createColumnWrapperStyle(contentContainerStyle) {
3143
3172
  };
3144
3173
  }
3145
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
+ }
3146
3260
  function getRenderedItem(ctx, state, key) {
3147
- var _a;
3261
+ var _a3;
3148
3262
  if (!state) {
3149
3263
  return null;
3150
3264
  }
@@ -3157,13 +3271,15 @@ function getRenderedItem(ctx, state, key) {
3157
3271
  return null;
3158
3272
  }
3159
3273
  let renderedItem = null;
3160
- if (renderItem && data[index]) {
3274
+ const extraData = peek$(ctx, "extraData");
3275
+ const item = data[index];
3276
+ if (renderItem && !isNullOrUndefined(item)) {
3161
3277
  const itemProps = {
3162
3278
  data,
3163
- extraData: peek$(ctx, "extraData"),
3279
+ extraData,
3164
3280
  index,
3165
- item: data[index],
3166
- type: getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : ""
3281
+ item,
3282
+ type: getItemType ? (_a3 = getItemType(item, index)) != null ? _a3 : "" : ""
3167
3283
  };
3168
3284
  renderedItem = isFunction(renderItem) ? renderItem(itemProps) : React3__namespace.default.createElement(renderItem, itemProps);
3169
3285
  }
@@ -3215,58 +3331,6 @@ function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
3215
3331
  return (event) => throttle(originalHandler, scrollEventThrottle, { nativeEvent: event.nativeEvent });
3216
3332
  }
3217
3333
 
3218
- // src/utils/updateAveragesOnDataChange.ts
3219
- function updateAveragesOnDataChange(state, oldData, newData) {
3220
- var _a;
3221
- const {
3222
- averageSizes,
3223
- sizesKnown,
3224
- indexByKey,
3225
- props: { itemsAreEqual, getItemType, keyExtractor }
3226
- } = state;
3227
- if (!itemsAreEqual || !oldData.length || !newData.length) {
3228
- for (const key in averageSizes) {
3229
- delete averageSizes[key];
3230
- }
3231
- return;
3232
- }
3233
- const itemTypesToPreserve = {};
3234
- const newDataLength = newData.length;
3235
- const oldDataLength = oldData.length;
3236
- for (let newIndex = 0; newIndex < newDataLength; newIndex++) {
3237
- const newItem = newData[newIndex];
3238
- const id = keyExtractor ? keyExtractor(newItem, newIndex) : String(newIndex);
3239
- const oldIndex = indexByKey.get(id);
3240
- if (oldIndex !== void 0 && oldIndex < oldDataLength) {
3241
- const knownSize = sizesKnown.get(id);
3242
- if (knownSize === void 0) continue;
3243
- const oldItem = oldData[oldIndex];
3244
- const areEqual = itemsAreEqual(oldItem, newItem, newIndex, newData);
3245
- if (areEqual) {
3246
- const itemType = getItemType ? (_a = getItemType(newItem, newIndex)) != null ? _a : "" : "";
3247
- let typeData = itemTypesToPreserve[itemType];
3248
- if (!typeData) {
3249
- typeData = itemTypesToPreserve[itemType] = { count: 0, totalSize: 0 };
3250
- }
3251
- typeData.totalSize += knownSize;
3252
- typeData.count++;
3253
- }
3254
- }
3255
- }
3256
- for (const key in averageSizes) {
3257
- delete averageSizes[key];
3258
- }
3259
- for (const itemType in itemTypesToPreserve) {
3260
- const { totalSize, count } = itemTypesToPreserve[itemType];
3261
- if (count > 0) {
3262
- averageSizes[itemType] = {
3263
- avg: totalSize / count,
3264
- num: count
3265
- };
3266
- }
3267
- }
3268
- }
3269
-
3270
3334
  // src/components/LegendList.tsx
3271
3335
  var DEFAULT_DRAW_DISTANCE = 250;
3272
3336
  var DEFAULT_ITEM_SIZE = 100;
@@ -3287,11 +3351,13 @@ var LegendList = typedMemo(
3287
3351
  })
3288
3352
  );
3289
3353
  var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
3354
+ var _a3, _b;
3290
3355
  const {
3291
3356
  alignItemsAtEnd = false,
3292
3357
  columnWrapperStyle,
3293
3358
  contentContainerStyle: contentContainerStyleProp,
3294
3359
  data: dataProp = [],
3360
+ dataVersion,
3295
3361
  drawDistance = 250,
3296
3362
  enableAverages = true,
3297
3363
  estimatedItemSize: estimatedItemSizeProp,
@@ -3302,6 +3368,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3302
3368
  getItemType,
3303
3369
  horizontal,
3304
3370
  initialContainerPoolRatio = 2,
3371
+ initialScrollAtEnd = false,
3305
3372
  initialScrollIndex: initialScrollIndexProp,
3306
3373
  initialScrollOffset: initialScrollOffsetProp,
3307
3374
  itemsAreEqual,
@@ -3310,7 +3377,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3310
3377
  ListHeaderComponent,
3311
3378
  maintainScrollAtEnd = false,
3312
3379
  maintainScrollAtEndThreshold = 0.1,
3313
- maintainVisibleContentPosition = true,
3380
+ maintainVisibleContentPosition = false,
3314
3381
  numColumns: numColumnsProp = 1,
3315
3382
  onEndReached,
3316
3383
  onEndReachedThreshold = 0.5,
@@ -3322,6 +3389,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3322
3389
  onScroll: onScrollProp,
3323
3390
  onStartReached,
3324
3391
  onStartReachedThreshold = 0.5,
3392
+ onStickyHeaderChange,
3393
+ onViewableItemsChanged,
3325
3394
  progressViewOffset,
3326
3395
  recycleItems = false,
3327
3396
  refreshControl,
@@ -3330,19 +3399,22 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3330
3399
  renderItem,
3331
3400
  scrollEventThrottle,
3332
3401
  snapToIndices,
3333
- stickyIndices,
3402
+ stickyHeaderIndices: stickyHeaderIndicesProp,
3403
+ stickyIndices: stickyIndicesDeprecated,
3334
3404
  style: styleProp,
3335
3405
  suggestEstimatedItemSize,
3406
+ viewabilityConfig,
3407
+ viewabilityConfigCallbackPairs,
3336
3408
  waitForInitialLayout = true,
3337
3409
  ...rest
3338
3410
  } = props;
3339
- const [renderNum, setRenderNum] = React3.useState(0);
3340
- const initialScroll = initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
3341
- const [canRender, setCanRender] = React3__namespace.useState(!IsNewArchitecture);
3342
3411
  const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
3343
3412
  const style = { ...StyleSheet.flatten(styleProp) };
3344
3413
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
3345
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);
3346
3418
  const ctx = useStateContext();
3347
3419
  ctx.columnWrapperStyle = columnWrapperStyle || (contentContainerStyle ? createColumnWrapperStyle(contentContainerStyle) : void 0);
3348
3420
  const refScroller = React3.useRef(null);
@@ -3350,6 +3422,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3350
3422
  const estimatedItemSize = estimatedItemSizeProp != null ? estimatedItemSizeProp : DEFAULT_ITEM_SIZE;
3351
3423
  const scrollBuffer = (drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE) || 1;
3352
3424
  const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (_item, index) => index.toString();
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
+ }
3353
3432
  const refState = React3.useRef();
3354
3433
  if (!refState.current) {
3355
3434
  if (!ctx.internalState) {
@@ -3360,18 +3439,29 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3360
3439
  columns: /* @__PURE__ */ new Map(),
3361
3440
  containerItemKeys: /* @__PURE__ */ new Set(),
3362
3441
  containerItemTypes: /* @__PURE__ */ new Map(),
3442
+ dataChangeNeedsScrollUpdate: false,
3443
+ didColumnsChange: false,
3444
+ didDataChange: false,
3363
3445
  enableScrollForNextCalculateItemsInView: true,
3364
3446
  endBuffered: -1,
3365
3447
  endNoBuffer: -1,
3366
- endReachedBlockedByTimer: false,
3448
+ endReachedSnapshot: void 0,
3367
3449
  firstFullyOnScreenIndex: -1,
3368
- idCache: /* @__PURE__ */ new Map(),
3450
+ idCache: [],
3369
3451
  idsInView: [],
3370
3452
  indexByKey: /* @__PURE__ */ new Map(),
3371
- 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,
3372
3461
  isAtEnd: false,
3373
3462
  isAtStart: false,
3374
3463
  isEndReached: false,
3464
+ isFirst: true,
3375
3465
  isStartReached: false,
3376
3466
  lastBatchingAction: Date.now(),
3377
3467
  lastLayout: void 0,
@@ -3396,7 +3486,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3396
3486
  sizesKnown: /* @__PURE__ */ new Map(),
3397
3487
  startBuffered: -1,
3398
3488
  startNoBuffer: -1,
3399
- startReachedBlockedByTimer: false,
3489
+ startReachedSnapshot: void 0,
3400
3490
  stickyContainerPool: /* @__PURE__ */ new Set(),
3401
3491
  stickyContainers: /* @__PURE__ */ new Map(),
3402
3492
  timeoutSizeMessage: 0,
@@ -3404,21 +3494,27 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3404
3494
  totalSize: 0,
3405
3495
  viewabilityConfigCallbackPairs: void 0
3406
3496
  };
3497
+ const internalState = ctx.internalState;
3498
+ internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, internalState, params);
3407
3499
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
3408
3500
  set$(ctx, "extraData", extraData);
3409
3501
  }
3410
3502
  refState.current = ctx.internalState;
3411
3503
  }
3412
3504
  const state = refState.current;
3413
- const isFirst = !state.props.renderItem;
3414
- const didDataChange = state.props.data !== dataProp;
3415
- const throttleScrollFn = (
3416
- // @ts-expect-error TODO Fix this
3417
- scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp
3418
- );
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;
3419
3514
  state.props = {
3420
3515
  alignItemsAtEnd,
3421
3516
  data: dataProp,
3517
+ dataVersion,
3422
3518
  enableAverages,
3423
3519
  estimatedItemSize,
3424
3520
  getEstimatedItemSize,
@@ -3426,7 +3522,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3426
3522
  getItemType,
3427
3523
  horizontal: !!horizontal,
3428
3524
  initialContainerPoolRatio,
3429
- initialScroll,
3430
3525
  itemsAreEqual,
3431
3526
  keyExtractor,
3432
3527
  maintainScrollAtEnd,
@@ -3440,45 +3535,25 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3440
3535
  onScroll: throttleScrollFn,
3441
3536
  onStartReached,
3442
3537
  onStartReachedThreshold,
3538
+ onStickyHeaderChange,
3443
3539
  recycleItems: !!recycleItems,
3444
3540
  renderItem,
3445
3541
  scrollBuffer,
3446
3542
  snapToIndices,
3447
- stickyIndicesArr: stickyIndices != null ? stickyIndices : [],
3448
- stickyIndicesSet: React3.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(",")]),
3449
3545
  stylePaddingBottom: stylePaddingBottomState,
3450
3546
  stylePaddingTop: stylePaddingTopState,
3451
3547
  suggestEstimatedItemSize: !!suggestEstimatedItemSize
3452
3548
  };
3453
3549
  state.refScroller = refScroller;
3454
- const checkResetContainers = (isFirst2) => {
3455
- const state2 = refState.current;
3456
- if (state2) {
3457
- if (!isFirst2 && state2.props.data !== dataProp) {
3458
- updateAveragesOnDataChange(state2, state2.props.data, dataProp);
3459
- }
3460
- state2.props.data = dataProp;
3461
- if (!isFirst2) {
3462
- calculateItemsInView(ctx, state2, { dataChanged: true, doMVCP: true });
3463
- const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
3464
- const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state2, false);
3465
- if (!didMaintainScrollAtEnd && dataProp.length > state2.props.data.length) {
3466
- state2.isEndReached = false;
3467
- }
3468
- if (!didMaintainScrollAtEnd) {
3469
- checkAtTop(state2);
3470
- checkAtBottom(ctx, state2);
3471
- }
3472
- }
3473
- }
3474
- };
3475
3550
  const memoizedLastItemKeys = React3.useMemo(() => {
3476
3551
  if (!dataProp.length) return [];
3477
3552
  return Array.from(
3478
3553
  { length: Math.min(numColumnsProp, dataProp.length) },
3479
3554
  (_, i) => getId(state, dataProp.length - 1 - i)
3480
3555
  );
3481
- }, [dataProp, numColumnsProp]);
3556
+ }, [dataProp, dataVersion, numColumnsProp]);
3482
3557
  const initializeStateVars = () => {
3483
3558
  set$(ctx, "lastItemKeys", memoizedLastItemKeys);
3484
3559
  set$(ctx, "numColumns", numColumnsProp);
@@ -3486,44 +3561,70 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3486
3561
  setPaddingTop(ctx, state, { stylePaddingTop: stylePaddingTopState });
3487
3562
  refState.current.props.stylePaddingBottom = stylePaddingBottomState;
3488
3563
  let paddingDiff = stylePaddingTopState - prevPaddingTop;
3489
- if (maintainVisibleContentPosition && paddingDiff && prevPaddingTop !== void 0 && Platform.OS === "ios") {
3564
+ if (paddingDiff && prevPaddingTop !== void 0 && Platform.OS === "ios") {
3490
3565
  if (state.scroll < 0) {
3491
3566
  paddingDiff += state.scroll;
3492
3567
  }
3493
3568
  requestAdjust(ctx, state, paddingDiff);
3494
3569
  }
3495
3570
  };
3496
- if (isFirst) {
3571
+ if (isFirstLocal) {
3497
3572
  initializeStateVars();
3498
- updateAllPositions(ctx, state);
3573
+ updateItemPositions(
3574
+ ctx,
3575
+ state,
3576
+ /*dataChanged*/
3577
+ true
3578
+ );
3499
3579
  }
3500
3580
  const initialContentOffset = React3.useMemo(() => {
3501
- if (initialScroll) {
3502
- const { index, viewOffset } = initialScroll;
3503
- let initialContentOffset2 = viewOffset || 0;
3504
- if (index !== void 0) {
3505
- initialContentOffset2 += calculateOffsetForIndex(ctx, state, index);
3506
- }
3507
- refState.current.isStartReached = initialContentOffset2 < refState.current.scrollLength * onStartReachedThreshold;
3508
- if (initialContentOffset2 > 0) {
3509
- scrollTo(state, { animated: false, index, offset: initialContentOffset2 });
3510
- }
3511
- return initialContentOffset2;
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
+ };
3512
3595
  }
3513
- 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;
3514
3612
  }, [renderNum]);
3515
- if (isFirst || didDataChange || numColumnsProp !== peek$(ctx, "numColumns")) {
3516
- state.lastBatchingAction = Date.now();
3517
- if (!keyExtractorProp && !isFirst && didDataChange) {
3518
- __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(
3519
3617
  "keyExtractor",
3520
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."
3521
3619
  );
3522
- state.sizes.clear();
3523
- state.positions.clear();
3620
+ refState.current.sizes.clear();
3621
+ refState.current.positions.clear();
3622
+ refState.current.totalSize = 0;
3623
+ set$(ctx, "totalSize", 0);
3524
3624
  }
3525
3625
  }
3526
3626
  const onLayoutHeader = React3.useCallback((rect, fromLayoutEffect) => {
3627
+ const { initialScroll } = refState.current;
3527
3628
  const size = rect[horizontal ? "width" : "height"];
3528
3629
  set$(ctx, "headerSize", size);
3529
3630
  if ((initialScroll == null ? void 0 : initialScroll.index) !== void 0) {
@@ -3534,132 +3635,71 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3534
3635
  }
3535
3636
  }
3536
3637
  }, []);
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
+ });
3537
3661
  React3.useLayoutEffect(() => {
3538
3662
  if (snapToIndices) {
3539
3663
  updateSnapToOffsets(ctx, state);
3540
3664
  }
3541
3665
  }, [snapToIndices]);
3542
3666
  React3.useLayoutEffect(() => {
3543
- const didAllocateContainers = dataProp.length > 0 && doInitialAllocateContainersCallback();
3544
- if (!didAllocateContainers) {
3545
- checkResetContainers(
3546
- /*isFirst*/
3547
- isFirst
3548
- );
3549
- }
3550
- }, [dataProp, numColumnsProp]);
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]);
3551
3681
  React3.useLayoutEffect(() => {
3552
3682
  set$(ctx, "extraData", extraData);
3553
3683
  }, [extraData]);
3554
- const { onLayout } = useSyncLayout({
3555
- onLayout: onLayoutProp,
3556
- onLayoutChange: React3.useCallback(
3557
- (rectangle) => {
3558
- handleLayout(ctx, state, rectangle, setCanRender);
3559
- },
3560
- [ctx, state, setCanRender]
3561
- ),
3562
- ref: refScroller
3563
- });
3564
3684
  React3.useLayoutEffect(initializeStateVars, [
3685
+ dataVersion,
3565
3686
  memoizedLastItemKeys.join(","),
3566
3687
  numColumnsProp,
3567
- stylePaddingTopState,
3568
- stylePaddingBottomState
3688
+ stylePaddingBottomState,
3689
+ stylePaddingTopState
3569
3690
  ]);
3570
- const doInitialAllocateContainersCallback = () => {
3571
- return doInitialAllocateContainers(ctx, state);
3572
- };
3573
- React3.useImperativeHandle(forwardedRef, () => {
3574
- const scrollIndexIntoView = (options) => {
3575
- const state2 = refState.current;
3576
- if (state2) {
3577
- const { index, ...rest2 } = options;
3578
- const { startNoBuffer, endNoBuffer } = state2;
3579
- if (index < startNoBuffer || index > endNoBuffer) {
3580
- const viewPosition = index < startNoBuffer ? 0 : 1;
3581
- scrollToIndex(ctx, state2, {
3582
- ...rest2,
3583
- index,
3584
- viewPosition
3585
- });
3586
- }
3587
- }
3588
- };
3589
- return {
3590
- flashScrollIndicators: () => {
3591
- var _a, _b;
3592
- return (_b = (_a = refScroller.current) == null ? void 0 : _a.flashScrollIndicators) == null ? void 0 : _b.call(_a);
3593
- },
3594
- getNativeScrollRef: () => refScroller.current,
3595
- getScrollableNode: () => refScroller.current,
3596
- getScrollResponder: () => refScroller.current,
3597
- getState: () => {
3598
- const state2 = refState.current;
3599
- return state2 ? {
3600
- contentLength: state2.totalSize,
3601
- data: state2.props.data,
3602
- end: state2.endNoBuffer,
3603
- endBuffered: state2.endBuffered,
3604
- isAtEnd: state2.isAtEnd,
3605
- isAtStart: state2.isAtStart,
3606
- positionAtIndex: (index) => state2.positions.get(getId(state2, index)),
3607
- positions: state2.positions,
3608
- scroll: state2.scroll,
3609
- scrollLength: state2.scrollLength,
3610
- sizeAtIndex: (index) => state2.sizesKnown.get(getId(state2, index)),
3611
- sizes: state2.sizesKnown,
3612
- start: state2.startNoBuffer,
3613
- startBuffered: state2.startBuffered
3614
- } : {};
3615
- },
3616
- scrollIndexIntoView,
3617
- scrollItemIntoView: ({ item, ...props2 }) => {
3618
- const data = refState.current.props.data;
3619
- const index = data.indexOf(item);
3620
- if (index !== -1) {
3621
- scrollIndexIntoView({ index, ...props2 });
3622
- }
3623
- },
3624
- scrollToEnd: (options) => {
3625
- const data = refState.current.props.data;
3626
- const stylePaddingBottom = refState.current.props.stylePaddingBottom;
3627
- const index = data.length - 1;
3628
- if (index !== -1) {
3629
- const paddingBottom = stylePaddingBottom || 0;
3630
- const footerSize = peek$(ctx, "footerSize") || 0;
3631
- scrollToIndex(ctx, state, {
3632
- index,
3633
- viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
3634
- viewPosition: 1,
3635
- ...options
3636
- });
3637
- }
3638
- },
3639
- scrollToIndex: (params) => scrollToIndex(ctx, state, params),
3640
- scrollToItem: ({ item, ...props2 }) => {
3641
- const data = refState.current.props.data;
3642
- const index = data.indexOf(item);
3643
- if (index !== -1) {
3644
- scrollToIndex(ctx, state, { index, ...props2 });
3645
- }
3646
- },
3647
- scrollToOffset: (params) => scrollTo(state, params),
3648
- setScrollProcessingEnabled: (enabled) => {
3649
- refState.current.scrollProcessingEnabled = enabled;
3650
- },
3651
- setVisibleContentAnchorOffset: (value) => {
3652
- const val = typeof value === "function" ? value(peek$(ctx, "scrollAdjustUserOffset") || 0) : value;
3653
- set$(ctx, "scrollAdjustUserOffset", val);
3654
- }
3655
- };
3656
- }, []);
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), []);
3657
3701
  {
3658
- React3.useEffect(() => {
3659
- if (initialContentOffset) {
3660
- scrollTo(state, { animated: false, offset: initialContentOffset });
3661
- }
3662
- }, []);
3702
+ React3.useEffect(doInitialScroll, []);
3663
3703
  }
3664
3704
  const fns = React3.useMemo(
3665
3705
  () => ({
@@ -3669,7 +3709,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3669
3709
  }),
3670
3710
  []
3671
3711
  );
3672
- const onScrollHandler = useStickyScrollHandler(stickyIndices, horizontal, ctx, fns.onScroll);
3712
+ const onScrollHandler = useStickyScrollHandler(stickyHeaderIndices, horizontal, ctx, fns.onScroll);
3673
3713
  return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement(
3674
3714
  ListComponent,
3675
3715
  {
@@ -3688,7 +3728,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3688
3728
  onMomentumScrollEnd: (event) => {
3689
3729
  {
3690
3730
  requestAnimationFrame(() => {
3691
- finishScrollTo(refState.current);
3731
+ finishScrollTo(ctx, refState.current);
3692
3732
  });
3693
3733
  }
3694
3734
  if (onMomentumScrollEnd) {
@@ -3708,45 +3748,22 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3708
3748
  }
3709
3749
  ),
3710
3750
  refScrollView: combinedRef,
3711
- scrollAdjustHandler: state.scrollAdjustHandler,
3751
+ scrollAdjustHandler: (_b = refState.current) == null ? void 0 : _b.scrollAdjustHandler,
3752
+ scrollEventThrottle: 16 ,
3712
3753
  snapToIndices,
3713
- stickyIndices,
3754
+ stickyHeaderIndices,
3714
3755
  style,
3715
3756
  updateItemSize: fns.updateItemSize,
3716
3757
  waitForInitialLayout
3717
3758
  }
3718
- ), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React3__namespace.createElement(DebugView, { state: refState.current }));
3759
+ ), IS_DEV && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React3__namespace.createElement(DebugView, { state: refState.current }));
3719
3760
  });
3720
- /*! Bundled license information:
3721
-
3722
- react-dom/cjs/react-dom.production.js:
3723
- (**
3724
- * @license React
3725
- * react-dom.production.js
3726
- *
3727
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3728
- *
3729
- * This source code is licensed under the MIT license found in the
3730
- * LICENSE file in the root directory of this source tree.
3731
- *)
3732
-
3733
- react-dom/cjs/react-dom.development.js:
3734
- (**
3735
- * @license React
3736
- * react-dom.development.js
3737
- *
3738
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3739
- *
3740
- * This source code is licensed under the MIT license found in the
3741
- * LICENSE file in the root directory of this source tree.
3742
- *)
3743
- */
3744
3761
 
3745
3762
  exports.LegendList = LegendList;
3746
3763
  exports.useIsLastItem = useIsLastItem;
3747
3764
  exports.useListScrollSize = useListScrollSize;
3748
3765
  exports.useRecyclingEffect = useRecyclingEffect;
3749
3766
  exports.useRecyclingState = useRecyclingState;
3750
- exports.useSyncLayout = useSyncLayout2;
3767
+ exports.useSyncLayout = useSyncLayout;
3751
3768
  exports.useViewability = useViewability;
3752
3769
  exports.useViewabilityAmount = useViewabilityAmount;