Skip to content

Commit e1ef688

Browse files
authored
Merge pull request #277 from kipr/auto-scroll-console
Add auto-scrolling to console
2 parents f8d2534 + 95f8105 commit e1ef688

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

src/components/Console/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Console extends React.PureComponent<Props, State> {
3535
render() {
3636
const { style, className, theme, text } = this.props;
3737
return (
38-
<ScrollArea style={style} className={className} theme={theme}>
38+
<ScrollArea style={style} className={className} theme={theme} autoscroll>
3939
<ConsoleText theme={theme} text={text} />
4040
</ScrollArea>
4141
);

src/components/ScrollArea.tsx

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { GlobalEvents, GLOBAL_EVENTS, Slow } from '../util';
1010

1111
export interface ScrollAreaProps extends StyleProps, ThemeProps {
1212
children: React.ReactNode;
13+
autoscroll?: boolean;
1314
}
1415

1516
export namespace Action {
@@ -110,14 +111,17 @@ class ScrollArea extends React.PureComponent<Props, State> {
110111
switch (element) {
111112
case this.outerRef_: {
112113
if (Vector2.eq(this.state.outerSize, size)) break;
114+
115+
this.updateTopOnResize(this.state.innerSize, size);
113116
this.setState({
114117
outerSize: size
115118
});
116119
break;
117120
}
118121
case this.innerRef_: {
119122
if (Vector2.eq(this.state.innerSize, size)) break;
120-
123+
124+
this.updateTopOnResize(size, this.state.outerSize);
121125
this.setState({
122126
innerSize: size
123127
});
@@ -126,6 +130,22 @@ class ScrollArea extends React.PureComponent<Props, State> {
126130
}
127131
};
128132

133+
private updateTopOnResize = (newInnerSize: Vector2, newOuterSize: Vector2) => {
134+
const { action } = this.state;
135+
136+
// Reset top to the bottom if...
137+
// a) autoscroll is enabled and currently at the bottom, or
138+
// b) top is no longer within the new scroll range
139+
if ((this.props.autoscroll && action.type === Action.Type.None && action.top >= this.maxTop) || Action.top(action) > newInnerSize.y - newOuterSize.y) {
140+
this.setState({
141+
action: {
142+
...action,
143+
top: Math.max(newInnerSize.y - newOuterSize.y, 0),
144+
}
145+
});
146+
}
147+
};
148+
129149
componentWillUnmount() {
130150
this.listener_.disconnect();
131151
}
@@ -170,10 +190,11 @@ class ScrollArea extends React.PureComponent<Props, State> {
170190
const current = Vector2.fromClient(event);
171191

172192
let top = 0;
173-
if (innerSize.y > outerSize.y) {
193+
const maxTop = this.maxTop;
194+
if (maxTop > 0) {
174195
const diff = Vector2.subtract(action.startOffset, current);
175196
const topDiff = diff.y * (outerSize.y > 0 ? (innerSize.y / outerSize.y) : 1);
176-
top = clamp(0, action.startTop - topDiff, innerSize.y - outerSize.y);
197+
top = clamp(0, action.startTop - topDiff, maxTop);
177198
}
178199

179200
this.setState({
@@ -202,10 +223,11 @@ class ScrollArea extends React.PureComponent<Props, State> {
202223

203224
private onWheel_ = (event: React.WheelEvent<HTMLDivElement>) => {
204225
const { state } = this;
205-
const { outerSize, innerSize, action } = state;
226+
const { action } = state;
206227
if (action.type !== Action.Type.None) return;
207228

208-
const top = innerSize.y > outerSize.y ? clamp(0, action.top + event.deltaY, innerSize.y - outerSize.y) : 0;
229+
const maxTop = this.maxTop;
230+
const top = clamp(0, action.top + event.deltaY, maxTop);
209231

210232
this.setState({
211233
action: {
@@ -240,6 +262,10 @@ class ScrollArea extends React.PureComponent<Props, State> {
240262
return (innerSize.y > 0 ? outerSize.y / innerSize.y : 1) * outerSize.y;
241263
}
242264

265+
private get maxTop() {
266+
return Math.max(this.state.innerSize.y - this.state.outerSize.y, 0);
267+
}
268+
243269
private slow_ = new Slow();
244270

245271
render() {
@@ -287,4 +313,4 @@ class ScrollArea extends React.PureComponent<Props, State> {
287313
}
288314
}
289315

290-
export default ScrollArea;
316+
export default ScrollArea;

0 commit comments

Comments
 (0)