v1.8.0 #429

Merged
LukeGus merged 198 commits from dev-1.8.0 into main 2025-11-05 16:36:16 +00:00
3 changed files with 882 additions and 0 deletions
Showing only changes of commit 8813e60ead - Show all commits

View File

@@ -0,0 +1,61 @@
import * as React from "react";
import * as SliderPrimitive from "@radix-ui/react-slider";
import { cn } from "@/lib/utils";
function Slider({
className,
defaultValue,
value,
min = 0,
max = 100,
...props
}: React.ComponentProps<typeof SliderPrimitive.Root>) {
const _values = React.useMemo(
() =>
Array.isArray(value)
? value
: Array.isArray(defaultValue)
? defaultValue
: [min, max],
[value, defaultValue, min, max],
);
return (
<SliderPrimitive.Root
data-slot="slider"
defaultValue={defaultValue}
value={value}
min={min}
max={max}
className={cn(
"relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col",
className,
)}
{...props}
>
<SliderPrimitive.Track
data-slot="slider-track"
className={cn(
"bg-muted relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5",
)}
>
<SliderPrimitive.Range
data-slot="slider-range"
className={cn(
"bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full",
)}
/>
</SliderPrimitive.Track>
{Array.from({ length: _values.length }, (_, index) => (
<SliderPrimitive.Thumb
data-slot="slider-thumb"
key={index}
className="border-primary ring-ring/50 block size-4 shrink-0 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50"
/>
))}
</SliderPrimitive.Root>
);
}
export { Slider };

View File

