feat(ui): merge /colors table into /theme dialog and restrict to authors

This commit is contained in:
Keith Guerin
2026-02-26 14:26:20 -08:00
parent c884813df5
commit 067d8982d6
4 changed files with 333 additions and 48 deletions

View File

@@ -51,7 +51,39 @@ describe('ColorsDisplay', () => {
name: 'Test Theme',
type: 'dark',
colors: {} as unknown as ColorsTheme,
semanticColors: {} as unknown as SemanticColors,
semanticColors: {
text: {
primary: '#ffffff',
secondary: '#cccccc',
link: '#0000ff',
accent: '#ff00ff',
response: '#ffffff',
},
background: {
primary: '#000000',
message: '#111111',
input: '#222222',
diff: {
added: '#003300',
removed: '#330000',
},
},
border: {
default: '#555555',
focused: '#0000ff',
},
ui: {
comment: '#666666',
symbol: '#cccccc',
dark: '#333333',
gradient: undefined,
},
status: {
error: '#ff0000',
success: '#00ff00',
warning: '#ffff00',
},
} as unknown as SemanticColors,
} as unknown as Theme);
});
@@ -60,21 +92,16 @@ describe('ColorsDisplay', () => {
});
it('renders correctly', async () => {
const mockTheme = themeManager.getActiveTheme();
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
<ColorsDisplay />,
<ColorsDisplay activeTheme={mockTheme} />,
);
await waitUntilReady();
const output = lastFrame();
// Check for title and description
expect(output).toContain('/colors - Theme Colors Demo');
expect(output).toContain('visualize how colors are used');
expect(output).toContain('How themes and terminals interact');
expect(output).toContain('TrueColor (Hex)');
expect(output).toContain('ANSI Names');
// Check for active theme name
expect(output).toContain('Test Theme');
expect(output).toContain('How themes and terminals interact:');
expect(output).toContain('TrueColor (Hex):');
// Check for some color names and values
expect(output).toContain('text.primary');

View File

@@ -7,8 +7,8 @@
import type React from 'react';
import { Box, Text } from 'ink';
import Gradient from 'ink-gradient';
import { themeManager } from '../themes/theme-manager.js';
import { theme } from '../semantic-colors.js';
import type { Theme } from '../themes/theme.js';
const COLOR_DESCRIPTIONS: Record<string, string> = {
'text.primary': 'Primary text color (uses terminal default if blank)',
@@ -56,9 +56,14 @@ type ColorRow = StandardColorRow | GradientColorRow | BackgroundColorRow;
const VALUE_COLUMN_WIDTH = '10%';
const NAME_COLUMN_WIDTH = '30%';
export const ColorsDisplay: React.FC = () => {
const semanticColors = themeManager.getSemanticColors();
const activeTheme = themeManager.getActiveTheme();
interface ColorsDisplayProps {
activeTheme: Theme;
}
export const ColorsDisplay: React.FC<ColorsDisplayProps> = ({
activeTheme,
}) => {
const semanticColors = activeTheme.semanticColors;
const backgroundRows: BackgroundColorRow[] = [];
const standardRows: StandardColorRow[] = [];
@@ -129,26 +134,17 @@ export const ColorsDisplay: React.FC = () => {
];
return (
<Box flexDirection="column" paddingX={1} marginY={1}>
<Box flexDirection="column" paddingX={0} marginY={1}>
<Box marginBottom={1} flexDirection="column">
<Text bold color={theme.text.accent}>
/colors - Theme Colors Demo
</Text>
<Text color={theme.text.primary}>
The purpose of this feature is to visualize how colors are used in the
app, test across a variety of Terminals (Mac Terminal, Ghostty,
iTerm2, VSCode, etc), and see how the colors change across different
themes.
</Text>
<Box marginTop={1} flexDirection="column">
<Box flexDirection="column">
<Text color={theme.text.primary}>
<Text bold>How themes and terminals interact:</Text>
</Text>
<Box marginLeft={2} flexDirection="column">
<Text color={theme.text.primary}>
<Text bold>TrueColor (Hex):</Text> Modern terminals (iTerm2,
Ghostty, VSCode) render hex codes exactly. They are{' '}
<Text italic>not</Text> overridden by terminal app themes.
<Text bold>TrueColor (Hex):</Text> Modern terminals render hex
codes exactly. They are <Text italic>not</Text> overridden by
terminal app themes.
</Text>
<Text color={theme.text.primary}>
<Text bold>ANSI Names:</Text> Colors like &apos;red&apos; or
@@ -161,21 +157,12 @@ export const ColorsDisplay: React.FC = () => {
foreground/background.
</Text>
<Text color={theme.text.primary}>
<Text bold>Compatibility:</Text> In terminals with limited color
(like older Mac Terminals), hex colors are automatically
approximated to the closest available ANSI color.
<Text bold>Compatibility:</Text> In terminals with limited
color, hex colors are automatically approximated to the closest
available ANSI color.
</Text>
</Box>
</Box>
<Box marginTop={1}>
<Text color={theme.text.primary}>
Active Theme:{' '}
<Text color={theme.text.accent} bold>
{activeTheme.name}
</Text>{' '}
({activeTheme.type})
</Text>
</Box>
</Box>
{/* Header */}

View File

@@ -23,6 +23,8 @@ import { useKeypress } from '../hooks/useKeypress.js';
import { useAlternateBuffer } from '../hooks/useAlternateBuffer.js';
import { ScopeSelector } from './shared/ScopeSelector.js';
import { useUIState } from '../contexts/UIStateContext.js';
import { ColorsDisplay } from './ColorsDisplay.js';
import { isDevelopment } from '../../utils/installationInfo.js';
interface ThemeDialogProps {
/** Callback function when a theme is selected */
@@ -372,6 +374,11 @@ def fibonacci(n):
terminalWidth={colorizeCodeWidth}
theme={previewTheme}
/>
{isDevelopment && (
<Box marginTop={1}>
<ColorsDisplay activeTheme={previewTheme} />
</Box>
)}
</Box>
);
})()}

View File

@@ -16,8 +16,74 @@ exports[`Initial Theme Selection > should default to a dark theme when terminal
│ 9. Solarized Dark │ 1 - print("Hello, " + name) │ │
│ 10. ANSI Light │ 1 + print(f"Hello, {name}!") │ │
│ 11. Ayu Light │ │ │
│ 12. Default Light └─────────────────────────────────────────────────┘
│ ▼
│ 12. Default Light │ │
│ ▼ │ How themes and terminals interact:
│ │ • TrueColor (Hex): Modern terminals render │ │
│ │ hex codes exactly. They are not overridden by │ │
│ │ terminal app themes. │ │
│ │ • ANSI Names: Colors like 'red' or 'green' │ │
│ │ (used in our ANSI theme) are mapped to your │ │
│ │ terminal app's specific palette. │ │
│ │ • Default colors: When Name or Value is │ │
│ │ '(blank)', the app uses your terminal's │ │
│ │ default foreground/background. │ │
│ │ • Compatibility: In terminals with limited │ │
│ │ color, hex colors are automatically │ │
│ │ approximated to the closest available ANSI │ │
│ │ color. │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ ValuName Usage │ │ │
│ │ │ e │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ #… background.pMain terminal background │ │
│ │ rimary color │ │
│ │ … backgroundSubtle background for message │ │
│ │ .message blocks │ │
│ │ #… background.Background for the input │ │
│ │ input prompt │ │
│ │ … backgroundBackground for added lines in │ │
│ │ .diff.addediffs │ │
│ │ d │ │
│ │ … backgroun Background for removed lines │ │
│ │ d.diff.re in diffs │ │
│ │ moved │ │
│ │ (bltext.prim Primary text color (uses │ │
│ │ ankary terminal default if blank) │ │
│ │ ) │ │
│ │ #6C7text.secondar Secondary/dimmed text │ │
│ │ 086 y color │ │
│ │ #89Btext.link Hyperlink and highlighting │ │
│ │ 4FA color │ │
│ │ #CBAtext.accent Accent color for emphasis │ │
│ │ 6F7 │ │
│ │ (bltext.resp Color for model response text │ │
│ │ ankonse (uses terminal default if │ │
│ │ ) blank) │ │
│ │ #3d3border.defaul Standard border color │ │
│ │ f51 t │ │
│ │ #89 border.focBorder color when an element │ │
│ │ B4F used is focused │ │
│ │ A │ │
│ │ #F3status.er Color for error messages and │ │
│ │ 8BAror critical status │ │
│ │ 8 │ │
│ │ #A6 status.sucColor for success messages and │ │
│ │ E3A cess positive status │ │
│ │ 1 │ │
│ │ #F9status.war Color for warnings and │ │
│ │ E2Aning cautionary status │ │
│ │ F │ │
│ │ #479ui.gradien Array of colors used for UI │ │
│ │ E4 t gradients │ │
│ │ #847A │ │
│ │ CE │ │
│ │ #C367 │ │
│ │ 7F │ │
│ │ │ │
│ │ │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ (Use Enter to select, Tab to configure scope, Esc to close) │
│ │
@@ -41,8 +107,74 @@ exports[`Initial Theme Selection > should default to a light theme when terminal
│ 9. Atom One Dark (Incompatible) │ 1 - print("Hello, " + name) │ │
│ 10. Ayu Dark (Incompatible) │ 1 + print(f"Hello, {name}!") │ │
│ 11. Default Dark (Incompatible) │ │ │
│ 12. Dracula Dark (Incompatible) └─────────────────────────────────────────────────┘
│ ▼
│ 12. Dracula Dark (Incompatible) │ │
│ ▼ │ How themes and terminals interact:
│ │ • TrueColor (Hex): Modern terminals render │ │
│ │ hex codes exactly. They are not overridden by │ │
│ │ terminal app themes. │ │
│ │ • ANSI Names: Colors like 'red' or 'green' │ │
│ │ (used in our ANSI theme) are mapped to your │ │
│ │ terminal app's specific palette. │ │
│ │ • Default colors: When Name or Value is │ │
│ │ '(blank)', the app uses your terminal's │ │
│ │ default foreground/background. │ │
│ │ • Compatibility: In terminals with limited │ │
│ │ color, hex colors are automatically │ │
│ │ approximated to the closest available ANSI │ │
│ │ color. │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ ValuName Usage │ │ │
│ │ │ e │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ #… background.pMain terminal background │ │
│ │ rimary color │ │
│ │ … backgroundSubtle background for message │ │
│ │ .message blocks │ │
│ │ #… background.Background for the input │ │
│ │ input prompt │ │
│ │ … backgroundBackground for added lines in │ │
│ │ .diff.addediffs │ │
│ │ d │ │
│ │ … backgroun Background for removed lines │ │
│ │ d.diff.re in diffs │ │
│ │ moved │ │
│ │ (bltext.prim Primary text color (uses │ │
│ │ ankary terminal default if blank) │ │
│ │ ) │ │
│ │ #97atext.secondar Secondary/dimmed text │ │
│ │ 0b0 y color │ │
│ │ #3B8text.link Hyperlink and highlighting │ │
│ │ 2F6 color │ │
│ │ #8B5text.accent Accent color for emphasis │ │
│ │ CF6 │ │
│ │ (bltext.resp Color for model response text │ │
│ │ ankonse (uses terminal default if │ │
│ │ ) blank) │ │
│ │ #d2dborder.defaul Standard border color │ │
│ │ 6dc t │ │
│ │ #3B border.focBorder color when an element │ │
│ │ 82F used is focused │ │
│ │ 6 │ │
│ │ #DDstatus.er Color for error messages and │ │
│ │ 4C4ror critical status │ │
│ │ C │ │
│ │ #3C status.sucColor for success messages and │ │
│ │ A84 cess positive status │ │
│ │ B │ │
│ │ #D5status.war Color for warnings and │ │
│ │ A40ning cautionary status │ │
│ │ A │ │
│ │ #479ui.gradien Array of colors used for UI │ │
│ │ E4 t gradients │ │
│ │ #847A │ │
│ │ CE │ │
│ │ #C367 │ │
│ │ 7F │ │
│ │ │ │
│ │ │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ (Use Enter to select, Tab to configure scope, Esc to close) │
│ │
@@ -66,8 +198,74 @@ exports[`Initial Theme Selection > should use the theme from settings even if te
│ 9. Solarized Dark │ 1 - print("Hello, " + name) │ │
│ 10. ANSI Light │ 1 + print(f"Hello, {name}!") │ │
│ 11. Ayu Light │ │ │
│ 12. Default Light └─────────────────────────────────────────────────┘
│ ▼
│ 12. Default Light │ │
│ ▼ │ How themes and terminals interact:
│ │ • TrueColor (Hex): Modern terminals render │ │
│ │ hex codes exactly. They are not overridden by │ │
│ │ terminal app themes. │ │
│ │ • ANSI Names: Colors like 'red' or 'green' │ │
│ │ (used in our ANSI theme) are mapped to your │ │
│ │ terminal app's specific palette. │ │
│ │ • Default colors: When Name or Value is │ │
│ │ '(blank)', the app uses your terminal's │ │
│ │ default foreground/background. │ │
│ │ • Compatibility: In terminals with limited │ │
│ │ color, hex colors are automatically │ │
│ │ approximated to the closest available ANSI │ │
│ │ color. │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ ValuName Usage │ │ │
│ │ │ e │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ #… background.pMain terminal background │ │
│ │ rimary color │ │
│ │ … backgroundSubtle background for message │ │
│ │ .message blocks │ │
│ │ #… background.Background for the input │ │
│ │ input prompt │ │
│ │ … backgroundBackground for added lines in │ │
│ │ .diff.addediffs │ │
│ │ d │ │
│ │ … backgroun Background for removed lines │ │
│ │ d.diff.re in diffs │ │
│ │ moved │ │
│ │ (bltext.prim Primary text color (uses │ │
│ │ ankary terminal default if blank) │ │
│ │ ) │ │
│ │ #6C7text.secondar Secondary/dimmed text │ │
│ │ 086 y color │ │
│ │ #89Btext.link Hyperlink and highlighting │ │
│ │ 4FA color │ │
│ │ #CBAtext.accent Accent color for emphasis │ │
│ │ 6F7 │ │
│ │ (bltext.resp Color for model response text │ │
│ │ ankonse (uses terminal default if │ │
│ │ ) blank) │ │
│ │ #3d3border.defaul Standard border color │ │
│ │ f51 t │ │
│ │ #89 border.focBorder color when an element │ │
│ │ B4F used is focused │ │
│ │ A │ │
│ │ #F3status.er Color for error messages and │ │
│ │ 8BAror critical status │ │
│ │ 8 │ │
│ │ #A6 status.sucColor for success messages and │ │
│ │ E3A cess positive status │ │
│ │ 1 │ │
│ │ #F9status.war Color for warnings and │ │
│ │ E2Aning cautionary status │ │
│ │ F │ │
│ │ #479ui.gradien Array of colors used for UI │ │
│ │ E4 t gradients │ │
│ │ #847A │ │
│ │ CE │ │
│ │ #C367 │ │
│ │ 7F │ │
│ │ │ │
│ │ │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ (Use Enter to select, Tab to configure scope, Esc to close) │
│ │
@@ -105,8 +303,74 @@ exports[`ThemeDialog Snapshots > should render correctly in theme selection mode
│ 9. Solarized Dark │ 1 - print("Hello, " + name) │ │
│ 10. ANSI Light │ 1 + print(f"Hello, {name}!") │ │
│ 11. Ayu Light │ │ │
│ 12. Default Light └─────────────────────────────────────────────────┘
│ ▼
│ 12. Default Light │ │
│ ▼ │ How themes and terminals interact:
│ │ • TrueColor (Hex): Modern terminals render │ │
│ │ hex codes exactly. They are not overridden by │ │
│ │ terminal app themes. │ │
│ │ • ANSI Names: Colors like 'red' or 'green' │ │
│ │ (used in our ANSI theme) are mapped to your │ │
│ │ terminal app's specific palette. │ │
│ │ • Default colors: When Name or Value is │ │
│ │ '(blank)', the app uses your terminal's │ │
│ │ default foreground/background. │ │
│ │ • Compatibility: In terminals with limited │ │
│ │ color, hex colors are automatically │ │
│ │ approximated to the closest available ANSI │ │
│ │ color. │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ ValuName Usage │ │ │
│ │ │ e │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ #… background.pMain terminal background │ │
│ │ rimary color │ │
│ │ … backgroundSubtle background for message │ │
│ │ .message blocks │ │
│ │ #… background.Background for the input │ │
│ │ input prompt │ │
│ │ … backgroundBackground for added lines in │ │
│ │ .diff.addediffs │ │
│ │ d │ │
│ │ … backgroun Background for removed lines │ │
│ │ d.diff.re in diffs │ │
│ │ moved │ │
│ │ (bltext.prim Primary text color (uses │ │
│ │ ankary terminal default if blank) │ │
│ │ ) │ │
│ │ #6C7text.secondar Secondary/dimmed text │ │
│ │ 086 y color │ │
│ │ #89Btext.link Hyperlink and highlighting │ │
│ │ 4FA color │ │
│ │ #CBAtext.accent Accent color for emphasis │ │
│ │ 6F7 │ │
│ │ (bltext.resp Color for model response text │ │
│ │ ankonse (uses terminal default if │ │
│ │ ) blank) │ │
│ │ #3d3border.defaul Standard border color │ │
│ │ f51 t │ │
│ │ #89 border.focBorder color when an element │ │
│ │ B4F used is focused │ │
│ │ A │ │
│ │ #F3status.er Color for error messages and │ │
│ │ 8BAror critical status │ │
│ │ 8 │ │
│ │ #A6 status.sucColor for success messages and │ │
│ │ E3A cess positive status │ │
│ │ 1 │ │
│ │ #F9status.war Color for warnings and │ │
│ │ E2Aning cautionary status │ │
│ │ F │ │
│ │ #479ui.gradien Array of colors used for UI │ │
│ │ E4 t gradients │ │
│ │ #847A │ │
│ │ CE │ │
│ │ #C367 │ │
│ │ 7F │ │
│ │ │ │
│ │ │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ (Use Enter to select, Tab to configure scope, Esc to close) │
│ │