← Components/Code

TerminalPrompt

terminalprompt-1779388705857.tsx
'use client';
import { useState, useRef, useEffect } from 'react';

export default function TerminalPrompt() {
  const [history, setHistory] = useState([
    { type: 'output', text: 'Welcome to Empire Terminal v2.0.0' },
    { type: 'output', text: 'Type "help" for available commands.' },
  ]);
  const [input, setInput] = useState('');
  const [cmdHistory, setCmdHistory] = useState([]);
  const [histIdx, setHistIdx] = useState(-1);
  const bottomRef = useRef(null);

  const commands = {
    help: () => 'Available: help, clear, whoami, date, echo <text>',
    whoami: () => 'empire-user (admin)',
    date: () => new Date().toLocaleString(),
    clear: () => { setHistory([]); return null; },
    echo: (args) => args.join(' ') || '(empty)',
  };

  const run = () => {
    if (!input.trim()) return;
    const parts = input.trim().split(' ');
    const cmd = parts[0].toLowerCase();
    const args = parts.slice(1);
    const out = commands[cmd] ? commands[cmd](args) : `Command not found: ${cmd}`;
    setCmdHistory(h => [input, ...h]);
    setHistIdx(-1);
    setHistory(h => [
      ...h,
      { type: 'input', text: input },
      ...(out !== null ? [{ type: 'output', text: out }] : []),
    ]);
    setInput('');
  };

  useEffect(() => { bottomRef.current?.scrollIntoView(); }, [history]);

  return (
    <div style={{
      fontFamily: 'monospace',
      background: '#0a0a0a',
      border: '1px solid rgba(255,255,255,0.1)',
      borderRadius: '12px',
      overflow: 'hidden',
      width: '480px',
    }}>
      <div style={{ background: '#1a1a1a', padding: '10px 16px', display: 'flex', gap: '8px', alignItems: 'center', borderBottom: '1px solid rgba(255,255,255,0.07)' }}>
        {['#ef4444', '#f59e0b', '#22c55e'].map(c => <div key={c} style={{ width: '12px', height: '12px', borderRadius: '50%', background: c }} />)}
        <span style={{ color: 'rgba(245,245,240,0.4)', fontSize: '12px', marginLeft: '8px' }}>empire-terminal</span>
      </div>
      <div style={{ padding: '16px', height: '220px', overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: '4px' }}>
        {history.map((h, i) => (
          <div key={i} style={{ display: 'flex', gap: '8px' }}>
            {h.type === 'input' && <span style={{ color: '#C9A84C' }}>❯</span>}
            <span style={{ color: h.type === 'input' ? '#F5F5F0' : 'rgba(245,245,240,0.55)', fontSize: '13px' }}>{h.text}</span>
          </div>
        ))}
        <div ref={bottomRef} />
      </div>
      <div style={{ display: 'flex', gap: '8px', padding: '10px 16px', borderTop: '1px solid rgba(255,255,255,0.07)', alignItems: 'center' }}>
        <span style={{ color: '#C9A84C', fontSize: '14px' }}>❯</span>
        <input
          value={input}
          onChange={e => setInput(e.target.value)}
          onKeyDown={e => {
            if (e.key === 'Enter') run();
            if (e.key === 'ArrowUp') { const i = Math.min(histIdx + 1, cmdHistory.length - 1); setHistIdx(i); setInput(cmdHistory[i] || ''); }
            if (e.key === 'ArrowDown') { const i = Math.max(histIdx - 1, -1); setHistIdx(i); setInput(i === -1 ? '' : cmdHistory[i]); }
          }}
          style={{
            flex: 1, background: 'none', border: 'none', color: '#F5F5F0',
            fontSize: '13px', outline: 'none', fontFamily: 'monospace',
          }}
          placeholder="type a command..."
          autoFocus
        />
      </div>
    </div>
  );
}

Component info

CategoryCode
Frameworkreact
TierFREE
Views0
Copies0

About

Interactive terminal-style prompt with history

More from Code

'use client'
import { useState } from 'react'

const EXAMPLES = {
  tsx: {
    label: 'TypeScript',
    code: `import { useState } from 'react'

interface ButtonProps {
  variant?: 'primary' | 'ghost'
  children: React.ReactNode
  onClick?: () => voi
CodeBlock
Code