Back to Component Explorer
Interactive Terminal
effectsDeveloper macOS style terminal command prompt with execution output logs and one-click copy.
#terminal#bash#developer#command#prompt
Live Interactive Preview
bash ~ interactive
➜~npx aurenza-ui init
✔ Ready! Aurenza UI setup complete.
Type 'help' to view all available commands.
Component Source Code
Select language in the dropdownTerminalCard.tsx
1'use client';23import React, { useState, useRef, useEffect } from 'react';4import { Check, Copy, CornerDownLeft } from 'lucide-react';56interface CommandHistory {7 command: string;8 output: string | React.ReactNode;9}1011export default function TerminalCard() {12 const [copied, setCopied] = useState(false);13 const [inputVal, setInputVal] = useState('');14 const [history, setHistory] = useState<CommandHistory[]>([15 {16 command: 'npx aurenza-ui init',17 output: (18 <div className="text-slate-400 text-[11px] space-y-0.5 font-mono">19 <p className="text-emerald-400">✔ Ready! Aurenza UI setup complete.</p>20 <p className="text-slate-500">Type 'help' to view all available commands.</p>21 </div>22 )23 }24 ]);25 const bottomRef = useRef<HTMLDivElement>(null);26 const inputRef = useRef<HTMLInputElement>(null);2728 const copy = () => {29 navigator.clipboard.writeText('npx aurenza-ui init');30 setCopied(true);31 setTimeout(() => setCopied(false), 2000);32 };3334 const handleCommand = (e: React.FormEvent) => {35 e.preventDefault();36 const cmd = inputVal.trim();37 if (!cmd) return;3839 let out: React.ReactNode = '';40 const lower = cmd.toLowerCase();4142 if (lower === 'help') {43 out = (44 <div className="text-[11px] text-slate-300 space-y-1">45 <p><span className="text-cyan-400 font-bold">components</span> - List top UI components</p>46 <p><span className="text-cyan-400 font-bold">version</span> - Display Aurenza UI release version</p>47 <p><span className="text-cyan-400 font-bold">theme</span> - Toggle spatial cyber matrix tokens</p>48 <p><span className="text-cyan-400 font-bold">clear</span> - Clear terminal session</p>49 </div>50 );51 } else if (lower === 'clear') {52 setHistory([]);53 setInputVal('');54 return;55 } else if (lower === 'components') {56 out = <div className="text-[11px] text-emerald-300">Available: 3D Spatial Globe, 5-Layer Orbit, Infinite Marquee, Bento Grid...</div>;57 } else if (lower === 'version') {58 out = <span className="text-blue-400 text-[11px]">aurenza-ui v2.4.0 (Turbopack + Tailwind v4)</span>;59 } else if (lower === 'theme') {60 out = <span className="text-purple-400 text-[11px]">✨ Spatial Dark Theme active</span>;61 } else {62 out = <span className="text-rose-400 text-[11px]">command not found: {cmd}. Type 'help' for list.</span>;63 }6465 setHistory((prev) => [...prev, { command: cmd, output: out }]);66 setInputVal('');67 };6869 const terminalBodyRef = useRef<HTMLDivElement>(null);7071 useEffect(() => {72 if (terminalBodyRef.current) {73 terminalBodyRef.current.scrollTop = terminalBodyRef.current.scrollHeight;74 }75 }, [history]);7677 return (78 <div79 onClick={() => inputRef.current?.focus()}80 className="w-full max-w-lg overflow-hidden rounded-3xl border border-slate-800 bg-slate-950 font-mono text-xs text-slate-100 shadow-2xl transition-all"81 >82 <div className="flex items-center justify-between border-b border-slate-800 bg-slate-900/80 px-4 py-2.5">83 <div className="flex items-center gap-2">84 <span className="h-3 w-3 rounded-full bg-rose-500/80 cursor-pointer" />85 <span className="h-3 w-3 rounded-full bg-amber-500/80 cursor-pointer" />86 <span className="h-3 w-3 rounded-full bg-emerald-500/80 cursor-pointer" />87 <span className="ml-2 font-sans text-xs text-slate-400 font-medium">bash ~ interactive</span>88 </div>89 <button90 onClick={(e) => {91 e.stopPropagation();92 copy();93 }}94 className="flex items-center gap-1 text-slate-400 hover:text-white transition cursor-pointer"95 >96 {copied ? <Check className="h-3.5 w-3.5 text-emerald-400" /> : <Copy className="h-3.5 w-3.5" />}97 <span>{copied ? 'Copied' : 'Copy'}</span>98 </button>99 </div>100101 <div className="p-4 sm:p-5 max-h-64 overflow-y-auto space-y-3">102 {history.map((h, i) => (103 <div key={i} className="space-y-1">104 <div className="flex items-center gap-2 text-emerald-400 font-bold">105 <span>➜</span>106 <span className="text-cyan-400">~</span>107 <span className="text-white font-normal">{h.command}</span>108 </div>109 <div>{h.output}</div>110 </div>111 ))}112113 <form onSubmit={handleCommand} className="flex items-center gap-2 pt-1">114 <span className="text-emerald-400 font-bold">➜</span>115 <span className="text-cyan-400 font-bold">~</span>116 <input117 ref={inputRef}118 type="text"119 value={inputVal}120 onChange={(e) => setInputVal(e.target.value)}121 placeholder="Type 'help' or any command..."122 className="flex-1 bg-transparent text-white placeholder:text-slate-600 outline-none font-mono text-xs caret-cyan-400"123 />124 <button type="submit" className="text-slate-500 hover:text-cyan-400 transition cursor-pointer">125 <CornerDownLeft className="h-3 w-3" />126 </button>127 </form>128 <div ref={bottomRef} />129 </div>130 </div>131 );132}Installation & Integration Guide
Step 1: Tailwind CSS v4 Setup
Tailwind DocsIf you do not have Tailwind installed yet, run this installation command:
Terminal
npm install tailwindcss @tailwindcss/postcss postcss
Then add the Tailwind directive to your main stylesheet (globals.css):
@import "tailwindcss";
Step 2: Install Icon Dependencies
npm install lucide-react react-icons
Step 3: Add Component File
Create a new file in your project at src/components/effects/TerminalCard.tsx and paste the copied code from the source viewer above.
Step 4: Usage Example
ExamplePage.tsx
1import InteractiveTerminal from '@/components/effects/TerminalCard';23export default function ExamplePage() {4 return (5 <main className="p-8 flex items-center justify-center min-h-screen">6 <InteractiveTerminal />7 </main>8 );9}