@@ -14,7 +14,15 @@ export class ViewportDataGrid<T> extends Common.ObjectWrapper.eventMixin<EventTy
1414 DataGridImpl ) < ViewportDataGridNode < T > > {
1515 private readonly onScrollBound : ( event : Event | null ) => void ;
1616 private visibleNodes : ViewportDataGridNode < T > [ ] ;
17- stickToBottom : boolean ;
17+ /** A datagrid preference to express that the grid represents an updating log of rows (eg Network panel request log, websocket messages).
18+ * If `true`, the datagrid will mostly keep the scroll at the bottom, so new items are visible.
19+ * If the data is sorted descending (eg Performance Call Tree, heap snapshot), keep the default of `false`.
20+ */
21+ enableAutoScrollToBottom : boolean = false ;
22+ /** When true, the datagrid will manipulate the scrollTop to focus on the bottom, mostly so new additions are visible.
23+ * Some actions will unset this, like revealing or expanding a particular node.
24+ * Only matters if enableAutoScrollToBottom is true. */
25+ keepScrollingToBottom : boolean = false ;
1826 private updateIsFromUser : boolean ;
1927 private lastScrollTop : number ;
2028 private firstVisibleIsStriped : boolean ;
@@ -29,7 +37,6 @@ export class ViewportDataGrid<T> extends Common.ObjectWrapper.eventMixin<EventTy
2937 this . visibleNodes = [ ] ;
3038 this . inline = false ;
3139
32- this . stickToBottom = false ;
3340 this . updateIsFromUser = false ;
3441 this . lastScrollTop = 0 ;
3542 this . firstVisibleIsStriped = false ;
@@ -60,15 +67,15 @@ export class ViewportDataGrid<T> extends Common.ObjectWrapper.eventMixin<EventTy
6067 }
6168
6269 override onResize ( ) : void {
63- if ( this . stickToBottom ) {
70+ if ( this . keepScrollingToBottom ) {
6471 this . scrollContainer . scrollTop = this . scrollContainer . scrollHeight - this . scrollContainer . clientHeight ;
6572 }
6673 this . scheduleUpdate ( ) ;
6774 super . onResize ( ) ;
6875 }
6976
70- setStickToBottom ( stick : boolean ) : void {
71- this . stickToBottom = stick ;
77+ setEnableAutoScrollToBottom ( stick : boolean ) : void {
78+ this . keepScrollingToBottom = this . enableAutoScrollToBottom = stick ;
7279 }
7380
7481 private onScroll ( _event : Event | null ) : void {
@@ -131,8 +138,10 @@ export class ViewportDataGrid<T> extends Common.ObjectWrapper.eventMixin<EventTy
131138 bottomPadding += nodes [ i ] . nodeSelfHeight ( ) ;
132139 }
133140
134- // enable stick-to-bottom if the last item is visible
135- this . stickToBottom = end === nodes . length ;
141+ if ( this . enableAutoScrollToBottom ) {
142+ // If we're scrolled to the very end, keep the scroll viewport focused to the end (as new items arrive)
143+ this . keepScrollingToBottom = end === nodes . length ;
144+ }
136145
137146 return {
138147 topPadding,
@@ -157,7 +166,7 @@ export class ViewportDataGrid<T> extends Common.ObjectWrapper.eventMixin<EventTy
157166 let scrollTop : number = this . scrollContainer . scrollTop ;
158167 const currentScrollTop = scrollTop ;
159168 const maxScrollTop = Math . max ( 0 , this . contentHeight ( ) - clientHeight ) ;
160- if ( ! this . updateIsFromUser && this . stickToBottom ) {
169+ if ( ! this . updateIsFromUser && this . keepScrollingToBottom ) {
161170 scrollTop = maxScrollTop ;
162171 }
163172 this . updateIsFromUser = false ;
@@ -185,7 +194,7 @@ export class ViewportDataGrid<T> extends Common.ObjectWrapper.eventMixin<EventTy
185194 const nodes = ( this . rootNode ( ) as ViewportDataGridNode < T > ) . flatChildren ( ) ;
186195 const index = nodes . indexOf ( visibleNodes [ 0 ] ) ;
187196 this . updateStripesClass ( Boolean ( index % 2 ) ) ;
188- if ( this . stickToBottom && index !== - 1 && Boolean ( index % 2 ) !== this . firstVisibleIsStriped ) {
197+ if ( this . keepScrollingToBottom && index !== - 1 && Boolean ( index % 2 ) !== this . firstVisibleIsStriped ) {
189198 offset += 1 ;
190199 }
191200 }
@@ -233,7 +242,7 @@ export class ViewportDataGrid<T> extends Common.ObjectWrapper.eventMixin<EventTy
233242 const visibleHeight = this . scrollContainer . offsetHeight - this . headerHeightInScroller ( ) ;
234243 if ( scrollTop > fromY ) {
235244 scrollTop = fromY ;
236- this . stickToBottom = false ;
245+ this . keepScrollingToBottom = false ;
237246 } else if ( scrollTop + visibleHeight < toY ) {
238247 scrollTop = toY - visibleHeight ;
239248 }
@@ -410,7 +419,7 @@ export class ViewportDataGridNode<T> extends DataGridNode<ViewportDataGridNode<T
410419 if ( this . expanded ) {
411420 return ;
412421 }
413- ( this . dataGrid as ViewportDataGrid < T > ) . stickToBottom = false ;
422+ ( this . dataGrid as ViewportDataGrid < T > ) . keepScrollingToBottom = false ;
414423 this . clearFlatNodes ( ) ;
415424 super . expand ( ) ;
416425 ( this . dataGrid as ViewportDataGrid < T > ) . scheduleUpdateStructure ( ) ;
0 commit comments