mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-21 02:24:09 -07:00
refactor(ui): Update and simplify use of gray colors in themes (#20141)
This commit is contained in:
@@ -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',
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user