@tanstack/virtual-core 3.0.0-beta.30 → 3.0.0-beta.32

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
@@ -289,7 +289,7 @@ export class Virtualizer<
289
289
  private itemMeasurementsCache: Record<Key, number> = {}
290
290
  private pendingMeasuredCacheIndexes: number[] = []
291
291
  private scrollRect: Rect
292
- private scrollOffset: number
292
+ scrollOffset: number
293
293
  private scrollAdjustments: number = 0
294
294
  private measureElementCache: Record<Key, TItemElement> = {}
295
295
  private pendingScrollToIndexCallback: (() => void) | null = null
@@ -611,10 +611,7 @@ export class Virtualizer<
611
611
  },
612
612
  )
613
613
 
614
- scrollToOffset = (
615
- toOffset: number,
616
- { align = 'start', behavior }: ScrollToOffsetOptions = {},
617
- ) => {
614
+ getOffsetForAlignment = (toOffset: number, align: ScrollAlignment) => {
618
615
  const offset = this.scrollOffset
619
616
  const size = this.getSize()
620
617
 
@@ -628,35 +625,43 @@ export class Virtualizer<
628
625
  }
629
626
  }
630
627
 
628
+ if (align === 'start') {
629
+ return toOffset
630
+ } else if (align === 'end') {
631
+ return toOffset - size
632
+ } else if (align === 'center') {
633
+ return toOffset - size / 2
634
+ }
635
+ return toOffset
636
+ }
637
+
638
+ scrollToOffset = (
639
+ toOffset: number,
640
+ { align = 'start', behavior }: ScrollToOffsetOptions = {},
641
+ ) => {
631
642
  const options = {
632
643
  adjustments: undefined,
633
644
  behavior,
634
645
  sync: false,
635
646
  }
636
- if (align === 'start') {
637
- this._scrollToOffset(toOffset, options)
638
- } else if (align === 'end') {
639
- this._scrollToOffset(toOffset - size, options)
640
- } else if (align === 'center') {
641
- this._scrollToOffset(toOffset - size / 2, options)
642
- }
647
+ this._scrollToOffset(this.getOffsetForAlignment(toOffset, align), options)
643
648
  }
644
649
 
645
650
  scrollToIndex = (
646
651
  index: number,
647
- { align = 'auto', ...rest }: ScrollToIndexOptions = {},
652
+ { align = 'auto', behavior }: ScrollToIndexOptions = {},
648
653
  ) => {
649
654
  this.pendingScrollToIndexCallback = null
650
655
 
651
- const measurements = this.getMeasurements()
652
656
  const offset = this.scrollOffset
653
657
  const size = this.getSize()
654
658
  const { count } = this.options
655
659
 
660
+ const measurements = this.getMeasurements()
656
661
  const measurement = measurements[Math.max(0, Math.min(index, count - 1))]
657
662
 
658
663
  if (!measurement) {
659
- return
664
+ throw new Error(`VirtualItem not found for index = ${index}`)
660
665
  }
661
666
 
662
667
  if (align === 'auto') {
@@ -672,31 +677,45 @@ export class Virtualizer<
672
677
  }
673
678
  }
674
679
 
675
- const toOffset =
676
- align === 'end'
677
- ? measurement.end + this.options.scrollPaddingEnd
678
- : measurement.start - this.options.scrollPaddingStart
680
+ const getOffsetForIndexAndAlignment = (measurement: VirtualItem) => {
681
+ const toOffset =
682
+ align === 'end'
683
+ ? measurement.end + this.options.scrollPaddingEnd
684
+ : measurement.start - this.options.scrollPaddingStart
685
+
686
+ return this.getOffsetForAlignment(toOffset, align)
687
+ }
688
+
689
+ const toOffset = getOffsetForIndexAndAlignment(measurement)
679
690
 
680
- this.scrollToOffset(toOffset, { align, ...rest })
691
+ if (toOffset === offset) {
692
+ return
693
+ }
694
+
695
+ const options = {
696
+ adjustments: undefined,
697
+ behavior,
698
+ sync: false,
699
+ }
700
+ this._scrollToOffset(toOffset, options)
681
701
 
682
702
  const isDynamic = Object.keys(this.measureElementCache).length > 0
683
703
 
684
704
  if (isDynamic) {
685
- const didSeen = () =>
686
- typeof this.itemMeasurementsCache[this.options.getItemKey(index)] ===
687
- 'number'
688
-
689
- if (!didSeen()) {
690
- this.pendingScrollToIndexCallback = () => {
691
- if (didSeen()) {
692
- this.pendingScrollToIndexCallback = null
693
- this.scrollToIndex(index, { align, ...rest })
694
- }
695
- }
705
+ this.pendingScrollToIndexCallback = () => {
706
+ this.scrollToIndex(index, { align, behavior })
696
707
  }
697
708
  }
698
709
  }
699
710
 
711
+ scrollBy = (adjustments: number, options?: { behavior: ScrollBehavior }) => {
712
+ this._scrollToOffset(this.scrollOffset, {
713
+ adjustments,
714
+ behavior: options?.behavior,
715
+ sync: false,
716
+ })
717
+ }
718
+
700
719
  getTotalSize = () =>
701
720
  (this.getMeasurements()[this.options.count - 1]?.end ||
702
721
  this.options.paddingStart) + this.options.paddingEnd