UNPKG

react-terminal-ui

Version:

A terminal react component with support for light and dark modes.

3 lines (2 loc) 7.42 kB
import n,{useState as e,useRef as t,useEffect as r}from"react";function a(n,e){var t="function"==typeof Symbol&&n[Symbol.iterator];if(!t)return n;var r,a,i=t.call(n),l=[];try{for(;(void 0===e||e-- >0)&&!(r=i.next()).done;)l.push(r.value)}catch(n){a={error:n}}finally{try{r&&!r.done&&(t=i.return)&&t.call(i)}finally{if(a)throw a.error}}return l}"function"==typeof SuppressedError&&SuppressedError;var i=function(e){var t=e.children,r=e.prompt;return n.createElement("div",{className:"react-terminal-line react-terminal-input","data-terminal-prompt":r||"$"},t)},l=function(e){var t=e.children;return n.createElement("div",{className:"react-terminal-line"},t)};!function(n,e){void 0===e&&(e={});var t=e.insertAt;if(n&&"undefined"!=typeof document){var r=document.head||document.getElementsByTagName("head")[0],a=document.createElement("style");a.type="text/css","top"===t&&r.firstChild?r.insertBefore(a,r.firstChild):r.appendChild(a),a.styleSheet?a.styleSheet.cssText=n:a.appendChild(document.createTextNode(n))}}("/**\n * Modfied version of [termynal.js](https://github.com/ines/termynal/blob/master/termynal.css).\n *\n * @author Ines Montani <ines@ines.io>\n * @version 0.0.1\n * @license MIT\n */\n .react-terminal-wrapper {\n width: 100%;\n background: #252a33;\n color: #eee;\n font-size: 18px;\n font-family: 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace;\n border-radius: 4px;\n padding: 75px 45px 35px;\n position: relative;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n }\n\n.react-terminal {\n overflow: auto;\n display: flex;\n flex-direction: column;\n}\n\n.react-terminal-wrapper.react-terminal-light {\n background: #ddd;\n color: #1a1e24;\n}\n\n.react-terminal-window-buttons {\n position: absolute;\n top: 15px;\n left: 15px;\n display: flex;\n flex-direction: row;\n gap: 10px;\n}\n\n.react-terminal-window-buttons button {\n width: 15px;\n height: 15px;\n border-radius: 50%;\n border: 0;\n}\n\n.react-terminal-window-buttons button.clickable {\n cursor: pointer;\n}\n\n.react-terminal-window-buttons button.red-btn {\n background: #d9515d;\n}\n\n.react-terminal-window-buttons button.yellow-btn {\n background: #f4c025;\n}\n\n.react-terminal-window-buttons button.green-btn {\n background: #3ec930;\n}\n\n.react-terminal-wrapper:after {\n content: attr(data-terminal-name);\n position: absolute;\n color: #a2a2a2;\n top: 5px;\n left: 0;\n width: 100%;\n text-align: center;\n pointer-events: none;\n}\n\n.react-terminal-wrapper.react-terminal-light:after {\n color: #D76D77;\n}\n\n.react-terminal-line {\n white-space: pre;\n}\n\n.react-terminal-line:before {\n /* Set up defaults and ensure empty lines are displayed. */\n content: '';\n display: inline-block;\n vertical-align: middle;\n color: #a2a2a2;\n}\n\n.react-terminal-light .react-terminal-line:before {\n color: #D76D77;\n}\n\n.react-terminal-input:before {\n margin-right: 0.75em;\n content: '$';\n}\n\n.react-terminal-input[data-terminal-prompt]:before {\n content: attr(data-terminal-prompt);\n}\n\n.react-terminal-wrapper:focus-within .react-terminal-active-input .cursor {\n position: relative;\n display: inline-block;\n width: 0.55em;\n height: 1em;\n top: 0.225em;\n background: #fff;\n -webkit-animation: blink 1s infinite;\n animation: blink 1s infinite;\n}\n\n/* Cursor animation */\n\n@-webkit-keyframes blink {\n 50% {\n opacity: 0;\n }\n}\n\n@keyframes blink {\n 50% {\n opacity: 0;\n }\n}\n\n.terminal-hidden-input {\n position: fixed;\n left: -1000px;\n}\n\n/* .react-terminal-progress {\n display: flex;\n margin: .5rem 0;\n}\n\n.react-terminal-progress-bar {\n background-color: #fff;\n border-radius: .25rem;\n width: 25%;\n}\n\n.react-terminal-wrapper.react-terminal-light .react-terminal-progress-bar {\n background-color: #000;\n} */\n");var o,c=function(e){var t=e.redBtnCallback,r=e.yellowBtnCallback,a=e.greenBtnCallback;return n.createElement("div",{className:"react-terminal-window-buttons"},n.createElement("button",{className:"".concat(r?"clickable":""," red-btn"),disabled:!t,onClick:t}),n.createElement("button",{className:"".concat(r?"clickable":""," yellow-btn"),disabled:!r,onClick:r}),n.createElement("button",{className:"".concat(a?"clickable":""," green-btn"),disabled:!a,onClick:a}))};!function(n){n[n.Light=0]="Light",n[n.Dark=1]="Dark"}(o||(o={}));var d=function(i){var l=i.name,d=i.prompt,s=i.height,m=void 0===s?"600px":s,u=i.colorMode,p=i.onInput,f=i.children,b=i.startingInputValue,y=void 0===b?"":b,h=i.redBtnCallback,v=i.yellowBtnCallback,w=i.greenBtnCallback,g=i.TopButtonsPanel,k=void 0===g?c:g,x=a(e(""),2),C=x[0],E=x[1],S=a(e(0),2),N=S[0],B=S[1],D=t(null);r((function(){E(y.trim())}),[y]),r((function(){var n,e;if(null!=p){var t=[],r=function(n){var e=function(){var e;return null===(e=null==n?void 0:n.querySelector(".terminal-hidden-input"))||void 0===e?void 0:e.focus()};null==n||n.addEventListener("click",e),t.push({terminalEl:n,listener:e})};try{for(var a=function(n){var e="function"==typeof Symbol&&Symbol.iterator,t=e&&n[e],r=0;if(t)return t.call(n);if(n&&"number"==typeof n.length)return{next:function(){return n&&r>=n.length&&(n=void 0),{value:n&&n[r++],done:!n}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}(document.getElementsByClassName("react-terminal-wrapper")),i=a.next();!i.done;i=a.next()){r(i.value)}}catch(e){n={error:e}}finally{try{i&&!i.done&&(e=a.return)&&e.call(a)}finally{if(n)throw n.error}}return function(){t.forEach((function(n){n.terminalEl.removeEventListener("click",n.listener)}))}}}),[p]);var T=["react-terminal-wrapper"];return u===o.Light&&T.push("react-terminal-light"),n.createElement("div",{className:T.join(" "),"data-terminal-name":l},n.createElement(k,{redBtnCallback:h,yellowBtnCallback:v,greenBtnCallback:w}),n.createElement("div",{className:"react-terminal",style:{height:m}},f,"function"==typeof p&&n.createElement("div",{className:"react-terminal-line react-terminal-input react-terminal-active-input","data-terminal-prompt":d||"$",key:"terminal-line-prompt"},C,n.createElement("span",{className:"cursor",style:{left:"".concat(N+1,"px")}})),n.createElement("div",{ref:D})),n.createElement("input",{className:"terminal-hidden-input",placeholder:"Terminal Hidden Input",value:C,autoFocus:null!=p,onChange:function(n){E(n.target.value)},onKeyDown:function(n){var e,t,r;if(p)if("Enter"===n.key)p(C),B(0),E(""),setTimeout((function(){var n;return null===(n=null==D?void 0:D.current)||void 0===n?void 0:n.scrollIntoView({behavior:"auto",block:"nearest"})}),500);else if(["ArrowLeft","ArrowRight","ArrowDown","ArrowUp","Delete"].includes(n.key)){var a=n.currentTarget,i="",l=C.length-(a.selectionStart||0);e=l,t=0,r=C.length,l=e>r?r:e<t?t:e,"ArrowLeft"===n.key?(l>C.length-1&&l--,i=C.slice(C.length-1-l)):"ArrowRight"===n.key||"Delete"===n.key?i=C.slice(C.length-l+1):"ArrowUp"===n.key&&(i=C.slice(0));var o=function(n,e){var t=document.createElement("span");t.style.visibility="hidden",t.style.position="absolute",t.style.fontSize=window.getComputedStyle(n).fontSize,t.style.fontFamily=window.getComputedStyle(n).fontFamily,t.innerText=e,document.body.appendChild(t);var r=t.getBoundingClientRect().width;return document.body.removeChild(t),-r}(a,i);B(o)}}}))};export{o as ColorMode,i as TerminalInput,l as TerminalOutput,d as default}; //# sourceMappingURL=index.es.js.map