feat(KB-070): add Ayu and One Dark themes to dashboard

- Add Ayu and One Dark to COLOR_THEMES and validThemes arrays
- Add CSS theme variables for both themes in styles.css
- Update ThemeSelector UI to include new theme options
- Extend Theme type to include ayu and one-dark values
- Update tests for ThemeSelector and useTheme hooks
- Add changeset for minor version bump
This commit is contained in:
gsxdsm
2026-03-29 23:26:16 -07:00
parent 99bfd4fb8f
commit 36cd94dbd5
7 changed files with 99 additions and 2 deletions

View File

@@ -24,6 +24,8 @@ const COLOR_THEMES: { value: ColorTheme; label: string; className: string }[] =
{ value: "monochrome", label: "Mono", className: "theme-swatch-monochrome" },
{ value: "high-contrast", label: "High Contrast", className: "theme-swatch-high-contrast" },
{ value: "solarized", label: "Solarized", className: "theme-swatch-solarized" },
{ value: "ayu", label: "Ayu", className: "theme-swatch-ayu" },
{ value: "one-dark", label: "One Dark", className: "theme-swatch-one-dark" },
];
/**

View File

@@ -84,6 +84,8 @@ describe("ThemeSelector", () => {
expect(screen.getByLabelText("Mono theme")).toBeDefined();
expect(screen.getByLabelText("High Contrast theme")).toBeDefined();
expect(screen.getByLabelText("Solarized theme")).toBeDefined();
expect(screen.getByLabelText("Ayu theme")).toBeDefined();
expect(screen.getByLabelText("One Dark theme")).toBeDefined();
});
it("marks current color theme as active", () => {
@@ -245,7 +247,7 @@ describe("ThemeSelector", () => {
const themeOptions = screen.getAllByRole("button").filter(
(btn) => btn.className.includes("theme-option")
);
expect(themeOptions.length).toBe(8);
expect(themeOptions.length).toBe(10);
themeOptions.forEach((btn) => {
const swatch = btn.querySelector(".theme-option-swatch");

View File

@@ -182,7 +182,7 @@ describe("useTheme", () => {
it("supports all valid color themes", () => {
const { result } = renderHook(() => useTheme());
const themes = ["default", "ocean", "forest", "sunset", "berry", "monochrome", "high-contrast", "solarized"];
const themes = ["default", "ocean", "forest", "sunset", "berry", "monochrome", "high-contrast", "solarized", "ayu", "one-dark"];
themes.forEach((theme) => {
act(() => result.current.setColorTheme(theme as typeof themes[number]));

View File

@@ -72,6 +72,8 @@ export function useTheme(): UseThemeReturn {
"monochrome",
"high-contrast",
"solarized",
"ayu",
"one-dark",
];
if (saved && validThemes.includes(saved as ColorTheme)) {
return saved as ColorTheme;

View File

@@ -4282,6 +4282,71 @@ html .column.drag-over * {
--color-error: #dc322f;
}
/* AYU - Popular code editor theme with dark and light variants */
[data-color-theme="ayu"] {
--bg: #0f1419;
--surface: #131d27;
--card: #1a2634;
--card-hover: #232d3b;
--border: #304357;
--text: #bfbdb6;
--text-muted: #565b66;
--text-dim: #4d5666;
--todo: #39bae6;
--in-progress: #ffb454;
--in-progress-rgb: 255, 180, 84;
--in-review: #7ee787;
--triage: #f2966b;
--done: #6c7986;
--color-success: #7ee787;
--color-error: #f07178;
--shadow: 0 4px 24px rgba(0, 0, 0, 0.5);
}
[data-color-theme="ayu"][data-theme="light"] {
--bg: #fafafa;
--surface: #f3f3f3;
--card: #ffffff;
--card-hover: #f0f0f0;
--border: #e0e0e0;
--text: #5c6166;
--text-muted: #8a9199;
--text-dim: #a0a0a0;
--todo: #007acc;
--in-progress: #ff8f40;
--in-progress-rgb: 255, 143, 64;
--in-review: #86b300;
--triage: #fa8d3e;
--done: #8a9199;
--color-success: #86b300;
--color-error: #f07178;
--shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
}
/* ONE DARK - Atom's iconic dark theme */
[data-color-theme="one-dark"] {
--bg: #282c34;
--surface: #21252b;
--card: #2c313a;
--card-hover: #353b45;
--border: #3e4451;
--text: #abb2bf;
--text-muted: #636d83;
--text-dim: #5c6370;
--todo: #61afef;
--in-progress: #c678dd;
--in-progress-rgb: 198, 120, 221;
--in-review: #98c379;
--triage: #e5c07b;
--done: #828997;
--color-success: #98c379;
--color-error: #e06c75;
--shadow: 0 4px 24px rgba(0, 0, 0, 0.5);
}
/* ============================================================
THEME SELECTOR COMPONENT STYLES
============================================================ */
@@ -4441,6 +4506,22 @@ html .column.drag-over * {
--surface: #073642;
}
.theme-swatch-ayu {
--bg: #0f1419;
--surface: #131d27;
}
.theme-swatch-one-dark {
--bg: #282c34;
--surface: #21252b;
}
/* Light mode swatch overrides */
[data-theme="light"] .theme-swatch-ayu {
--bg: #fafafa;
--surface: #f3f3f3;
}
/* Reset to defaults button */
.theme-reset-btn {
display: flex;