/react-terminal

A react component library for rendering a bash like terminal on the web.

Primary LanguageTypeScript

๐Ÿ–ฅ๏ธ React Terminal

A sleek and customizable terminal emulator component for React applications.

๐Ÿš€ Features

  • ๐ŸŽจ Customizable themes (7+ built-in themes)
  • ๐Ÿ” Command prediction (with tab autocomplete)
  • ๐Ÿ“‚ Built-in file system simulation
  • โŒจ๏ธ Built-in commands (ls, cd, cat, etc.)
  • ๐Ÿ”ง Extensible with custom commands (async commands supported)
  • โฎ๏ธ Command history navigation
  • ๐Ÿ”„ Async command loading animation

๐Ÿ“ฆ Installation

npm install react-terminal

๐Ÿ› ๏ธ Usage

// App.tsx
import { Terminal, TerminalContextProvider } from 'react-terminal';

// !Don't forget to wrap your app's entry point with TerminalContextProvider!
function App() {
  return (
      <TerminalContextProvider>
        {/* Rest of your components */}
      </TerminalContextProvider>
  );
}

// SomeComponent.tsx
import { Terminal } from 'react-terminal';

function SomeComponent() {
  return (
    <Terminal
      prompt="user@anon:"
      theme="dark"
      welcomeMessage="Welcome to React Terminal Emulator!"
    />
  )
}

๐ŸŽ›๏ธ Props

Name Description Type Default
prompt The prompt string displayed before each command string "user@anon:"
commands Custom commands object IUserCommands {}
directoryStructure Initial directory structure IDirectoryStructure {}
height Height of the terminal string CSS units "100%"
width Width of the terminal string CSS units "100%"
borderRadius Border radius of the terminal string CSS units "0.7rem"
commandPrediction Enable command prediction boolean false
showTopBar Show the top bar of the terminal boolean true
topBarHeight Height of the top bar string CSS units "8%"
theme Terminal theme "dark" | "light" | "hacker" | "sunset" | "nordica" | "pastelDream" | "monokai" | "solarized" | ITheme "dark"
welcomeMessage Welcome message displayed on start string | React.JSX.Element ""
showTopBarPrompt Show prompt in the top bar boolean true
autoCompleteAnimation Enable autocomplete animation (WIP) boolean false
btn1Callback Callback for the first top bar button (args: any) => any undefined
btn2Callback Callback for the second top bar button (args: any) => any undefined
btn3Callback Callback for the third top bar button (args: any) => any undefined
asyncCommandLoader Loader style for async commands string See them in action here "aesthetic2"
asyncCommandLoaderSpeed Speed multiplier for async command loader number range(0, 1) 0.5
๐Ÿ” Complicated Types

IUserCommands

type IUserCommands = Record<
  string,
  | string
  | React.JSX.Element
  | ((args?: any) => React.JSX.Element | string | void | Promise<string | void>)
>;

This type defines a record where each key represents a command, and the value can be a simple string, a React element, or a function that returns a string, a React element, or a Promise.

Example:

const commands = {
  hello: "Hello, World!", // Simple string response
  greet: (name) => `Hello, ${name}!`, // Function that returns a string
  react: <strong>React is awesome!</strong>, // React element
  asyncTask: async () => {
    await someAsyncOperation();
    return "Task completed!"; // Async function returning a string
  },
};

IDirectoryStructure

interface IFile {
  content: string | JSX.Element;
}

interface IDirectory {
  [key: string]: IFile | IDirectory;
}

type IDirectoryStructure = IDirectory;

IDirectoryStructure represents the structure of the terminal's file system. It consists of a recursive structure of directories and files. Each directory contains files or other directories. A file has a content field, which can be a string or a React element.

Example:

const fileSystem = {
  home: {
    "README.md": { content: "# Welcome to the Home Directory" }, // File with string content
    projects: {
      "project1.txt": { content: "Project 1 details" }, // File within a nested directory
      "project2.md": { content: <em>Project 2 documentation</em> }, // File with React element content
    },
  },
  etc: {
    config: {
      "settings.json": { content: '{"theme": "dark"}' }, // JSON file content
    },
  },
};

ITheme

interface ITheme {
  terminalBg: string;
  topBarBg: string;
  promptColor: string;
  pwdColor: string;
  textColor: string;
  predictionColor: string;
}

ITheme allows customization of various terminal colors. Each property corresponds to a CSS color value:

  • terminalBg: Background color of the terminal.
  • topBarBg: Background color of the top bar.
  • promptColor: Color of the prompt string.
  • pwdColor: Color of the present working directory display.
  • textColor: Default text color.
  • predictionColor: Color of the command prediction text.

Example:

const customTheme: ITheme = {
  terminalBg: "#1e1e1e", // Dark background
  topBarBg: "#333333", // Darker top bar
  promptColor: "#00FF00", // Bright green prompt
  pwdColor: "#FFD700", // Golden color for directory path
  textColor: "#FFFFFF", // White text color
  predictionColor: "#AAAAAA", // Grey prediction text
};

๐ŸŒˆ Themes

The terminal comes with several built-in themes:

  • ๐ŸŒž Light
  • ๐ŸŒš Dark
  • ๐Ÿ‘จโ€๐Ÿ’ป Hacker
  • ๐ŸŒ… Sunset
  • โ„๏ธ Nordica
  • ๐Ÿฌ Pastel Dream
  • ๐ŸŽจ Monokai
  • ๐ŸŒŠ Solarized

You can also create custom themes by passing an ITheme object.

๐Ÿ”ง Custom Commands

You can add custom commands to the terminal:

const customCommands = {
  hello: "Hello, World!",
  greet: (name) => `Hello, ${name}!`,
  asyncTask: async () => {
    await someAsyncOperation();
    return "Task completed!";
  },
};

<Terminal commands={customCommands} />

๐Ÿ› ๏ธ Built-in Commands

The terminal includes several built-in commands to provide essential functionalities:

  • ๐Ÿงน clear: Clears the terminal screen, removing all previous commands and outputs.

  • ๐Ÿ—ฃ๏ธ echo [text]: Prints the provided text to the terminal. Useful for displaying messages or values of variables.

  • ๐Ÿ“ cd [directory]: Changes the current working directory to the specified directory. Use cd .. to move to the parent directory.

  • ๐Ÿ“‚ ls: Lists the contents of the current directory, including files and subdirectories.

  • ๐Ÿ“„ cat [file]: Displays the content of the specified file. Use this to read and view file contents directly in the terminal.

  • ๐Ÿ“Œ pwd: Prints the current working directory path.

  • ๐Ÿ“‚ mkdir [directory]: Creates a new directory with the specified directory name in the current location.

  • ๐Ÿ—‘๏ธ rm [file/directory]: Removes the specified file or directory. Be careful, as this action is irreversible!

  • ๐Ÿ“… date: Displays the current date and time.

  • ๐ŸŽจ setTheme [theme]: Changes the terminal's theme to the specified theme, allowing users to switch between different visual styles on the fly.

Built-in commands related to the file system/directory structure are disabled if the directoryStructure prop is not present.

๐Ÿค Contributing

Contributions, issues, and feature requests are welcome! Feel free to check the issues page.

๐Ÿ“„ License

This project is MIT licensed.

README is incomplete, will be updated soon.

Component is almost ready to be published to npm. Until then, to run and test the project locally:

git clone https://github.com/zaidsidd360/react-terminal.git
cd react-terminal
npm i

or

yarn

then

cd example

repeat npm i or yarn and finally,

npm run dev

or

yarn dev