feat(FN-1214): add ember color theme
- Add ember theme to COLOR_THEMES array in types.ts - Add ember theme CSS variables in styles.css - Add ember theme swatch preview in ThemeSelector component - Add ember to validThemes validation in index.html - Add ThemeSelector tests for ember theme
This commit is contained in:
@@ -54,6 +54,7 @@ export const COLOR_THEMES = [
|
||||
"espresso",
|
||||
"mars",
|
||||
"poimandres",
|
||||
"ember",
|
||||
] as const;
|
||||
export type ColorTheme = (typeof COLOR_THEMES)[number];
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ const COLOR_THEMES: { value: ColorTheme; label: string; className: string }[] =
|
||||
{ value: "espresso", label: "Espresso", className: "theme-swatch-espresso" },
|
||||
{ value: "mars", label: "Mars", className: "theme-swatch-mars" },
|
||||
{ value: "poimandres", label: "Poimandres", className: "theme-swatch-poimandres" },
|
||||
{ value: "ember", label: "Ember", className: "theme-swatch-ember" },
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -115,6 +115,7 @@ describe("ThemeSelector", () => {
|
||||
expect(screen.getByLabelText("Espresso theme")).toBeDefined();
|
||||
expect(screen.getByLabelText("Mars theme")).toBeDefined();
|
||||
expect(screen.getByLabelText("Poimandres theme")).toBeDefined();
|
||||
expect(screen.getByLabelText("Ember theme")).toBeDefined();
|
||||
});
|
||||
|
||||
it("marks current color theme as active", () => {
|
||||
@@ -226,6 +227,9 @@ describe("ThemeSelector", () => {
|
||||
|
||||
fireEvent.click(screen.getByLabelText("Silver theme"));
|
||||
expect(onColorThemeChange).toHaveBeenCalledWith("silver");
|
||||
|
||||
fireEvent.click(screen.getByLabelText("Ember theme"));
|
||||
expect(onColorThemeChange).toHaveBeenCalledWith("ember");
|
||||
});
|
||||
|
||||
it("displays Nord in preview when selected", () => {
|
||||
@@ -397,6 +401,19 @@ describe("ThemeSelector", () => {
|
||||
expect(screen.getByText(/Dark \/ Silver/)).toBeDefined();
|
||||
});
|
||||
|
||||
it("displays Ember in preview when selected", () => {
|
||||
render(
|
||||
<ThemeSelector
|
||||
themeMode="dark"
|
||||
colorTheme="ember"
|
||||
onThemeModeChange={vi.fn()}
|
||||
onColorThemeChange={vi.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(screen.getByText(/Dark \/ Ember/)).toBeDefined();
|
||||
});
|
||||
|
||||
it("displays dramatic theme names in preview when selected", () => {
|
||||
const { rerender } = render(
|
||||
<ThemeSelector
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
try {
|
||||
var mode = localStorage.getItem('kb-dashboard-theme-mode') || 'dark';
|
||||
var colorTheme = localStorage.getItem('kb-dashboard-color-theme') || 'default';
|
||||
var validThemes = ['default', 'ocean', 'forest', 'sunset', 'zen', 'berry', 'high-contrast', 'industrial', 'monochrome', 'slate', 'ash', 'graphite', 'silver', 'solarized', 'factory', 'ayu', 'one-dark', 'nord', 'dracula', 'gruvbox', 'tokyo-night', 'catppuccin-mocha', 'github-dark', 'everforest', 'rose-pine', 'kanagawa', 'night-owl', 'palenight', 'monokai-pro', 'slime', 'brutalist', 'neon-city', 'parchment', 'terminal', 'glass', 'horizon', 'vitesse', 'outrun', 'snazzy', 'porple', 'espresso', 'mars', 'poimandres'];
|
||||
var validThemes = ['default', 'ocean', 'forest', 'sunset', 'zen', 'berry', 'high-contrast', 'industrial', 'monochrome', 'slate', 'ash', 'graphite', 'silver', 'solarized', 'factory', 'ayu', 'one-dark', 'nord', 'dracula', 'gruvbox', 'tokyo-night', 'catppuccin-mocha', 'github-dark', 'everforest', 'rose-pine', 'kanagawa', 'night-owl', 'palenight', 'monokai-pro', 'slime', 'brutalist', 'neon-city', 'parchment', 'terminal', 'glass', 'horizon', 'vitesse', 'outrun', 'snazzy', 'porple', 'espresso', 'mars', 'poimandres', 'ember'];
|
||||
if (!validThemes.includes(colorTheme)) {
|
||||
colorTheme = 'default';
|
||||
}
|
||||
|
||||
@@ -9896,6 +9896,47 @@ html .column.drag-over * {
|
||||
--accent: #606060;
|
||||
}
|
||||
|
||||
/* EMBER - Dark graphite with orange accent */
|
||||
[data-color-theme="ember"] {
|
||||
--todo: #a0a0a0;
|
||||
--in-progress: #b8b8b8;
|
||||
--in-progress-rgb: 184, 184, 184;
|
||||
--in-review: #d0d0d0;
|
||||
--triage: #808080;
|
||||
--done: #686868;
|
||||
--color-success: #d0d0d0;
|
||||
--color-error: #ff6b6b;
|
||||
--cta-bg: #d4622a;
|
||||
--cta-border: #e8773a;
|
||||
--cta-text: #fff;
|
||||
--cta-bg-hover: #e8773a;
|
||||
--cta-border-hover: #f09050;
|
||||
--cta-glow: 0 0 8px rgba(232, 119, 58, 0.3);
|
||||
--logo-accent: #e8773a;
|
||||
--color-info: #e8773a;
|
||||
--accent: #e8773a;
|
||||
}
|
||||
|
||||
[data-color-theme="ember"][data-theme="light"] {
|
||||
--todo: #404040;
|
||||
--in-progress: #606060;
|
||||
--in-progress-rgb: 96, 96, 96;
|
||||
--in-review: #606060;
|
||||
--triage: #2a2a2a;
|
||||
--done: #606060;
|
||||
--color-success: #404040;
|
||||
--color-error: #dc2626;
|
||||
--cta-bg: #c05820;
|
||||
--cta-border: #d4622a;
|
||||
--cta-text: #fff;
|
||||
--cta-bg-hover: #d4622a;
|
||||
--cta-border-hover: #e07030;
|
||||
--cta-glow: 0 0 8px rgba(192, 88, 32, 0.3);
|
||||
--logo-accent: #d4622a;
|
||||
--color-info: #c05820;
|
||||
--accent: #d4622a;
|
||||
}
|
||||
|
||||
/* SILVER - Light silvery grays */
|
||||
[data-color-theme="silver"] {
|
||||
--todo: #b0b0b0;
|
||||
@@ -12836,6 +12877,11 @@ body[data-color-theme="terminal"][data-theme="light"]::before {
|
||||
--surface: #27272a;
|
||||
}
|
||||
|
||||
.theme-swatch-ember {
|
||||
--bg: #18181b;
|
||||
--surface: #27272a;
|
||||
}
|
||||
|
||||
.theme-swatch-silver {
|
||||
--bg: #27272a;
|
||||
--surface: #3f3f46;
|
||||
@@ -13127,6 +13173,11 @@ body[data-color-theme="terminal"][data-theme="light"]::before {
|
||||
--surface: #f4f4f5;
|
||||
}
|
||||
|
||||
[data-theme="light"] .theme-swatch-ember {
|
||||
--bg: #fafafa;
|
||||
--surface: #f4f4f5;
|
||||
}
|
||||
|
||||
[data-theme="light"] .theme-swatch-silver {
|
||||
--bg: #fafafa;
|
||||
--surface: #f4f4f5;
|
||||
|
||||
Reference in New Issue
Block a user