Skip to content

Commit c4e1d38

Browse files
committed
MVP
1 parent 506c889 commit c4e1d38

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

src/index.tsx

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,26 @@ export type Props = {
1414

1515
type State = {
1616
output: Array<string>,
17+
commandInProgress: boolean,
1718
}
1819

1920
export default class ReactConsole extends React.Component<Props, State> {
2021

2122
formRef : any = null;
2223
inputRef: any = null;
23-
outputRef: any = null;
24+
wrapperRef: any = null;
2425

2526
static defaultProps = {
2627
prompt: '$',
2728
};
2829

2930
state = {
30-
output: []
31+
output: [],
32+
commandInProgress: false,
3133
};
3234

3335
scrollToBottom = () => {
34-
this.outputRef.scrollTo(0, this.outputRef.scrollHeight)
36+
this.wrapperRef.scrollTo(0, this.wrapperRef.scrollHeight)
3537
};
3638

3739
onSubmit = async (e: any) => {
@@ -45,23 +47,31 @@ export default class ReactConsole extends React.Component<Props, State> {
4547
const [cmd, ...args] = inputString.split(" ");
4648
const command = this.props.commands[cmd];
4749

50+
const log = `${prompt}\xa0${inputString}`;
51+
52+
await this.setState({ commandInProgress: true });
53+
4854
if (command) {
4955
try {
50-
const ret = await command.fn(...args)
51-
this.setState({
52-
output: [...this.state.output, `${prompt} ${ret}`]
53-
}, this.scrollToBottom)
56+
const ret = await command.fn(...args);
57+
await this.setState({
58+
output: [...this.state.output, log, ret]
59+
})
5460
} catch (err) {
5561

5662
}
63+
this.scrollToBottom()
64+
5765
} else {
5866
this.setState({
59-
output: [...this.state.output, `${prompt} Command '${cmd}' does not exist`]
67+
output: [...this.state.output, log, `Command '${cmd}' does not exist`]
6068
}, this.scrollToBottom)
6169
}
6270
if(this.formRef) {
6371
this.formRef.reset()
6472
}
73+
this.setState({ commandInProgress: false });
74+
this.inputRef.focus()
6575
};
6676

6777
render() {
@@ -70,8 +80,10 @@ export default class ReactConsole extends React.Component<Props, State> {
7080
} = this.props;
7181

7282
return (
73-
<div className={styles.wrapper}>
74-
<div className={styles.output} ref={ref => this.outputRef = ref}>
83+
<div className={styles.wrapper} onClick={this.focusConsole} ref={ref => this.wrapperRef = ref}>
84+
<div
85+
className={styles.output}
86+
>
7587
{this.state.output.map((line, key) =>
7688
<div key={key}>{line}</div>
7789
)}
@@ -81,11 +93,13 @@ export default class ReactConsole extends React.Component<Props, State> {
8193
onSubmit={this.onSubmit}
8294
>
8395
<div className={styles.promptWrapper}>
84-
<span>{prompt}</span>
96+
<span>{prompt}&nbsp;</span>
8597
<input
98+
disabled={this.state.commandInProgress}
8699
ref={ref => this.inputRef = ref}
87100
autoFocus
88101
autoComplete={'off'}
102+
spellCheck={false}
89103
autoCapitalize={'false'}
90104
name="input"
91105
className={styles.input}
@@ -95,4 +109,8 @@ export default class ReactConsole extends React.Component<Props, State> {
95109
</div>
96110
)
97111
}
112+
113+
focusConsole = () => {
114+
this.inputRef.focus()
115+
}
98116
}

src/styles.css

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,22 @@
99
font-size: 13px;
1010
padding: 10px;
1111
height: 300px;
12+
overflow-y: auto;
1213
}
1314

1415
.output {
15-
overflow-y: auto;
1616
}
1717

1818
.promptWrapper {
1919
display: flex;
2020
}
2121

2222
.input {
23-
margin-left: 3px;
2423
flex: 1;
2524
background: transparent;
2625
border: none;
2726
outline: none;
2827
color: white;
28+
font-family: monospace;
29+
font-size: 13px;
2930
}

0 commit comments

Comments
 (0)