Open-source terminal app (local + SSH): split panes, themes, SFTP, server monitoring, broadcast input, ZMODEM, system tray, single instance. Electron + React + TypeScript. MIT License.
383 lines
9.0 KiB
TypeScript
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
|
|
}
|