@tanstack/virtual-core 3.5.1 → 3.7.0
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/dist/cjs/index.cjs +134 -60
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +16 -13
- package/dist/esm/index.d.ts +16 -13
- package/dist/esm/index.js +134 -60
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +169 -85
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -28,13 +28,14 @@ export interface Range {
|
|
|
28
28
|
|
|
29
29
|
type Key = number | string
|
|
30
30
|
|
|
31
|
-
export interface VirtualItem {
|
|
31
|
+
export interface VirtualItem<TItemElement extends Element> {
|
|
32
32
|
key: Key
|
|
33
33
|
index: number
|
|
34
34
|
start: number
|
|
35
35
|
end: number
|
|
36
36
|
size: number
|
|
37
37
|
lane: number
|
|
38
|
+
measureElement: (node: TItemElement | null | undefined) => void
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
export interface Rect {
|
|
@@ -315,9 +316,10 @@ export interface VirtualizerOptions<
|
|
|
315
316
|
scrollMargin?: number
|
|
316
317
|
gap?: number
|
|
317
318
|
indexAttribute?: string
|
|
318
|
-
initialMeasurementsCache?: VirtualItem[]
|
|
319
|
+
initialMeasurementsCache?: VirtualItem<TItemElement>[]
|
|
319
320
|
lanes?: number
|
|
320
321
|
isScrollingResetDelay?: number
|
|
322
|
+
enabled?: boolean
|
|
321
323
|
}
|
|
322
324
|
|
|
323
325
|
export class Virtualizer<
|
|
@@ -330,21 +332,21 @@ export class Virtualizer<
|
|
|
330
332
|
targetWindow: (Window & typeof globalThis) | null = null
|
|
331
333
|
isScrolling: boolean = false
|
|
332
334
|
private scrollToIndexTimeoutId: number | null = null
|
|
333
|
-
measurementsCache: VirtualItem[] = []
|
|
335
|
+
measurementsCache: VirtualItem<TItemElement>[] = []
|
|
334
336
|
private itemSizeCache = new Map<Key, number>()
|
|
335
337
|
private pendingMeasuredCacheIndexes: number[] = []
|
|
336
|
-
scrollRect: Rect
|
|
337
|
-
scrollOffset: number
|
|
338
|
+
scrollRect: Rect | null = null
|
|
339
|
+
scrollOffset: number | null = null
|
|
338
340
|
scrollDirection: ScrollDirection | null = null
|
|
339
341
|
private scrollAdjustments: number = 0
|
|
340
342
|
shouldAdjustScrollPositionOnItemSizeChange:
|
|
341
343
|
| undefined
|
|
342
344
|
| ((
|
|
343
|
-
item: VirtualItem
|
|
345
|
+
item: VirtualItem<TItemElement>,
|
|
344
346
|
delta: number,
|
|
345
347
|
instance: Virtualizer<TScrollElement, TItemElement>,
|
|
346
348
|
) => boolean)
|
|
347
|
-
|
|
349
|
+
elementsCache = new Map<Key, TItemElement>()
|
|
348
350
|
private observer = (() => {
|
|
349
351
|
let _ro: ResizeObserver | null = null
|
|
350
352
|
|
|
@@ -375,17 +377,6 @@ export class Virtualizer<
|
|
|
375
377
|
|
|
376
378
|
constructor(opts: VirtualizerOptions<TScrollElement, TItemElement>) {
|
|
377
379
|
this.setOptions(opts)
|
|
378
|
-
this.scrollRect = this.options.initialRect
|
|
379
|
-
this.scrollOffset =
|
|
380
|
-
typeof this.options.initialOffset === 'function'
|
|
381
|
-
? this.options.initialOffset()
|
|
382
|
-
: this.options.initialOffset
|
|
383
|
-
this.measurementsCache = this.options.initialMeasurementsCache
|
|
384
|
-
this.measurementsCache.forEach((item) => {
|
|
385
|
-
this.itemSizeCache.set(item.key, item.size)
|
|
386
|
-
})
|
|
387
|
-
|
|
388
|
-
this.notify(false, false)
|
|
389
380
|
}
|
|
390
381
|
|
|
391
382
|
setOptions = (opts: VirtualizerOptions<TScrollElement, TItemElement>) => {
|
|
@@ -413,6 +404,7 @@ export class Virtualizer<
|
|
|
413
404
|
initialMeasurementsCache: [],
|
|
414
405
|
lanes: 1,
|
|
415
406
|
isScrollingResetDelay: 150,
|
|
407
|
+
enabled: true,
|
|
416
408
|
...opts,
|
|
417
409
|
}
|
|
418
410
|
}
|
|
@@ -437,22 +429,30 @@ export class Virtualizer<
|
|
|
437
429
|
this.unsubs.filter(Boolean).forEach((d) => d!())
|
|
438
430
|
this.unsubs = []
|
|
439
431
|
this.scrollElement = null
|
|
432
|
+
this.targetWindow = null
|
|
433
|
+
this.observer.disconnect()
|
|
434
|
+
this.elementsCache.clear()
|
|
440
435
|
}
|
|
441
436
|
|
|
442
437
|
_didMount = () => {
|
|
443
|
-
this.measureElementCache.forEach(this.observer.observe)
|
|
444
438
|
return () => {
|
|
445
|
-
this.observer.disconnect()
|
|
446
439
|
this.cleanup()
|
|
447
440
|
}
|
|
448
441
|
}
|
|
449
442
|
|
|
450
443
|
_willUpdate = () => {
|
|
451
|
-
const scrollElement = this.options.
|
|
444
|
+
const scrollElement = this.options.enabled
|
|
445
|
+
? this.options.getScrollElement()
|
|
446
|
+
: null
|
|
452
447
|
|
|
453
448
|
if (this.scrollElement !== scrollElement) {
|
|
454
449
|
this.cleanup()
|
|
455
450
|
|
|
451
|
+
if (!scrollElement) {
|
|
452
|
+
this.notify(false, false)
|
|
453
|
+
return
|
|
454
|
+
}
|
|
455
|
+
|
|
456
456
|
this.scrollElement = scrollElement
|
|
457
457
|
|
|
458
458
|
if (this.scrollElement && 'ownerDocument' in this.scrollElement) {
|
|
@@ -461,7 +461,7 @@ export class Virtualizer<
|
|
|
461
461
|
this.targetWindow = this.scrollElement?.window ?? null
|
|
462
462
|
}
|
|
463
463
|
|
|
464
|
-
this._scrollToOffset(this.
|
|
464
|
+
this._scrollToOffset(this.getScrollOffset(), {
|
|
465
465
|
adjustments: undefined,
|
|
466
466
|
behavior: undefined,
|
|
467
467
|
})
|
|
@@ -477,7 +477,7 @@ export class Virtualizer<
|
|
|
477
477
|
this.options.observeElementOffset(this, (offset, isScrolling) => {
|
|
478
478
|
this.scrollAdjustments = 0
|
|
479
479
|
this.scrollDirection = isScrolling
|
|
480
|
-
? this.
|
|
480
|
+
? this.getScrollOffset() < offset
|
|
481
481
|
? 'forward'
|
|
482
482
|
: 'backward'
|
|
483
483
|
: null
|
|
@@ -493,36 +493,37 @@ export class Virtualizer<
|
|
|
493
493
|
}
|
|
494
494
|
|
|
495
495
|
private getSize = () => {
|
|
496
|
+
if (!this.options.enabled) {
|
|
497
|
+
this.scrollRect = null
|
|
498
|
+
return 0
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
this.scrollRect = this.scrollRect ?? this.options.initialRect
|
|
502
|
+
|
|
496
503
|
return this.scrollRect[this.options.horizontal ? 'width' : 'height']
|
|
497
504
|
}
|
|
498
505
|
|
|
499
|
-
private
|
|
500
|
-
()
|
|
501
|
-
this.
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
this.
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
}
|
|
514
|
-
},
|
|
515
|
-
{
|
|
516
|
-
key: false,
|
|
517
|
-
},
|
|
518
|
-
)
|
|
506
|
+
private getScrollOffset = () => {
|
|
507
|
+
if (!this.options.enabled) {
|
|
508
|
+
this.scrollOffset = null
|
|
509
|
+
return 0
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
this.scrollOffset =
|
|
513
|
+
this.scrollOffset ??
|
|
514
|
+
(typeof this.options.initialOffset === 'function'
|
|
515
|
+
? this.options.initialOffset()
|
|
516
|
+
: this.options.initialOffset)
|
|
517
|
+
|
|
518
|
+
return this.scrollOffset
|
|
519
|
+
}
|
|
519
520
|
|
|
520
521
|
private getFurthestMeasurement = (
|
|
521
|
-
measurements: VirtualItem[],
|
|
522
|
+
measurements: VirtualItem<TItemElement>[],
|
|
522
523
|
index: number,
|
|
523
524
|
) => {
|
|
524
525
|
const furthestMeasurementsFound = new Map<number, true>()
|
|
525
|
-
const furthestMeasurements = new Map<number, VirtualItem
|
|
526
|
+
const furthestMeasurements = new Map<number, VirtualItem<TItemElement>>()
|
|
526
527
|
for (let m = index - 1; m >= 0; m--) {
|
|
527
528
|
const measurement = measurements[m]!
|
|
528
529
|
|
|
@@ -558,9 +559,48 @@ export class Virtualizer<
|
|
|
558
559
|
: undefined
|
|
559
560
|
}
|
|
560
561
|
|
|
562
|
+
private getMeasurementOptions = memo(
|
|
563
|
+
() => [
|
|
564
|
+
this.options.count,
|
|
565
|
+
this.options.paddingStart,
|
|
566
|
+
this.options.scrollMargin,
|
|
567
|
+
this.options.getItemKey,
|
|
568
|
+
this.options.enabled,
|
|
569
|
+
],
|
|
570
|
+
(count, paddingStart, scrollMargin, getItemKey, enabled) => {
|
|
571
|
+
this.pendingMeasuredCacheIndexes = []
|
|
572
|
+
return {
|
|
573
|
+
count,
|
|
574
|
+
paddingStart,
|
|
575
|
+
scrollMargin,
|
|
576
|
+
getItemKey,
|
|
577
|
+
enabled,
|
|
578
|
+
}
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
key: false,
|
|
582
|
+
},
|
|
583
|
+
)
|
|
584
|
+
|
|
561
585
|
private getMeasurements = memo(
|
|
562
586
|
() => [this.getMeasurementOptions(), this.itemSizeCache],
|
|
563
|
-
(
|
|
587
|
+
(
|
|
588
|
+
{ count, paddingStart, scrollMargin, getItemKey, enabled },
|
|
589
|
+
itemSizeCache,
|
|
590
|
+
) => {
|
|
591
|
+
if (!enabled) {
|
|
592
|
+
this.measurementsCache = []
|
|
593
|
+
this.itemSizeCache.clear()
|
|
594
|
+
return []
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
if (this.measurementsCache.length === 0) {
|
|
598
|
+
this.measurementsCache = this.options.initialMeasurementsCache
|
|
599
|
+
this.measurementsCache.forEach((item) => {
|
|
600
|
+
this.itemSizeCache.set(item.key, item.size)
|
|
601
|
+
})
|
|
602
|
+
}
|
|
603
|
+
|
|
564
604
|
const min =
|
|
565
605
|
this.pendingMeasuredCacheIndexes.length > 0
|
|
566
606
|
? Math.min(...this.pendingMeasuredCacheIndexes)
|
|
@@ -570,6 +610,38 @@ export class Virtualizer<
|
|
|
570
610
|
const measurements = this.measurementsCache.slice(0, min)
|
|
571
611
|
|
|
572
612
|
for (let i = min; i < count; i++) {
|
|
613
|
+
let measureElement = this.measurementsCache[i]?.measureElement
|
|
614
|
+
|
|
615
|
+
if (!measureElement) {
|
|
616
|
+
measureElement = (node: TItemElement | null | undefined) => {
|
|
617
|
+
const key = getItemKey(i)
|
|
618
|
+
const prevNode = this.elementsCache.get(key)
|
|
619
|
+
|
|
620
|
+
if (!node) {
|
|
621
|
+
if (prevNode) {
|
|
622
|
+
this.observer.unobserve(prevNode)
|
|
623
|
+
this.elementsCache.delete(key)
|
|
624
|
+
}
|
|
625
|
+
return
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
if (prevNode !== node) {
|
|
629
|
+
if (prevNode) {
|
|
630
|
+
this.observer.unobserve(prevNode)
|
|
631
|
+
}
|
|
632
|
+
this.observer.observe(node)
|
|
633
|
+
this.elementsCache.set(key, node)
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
if (node.isConnected) {
|
|
637
|
+
this.resizeItem(
|
|
638
|
+
i,
|
|
639
|
+
this.options.measureElement(node, undefined, this),
|
|
640
|
+
)
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
|
|
573
645
|
const key = getItemKey(i)
|
|
574
646
|
|
|
575
647
|
const furthestMeasurement =
|
|
@@ -600,6 +672,7 @@ export class Virtualizer<
|
|
|
600
672
|
end,
|
|
601
673
|
key,
|
|
602
674
|
lane,
|
|
675
|
+
measureElement,
|
|
603
676
|
}
|
|
604
677
|
}
|
|
605
678
|
|
|
@@ -614,7 +687,7 @@ export class Virtualizer<
|
|
|
614
687
|
)
|
|
615
688
|
|
|
616
689
|
calculateRange = memo(
|
|
617
|
-
() => [this.getMeasurements(), this.getSize(), this.
|
|
690
|
+
() => [this.getMeasurements(), this.getSize(), this.getScrollOffset()],
|
|
618
691
|
(measurements, outerSize, scrollOffset) => {
|
|
619
692
|
return (this.range =
|
|
620
693
|
measurements.length > 0 && outerSize > 0
|
|
@@ -672,34 +745,37 @@ export class Virtualizer<
|
|
|
672
745
|
node: TItemElement,
|
|
673
746
|
entry: ResizeObserverEntry | undefined,
|
|
674
747
|
) => {
|
|
675
|
-
const
|
|
748
|
+
const i = this.indexFromElement(node)
|
|
749
|
+
const item = this.getMeasurements()[i]
|
|
676
750
|
|
|
677
751
|
if (!item || !node.isConnected) {
|
|
678
|
-
this.
|
|
752
|
+
this.elementsCache.forEach((cached, key) => {
|
|
679
753
|
if (cached === node) {
|
|
680
754
|
this.observer.unobserve(node)
|
|
681
|
-
this.
|
|
755
|
+
this.elementsCache.delete(key)
|
|
682
756
|
}
|
|
683
757
|
})
|
|
684
758
|
return
|
|
685
759
|
}
|
|
686
760
|
|
|
687
|
-
const prevNode = this.
|
|
761
|
+
const prevNode = this.elementsCache.get(item.key)
|
|
688
762
|
|
|
689
763
|
if (prevNode !== node) {
|
|
690
764
|
if (prevNode) {
|
|
691
765
|
this.observer.unobserve(prevNode)
|
|
692
766
|
}
|
|
693
767
|
this.observer.observe(node)
|
|
694
|
-
this.
|
|
768
|
+
this.elementsCache.set(item.key, node)
|
|
695
769
|
}
|
|
696
770
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
this.resizeItem(item, measuredItemSize)
|
|
771
|
+
this.resizeItem(i, this.options.measureElement(node, entry, this))
|
|
700
772
|
}
|
|
701
773
|
|
|
702
|
-
resizeItem = (
|
|
774
|
+
resizeItem = (index: number, size: number) => {
|
|
775
|
+
const item = this.getMeasurements()[index]
|
|
776
|
+
if (!item) {
|
|
777
|
+
return
|
|
778
|
+
}
|
|
703
779
|
const itemSize = this.itemSizeCache.get(item.key) ?? item.size
|
|
704
780
|
const delta = size - itemSize
|
|
705
781
|
|
|
@@ -707,13 +783,13 @@ export class Virtualizer<
|
|
|
707
783
|
if (
|
|
708
784
|
this.shouldAdjustScrollPositionOnItemSizeChange !== undefined
|
|
709
785
|
? this.shouldAdjustScrollPositionOnItemSizeChange(item, delta, this)
|
|
710
|
-
: item.start < this.
|
|
786
|
+
: item.start < this.getScrollOffset() + this.scrollAdjustments
|
|
711
787
|
) {
|
|
712
788
|
if (process.env.NODE_ENV !== 'production' && this.options.debug) {
|
|
713
789
|
console.info('correction', delta)
|
|
714
790
|
}
|
|
715
791
|
|
|
716
|
-
this._scrollToOffset(this.
|
|
792
|
+
this._scrollToOffset(this.getScrollOffset(), {
|
|
717
793
|
adjustments: (this.scrollAdjustments += delta),
|
|
718
794
|
behavior: undefined,
|
|
719
795
|
})
|
|
@@ -726,7 +802,7 @@ export class Virtualizer<
|
|
|
726
802
|
}
|
|
727
803
|
}
|
|
728
804
|
|
|
729
|
-
measureElement = (node: TItemElement | null) => {
|
|
805
|
+
measureElement = (node: TItemElement | null | undefined) => {
|
|
730
806
|
if (!node) {
|
|
731
807
|
return
|
|
732
808
|
}
|
|
@@ -737,7 +813,7 @@ export class Virtualizer<
|
|
|
737
813
|
getVirtualItems = memo(
|
|
738
814
|
() => [this.getIndexes(), this.getMeasurements()],
|
|
739
815
|
(indexes, measurements) => {
|
|
740
|
-
const virtualItems: VirtualItem[] = []
|
|
816
|
+
const virtualItems: VirtualItem<TItemElement>[] = []
|
|
741
817
|
|
|
742
818
|
for (let k = 0, len = indexes.length; k < len; k++) {
|
|
743
819
|
const i = indexes[k]!
|
|
@@ -756,7 +832,9 @@ export class Virtualizer<
|
|
|
756
832
|
|
|
757
833
|
getVirtualItemForOffset = (offset: number) => {
|
|
758
834
|
const measurements = this.getMeasurements()
|
|
759
|
-
|
|
835
|
+
if (measurements.length === 0) {
|
|
836
|
+
return undefined
|
|
837
|
+
}
|
|
760
838
|
return notUndefined(
|
|
761
839
|
measurements[
|
|
762
840
|
findNearestBinarySearch(
|
|
@@ -771,11 +849,12 @@ export class Virtualizer<
|
|
|
771
849
|
|
|
772
850
|
getOffsetForAlignment = (toOffset: number, align: ScrollAlignment) => {
|
|
773
851
|
const size = this.getSize()
|
|
852
|
+
const scrollOffset = this.getScrollOffset()
|
|
774
853
|
|
|
775
854
|
if (align === 'auto') {
|
|
776
|
-
if (toOffset <=
|
|
855
|
+
if (toOffset <= scrollOffset) {
|
|
777
856
|
align = 'start'
|
|
778
|
-
} else if (toOffset >=
|
|
857
|
+
} else if (toOffset >= scrollOffset + size) {
|
|
779
858
|
align = 'end'
|
|
780
859
|
} else {
|
|
781
860
|
align = 'start'
|
|
@@ -799,7 +878,7 @@ export class Virtualizer<
|
|
|
799
878
|
: this.scrollElement[scrollSizeProp]
|
|
800
879
|
: 0
|
|
801
880
|
|
|
802
|
-
const maxOffset = scrollSize -
|
|
881
|
+
const maxOffset = scrollSize - size
|
|
803
882
|
|
|
804
883
|
return Math.max(Math.min(maxOffset, toOffset), 0)
|
|
805
884
|
}
|
|
@@ -807,33 +886,33 @@ export class Virtualizer<
|
|
|
807
886
|
getOffsetForIndex = (index: number, align: ScrollAlignment = 'auto') => {
|
|
808
887
|
index = Math.max(0, Math.min(index, this.options.count - 1))
|
|
809
888
|
|
|
810
|
-
const
|
|
889
|
+
const item = this.getMeasurements()[index]
|
|
890
|
+
if (!item) {
|
|
891
|
+
return undefined
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
const size = this.getSize()
|
|
895
|
+
const scrollOffset = this.getScrollOffset()
|
|
811
896
|
|
|
812
897
|
if (align === 'auto') {
|
|
813
|
-
if (
|
|
814
|
-
measurement.end >=
|
|
815
|
-
this.scrollOffset + this.getSize() - this.options.scrollPaddingEnd
|
|
816
|
-
) {
|
|
898
|
+
if (item.end >= scrollOffset + size - this.options.scrollPaddingEnd) {
|
|
817
899
|
align = 'end'
|
|
818
|
-
} else if (
|
|
819
|
-
measurement.start <=
|
|
820
|
-
this.scrollOffset + this.options.scrollPaddingStart
|
|
821
|
-
) {
|
|
900
|
+
} else if (item.start <= scrollOffset + this.options.scrollPaddingStart) {
|
|
822
901
|
align = 'start'
|
|
823
902
|
} else {
|
|
824
|
-
return [
|
|
903
|
+
return [scrollOffset, align] as const
|
|
825
904
|
}
|
|
826
905
|
}
|
|
827
906
|
|
|
828
907
|
const toOffset =
|
|
829
908
|
align === 'end'
|
|
830
|
-
?
|
|
831
|
-
:
|
|
909
|
+
? item.end + this.options.scrollPaddingEnd
|
|
910
|
+
: item.start - this.options.scrollPaddingStart
|
|
832
911
|
|
|
833
912
|
return [this.getOffsetForAlignment(toOffset, align), align] as const
|
|
834
913
|
}
|
|
835
914
|
|
|
836
|
-
private isDynamicMode = () => this.
|
|
915
|
+
private isDynamicMode = () => this.elementsCache.size > 0
|
|
837
916
|
|
|
838
917
|
private cancelScrollToIndex = () => {
|
|
839
918
|
if (this.scrollToIndexTimeoutId !== null && this.targetWindow) {
|
|
@@ -874,22 +953,27 @@ export class Virtualizer<
|
|
|
874
953
|
)
|
|
875
954
|
}
|
|
876
955
|
|
|
877
|
-
const
|
|
956
|
+
const offsetAndAlign = this.getOffsetForIndex(index, initialAlign)
|
|
957
|
+
if (!offsetAndAlign) return
|
|
958
|
+
|
|
959
|
+
const [offset, align] = offsetAndAlign
|
|
878
960
|
|
|
879
|
-
this._scrollToOffset(
|
|
961
|
+
this._scrollToOffset(offset, { adjustments: undefined, behavior })
|
|
880
962
|
|
|
881
963
|
if (behavior !== 'smooth' && this.isDynamicMode() && this.targetWindow) {
|
|
882
964
|
this.scrollToIndexTimeoutId = this.targetWindow.setTimeout(() => {
|
|
883
965
|
this.scrollToIndexTimeoutId = null
|
|
884
966
|
|
|
885
|
-
const elementInDOM = this.
|
|
967
|
+
const elementInDOM = this.elementsCache.has(
|
|
886
968
|
this.options.getItemKey(index),
|
|
887
969
|
)
|
|
888
970
|
|
|
889
971
|
if (elementInDOM) {
|
|
890
|
-
const [
|
|
972
|
+
const [latestOffset] = notUndefined(
|
|
973
|
+
this.getOffsetForIndex(index, align),
|
|
974
|
+
)
|
|
891
975
|
|
|
892
|
-
if (!approxEqual(
|
|
976
|
+
if (!approxEqual(latestOffset, this.getScrollOffset())) {
|
|
893
977
|
this.scrollToIndex(index, { align, behavior })
|
|
894
978
|
}
|
|
895
979
|
} else {
|
|
@@ -908,7 +992,7 @@ export class Virtualizer<
|
|
|
908
992
|
)
|
|
909
993
|
}
|
|
910
994
|
|
|
911
|
-
this._scrollToOffset(this.
|
|
995
|
+
this._scrollToOffset(this.getScrollOffset() + delta, {
|
|
912
996
|
adjustments: undefined,
|
|
913
997
|
behavior,
|
|
914
998
|
})
|
|
@@ -979,12 +1063,12 @@ const findNearestBinarySearch = (
|
|
|
979
1063
|
}
|
|
980
1064
|
}
|
|
981
1065
|
|
|
982
|
-
function calculateRange({
|
|
1066
|
+
function calculateRange<TItemElement extends Element>({
|
|
983
1067
|
measurements,
|
|
984
1068
|
outerSize,
|
|
985
1069
|
scrollOffset,
|
|
986
1070
|
}: {
|
|
987
|
-
measurements: VirtualItem[]
|
|
1071
|
+
measurements: VirtualItem<TItemElement>[]
|
|
988
1072
|
outerSize: number
|
|
989
1073
|
scrollOffset: number
|
|
990
1074
|
}) {
|