@@ -41,6 +41,7 @@ export class MainPanel extends React.Component<IMainPanelProps, IMainPanelState>
41
41
private stackLimit = 10 ;
42
42
private updateCount = 0 ;
43
43
private renderCount = 0 ;
44
+ private internalScrollCount = 0 ;
44
45
private editCellRef : Cell | null = null ;
45
46
private mainPanel : HTMLDivElement | null = null ;
46
47
private variableExplorerRef : React . RefObject < VariableExplorer > ;
@@ -68,7 +69,8 @@ export class MainPanel extends React.Component<IMainPanelProps, IMainPanelState>
68
69
editorOptions : this . computeEditorOptions ( ) ,
69
70
currentExecutionCount : 0 ,
70
71
debugging : false ,
71
- enableGather : getSettings && getSettings ( ) . enableGather
72
+ enableGather : getSettings && getSettings ( ) . enableGather ,
73
+ isAtBottom : true
72
74
} ;
73
75
74
76
// Add test state if necessary
@@ -151,7 +153,7 @@ export class MainPanel extends React.Component<IMainPanelProps, IMainPanelState>
151
153
< section id = 'main-panel-variable' aria-label = { getLocString ( 'DataScience.collapseVariableExplorerLabel' , 'Variables' ) } >
152
154
{ this . renderVariablePanel ( baseTheme ) }
153
155
</ section >
154
- < main id = 'main-panel-content' >
156
+ < main id = 'main-panel-content' onScroll = { this . handleScroll } >
155
157
{ this . renderContentPanel ( baseTheme ) }
156
158
</ main >
157
159
< section id = 'main-panel-footer' aria-label = { getLocString ( 'DataScience.editSection' , 'Input new cells here' ) } >
@@ -161,6 +163,26 @@ export class MainPanel extends React.Component<IMainPanelProps, IMainPanelState>
161
163
) ;
162
164
}
163
165
166
+ // This handles the scrolling. Its called from the props of contentPanel.
167
+ // We only scroll when the state indicates we are at the bottom of the interactive window,
168
+ // otherwise it sometimes scrolls when the user wasn't at the bottom.
169
+ public scrollDiv = ( div : HTMLDivElement ) => {
170
+ if ( this . state . isAtBottom ) {
171
+ this . internalScrollCount += 1 ;
172
+ div . scrollIntoView ( { behavior : 'auto' , block : 'start' , inline : 'nearest' } ) ;
173
+ }
174
+ }
175
+
176
+ public handleScroll = ( e : React . UIEvent < HTMLDivElement > ) => {
177
+ if ( this . internalScrollCount > 0 ) {
178
+ this . internalScrollCount -= 1 ;
179
+ } else {
180
+ this . setState ( {
181
+ isAtBottom : e . currentTarget . scrollHeight - e . currentTarget . scrollTop === e . currentTarget . clientHeight
182
+ } ) ;
183
+ }
184
+ }
185
+
164
186
// tslint:disable-next-line:no-any cyclomatic-complexity max-func-body-length
165
187
public handleMessage = ( msg : string , payload ?: any ) => {
166
188
switch ( msg ) {
@@ -445,7 +467,8 @@ export class MainPanel extends React.Component<IMainPanelProps, IMainPanelState>
445
467
openLink : this . openLink ,
446
468
expandImage : this . showPlot ,
447
469
gatherCode : this . gatherCode ,
448
- enableGather : this . state . enableGather
470
+ enableGather : this . state . enableGather ,
471
+ scrollToBottom : this . scrollDiv
449
472
} ;
450
473
}
451
474
private getToolbarProps = ( baseTheme : string ) : IToolbarPanelProps => {
0 commit comments