forked from linuswillner/react-console-emulator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
App.jsx
293 lines (281 loc) Β· 11.2 KB
/
App.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
// react-console-emulator example app
import React, { Component } from 'react'
// Demo only
import './extra/demo.scss'
import config from './extra/config'
import Header from './extra/components/Header'
import Row from './extra/components/Row'
import Tile from './extra/components/Tile'
import Footer from './extra/components/Footer'
import Terminal from '../src/Terminal' // In your app, import from 'react-console-emulator'
export default class App extends Component {
constructor (props) {
super(props)
this.state = {
locked: false,
increment: 0,
isProgressing: false,
progress: 0
}
this.terminal = React.createRef()
this.progressTerminal = React.createRef()
}
generateTerminalDemos = (terminals) => {
const rows = []
let rowAmount = 0
while (terminals.length > 0) {
// Row amount is just here to satisfy React
rowAmount = ++rowAmount
// Limit rows to 2 terminals for looks' sake
rows.push(
<Row key={rowAmount}>
{
terminals.splice(0, 2).map((terminal, i) => {
return (
<Tile key={i} title={terminal.title} link={terminal.link}>
{terminal.component}
</Tile>
)
})
}
</Row>
)
}
return rows
}
render () {
const { globalStyles, commands, casingCommands } = config
const terminals = [
{
title: 'Default terminal (With autoFocus enabled)',
link: 'https://github.com/linuswillner/react-console-emulator/blob/master/demo/App.jsx#L61-L65',
component: <Terminal
style={globalStyles}
commands={commands}
autoFocus
/>
},
{
title: 'Default welcome message (With danger mode enabled)',
link: 'https://github.com/linuswillner/react-console-emulator/blob/master/demo/App.jsx#L70-L75',
component: <Terminal
style={globalStyles}
commands={commands}
welcomeMessage
dangerMode
/>
},
{
title: 'Custom welcome message as an array, overriding of default commands enabled, custom error message and command callback',
link: 'https://github.com/linuswillner/react-console-emulator/blob/master/demo/App.jsx#L80-L95',
component: <Terminal
style={globalStyles}
commands={{
help: {
description: 'Custom help command.',
fn: () => 'This help command was assigned with the help of noDefaults.'
}
}}
welcomeMessage={[
'This terminal has no default commands and a custom error message when a command cannot be found.',
'Commands entered in this terminal will get their results output to the console via the command callback. See it by pressing F12.'
]}
noDefaults
errorText={'I couldn\'t find a command called [command]!'} // The [command] placeholder is replaced at runtime with the input command
commandCallback={commandResult => console.log('Command executed, result:', commandResult)}
/>
},
{
title: 'Custom styles on the terminal elements (Incl. restyling the background) and JSX as prompt label',
link: 'https://github.com/linuswillner/react-console-emulator/blob/master/demo/App.jsx#100-L114',
component: <Terminal
commands={commands}
welcomeMessage={[
'The terminal is extensively customisable.',
'You can set a custom background and change all of the colors in the terminal.',
'You can even set a custom prompt label.'
]}
// Remember to unset background-color before setting, as this can lead to styling bugs as per React
style={{ backgroundColor: null, background: 'url(\'https://storage.needpix.com/rsynced_images/abstract-wallpaper-1442844111BON.jpg\')' }} // Terminal background
contentStyle={{ color: '#FF8E00' }} // Text colour
promptLabelStyle={{ color: '#FFFFFF' }} // Prompt label colour
inputTextStyle={{ color: 'red' }} // Prompt text colour
promptLabel={<b>root@React:~$</b>}
styleEchoBack='fullInherit' // Inherit echo styling from prompt
/>
},
{
title: 'Manual pushing with no echo back (Due to manual pushing) and custom terminal message colours',
link: 'https://github.com/linuswillner/react-console-emulator/blob/master/demo/App.jsx#L119-L138',
component: <Terminal
style={globalStyles}
ref={this.terminal}
commands={{
wait: {
description: 'Waits 1000 ms and then pushes content to the output like any command.',
fn: () => {
const terminal = this.terminal.current
setTimeout(() => terminal.pushToStdout('Tada! 1000 ms passed!'), 1000)
return 'Running, please wait...'
}
}
}}
messageStyle={{ color: 'red' }} // Message colour
noEchoBack
welcomeMessage={[
'This terminal uses manual pushing, yet works as any normal terminal. Check the help command for more information.',
'This terminal also has custom message styling.'
]}
/>
},
{
title: 'History demo',
link: 'https://github.com/linuswillner/react-console-emulator/blob/master/demo/App.jsx#L143-L147',
component: <Terminal
style={globalStyles}
commands={commands}
welcomeMessage='The terminal also keeps track of your commands and allows you to recall them. Use the up and down arrow keys to navigate your history.'
/>
},
{
title: 'EOL parsing enabled',
link: 'https://github.com/linuswillner/react-console-emulator/blob/master/demo/App.jsx#L152-L160',
component: <Terminal
style={globalStyles}
commands={commands}
welcomeMessage={[
// I have to use 0-width space here, because otherwise this will get parsed as a line break too :D
'This terminal parses LF line breaks (\\\u200Bn).',
'Try putting some line breaks in the echo command and see what happens!'
]}
/>
},
{
title: 'EOL parsing disabled',
link: 'https://github.com/linuswillner/react-console-emulator/blob/master/demo/App.jsx#L165-L173',
component: <Terminal
style={globalStyles}
commands={commands}
welcomeMessage={[
'This terminal does not parse line breaks.',
'Try putting some line breaks in the echo command and see what happens!'
]}
noNewlineParsing
/>
},
{
title: 'Case sensitive command validation',
link: 'https://github.com/linuswillner/react-console-emulator/blob/master/demo/App.jsx#L178-L185',
component: <Terminal
style={globalStyles}
commands={casingCommands}
welcomeMessage={[
'This terminal requires commands to be input in correct casing.',
'Try running "help" and then running both "CaSeMatTeRs" and "casematters"!'
]}
/>
},
{
title: 'Case insensitive command validation',
link: 'https://github.com/linuswillner/react-console-emulator/blob/master/demo/App.jsx#L190-L198',
component: <Terminal
style={globalStyles}
commands={casingCommands}
welcomeMessage={[
'This terminal does not require commands to be input in correct casing.',
'Try running "help" and then running both "CaSeMatTeRs" and "casematters"!'
]}
ignoreCommandCase
/>
},
{
title: 'Read-only terminal',
link: 'https://github.com/linuswillner/react-console-emulator/blob/master/demo/App.jsx#L203-L208',
component: <Terminal
style={globalStyles}
commands={commands}
welcomeMessage='This terminal is read-only, and does not take any input.'
readOnly
/>
},
{
title: 'Terminal that disables input on process',
link: 'https://github.com/linuswillner/react-console-emulator/blob/master/demo/App.jsx#L213-L219',
component: <Terminal
style={globalStyles}
commands={commands}
welcomeMessage='This terminal hides the input when the terminal is disabled on command process. Try running the "delay" command and see what happens!'
hidePromptWhenDisabled
disableOnProcess
/>
},
{
title: 'Terminal with conditionally locked output',
link: 'https://github.com/linuswillner/react-console-emulator/blob/master/demo/App.jsx#L224-L239',
component: <Terminal
style={globalStyles}
commands={{
increment: {
description: 'Increments a number by one.',
fn: () => {
this.setState({ locked: true }) // This is just here so the welcome message or anything run before 'increment' doesn't go away
const newIncrement = this.state.increment + 1
this.setState({ increment: newIncrement })
return newIncrement
}
}
}}
welcomeMessage='This terminal updates the output of the "increment" command when run multiple times in succession.'
locked={this.state.locked}
/>
},
{
title: 'Raw HTML output',
link: 'https://github.com/linuswillner/react-console-emulator/blob/master/demo/App.jsx#L244-L249',
component: <Terminal
style={globalStyles}
commands={commands}
welcomeMessage='This terminal should render raw HTML to stdout. Try running the `html` command to see what happens!'
dangerMode
/>
},
{
title: 'Progress demo',
link: 'https://github.com/linuswillner/react-console-emulator/blob/master/demo/App.jsx#L254-L281',
component: <Terminal
style={globalStyles}
ref={this.progressTerminal}
commands={{
progress: {
description: 'Displays a progress counter.',
fn: () => {
this.setState({ isProgressing: true }, () => {
const terminal = this.progressTerminal.current
const interval = setInterval(() => {
if (this.state.progress === 100) { // Stop at 100%
clearInterval(interval)
this.setState({ isProgressing: false, progress: 0 })
} else {
this.setState({ progress: this.state.progress + 1 }, () => terminal.pushToStdout(`Progress: ${this.state.progress}%`))
}
}, 15)
})
return ''
}
}
}}
welcomeMessage='This terminal displays a progress counter when you run the "progress" command.'
disabled={this.state.isProgressing}
locked={this.state.isProgressing}
/>
}
]
return (
<main>
<Header/>
{this.generateTerminalDemos(terminals)}
<Footer/>
</main>
)
}
}