@react-stately/virtualizer 3.4.2-nightly.3696 → 3.4.2-nightly.3705

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/import.mjs +1421 -0
  2. package/package.json +9 -4
@@ -0,0 +1,1421 @@
1
+ import {useState as $8D3nr$useState, useMemo as $8D3nr$useMemo, useEffect as $8D3nr$useEffect, useCallback as $8D3nr$useCallback} from "react";
2
+ import {useLayoutEffect as $8D3nr$useLayoutEffect} from "@react-aria/utils";
3
+ import $8D3nr$swchelperssrc_define_propertymjs from "@swc/helpers/src/_define_property.mjs";
4
+
5
+ /*
6
+ * Copyright 2020 Adobe. All rights reserved.
7
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License. You may obtain a copy
9
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software distributed under
12
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
13
+ * OF ANY KIND, either express or implied. See the License for the specific language
14
+ * governing permissions and limitations under the License.
15
+ */ /*
16
+ * Copyright 2020 Adobe. All rights reserved.
17
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
18
+ * you may not use this file except in compliance with the License. You may obtain a copy
19
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
20
+ *
21
+ * Unless required by applicable law or agreed to in writing, software distributed under
22
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
23
+ * OF ANY KIND, either express or implied. See the License for the specific language
24
+ * governing permissions and limitations under the License.
25
+ */ class $c74cda7d31af1253$export$c84671f46d6a1ca {
26
+ /**
27
+ * Returns whether the layout should invalidate in response to
28
+ * visible rectangle changes. By default, it only invalidates
29
+ * when the collection view's size changes. Return true always
30
+ * to make the layout invalidate while scrolling (e.g. sticky headers).
31
+ */ shouldInvalidate(newRect, oldRect) {
32
+ // By default, invalidate when the size changes
33
+ return newRect.width !== oldRect.width || newRect.height !== oldRect.height;
34
+ }
35
+ /**
36
+ * This method allows the layout to perform any pre-computation
37
+ * it needs to in order to prepare {@link LayoutInfo}s for retrieval.
38
+ * Called by the collection view before {@link getVisibleLayoutInfos}
39
+ * or {@link getLayoutInfo} are called.
40
+ */ validate(invalidationContext) {}
41
+ /**
42
+ * Returns a {@link DragTarget} describing a view at the given point to be dragged.
43
+ * Return `null` to cancel the drag. The default implementation returns the view at the given point.
44
+ * @param point The point at which the drag occurred.
45
+ */ // getDragTarget(point: Point): DragTarget | null {
46
+ // let target = this.virtualizer.keyAtPoint(point);
47
+ // if (!target) {
48
+ // return null;
49
+ // }
50
+ // return {
51
+ // type: 'item',
52
+ // key: target
53
+ // };
54
+ // }
55
+ /**
56
+ * Returns a {@link DragTarget} object describing where a drop should occur. Return `null`
57
+ * to reject the drop. The dropped items will be inserted before the resulting target.
58
+ * @param point The point at which the drop occurred.
59
+ */ // getDropTarget(point: Point): DropTarget | null {
60
+ // return null;
61
+ // }
62
+ /**
63
+ * Returns the starting attributes for an animated insertion.
64
+ * The view is animated from this {@link LayoutInfo} to the one returned by {@link getLayoutInfo}.
65
+ * The default implementation just returns its input.
66
+ *
67
+ * @param layoutInfo The proposed LayoutInfo for this view.
68
+ */ getInitialLayoutInfo(layoutInfo) {
69
+ return layoutInfo;
70
+ }
71
+ /**
72
+ * Returns the ending attributes for an animated removal.
73
+ * The view is animated from the {@link LayoutInfo} returned by {@link getLayoutInfo}
74
+ * to the one returned by this method. The default implementation returns its input.
75
+ *
76
+ * @param layoutInfo The original LayoutInfo for this view.
77
+ */ getFinalLayoutInfo(layoutInfo) {
78
+ return layoutInfo;
79
+ }
80
+ }
81
+
82
+
83
+ /*
84
+ * Copyright 2020 Adobe. All rights reserved.
85
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
86
+ * you may not use this file except in compliance with the License. You may obtain a copy
87
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
88
+ *
89
+ * Unless required by applicable law or agreed to in writing, software distributed under
90
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
91
+ * OF ANY KIND, either express or implied. See the License for the specific language
92
+ * governing permissions and limitations under the License.
93
+ */ class $d7fd61009c21d0bb$export$7e0eeb9da702a085 {
94
+ /**
95
+ * Returns a copy of the LayoutInfo.
96
+ */ copy() {
97
+ let res = new $d7fd61009c21d0bb$export$7e0eeb9da702a085(this.type, this.key, this.rect.copy());
98
+ res.estimatedSize = this.estimatedSize;
99
+ res.opacity = this.opacity;
100
+ res.transform = this.transform;
101
+ res.parentKey = this.parentKey;
102
+ res.isSticky = this.isSticky;
103
+ res.zIndex = this.zIndex;
104
+ res.allowOverflow = this.allowOverflow;
105
+ return res;
106
+ }
107
+ /**
108
+ * @param type A string representing the view type. Should be `'item'` for item views.
109
+ Other types are used by supplementary views.
110
+ * @param key The unique key for this view.
111
+ * @param rect The rectangle describing the size and position of this view.
112
+ */ constructor(type, key, rect){
113
+ this.type = type;
114
+ this.key = key;
115
+ this.parentKey = null;
116
+ this.rect = rect;
117
+ this.estimatedSize = false;
118
+ this.isSticky = false;
119
+ this.opacity = 1;
120
+ this.transform = null;
121
+ this.zIndex = 0;
122
+ this.allowOverflow = false;
123
+ }
124
+ }
125
+
126
+
127
+ /*
128
+ * Copyright 2020 Adobe. All rights reserved.
129
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
130
+ * you may not use this file except in compliance with the License. You may obtain a copy
131
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
132
+ *
133
+ * Unless required by applicable law or agreed to in writing, software distributed under
134
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
135
+ * OF ANY KIND, either express or implied. See the License for the specific language
136
+ * governing permissions and limitations under the License.
137
+ */ class $3041db3296945e6e$export$baf26146a414f24a {
138
+ /**
139
+ * Returns a copy of this point.
140
+ */ copy() {
141
+ return new $3041db3296945e6e$export$baf26146a414f24a(this.x, this.y);
142
+ }
143
+ /**
144
+ * Checks if two points are equal.
145
+ */ equals(point) {
146
+ return this.x === point.x && this.y === point.y;
147
+ }
148
+ /**
149
+ * Returns true if this point is the origin.
150
+ */ isOrigin() {
151
+ return this.x === 0 && this.y === 0;
152
+ }
153
+ constructor(x = 0, y = 0){
154
+ this.x = x;
155
+ this.y = y;
156
+ }
157
+ }
158
+
159
+
160
+ /*
161
+ * Copyright 2020 Adobe. All rights reserved.
162
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
163
+ * you may not use this file except in compliance with the License. You may obtain a copy
164
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
165
+ *
166
+ * Unless required by applicable law or agreed to in writing, software distributed under
167
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
168
+ * OF ANY KIND, either express or implied. See the License for the specific language
169
+ * governing permissions and limitations under the License.
170
+ */
171
+ class $60423f92c7f9ad87$export$c79fc6492f3af13d {
172
+ /**
173
+ * The maximum x-coordinate in the rectangle.
174
+ */ get maxX() {
175
+ return this.x + this.width;
176
+ }
177
+ /**
178
+ * The maximum y-coordinate in the rectangle.
179
+ */ get maxY() {
180
+ return this.y + this.height;
181
+ }
182
+ /**
183
+ * The area of the rectangle.
184
+ */ get area() {
185
+ return this.width * this.height;
186
+ }
187
+ /**
188
+ * The top left corner of the rectangle.
189
+ */ get topLeft() {
190
+ return new (0, $3041db3296945e6e$export$baf26146a414f24a)(this.x, this.y);
191
+ }
192
+ /**
193
+ * The top right corner of the rectangle.
194
+ */ get topRight() {
195
+ return new (0, $3041db3296945e6e$export$baf26146a414f24a)(this.maxX, this.y);
196
+ }
197
+ /**
198
+ * The bottom left corner of the rectangle.
199
+ */ get bottomLeft() {
200
+ return new (0, $3041db3296945e6e$export$baf26146a414f24a)(this.x, this.maxY);
201
+ }
202
+ /**
203
+ * The bottom right corner of the rectangle.
204
+ */ get bottomRight() {
205
+ return new (0, $3041db3296945e6e$export$baf26146a414f24a)(this.maxX, this.maxY);
206
+ }
207
+ /**
208
+ * Returns whether this rectangle intersects another rectangle.
209
+ * @param rect - The rectangle to check.
210
+ */ intersects(rect) {
211
+ return this.x <= rect.x + rect.width && rect.x <= this.x + this.width && this.y <= rect.y + rect.height && rect.y <= this.y + this.height;
212
+ }
213
+ /**
214
+ * Returns whether this rectangle fully contains another rectangle.
215
+ * @param rect - The rectangle to check.
216
+ */ containsRect(rect) {
217
+ return this.x <= rect.x && this.y <= rect.y && this.maxX >= rect.maxX && this.maxY >= rect.maxY;
218
+ }
219
+ /**
220
+ * Returns whether the rectangle contains the given point.
221
+ * @param point - The point to check.
222
+ */ containsPoint(point) {
223
+ return this.x <= point.x && this.y <= point.y && this.maxX >= point.x && this.maxY >= point.y;
224
+ }
225
+ /**
226
+ * Returns the first corner of this rectangle (from top to bottom, left to right)
227
+ * that is contained in the given rectangle, or null of the rectangles do not intersect.
228
+ * @param rect - The rectangle to check.
229
+ */ getCornerInRect(rect) {
230
+ for (let key of [
231
+ "topLeft",
232
+ "topRight",
233
+ "bottomLeft",
234
+ "bottomRight"
235
+ ]){
236
+ if (rect.containsPoint(this[key])) return key;
237
+ }
238
+ return null;
239
+ }
240
+ equals(rect) {
241
+ return rect.x === this.x && rect.y === this.y && rect.width === this.width && rect.height === this.height;
242
+ }
243
+ pointEquals(point) {
244
+ return this.x === point.x && this.y === point.y;
245
+ }
246
+ sizeEquals(size) {
247
+ return this.width === size.width && this.height === size.height;
248
+ }
249
+ /**
250
+ * Returns the union of this Rect and another.
251
+ */ union(other) {
252
+ let x = Math.min(this.x, other.x);
253
+ let y = Math.min(this.y, other.y);
254
+ let width = Math.max(this.maxX, other.maxX) - x;
255
+ let height = Math.max(this.maxY, other.maxY) - y;
256
+ return new $60423f92c7f9ad87$export$c79fc6492f3af13d(x, y, width, height);
257
+ }
258
+ /**
259
+ * Returns the intersection of this Rect with another.
260
+ * If the rectangles do not intersect, an all zero Rect is returned.
261
+ */ intersection(other) {
262
+ if (!this.intersects(other)) return new $60423f92c7f9ad87$export$c79fc6492f3af13d(0, 0, 0, 0);
263
+ let x = Math.max(this.x, other.x);
264
+ let y = Math.max(this.y, other.y);
265
+ return new $60423f92c7f9ad87$export$c79fc6492f3af13d(x, y, Math.min(this.maxX, other.maxX) - x, Math.min(this.maxY, other.maxY) - y);
266
+ }
267
+ /**
268
+ * Returns a copy of this rectangle.
269
+ */ copy() {
270
+ return new $60423f92c7f9ad87$export$c79fc6492f3af13d(this.x, this.y, this.width, this.height);
271
+ }
272
+ constructor(x = 0, y = 0, width = 0, height = 0){
273
+ this.x = x;
274
+ this.y = y;
275
+ this.width = width;
276
+ this.height = height;
277
+ }
278
+ }
279
+
280
+
281
+ /*
282
+ * Copyright 2020 Adobe. All rights reserved.
283
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
284
+ * you may not use this file except in compliance with the License. You may obtain a copy
285
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
286
+ *
287
+ * Unless required by applicable law or agreed to in writing, software distributed under
288
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
289
+ * OF ANY KIND, either express or implied. See the License for the specific language
290
+ * governing permissions and limitations under the License.
291
+ */ class $ee1bfa90a957fb8a$export$cb6da89c6af1a8ec {
292
+ /**
293
+ * Returns a copy of this size.
294
+ */ copy() {
295
+ return new $ee1bfa90a957fb8a$export$cb6da89c6af1a8ec(this.width, this.height);
296
+ }
297
+ /**
298
+ * Returns whether this size is equal to another one.
299
+ */ equals(other) {
300
+ return this.width === other.width && this.height === other.height;
301
+ }
302
+ /**
303
+ * The total area of the Size.
304
+ */ get area() {
305
+ return this.width * this.height;
306
+ }
307
+ constructor(width = 0, height = 0){
308
+ this.width = width;
309
+ this.height = height;
310
+ }
311
+ }
312
+
313
+
314
+ /*
315
+ * Copyright 2020 Adobe. All rights reserved.
316
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
317
+ * you may not use this file except in compliance with the License. You may obtain a copy
318
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
319
+ *
320
+ * Unless required by applicable law or agreed to in writing, software distributed under
321
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
322
+ * OF ANY KIND, either express or implied. See the License for the specific language
323
+ * governing permissions and limitations under the License.
324
+ */ let $ad1d98aa8f0c31b4$var$KEY = 0;
325
+ class $ad1d98aa8f0c31b4$export$1a5223887c560441 {
326
+ /**
327
+ * Prepares the view for reuse. Called just before the view is removed from the DOM.
328
+ */ prepareForReuse() {
329
+ this.content = null;
330
+ this.rendered = null;
331
+ this.layoutInfo = null;
332
+ }
333
+ constructor(virtualizer){
334
+ this.virtualizer = virtualizer;
335
+ this.key = ++$ad1d98aa8f0c31b4$var$KEY;
336
+ }
337
+ }
338
+
339
+
340
+ /*
341
+ * Copyright 2020 Adobe. All rights reserved.
342
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
343
+ * you may not use this file except in compliance with the License. You may obtain a copy
344
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
345
+ *
346
+ * Unless required by applicable law or agreed to in writing, software distributed under
347
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
348
+ * OF ANY KIND, either express or implied. See the License for the specific language
349
+ * governing permissions and limitations under the License.
350
+ */
351
+
352
+
353
+ /*
354
+ * Copyright 2020 Adobe. All rights reserved.
355
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
356
+ * you may not use this file except in compliance with the License. You may obtain a copy
357
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
358
+ *
359
+ * Unless required by applicable law or agreed to in writing, software distributed under
360
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
361
+ * OF ANY KIND, either express or implied. See the License for the specific language
362
+ * governing permissions and limitations under the License.
363
+ */ /*
364
+ * Copyright 2020 Adobe. All rights reserved.
365
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
366
+ * you may not use this file except in compliance with the License. You may obtain a copy
367
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
368
+ *
369
+ * Unless required by applicable law or agreed to in writing, software distributed under
370
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
371
+ * OF ANY KIND, either express or implied. See the License for the specific language
372
+ * governing permissions and limitations under the License.
373
+ */
374
+ // use high res timer if available
375
+ let $3eb131dcf37ad5f8$var$perf = typeof window !== "undefined" ? window.performance : null;
376
+ // @ts-ignore
377
+ let $3eb131dcf37ad5f8$var$perfNow = $3eb131dcf37ad5f8$var$perf && ($3eb131dcf37ad5f8$var$perf.now || $3eb131dcf37ad5f8$var$perf.webkitNow || $3eb131dcf37ad5f8$var$perf.msNow || $3eb131dcf37ad5f8$var$perf.mozNow);
378
+ let $3eb131dcf37ad5f8$var$getTime = $3eb131dcf37ad5f8$var$perfNow ? $3eb131dcf37ad5f8$var$perfNow.bind($3eb131dcf37ad5f8$var$perf) : function() {
379
+ return Date.now ? Date.now() : new Date().getTime();
380
+ };
381
+ let $3eb131dcf37ad5f8$var$fixTs;
382
+ function $3eb131dcf37ad5f8$export$dc0b63720788090c(begin, end, duration, ease, fn) {
383
+ let canceled = false;
384
+ let raf_id;
385
+ let promise = new Promise((resolve)=>{
386
+ let start = $3eb131dcf37ad5f8$var$getTime();
387
+ let diffX = end.x - begin.x;
388
+ let diffY = end.y - begin.y;
389
+ raf_id = requestAnimationFrame(function run(t) {
390
+ // if we're using a high res timer, make sure timestamp is not the old epoch-based value.
391
+ // http://updates.html5rocks.com/2012/05/requestAnimationFrame-API-now-with-sub-millisecond-precision
392
+ if ($3eb131dcf37ad5f8$var$fixTs == null) $3eb131dcf37ad5f8$var$fixTs = t > 1e12 !== $3eb131dcf37ad5f8$var$getTime() > 1e12;
393
+ if ($3eb131dcf37ad5f8$var$fixTs) t = $3eb131dcf37ad5f8$var$getTime();
394
+ // check if we're done
395
+ let delta = t - start;
396
+ if (delta > duration) {
397
+ fn(end);
398
+ resolve();
399
+ } else {
400
+ // call frame callback after computing eased time and get the next frame
401
+ let proceed = fn(new (0, $3041db3296945e6e$export$baf26146a414f24a)(begin.x + diffX * ease(delta / duration), begin.y + diffY * ease(delta / duration)));
402
+ if (proceed !== false && !canceled) raf_id = requestAnimationFrame(run);
403
+ }
404
+ });
405
+ });
406
+ promise.cancel = function() {
407
+ canceled = true;
408
+ cancelAnimationFrame(raf_id);
409
+ };
410
+ return promise;
411
+ }
412
+ function $3eb131dcf37ad5f8$export$77860c106b4a6a2e(t) {
413
+ return t;
414
+ }
415
+ function $3eb131dcf37ad5f8$export$57636bb43b1ccbb0(t) {
416
+ return Math.sin(t * Math.PI / 2);
417
+ }
418
+
419
+
420
+ /*
421
+ * Copyright 2020 Adobe. All rights reserved.
422
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
423
+ * you may not use this file except in compliance with the License. You may obtain a copy
424
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
425
+ *
426
+ * Unless required by applicable law or agreed to in writing, software distributed under
427
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
428
+ * OF ANY KIND, either express or implied. See the License for the specific language
429
+ * governing permissions and limitations under the License.
430
+ */ function $fc36f9a046a9ce79$export$37a26b283fd7740e(a, b) {
431
+ let res = new Set();
432
+ for (let key of a.keys())if (!b.has(key)) res.add(key);
433
+ return res;
434
+ }
435
+ function $fc36f9a046a9ce79$export$acaf96a27438246b(a, b) {
436
+ let toRemove = $fc36f9a046a9ce79$export$37a26b283fd7740e(a, b);
437
+ let toAdd = $fc36f9a046a9ce79$export$37a26b283fd7740e(b, a);
438
+ let toUpdate = new Set;
439
+ for (let key of a.keys())if (b.has(key)) toUpdate.add(key);
440
+ return {
441
+ toRemove: toRemove,
442
+ toAdd: toAdd,
443
+ toUpdate: toUpdate
444
+ };
445
+ }
446
+ function* $fc36f9a046a9ce79$export$cfc14088dfefce5f(...iterators) {
447
+ for (let iterator of iterators)yield* iterator;
448
+ }
449
+ function $fc36f9a046a9ce79$export$6897c284b6f9f4dc(object) {
450
+ let res = {};
451
+ for(let key in object)res[object[key]] = key;
452
+ return res;
453
+ }
454
+ function $fc36f9a046a9ce79$export$a8d0d0c8d1c5df64(a, b) {
455
+ if (a === b) return true;
456
+ if (a.size !== b.size) return false;
457
+ for (let key of a){
458
+ if (!b.has(key)) return false;
459
+ }
460
+ return true;
461
+ }
462
+
463
+
464
+ /*
465
+ * Copyright 2020 Adobe. All rights reserved.
466
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
467
+ * you may not use this file except in compliance with the License. You may obtain a copy
468
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
469
+ *
470
+ * Unless required by applicable law or agreed to in writing, software distributed under
471
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
472
+ * OF ANY KIND, either express or implied. See the License for the specific language
473
+ * governing permissions and limitations under the License.
474
+ */
475
+
476
+
477
+ class $364191b3decf3697$var$RollingAverage {
478
+ addSample(sample) {
479
+ this.count++;
480
+ this.value += (sample - this.value) / this.count;
481
+ }
482
+ constructor(){
483
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "count", 0);
484
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "value", 0);
485
+ }
486
+ }
487
+ class $364191b3decf3697$export$4455ee6afb38dcbb {
488
+ setVisibleRect(rect) {
489
+ let time = performance.now() - this.startTime;
490
+ if (time < 500) {
491
+ this.averageTime.addSample(time);
492
+ if (rect.x !== this.visibleRect.x && time > 0) this.velocity.x = (rect.x - this.visibleRect.x) / time;
493
+ if (rect.y !== this.visibleRect.y && time > 0) this.velocity.y = (rect.y - this.visibleRect.y) / time;
494
+ }
495
+ this.startTime = performance.now();
496
+ this.visibleRect = rect;
497
+ }
498
+ collectMetrics() {
499
+ let time = performance.now() - this.startTime;
500
+ if (time < 500) this.averagePerf.addSample(time);
501
+ if (this.visibleRect.height > 0) {
502
+ let o = Math.abs(this.velocity.y * (this.averageTime.value + this.averagePerf.value));
503
+ this.overscanY.addSample(o);
504
+ }
505
+ if (this.visibleRect.width > 0) {
506
+ let o1 = Math.abs(this.velocity.x * (this.averageTime.value + this.averagePerf.value));
507
+ this.overscanX.addSample(o1);
508
+ }
509
+ }
510
+ getOverscannedRect() {
511
+ let overscanned = this.visibleRect.copy();
512
+ let overscanY = Math.round(Math.min(this.visibleRect.height * 2, this.overscanY.value) / 100) * 100;
513
+ if (this.velocity.y > 0) {
514
+ overscanned.y -= overscanY * 0.2;
515
+ overscanned.height += overscanY + overscanY * 0.2;
516
+ } else {
517
+ overscanned.y -= overscanY;
518
+ overscanned.height += overscanY + overscanY * 0.2;
519
+ }
520
+ let overscanX = Math.round(Math.min(this.visibleRect.width * 2, this.overscanX.value) / 100) * 100;
521
+ if (this.velocity.x > 0) {
522
+ overscanned.x -= overscanX * 0.2;
523
+ overscanned.width += overscanX + overscanX * 0.2;
524
+ } else {
525
+ overscanned.x -= overscanX;
526
+ overscanned.width += overscanX + overscanX * 0.2;
527
+ }
528
+ return overscanned;
529
+ }
530
+ constructor(){
531
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "startTime", 0);
532
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "averagePerf", new $364191b3decf3697$var$RollingAverage());
533
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "averageTime", new $364191b3decf3697$var$RollingAverage());
534
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "velocity", new (0, $3041db3296945e6e$export$baf26146a414f24a)(5, 5));
535
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "overscanX", new $364191b3decf3697$var$RollingAverage());
536
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "overscanY", new $364191b3decf3697$var$RollingAverage());
537
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "visibleRect", new (0, $60423f92c7f9ad87$export$c79fc6492f3af13d)());
538
+ }
539
+ }
540
+
541
+
542
+
543
+
544
+
545
+
546
+ /*
547
+ * Copyright 2020 Adobe. All rights reserved.
548
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
549
+ * you may not use this file except in compliance with the License. You may obtain a copy
550
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
551
+ *
552
+ * Unless required by applicable law or agreed to in writing, software distributed under
553
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
554
+ * OF ANY KIND, either express or implied. See the License for the specific language
555
+ * governing permissions and limitations under the License.
556
+ */
557
+ class $8e135e531d8dcb66$export$febc5573c75cefb0 {
558
+ constructor(){
559
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "level", 0);
560
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "actions", []);
561
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "animated", true);
562
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "initialMap", new Map());
563
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "finalMap", new Map());
564
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "initialLayoutInfo", new Map());
565
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "finalLayoutInfo", new Map());
566
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "removed", new Map());
567
+ (0, $8D3nr$swchelperssrc_define_propertymjs)(this, "toRemove", new Map());
568
+ }
569
+ }
570
+
571
+
572
+ class $38b9490c1cca8fc4$export$89be5a243e59c4b2 {
573
+ _setContentSize(size) {
574
+ this._contentSize = size;
575
+ this.delegate.setContentSize(size);
576
+ }
577
+ _setContentOffset(offset) {
578
+ let rect = new (0, $60423f92c7f9ad87$export$c79fc6492f3af13d)(offset.x, offset.y, this._visibleRect.width, this._visibleRect.height);
579
+ this.delegate.setVisibleRect(rect);
580
+ }
581
+ /**
582
+ * Get the size of the scrollable content.
583
+ */ get contentSize() {
584
+ return this._contentSize;
585
+ }
586
+ /**
587
+ * Get the collection view's currently visible rectangle.
588
+ */ get visibleRect() {
589
+ return this._visibleRect;
590
+ }
591
+ /**
592
+ * Set the collection view's currently visible rectangle.
593
+ */ set visibleRect(rect) {
594
+ this._setVisibleRect(rect);
595
+ }
596
+ _setVisibleRect(rect, forceUpdate = false) {
597
+ let current = this._visibleRect;
598
+ // Ignore if the rects are equal
599
+ if (rect.equals(current)) return;
600
+ if (this.shouldOverscan) this._overscanManager.setVisibleRect(rect);
601
+ let shouldInvalidate = this.layout && this.layout.shouldInvalidate(rect, this._visibleRect);
602
+ this._resetAnimatedContentOffset();
603
+ this._visibleRect = rect;
604
+ if (shouldInvalidate) this.relayout({
605
+ offsetChanged: !rect.pointEquals(current),
606
+ sizeChanged: !rect.sizeEquals(current)
607
+ });
608
+ else this.updateSubviews(forceUpdate);
609
+ }
610
+ get collection() {
611
+ return this._collection;
612
+ }
613
+ set collection(data) {
614
+ this._setData(data);
615
+ }
616
+ _setData(data) {
617
+ if (data === this._collection) return;
618
+ if (this._collection) this._runTransaction(()=>{
619
+ this._collection = data;
620
+ }, this.transitionDuration > 0);
621
+ else {
622
+ this._collection = data;
623
+ this.reloadData();
624
+ }
625
+ }
626
+ /**
627
+ * Reloads the data from the data source and relayouts the collection view.
628
+ * Does not animate any changes. Equivalent to re-assigning the same data source
629
+ * to the collection view.
630
+ */ reloadData() {
631
+ this.relayout({
632
+ contentChanged: true
633
+ });
634
+ }
635
+ /**
636
+ * Returns the item with the given key.
637
+ */ getItem(key) {
638
+ return this._collection ? this._collection.getItem(key) : null;
639
+ }
640
+ /** The set of persisted keys are always present in the DOM, even if not currently in view. */ get persistedKeys() {
641
+ return this._persistedKeys;
642
+ }
643
+ /** The set of persisted keys are always present in the DOM, even if not currently in view. */ set persistedKeys(persistedKeys) {
644
+ if (!(0, $fc36f9a046a9ce79$export$a8d0d0c8d1c5df64)(persistedKeys, this._persistedKeys)) {
645
+ this._persistedKeys = persistedKeys;
646
+ this.updateSubviews();
647
+ }
648
+ }
649
+ /** Returns whether the given key, or an ancestor, is persisted. */ isPersistedKey(key) {
650
+ // Quick check if the key is directly in the set of persisted keys.
651
+ if (this._persistedKeys.has(key)) return true;
652
+ // If not, check if the key is an ancestor of any of the persisted keys.
653
+ for (let k of this._persistedKeys)while(k != null){
654
+ let layoutInfo = this.layout.getLayoutInfo(k);
655
+ if (!layoutInfo) break;
656
+ k = layoutInfo.parentKey;
657
+ if (k === key) return true;
658
+ }
659
+ return false;
660
+ }
661
+ /**
662
+ * Get the collection view's layout.
663
+ */ get layout() {
664
+ return this._layout;
665
+ }
666
+ /**
667
+ * Set the collection view's layout.
668
+ */ set layout(layout) {
669
+ this.setLayout(layout);
670
+ }
671
+ /**
672
+ * Sets the collection view's layout, optionally with an animated transition
673
+ * from the current layout to the new layout.
674
+ * @param layout The layout to switch to.
675
+ * @param animated Whether to animate the layout change.
676
+ */ setLayout(layout, animated = false) {
677
+ if (layout === this._layout) return;
678
+ let applyLayout = ()=>{
679
+ if (this._layout) // @ts-ignore
680
+ this._layout.virtualizer = null;
681
+ layout.virtualizer = this;
682
+ this._layout = layout;
683
+ };
684
+ if (animated) // Animated layout transitions are really simple, thanks to our transaction support.
685
+ // We just set the layout inside a transaction action, which runs after the initial
686
+ // layout infos for the animation are retrieved from the previous layout. Then, the
687
+ // final layout infos are retrieved from the new layout, and animations occur.
688
+ this._runTransaction(applyLayout);
689
+ else {
690
+ applyLayout();
691
+ this.relayout();
692
+ }
693
+ }
694
+ _getReuseType(layoutInfo, content) {
695
+ if (layoutInfo.type === "item" && content) {
696
+ let type = this.delegate.getType ? this.delegate.getType(content) : "item";
697
+ let reuseType = type === "item" ? "item" : layoutInfo.type + "_" + type;
698
+ return {
699
+ type: type,
700
+ reuseType: reuseType
701
+ };
702
+ }
703
+ return {
704
+ type: layoutInfo.type,
705
+ reuseType: layoutInfo.type
706
+ };
707
+ }
708
+ getReusableView(layoutInfo) {
709
+ let content = this.getItem(layoutInfo.key);
710
+ let { reuseType: reuseType } = this._getReuseType(layoutInfo, content);
711
+ if (!this._reusableViews[reuseType]) this._reusableViews[reuseType] = [];
712
+ let reusable = this._reusableViews[reuseType];
713
+ let view = reusable.length > 0 ? reusable.pop() : new (0, $ad1d98aa8f0c31b4$export$1a5223887c560441)(this);
714
+ view.viewType = reuseType;
715
+ if (!this._animatedContentOffset.isOrigin()) {
716
+ layoutInfo = layoutInfo.copy();
717
+ layoutInfo.rect.x += this._animatedContentOffset.x;
718
+ layoutInfo.rect.y += this._animatedContentOffset.y;
719
+ }
720
+ view.layoutInfo = layoutInfo;
721
+ this._renderView(view);
722
+ return view;
723
+ }
724
+ _renderView(reusableView) {
725
+ let { type: type , key: key } = reusableView.layoutInfo;
726
+ reusableView.content = this.getItem(key);
727
+ reusableView.rendered = this._renderContent(type, reusableView.content);
728
+ }
729
+ _renderContent(type, content) {
730
+ let cached = this._renderedContent.get(content);
731
+ if (cached != null) return cached;
732
+ let rendered = this.delegate.renderView(type, content);
733
+ if (content) this._renderedContent.set(content, rendered);
734
+ return rendered;
735
+ }
736
+ /**
737
+ * Returns an array of all currently visible views, including both
738
+ * item views and supplementary views.
739
+ */ get visibleViews() {
740
+ return Array.from(this._visibleViews.values());
741
+ }
742
+ /**
743
+ * Gets the visible view for the given type and key. Returns null if
744
+ * the view is not currently visible.
745
+ *
746
+ * @param key The key of the view to retrieve.
747
+ */ getView(key) {
748
+ return this._visibleViews.get(key) || null;
749
+ }
750
+ /**
751
+ * Returns an array of visible views matching the given type.
752
+ * @param type The view type to find.
753
+ */ getViewsOfType(type) {
754
+ return this.visibleViews.filter((v)=>v.layoutInfo && v.layoutInfo.type === type);
755
+ }
756
+ /**
757
+ * Returns the key for the given view. Returns null
758
+ * if the view is not currently visible.
759
+ */ keyForView(view) {
760
+ if (view && view.layoutInfo) return view.layoutInfo.key;
761
+ return null;
762
+ }
763
+ /**
764
+ * Returns the key for the item view currently at the given point.
765
+ */ keyAtPoint(point) {
766
+ let rect = new (0, $60423f92c7f9ad87$export$c79fc6492f3af13d)(point.x, point.y, 1, 1);
767
+ let layoutInfos = this.layout.getVisibleLayoutInfos(rect);
768
+ // Layout may return multiple layout infos in the case of
769
+ // persisted keys, so find the first one that actually intersects.
770
+ for (let layoutInfo of layoutInfos){
771
+ if (layoutInfo.rect.intersects(rect)) return layoutInfo.key;
772
+ }
773
+ return null;
774
+ }
775
+ /**
776
+ * Cleanup for when the Virtualizer will be unmounted.
777
+ */ willUnmount() {
778
+ cancelAnimationFrame(this._relayoutRaf);
779
+ }
780
+ /**
781
+ * Triggers a layout invalidation, and updates the visible subviews.
782
+ */ relayout(context = {}) {
783
+ // Ignore relayouts while animating the scroll position
784
+ if (this._scrollAnimation || typeof requestAnimationFrame === "undefined") return;
785
+ // If we already scheduled a relayout, extend the invalidation
786
+ // context so we coalesce multiple relayouts in the same frame.
787
+ if (this._invalidationContext) {
788
+ Object.assign(this._invalidationContext, context);
789
+ return;
790
+ }
791
+ this._invalidationContext = context;
792
+ this._relayoutRaf = requestAnimationFrame(()=>{
793
+ this._relayoutRaf = null;
794
+ this.relayoutNow();
795
+ });
796
+ }
797
+ /**
798
+ * Performs a relayout immediately. Prefer {@link relayout} over this method
799
+ * where possible, since it coalesces multiple layout passes in the same tick.
800
+ */ relayoutNow(context = this._invalidationContext || {}) {
801
+ // Cancel the scheduled relayout, since we're doing it now.
802
+ if (this._relayoutRaf) {
803
+ cancelAnimationFrame(this._relayoutRaf);
804
+ this._relayoutRaf = null;
805
+ // Update the provided context with the current invalidationContext since we are cancelling
806
+ // a scheduled relayoutNow call that has this._invalidationContext set as its default context arg (relayoutNow() in relayout)
807
+ context = {
808
+ ...this._invalidationContext,
809
+ ...context
810
+ };
811
+ }
812
+ // Reset the invalidation context
813
+ this._invalidationContext = null;
814
+ // Do nothing if we don't have a layout or content, or we are
815
+ // in the middle of an animated scroll transition.
816
+ if (!this.layout || !this._collection || this._scrollAnimation) return;
817
+ let scrollAnchor = this._getScrollAnchor();
818
+ // Trigger the beforeLayout hook, if provided
819
+ if (typeof context.beforeLayout === "function") context.beforeLayout();
820
+ // Validate the layout
821
+ this.layout.validate(context);
822
+ this._setContentSize(this.layout.getContentSize());
823
+ // Trigger the afterLayout hook, if provided
824
+ if (typeof context.afterLayout === "function") context.afterLayout();
825
+ // Adjust scroll position based on scroll anchor, and constrain.
826
+ // If the content changed, scroll to the top.
827
+ let visibleRect = this.getVisibleRect();
828
+ let restoredScrollAnchor = this._restoreScrollAnchor(scrollAnchor, context);
829
+ let contentOffsetX = context.contentChanged ? 0 : restoredScrollAnchor.x;
830
+ let contentOffsetY = context.contentChanged ? 0 : restoredScrollAnchor.y;
831
+ contentOffsetX = Math.max(0, Math.min(this.contentSize.width - visibleRect.width, contentOffsetX));
832
+ contentOffsetY = Math.max(0, Math.min(this.contentSize.height - visibleRect.height, contentOffsetY));
833
+ let hasLayoutUpdates = false;
834
+ if (contentOffsetX !== visibleRect.x || contentOffsetY !== visibleRect.y) {
835
+ // If this is an animated relayout, we do not immediately scroll because it would be jittery.
836
+ // Save the difference between the current and new content offsets, and apply it to the
837
+ // individual content items instead. At the end of the animation, we'll reset and set the
838
+ // scroll offset for real. This ensures jitter-free animation since we don't need to sync
839
+ // the scroll animation and the content animation.
840
+ if (context.animated || !this._animatedContentOffset.isOrigin()) {
841
+ this._animatedContentOffset.x += visibleRect.x - contentOffsetX;
842
+ this._animatedContentOffset.y += visibleRect.y - contentOffsetY;
843
+ hasLayoutUpdates = this.updateSubviews(context.contentChanged);
844
+ } else this._setContentOffset(new (0, $3041db3296945e6e$export$baf26146a414f24a)(contentOffsetX, contentOffsetY));
845
+ } else hasLayoutUpdates = this.updateSubviews(context.contentChanged);
846
+ // Apply layout infos, unless this is coming from an animated transaction
847
+ if (!(context.transaction && context.animated)) this._applyLayoutInfos();
848
+ // Wait for animations, and apply the afterAnimation hook, if provided
849
+ if (context.animated && hasLayoutUpdates) {
850
+ this._enableTransitions();
851
+ let done = ()=>{
852
+ this._disableTransitions();
853
+ // Reset scroll position after animations (see above comment).
854
+ if (!this._animatedContentOffset.isOrigin()) {
855
+ // Get the content offset to scroll to, taking _animatedContentOffset into account.
856
+ let { x: x , y: y } = this.getVisibleRect();
857
+ this._resetAnimatedContentOffset();
858
+ this._setContentOffset(new (0, $3041db3296945e6e$export$baf26146a414f24a)(x, y));
859
+ }
860
+ if (typeof context.afterAnimation === "function") context.afterAnimation();
861
+ };
862
+ // Sometimes the animation takes slightly longer than expected.
863
+ setTimeout(done, this.transitionDuration + 100);
864
+ return;
865
+ } else if (typeof context.afterAnimation === "function") context.afterAnimation();
866
+ }
867
+ /**
868
+ * Corrects DOM order of visible views to match item order of collection.
869
+ */ _correctItemOrder() {
870
+ // Defer until after scrolling and animated transactions are complete
871
+ if (this._isScrolling || this._transaction) return;
872
+ for (let key of this._visibleLayoutInfos.keys()){
873
+ let view = this._visibleViews.get(key);
874
+ this._children.delete(view);
875
+ this._children.add(view);
876
+ }
877
+ }
878
+ _enableTransitions() {
879
+ this.delegate.beginAnimations();
880
+ }
881
+ _disableTransitions() {
882
+ this.delegate.endAnimations();
883
+ }
884
+ _getScrollAnchor() {
885
+ if (!this.anchorScrollPosition) return null;
886
+ let visibleRect = this.getVisibleRect();
887
+ // Ask the delegate to provide a scroll anchor, if possible
888
+ if (this.delegate.getScrollAnchor) {
889
+ let key = this.delegate.getScrollAnchor(visibleRect);
890
+ if (key != null) {
891
+ let layoutInfo = this.layout.getLayoutInfo(key);
892
+ let corner = layoutInfo.rect.getCornerInRect(visibleRect);
893
+ if (corner) {
894
+ let key1 = layoutInfo.key;
895
+ let offset = layoutInfo.rect[corner].y - visibleRect.y;
896
+ return {
897
+ key: key1,
898
+ layoutInfo: layoutInfo,
899
+ corner: corner,
900
+ offset: offset
901
+ };
902
+ }
903
+ }
904
+ }
905
+ // No need to anchor the scroll position if it is at the top
906
+ if (visibleRect.y === 0 && !this.anchorScrollPositionAtTop) return null;
907
+ // Find a view with a visible corner that has the smallest distance to the top of the collection view
908
+ let cornerAnchor = null;
909
+ for (let [key2, view] of this._visibleViews){
910
+ let layoutInfo1 = view.layoutInfo;
911
+ if (layoutInfo1 && layoutInfo1.rect.area > 0) {
912
+ let corner1 = layoutInfo1.rect.getCornerInRect(visibleRect);
913
+ if (corner1) {
914
+ let offset1 = layoutInfo1.rect[corner1].y - visibleRect.y;
915
+ if (!cornerAnchor || offset1 < cornerAnchor.offset) cornerAnchor = {
916
+ key: key2,
917
+ layoutInfo: layoutInfo1,
918
+ corner: corner1,
919
+ offset: offset1
920
+ };
921
+ }
922
+ }
923
+ }
924
+ return cornerAnchor;
925
+ }
926
+ _restoreScrollAnchor(scrollAnchor, context) {
927
+ let contentOffset = this.getVisibleRect();
928
+ if (scrollAnchor) {
929
+ var _context_transaction;
930
+ let finalAnchor = ((_context_transaction = context.transaction) === null || _context_transaction === void 0 ? void 0 : _context_transaction.animated) ? context.transaction.finalMap.get(scrollAnchor.key) : this.layout.getLayoutInfo(scrollAnchor.layoutInfo.key);
931
+ if (finalAnchor) {
932
+ let adjustment = finalAnchor.rect[scrollAnchor.corner].y - contentOffset.y - scrollAnchor.offset;
933
+ contentOffset.y += adjustment;
934
+ }
935
+ }
936
+ return contentOffset;
937
+ }
938
+ getVisibleRect() {
939
+ let v = this.visibleRect;
940
+ let x = v.x - this._animatedContentOffset.x;
941
+ let y = v.y - this._animatedContentOffset.y;
942
+ return new (0, $60423f92c7f9ad87$export$c79fc6492f3af13d)(x, y, v.width, v.height);
943
+ }
944
+ getVisibleLayoutInfos() {
945
+ let rect = this.shouldOverscan ? this._overscanManager.getOverscannedRect() : this.getVisibleRect();
946
+ this._visibleLayoutInfos = this._getLayoutInfoMap(rect);
947
+ return this._visibleLayoutInfos;
948
+ }
949
+ _getLayoutInfoMap(rect, copy = false) {
950
+ let layoutInfos = this.layout.getVisibleLayoutInfos(rect);
951
+ let map = new Map;
952
+ for (let layoutInfo of layoutInfos){
953
+ if (copy) layoutInfo = layoutInfo.copy();
954
+ map.set(layoutInfo.key, layoutInfo);
955
+ }
956
+ return map;
957
+ }
958
+ updateSubviews(forceUpdate = false) {
959
+ if (!this._collection) return;
960
+ let visibleLayoutInfos = this.getVisibleLayoutInfos();
961
+ let currentlyVisible = this._visibleViews;
962
+ let toAdd, toRemove, toUpdate;
963
+ // If this is a force update, remove and re-add all views.
964
+ // Otherwise, find and update the diff.
965
+ if (forceUpdate) {
966
+ toAdd = visibleLayoutInfos;
967
+ toRemove = currentlyVisible;
968
+ toUpdate = new Set();
969
+ } else {
970
+ ({ toAdd: toAdd , toRemove: toRemove , toUpdate: toUpdate } = (0, $fc36f9a046a9ce79$export$acaf96a27438246b)(currentlyVisible, visibleLayoutInfos));
971
+ for (let key of toUpdate){
972
+ let view = currentlyVisible.get(key);
973
+ if (!view || !view.layoutInfo) continue;
974
+ let item = this.getItem(visibleLayoutInfos.get(key).key);
975
+ if (view.content === item) toUpdate.delete(key);
976
+ else {
977
+ // If the view type changes, delete and recreate the view instead of updating
978
+ let { reuseType: reuseType } = this._getReuseType(view.layoutInfo, item);
979
+ if (view.viewType !== reuseType) {
980
+ toUpdate.delete(key);
981
+ toAdd.add(key);
982
+ toRemove.add(key);
983
+ }
984
+ }
985
+ }
986
+ // We are done if the sets are equal
987
+ if (toAdd.size === 0 && toRemove.size === 0 && toUpdate.size === 0) {
988
+ if (this._transaction) this._applyLayoutInfos();
989
+ return;
990
+ }
991
+ }
992
+ // Track views that should be removed. They are not removed from
993
+ // the DOM immediately, since we may reuse and need to re-insert
994
+ // them back into the DOM anyway.
995
+ let removed = new Set();
996
+ for (let key1 of toRemove.keys()){
997
+ let view1 = this._visibleViews.get(key1);
998
+ if (view1) {
999
+ removed.add(view1);
1000
+ this._visibleViews.delete(key1);
1001
+ // If we are in the middle of a transaction, wait until the end
1002
+ // of the animations to remove the views from the DOM. Also means
1003
+ // we can't reuse those views immediately.
1004
+ if (this._transaction) this._transaction.toRemove.set(key1, view1);
1005
+ else this.reuseView(view1);
1006
+ }
1007
+ }
1008
+ for (let key2 of toAdd.keys()){
1009
+ let layoutInfo = visibleLayoutInfos.get(key2);
1010
+ let view2;
1011
+ // If we're in a transaction, and a layout change happens
1012
+ // during the animations such that a view that was going
1013
+ // to be removed is now not, we don't create a new view
1014
+ // since the old one is still in the DOM, marked as toRemove.
1015
+ if (this._transaction) {
1016
+ // if transaction, get initial layout attributes for the animation
1017
+ if (this._transaction.initialLayoutInfo.has(key2)) layoutInfo = this._transaction.initialLayoutInfo.get(key2);
1018
+ view2 = this._transaction.toRemove.get(key2);
1019
+ if (view2) {
1020
+ this._transaction.toRemove.delete(key2);
1021
+ this._applyLayoutInfo(view2, layoutInfo);
1022
+ }
1023
+ }
1024
+ if (!view2) {
1025
+ // Create or reuse a view for this row
1026
+ view2 = this.getReusableView(layoutInfo);
1027
+ // Add the view to the DOM if needed
1028
+ if (!removed.has(view2)) this._children.add(view2);
1029
+ }
1030
+ this._visibleViews.set(key2, view2);
1031
+ removed.delete(view2);
1032
+ }
1033
+ for (let key3 of toUpdate){
1034
+ let view3 = currentlyVisible.get(key3);
1035
+ this._renderedContent.delete(key3);
1036
+ this._renderView(view3);
1037
+ }
1038
+ // Remove the remaining rows to delete from the DOM
1039
+ if (!this._transaction) this.removeViews(removed);
1040
+ this._correctItemOrder();
1041
+ this._flushVisibleViews();
1042
+ let hasLayoutUpdates = this._transaction && (toAdd.size > 0 || toRemove.size > 0 || this._hasLayoutUpdates());
1043
+ if (hasLayoutUpdates) requestAnimationFrame(()=>{
1044
+ // If we're in a transaction, apply animations to visible views
1045
+ // and "to be removed" views, which animate off screen.
1046
+ if (this._transaction) requestAnimationFrame(()=>this._applyLayoutInfos());
1047
+ });
1048
+ return hasLayoutUpdates;
1049
+ }
1050
+ afterRender() {
1051
+ if (this.shouldOverscan) this._overscanManager.collectMetrics();
1052
+ }
1053
+ _flushVisibleViews() {
1054
+ // CollectionVirtualizer deals with a flattened set of LayoutInfos, but they can represent heirarchy
1055
+ // by referencing a parentKey. Just before rendering the visible views, we rebuild this heirarchy
1056
+ // by creating a mapping of views by parent key and recursively calling the delegate's renderWrapper
1057
+ // method to build the final tree.
1058
+ let viewsByParentKey = new Map([
1059
+ [
1060
+ null,
1061
+ []
1062
+ ]
1063
+ ]);
1064
+ for (let view of this._children){
1065
+ var _view_layoutInfo, _viewsByParentKey_get, _view_layoutInfo1, _view_layoutInfo2, _view_layoutInfo3;
1066
+ if (((_view_layoutInfo = view.layoutInfo) === null || _view_layoutInfo === void 0 ? void 0 : _view_layoutInfo.parentKey) != null && !viewsByParentKey.has(view.layoutInfo.parentKey)) viewsByParentKey.set(view.layoutInfo.parentKey, []);
1067
+ (_viewsByParentKey_get = viewsByParentKey.get((_view_layoutInfo1 = view.layoutInfo) === null || _view_layoutInfo1 === void 0 ? void 0 : _view_layoutInfo1.parentKey)) === null || _viewsByParentKey_get === void 0 ? void 0 : _viewsByParentKey_get.push(view);
1068
+ if (!viewsByParentKey.has((_view_layoutInfo2 = view.layoutInfo) === null || _view_layoutInfo2 === void 0 ? void 0 : _view_layoutInfo2.key)) viewsByParentKey.set((_view_layoutInfo3 = view.layoutInfo) === null || _view_layoutInfo3 === void 0 ? void 0 : _view_layoutInfo3.key, []);
1069
+ }
1070
+ let buildTree = (parent, views)=>views.map((view)=>{
1071
+ let children = viewsByParentKey.get(view.layoutInfo.key);
1072
+ return this.delegate.renderWrapper(parent, view, children, (childViews)=>buildTree(view, childViews));
1073
+ });
1074
+ let children = buildTree(null, viewsByParentKey.get(null));
1075
+ this.delegate.setVisibleViews(children);
1076
+ }
1077
+ _applyLayoutInfo(view, layoutInfo) {
1078
+ if (view.layoutInfo === layoutInfo) return false;
1079
+ view.layoutInfo = layoutInfo;
1080
+ return true;
1081
+ }
1082
+ _applyLayoutInfos() {
1083
+ let updated = false;
1084
+ // Apply layout infos to visible views
1085
+ for (let view of this._visibleViews.values()){
1086
+ let cur = view.layoutInfo;
1087
+ if ((cur === null || cur === void 0 ? void 0 : cur.key) != null) {
1088
+ let layoutInfo = this.layout.getLayoutInfo(cur.key);
1089
+ if (this._applyLayoutInfo(view, layoutInfo)) updated = true;
1090
+ }
1091
+ }
1092
+ // Apply final layout infos for views that will be removed
1093
+ if (this._transaction) {
1094
+ for (let view1 of this._transaction.toRemove.values()){
1095
+ let cur1 = view1.layoutInfo;
1096
+ if ((cur1 === null || cur1 === void 0 ? void 0 : cur1.key) != null) {
1097
+ let layoutInfo1 = this.layout.getLayoutInfo(cur1.key);
1098
+ if (this._applyLayoutInfo(view1, layoutInfo1)) updated = true;
1099
+ }
1100
+ }
1101
+ for (let view2 of this._transaction.removed.values()){
1102
+ let cur2 = view2.layoutInfo;
1103
+ let layoutInfo2 = this._transaction.finalLayoutInfo.get(cur2.key) || cur2;
1104
+ layoutInfo2 = this.layout.getFinalLayoutInfo(layoutInfo2.copy());
1105
+ if (this._applyLayoutInfo(view2, layoutInfo2)) updated = true;
1106
+ }
1107
+ }
1108
+ if (updated) this._flushVisibleViews();
1109
+ }
1110
+ _hasLayoutUpdates() {
1111
+ if (!this._transaction) return false;
1112
+ for (let view of this._visibleViews.values()){
1113
+ let cur = view.layoutInfo;
1114
+ if (!cur) return true;
1115
+ let layoutInfo = this.layout.getLayoutInfo(cur.key);
1116
+ if (// Uses equals rather than pointEquals so that width/height changes are taken into account
1117
+ !cur.rect.equals(layoutInfo.rect) || cur.opacity !== layoutInfo.opacity || cur.transform !== layoutInfo.transform) return true;
1118
+ }
1119
+ return false;
1120
+ }
1121
+ reuseView(view) {
1122
+ view.prepareForReuse();
1123
+ this._reusableViews[view.viewType].push(view);
1124
+ }
1125
+ removeViews(toRemove) {
1126
+ for (let view of toRemove)this._children.delete(view);
1127
+ }
1128
+ updateItemSize(key, size) {
1129
+ // TODO: we should be able to invalidate a single index path
1130
+ // @ts-ignore
1131
+ if (!this.layout.updateItemSize) return;
1132
+ // If the scroll position is currently animating, add the update
1133
+ // to a queue to be processed after the animation is complete.
1134
+ if (this._scrollAnimation) {
1135
+ this._sizeUpdateQueue.set(key, size);
1136
+ return;
1137
+ }
1138
+ // @ts-ignore
1139
+ let changed = this.layout.updateItemSize(key, size);
1140
+ if (changed) this.relayout();
1141
+ }
1142
+ startScrolling() {
1143
+ this._isScrolling = true;
1144
+ }
1145
+ endScrolling() {
1146
+ this._isScrolling = false;
1147
+ this._correctItemOrder();
1148
+ this._flushVisibleViews();
1149
+ }
1150
+ _resetAnimatedContentOffset() {
1151
+ // Reset the animated content offset of subviews. See comment in relayoutNow for details.
1152
+ if (!this._animatedContentOffset.isOrigin()) {
1153
+ this._animatedContentOffset = new (0, $3041db3296945e6e$export$baf26146a414f24a)(0, 0);
1154
+ this._applyLayoutInfos();
1155
+ }
1156
+ }
1157
+ /**
1158
+ * Scrolls the item with the given key into view, optionally with an animation.
1159
+ * @param key The key of the item to scroll into view.
1160
+ * @param duration The duration of the scroll animation.
1161
+ */ scrollToItem(key, options) {
1162
+ // key can be 0, so check if null or undefined
1163
+ if (key == null) return;
1164
+ let layoutInfo = this.layout.getLayoutInfo(key);
1165
+ if (!layoutInfo) return;
1166
+ let { duration: duration = 300 , shouldScrollX: shouldScrollX = true , shouldScrollY: shouldScrollY = true , offsetX: offsetX = 0 , offsetY: offsetY = 0 } = options;
1167
+ let x = this.visibleRect.x;
1168
+ let y = this.visibleRect.y;
1169
+ let minX = layoutInfo.rect.x - offsetX;
1170
+ let minY = layoutInfo.rect.y - offsetY;
1171
+ let maxX = x + this.visibleRect.width;
1172
+ let maxY = y + this.visibleRect.height;
1173
+ if (shouldScrollX) {
1174
+ if (minX <= x || maxX === 0) x = minX;
1175
+ else if (layoutInfo.rect.maxX > maxX) x += layoutInfo.rect.maxX - maxX;
1176
+ }
1177
+ if (shouldScrollY) {
1178
+ if (minY <= y || maxY === 0) y = minY;
1179
+ else if (layoutInfo.rect.maxY > maxY) y += layoutInfo.rect.maxY - maxY;
1180
+ }
1181
+ return this.scrollTo(new (0, $3041db3296945e6e$export$baf26146a414f24a)(x, y), duration);
1182
+ }
1183
+ /**
1184
+ * Performs an animated scroll to the given offset.
1185
+ * @param offset - The offset to scroll to.
1186
+ * @param duration The duration of the animation.
1187
+ * @returns A promise that resolves when the animation is complete.
1188
+ */ scrollTo(offset, duration = 300) {
1189
+ // Cancel the current scroll animation
1190
+ if (this._scrollAnimation) {
1191
+ this._scrollAnimation.cancel();
1192
+ this._scrollAnimation = null;
1193
+ }
1194
+ // Set the content offset synchronously if the duration is zero
1195
+ if (duration <= 0 || this.visibleRect.pointEquals(offset)) {
1196
+ this._setContentOffset(offset);
1197
+ return Promise.resolve();
1198
+ }
1199
+ this.startScrolling();
1200
+ this._scrollAnimation = (0, $3eb131dcf37ad5f8$export$dc0b63720788090c)(this.visibleRect, offset, duration, (0, $3eb131dcf37ad5f8$export$57636bb43b1ccbb0), (offset)=>{
1201
+ this._setContentOffset(offset);
1202
+ });
1203
+ this._scrollAnimation.then(()=>{
1204
+ this._scrollAnimation = null;
1205
+ // Process view size updates that occurred during the animation.
1206
+ // Only views that are still visible will be actually updated.
1207
+ for (let [key, size] of this._sizeUpdateQueue)this.updateItemSize(key, size);
1208
+ this._sizeUpdateQueue.clear();
1209
+ this.relayout();
1210
+ this._processTransactionQueue();
1211
+ this.endScrolling();
1212
+ });
1213
+ return this._scrollAnimation;
1214
+ }
1215
+ _runTransaction(action, animated) {
1216
+ this._startTransaction();
1217
+ if (this._nextTransaction) this._nextTransaction.actions.push(action);
1218
+ this._endTransaction(animated);
1219
+ }
1220
+ _startTransaction() {
1221
+ if (!this._nextTransaction) this._nextTransaction = new (0, $8e135e531d8dcb66$export$febc5573c75cefb0);
1222
+ this._nextTransaction.level++;
1223
+ }
1224
+ _endTransaction(animated) {
1225
+ if (!this._nextTransaction) return false;
1226
+ // Save whether the transaction should be animated.
1227
+ if (animated != null) this._nextTransaction.animated = animated;
1228
+ // If we haven't reached level 0, we are still in a
1229
+ // nested transaction. Wait for the parent to end.
1230
+ if (--this._nextTransaction.level > 0) return false;
1231
+ // Do nothing for empty transactions
1232
+ if (this._nextTransaction.actions.length === 0) {
1233
+ this._nextTransaction = null;
1234
+ return false;
1235
+ }
1236
+ // Default animations to true
1237
+ if (this._nextTransaction.animated == null) this._nextTransaction.animated = true;
1238
+ // Enqueue the transaction
1239
+ this._transactionQueue.push(this._nextTransaction);
1240
+ this._nextTransaction = null;
1241
+ this._processTransactionQueue();
1242
+ return true;
1243
+ }
1244
+ _processTransactionQueue() {
1245
+ // If the current transaction is animating, wait until the end
1246
+ // to process the next transaction.
1247
+ if (this._transaction || this._scrollAnimation) return;
1248
+ let next = this._transactionQueue.shift();
1249
+ if (next) this._performTransaction(next);
1250
+ }
1251
+ _getContentRect() {
1252
+ return new (0, $60423f92c7f9ad87$export$c79fc6492f3af13d)(0, 0, this.contentSize.width, this.contentSize.height);
1253
+ }
1254
+ _performTransaction(transaction) {
1255
+ this._transaction = transaction;
1256
+ this.relayoutNow({
1257
+ transaction: transaction,
1258
+ animated: transaction.animated,
1259
+ beforeLayout: ()=>{
1260
+ // Get the initial layout infos for all views before the updates
1261
+ // so we can figure out which views to add and remove.
1262
+ if (transaction.animated) transaction.initialMap = this._getLayoutInfoMap(this._getContentRect(), true);
1263
+ // Apply the actions that occurred during this transaction
1264
+ for (let action of transaction.actions)action();
1265
+ },
1266
+ afterLayout: ()=>{
1267
+ // Get the final layout infos after the updates
1268
+ if (transaction.animated) {
1269
+ transaction.finalMap = this._getLayoutInfoMap(this._getContentRect());
1270
+ this._setupTransactionAnimations(transaction);
1271
+ } else this._transaction = null;
1272
+ },
1273
+ afterAnimation: ()=>{
1274
+ // Remove and reuse views when animations are done
1275
+ if (transaction.toRemove.size > 0 || transaction.removed.size > 0) for (let view of (0, $fc36f9a046a9ce79$export$cfc14088dfefce5f)(transaction.toRemove.values(), transaction.removed.values())){
1276
+ this._children.delete(view);
1277
+ this.reuseView(view);
1278
+ }
1279
+ this._transaction = null;
1280
+ // Ensure DOM order is correct for accessibility after animations are complete
1281
+ this._correctItemOrder();
1282
+ this._flushVisibleViews();
1283
+ this._processTransactionQueue();
1284
+ }
1285
+ });
1286
+ }
1287
+ _setupTransactionAnimations(transaction) {
1288
+ let { initialMap: initialMap , finalMap: finalMap } = transaction;
1289
+ // Store initial and final layout infos for animations
1290
+ for (let [key, layoutInfo] of initialMap)if (finalMap.has(key)) // Store the initial layout info for use during animations.
1291
+ transaction.initialLayoutInfo.set(key, layoutInfo);
1292
+ else // This view was removed. Store the layout info for use
1293
+ // in Layout#getFinalLayoutInfo during animations.
1294
+ transaction.finalLayoutInfo.set(layoutInfo.key, layoutInfo);
1295
+ // Get initial layout infos for views that were added
1296
+ for (let [key1, layoutInfo1] of finalMap)if (!initialMap.has(key1)) {
1297
+ let initialLayoutInfo = this.layout.getInitialLayoutInfo(layoutInfo1.copy());
1298
+ transaction.initialLayoutInfo.set(key1, initialLayoutInfo);
1299
+ }
1300
+ // Figure out which views were removed.
1301
+ for (let [key2, view] of this._visibleViews)// If an item has a width of 0, there is no need to remove it from the _visibleViews.
1302
+ // Removing an item with width of 0 can cause a loop where the item gets added, removed,
1303
+ // added, removed... etc in a loop.
1304
+ if (!finalMap.has(key2) && view.layoutInfo.rect.width > 0) {
1305
+ transaction.removed.set(key2, view);
1306
+ this._visibleViews.delete(key2);
1307
+ // In case something weird happened, where we have a view but no
1308
+ // initial layout info, use the one attached to the view.
1309
+ if (view.layoutInfo) {
1310
+ if (!transaction.finalLayoutInfo.has(view.layoutInfo.key)) transaction.finalLayoutInfo.set(view.layoutInfo.key, view.layoutInfo);
1311
+ }
1312
+ }
1313
+ }
1314
+ constructor(options = {}){
1315
+ this._contentSize = new (0, $ee1bfa90a957fb8a$export$cb6da89c6af1a8ec);
1316
+ this._visibleRect = new (0, $60423f92c7f9ad87$export$c79fc6492f3af13d);
1317
+ this._reusableViews = {};
1318
+ this._visibleLayoutInfos = new Map();
1319
+ this._visibleViews = new Map();
1320
+ this._renderedContent = new WeakMap();
1321
+ this._children = new Set();
1322
+ this._invalidationContext = null;
1323
+ this._overscanManager = new (0, $364191b3decf3697$export$4455ee6afb38dcbb)();
1324
+ this._persistedKeys = new Set();
1325
+ this._scrollAnimation = null;
1326
+ this._isScrolling = false;
1327
+ this._sizeUpdateQueue = new Map();
1328
+ this._animatedContentOffset = new (0, $3041db3296945e6e$export$baf26146a414f24a)(0, 0);
1329
+ this._transaction = null;
1330
+ this._nextTransaction = null;
1331
+ this._transactionQueue = [];
1332
+ var _options_transitionDuration;
1333
+ // Set options from passed object if given
1334
+ this.transitionDuration = (_options_transitionDuration = options.transitionDuration) !== null && _options_transitionDuration !== void 0 ? _options_transitionDuration : 500;
1335
+ this.anchorScrollPosition = options.anchorScrollPosition || false;
1336
+ this.anchorScrollPositionAtTop = options.anchorScrollPositionAtTop || false;
1337
+ this.shouldOverscan = options.shouldOverscan !== false;
1338
+ for (let key of [
1339
+ "delegate",
1340
+ "size",
1341
+ "layout",
1342
+ "collection"
1343
+ ])if (options[key]) this[key] = options[key];
1344
+ }
1345
+ }
1346
+
1347
+
1348
+ function $fc0b13b484ac1194$export$1505db82fe357e65(opts) {
1349
+ let [visibleViews, setVisibleViews] = (0, $8D3nr$useState)([]);
1350
+ let [contentSize, setContentSize] = (0, $8D3nr$useState)(new (0, $ee1bfa90a957fb8a$export$cb6da89c6af1a8ec)());
1351
+ let [isAnimating, setAnimating] = (0, $8D3nr$useState)(false);
1352
+ let [isScrolling, setScrolling] = (0, $8D3nr$useState)(false);
1353
+ let virtualizer = (0, $8D3nr$useMemo)(()=>new (0, $38b9490c1cca8fc4$export$89be5a243e59c4b2)(), []);
1354
+ virtualizer.delegate = {
1355
+ setVisibleViews: setVisibleViews,
1356
+ setVisibleRect (rect) {
1357
+ virtualizer.visibleRect = rect;
1358
+ opts.onVisibleRectChange(rect);
1359
+ },
1360
+ setContentSize: setContentSize,
1361
+ renderView: opts.renderView,
1362
+ renderWrapper: opts.renderWrapper,
1363
+ beginAnimations: ()=>setAnimating(true),
1364
+ endAnimations: ()=>setAnimating(false),
1365
+ getScrollAnchor: opts.getScrollAnchor
1366
+ };
1367
+ virtualizer.layout = opts.layout;
1368
+ virtualizer.collection = opts.collection;
1369
+ virtualizer.transitionDuration = opts.transitionDuration;
1370
+ (0, $8D3nr$useLayoutEffect)(()=>{
1371
+ virtualizer.afterRender();
1372
+ });
1373
+ // eslint-disable-next-line arrow-body-style
1374
+ (0, $8D3nr$useEffect)(()=>{
1375
+ return ()=>virtualizer.willUnmount();
1376
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1377
+ }, []);
1378
+ let setVisibleRect = (0, $8D3nr$useCallback)((rect)=>{
1379
+ virtualizer.visibleRect = rect;
1380
+ }, [
1381
+ virtualizer
1382
+ ]);
1383
+ let startScrolling = (0, $8D3nr$useCallback)(()=>{
1384
+ virtualizer.startScrolling();
1385
+ setScrolling(true);
1386
+ }, [
1387
+ virtualizer
1388
+ ]);
1389
+ let endScrolling = (0, $8D3nr$useCallback)(()=>{
1390
+ virtualizer.endScrolling();
1391
+ setScrolling(false);
1392
+ }, [
1393
+ virtualizer
1394
+ ]);
1395
+ let state = (0, $8D3nr$useMemo)(()=>({
1396
+ virtualizer: virtualizer,
1397
+ visibleViews: visibleViews,
1398
+ setVisibleRect: setVisibleRect,
1399
+ contentSize: contentSize,
1400
+ isAnimating: isAnimating,
1401
+ isScrolling: isScrolling,
1402
+ startScrolling: startScrolling,
1403
+ endScrolling: endScrolling
1404
+ }), [
1405
+ virtualizer,
1406
+ visibleViews,
1407
+ setVisibleRect,
1408
+ contentSize,
1409
+ isAnimating,
1410
+ isScrolling,
1411
+ startScrolling,
1412
+ endScrolling
1413
+ ]);
1414
+ return state;
1415
+ }
1416
+
1417
+
1418
+
1419
+
1420
+ export {$c74cda7d31af1253$export$c84671f46d6a1ca as Layout, $d7fd61009c21d0bb$export$7e0eeb9da702a085 as LayoutInfo, $3041db3296945e6e$export$baf26146a414f24a as Point, $60423f92c7f9ad87$export$c79fc6492f3af13d as Rect, $ee1bfa90a957fb8a$export$cb6da89c6af1a8ec as Size, $ad1d98aa8f0c31b4$export$1a5223887c560441 as ReusableView, $fc0b13b484ac1194$export$1505db82fe357e65 as useVirtualizerState};
1421
+ //# sourceMappingURL=module.js.map