From 3013a0acb5e47b129b0fe391b6f859b693ae1f07 Mon Sep 17 00:00:00 2001 From: Dan Zaharia Date: Wed, 4 Mar 2026 11:27:00 -0500 Subject: [PATCH] fix(cli): ensure both light and dark themes are saved in the theme dialog --- .../cli/src/ui/components/ThemeDialog.tsx | 37 +++++++++++++++---- packages/cli/src/ui/hooks/useThemeCommand.ts | 21 +++++++++++ 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/packages/cli/src/ui/components/ThemeDialog.tsx b/packages/cli/src/ui/components/ThemeDialog.tsx index d9fd4a4e56..72b43bae71 100644 --- a/packages/cli/src/ui/components/ThemeDialog.tsx +++ b/packages/cli/src/ui/components/ThemeDialog.tsx @@ -31,6 +31,8 @@ interface ThemeDialogProps { onSelect: ( themeName: string, scope: LoadableSettingScope, + themeMode?: 'light' | 'dark', + otherThemeName?: string, ) => void | Promise; /** Callback function when the dialog is cancelled */ @@ -44,7 +46,10 @@ interface ThemeDialogProps { terminalWidth: number; } -import { resolveColor , getThemeTypeFromBackgroundColor } from '../themes/color-utils.js'; +import { + resolveColor, + getThemeTypeFromBackgroundColor, +} from '../themes/color-utils.js'; import { DefaultLight } from '../themes/default-light.js'; import { DefaultDark } from '../themes/default.js'; @@ -137,10 +142,19 @@ export function ThemeDialog({ const handleThemeSelect = useCallback( async (themeName: string) => { - // @ts-expect-error adding extra argument for the updated hook - await onSelect(themeName, selectedScope, activeTab); + const otherThemeName = + activeTab === 'light' + ? highlightedThemeNameDark + : highlightedThemeNameLight; + await onSelect(themeName, selectedScope, activeTab, otherThemeName); }, - [onSelect, selectedScope, activeTab], + [ + onSelect, + selectedScope, + activeTab, + highlightedThemeNameDark, + highlightedThemeNameLight, + ], ); const handleThemeHighlight = (themeName: string) => { @@ -158,10 +172,19 @@ export function ThemeDialog({ const handleScopeSelect = useCallback( async (scope: LoadableSettingScope) => { - // @ts-expect-error adding extra argument - await onSelect(highlightedThemeName, scope, activeTab); + const otherThemeName = + activeTab === 'light' + ? highlightedThemeNameDark + : highlightedThemeNameLight; + await onSelect(highlightedThemeName, scope, activeTab, otherThemeName); }, - [onSelect, highlightedThemeName, activeTab], + [ + onSelect, + highlightedThemeName, + activeTab, + highlightedThemeNameDark, + highlightedThemeNameLight, + ], ); const [mode, setMode] = useState<'theme' | 'scope'>('theme'); diff --git a/packages/cli/src/ui/hooks/useThemeCommand.ts b/packages/cli/src/ui/hooks/useThemeCommand.ts index ce9684e7de..a03fe948e5 100644 --- a/packages/cli/src/ui/hooks/useThemeCommand.ts +++ b/packages/cli/src/ui/hooks/useThemeCommand.ts @@ -26,6 +26,7 @@ interface UseThemeCommandReturn { themeName: string, scope: LoadableSettingScope, themeMode?: 'light' | 'dark', + otherThemeName?: string, ) => Promise; handleThemeHighlight: (themeName: string | undefined) => void; } @@ -99,6 +100,7 @@ export const useThemeCommand = ( themeName: string, scope: LoadableSettingScope, themeMode?: 'light' | 'dark', + otherThemeName?: string, ) => { try { const mergedCustomThemes = { @@ -114,10 +116,29 @@ export const useThemeCommand = ( return; } + if (otherThemeName) { + const isBuiltInOther = themeManager.findThemeByName(otherThemeName); + const isCustomOther = + otherThemeName && mergedCustomThemes[otherThemeName]; + if (!isBuiltInOther && !isCustomOther) { + setThemeError( + `Theme "${otherThemeName}" not found in selected scope.`, + ); + setIsThemeDialogOpen(true); + return; + } + } + if (themeMode === 'light') { loadedSettings.setValue(scope, 'ui.themeLight', themeName); + if (otherThemeName) { + loadedSettings.setValue(scope, 'ui.themeDark', otherThemeName); + } } else if (themeMode === 'dark') { loadedSettings.setValue(scope, 'ui.themeDark', themeName); + if (otherThemeName) { + loadedSettings.setValue(scope, 'ui.themeLight', otherThemeName); + } } else { loadedSettings.setValue(scope, 'ui.themeLight', themeName); loadedSettings.setValue(scope, 'ui.themeDark', themeName);