UNPKG

react-io-terminal

Version:

A React terminal component. Displays a terminal to the user on the web page and lets you hook into it.

139 lines (123 loc) 3.62 kB
import React, { useState, useEffect } from "react"; import "./index.css"; const Terminal = (props) => { //Component state const [inputValue, setInputValue] = useState(""); const [lines, setLines] = useState([]); const [newID, setNewID] = useState(0); //Load config for component let config = props.Config || {}; const conf = { prefix: config.prefix || ">", userOutPrefix: config.userOutPrefix || "< ", callbackOutPrefix: config.handlerOutPrefix || "[callback]", callback: config.handler || (() => { return "OK"; }), textColor: config.textColor || "white", background: config.background || "blue", font: config.font || "monospace", fontSize: config.fontSize || "1em", getFocusOnRender: config.getFocusOnRender || false, }; /* Function for getting a new id every time. * * Addition parameter allows you to get multiple ids. * Just call getID() once, with the amount of ids you * are going to need, and do id+n. */ const getID = (addition) => { let tempID = newID; //Plus operator setNewID(newID + addition); return tempID; }; const addLines = (linesToAdd) => { if (Array.isArray(linesToAdd)) { const baseID = getID(linesToAdd.length); let objArr = []; for (let i = 0; i < linesToAdd.length; i++) { objArr.push({ content: String(linesToAdd[i]), id: baseID + i }); } setLines(lines.concat(objArr)); } else { setLines(lines.concat({ content: String(linesToAdd), id: getID(1) })); } }; const handleInput = (e) => { setInputValue(e.target.value); }; const handleKeypress = (e) => { if (e.keyCode == 13) { if (inputValue === "") return; let lineArr = [`${conf.userOutPrefix}${inputValue}`]; const callbackResponse = conf.callback(inputValue); let line; if (Array.isArray(callbackResponse)) { for (line in callbackResponse) { lineArr = lineArr.concat( `${conf.callbackOutPrefix}${String(callbackResponse[line])}` ); } } else { lineArr = lineArr.concat( `${conf.callbackOutPrefix}${String(callbackResponse)}` ); } addLines(lineArr); setInputValue(""); } }; useEffect(() => { if (conf.getFocusOnRender) document.getElementById("lineInput").focus(); }); const lineList = lines.map((x) => ( <li style={{ color: conf.textColor }} className="terminalLine" key={x.id}> {x.content} </li> )); const handleClick = (e) => { document.getElementById("lineInput").focus(); }; return ( <div className="terminal-container" style={{ background: conf.background, fontFamily: conf.font, fontSize: conf.fontSize, }} onClick={handleClick} > <div style={{ background: conf.background }} className="content-container" > <ul style={{ color: conf.textColor }}> {lineList} <li style={{ color: conf.textColor }} id={-1} className="inputLineContainer" > {conf.prefix} <input style={{ color: conf.textColor }} spellCheck="false" autoComplete="off" id="lineInput" value={inputValue} onKeyDown={handleKeypress} type="text" className="inputLineInput" onChange={handleInput} ></input> </li> </ul> </div> </div> ); }; export default Terminal;