@@ -972,11 +972,30 @@ export class Virtualizer<
972972 )
973973 }
974974
975+ private getMaxScrollOffset = ( ) => {
976+ if ( ! this . scrollElement ) return 0
977+
978+ if ( 'scrollHeight' in this . scrollElement ) {
979+ // Element
980+ return this . options . horizontal
981+ ? this . scrollElement . scrollWidth - this . scrollElement . clientWidth
982+ : this . scrollElement . scrollHeight - this . scrollElement . clientHeight
983+ } else {
984+ // Window
985+ const doc = this . scrollElement . document . documentElement
986+ return this . options . horizontal
987+ ? doc . scrollWidth - this . scrollElement . innerWidth
988+ : doc . scrollHeight - this . scrollElement . innerHeight
989+ }
990+ }
991+
975992 getOffsetForAlignment = (
976993 toOffset : number ,
977994 align : ScrollAlignment ,
978995 itemSize = 0 ,
979996 ) => {
997+ if ( ! this . scrollElement ) return 0
998+
980999 const size = this . getSize ( )
9811000 const scrollOffset = this . getScrollOffset ( )
9821001
@@ -992,7 +1011,7 @@ export class Virtualizer<
9921011 toOffset -= size
9931012 }
9941013
995- const maxOffset = this . getTotalSize ( ) + this . options . scrollMargin - size
1014+ const maxOffset = this . getMaxScrollOffset ( )
9961015
9971016 return Math . max ( Math . min ( maxOffset , toOffset ) , 0 )
9981017 }
@@ -1014,10 +1033,18 @@ export class Virtualizer<
10141033 } else if ( item . start <= scrollOffset + this . options . scrollPaddingStart ) {
10151034 align = 'start'
10161035 } else {
1017- return [ scrollOffset , align ] as const
1036+ // Item is already visible, return current position with concrete alignment
1037+ // to avoid infinite retry loop if measurements change
1038+ return [ scrollOffset , 'start' ] as const
10181039 }
10191040 }
10201041
1042+ // For the last item with 'end' alignment, use browser's actual max scroll
1043+ // to account for borders/padding that aren't in our measurements
1044+ if ( align === 'end' && index === this . options . count - 1 ) {
1045+ return [ this . getMaxScrollOffset ( ) , align ] as const
1046+ }
1047+
10211048 const toOffset =
10221049 align === 'end'
10231050 ? item . end + this . options . scrollPaddingEnd
0 commit comments