import { useCallback } from 'react'; import { Maximize2 } from 'lucide-react'; import { cn } from '@/lib/utils'; // ============================================================ // TerminalHotkeyBar — v1.10.8d port of boolab's TerminalHotkeyBar.jsx + // terminalHotkeysStore.js DEFAULT_BAR. The catalog is hardcoded inline (no // zustand store, no settings UI) — single-user homelab doesn't need either. // Add new entries by extending HOTKEY_BAR below. // ============================================================ type Hotkey = | { id: string; label: string; bytes: string; sticky?: undefined } | { id: string; label: string; sticky: 'ctrl'; bytes?: undefined }; const HOTKEY_BAR: Hotkey[] = [ { id: 'esc', label: 'Esc', bytes: '\x1b' }, { id: 'shift-tab', label: '⇧Tab', bytes: '\x1b[Z' }, { id: 'tab', label: 'Tab', bytes: '\t' }, { id: 'ctrl', label: 'Ctrl', sticky: 'ctrl' }, { id: 'ctrl-c', label: 'Ctrl+C', bytes: '\x03' }, { id: 'arrow-up', label: '↑', bytes: '\x1b[A' }, { id: 'arrow-down', label: '↓', bytes: '\x1b[B' }, { id: 'arrow-left', label: '←', bytes: '\x1b[D' }, { id: 'arrow-right', label: '→', bytes: '\x1b[C' }, ]; interface TerminalHotkeyBarProps { ctrlArmed: boolean; onSendBytes: (bytes: string) => void; onArmCtrl: () => void; onFit: () => void; } export function TerminalHotkeyBar({ ctrlArmed, onSendBytes, onArmCtrl, onFit, }: TerminalHotkeyBarProps) { // Stop the touch from reaching the terminal pane below (which calls // preventDefault on touchmove to suppress page-scroll). Without this a // tap-and-drag on a hotkey button would also scroll the terminal buffer. const stopTouch = useCallback((e: React.TouchEvent) => e.stopPropagation(), []); const press = useCallback( (entry: Hotkey) => { if (entry.sticky === 'ctrl') { onArmCtrl(); } else if (entry.bytes !== undefined) { onSendBytes(entry.bytes); } }, [onArmCtrl, onSendBytes], ); return (
{HOTKEY_BAR.map((entry) => { const isCtrl = entry.sticky === 'ctrl'; const armed = isCtrl && ctrlArmed; return ( ); })}
); }