feat: Detect background color (#15132)

This commit is contained in:
Jacob Richman
2025-12-18 10:36:48 -08:00
committed by GitHub
parent 54466a3ea8
commit 322232e514
28 changed files with 1031 additions and 359 deletions

View File

@@ -6,7 +6,11 @@
import type { CSSProperties } from 'react';
import type { SemanticColors } from './semantic-tokens.js';
import { resolveColor, interpolateColor } from './color-utils.js';
import {
resolveColor,
interpolateColor,
getThemeTypeFromBackgroundColor,
} from './color-utils.js';
export type ThemeType = 'light' | 'dark' | 'ansi' | 'custom';
@@ -499,3 +503,40 @@ function isValidThemeName(name: string): boolean {
// Theme name should be non-empty and not contain invalid characters
return name.trim().length > 0 && name.trim().length <= 50;
}
/**
* Picks a default theme name based on terminal background color.
* It first tries to find a theme with an exact background color match.
* If no match is found, it falls back to a light or dark theme based on the
* luminance of the background color.
* @param terminalBackground The hex color string of the terminal background.
* @param availableThemes A list of available themes to search through.
* @param defaultDarkThemeName The name of the fallback dark theme.
* @param defaultLightThemeName The name of the fallback light theme.
* @returns The name of the chosen theme.
*/
export function pickDefaultThemeName(
terminalBackground: string | undefined,
availableThemes: readonly Theme[],
defaultDarkThemeName: string,
defaultLightThemeName: string,
): string {
if (terminalBackground) {
const lowerTerminalBackground = terminalBackground.toLowerCase();
for (const theme of availableThemes) {
if (!theme.colors.Background) continue;
// resolveColor can return undefined
const themeBg = resolveColor(theme.colors.Background)?.toLowerCase();
if (themeBg === lowerTerminalBackground) {
return theme.name;
}
}
}
const themeType = getThemeTypeFromBackgroundColor(terminalBackground);
if (themeType === 'light') {
return defaultLightThemeName;
}
return defaultDarkThemeName;
}