DEV Community

Nitin Tulswani
Nitin Tulswani

Posted on

Terminal in React JS

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);
      }
    }
  }}
/>
Enter fullscreen mode Exit fullscreen mode

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>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

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" />
Enter fullscreen mode Exit fullscreen mode

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',
        },
      ],
    },
  }}
/>
Enter fullscreen mode Exit fullscreen mode

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(),
  ]}
/>
Enter fullscreen mode Exit fullscreen mode

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',
    },
  }}
/>
Enter fullscreen mode Exit fullscreen mode

OS specific shortcuts


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

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'
    }
  }}
/>
Enter fullscreen mode Exit fullscreen mode

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

Top comments (1)

Collapse
 
rodislavable profile image
Rodislav Moldovan

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.