@tanstack/virtual-core 3.0.0-beta.2 → 3.0.0-beta.20

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/src/index.ts CHANGED
@@ -1,4 +1,3 @@
1
- import observeRect from '@reach/observe-rect'
2
1
  import { memo } from './utils'
3
2
 
4
3
  export * from './utils'
@@ -7,8 +6,9 @@ export * from './utils'
7
6
 
8
7
  type ScrollAlignment = 'start' | 'center' | 'end' | 'auto'
9
8
 
10
- interface ScrollToOptions {
11
- align: ScrollAlignment
9
+ export interface ScrollToOptions {
10
+ align?: ScrollAlignment
11
+ smoothScroll?: boolean
12
12
  }
13
13
 
14
14
  type ScrollToOffsetOptions = ScrollToOptions
@@ -58,12 +58,34 @@ export const defaultRangeExtractor = (range: Range) => {
58
58
  return arr
59
59
  }
60
60
 
61
+ const memoRectCallback = (
62
+ instance: Virtualizer<any, any>,
63
+ cb: (rect: Rect) => void,
64
+ ) => {
65
+ let prev: Rect = { height: -1, width: -1 }
66
+
67
+ return (rect: Rect) => {
68
+ if (
69
+ instance.options.horizontal
70
+ ? rect.width !== prev.width
71
+ : rect.height !== prev.height
72
+ ) {
73
+ cb(rect)
74
+ }
75
+
76
+ prev = rect
77
+ }
78
+ }
79
+
61
80
  export const observeElementRect = (
62
81
  instance: Virtualizer<any, any>,
63
82
  cb: (rect: Rect) => void,
64
83
  ) => {
65
- const observer = observeRect(instance.scrollElement as Element, (rect) => {
66
- cb(rect)
84
+ const observer = new ResizeObserver((entries) => {
85
+ cb({
86
+ width: entries[0]?.contentRect.width as number,
87
+ height: entries[0]?.contentRect.height as number,
88
+ })
67
89
  })
68
90
 
69
91
  if (!instance.scrollElement) {
@@ -72,10 +94,10 @@ export const observeElementRect = (
72
94
 
73
95
  cb(instance.scrollElement.getBoundingClientRect())
74
96
 
75
- observer.observe()
97
+ observer.observe(instance.scrollElement)
76
98
 
77
99
  return () => {
78
- observer.unobserve()
100
+ observer.unobserve(instance.scrollElement)
79
101
  }
80
102
  }
81
103
 
@@ -83,12 +105,12 @@ export const observeWindowRect = (
83
105
  instance: Virtualizer<any, any>,
84
106
  cb: (rect: Rect) => void,
85
107
  ) => {
86
- const onResize = () => {
87
- cb({
108
+ const memoizedCallback = memoRectCallback(instance, cb)
109
+ const onResize = () =>
110
+ memoizedCallback({
88
111
  width: instance.scrollElement.innerWidth,
89
112
  height: instance.scrollElement.innerHeight,
90
113
  })
91
- }
92
114
 
93
115
  if (!instance.scrollElement) {
94
116
  return
@@ -106,60 +128,61 @@ export const observeWindowRect = (
106
128
  }
107
129
  }
108
130
 
109
- export const observeElementOffset = (
110
- instance: Virtualizer<any, any>,
111
- cb: (offset: number) => void,
112
- ) => {
113
- const onScroll = () =>
114
- cb(
115
- instance.scrollElement[
116
- instance.options.horizontal ? 'scrollLeft' : 'scrollTop'
117
- ],
118
- )
131
+ type ObserverMode = 'element' | 'window'
119
132
 
120
- if (!instance.scrollElement) {
121
- return
122
- }
133
+ const scrollProps = {
134
+ element: ['scrollLeft', 'scrollTop'],
135
+ window: ['scrollX', 'scrollY'],
136
+ } as const
123
137
 
124
- onScroll()
138
+ const createOffsetObserver = (mode: ObserverMode) => {
139
+ return (instance: Virtualizer<any, any>, cb: (offset: number) => void) => {
140
+ if (!instance.scrollElement) {
141
+ return
142
+ }
125
143
 
126
- instance.scrollElement.addEventListener('scroll', onScroll, {
127
- capture: false,
128
- passive: true,
129
- })
144
+ const propX = scrollProps[mode][0]
145
+ const propY = scrollProps[mode][1]
130
146
 
131
- return () => {
132
- instance.scrollElement.removeEventListener('scroll', onScroll)
133
- }
134
- }
147
+ let prevX: number = instance.scrollElement[propX]
148
+ let prevY: number = instance.scrollElement[propY]
135
149
 
136
- export const observeWindowOffset = (
137
- instance: Virtualizer<any, any>,
138
- cb: (offset: number) => void,
139
- ) => {
140
- const onScroll = () =>
141
- cb(
142
- instance.scrollElement[
143
- instance.options.horizontal ? 'scrollX' : 'scrollY'
144
- ],
145
- )
150
+ const scroll = () => {
151
+ const offset =
152
+ instance.scrollElement[instance.options.horizontal ? propX : propY]
146
153
 
147
- if (!instance.scrollElement) {
148
- return
149
- }
154
+ cb(Math.max(0, offset - instance.options.scrollMargin))
155
+ }
150
156
 
151
- onScroll()
157
+ scroll()
152
158
 
153
- instance.scrollElement.addEventListener('scroll', onScroll, {
154
- capture: false,
155
- passive: true,
156
- })
159
+ const onScroll = (e: Event) => {
160
+ const target = e.currentTarget as HTMLElement & Window
161
+ const scrollX = target[propX]
162
+ const scrollY = target[propY]
157
163
 
158
- return () => {
159
- instance.scrollElement.removeEventListener('scroll', onScroll)
164
+ if (instance.options.horizontal ? prevX - scrollX : prevY - scrollY) {
165
+ scroll()
166
+ }
167
+
168
+ prevX = scrollX
169
+ prevY = scrollY
170
+ }
171
+
172
+ instance.scrollElement.addEventListener('scroll', onScroll, {
173
+ capture: false,
174
+ passive: true,
175
+ })
176
+
177
+ return () => {
178
+ instance.scrollElement.removeEventListener('scroll', onScroll)
179
+ }
160
180
  }
161
181
  }
162
182
 
183
+ export const observeElementOffset = createOffsetObserver('element')
184
+ export const observeWindowOffset = createOffsetObserver('window')
185
+
163
186
  export const measureElement = (
164
187
  element: unknown,
165
188
  instance: Virtualizer<any, any>,
@@ -171,22 +194,26 @@ export const measureElement = (
171
194
 
172
195
  export const windowScroll = (
173
196
  offset: number,
174
- canSmooth: boolean,
197
+ { canSmooth, sync }: { canSmooth: boolean; sync: boolean },
175
198
  instance: Virtualizer<any, any>,
176
199
  ) => {
177
- ;(instance.scrollElement as Window)?.scrollTo({
178
- [instance.options.horizontal ? 'left' : 'top']: offset,
200
+ const toOffset = sync ? offset : offset + instance.options.scrollMargin
201
+
202
+ ;(instance.scrollElement as Window)?.scrollTo?.({
203
+ [instance.options.horizontal ? 'left' : 'top']: toOffset,
179
204
  behavior: canSmooth ? 'smooth' : undefined,
180
205
  })
181
206
  }
182
207
 
183
208
  export const elementScroll = (
184
209
  offset: number,
185
- canSmooth: boolean,
210
+ { canSmooth, sync }: { canSmooth: boolean; sync: boolean },
186
211
  instance: Virtualizer<any, any>,
187
212
  ) => {
188
- ;(instance.scrollElement as Element)?.scrollTo({
189
- [instance.options.horizontal ? 'left' : 'top']: offset,
213
+ const toOffset = sync ? offset : offset + instance.options.scrollMargin
214
+
215
+ ;(instance.scrollElement as Element)?.scrollTo?.({
216
+ [instance.options.horizontal ? 'left' : 'top']: toOffset,
190
217
  behavior: canSmooth ? 'smooth' : undefined,
191
218
  })
192
219
  }
@@ -203,7 +230,7 @@ export interface VirtualizerOptions<
203
230
  // Required from the framework adapter (but can be overridden)
204
231
  scrollToFn: (
205
232
  offset: number,
206
- canSmooth: boolean,
233
+ options: { canSmooth: boolean; sync: boolean },
207
234
  instance: Virtualizer<TScrollElement, TItemElement>,
208
235
  ) => void
209
236
  observeElementRect: (
@@ -233,24 +260,39 @@ export interface VirtualizerOptions<
233
260
  getItemKey?: (index: number) => Key
234
261
  rangeExtractor?: (range: Range) => number[]
235
262
  enableSmoothScroll?: boolean
263
+ scrollMargin?: number
264
+ scrollingDelay?: number
236
265
  }
237
266
 
238
267
  export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
239
268
  private unsubs: (void | (() => void))[] = []
240
269
  options!: Required<VirtualizerOptions<TScrollElement, TItemElement>>
241
270
  scrollElement: TScrollElement | null = null
271
+ isScrolling: boolean = false
272
+ private isScrollingTimeoutId: ReturnType<typeof setTimeout> | null = null
242
273
  private measurementsCache: Item[] = []
243
274
  private itemMeasurementsCache: Record<Key, number> = {}
244
275
  private pendingMeasuredCacheIndexes: number[] = []
245
276
  private scrollRect: Rect
246
277
  private scrollOffset: number
278
+ private scrollDelta: number = 0
247
279
  private destinationOffset: undefined | number
248
280
  private scrollCheckFrame!: ReturnType<typeof setTimeout>
281
+ private measureElementCache: Record<
282
+ number,
283
+ (measurableItem: TItemElement | null) => void
284
+ > = {}
285
+ range: { startIndex: number; endIndex: number } = {
286
+ startIndex: 0,
287
+ endIndex: 0,
288
+ }
249
289
 
250
290
  constructor(opts: VirtualizerOptions<TScrollElement, TItemElement>) {
251
291
  this.setOptions(opts)
252
292
  this.scrollRect = this.options.initialRect
253
293
  this.scrollOffset = this.options.initialOffset
294
+
295
+ this.calculateRange()
254
296
  }
255
297
 
256
298
  setOptions = (opts: VirtualizerOptions<TScrollElement, TItemElement>) => {
@@ -273,6 +315,8 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
273
315
  onChange: () => {},
274
316
  measureElement,
275
317
  initialRect: { width: 0, height: 0 },
318
+ scrollMargin: 0,
319
+ scrollingDelay: 150,
276
320
  ...opts,
277
321
  }
278
322
  }
@@ -284,6 +328,7 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
284
328
  private cleanup = () => {
285
329
  this.unsubs.filter(Boolean).forEach((d) => d!())
286
330
  this.unsubs = []
331
+ this.scrollElement = null
287
332
  }
288
333
 
289
334
  _didMount = () => {
@@ -299,20 +344,47 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
299
344
  this.cleanup()
300
345
 
301
346
  this.scrollElement = scrollElement
347
+ this._scrollToOffset(this.scrollOffset, {
348
+ canSmooth: false,
349
+ sync: true,
350
+ requested: false,
351
+ })
302
352
 
303
353
  this.unsubs.push(
304
354
  this.options.observeElementRect(this, (rect) => {
305
355
  this.scrollRect = rect
306
- this.notify()
356
+ this.calculateRange()
307
357
  }),
308
358
  )
309
359
 
310
360
  this.unsubs.push(
311
361
  this.options.observeElementOffset(this, (offset) => {
312
- this.scrollOffset = offset
313
- this.notify()
362
+ if (this.isScrollingTimeoutId !== null) {
363
+ clearTimeout(this.isScrollingTimeoutId)
364
+ this.isScrollingTimeoutId = null
365
+ }
366
+
367
+ if (this.scrollOffset !== offset) {
368
+ this.scrollOffset = offset
369
+ this.isScrolling = true
370
+ this.scrollDelta = 0
371
+
372
+ this.isScrollingTimeoutId = setTimeout(() => {
373
+ this.isScrollingTimeoutId = null
374
+ this.isScrolling = false
375
+
376
+ this.notify()
377
+ }, this.options.scrollingDelay)
378
+ } else {
379
+ this.isScrolling = false
380
+ this.scrollDelta = 0
381
+ }
382
+
383
+ this.calculateRange()
314
384
  }),
315
385
  )
386
+ } else if (!this.isScrolling) {
387
+ this.calculateRange()
316
388
  }
317
389
  }
318
390
 
@@ -354,22 +426,30 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
354
426
  return measurements
355
427
  },
356
428
  {
357
- key: process.env.NODE_ENV === 'development' && 'getMeasurements',
429
+ key: process.env.NODE_ENV !== 'production' && 'getMeasurements',
358
430
  debug: () => this.options.debug,
359
431
  },
360
432
  )
361
433
 
362
- private calculateRange = memo(
434
+ calculateRange = memo(
363
435
  () => [this.getMeasurements(), this.getSize(), this.scrollOffset],
364
436
  (measurements, outerSize, scrollOffset) => {
365
- return calculateRange({
437
+ const range = calculateRange({
366
438
  measurements,
367
439
  outerSize,
368
440
  scrollOffset,
369
441
  })
442
+ if (
443
+ range.startIndex !== this.range.startIndex ||
444
+ range.endIndex !== this.range.endIndex
445
+ ) {
446
+ this.range = range
447
+ this.notify()
448
+ }
449
+ return this.range
370
450
  },
371
451
  {
372
- key: process.env.NODE_ENV === 'development' && 'calculateRange',
452
+ key: process.env.NODE_ENV !== 'production' && 'calculateRange',
373
453
  debug: () => this.options.debug,
374
454
  },
375
455
  )
@@ -377,7 +457,7 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
377
457
  private getIndexes = memo(
378
458
  () => [
379
459
  this.options.rangeExtractor,
380
- this.calculateRange(),
460
+ this.range,
381
461
  this.options.overscan,
382
462
  this.options.count,
383
463
  ],
@@ -389,7 +469,8 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
389
469
  })
390
470
  },
391
471
  {
392
- key: process.env.NODE_ENV === 'development' && 'getIndexes',
472
+ key: process.env.NODE_ENV !== 'production' && 'getIndexes',
473
+ debug: () => this.options.debug,
393
474
  },
394
475
  )
395
476
 
@@ -400,91 +481,110 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
400
481
  this.options.measureElement,
401
482
  ],
402
483
  (indexes, measurements, measureElement) => {
484
+ const makeMeasureElement =
485
+ (index: number) => (measurableItem: TItemElement | null) => {
486
+ const item = this.measurementsCache[index]!
487
+
488
+ if (!measurableItem) {
489
+ return
490
+ }
491
+
492
+ const measuredItemSize = measureElement(measurableItem, this)
493
+ const itemSize = this.itemMeasurementsCache[item.key] ?? item.size
494
+
495
+ if (measuredItemSize !== itemSize) {
496
+ if (item.start < this.scrollOffset) {
497
+ if (process.env.NODE_ENV !== 'production' && this.options.debug) {
498
+ console.info('correction', measuredItemSize - itemSize)
499
+ }
500
+
501
+ if (this.destinationOffset === undefined) {
502
+ this.scrollDelta += measuredItemSize - itemSize
503
+
504
+ this._scrollToOffset(this.scrollOffset + this.scrollDelta, {
505
+ canSmooth: false,
506
+ sync: false,
507
+ requested: false,
508
+ })
509
+ }
510
+ }
511
+
512
+ this.pendingMeasuredCacheIndexes.push(index)
513
+ this.itemMeasurementsCache = {
514
+ ...this.itemMeasurementsCache,
515
+ [item.key]: measuredItemSize,
516
+ }
517
+ this.notify()
518
+ }
519
+ }
520
+
403
521
  const virtualItems: VirtualItem<TItemElement>[] = []
404
522
 
523
+ const currentMeasureElements: typeof this.measureElementCache = {}
524
+
405
525
  for (let k = 0, len = indexes.length; k < len; k++) {
406
526
  const i = indexes[k]!
407
527
  const measurement = measurements[i]!
408
528
 
409
529
  const item = {
410
530
  ...measurement,
411
- measureElement: (measurableItem: TItemElement | null) => {
412
- if (measurableItem) {
413
- const measuredItemSize = measureElement(measurableItem, this)
414
-
415
- if (measuredItemSize !== item.size) {
416
- if (item.start < this.scrollOffset) {
417
- if (
418
- process.env.NODE_ENV === 'development' &&
419
- this.options.debug
420
- )
421
- console.info('correction', measuredItemSize - item.size)
422
-
423
- if (!this.destinationOffset) {
424
- this._scrollToOffset(
425
- this.scrollOffset + (measuredItemSize - item.size),
426
- false,
427
- )
428
- }
429
- }
430
-
431
- this.pendingMeasuredCacheIndexes.push(i)
432
- this.itemMeasurementsCache = {
433
- ...this.itemMeasurementsCache,
434
- [item.key]: measuredItemSize,
435
- }
436
- this.notify()
437
- }
438
- }
439
- },
531
+ measureElement: (currentMeasureElements[i] =
532
+ this.measureElementCache[i] ?? makeMeasureElement(i)),
440
533
  }
441
-
442
534
  virtualItems.push(item)
443
535
  }
444
536
 
537
+ this.measureElementCache = currentMeasureElements
538
+
445
539
  return virtualItems
446
540
  },
447
541
  {
448
- key: process.env.NODE_ENV === 'development' && 'getIndexes',
542
+ key: process.env.NODE_ENV !== 'production' && 'getIndexes',
543
+ debug: () => this.options.debug,
449
544
  },
450
545
  )
451
546
 
452
547
  scrollToOffset = (
453
548
  toOffset: number,
454
- { align }: ScrollToOffsetOptions = { align: 'start' },
549
+ {
550
+ align = 'start',
551
+ smoothScroll = this.options.enableSmoothScroll,
552
+ }: ScrollToOffsetOptions = {},
455
553
  ) => {
456
- const attempt = () => {
457
- const offset = this.scrollOffset
458
- const size = this.getSize()
459
-
460
- if (align === 'auto') {
461
- if (toOffset <= offset) {
462
- align = 'start'
463
- } else if (toOffset >= offset + size) {
464
- align = 'end'
465
- } else {
466
- align = 'start'
467
- }
468
- }
554
+ const offset = this.scrollOffset
555
+ const size = this.getSize()
469
556
 
470
- if (align === 'start') {
471
- this._scrollToOffset(toOffset, true)
472
- } else if (align === 'end') {
473
- this._scrollToOffset(toOffset - size, true)
474
- } else if (align === 'center') {
475
- this._scrollToOffset(toOffset - size / 2, true)
557
+ if (align === 'auto') {
558
+ if (toOffset <= offset) {
559
+ align = 'start'
560
+ } else if (toOffset >= offset + size) {
561
+ align = 'end'
562
+ } else {
563
+ align = 'start'
476
564
  }
477
565
  }
478
566
 
479
- attempt()
480
- requestAnimationFrame(() => {
481
- attempt()
482
- })
567
+ const options = {
568
+ canSmooth: smoothScroll,
569
+ sync: false,
570
+ requested: true,
571
+ }
572
+ if (align === 'start') {
573
+ this._scrollToOffset(toOffset, options)
574
+ } else if (align === 'end') {
575
+ this._scrollToOffset(toOffset - size, options)
576
+ } else if (align === 'center') {
577
+ this._scrollToOffset(toOffset - size / 2, options)
578
+ }
483
579
  }
484
580
 
485
581
  scrollToIndex = (
486
582
  index: number,
487
- { align, ...rest }: ScrollToIndexOptions = { align: 'auto' },
583
+ {
584
+ align = 'auto',
585
+ smoothScroll = this.options.enableSmoothScroll,
586
+ ...rest
587
+ }: ScrollToIndexOptions = {},
488
588
  ) => {
489
589
  const measurements = this.getMeasurements()
490
590
  const offset = this.scrollOffset
@@ -515,22 +615,27 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
515
615
  ? measurement.end + this.options.scrollPaddingEnd
516
616
  : measurement.start - this.options.scrollPaddingStart
517
617
 
518
- this.scrollToOffset(toOffset, { align, ...rest })
618
+ this.scrollToOffset(toOffset, { align, smoothScroll, ...rest })
519
619
  }
520
620
 
521
621
  getTotalSize = () =>
522
622
  (this.getMeasurements()[this.options.count - 1]?.end ||
523
623
  this.options.paddingStart) + this.options.paddingEnd
524
624
 
525
- private _scrollToOffset = (offset: number, canSmooth: boolean) => {
625
+ private _scrollToOffset = (
626
+ offset: number,
627
+ {
628
+ requested,
629
+ canSmooth,
630
+ sync,
631
+ }: { canSmooth: boolean; sync: boolean; requested: boolean },
632
+ ) => {
526
633
  clearTimeout(this.scrollCheckFrame)
527
634
 
528
- this.destinationOffset = offset
529
- this.options.scrollToFn(
530
- offset,
531
- this.options.enableSmoothScroll && canSmooth,
532
- this,
533
- )
635
+ if (requested) {
636
+ this.destinationOffset = offset
637
+ }
638
+ this.options.scrollToFn(offset, { canSmooth, sync }, this)
534
639
 
535
640
  let scrollCheckFrame: ReturnType<typeof setTimeout>
536
641
 
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../src/index.ts"],"sourcesContent":["import observeRect from '@reach/observe-rect'\nimport { memo } from './utils'\n\nexport * from './utils'\n\n//\n\ntype ScrollAlignment = 'start' | 'center' | 'end' | 'auto'\n\ninterface ScrollToOptions {\n align: ScrollAlignment\n}\n\ntype ScrollToOffsetOptions = ScrollToOptions\n\ntype ScrollToIndexOptions = ScrollToOptions\n\nexport interface Range {\n startIndex: number\n endIndex: number\n overscan: number\n count: number\n}\n\ntype Key = number | string\n\ninterface Item {\n key: Key\n index: number\n start: number\n end: number\n size: number\n}\n\ninterface Rect {\n width: number\n height: number\n}\n\nexport interface VirtualItem<TItemElement> extends Item {\n measureElement: (el: TItemElement | null) => void\n}\n\n//\n\nexport const defaultKeyExtractor = (index: number) => index\n\nexport const defaultRangeExtractor = (range: Range) => {\n const start = Math.max(range.startIndex - range.overscan, 0)\n const end = Math.min(range.endIndex + range.overscan, range.count - 1)\n\n const arr = []\n\n for (let i = start; i <= end; i++) {\n arr.push(i)\n }\n\n return arr\n}\n\nexport const observeElementRect = (\n instance: Virtualizer<any, any>,\n cb: (rect: Rect) => void,\n) => {\n const observer = observeRect(instance.scrollElement as Element, (rect) => {\n cb(rect)\n })\n\n if (!instance.scrollElement) {\n return\n }\n\n cb(instance.scrollElement.getBoundingClientRect())\n\n observer.observe()\n\n return () => {\n observer.unobserve()\n }\n}\n\nexport const observeWindowRect = (\n instance: Virtualizer<any, any>,\n cb: (rect: Rect) => void,\n) => {\n const onResize = () => {\n cb({\n width: instance.scrollElement.innerWidth,\n height: instance.scrollElement.innerHeight,\n })\n }\n\n if (!instance.scrollElement) {\n return\n }\n\n onResize()\n\n instance.scrollElement.addEventListener('resize', onResize, {\n capture: false,\n passive: true,\n })\n\n return () => {\n instance.scrollElement.removeEventListener('resize', onResize)\n }\n}\n\nexport const observeElementOffset = (\n instance: Virtualizer<any, any>,\n cb: (offset: number) => void,\n) => {\n const onScroll = () =>\n cb(\n instance.scrollElement[\n instance.options.horizontal ? 'scrollLeft' : 'scrollTop'\n ],\n )\n\n if (!instance.scrollElement) {\n return\n }\n\n onScroll()\n\n instance.scrollElement.addEventListener('scroll', onScroll, {\n capture: false,\n passive: true,\n })\n\n return () => {\n instance.scrollElement.removeEventListener('scroll', onScroll)\n }\n}\n\nexport const observeWindowOffset = (\n instance: Virtualizer<any, any>,\n cb: (offset: number) => void,\n) => {\n const onScroll = () =>\n cb(\n instance.scrollElement[\n instance.options.horizontal ? 'scrollX' : 'scrollY'\n ],\n )\n\n if (!instance.scrollElement) {\n return\n }\n\n onScroll()\n\n instance.scrollElement.addEventListener('scroll', onScroll, {\n capture: false,\n passive: true,\n })\n\n return () => {\n instance.scrollElement.removeEventListener('scroll', onScroll)\n }\n}\n\nexport const measureElement = (\n element: unknown,\n instance: Virtualizer<any, any>,\n) => {\n return (element as Element).getBoundingClientRect()[\n instance.options.horizontal ? 'width' : 'height'\n ]\n}\n\nexport const windowScroll = (\n offset: number,\n canSmooth: boolean,\n instance: Virtualizer<any, any>,\n) => {\n ;(instance.scrollElement as Window)?.scrollTo({\n [instance.options.horizontal ? 'left' : 'top']: offset,\n behavior: canSmooth ? 'smooth' : undefined,\n })\n}\n\nexport const elementScroll = (\n offset: number,\n canSmooth: boolean,\n instance: Virtualizer<any, any>,\n) => {\n ;(instance.scrollElement as Element)?.scrollTo({\n [instance.options.horizontal ? 'left' : 'top']: offset,\n behavior: canSmooth ? 'smooth' : undefined,\n })\n}\n\nexport interface VirtualizerOptions<\n TScrollElement = unknown,\n TItemElement = unknown,\n> {\n // Required from the user\n count: number\n getScrollElement: () => TScrollElement\n estimateSize: (index: number) => number\n\n // Required from the framework adapter (but can be overridden)\n scrollToFn: (\n offset: number,\n canSmooth: boolean,\n instance: Virtualizer<TScrollElement, TItemElement>,\n ) => void\n observeElementRect: (\n instance: Virtualizer<TScrollElement, TItemElement>,\n cb: (rect: Rect) => void,\n ) => void | (() => void)\n observeElementOffset: (\n instance: Virtualizer<TScrollElement, TItemElement>,\n cb: (offset: number) => void,\n ) => void | (() => void)\n\n // Optional\n debug?: any\n initialRect?: Rect\n onChange?: (instance: Virtualizer<TScrollElement, TItemElement>) => void\n measureElement?: (\n el: TItemElement,\n instance: Virtualizer<TScrollElement, TItemElement>,\n ) => number\n overscan?: number\n horizontal?: boolean\n paddingStart?: number\n paddingEnd?: number\n scrollPaddingStart?: number\n scrollPaddingEnd?: number\n initialOffset?: number\n getItemKey?: (index: number) => Key\n rangeExtractor?: (range: Range) => number[]\n enableSmoothScroll?: boolean\n}\n\nexport class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {\n private unsubs: (void | (() => void))[] = []\n options!: Required<VirtualizerOptions<TScrollElement, TItemElement>>\n scrollElement: TScrollElement | null = null\n private measurementsCache: Item[] = []\n private itemMeasurementsCache: Record<Key, number> = {}\n private pendingMeasuredCacheIndexes: number[] = []\n private scrollRect: Rect\n private scrollOffset: number\n private destinationOffset: undefined | number\n private scrollCheckFrame!: ReturnType<typeof setTimeout>\n\n constructor(opts: VirtualizerOptions<TScrollElement, TItemElement>) {\n this.setOptions(opts)\n this.scrollRect = this.options.initialRect\n this.scrollOffset = this.options.initialOffset\n }\n\n setOptions = (opts: VirtualizerOptions<TScrollElement, TItemElement>) => {\n Object.entries(opts).forEach(([key, value]) => {\n if (typeof value === 'undefined') delete (opts as any)[key]\n })\n\n this.options = {\n debug: false,\n initialOffset: 0,\n overscan: 1,\n paddingStart: 0,\n paddingEnd: 0,\n scrollPaddingStart: 0,\n scrollPaddingEnd: 0,\n horizontal: false,\n getItemKey: defaultKeyExtractor,\n rangeExtractor: defaultRangeExtractor,\n enableSmoothScroll: true,\n onChange: () => {},\n measureElement,\n initialRect: { width: 0, height: 0 },\n ...opts,\n }\n }\n\n private notify = () => {\n this.options.onChange?.(this)\n }\n\n private cleanup = () => {\n this.unsubs.filter(Boolean).forEach((d) => d!())\n this.unsubs = []\n }\n\n _didMount = () => {\n return () => {\n this.cleanup()\n }\n }\n\n _willUpdate = () => {\n const scrollElement = this.options.getScrollElement()\n\n if (this.scrollElement !== scrollElement) {\n this.cleanup()\n\n this.scrollElement = scrollElement\n\n this.unsubs.push(\n this.options.observeElementRect(this, (rect) => {\n this.scrollRect = rect\n this.notify()\n }),\n )\n\n this.unsubs.push(\n this.options.observeElementOffset(this, (offset) => {\n this.scrollOffset = offset\n this.notify()\n }),\n )\n }\n }\n\n private getSize = () => {\n return this.scrollRect[this.options.horizontal ? 'width' : 'height']\n }\n\n private getMeasurements = memo(\n () => [\n this.options.count,\n this.options.paddingStart,\n this.options.getItemKey,\n this.itemMeasurementsCache,\n ],\n (count, paddingStart, getItemKey, measurementsCache) => {\n const min =\n this.pendingMeasuredCacheIndexes.length > 0\n ? Math.min(...this.pendingMeasuredCacheIndexes)\n : 0\n this.pendingMeasuredCacheIndexes = []\n\n const measurements = this.measurementsCache.slice(0, min)\n\n for (let i = min; i < count; i++) {\n const key = getItemKey(i)\n const measuredSize = measurementsCache[key]\n const start = measurements[i - 1]\n ? measurements[i - 1]!.end\n : paddingStart\n const size =\n typeof measuredSize === 'number'\n ? measuredSize\n : this.options.estimateSize(i)\n const end = start + size\n measurements[i] = { index: i, start, size, end, key }\n }\n\n this.measurementsCache = measurements\n return measurements\n },\n {\n key: process.env.NODE_ENV === 'development' && 'getMeasurements',\n debug: () => this.options.debug,\n },\n )\n\n private calculateRange = memo(\n () => [this.getMeasurements(), this.getSize(), this.scrollOffset],\n (measurements, outerSize, scrollOffset) => {\n return calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n })\n },\n {\n key: process.env.NODE_ENV === 'development' && 'calculateRange',\n debug: () => this.options.debug,\n },\n )\n\n private getIndexes = memo(\n () => [\n this.options.rangeExtractor,\n this.calculateRange(),\n this.options.overscan,\n this.options.count,\n ],\n (rangeExtractor, range, overscan, count) => {\n return rangeExtractor({\n ...range,\n overscan,\n count: count,\n })\n },\n {\n key: process.env.NODE_ENV === 'development' && 'getIndexes',\n },\n )\n\n getVirtualItems = memo(\n () => [\n this.getIndexes(),\n this.getMeasurements(),\n this.options.measureElement,\n ],\n (indexes, measurements, measureElement) => {\n const virtualItems: VirtualItem<TItemElement>[] = []\n\n for (let k = 0, len = indexes.length; k < len; k++) {\n const i = indexes[k]!\n const measurement = measurements[i]!\n\n const item = {\n ...measurement,\n measureElement: (measurableItem: TItemElement | null) => {\n if (measurableItem) {\n const measuredItemSize = measureElement(measurableItem, this)\n\n if (measuredItemSize !== item.size) {\n if (item.start < this.scrollOffset) {\n if (\n process.env.NODE_ENV === 'development' &&\n this.options.debug\n )\n console.info('correction', measuredItemSize - item.size)\n\n if (!this.destinationOffset) {\n this._scrollToOffset(\n this.scrollOffset + (measuredItemSize - item.size),\n false,\n )\n }\n }\n\n this.pendingMeasuredCacheIndexes.push(i)\n this.itemMeasurementsCache = {\n ...this.itemMeasurementsCache,\n [item.key]: measuredItemSize,\n }\n this.notify()\n }\n }\n },\n }\n\n virtualItems.push(item)\n }\n\n return virtualItems\n },\n {\n key: process.env.NODE_ENV === 'development' && 'getIndexes',\n },\n )\n\n scrollToOffset = (\n toOffset: number,\n { align }: ScrollToOffsetOptions = { align: 'start' },\n ) => {\n const attempt = () => {\n const offset = this.scrollOffset\n const size = this.getSize()\n\n if (align === 'auto') {\n if (toOffset <= offset) {\n align = 'start'\n } else if (toOffset >= offset + size) {\n align = 'end'\n } else {\n align = 'start'\n }\n }\n\n if (align === 'start') {\n this._scrollToOffset(toOffset, true)\n } else if (align === 'end') {\n this._scrollToOffset(toOffset - size, true)\n } else if (align === 'center') {\n this._scrollToOffset(toOffset - size / 2, true)\n }\n }\n\n attempt()\n requestAnimationFrame(() => {\n attempt()\n })\n }\n\n scrollToIndex = (\n index: number,\n { align, ...rest }: ScrollToIndexOptions = { align: 'auto' },\n ) => {\n const measurements = this.getMeasurements()\n const offset = this.scrollOffset\n const size = this.getSize()\n const { count } = this.options\n\n const measurement = measurements[Math.max(0, Math.min(index, count - 1))]\n\n if (!measurement) {\n return\n }\n\n if (align === 'auto') {\n if (measurement.end >= offset + size - this.options.scrollPaddingEnd) {\n align = 'end'\n } else if (\n measurement.start <=\n offset + this.options.scrollPaddingStart\n ) {\n align = 'start'\n } else {\n return\n }\n }\n\n const toOffset =\n align === 'end'\n ? measurement.end + this.options.scrollPaddingEnd\n : measurement.start - this.options.scrollPaddingStart\n\n this.scrollToOffset(toOffset, { align, ...rest })\n }\n\n getTotalSize = () =>\n (this.getMeasurements()[this.options.count - 1]?.end ||\n this.options.paddingStart) + this.options.paddingEnd\n\n private _scrollToOffset = (offset: number, canSmooth: boolean) => {\n clearTimeout(this.scrollCheckFrame)\n\n this.destinationOffset = offset\n this.options.scrollToFn(\n offset,\n this.options.enableSmoothScroll && canSmooth,\n this,\n )\n\n let scrollCheckFrame: ReturnType<typeof setTimeout>\n\n const check = () => {\n let lastOffset = this.scrollOffset\n this.scrollCheckFrame = scrollCheckFrame = setTimeout(() => {\n if (this.scrollCheckFrame !== scrollCheckFrame) {\n return\n }\n\n if (this.scrollOffset === lastOffset) {\n this.destinationOffset = undefined\n return\n }\n lastOffset = this.scrollOffset\n check()\n }, 100)\n }\n\n check()\n }\n\n measure = () => {\n this.itemMeasurementsCache = {}\n this.notify()\n }\n}\n\nconst findNearestBinarySearch = (\n low: number,\n high: number,\n getCurrentValue: (i: number) => number,\n value: number,\n) => {\n while (low <= high) {\n const middle = ((low + high) / 2) | 0\n const currentValue = getCurrentValue(middle)\n\n if (currentValue < value) {\n low = middle + 1\n } else if (currentValue > value) {\n high = middle - 1\n } else {\n return middle\n }\n }\n\n if (low > 0) {\n return low - 1\n } else {\n return 0\n }\n}\n\nfunction calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n}: {\n measurements: Item[]\n outerSize: number\n scrollOffset: number\n}) {\n const count = measurements.length - 1\n const getOffset = (index: number) => measurements[index]!.start\n\n const startIndex = findNearestBinarySearch(0, count, getOffset, scrollOffset)\n let endIndex = startIndex\n\n while (\n endIndex < count &&\n measurements[endIndex]!.end < scrollOffset + outerSize\n ) {\n endIndex++\n }\n\n return { startIndex, endIndex }\n}\n"],"names":["defaultKeyExtractor","index","defaultRangeExtractor","range","start","Math","max","startIndex","overscan","end","min","endIndex","count","arr","i","push","observeElementRect","instance","cb","observer","observeRect","scrollElement","rect","getBoundingClientRect","observe","unobserve","observeWindowRect","onResize","width","innerWidth","height","innerHeight","addEventListener","capture","passive","removeEventListener","observeElementOffset","onScroll","options","horizontal","observeWindowOffset","measureElement","element","windowScroll","offset","canSmooth","scrollTo","behavior","undefined","elementScroll","Virtualizer","constructor","opts","unsubs","measurementsCache","itemMeasurementsCache","pendingMeasuredCacheIndexes","setOptions","Object","entries","forEach","key","value","debug","initialOffset","paddingStart","paddingEnd","scrollPaddingStart","scrollPaddingEnd","getItemKey","rangeExtractor","enableSmoothScroll","onChange","initialRect","notify","cleanup","filter","Boolean","d","_didMount","_willUpdate","getScrollElement","scrollRect","scrollOffset","getSize","getMeasurements","memo","length","measurements","slice","measuredSize","size","estimateSize","process","env","NODE_ENV","calculateRange","outerSize","getIndexes","getVirtualItems","indexes","virtualItems","k","len","measurement","item","measurableItem","measuredItemSize","console","info","destinationOffset","_scrollToOffset","scrollToOffset","toOffset","align","attempt","requestAnimationFrame","scrollToIndex","rest","getTotalSize","clearTimeout","scrollCheckFrame","scrollToFn","check","lastOffset","setTimeout","measure","findNearestBinarySearch","low","high","getCurrentValue","middle","currentValue","getOffset"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sources":["../../../../../src/utils.ts"],"sourcesContent":["export type NoInfer<A extends any> = [A][A extends any ? 0 : never]\n\nexport type PartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\n\nexport function memo<TDeps extends readonly any[], TResult>(\n getDeps: () => [...TDeps],\n fn: (...args: NoInfer<[...TDeps]>) => TResult,\n opts: {\n key: any\n debug?: () => any\n onChange?: (result: TResult) => void\n },\n): () => TResult {\n let deps: any[] = []\n let result: TResult | undefined\n\n return () => {\n let depTime: number\n if (opts.key && opts.debug?.()) depTime = Date.now()\n\n const newDeps = getDeps()\n\n const depsChanged =\n newDeps.length !== deps.length ||\n newDeps.some((dep: any, index: number) => deps[index] !== dep)\n\n if (!depsChanged) {\n return result!\n }\n\n deps = newDeps\n\n let resultTime: number\n if (opts.key && opts.debug?.()) resultTime = Date.now()\n\n result = fn(...newDeps)\n opts?.onChange?.(result)\n\n if (opts.key && opts.debug?.()) {\n const depEndTime = Math.round((Date.now() - depTime!) * 100) / 100\n const resultEndTime = Math.round((Date.now() - resultTime!) * 100) / 100\n const resultFpsPercentage = resultEndTime / 16\n\n const pad = (str: number | string, num: number) => {\n str = String(str)\n while (str.length < num) {\n str = ' ' + str\n }\n return str\n }\n\n console.info(\n `%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`,\n `\n font-size: .6rem;\n font-weight: bold;\n color: hsl(${Math.max(\n 0,\n Math.min(120 - 120 * resultFpsPercentage, 120),\n )}deg 100% 31%);`,\n opts?.key,\n )\n }\n\n return result!\n }\n}\n"],"names":["memo","getDeps","fn","opts","deps","result","depTime","key","debug","Date","now","newDeps","depsChanged","length","some","dep","index","resultTime","onChange","depEndTime","Math","round","resultEndTime","resultFpsPercentage","pad","str","num","String","console","info","max","min"],"mappings":";;;;;;;;;;;;;;AAIO,SAASA,IAAT,CACLC,OADK,EAELC,EAFK,EAGLC,IAHK,EAQU;EACf,IAAIC,IAAW,GAAG,EAAlB,CAAA;AACA,EAAA,IAAIC,MAAJ,CAAA;AAEA,EAAA,OAAO,MAAM;AACX,IAAA,IAAIC,OAAJ,CAAA;AACA,IAAA,IAAIH,IAAI,CAACI,GAAL,IAAYJ,IAAI,CAACK,KAAjB,IAAYL,IAAAA,IAAAA,IAAI,CAACK,KAAL,EAAhB,EAAgCF,OAAO,GAAGG,IAAI,CAACC,GAAL,EAAV,CAAA;IAEhC,MAAMC,OAAO,GAAGV,OAAO,EAAvB,CAAA;IAEA,MAAMW,WAAW,GACfD,OAAO,CAACE,MAAR,KAAmBT,IAAI,CAACS,MAAxB,IACAF,OAAO,CAACG,IAAR,CAAa,CAACC,GAAD,EAAWC,KAAX,KAA6BZ,IAAI,CAACY,KAAD,CAAJ,KAAgBD,GAA1D,CAFF,CAAA;;IAIA,IAAI,CAACH,WAAL,EAAkB;AAChB,MAAA,OAAOP,MAAP,CAAA;AACD,KAAA;;AAEDD,IAAAA,IAAI,GAAGO,OAAP,CAAA;AAEA,IAAA,IAAIM,UAAJ,CAAA;AACA,IAAA,IAAId,IAAI,CAACI,GAAL,IAAYJ,IAAI,CAACK,KAAjB,IAAYL,IAAAA,IAAAA,IAAI,CAACK,KAAL,EAAhB,EAAgCS,UAAU,GAAGR,IAAI,CAACC,GAAL,EAAb,CAAA;AAEhCL,IAAAA,MAAM,GAAGH,EAAE,CAAC,GAAGS,OAAJ,CAAX,CAAA;IACAR,IAAI,IAAA,IAAJ,GAAAA,KAAAA,CAAAA,GAAAA,IAAI,CAAEe,QAAN,oBAAAf,IAAI,CAAEe,QAAN,CAAiBb,MAAjB,CAAA,CAAA;;AAEA,IAAA,IAAIF,IAAI,CAACI,GAAL,IAAYJ,IAAI,CAACK,KAAjB,IAAA,IAAA,IAAYL,IAAI,CAACK,KAAL,EAAhB,EAAgC;AAC9B,MAAA,MAAMW,UAAU,GAAGC,IAAI,CAACC,KAAL,CAAW,CAACZ,IAAI,CAACC,GAAL,EAAaJ,GAAAA,OAAd,IAA0B,GAArC,IAA4C,GAA/D,CAAA;AACA,MAAA,MAAMgB,aAAa,GAAGF,IAAI,CAACC,KAAL,CAAW,CAACZ,IAAI,CAACC,GAAL,EAAaO,GAAAA,UAAd,IAA6B,GAAxC,IAA+C,GAArE,CAAA;AACA,MAAA,MAAMM,mBAAmB,GAAGD,aAAa,GAAG,EAA5C,CAAA;;AAEA,MAAA,MAAME,GAAG,GAAG,CAACC,GAAD,EAAuBC,GAAvB,KAAuC;AACjDD,QAAAA,GAAG,GAAGE,MAAM,CAACF,GAAD,CAAZ,CAAA;;AACA,QAAA,OAAOA,GAAG,CAACZ,MAAJ,GAAaa,GAApB,EAAyB;UACvBD,GAAG,GAAG,MAAMA,GAAZ,CAAA;AACD,SAAA;;AACD,QAAA,OAAOA,GAAP,CAAA;OALF,CAAA;;AAQAG,MAAAA,OAAO,CAACC,IAAR,CAAA,WAAA,GACSL,GAAG,CAACF,aAAD,EAAgB,CAAhB,CADZ,GAAA,IAAA,GACmCE,GAAG,CAACL,UAAD,EAAa,CAAb,CADtC,uGAKmBC,IAAI,CAACU,GAAL,CACX,CADW,EAEXV,IAAI,CAACW,GAAL,CAAS,MAAM,GAAMR,GAAAA,mBAArB,EAA0C,GAA1C,CAFW,CALnB,GAAA,gBAAA,EASEpB,IATF,IASEA,IAAAA,GAAAA,KAAAA,CAAAA,GAAAA,IAAI,CAAEI,GATR,CAAA,CAAA;AAWD,KAAA;;AAED,IAAA,OAAOF,MAAP,CAAA;GAhDF,CAAA;AAkDD;;;;"}