@tanstack/virtual-core 3.0.0-beta.63 → 3.0.0-beta.66

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
@@ -243,7 +243,10 @@ export interface VirtualizerOptions<
243
243
  // Optional
244
244
  debug?: any
245
245
  initialRect?: Rect
246
- onChange?: (instance: Virtualizer<TScrollElement, TItemElement>) => void
246
+ onChange?: (
247
+ instance: Virtualizer<TScrollElement, TItemElement>,
248
+ sync: boolean,
249
+ ) => void
247
250
  measureElement?: (
248
251
  element: TItemElement,
249
252
  entry: ResizeObserverEntry | undefined,
@@ -307,10 +310,7 @@ export class Virtualizer<
307
310
  unobserve: (target: Element) => get()?.unobserve(target),
308
311
  }
309
312
  })()
310
- range: { startIndex: number; endIndex: number } = {
311
- startIndex: 0,
312
- endIndex: 0,
313
- }
313
+ range: { startIndex: number; endIndex: number } | null = null
314
314
 
315
315
  constructor(opts: VirtualizerOptions<TScrollElement, TItemElement>) {
316
316
  this.setOptions(opts)
@@ -352,10 +352,34 @@ export class Virtualizer<
352
352
  }
353
353
  }
354
354
 
355
- private notify = () => {
356
- this.options.onChange?.(this)
355
+ private notify = (sync: boolean) => {
356
+ this.options.onChange?.(this, sync)
357
357
  }
358
358
 
359
+ private maybeNotify = memo(
360
+ () => {
361
+ this.calculateRange()
362
+
363
+ return [
364
+ this.isScrolling,
365
+ this.range ? this.range.startIndex : null,
366
+ this.range ? this.range.endIndex : null,
367
+ ]
368
+ },
369
+ (isScrolling) => {
370
+ this.notify(isScrolling)
371
+ },
372
+ {
373
+ key: process.env.NODE_ENV !== 'production' && 'maybeNotify',
374
+ debug: () => this.options.debug,
375
+ initialDeps: [
376
+ this.isScrolling,
377
+ this.range ? this.range.startIndex : null,
378
+ this.range ? this.range.endIndex : null,
379
+ ] as [boolean, number | null, number | null],
380
+ },
381
+ )
382
+
359
383
  private cleanup = () => {
360
384
  this.unsubs.filter(Boolean).forEach((d) => d!())
361
385
  this.unsubs = []
@@ -385,15 +409,8 @@ export class Virtualizer<
385
409
 
386
410
  this.unsubs.push(
387
411
  this.options.observeElementRect(this, (rect) => {
388
- const prev = this.scrollRect
389
412
  this.scrollRect = rect
390
- if (
391
- this.options.horizontal
392
- ? rect.width !== prev.width
393
- : rect.height !== prev.height
394
- ) {
395
- this.maybeNotify()
396
- }
413
+ this.maybeNotify()
397
414
  }),
398
415
  )
399
416
 
@@ -549,11 +566,14 @@ export class Virtualizer<
549
566
  calculateRange = memo(
550
567
  () => [this.getMeasurements(), this.getSize(), this.scrollOffset],
551
568
  (measurements, outerSize, scrollOffset) => {
552
- return (this.range = calculateRange({
553
- measurements,
554
- outerSize,
555
- scrollOffset,
556
- }))
569
+ return (this.range =
570
+ measurements.length > 0 && outerSize > 0
571
+ ? calculateRange({
572
+ measurements,
573
+ outerSize,
574
+ scrollOffset,
575
+ })
576
+ : null)
557
577
  },
558
578
  {
559
579
  key: process.env.NODE_ENV !== 'production' && 'calculateRange',
@@ -561,36 +581,15 @@ export class Virtualizer<
561
581
  },
562
582
  )
563
583
 
564
- private maybeNotify = memo(
565
- () => {
566
- const range = this.calculateRange()
567
-
568
- return [range.startIndex, range.endIndex, this.isScrolling]
569
- },
570
- () => {
571
- this.notify()
572
- },
573
- {
574
- key: process.env.NODE_ENV !== 'production' && 'maybeNotify',
575
- debug: () => this.options.debug,
576
- initialDeps: [
577
- this.range.startIndex,
578
- this.range.endIndex,
579
- this.isScrolling,
580
- ],
581
- },
582
- )
583
-
584
584
  private getIndexes = memo(
585
585
  () => [
586
586
  this.options.rangeExtractor,
587
587
  this.calculateRange(),
588
588
  this.options.overscan,
589
589
  this.options.count,
590
- this.getSize(),
591
590
  ],
592
- (rangeExtractor, range, overscan, count, outerSize) => {
593
- return outerSize === 0
591
+ (rangeExtractor, range, overscan, count) => {
592
+ return range === null
594
593
  ? []
595
594
  : rangeExtractor({
596
595
  ...range,
@@ -668,7 +667,7 @@ export class Virtualizer<
668
667
  this.pendingMeasuredCacheIndexes.push(item.index)
669
668
  this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size))
670
669
 
671
- this.notify()
670
+ this.notify(false)
672
671
  }
673
672
  }
674
673
 
@@ -881,7 +880,7 @@ export class Virtualizer<
881
880
 
882
881
  measure = () => {
883
882
  this.itemSizeCache = new Map()
884
- this.notify()
883
+ this.notify(false)
885
884
  }
886
885
  }
887
886