refactor(ui): Update and simplify use of gray colors in themes (#20141)

This commit is contained in:
Keith Guerin
2026-02-24 01:21:10 -08:00
committed by GitHub
parent e69e23e4a0
commit d143a83d5b
13 changed files with 124 additions and 58 deletions
+4
View File
@@ -24,6 +24,8 @@ const noColorColorsTheme: ColorsTheme = {
Comment: '',
Gray: '',
DarkGray: '',
InputBackground: '',
MessageBackground: '',
};
const noColorSemanticColors: SemanticColors = {
@@ -36,6 +38,8 @@ const noColorSemanticColors: SemanticColors = {
},
background: {
primary: '',
message: '',
input: '',
diff: {
added: '',
removed: '',
@@ -16,6 +16,8 @@ export interface SemanticColors {
};
background: {
primary: string;
message: string;
input: string;
diff: {
added: string;
removed: string;
@@ -48,13 +50,15 @@ export const lightSemanticColors: SemanticColors = {
},
background: {
primary: lightTheme.Background,
message: lightTheme.MessageBackground!,
input: lightTheme.InputBackground!,
diff: {
added: lightTheme.DiffAdded,
removed: lightTheme.DiffRemoved,
},
},
border: {
default: lightTheme.Gray,
default: lightTheme.DarkGray,
focused: lightTheme.AccentBlue,
},
ui: {
@@ -80,13 +84,15 @@ export const darkSemanticColors: SemanticColors = {
},
background: {
primary: darkTheme.Background,
message: darkTheme.MessageBackground!,
input: darkTheme.InputBackground!,
diff: {
added: darkTheme.DiffAdded,
removed: darkTheme.DiffRemoved,
},
},
border: {
default: darkTheme.Gray,
default: darkTheme.DarkGray,
focused: darkTheme.AccentBlue,
},
ui: {
@@ -36,6 +36,8 @@ const semanticColors: SemanticColors = {
},
background: {
primary: '#002b36',
message: '#073642',
input: '#073642',
diff: {
added: '#00382f',
removed: '#3d0115',
@@ -36,6 +36,8 @@ const semanticColors: SemanticColors = {
},
background: {
primary: '#fdf6e3',
message: '#eee8d5',
input: '#eee8d5',
diff: {
added: '#d7f2d7',
removed: '#f2d7d7',
+25 -12
View File
@@ -29,7 +29,11 @@ import {
getThemeTypeFromBackgroundColor,
resolveColor,
} from './color-utils.js';
import { DEFAULT_BORDER_OPACITY } from '../constants.js';
import {
DEFAULT_BACKGROUND_OPACITY,
DEFAULT_INPUT_BACKGROUND_OPACITY,
DEFAULT_BORDER_OPACITY,
} from '../constants.js';
import { ANSI } from './ansi.js';
import { ANSILight } from './ansi-light.js';
import { NoColorTheme } from './no-color.js';
@@ -310,7 +314,21 @@ class ThemeManager {
this.cachedColors = {
...colors,
Background: this.terminalBackground,
DarkGray: interpolateColor(colors.Gray, this.terminalBackground, 0.5),
DarkGray: interpolateColor(
this.terminalBackground,
colors.Gray,
DEFAULT_BORDER_OPACITY,
),
InputBackground: interpolateColor(
this.terminalBackground,
colors.Gray,
DEFAULT_INPUT_BACKGROUND_OPACITY,
),
MessageBackground: interpolateColor(
this.terminalBackground,
colors.Gray,
DEFAULT_BACKGROUND_OPACITY,
),
};
} else {
this.cachedColors = colors;
@@ -336,27 +354,22 @@ class ThemeManager {
this.terminalBackground &&
this.isThemeCompatible(activeTheme, this.terminalBackground)
) {
const colors = this.getColors();
this.cachedSemanticColors = {
...semanticColors,
background: {
...semanticColors.background,
primary: this.terminalBackground,
message: colors.MessageBackground!,
input: colors.InputBackground!,
},
border: {
...semanticColors.border,
default: interpolateColor(
this.terminalBackground,
activeTheme.colors.Gray,
DEFAULT_BORDER_OPACITY,
),
default: colors.DarkGray,
},
ui: {
...semanticColors.ui,
dark: interpolateColor(
activeTheme.colors.Gray,
this.terminalBackground,
0.5,
),
dark: colors.DarkGray,
},
};
} else {
+7 -7
View File
@@ -37,11 +37,11 @@ describe('createCustomTheme', () => {
it('should interpolate DarkGray when not provided', () => {
const theme = createCustomTheme(baseTheme);
// Interpolate between Gray (#cccccc) and Background (#000000) at 0.5
// Interpolate between Background (#000000) and Gray (#cccccc) at 0.4
// #cccccc is RGB(204, 204, 204)
// #000000 is RGB(0, 0, 0)
// Midpoint is RGB(102, 102, 102) which is #666666
expect(theme.colors.DarkGray).toBe('#666666');
// Result is RGB(82, 82, 82) which is #525252
expect(theme.colors.DarkGray).toBe('#525252');
});
it('should use provided DarkGray', () => {
@@ -64,8 +64,8 @@ describe('createCustomTheme', () => {
},
};
const theme = createCustomTheme(customTheme);
// Should be interpolated between #cccccc and #000000 at 0.5 -> #666666
expect(theme.colors.DarkGray).toBe('#666666');
// Should be interpolated between #000000 and #cccccc at 0.4 -> #525252
expect(theme.colors.DarkGray).toBe('#525252');
});
it('should prefer text.secondary over Gray for interpolation', () => {
@@ -81,8 +81,8 @@ describe('createCustomTheme', () => {
},
};
const theme = createCustomTheme(customTheme);
// Interpolate between #cccccc and #000000 -> #666666
expect(theme.colors.DarkGray).toBe('#666666');
// Interpolate between #000000 and #cccccc -> #525252
expect(theme.colors.DarkGray).toBe('#525252');
});
});
+61 -17
View File
@@ -15,7 +15,11 @@ import {
} from './color-utils.js';
import type { CustomTheme } from '@google/gemini-cli-core';
import { DEFAULT_BORDER_OPACITY } from '../constants.js';
import {
DEFAULT_BACKGROUND_OPACITY,
DEFAULT_INPUT_BACKGROUND_OPACITY,
DEFAULT_BORDER_OPACITY,
} from '../constants.js';
export type { CustomTheme };
@@ -37,6 +41,8 @@ export interface ColorsTheme {
Comment: string;
Gray: string;
DarkGray: string;
InputBackground?: string;
MessageBackground?: string;
GradientColors?: string[];
}
@@ -55,7 +61,17 @@ export const lightTheme: ColorsTheme = {
DiffRemoved: '#FFCCCC',
Comment: '#008000',
Gray: '#97a0b0',
DarkGray: interpolateColor('#97a0b0', '#FAFAFA', 0.5),
DarkGray: interpolateColor('#FAFAFA', '#97a0b0', DEFAULT_BORDER_OPACITY),
InputBackground: interpolateColor(
'#FAFAFA',
'#97a0b0',
DEFAULT_INPUT_BACKGROUND_OPACITY,
),
MessageBackground: interpolateColor(
'#FAFAFA',
'#97a0b0',
DEFAULT_BACKGROUND_OPACITY,
),
GradientColors: ['#4796E4', '#847ACE', '#C3677F'],
};
@@ -74,7 +90,17 @@ export const darkTheme: ColorsTheme = {
DiffRemoved: '#430000',
Comment: '#6C7086',
Gray: '#6C7086',
DarkGray: interpolateColor('#6C7086', '#1E1E2E', 0.5),
DarkGray: interpolateColor('#1E1E2E', '#6C7086', DEFAULT_BORDER_OPACITY),
InputBackground: interpolateColor(
'#1E1E2E',
'#6C7086',
DEFAULT_INPUT_BACKGROUND_OPACITY,
),
MessageBackground: interpolateColor(
'#1E1E2E',
'#6C7086',
DEFAULT_BACKGROUND_OPACITY,
),
GradientColors: ['#4796E4', '#847ACE', '#C3677F'],
};
@@ -94,6 +120,8 @@ export const ansiTheme: ColorsTheme = {
Comment: 'gray',
Gray: 'gray',
DarkGray: 'gray',
InputBackground: 'black',
MessageBackground: 'black',
};
export class Theme {
@@ -131,17 +159,27 @@ export class Theme {
},
background: {
primary: this.colors.Background,
message:
this.colors.MessageBackground ??
interpolateColor(
this.colors.Background,
this.colors.Gray,
DEFAULT_BACKGROUND_OPACITY,
),
input:
this.colors.InputBackground ??
interpolateColor(
this.colors.Background,
this.colors.Gray,
DEFAULT_INPUT_BACKGROUND_OPACITY,
),
diff: {
added: this.colors.DiffAdded,
removed: this.colors.DiffRemoved,
},
},
border: {
default: interpolateColor(
this.colors.Background,
this.colors.Gray,
DEFAULT_BORDER_OPACITY,
),
default: this.colors.DarkGray,
focused: this.colors.AccentBlue,
},
ui: {
@@ -242,10 +280,20 @@ export function createCustomTheme(customTheme: CustomTheme): Theme {
DarkGray:
customTheme.DarkGray ??
interpolateColor(
customTheme.text?.secondary ?? customTheme.Gray ?? '',
customTheme.background?.primary ?? customTheme.Background ?? '',
0.5,
customTheme.text?.secondary ?? customTheme.Gray ?? '',
DEFAULT_BORDER_OPACITY,
),
InputBackground: interpolateColor(
customTheme.background?.primary ?? customTheme.Background ?? '',
customTheme.text?.secondary ?? customTheme.Gray ?? '',
DEFAULT_INPUT_BACKGROUND_OPACITY,
),
MessageBackground: interpolateColor(
customTheme.background?.primary ?? customTheme.Background ?? '',
customTheme.text?.secondary ?? customTheme.Gray ?? '',
DEFAULT_BACKGROUND_OPACITY,
),
GradientColors: customTheme.ui?.gradient ?? customTheme.GradientColors,
};
@@ -400,19 +448,15 @@ export function createCustomTheme(customTheme: CustomTheme): Theme {
},
background: {
primary: customTheme.background?.primary ?? colors.Background,
message: colors.MessageBackground!,
input: colors.InputBackground!,
diff: {
added: customTheme.background?.diff?.added ?? colors.DiffAdded,
removed: customTheme.background?.diff?.removed ?? colors.DiffRemoved,
},
},
border: {
default:
customTheme.border?.default ??
interpolateColor(
colors.Background,
colors.Gray,
DEFAULT_BORDER_OPACITY,
),
default: colors.DarkGray,
focused: customTheme.border?.focused ?? colors.AccentBlue,
},
ui: {