loading...

Terminal in React JS

ntulswani profile image Nitin Tulswani ・4 min read

screenshot

Already more than two weeks ago, I created terminal-in-react, a component that renders a terminal in React JS. I wanted to create something interesting with React and then I’d this crazy idea.

How it works ?

The component renders a terminal interface which allows you to add your own commands. For example – let’s add a command that will type the given text automatically.

<Terminal
  commands={{
    "type-text": (args, print, runCommand) => {
      const text = args.slice(1).join(' ');
      print('');
      for (let i = 0; i < text.length; i += 1) {
        setTimeout(() => {
          runCommand(`edit-line ${text.slice(0, i + 1)}`);
        }, 100 * i);
      }
    }
  }}
/>

Don’t worry, we will look into the API later. Let’s see how this command works.

type

Interesting! Right ? But there is more…

Basic example


import React, { Component } from 'react';
import Terminal from 'terminal-in-react';
import 'terminal-in-react/lib/css/index.css';

class App extends Component {
  showMsg = () => 'Hello World'

  render() {
    return (
      <div style={{ display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }}>
        <Terminal
          color='green'
          backgroundColor='black'
          barColor='black'
          style={{ fontWeight: "bold", fontSize: "1em" }}
          commands={{
            'open-google': () => window.open('google.com', '_blank'),
            showmsg: this.showMsg,
            popup: () => alert('Terminal in React')
          }}
          descriptions={{
            'open-google': 'opens google.com',
            showmsg: 'shows a message',
            alert: 'alert', popup: 'alert'
          }}
          msg='You can write anything here. Example - Hello! My name is Foo and I like Bar.'
        />
      </div>
    );
  }
}

In the above example I’ve added three commands, open-google , showmsg and popup . Also I’ve described all the three commands with a description prop.

Display message

Display a message with msg prop when the component mounts.

<Terminal msg="Hello World" />

Customisation

To customise the terminal look, you can pass prop color to change the text color, backgroundColor to change the background color and barColor to change the color of bar.

Minimise, Maximise and Close

Yup! Those three buttons actually work 😅

Creating advance commands

You can also add a command that performs some async stuff rather that basic I/O using the advance command api. It has three parameters -

  • arguments - input array
  • print - method to write new line
  • runCommand - to call the command

<Terminal
  commands={{
    color: {
      method: (args, print, runCommand) => {
        print(`The color is ${args._[0] || args.color}`);
      },
      options: [
        {
          name: 'color',
          description: 'The color the output should be',
          defaultValue: 'white',
        },
      ],
    },
  }}
/>

Using plugins 🔥

We have also developed a plugin system for the component which helps you develop custom plugins.

One example of the plugin is terminal-in-react-pseudo-file-system-plugin which creates a fake file system.

<Terminal
  plugins={[
    new PseudoFileSystem(),
  ]}
/>

Let’s see it in action,

Woaah! Awesome!! Let us know if you make something interesting 😃

More features

  • Tab autocomplete

  • Multi-line input

  • Check history of your commands

Keyboard shortcuts

You can also define keyboard shortcuts. They have to be grouped by os. The three available are win, darwin, and linux. You can group multiple os by a , for example if the shortcut was for all platforms win,darwin,linux would be fine as a key. The value of the shortcut should be a command to run.

<Terminal
  shortcuts={{
    'darwin,win,linux': {
      'ctrl + a': 'echo whoo',
    },
  }}
/>

OS specific shortcuts


<Terminal
  shortcuts={{
    'win': {
      'ctrl + a': 'echo hi windows',
    },
    'darwin': {
      'cmd + a': 'echo hi mac'
    },
    'linux': {
      'ctrl + a': 'echo hi linux'
    }
  }}
/>

or mix and match


<Terminal
  shortcuts={{
    'win,linux': {
      'ctrl + b': 'echo we are special',
    },
    'win': {
      'ctrl + a': 'echo hi windows',
    },
    'darwin': {
      'cmd + a': 'echo hi mac'
    },
    'linux': {
      'ctrl + a': 'echo hi linux'
    }
  }}
/>

Built-in commands

  • clear - clears the screen
  • help - list all the commands
  • show - shows a msg if any
  • echo - display the input message
  • edit-line - edits the last line or a given line using the -l argument

Current status

We are working on -

  • adding workspaces and tabs
  • parser (to write basic programs)
  • expanding the plugin system

So expect much more features in the next release 😎

Shoutout to Jonathan Gertig and Christian Varisco for their amazing contributions to the project 🎉 . Thank you so much!!

If you want to contribute to the project, here is the contributing guide. I’m excited to see your pull request.

GitHub - https://github.com/nitin42/terminal-in-react

Website - http://terminal-in-react.surge.sh/

Docs - https://github.com/nitin42/terminal-in-react/wiki

Posted on Jul 25 '17 by:

Discussion

markdown guide
 

Hello, the terminal looks very nice to me. I would like to know if you would be interested to help me to integrate it as plugin for Graylog Web Interface, in order to display the logs in a console like interface.

Thanks.