diff --git a/demo/index.tsx b/demo/index.tsx
index 79109d8..767289f 100644
--- a/demo/index.tsx
+++ b/demo/index.tsx
@@ -1,6 +1,6 @@
import React, { useState, MouseEvent } from 'react'
import ReactDOM from 'react-dom';
-import Terminal, { ColorMode, TerminalInput, TerminalOutput } from '../src/index';
+import Terminal, { ColorMode, TerminalInput, TerminalOutput, TerminalProgress } from '../src/index';
import './style.css';
@@ -13,6 +13,7 @@ const TerminalController = (props = {}) => {
'view-source' will navigate to the React Terminal UI github source.,
'view-react-docs' will navigate to the react docs.,
'clear' will clear the terminal.,
+
]);
function toggleColorMode (e: MouseEvent) {
diff --git a/src/index.tsx b/src/index.tsx
index a615135..32c06ce 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,6 +1,8 @@
import React, { useState, useEffect, useRef, KeyboardEvent, ChangeEvent, ReactNode, ReactNodeArray } from 'react';
import TerminalInput from './linetypes/TerminalInput';
import TerminalOutput from './linetypes/TerminalOutput';
+import TerminalProgress from './linetypes/TerminalProgress';
+import TerminalLoader from './linetypes/TerminalLoader'
import './style.css';
export enum ColorMode {
@@ -19,9 +21,10 @@ export interface Props {
redBtnCallback?: () => void;
yellowBtnCallback?: () => void;
greenBtnCallback?: () => void;
+ loading?: boolean;
}
-const Terminal = ({name, prompt, height = "600px", colorMode, onInput, children, startingInputValue = "", redBtnCallback, yellowBtnCallback, greenBtnCallback}: Props) => {
+const Terminal = ({name, prompt, height = "600px", colorMode, onInput, children, startingInputValue = "", redBtnCallback, yellowBtnCallback, greenBtnCallback, loading}: Props) => {
const [currentLineInput, setCurrentLineInput] = useState('');
const [cursorPos, setCursorPos] = useState(0);
@@ -120,13 +123,13 @@ const Terminal = ({name, prompt, height = "600px", colorMode, onInput, children,
{ children }
- { typeof onInput === 'function' &&
{ currentLineInput }
}
+ { typeof onInput === 'function' && !loading &&
{ currentLineInput }
}
-
+ {!loading && }
);
}
-export { TerminalInput, TerminalOutput };
+export { TerminalInput, TerminalOutput, TerminalProgress, TerminalLoader };
export default Terminal;
diff --git a/src/linetypes/TerminalLoader.tsx b/src/linetypes/TerminalLoader.tsx
new file mode 100644
index 0000000..c6c4a9a
--- /dev/null
+++ b/src/linetypes/TerminalLoader.tsx
@@ -0,0 +1,26 @@
+import React, { PropsWithChildren, useEffect, useState } from "react";
+export const loaderChars = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
+
+type TerminalLoaderProps = PropsWithChildren<{
+ loaderCharacters?: Array
+}>;
+
+
+const TerminalLoader = ({ loaderCharacters = loaderChars }: TerminalLoaderProps) => {
+ const [loaderIndex, setLoaderIndex] = useState(0);
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setLoaderIndex((loaderIndex + 1) % loaderCharacters.length);
+ }, 100);
+ return () => clearInterval(interval);
+ }, [loaderIndex]);
+
+ return (
+
+ {loaderCharacters[loaderIndex]}
+
+ );
+};
+
+export default TerminalLoader;
diff --git a/src/linetypes/TerminalProgress.tsx b/src/linetypes/TerminalProgress.tsx
new file mode 100644
index 0000000..b397261
--- /dev/null
+++ b/src/linetypes/TerminalProgress.tsx
@@ -0,0 +1,34 @@
+import React, { PropsWithChildren } from "react";
+import TerminalLoader from "./TerminalLoader";
+
+type TerminalProgressProps = PropsWithChildren<{
+ progressPercentage?: number;
+ progressLength?: number;
+ progressChar?: string;
+}>;
+
+const TerminalProgress = ({
+ progressPercentage = 0,
+ progressLength = 20,
+ progressChar = "█",
+}: TerminalProgressProps) => {
+ return (
+
+
+ {progressChar.repeat(progressPercentage * progressLength)}
+
+
+ {progressChar.repeat(
+ progressLength - progressPercentage * progressLength
+ )}
+
+
+ {Math.round(progressPercentage * 100).toString()}%
+
+ );
+};
+
+export default TerminalProgress;
diff --git a/src/style.css b/src/style.css
index d6a4b92..20cc4e7 100644
--- a/src/style.css
+++ b/src/style.css
@@ -145,3 +145,36 @@
.react-terminal-wrapper.react-terminal-light .react-terminal-progress-bar {
background-color: #000;
} */
+
+.react-terminal-progress {
+ display: flex;
+ margin: .5rem 0;
+ align-items: center;
+}
+
+.react-terminal-progress-filled {
+ color: #fff;
+}
+
+.react-terminal-progress-empty {
+ color: #000;
+}
+
+.react-terminal-light .react-terminal-progress-filled {
+ color: #1a1e24;
+}
+
+.react-terminal-light .react-terminal-progress-empty {
+ color: #fff;
+}
+
+.react-terminal-loader {
+ font-size: 20px;
+ margin-bottom: -2px;
+ margin-left: 0.5rem;
+}
+
+.react-terminal-progress-label {
+ margin-left: 1rem;
+ font-size: 16px;
+}
\ No newline at end of file