@@ -0,0 +1,719 @@
export interface TerminalTheme {
name: string;
category: "dark" | "light" | "colorful";
colors: {
background: string;
foreground: string;
cursor?: string;
cursorAccent?: string;
selectionBackground?: string;
selectionForeground?: string;
black: string;
red: string;
green: string;
yellow: string;
blue: string;
magenta: string;
cyan: string;
white: string;
brightBlack: string;
brightRed: string;
brightGreen: string;
brightYellow: string;
brightBlue: string;
brightMagenta: string;
brightCyan: string;
brightWhite: string;
};
}
export const TERMINAL_THEMES: Record<string, TerminalTheme> = {
// Current default theme
termix: {
name: "Termix Default",
category: "dark",
colors: {
background: "#18181b",
foreground: "#f7f7f7",
cursor: "#f7f7f7",
cursorAccent: "#18181b",
selectionBackground: "#3a3a3d",
black: "#2e3436",
red: "#cc0000",
green: "#4e9a06",
yellow: "#c4a000",
blue: "#3465a4",
magenta: "#75507b",
cyan: "#06989a",
white: "#d3d7cf",
brightBlack: "#555753",
brightRed: "#ef2929",
brightGreen: "#8ae234",
brightYellow: "#fce94f",
brightBlue: "#729fcf",
brightMagenta: "#ad7fa8",
brightCyan: "#34e2e2",
brightWhite: "#eeeeec",
},
},
dracula: {
name: "Dracula",
category: "dark",
colors: {
background: "#282a36",
foreground: "#f8f8f2",
cursor: "#f8f8f2",
cursorAccent: "#282a36",
selectionBackground: "#44475a",
black: "#21222c",
red: "#ff5555",
green: "#50fa7b",
yellow: "#f1fa8c",
blue: "#bd93f9",
magenta: "#ff79c6",
cyan: "#8be9fd",
white: "#f8f8f2",
brightBlack: "#6272a4",
brightRed: "#ff6e6e",
brightGreen: "#69ff94",
brightYellow: "#ffffa5",
brightBlue: "#d6acff",
brightMagenta: "#ff92df",
brightCyan: "#a4ffff",
brightWhite: "#ffffff",
},
},
monokai: {
name: "Monokai",
category: "dark",
colors: {
background: "#272822",
foreground: "#f8f8f2",
cursor: "#f8f8f0",
cursorAccent: "#272822",
selectionBackground: "#49483e",
black: "#272822",
red: "#f92672",
green: "#a6e22e",
yellow: "#f4bf75",
blue: "#66d9ef",
magenta: "#ae81ff",
cyan: "#a1efe4",
white: "#f8f8f2",
brightBlack: "#75715e",
brightRed: "#f92672",
brightGreen: "#a6e22e",
brightYellow: "#f4bf75",
brightBlue: "#66d9ef",
brightMagenta: "#ae81ff",
brightCyan: "#a1efe4",
brightWhite: "#f9f8f5",
},
},
nord: {
name: "Nord",
category: "dark",
colors: {
background: "#2e3440",
foreground: "#d8dee9",
cursor: "#d8dee9",
cursorAccent: "#2e3440",
selectionBackground: "#434c5e",
black: "#3b4252",
red: "#bf616a",
green: "#a3be8c",
yellow: "#ebcb8b",
blue: "#81a1c1",
magenta: "#b48ead",
cyan: "#88c0d0",
white: "#e5e9f0",
brightBlack: "#4c566a",
brightRed: "#bf616a",
brightGreen: "#a3be8c",
brightYellow: "#ebcb8b",
brightBlue: "#81a1c1",
brightMagenta: "#b48ead",
brightCyan: "#8fbcbb",
brightWhite: "#eceff4",
},
},
gruvboxDark: {
name: "Gruvbox Dark",
category: "dark",
colors: {
background: "#282828",
foreground: "#ebdbb2",
cursor: "#ebdbb2",
cursorAccent: "#282828",
selectionBackground: "#504945",
black: "#282828",
red: "#cc241d",
green: "#98971a",
yellow: "#d79921",
blue: "#458588",
magenta: "#b16286",
cyan: "#689d6a",
white: "#a89984",
brightBlack: "#928374",
brightRed: "#fb4934",
brightGreen: "#b8bb26",
brightYellow: "#fabd2f",
brightBlue: "#83a598",
brightMagenta: "#d3869b",
brightCyan: "#8ec07c",
brightWhite: "#ebdbb2",
},
},
gruvboxLight: {
name: "Gruvbox Light",
category: "light",
colors: {
background: "#fbf1c7",
foreground: "#3c3836",
cursor: "#3c3836",
cursorAccent: "#fbf1c7",
selectionBackground: "#d5c4a1",
black: "#fbf1c7",
red: "#cc241d",
green: "#98971a",
yellow: "#d79921",
blue: "#458588",
magenta: "#b16286",
cyan: "#689d6a",
white: "#7c6f64",
brightBlack: "#928374",
brightRed: "#9d0006",
brightGreen: "#79740e",
brightYellow: "#b57614",
brightBlue: "#076678",
brightMagenta: "#8f3f71",
brightCyan: "#427b58",
brightWhite: "#3c3836",
},
},
solarizedDark: {
name: "Solarized Dark",
category: "dark",
colors: {
background: "#002b36",
foreground: "#839496",
cursor: "#839496",
cursorAccent: "#002b36",
selectionBackground: "#073642",
black: "#073642",
red: "#dc322f",
green: "#859900",
yellow: "#b58900",
blue: "#268bd2",
magenta: "#d33682",
cyan: "#2aa198",
white: "#eee8d5",
brightBlack: "#002b36",
brightRed: "#cb4b16",
brightGreen: "#586e75",
brightYellow: "#657b83",
brightBlue: "#839496",
brightMagenta: "#6c71c4",
brightCyan: "#93a1a1",
brightWhite: "#fdf6e3",
},
},
solarizedLight: {
name: "Solarized Light",
category: "light",
colors: {
background: "#fdf6e3",
foreground: "#657b83",
cursor: "#657b83",
cursorAccent: "#fdf6e3",
selectionBackground: "#eee8d5",
black: "#073642",
red: "#dc322f",
green: "#859900",
yellow: "#b58900",
blue: "#268bd2",
magenta: "#d33682",
cyan: "#2aa198",
white: "#eee8d5",
brightBlack: "#002b36",
brightRed: "#cb4b16",
brightGreen: "#586e75",
brightYellow: "#657b83",
brightBlue: "#839496",
brightMagenta: "#6c71c4",
brightCyan: "#93a1a1",
brightWhite: "#fdf6e3",
},
},
oneDark: {
name: "One Dark",
category: "dark",
colors: {
background: "#282c34",
foreground: "#abb2bf",
cursor: "#528bff",
cursorAccent: "#282c34",
selectionBackground: "#3e4451",
black: "#282c34",
red: "#e06c75",
green: "#98c379",
yellow: "#e5c07b",
blue: "#61afef",
magenta: "#c678dd",
cyan: "#56b6c2",
white: "#abb2bf",
brightBlack: "#5c6370",
brightRed: "#e06c75",
brightGreen: "#98c379",
brightYellow: "#e5c07b",
brightBlue: "#61afef",
brightMagenta: "#c678dd",
brightCyan: "#56b6c2",
brightWhite: "#ffffff",
},
},
tokyoNight: {
name: "Tokyo Night",
category: "dark",
colors: {
background: "#1a1b26",
foreground: "#a9b1d6",
cursor: "#a9b1d6",
cursorAccent: "#1a1b26",
selectionBackground: "#283457",
black: "#15161e",
red: "#f7768e",
green: "#9ece6a",
yellow: "#e0af68",
blue: "#7aa2f7",
magenta: "#bb9af7",
cyan: "#7dcfff",
white: "#a9b1d6",
brightBlack: "#414868",
brightRed: "#f7768e",
brightGreen: "#9ece6a",
brightYellow: "#e0af68",
brightBlue: "#7aa2f7",
brightMagenta: "#bb9af7",
brightCyan: "#7dcfff",
brightWhite: "#c0caf5",
},
},
ayuDark: {
name: "Ayu Dark",
category: "dark",
colors: {
background: "#0a0e14",
foreground: "#b3b1ad",
cursor: "#e6b450",
cursorAccent: "#0a0e14",
selectionBackground: "#253340",
black: "#01060e",
red: "#ea6c73",
green: "#91b362",
yellow: "#f9af4f",
blue: "#53bdfa",
magenta: "#fae994",
cyan: "#90e1c6",
white: "#c7c7c7",
brightBlack: "#686868",
brightRed: "#f07178",
brightGreen: "#c2d94c",
brightYellow: "#ffb454",
brightBlue: "#59c2ff",
brightMagenta: "#ffee99",
brightCyan: "#95e6cb",
brightWhite: "#ffffff",
},
},
ayuLight: {
name: "Ayu Light",
category: "light",
colors: {
background: "#fafafa",
foreground: "#5c6166",
cursor: "#ff9940",
cursorAccent: "#fafafa",
selectionBackground: "#d1e4f4",
black: "#000000",
red: "#f51818",
green: "#86b300",
yellow: "#f2ae49",
blue: "#399ee6",
magenta: "#a37acc",
cyan: "#4cbf99",
white: "#c7c7c7",
brightBlack: "#686868",
brightRed: "#ff3333",
brightGreen: "#b8e532",
brightYellow: "#ffc849",
brightBlue: "#59c2ff",
brightMagenta: "#bf7ce0",
brightCyan: "#5cf7a0",
brightWhite: "#ffffff",
},
},
materialTheme: {
name: "Material Theme",
category: "dark",
colors: {
background: "#263238",
foreground: "#eeffff",
cursor: "#ffcc00",
cursorAccent: "#263238",
selectionBackground: "#546e7a",
black: "#000000",
red: "#e53935",
green: "#91b859",
yellow: "#ffb62c",
blue: "#6182b8",
magenta: "#7c4dff",
cyan: "#39adb5",
white: "#ffffff",
brightBlack: "#546e7a",
brightRed: "#ff5370",
brightGreen: "#c3e88d",
brightYellow: "#ffcb6b",
brightBlue: "#82aaff",
brightMagenta: "#c792ea",
brightCyan: "#89ddff",
brightWhite: "#ffffff",
},
},
palenight: {
name: "Palenight",
category: "dark",
colors: {
background: "#292d3e",
foreground: "#a6accd",
cursor: "#ffcc00",
cursorAccent: "#292d3e",
selectionBackground: "#676e95",
black: "#292d3e",
red: "#f07178",
green: "#c3e88d",
yellow: "#ffcb6b",
blue: "#82aaff",
magenta: "#c792ea",
cyan: "#89ddff",
white: "#d0d0d0",
brightBlack: "#434758",
brightRed: "#ff8b92",
brightGreen: "#ddffa7",
brightYellow: "#ffe585",
brightBlue: "#9cc4ff",
brightMagenta: "#e1acff",
brightCyan: "#a3f7ff",
brightWhite: "#ffffff",
},
},
oceanicNext: {
name: "Oceanic Next",
category: "dark",
colors: {
background: "#1b2b34",
foreground: "#cdd3de",
cursor: "#c0c5ce",
cursorAccent: "#1b2b34",
selectionBackground: "#343d46",
black: "#343d46",
red: "#ec5f67",
green: "#99c794",
yellow: "#fac863",
blue: "#6699cc",
magenta: "#c594c5",
cyan: "#5fb3b3",
white: "#cdd3de",
brightBlack: "#65737e",
brightRed: "#ec5f67",
brightGreen: "#99c794",
brightYellow: "#fac863",
brightBlue: "#6699cc",
brightMagenta: "#c594c5",
brightCyan: "#5fb3b3",
brightWhite: "#d8dee9",
},
},
nightOwl: {
name: "Night Owl",
category: "dark",
colors: {
background: "#011627",
foreground: "#d6deeb",
cursor: "#80a4c2",
cursorAccent: "#011627",
selectionBackground: "#1d3b53",
black: "#011627",
red: "#ef5350",
green: "#22da6e",
yellow: "#c5e478",
blue: "#82aaff",
magenta: "#c792ea",
cyan: "#21c7a8",
white: "#ffffff",
brightBlack: "#575656",
brightRed: "#ef5350",
brightGreen: "#22da6e",
brightYellow: "#ffeb95",
brightBlue: "#82aaff",
brightMagenta: "#c792ea",
brightCyan: "#7fdbca",
brightWhite: "#ffffff",
},
},
synthwave84: {
name: "Synthwave '84",
category: "colorful",
colors: {
background: "#241b2f",
foreground: "#f92aad",
cursor: "#f92aad",
cursorAccent: "#241b2f",
selectionBackground: "#495495",
black: "#000000",
red: "#f6188f",
green: "#1eff8e",
yellow: "#ffe261",
blue: "#03edf9",
magenta: "#f10596",
cyan: "#03edf9",
white: "#ffffff",
brightBlack: "#5a5a5a",
brightRed: "#ff1a8e",
brightGreen: "#1eff8e",
brightYellow: "#ffff00",
brightBlue: "#00d8ff",
brightMagenta: "#ff00d4",
brightCyan: "#00ffff",
brightWhite: "#ffffff",
},
},
cobalt2: {
name: "Cobalt2",
category: "dark",
colors: {
background: "#193549",
foreground: "#ffffff",
cursor: "#f0cc09",
cursorAccent: "#193549",
selectionBackground: "#0050a4",
black: "#000000",
red: "#ff0000",
green: "#38de21",
yellow: "#ffe50a",
blue: "#1460d2",
magenta: "#ff005d",
cyan: "#00bbbb",
white: "#bbbbbb",
brightBlack: "#555555",
brightRed: "#f40e17",
brightGreen: "#3bd01d",
brightYellow: "#edc809",
brightBlue: "#5555ff",
brightMagenta: "#ff55ff",
brightCyan: "#6ae3fa",
brightWhite: "#ffffff",
},
},
snazzy: {
name: "Snazzy",
category: "dark",
colors: {
background: "#282a36",
foreground: "#eff0eb",
cursor: "#97979b",
cursorAccent: "#282a36",
selectionBackground: "#97979b",
black: "#282a36",
red: "#ff5c57",
green: "#5af78e",
yellow: "#f3f99d",
blue: "#57c7ff",
magenta: "#ff6ac1",
cyan: "#9aedfe",
white: "#f1f1f0",
brightBlack: "#686868",
brightRed: "#ff5c57",
brightGreen: "#5af78e",
brightYellow: "#f3f99d",
brightBlue: "#57c7ff",
brightMagenta: "#ff6ac1",
brightCyan: "#9aedfe",
brightWhite: "#eff0eb",
},
},
atomOneDark: {
name: "Atom One Dark",
category: "dark",
colors: {
background: "#1e2127",
foreground: "#abb2bf",
cursor: "#528bff",
cursorAccent: "#1e2127",
selectionBackground: "#3e4451",
black: "#000000",
red: "#e06c75",
green: "#98c379",
yellow: "#d19a66",
blue: "#61afef",
magenta: "#c678dd",
cyan: "#56b6c2",
white: "#abb2bf",
brightBlack: "#5c6370",
brightRed: "#e06c75",
brightGreen: "#98c379",
brightYellow: "#d19a66",
brightBlue: "#61afef",
brightMagenta: "#c678dd",
brightCyan: "#56b6c2",
brightWhite: "#ffffff",
},
},
catppuccinMocha: {
name: "Catppuccin Mocha",
category: "dark",
colors: {
background: "#1e1e2e",
foreground: "#cdd6f4",
cursor: "#f5e0dc",
cursorAccent: "#1e1e2e",
selectionBackground: "#585b70",
black: "#45475a",
red: "#f38ba8",
green: "#a6e3a1",
yellow: "#f9e2af",
blue: "#89b4fa",
magenta: "#f5c2e7",
cyan: "#94e2d5",
white: "#bac2de",
brightBlack: "#585b70",
brightRed: "#f38ba8",
brightGreen: "#a6e3a1",
brightYellow: "#f9e2af",
brightBlue: "#89b4fa",
brightMagenta: "#f5c2e7",
brightCyan: "#94e2d5",
brightWhite: "#a6adc8",
},
},
};
// Font families available for terminal
export const TERMINAL_FONTS = [
{
value: "Caskaydia Cove Nerd Font Mono",
label: "Caskaydia Cove Nerd Font Mono",
fallback:
'"Caskaydia Cove Nerd Font Mono", "SF Mono", Consolas, "Liberation Mono", monospace',
},
{
value: "JetBrains Mono",
label: "JetBrains Mono",
fallback:
'"JetBrains Mono", "SF Mono", Consolas, "Liberation Mono", monospace',
},
{
value: "Fira Code",
label: "Fira Code",
fallback: '"Fira Code", "SF Mono", Consolas, "Liberation Mono", monospace',
},
{
value: "Cascadia Code",
label: "Cascadia Code",
fallback:
'"Cascadia Code", "SF Mono", Consolas, "Liberation Mono", monospace',
},
{
value: "Source Code Pro",
label: "Source Code Pro",
fallback:
'"Source Code Pro", "SF Mono", Consolas, "Liberation Mono", monospace',
},
{
value: "SF Mono",
label: "SF Mono",
fallback: '"SF Mono", Consolas, "Liberation Mono", monospace',
},
{
value: "Consolas",
label: "Consolas",
fallback: 'Consolas, "Liberation Mono", monospace',
},
{
value: "Monaco",
label: "Monaco",
fallback: 'Monaco, "Liberation Mono", monospace',
},
];
// Cursor styles
export const CURSOR_STYLES = [
{ value: "block", label: "Block" },
{ value: "underline", label: "Underline" },
{ value: "bar", label: "Bar" },
] as const;
// Bell styles
export const BELL_STYLES = [
{ value: "none", label: "None" },
{ value: "sound", label: "Sound" },
{ value: "visual", label: "Visual" },
{ value: "both", label: "Both" },
] as const;
// Fast scroll modifiers
export const FAST_SCROLL_MODIFIERS = [
{ value: "alt", label: "Alt" },
{ value: "ctrl", label: "Ctrl" },
{ value: "shift", label: "Shift" },
] as const;
// Default terminal configuration
export const DEFAULT_TERMINAL_CONFIG = {
// Appearance
cursorBlink: true,
cursorStyle: "bar" as const,
fontSize: 14,
fontFamily: "Caskaydia Cove Nerd Font Mono",
letterSpacing: 0,
lineHeight: 1.2,
theme: "termix",
// Behavior
scrollback: 10000,
bellStyle: "none" as const,
rightClickSelectsWord: false,
fastScrollModifier: "alt" as const,
fastScrollSensitivity: 5,
minimumContrastRatio: 1,
// Advanced
backspaceMode: "normal" as const,
agentForwarding: false,
environmentVariables: [] as Array<{ key: string; value: string }>,
startupSnippetId: null as number | null,
autoMosh: false,
moshCommand: "mosh-server new -s -l LANG=en_US.UTF-8",
};
export type TerminalConfigType = typeof DEFAULT_TERMINAL_CONFIG;

