Skip to content

Commit 506c889

Browse files
committed
Initial commit
1 parent 5f48997 commit 506c889

File tree

5 files changed

+130
-15
lines changed

5 files changed

+130
-15
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
1+
.idea
22
# See https://help.github.com/ignore-files/ for more about ignoring files.
33

44
# dependencies

.idea/vcs.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/src/App.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
import React, { Component } from 'react'
22

3-
import ExampleComponent from 'react-console'
3+
import ReactConsole from 'react-console'
44

55
export default class App extends Component {
66
render () {
77
return (
88
<div>
9-
<ExampleComponent text='Modern React component module' />
9+
<ReactConsole
10+
commands={{
11+
echo: {
12+
description: 'Echo',
13+
fn: (...args) => {
14+
return new Promise((resolve, reject) => {
15+
setTimeout(() => {
16+
resolve(`${args.join(' ')}`)
17+
}, 2000)
18+
})
19+
}
20+
}
21+
}}
22+
/>
1023
</div>
1124
)
1225
}

src/index.tsx

Lines changed: 82 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,97 @@
11
/**
2-
* @class ExampleComponent
2+
* @class ReactConsole
33
*/
44

55
import * as React from 'react'
66

77
import styles from './styles.css'
88

9-
export type Props = { text: string }
9+
export type Props = {
10+
text: string,
11+
prompt: React.Component,
12+
commands: any,
13+
}
14+
15+
type State = {
16+
output: Array<string>,
17+
}
18+
19+
export default class ReactConsole extends React.Component<Props, State> {
20+
21+
formRef : any = null;
22+
inputRef: any = null;
23+
outputRef: any = null;
24+
25+
static defaultProps = {
26+
prompt: '$',
27+
};
28+
29+
state = {
30+
output: []
31+
};
32+
33+
scrollToBottom = () => {
34+
this.outputRef.scrollTo(0, this.outputRef.scrollHeight)
35+
};
36+
37+
onSubmit = async (e: any) => {
38+
const { prompt } = this.props
39+
e.preventDefault();
40+
const data = new FormData(e.target);
41+
const inputString: string = data.get('input') as string;
42+
if (inputString === null) {
43+
return
44+
}
45+
const [cmd, ...args] = inputString.split(" ");
46+
const command = this.props.commands[cmd];
47+
48+
if (command) {
49+
try {
50+
const ret = await command.fn(...args)
51+
this.setState({
52+
output: [...this.state.output, `${prompt} ${ret}`]
53+
}, this.scrollToBottom)
54+
} catch (err) {
55+
56+
}
57+
} else {
58+
this.setState({
59+
output: [...this.state.output, `${prompt} Command '${cmd}' does not exist`]
60+
}, this.scrollToBottom)
61+
}
62+
if(this.formRef) {
63+
this.formRef.reset()
64+
}
65+
};
1066

11-
export default class ExampleComponent extends React.Component<Props> {
1267
render() {
1368
const {
14-
text
15-
} = this.props
69+
prompt,
70+
} = this.props;
1671

1772
return (
18-
<div className={styles.test}>
19-
Example Component: {text}
73+
<div className={styles.wrapper}>
74+
<div className={styles.output} ref={ref => this.outputRef = ref}>
75+
{this.state.output.map((line, key) =>
76+
<div key={key}>{line}</div>
77+
)}
78+
</div>
79+
<form
80+
ref={ref => this.formRef = ref}
81+
onSubmit={this.onSubmit}
82+
>
83+
<div className={styles.promptWrapper}>
84+
<span>{prompt}</span>
85+
<input
86+
ref={ref => this.inputRef = ref}
87+
autoFocus
88+
autoComplete={'off'}
89+
autoCapitalize={'false'}
90+
name="input"
91+
className={styles.input}
92+
/>
93+
</div>
94+
</form>
2095
</div>
2196
)
2297
}

src/styles.css

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,29 @@
11
/* add css styles here (optional) */
22

3-
.test {
4-
display: inline-block;
5-
margin: 2em auto;
6-
border: 2px solid #000;
7-
font-size: 2em;
3+
.wrapper {
4+
display: flex;
5+
flex-direction: column;
6+
background-color: black;
7+
color: white;
8+
font-family: monospace;
9+
font-size: 13px;
10+
padding: 10px;
11+
height: 300px;
12+
}
13+
14+
.output {
15+
overflow-y: auto;
16+
}
17+
18+
.promptWrapper {
19+
display: flex;
20+
}
21+
22+
.input {
23+
margin-left: 3px;
24+
flex: 1;
25+
background: transparent;
26+
border: none;
27+
outline: none;
28+
color: white;
829
}

0 commit comments

Comments
 (0)