2025-12-31 22:20:12 -06:00
|
|
|
import {
|
|
|
|
|
TERMINAL_THEMES,
|
|
|
|
|
TERMINAL_FONTS,
|
|
|
|
|
} from "@/constants/terminal-themes.ts";
|
|
|
|
|
import { useTheme } from "@/components/theme-provider.tsx";
|
2025-11-05 10:36:16 -06:00
|
|
|
|
|
|
|
|
interface TerminalPreviewProps {
|
|
|
|
|
theme: string;
|
|
|
|
|
fontSize?: number;
|
|
|
|
|
fontFamily?: string;
|
|
|
|
|
cursorStyle?: "block" | "underline" | "bar";
|
|
|
|
|
cursorBlink?: boolean;
|
|
|
|
|
letterSpacing?: number;
|
|
|
|
|
lineHeight?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function TerminalPreview({
|
|
|
|
|
theme = "termix",
|
|
|
|
|
fontSize = 14,
|
|
|
|
|
fontFamily = "Caskaydia Cove Nerd Font Mono",
|
|
|
|
|
cursorStyle = "bar",
|
|
|
|
|
cursorBlink = true,
|
|
|
|
|
letterSpacing = 0,
|
|
|
|
|
lineHeight = 1.2,
|
|
|
|
|
}: TerminalPreviewProps) {
|
2025-12-31 22:20:12 -06:00
|
|
|
const { theme: appTheme } = useTheme();
|
|
|
|
|
|
|
|
|
|
const resolvedTheme =
|
|
|
|
|
theme === "termix"
|
|
|
|
|
? appTheme === "dark" ||
|
|
|
|
|
(appTheme === "system" &&
|
|
|
|
|
window.matchMedia("(prefers-color-scheme: dark)").matches)
|
|
|
|
|
? "termixDark"
|
|
|
|
|
: "termixLight"
|
|
|
|
|
: theme;
|
|
|
|
|
|
2025-11-05 10:36:16 -06:00
|
|
|
return (
|
|
|
|
|
<div className="border border-input rounded-md overflow-hidden">
|
|
|
|
|
<div
|
|
|
|
|
className="p-4 font-mono text-sm"
|
|
|
|
|
style={{
|
|
|
|
|
fontSize: `${fontSize}px`,
|
|
|
|
|
fontFamily:
|
|
|
|
|
TERMINAL_FONTS.find((f) => f.value === fontFamily)?.fallback ||
|
|
|
|
|
TERMINAL_FONTS[0].fallback,
|
|
|
|
|
letterSpacing: `${letterSpacing}px`,
|
|
|
|
|
lineHeight,
|
2025-12-31 22:20:12 -06:00
|
|
|
background:
|
|
|
|
|
TERMINAL_THEMES[resolvedTheme]?.colors.background ||
|
|
|
|
|
"var(--bg-base)",
|
|
|
|
|
color:
|
|
|
|
|
TERMINAL_THEMES[resolvedTheme]?.colors.foreground ||
|
|
|
|
|
"var(--foreground)",
|
2025-11-05 10:36:16 -06:00
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div>
|
2025-12-31 22:20:12 -06:00
|
|
|
<span style={{ color: TERMINAL_THEMES[resolvedTheme]?.colors.green }}>
|
2025-11-05 10:36:16 -06:00
|
|
|
user@termix
|
|
|
|
|
</span>
|
|
|
|
|
<span>:</span>
|
2025-12-31 22:20:12 -06:00
|
|
|
<span style={{ color: TERMINAL_THEMES[resolvedTheme]?.colors.blue }}>
|
|
|
|
|
~
|
|
|
|
|
</span>
|
2025-11-05 10:36:16 -06:00
|
|
|
<span>$ ls -la</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
2025-12-31 22:20:12 -06:00
|
|
|
<span style={{ color: TERMINAL_THEMES[resolvedTheme]?.colors.blue }}>
|
2025-11-05 10:36:16 -06:00
|
|
|
drwxr-xr-x
|
|
|
|
|
</span>
|
|
|
|
|
<span> 5 user </span>
|
2025-12-31 22:20:12 -06:00
|
|
|
<span style={{ color: TERMINAL_THEMES[resolvedTheme]?.colors.cyan }}>
|
2025-11-05 10:36:16 -06:00
|
|
|
docs
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
2025-12-31 22:20:12 -06:00
|
|
|
<span style={{ color: TERMINAL_THEMES[resolvedTheme]?.colors.green }}>
|
2025-11-05 10:36:16 -06:00
|
|
|
-rwxr-xr-x
|
|
|
|
|
</span>
|
|
|
|
|
<span> 1 user </span>
|
2025-12-31 22:20:12 -06:00
|
|
|
<span style={{ color: TERMINAL_THEMES[resolvedTheme]?.colors.green }}>
|
2025-11-05 10:36:16 -06:00
|
|
|
script.sh
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<span>-rw-r--r--</span>
|
|
|
|
|
<span> 1 user </span>
|
|
|
|
|
<span>README.md</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
2025-12-31 22:20:12 -06:00
|
|
|
<span style={{ color: TERMINAL_THEMES[resolvedTheme]?.colors.green }}>
|
2025-11-05 10:36:16 -06:00
|
|
|
user@termix
|
|
|
|
|
</span>
|
|
|
|
|
<span>:</span>
|
2025-12-31 22:20:12 -06:00
|
|
|
<span style={{ color: TERMINAL_THEMES[resolvedTheme]?.colors.blue }}>
|
|
|
|
|
~
|
|
|
|
|
</span>
|
2025-11-05 10:36:16 -06:00
|
|
|
<span>$ </span>
|
|
|
|
|
<span
|
|
|
|
|
className="inline-block"
|
|
|
|
|
style={{
|
|
|
|
|
width: cursorStyle === "block" ? "0.6em" : "0.1em",
|
|
|
|
|
height:
|
|
|
|
|
cursorStyle === "underline"
|
|
|
|
|
? "0.15em"
|
|
|
|
|
: cursorStyle === "bar"
|
|
|
|
|
? `${fontSize}px`
|
|
|
|
|
: `${fontSize}px`,
|
2025-12-31 22:20:12 -06:00
|
|
|
background:
|
|
|
|
|
TERMINAL_THEMES[resolvedTheme]?.colors.cursor || "#f7f7f7",
|
2025-11-05 10:36:16 -06:00
|
|
|
animation: cursorBlink ? "blink 1s step-end infinite" : "none",
|
|
|
|
|
verticalAlign:
|
|
|
|
|
cursorStyle === "underline" ? "bottom" : "text-bottom",
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<style>{`
|
|
|
|
|
@keyframes blink {
|
|
|
|
|
0%, 49% { opacity: 1; }
|
|
|
|
|
50%, 100% { opacity: 0; }
|
|
|
|
|
}
|
|
|
|
|
`}</style>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|