View File

@@ -0,0 +1,102 @@
import type { TerminalTheme } from "@/constants/terminal-themes";
import { TERMINAL_THEMES, TERMINAL_FONTS } from "@/constants/terminal-themes";
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) {
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,
background: TERMINAL_THEMES[theme]?.colors.background || "#18181b",
color: TERMINAL_THEMES[theme]?.colors.foreground || "#f7f7f7",
}}
>
<div>
<span style={{ color: TERMINAL_THEMES[theme]?.colors.green }}>
user@termix
</span>
<span>:</span>
<span style={{ color: TERMINAL_THEMES[theme]?.colors.blue }}>~</span>
<span>$ ls -la</span>
</div>
<div>
<span style={{ color: TERMINAL_THEMES[theme]?.colors.blue }}>
drwxr-xr-x
</span>
<span> 5 user </span>
<span style={{ color: TERMINAL_THEMES[theme]?.colors.cyan }}>
docs
</span>
</div>
<div>
<span style={{ color: TERMINAL_THEMES[theme]?.colors.green }}>
-rwxr-xr-x
</span>
<span> 1 user </span>
<span style={{ color: TERMINAL_THEMES[theme]?.colors.green }}>
script.sh
</span>
</div>
<div>
<span>-rw-r--r--</span>
<span> 1 user </span>
<span>README.md</span>
</div>
<div>
<span style={{ color: TERMINAL_THEMES[theme]?.colors.green }}>
user@termix
</span>
<span>:</span>
<span style={{ color: TERMINAL_THEMES[theme]?.colors.blue }}>~</span>
<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`,
background: TERMINAL_THEMES[theme]?.colors.cursor || "#f7f7f7",
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>
);
}