@tanstack/virtual-core 3.0.0-beta.35 → 3.0.0-beta.39
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/build/lib/index.d.ts +2 -4
- package/build/lib/index.esm.js +74 -41
- package/build/lib/index.esm.js.map +1 -1
- package/build/lib/index.js +74 -41
- package/build/lib/index.js.map +1 -1
- package/build/lib/index.mjs +74 -41
- package/build/lib/index.mjs.map +1 -1
- package/build/umd/index.development.js +74 -41
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +88 -38
package/src/index.ts
CHANGED
|
@@ -288,6 +288,7 @@ export class Virtualizer<
|
|
|
288
288
|
scrollElement: TScrollElement | null = null
|
|
289
289
|
isScrolling: boolean = false
|
|
290
290
|
private isScrollingTimeoutId: ReturnType<typeof setTimeout> | null = null
|
|
291
|
+
private scrollToIndexTimeoutId: ReturnType<typeof setTimeout> | null = null
|
|
291
292
|
measurementsCache: VirtualItem[] = []
|
|
292
293
|
private itemSizeCache: Record<Key, number> = {}
|
|
293
294
|
private pendingMeasuredCacheIndexes: number[] = []
|
|
@@ -296,7 +297,6 @@ export class Virtualizer<
|
|
|
296
297
|
scrollDirection: ScrollDirection | null = null
|
|
297
298
|
private scrollAdjustments: number = 0
|
|
298
299
|
private measureElementCache: Record<Key, TItemElement> = {}
|
|
299
|
-
private pendingScrollToIndexCallback: (() => void) | null = null
|
|
300
300
|
private getResizeObserver = (() => {
|
|
301
301
|
let _ro: ResizeObserver | null = null
|
|
302
302
|
|
|
@@ -380,8 +380,6 @@ export class Virtualizer<
|
|
|
380
380
|
}
|
|
381
381
|
|
|
382
382
|
_willUpdate = () => {
|
|
383
|
-
this.pendingScrollToIndexCallback?.()
|
|
384
|
-
|
|
385
383
|
const scrollElement = this.options.getScrollElement()
|
|
386
384
|
|
|
387
385
|
if (this.scrollElement !== scrollElement) {
|
|
@@ -521,7 +519,7 @@ export class Virtualizer<
|
|
|
521
519
|
return rangeExtractor({
|
|
522
520
|
...range,
|
|
523
521
|
overscan,
|
|
524
|
-
count
|
|
522
|
+
count,
|
|
525
523
|
})
|
|
526
524
|
},
|
|
527
525
|
{
|
|
@@ -579,11 +577,7 @@ export class Virtualizer<
|
|
|
579
577
|
const delta = measuredItemSize - itemSize
|
|
580
578
|
|
|
581
579
|
if (delta !== 0) {
|
|
582
|
-
if (
|
|
583
|
-
item.start < this.scrollOffset &&
|
|
584
|
-
this.isScrolling &&
|
|
585
|
-
this.scrollDirection === 'backward'
|
|
586
|
-
) {
|
|
580
|
+
if (item.start < this.scrollOffset) {
|
|
587
581
|
if (process.env.NODE_ENV !== 'production' && this.options.debug) {
|
|
588
582
|
console.info('correction', delta)
|
|
589
583
|
}
|
|
@@ -632,13 +626,12 @@ export class Virtualizer<
|
|
|
632
626
|
)
|
|
633
627
|
|
|
634
628
|
getOffsetForAlignment = (toOffset: number, align: ScrollAlignment) => {
|
|
635
|
-
const offset = this.scrollOffset
|
|
636
629
|
const size = this.getSize()
|
|
637
630
|
|
|
638
631
|
if (align === 'auto') {
|
|
639
|
-
if (toOffset <=
|
|
632
|
+
if (toOffset <= this.scrollOffset) {
|
|
640
633
|
align = 'start'
|
|
641
|
-
} else if (toOffset >=
|
|
634
|
+
} else if (toOffset >= this.scrollOffset + size) {
|
|
642
635
|
align = 'end'
|
|
643
636
|
} else {
|
|
644
637
|
align = 'start'
|
|
@@ -646,19 +639,40 @@ export class Virtualizer<
|
|
|
646
639
|
}
|
|
647
640
|
|
|
648
641
|
if (align === 'start') {
|
|
649
|
-
|
|
642
|
+
toOffset = toOffset
|
|
650
643
|
} else if (align === 'end') {
|
|
651
|
-
|
|
644
|
+
toOffset = toOffset - size
|
|
652
645
|
} else if (align === 'center') {
|
|
653
|
-
|
|
646
|
+
toOffset = toOffset - size / 2
|
|
654
647
|
}
|
|
655
|
-
|
|
648
|
+
|
|
649
|
+
const scrollSizeProp = this.options.horizontal
|
|
650
|
+
? 'scrollWidth'
|
|
651
|
+
: 'scrollHeight'
|
|
652
|
+
const scrollSize = this.scrollElement
|
|
653
|
+
? 'document' in this.scrollElement
|
|
654
|
+
? this.scrollElement.document.documentElement[scrollSizeProp]
|
|
655
|
+
: this.scrollElement[scrollSizeProp]
|
|
656
|
+
: 0
|
|
657
|
+
|
|
658
|
+
const maxOffset = scrollSize - this.getSize()
|
|
659
|
+
|
|
660
|
+
return Math.max(Math.min(maxOffset, toOffset), 0)
|
|
656
661
|
}
|
|
657
662
|
|
|
658
663
|
scrollToOffset = (
|
|
659
664
|
toOffset: number,
|
|
660
665
|
{ align = 'start', behavior }: ScrollToOffsetOptions = {},
|
|
661
666
|
) => {
|
|
667
|
+
const isDynamic = Object.keys(this.measureElementCache).length > 0
|
|
668
|
+
|
|
669
|
+
if (isDynamic && behavior === 'smooth') {
|
|
670
|
+
console.warn(
|
|
671
|
+
'The `smooth` scroll behavior is not supported with dynamic size.',
|
|
672
|
+
)
|
|
673
|
+
return
|
|
674
|
+
}
|
|
675
|
+
|
|
662
676
|
const options = {
|
|
663
677
|
adjustments: undefined,
|
|
664
678
|
behavior,
|
|
@@ -671,25 +685,43 @@ export class Virtualizer<
|
|
|
671
685
|
index: number,
|
|
672
686
|
{ align = 'auto', behavior }: ScrollToIndexOptions = {},
|
|
673
687
|
) => {
|
|
674
|
-
this.
|
|
688
|
+
if (this.scrollToIndexTimeoutId !== null) {
|
|
689
|
+
clearTimeout(this.scrollToIndexTimeoutId)
|
|
690
|
+
this.scrollToIndexTimeoutId = null
|
|
691
|
+
}
|
|
675
692
|
|
|
676
|
-
const
|
|
677
|
-
|
|
678
|
-
|
|
693
|
+
const isDynamic = Object.keys(this.measureElementCache).length > 0
|
|
694
|
+
|
|
695
|
+
if (isDynamic && behavior === 'smooth') {
|
|
696
|
+
console.warn(
|
|
697
|
+
'The `smooth` scroll behavior is not supported with dynamic size.',
|
|
698
|
+
)
|
|
699
|
+
return
|
|
700
|
+
}
|
|
679
701
|
|
|
680
|
-
const
|
|
681
|
-
|
|
702
|
+
const getMeasurement = () => {
|
|
703
|
+
const measurements = this.getMeasurements()
|
|
704
|
+
const measurement =
|
|
705
|
+
measurements[Math.max(0, Math.min(index, this.options.count - 1))]
|
|
682
706
|
|
|
683
|
-
|
|
684
|
-
|
|
707
|
+
if (!measurement) {
|
|
708
|
+
throw new Error(`VirtualItem not found for index = ${index}`)
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
return measurement
|
|
685
712
|
}
|
|
686
713
|
|
|
714
|
+
const measurement = getMeasurement()
|
|
715
|
+
|
|
687
716
|
if (align === 'auto') {
|
|
688
|
-
if (
|
|
717
|
+
if (
|
|
718
|
+
measurement.end >=
|
|
719
|
+
this.scrollOffset + this.getSize() - this.options.scrollPaddingEnd
|
|
720
|
+
) {
|
|
689
721
|
align = 'end'
|
|
690
722
|
} else if (
|
|
691
723
|
measurement.start <=
|
|
692
|
-
|
|
724
|
+
this.scrollOffset + this.options.scrollPaddingStart
|
|
693
725
|
) {
|
|
694
726
|
align = 'start'
|
|
695
727
|
} else {
|
|
@@ -708,29 +740,47 @@ export class Virtualizer<
|
|
|
708
740
|
|
|
709
741
|
const toOffset = getOffsetForIndexAndAlignment(measurement)
|
|
710
742
|
|
|
711
|
-
if (toOffset === offset) {
|
|
712
|
-
return
|
|
713
|
-
}
|
|
714
|
-
|
|
715
743
|
const options = {
|
|
716
744
|
adjustments: undefined,
|
|
717
745
|
behavior,
|
|
718
746
|
}
|
|
719
747
|
this._scrollToOffset(toOffset, options)
|
|
720
748
|
|
|
721
|
-
const
|
|
749
|
+
const approxEqual = (a: number, b: number) => Math.abs(a - b) < 1
|
|
722
750
|
|
|
723
751
|
if (isDynamic) {
|
|
724
|
-
this.
|
|
725
|
-
this.
|
|
726
|
-
|
|
752
|
+
this.scrollToIndexTimeoutId = setTimeout(() => {
|
|
753
|
+
this.scrollToIndexTimeoutId = null
|
|
754
|
+
|
|
755
|
+
const elementInDOM =
|
|
756
|
+
!!this.measureElementCache[this.options.getItemKey(index)]
|
|
757
|
+
|
|
758
|
+
if (elementInDOM) {
|
|
759
|
+
const toOffset = getOffsetForIndexAndAlignment(getMeasurement())
|
|
760
|
+
|
|
761
|
+
if (!approxEqual(toOffset, this.scrollOffset)) {
|
|
762
|
+
this.scrollToIndex(index, { align, behavior })
|
|
763
|
+
}
|
|
764
|
+
} else {
|
|
765
|
+
this.scrollToIndex(index, { align, behavior })
|
|
766
|
+
}
|
|
767
|
+
})
|
|
727
768
|
}
|
|
728
769
|
}
|
|
729
770
|
|
|
730
|
-
scrollBy = (
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
771
|
+
scrollBy = (delta: number, { behavior }: ScrollToOffsetOptions = {}) => {
|
|
772
|
+
const isDynamic = Object.keys(this.measureElementCache).length > 0
|
|
773
|
+
|
|
774
|
+
if (isDynamic && behavior === 'smooth') {
|
|
775
|
+
console.warn(
|
|
776
|
+
'The `smooth` scroll behavior is not supported with dynamic size.',
|
|
777
|
+
)
|
|
778
|
+
return
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
this._scrollToOffset(this.scrollOffset + delta, {
|
|
782
|
+
adjustments: undefined,
|
|
783
|
+
behavior,
|
|
734
784
|
})
|
|
735
785
|
}
|
|
736
786
|
|