Files
OpenTerminal/src/shared/theme.ts
T
Bill a9acdbe500 Initial commit: OpenTerminal v0.1.0
Open-source terminal app (local + SSH): split panes, themes, SFTP,
server monitoring, broadcast input, ZMODEM, system tray, single instance.
Electron + React + TypeScript. MIT License.
2026-09-07 16:15:50 +08:00

383 lines
9.0 KiB
TypeScript

/**
* Terminal color theme model. Palette layout mirrors xterm.js ITheme.
* Values of builtin themes come from the public-domain iTerm2-Color-Schemes / xterm-theme collections.
*/
export interface ThemeColors {
background: string
foreground: string
cursor: string
/** accent block behind cursor text; falls back to foreground if omitted */
cursorAccent?: string
selectionBackground: 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 interface TerminalTheme {
id: string
name: string
builtin: boolean
colors: ThemeColors
}
export const DEFAULT_DARK: TerminalTheme = {
id: 'default-dark',
name: 'OpenTerminal Dark',
builtin: true,
colors: {
background: '#1e1e1e',
foreground: '#cccccc',
cursor: '#ffffff',
cursorAccent: '#1e1e1e',
selectionBackground: '#264f78',
black: '#000000',
red: '#cd3131',
green: '#0dbc79',
yellow: '#e5e510',
blue: '#2472c8',
magenta: '#bc3fbc',
cyan: '#11a8cd',
white: '#e5e5e5',
brightBlack: '#666666',
brightRed: '#f14c4c',
brightGreen: '#23d18b',
brightYellow: '#f5f543',
brightBlue: '#3b8eea',
brightMagenta: '#d670d6',
brightCyan: '#29b8db',
brightWhite: '#ffffff'
}
}
export const BUILTIN_THEMES: TerminalTheme[] = [
DEFAULT_DARK,
{
id: 'dracula',
name: 'Dracula',
builtin: true,
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'
}
},
{
id: 'one-half-dark',
name: 'One Half Dark',
builtin: true,
colors: {
background: '#282c34',
foreground: '#dcdfe4',
cursor: '#61afef',
cursorAccent: '#282c34',
selectionBackground: '#3e4451',
black: '#282c34',
red: '#e06c75',
green: '#98c379',
yellow: '#e5c07b',
blue: '#61afef',
magenta: '#c678dd',
cyan: '#56b6c2',
white: '#dcdfe4',
brightBlack: '#5c6370',
brightRed: '#e06c75',
brightGreen: '#98c379',
brightYellow: '#e5c07b',
brightBlue: '#61afef',
brightMagenta: '#c678dd',
brightCyan: '#56b6c2',
brightWhite: '#ffffff'
}
},
{
id: 'one-half-light',
name: 'One Half Light',
builtin: true,
colors: {
background: '#fafafa',
foreground: '#383a42',
cursor: '#383a42',
cursorAccent: '#fafafa',
selectionBackground: '#d2d6db',
black: '#383a42',
red: '#e45649',
green: '#50a14f',
yellow: '#c18401',
blue: '#0184bc',
magenta: '#a626a4',
cyan: '#0997b3',
white: '#fafafa',
brightBlack: '#4f525e',
brightRed: '#e06c75',
brightGreen: '#98c379',
brightYellow: '#e5c07b',
brightBlue: '#61afef',
brightMagenta: '#c678dd',
brightCyan: '#56b6c2',
brightWhite: '#ffffff'
}
},
{
id: 'solarized-dark',
name: 'Solarized Dark',
builtin: true,
colors: {
background: '#002b36',
foreground: '#839496',
cursor: '#93a1a1',
cursorAccent: '#002b36',
selectionBackground: '#073642',
black: '#002b36',
red: '#dc322f',
green: '#859900',
yellow: '#b58900',
blue: '#268bd2',
magenta: '#d33682',
cyan: '#2aa198',
white: '#eee8d5',
brightBlack: '#073642',
brightRed: '#cb4b16',
brightGreen: '#586e75',
brightYellow: '#657b83',
brightBlue: '#839496',
brightMagenta: '#6c71c4',
brightCyan: '#93a1a1',
brightWhite: '#fdf6e3'
}
},
{
id: 'solarized-light',
name: 'Solarized Light',
builtin: true,
colors: {
background: '#fdf6e3',
foreground: '#657b83',
cursor: '#586e75',
cursorAccent: '#fdf6e3',
selectionBackground: '#eee8d5',
black: '#073642',
red: '#dc322f',
green: '#859900',
yellow: '#b58900',
blue: '#268bd2',
magenta: '#d33682',
cyan: '#2aa198',
white: '#eee8d5',
brightBlack: '#93a1a1',
brightRed: '#cb4b16',
brightGreen: '#586e75',
brightYellow: '#657b83',
brightBlue: '#839496',
brightMagenta: '#6c71c4',
brightCyan: '#93a1a1',
brightWhite: '#fdf6e3'
}
},
{
id: 'gruvbox-dark',
name: 'Gruvbox Dark',
builtin: true,
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'
}
},
{
id: 'nord',
name: 'Nord',
builtin: true,
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'
}
},
{
id: 'monokai',
name: 'Monokai',
builtin: true,
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'
}
},
{
id: 'github-light',
name: 'GitHub Light',
builtin: true,
colors: {
background: '#ffffff',
foreground: '#4d4d4c',
cursor: '#4d4d4c',
cursorAccent: '#ffffff',
selectionBackground: '#dcdcdc',
black: '#3e3e3e',
red: '#c91b00',
green: '#00c200',
yellow: '#c7c400',
blue: '#0225c7',
magenta: '#c930c7',
cyan: '#00c5c7',
white: '#c7c7c7',
brightBlack: '#676767',
brightRed: '#ff6d67',
brightGreen: '#5ff967',
brightYellow: '#ffff6c',
brightBlue: '#6871ff',
brightMagenta: '#ff76ff',
brightCyan: '#5ffdff',
brightWhite: '#ffffff'
}
},
{
id: 'afterglow',
name: 'Afterglow',
builtin: true,
colors: {
background: '#1f1f1f',
foreground: '#d0d0d0',
cursor: '#f5f5f5',
cursorAccent: '#1f1f1f',
selectionBackground: '#4a4a4a',
black: '#1f1f1f',
red: '#ac4142',
green: '#7e8e50',
yellow: '#e5b567',
blue: '#6c99bb',
magenta: '#9f4e85',
cyan: '#508451',
white: '#d0d0d0',
brightBlack: '#5a5a5a',
brightRed: '#ac4142',
brightGreen: '#7e8e50',
brightYellow: '#e5b567',
brightBlue: '#6c99bb',
brightMagenta: '#9f4e85',
brightCyan: '#508451',
brightWhite: '#f5f5f5'
}
},
{
id: 'material-dark',
name: 'Material Dark',
builtin: true,
colors: {
background: '#263238',
foreground: '#eeffff',
cursor: '#ffffff',
cursorAccent: '#263238',
selectionBackground: '#2a4153',
black: '#263238',
red: '#f07178',
green: '#c3e88d',
yellow: '#ffcb6b',
blue: '#82aaff',
magenta: '#c792ea',
cyan: '#89ddff',
white: '#eeeeee',
brightBlack: '#546e7a',
brightRed: '#f07178',
brightGreen: '#c3e88d',
brightYellow: '#ffcb6b',
brightBlue: '#82aaff',
brightMagenta: '#c792ea',
brightCyan: '#89ddff',
brightWhite: '#ffffff'
}
}
]
/** Resolve a theme by id; falls back to the default dark theme. */
export function getThemeById(id: string, customThemes: TerminalTheme[] = []): TerminalTheme {
return [...BUILTIN_THEMES, ...customThemes].find((t) => t.id === id) ?? DEFAULT_DARK
}