react-command-flow
Version:
A beautiful interactive CLI-style command interface for React apps
261 lines (221 loc) • 6.59 kB
Markdown
# 🖥️ React Command Flow
A beautifully interactive CLI-style command interface for React apps.
Type commands, flow through steps, and build dynamic, conversational UI experiences.
## ✨ Features
- 🖋 Terminal-style input & output
- 📋 Step-based command flows
- ✅ Built-in validation (sync & async)
- 🔀 Conditional prompts, branching logic
- ⚡ Dynamic suggestions & tab completion
- 💅 Theme support
- 🔍 Help & clear commands out of the box
- 🔌 Easy to extend and customize
## 📦 Installation
```bash
npm install react-command-flow
```
## ⚡ Usage
```jsx
import React from "react";
import { CommandLine } from "react-command-flow";
import { commands } from "./commands";
export default function App() {
return (
<div style={{ padding: "2rem" }}>
<h1>React Command Flow Demo</h1>
<CommandLine commands={commands} />
</div>
);
}
```
## 📚 Defining Commands
```js
const colors = ["Red", "Green", "Blue", "Yellow", "Purple"];
const shapes = ["Circle", "Square", "Triangle", "Rectangle", "Hexagon"];
const commands = {
"color-shape-quiz": {
description: "Start your color and shape quiz 🌈🔺",
steps: [
{
prompt: async () => {
await new Promise((res) => setTimeout(res, 1000)); // async wait
return `What is your favorite color?\n${colors
.map((c, i) => `${i + 1}. ${c}`)
.join("\n")}\nEnter color index:`;
},
field: "colorIndex",
validate: async (val) => {
return ["1", "2", "3", "4", "5"].includes(val)
? true
: "❌ Please select a number between 1 and 5.";
},
redirectToCommand: (val) => {
const color = colors[parseInt(val) - 1];
if (color === "Red") return "color-red-flow";
if (color === "Green") return "color-green-flow";
if (color === "Blue") return "color-blue-flow";
if (color === "Yellow") return "color-yellow-flow";
if (color === "Purple") return "color-purple-flow";
return "color-other-flow";
},
},
],
onComplete: () => "Redirecting...",
},
"color-red-flow": {
description: "Red color path 🔴",
hidden: true,
steps: [
{
prompt: "What shape do you associate with Red?",
field: "redShape",
validate: (val) => {
return shapes.includes(val) ? true : "❌ Please enter a valid shape.";
},
},
],
onComplete: async () => {
await new Promise((res) => setTimeout(res, 1000)); // fake async post
return "✅ Red is a powerful color!";
},
},
"color-green-flow": {
description: "Green color path 🟢",
hidden: true,
steps: [
{
prompt: "What shape do you associate with Green?",
field: "greenShape",
validate: (val) => {
return shapes.includes(val) ? true : "❌ Please enter a valid shape.";
},
},
],
onComplete: async () => {
await new Promise((res) => setTimeout(res, 1000)); // fake async post
return "✅ Green is a calming color!";
},
},
"color-blue-flow": {
description: "Blue color path 🔵",
hidden: true,
steps: [
{
prompt: "What shape do you associate with Blue?",
field: "blueShape",
validate: (val) => {
return shapes.includes(val) ? true : "❌ Please enter a valid shape.";
},
},
],
onComplete: async () => {
await new Promise((res) => setTimeout(res, 1000)); // fake async post
return "✅ Blue is a soothing color!";
},
},
"color-yellow-flow": {
description: "Yellow color path 🟡",
hidden: true,
steps: [
{
prompt: "What shape do you associate with Yellow?",
field: "yellowShape",
validate: (val) => {
return shapes.includes(val) ? true : "❌ Please enter a valid shape.";
},
},
{
prompt: "What emotion do you associate with Yellow?",
field: "yellowEmotion",
validate: (val) => {
const emotions = ["happiness", "energy", "warmth", "caution"];
return emotions.includes(val.toLowerCase())
? true
: "❌ Please enter a valid emotion (happiness, energy, warmth, caution).";
},
},
{
prompt: "What object do you associate with Yellow?",
field: "yellowObject",
validate: (val) => {
return val.length > 0 ? true : "❌ Please enter a valid object.";
},
},
],
onComplete: async () => {
await new Promise((res) => setTimeout(res, 1000)); // fake async post
return "✅ Yellow is a bright and cheerful color!";
},
},
"color-purple-flow": {
description: "Purple color path 🟣",
hidden: true,
steps: [
{
prompt: "What shape do you associate with Purple?",
field: "purpleShape",
validate: (val) => {
return shapes.includes(val) ? true : "❌ Please enter a valid shape.";
},
},
],
onComplete: async () => {
await new Promise((res) => setTimeout(res, 1000)); // fake async post
return "✅ Purple is a royal color!";
},
},
"color-other-flow": {
description: "Other color path 🌈",
hidden: true,
steps: [],
onComplete: () => "💛 All colors are beautiful!",
},
help: {
description: "List available commands",
steps: [],
onComplete: (_, __, all) => {
return Object.entries(all)
.filter(([_, c]) => !c.hidden)
.map(([name, c]) => `- ${name}: ${c.description}`)
.join("\n");
},
},
clear: {
description: "Clear the screen",
steps: [],
onComplete: () => "__CLEAR__",
},
};
// Alias added outside
commands["?"] = commands.help;
export default commands;
```
## 🧠 Advanced Examples
- 🔁 Async prompt resolution
- ✅ Custom validation per step
- 🔀 `onStep` logic to transform values
- 🧭 Conditional steps (based on previous answers)
- 📦 Redirects to subcommands (optional)
## 🖌️ Theming
Supports custom themes with colors and fonts.
You can pass a `theme` prop to `<CommandLine />`.
## 💡 Example Commands You Can Try
- `hello`
- `profile-setup`
- `select-server`
- `help`
- `clear`
## 📜 License
MIT — free to use, modify, contribute.
Made with 💛 by Stam & React Command Flow Contributors.
## ⭐ Star this repo if you like it!
Let's build the coolest CLI UIs in the React world 🌍