fix(theme): 浅色主题 ANSI 调色板重做到 WCAG AA + MCR/bold 动态开关 + antd 算法随亮度切换;github-light 底色柔化 #f6f8fa

This commit is contained in:
Bill committed 2026-10-16 20:23:33 +08:00
1 parent 2136221f2c
commit 79bea68c13
6 files changed
+114 -57

No files matched your search

+2 -2
View File
@@ -56,7 +56,7 @@ class ErrorBoundaryClass extends Component<ErrorBoundaryClassProps, ErrorBoundar
alignItems: 'center',
justifyContent: 'center',
gap: 12,
color: '#cccccc'
color: 'var(--ot-text, #cccccc)'
}}
>
<div>{tFor(this.props.language, 'workspace.error.title')}</div>
@@ -66,7 +66,7 @@ class ErrorBoundaryClass extends Component<ErrorBoundaryClassProps, ErrorBoundar
maxHeight: 240,
overflow: 'auto',
whiteSpace: 'pre-wrap',
color: '#ff6b6b',
color: 'var(--ot-danger-fg, #ff6b6b)',
fontSize: 12
}}
>
+6 -3
View File
@@ -10,6 +10,7 @@ import { ErrorBoundary } from './ErrorBoundary'
import ZmodemOffers from './workspace/ZmodemOffers'
import { useSettingsStore } from './settings/store'
import { mix } from './theme/chrome'
import { isLightTheme } from './theme/semantic'
import './global.css'
// Diagnostics: report renderer main-thread freezes after recovery. console.error
@@ -221,14 +222,16 @@ function ThemedConfigProvider({ children }: { children: ReactNode }): React.JSX.
const themeId = useSettingsStore((s) => s.settings.terminal.themeId)
const customThemes = useSettingsStore((s) => s.settings.customThemes)
const colors = getThemeById(themeId, customThemes).colors
const light = isLightTheme(colors.background)
return (
<ConfigProvider
theme={{
algorithm: antdTheme.darkAlgorithm,
// antd has no lightAlgorithm — light is the default algorithm.
algorithm: light ? antdTheme.defaultAlgorithm : antdTheme.darkAlgorithm,
token: {
colorBgBase: colors.background,
colorBgContainer: mix(colors.background, colors.foreground, 0.06) ?? '#1f1f1f',
colorBgElevated: mix(colors.background, colors.foreground, 0.1) ?? '#252525',
colorBgContainer: mix(colors.background, colors.foreground, 0.06) ?? (light ? '#f5f5f5' : '#1f1f1f'),
colorBgElevated: mix(colors.background, colors.foreground, 0.1) ?? (light ? '#f5f5f5' : '#252525'),
colorTextBase: colors.foreground,
borderRadius: 6
}
+17 -9
View File
@@ -9,6 +9,7 @@ import { ClearOutlined, CopyOutlined, ExportOutlined, FolderOpenOutlined, PauseO
import { Checkbox, Modal } from 'antd'
import { DEFAULT_LANGUAGE, tFor, type Language } from '@shared/i18n'
import { getThemeById } from '@shared/theme'
import { isLightTheme } from '@renderer/theme/semantic'
import type { CommandItem } from '@shared/commands'
import { highlightModeOf, type TerminalSettings } from '@shared/settings'
import { rulesForProfile } from '@shared/highlightProfiles'
@@ -846,6 +847,8 @@ export function TerminalView({
// ---- terminal instance: built once per session ----
useLayoutEffect(() => {
const themeColors = getThemeById(themeOpts.themeId, themeOpts.customThemes).colors
const lightTheme = isLightTheme(themeColors.background)
const term = new Terminal({
fontSize: fontOpts.fontSize,
fontFamily: fontOpts.fontFamily,
@@ -857,16 +860,21 @@ export function TerminalView({
cursorBlink: fontOpts.cursorBlink,
cursorStyle: fontOpts.cursorStyle,
cursorInactiveStyle: fontOpts.cursorInactiveStyle,
theme: withChromeColors(getThemeById(themeOpts.themeId, themeOpts.customThemes).colors as ITheme, bgOpts.image !== ''),
theme: withChromeColors(themeColors as ITheme, bgOpts.image !== ''),
allowProposedApi: true,
allowTransparency: true,
overviewRuler: { width: 9, showTopBorder: false, showBottomBorder: false },
drawBoldTextInBrightColors: true,
// Light themes ship WCAG-compliant palettes, but apps still emit
// dark-tuned bright/bold colors; bold must NOT jump to the bright set.
drawBoldTextInBrightColors: !lightTheme,
// In image mode the xterm background is transparent (#00000000), which
// xterm's contrast cache treats as black; a raised contrast floor lifts
// dark foreground colors (light themes) enough to stay readable over
// the wallpaper. Without an image keep 1 (off) to honor theme colors.
minimumContrastRatio: bgOpts.image ? 4.5 : 1,
// the wallpaper. Without an image light themes keep the 4.5 floor to
// rescue low-contrast app output; dark themes keep 1 (off) to honor
// theme colors. (Spelled minimumContrastRatio — minContrastRatio is
// silently ignored.)
minimumContrastRatio: bgOpts.image || lightTheme ? 4.5 : 1,
automaticFontFallback: true,
convertEol: false,
windowsPty: { backend: 'conpty', buildNumber: 0 }
@@ -1261,11 +1269,11 @@ export function TerminalView({
useEffect(() => {
const term = termRef.current
if (!term) return
term.options.theme = withChromeColors(
getThemeById(themeOpts.themeId, themeOpts.customThemes).colors as ITheme,
bgOpts.image !== ''
)
term.options.minimumContrastRatio = bgOpts.image ? 4.5 : 1
const colors = getThemeById(themeOpts.themeId, themeOpts.customThemes).colors
const lightTheme = isLightTheme(colors.background)
term.options.theme = withChromeColors(colors as ITheme, bgOpts.image !== '')
term.options.drawBoldTextInBrightColors = !lightTheme
term.options.minimumContrastRatio = bgOpts.image || lightTheme ? 4.5 : 1
}, [themeOpts, bgOpts])
// ---- renderer mode changes: keep the instance, swap renderer, refit ----
+42 -42
View File
@@ -133,21 +133,21 @@ export const BUILTIN_THEMES: TerminalTheme[] = [
cursorAccent: '#fafafa',
selectionBackground: '#d2d6db',
black: '#383a42',
red: '#e45649',
green: '#50a14f',
yellow: '#c18401',
blue: '#0184bc',
red: '#c2493e',
green: '#40813f',
yellow: '#9a6a01',
blue: '#0177a9',
magenta: '#a626a4',
cyan: '#0997b3',
white: '#fafafa',
cyan: '#07798f',
white: '#717171',
brightBlack: '#4f525e',
brightRed: '#e06c75',
brightGreen: '#98c379',
brightYellow: '#e5c07b',
brightBlue: '#61afef',
brightMagenta: '#c678dd',
brightCyan: '#56b6c2',
brightWhite: '#ffffff'
brightRed: '#b3565e',
brightGreen: '#5b7549',
brightYellow: '#7e6a44',
brightBlue: '#3f729b',
brightMagenta: '#955aa6',
brightCyan: '#38767e',
brightWhite: '#737373'
}
},
{
@@ -184,26 +184,26 @@ export const BUILTIN_THEMES: TerminalTheme[] = [
builtin: true,
colors: {
background: '#fdf6e3',
foreground: '#657b83',
foreground: '#586e75',
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',
red: '#d1302d',
green: '#647300',
yellow: '#886700',
blue: '#2076b3',
magenta: '#c8337c',
cyan: '#207972',
white: '#6b6860',
brightBlack: '#677171',
brightRed: '#c14715',
brightGreen: '#586e75',
brightYellow: '#657b83',
brightBlue: '#839496',
brightMagenta: '#6c71c4',
brightCyan: '#93a1a1',
brightWhite: '#fdf6e3'
brightYellow: '#5b6f76',
brightBlue: '#626f71',
brightMagenta: '#6166b0',
brightCyan: '#677171',
brightWhite: '#726f66'
}
},
{
@@ -295,27 +295,27 @@ export const BUILTIN_THEMES: TerminalTheme[] = [
name: 'GitHub Light',
builtin: true,
colors: {
background: '#ffffff',
background: '#f6f8fa',
foreground: '#4d4d4c',
cursor: '#4d4d4c',
cursorAccent: '#ffffff',
cursorAccent: '#f6f8fa',
selectionBackground: '#dcdcdc',
black: '#3e3e3e',
red: '#c91b00',
green: '#00c200',
yellow: '#c7c400',
green: '#007e00',
yellow: '#777600',
blue: '#0225c7',
magenta: '#c930c7',
cyan: '#00c5c7',
white: '#c7c7c7',
magenta: '#bf2ebd',
cyan: '#007677',
white: '#6d6d6d',
brightBlack: '#676767',
brightRed: '#ff6d67',
brightGreen: '#5ff967',
brightYellow: '#ffff6c',
brightBlue: '#6871ff',
brightMagenta: '#ff76ff',
brightCyan: '#5ffdff',
brightWhite: '#ffffff'
brightRed: '#b34c48',
brightGreen: '#307d34',
brightYellow: '#737331',
brightBlue: '#5860d9',
brightMagenta: '#a64da6',
brightCyan: '#2b7273',
brightWhite: '#666666'
}
},
{