fix: remove dead code and fix isDark property reference on ThemeColors
This commit is contained in:
parent
9ec6bce9c9
commit
3d54df27b4
361
src/lib/theme.ts
Normal file
361
src/lib/theme.ts
Normal file
@ -0,0 +1,361 @@
|
||||
/**
|
||||
* Theme system — dynamic CSS variable manager
|
||||
* Each theme maps to a full set of CSS custom properties.
|
||||
*/
|
||||
|
||||
export interface ThemeColors {
|
||||
background: string;
|
||||
foreground: string;
|
||||
card: string;
|
||||
cardForeground: string;
|
||||
popover: string;
|
||||
popoverForeground: string;
|
||||
primary: string;
|
||||
primaryForeground: string;
|
||||
secondary: string;
|
||||
secondaryForeground: string;
|
||||
muted: string;
|
||||
mutedForeground: string;
|
||||
accent: string;
|
||||
accentForeground: string;
|
||||
destructive: string;
|
||||
border: string;
|
||||
input: string;
|
||||
ring: string;
|
||||
sidebar: string;
|
||||
sidebarForeground: string;
|
||||
sidebarPrimary: string;
|
||||
sidebarPrimaryForeground: string;
|
||||
sidebarAccent: string;
|
||||
sidebarAccentForeground: string;
|
||||
sidebarBorder: string;
|
||||
sidebarRing: string;
|
||||
}
|
||||
|
||||
export interface ThemePreset {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
colors: ThemeColors;
|
||||
radius: string;
|
||||
isDark: boolean;
|
||||
}
|
||||
|
||||
export const themePresets: ThemePreset[] = [
|
||||
{
|
||||
id: "pure-white",
|
||||
name: "Pure White",
|
||||
description: "Minimal white with crisp blacks and subtle borders",
|
||||
isDark: false,
|
||||
radius: "0.875rem",
|
||||
colors: {
|
||||
background: "#ffffff",
|
||||
foreground: "#111111",
|
||||
card: "#ffffff",
|
||||
cardForeground: "#111111",
|
||||
popover: "#ffffff",
|
||||
popoverForeground: "#111111",
|
||||
primary: "#111111",
|
||||
primaryForeground: "#ffffff",
|
||||
secondary: "#f5f5f5",
|
||||
secondaryForeground: "#111111",
|
||||
muted: "#f5f5f5",
|
||||
mutedForeground: "#737373",
|
||||
accent: "#f5f5f5",
|
||||
accentForeground: "#111111",
|
||||
destructive: "#ef4444",
|
||||
border: "#e8e8e8",
|
||||
input: "#e8e8e8",
|
||||
ring: "#111111",
|
||||
sidebar: "#fafafa",
|
||||
sidebarForeground: "#111111",
|
||||
sidebarPrimary: "#111111",
|
||||
sidebarPrimaryForeground: "#ffffff",
|
||||
sidebarAccent: "#f5f5f5",
|
||||
sidebarAccentForeground: "#111111",
|
||||
sidebarBorder: "#e8e8e8",
|
||||
sidebarRing: "#111111",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "soft-gray",
|
||||
name: "Soft Gray",
|
||||
description: "Warm gray tones with gentle contrast",
|
||||
isDark: false,
|
||||
radius: "0.875rem",
|
||||
colors: {
|
||||
background: "#f8f8f7",
|
||||
foreground: "#1c1c1c",
|
||||
card: "#ffffff",
|
||||
cardForeground: "#1c1c1c",
|
||||
popover: "#ffffff",
|
||||
popoverForeground: "#1c1c1c",
|
||||
primary: "#1c1c1c",
|
||||
primaryForeground: "#ffffff",
|
||||
secondary: "#eeedec",
|
||||
secondaryForeground: "#1c1c1c",
|
||||
muted: "#eeedec",
|
||||
mutedForeground: "#6e6d6c",
|
||||
accent: "#eeedec",
|
||||
accentForeground: "#1c1c1c",
|
||||
destructive: "#ef4444",
|
||||
border: "#e4e3e2",
|
||||
input: "#e4e3e2",
|
||||
ring: "#1c1c1c",
|
||||
sidebar: "#f3f2f1",
|
||||
sidebarForeground: "#1c1c1c",
|
||||
sidebarPrimary: "#1c1c1c",
|
||||
sidebarPrimaryForeground: "#ffffff",
|
||||
sidebarAccent: "#eeedec",
|
||||
sidebarAccentForeground: "#1c1c1c",
|
||||
sidebarBorder: "#e4e3e2",
|
||||
sidebarRing: "#1c1c1c",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "cool-slate",
|
||||
name: "Cool Slate",
|
||||
description: "Icy blue-gray palette inspired by modern dashboards",
|
||||
isDark: false,
|
||||
radius: "0.875rem",
|
||||
colors: {
|
||||
background: "#f6f7f9",
|
||||
foreground: "#1a1d23",
|
||||
card: "#ffffff",
|
||||
cardForeground: "#1a1d23",
|
||||
popover: "#ffffff",
|
||||
popoverForeground: "#1a1d23",
|
||||
primary: "#3b5bdb",
|
||||
primaryForeground: "#ffffff",
|
||||
secondary: "#e9ecf1",
|
||||
secondaryForeground: "#1a1d23",
|
||||
muted: "#e9ecf1",
|
||||
mutedForeground: "#5c6370",
|
||||
accent: "#e9ecf1",
|
||||
accentForeground: "#1a1d23",
|
||||
destructive: "#ef4444",
|
||||
border: "#dde0e6",
|
||||
input: "#dde0e6",
|
||||
ring: "#3b5bdb",
|
||||
sidebar: "#f0f1f4",
|
||||
sidebarForeground: "#1a1d23",
|
||||
sidebarPrimary: "#3b5bdb",
|
||||
sidebarPrimaryForeground: "#ffffff",
|
||||
sidebarAccent: "#e9ecf1",
|
||||
sidebarAccentForeground: "#1a1d23",
|
||||
sidebarBorder: "#dde0e6",
|
||||
sidebarRing: "#3b5bdb",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "warm-cream",
|
||||
name: "Warm Cream",
|
||||
description: "Cozy off-white with warm amber undertones",
|
||||
isDark: false,
|
||||
radius: "0.875rem",
|
||||
colors: {
|
||||
background: "#fdfbf7",
|
||||
foreground: "#1c1917",
|
||||
card: "#ffffff",
|
||||
cardForeground: "#1c1917",
|
||||
popover: "#ffffff",
|
||||
popoverForeground: "#1c1917",
|
||||
primary: "#b45309",
|
||||
primaryForeground: "#ffffff",
|
||||
secondary: "#f5f0e8",
|
||||
secondaryForeground: "#1c1917",
|
||||
muted: "#f5f0e8",
|
||||
mutedForeground: "#78716c",
|
||||
accent: "#f5f0e8",
|
||||
accentForeground: "#1c1917",
|
||||
destructive: "#ef4444",
|
||||
border: "#e7e0d5",
|
||||
input: "#e7e0d5",
|
||||
ring: "#b45309",
|
||||
sidebar: "#f8f5f0",
|
||||
sidebarForeground: "#1c1917",
|
||||
sidebarPrimary: "#b45309",
|
||||
sidebarPrimaryForeground: "#ffffff",
|
||||
sidebarAccent: "#f5f0e8",
|
||||
sidebarAccentForeground: "#1c1917",
|
||||
sidebarBorder: "#e7e0d5",
|
||||
sidebarRing: "#b45309",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "forest",
|
||||
name: "Forest",
|
||||
description: "Nature-inspired green tones for calm focus",
|
||||
isDark: false,
|
||||
radius: "0.875rem",
|
||||
colors: {
|
||||
background: "#f6f7f4",
|
||||
foreground: "#1a1c18",
|
||||
card: "#ffffff",
|
||||
cardForeground: "#1a1c18",
|
||||
popover: "#ffffff",
|
||||
popoverForeground: "#1a1c18",
|
||||
primary: "#15803d",
|
||||
primaryForeground: "#ffffff",
|
||||
secondary: "#e8ebe4",
|
||||
secondaryForeground: "#1a1c18",
|
||||
muted: "#e8ebe4",
|
||||
mutedForeground: "#5f6358",
|
||||
accent: "#e8ebe4",
|
||||
accentForeground: "#1a1c18",
|
||||
destructive: "#ef4444",
|
||||
border: "#dde1d8",
|
||||
input: "#dde1d8",
|
||||
ring: "#15803d",
|
||||
sidebar: "#eff1ec",
|
||||
sidebarForeground: "#1a1c18",
|
||||
sidebarPrimary: "#15803d",
|
||||
sidebarPrimaryForeground: "#ffffff",
|
||||
sidebarAccent: "#e8ebe4",
|
||||
sidebarAccentForeground: "#1a1c18",
|
||||
sidebarBorder: "#dde1d8",
|
||||
sidebarRing: "#15803d",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "dark",
|
||||
name: "Dark",
|
||||
description: "Clean dark mode with balanced contrast",
|
||||
isDark: true,
|
||||
radius: "0.875rem",
|
||||
colors: {
|
||||
background: "#0f1115",
|
||||
foreground: "#ececf1",
|
||||
card: "#16181d",
|
||||
cardForeground: "#ececf1",
|
||||
popover: "#16181d",
|
||||
popoverForeground: "#ececf1",
|
||||
primary: "#5E6AD2",
|
||||
primaryForeground: "#ffffff",
|
||||
secondary: "#1f2128",
|
||||
secondaryForeground: "#ececf1",
|
||||
muted: "#1f2128",
|
||||
mutedForeground: "#8a8f98",
|
||||
accent: "#1f2128",
|
||||
accentForeground: "#ececf1",
|
||||
destructive: "#ef4444",
|
||||
border: "rgba(255,255,255,0.08)",
|
||||
input: "rgba(255,255,255,0.08)",
|
||||
ring: "#5E6AD2",
|
||||
sidebar: "#0f1115",
|
||||
sidebarForeground: "#ececf1",
|
||||
sidebarPrimary: "#5E6AD2",
|
||||
sidebarPrimaryForeground: "#ffffff",
|
||||
sidebarAccent: "#1f2128",
|
||||
sidebarAccentForeground: "#ececf1",
|
||||
sidebarBorder: "rgba(255,255,255,0.08)",
|
||||
sidebarRing: "#5E6AD2",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "midnight",
|
||||
name: "Midnight",
|
||||
description: "Deep navy dark theme for late-night sessions",
|
||||
isDark: true,
|
||||
radius: "0.875rem",
|
||||
colors: {
|
||||
background: "#0a0e1a",
|
||||
foreground: "#d8dce8",
|
||||
card: "#111827",
|
||||
cardForeground: "#d8dce8",
|
||||
popover: "#111827",
|
||||
popoverForeground: "#d8dce8",
|
||||
primary: "#60a5fa",
|
||||
primaryForeground: "#0a0e1a",
|
||||
secondary: "#1e293b",
|
||||
secondaryForeground: "#d8dce8",
|
||||
muted: "#1e293b",
|
||||
mutedForeground: "#7a8299",
|
||||
accent: "#1e293b",
|
||||
accentForeground: "#d8dce8",
|
||||
destructive: "#f87171",
|
||||
border: "rgba(255,255,255,0.07)",
|
||||
input: "rgba(255,255,255,0.07)",
|
||||
ring: "#60a5fa",
|
||||
sidebar: "#0d1220",
|
||||
sidebarForeground: "#d8dce8",
|
||||
sidebarPrimary: "#60a5fa",
|
||||
sidebarPrimaryForeground: "#0a0e1a",
|
||||
sidebarAccent: "#1e293b",
|
||||
sidebarAccentForeground: "#d8dce8",
|
||||
sidebarBorder: "rgba(255,255,255,0.07)",
|
||||
sidebarRing: "#60a5fa",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const defaultThemeId = "pure-white";
|
||||
|
||||
const STORAGE_KEY = "gitdataai-theme";
|
||||
|
||||
export function getSavedThemeId(): string {
|
||||
try {
|
||||
return localStorage.getItem(STORAGE_KEY) || defaultThemeId;
|
||||
} catch {
|
||||
return defaultThemeId;
|
||||
}
|
||||
}
|
||||
|
||||
export function saveThemeId(id: string) {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, id);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
|
||||
export function applyTheme(preset: ThemePreset) {
|
||||
const root = document.documentElement;
|
||||
const c = preset.colors;
|
||||
|
||||
root.style.setProperty("--background", c.background);
|
||||
root.style.setProperty("--foreground", c.foreground);
|
||||
root.style.setProperty("--card", c.card);
|
||||
root.style.setProperty("--card-foreground", c.cardForeground);
|
||||
root.style.setProperty("--popover", c.popover);
|
||||
root.style.setProperty("--popover-foreground", c.popoverForeground);
|
||||
root.style.setProperty("--primary", c.primary);
|
||||
root.style.setProperty("--primary-foreground", c.primaryForeground);
|
||||
root.style.setProperty("--secondary", c.secondary);
|
||||
root.style.setProperty("--secondary-foreground", c.secondaryForeground);
|
||||
root.style.setProperty("--muted", c.muted);
|
||||
root.style.setProperty("--muted-foreground", c.mutedForeground);
|
||||
root.style.setProperty("--accent", c.accent);
|
||||
root.style.setProperty("--accent-foreground", c.accentForeground);
|
||||
root.style.setProperty("--destructive", c.destructive);
|
||||
root.style.setProperty("--border", c.border);
|
||||
root.style.setProperty("--input", c.input);
|
||||
root.style.setProperty("--ring", c.ring);
|
||||
root.style.setProperty("--radius", preset.radius);
|
||||
root.style.setProperty("--sidebar", c.sidebar);
|
||||
root.style.setProperty("--sidebar-foreground", c.sidebarForeground);
|
||||
root.style.setProperty("--sidebar-primary", c.sidebarPrimary);
|
||||
root.style.setProperty("--sidebar-primary-foreground", c.sidebarPrimaryForeground);
|
||||
root.style.setProperty("--sidebar-accent", c.sidebarAccent);
|
||||
root.style.setProperty("--sidebar-accent-foreground", c.sidebarAccentForeground);
|
||||
root.style.setProperty("--sidebar-border", c.sidebarBorder);
|
||||
root.style.setProperty("--sidebar-ring", c.sidebarRing);
|
||||
|
||||
// Chart colors — derive from primary/muted
|
||||
root.style.setProperty("--chart-1", c.primary);
|
||||
root.style.setProperty("--chart-2", c.mutedForeground);
|
||||
root.style.setProperty("--chart-3", preset.isDark ? "#8a8f98" : "#4b5563");
|
||||
root.style.setProperty("--chart-4", preset.isDark ? "#6e7681" : "#374151");
|
||||
root.style.setProperty("--chart-5", preset.isDark ? "#4b5563" : "#1f2937");
|
||||
|
||||
// Toggle dark class for any tailwind dark: variants still in use
|
||||
if (preset.isDark) {
|
||||
root.classList.add("dark");
|
||||
} else {
|
||||
root.classList.remove("dark");
|
||||
}
|
||||
}
|
||||
|
||||
export function getThemeById(id: string): ThemePreset | undefined {
|
||||
return themePresets.find((t) => t.id === id);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user