🐛 fix(query-editor): 统一主题背景与结果区布局

让 Monaco、SQL 工具栏、数据网格和嵌入日志统一使用当前主题的工作台表面色,并兼容自定义主题覆盖。

统一结果 Tab 的高度、圆角与间距,移除嵌入日志重复标题,将清空日志和隐藏结果区操作并排放到 Tab 栏右侧。

补充主题、工具栏、结果 Tab 和日志面板回归测试。
This commit is contained in:
Syngnat
2026-07-30 17:49:58 +08:00
parent 84569e409c
commit ffd1be8ad6
12 changed files with 188 additions and 74 deletions

View File

@@ -51,11 +51,18 @@ describe('custom theme CSS validation', () => {
);
});
it('injects --gn-monaco-bg for hand-written themes that only set panel', () => {
it('injects --gn-monaco-bg for hand-written themes that only set theme surfaces', () => {
const css = 'body[data-custom-theme] {\n --gn-bg-panel: #f7faf8;\n --gn-bg-panel-2: #eef3f0;\n}';
const next = ensureCustomThemeMonacoSurfaceVars(css);
expect(next).toContain('--gn-monaco-bg: var(--gn-bg-panel-2)');
expect(next).toContain('--gn-bg-panel: #f7faf8');
});
it('keeps legacy hand-written themes aligned when they only define panel', () => {
const css = 'body[data-custom-theme] {\n --gn-bg-panel: #f7faf8;\n}';
const next = ensureCustomThemeMonacoSurfaceVars(css);
expect(next).toContain('--gn-monaco-bg: var(--gn-bg-panel)');
expect(next).toContain('--gn-bg-panel: #f7faf8');
});
it('does not override an explicit --gn-monaco-bg in custom theme CSS', () => {

View File

@@ -220,19 +220,20 @@ export const createCustomThemeId = (): string => {
/**
* Ensure Monaco surface token exists for hand-written custom themes.
* Presets already define it; user CSS that only sets --gn-bg-panel still needs this.
* Presets already define it; hand-written CSS still needs the shared theme surface default.
* If the theme already declares --gn-monaco-bg, leave it alone (user override wins).
*/
export const ensureCustomThemeMonacoSurfaceVars = (css: string): string => {
const source = String(css || '');
if (/--gn-monaco-bg\s*:/.test(source)) return source;
const surfaceVar = /--gn-bg-panel-2\s*:/.test(source) ? '--gn-bg-panel-2' : '--gn-bg-panel';
const trimmed = source.trimEnd();
const appendix = [
'',
'/* GoNavi: Monaco surface follows panel unless the theme overrides --gn-monaco-bg */',
`/* GoNavi: Monaco surface follows ${surfaceVar} unless the theme overrides --gn-monaco-bg */`,
'body[data-custom-theme],',
'body[data-custom-theme][data-ui-version="v2"] {',
' --gn-monaco-bg: var(--gn-bg-panel);',
` --gn-monaco-bg: var(${surfaceVar});`,
'}',
'',
].join('\n');
@@ -396,7 +397,7 @@ body[data-custom-theme][data-ui-version="v2"] {
--gn-bg-chrome: #171a23;
--gn-bg-panel: #1d202b;
--gn-bg-panel-2: #232733;
--gn-monaco-bg: var(--gn-bg-panel);
--gn-monaco-bg: var(--gn-bg-panel-2);
--gn-bg-hover: rgba(255, 255, 255, 0.06);
--gn-bg-active: rgba(255, 255, 255, 0.10);
--gn-bg-selected: rgba(139, 92, 246, 0.18);

View File

@@ -48,11 +48,15 @@ describe('built-in custom theme presets', () => {
expect(sanitizeCustomThemeDefinition(preset)).toEqual(expect.objectContaining({ id: preset.id }));
expect(preset.css).toContain('--gn-ant-primary:');
expect(preset.css).toContain('--gn-ant-on-primary:');
expect(preset.css).toContain('--gn-monaco-bg: var(--gn-bg-panel-2);');
expect(preset.css).toContain('--gn-settings-card-bg:');
expect(preset.css).toContain('--gn-explain-critical:');
expect(preset.css).toContain('--gn-status-connected:');
expect(preset.css).toContain('.gn-v2-tab-label-part-host');
expect(preset.css).toContain('.gn-v2-tab-label-part-database');
expect(preset.css).toContain(
'background-color: var(--gn-monaco-bg, var(--gn-bg-panel-2)) !important;',
);
}
expect(BUILTIN_CUSTOM_THEME_PRESETS.filter((preset) => preset.baseMode === 'dark')).toHaveLength(4);
expect(BUILTIN_CUSTOM_THEME_PRESETS.filter((preset) => preset.baseMode === 'light')).toHaveLength(2);
@@ -70,6 +74,7 @@ describe('built-in custom theme presets', () => {
expect(comfortDark.css).toContain('.gn-v2-query-toolbar-save-action');
expect(comfortDark.css).toContain('.gn-v2-ai-panel .ai-logo');
expect(comfortDark.css).toContain('.monaco-editor-background');
expect(comfortDark.css).not.toContain('background-color: var(--gn-bg-input) !important;');
});
it('keeps preset text and solid-button colors at WCAG AA contrast', () => {

View File

@@ -254,7 +254,7 @@ body[data-custom-theme][data-ui-version="v2"] {
--gn-bg-chrome: ${palette.chrome};
--gn-bg-panel: ${palette.panel};
--gn-bg-panel-2: ${palette.panel2};
--gn-monaco-bg: var(--gn-bg-panel);
--gn-monaco-bg: var(--gn-bg-panel-2);
--gn-bg-input: ${palette.input};
--gn-bg-subtle: ${palette.panel2};
--gn-bg-hover: ${palette.hover};
@@ -455,7 +455,7 @@ body[data-custom-theme][data-ui-version="v2"] .monaco-editor,
body[data-custom-theme][data-ui-version="v2"] .monaco-editor-background,
body[data-custom-theme][data-ui-version="v2"] .monaco-editor .margin,
body[data-custom-theme][data-ui-version="v2"] .monaco-editor .sticky-widget {
background-color: var(--gn-bg-input) !important;
background-color: var(--gn-monaco-bg, var(--gn-bg-panel-2)) !important;
}`;
const createPreset = (