mirror of
https://codeberg.org/likwid/likwid.git
synced 2026-06-25 15:37:42 +00:00
288 lines
8.7 KiB
TypeScript
288 lines
8.7 KiB
TypeScript
|
|
export interface Theme {
|
||
|
|
id: string;
|
||
|
|
name: string;
|
||
|
|
description: string;
|
||
|
|
author: string;
|
||
|
|
isDark: boolean;
|
||
|
|
colors: {
|
||
|
|
bg: string;
|
||
|
|
bgAlt: string;
|
||
|
|
surface: string;
|
||
|
|
surfaceHover: string;
|
||
|
|
border: string;
|
||
|
|
borderHover: string;
|
||
|
|
text: string;
|
||
|
|
textMuted: string;
|
||
|
|
textInverse: string;
|
||
|
|
primary: string;
|
||
|
|
primaryHover: string;
|
||
|
|
primaryMuted: string;
|
||
|
|
secondary: string;
|
||
|
|
secondaryHover: string;
|
||
|
|
info: string;
|
||
|
|
infoHover: string;
|
||
|
|
infoMuted: string;
|
||
|
|
neutral: string;
|
||
|
|
neutralHover: string;
|
||
|
|
neutralMuted: string;
|
||
|
|
success: string;
|
||
|
|
successMuted: string;
|
||
|
|
successHover: string;
|
||
|
|
warning: string;
|
||
|
|
warningMuted: string;
|
||
|
|
error: string;
|
||
|
|
errorMuted: string;
|
||
|
|
errorHover: string;
|
||
|
|
link: string;
|
||
|
|
linkVisited: string;
|
||
|
|
overlay: string;
|
||
|
|
fieldBg: string;
|
||
|
|
onPrimary: string;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export const themes: Record<string, Theme> = {
|
||
|
|
neutral: {
|
||
|
|
id: 'neutral',
|
||
|
|
name: 'Neutral Dark',
|
||
|
|
description: 'Default dark theme with neutral colors',
|
||
|
|
author: 'Likwid',
|
||
|
|
isDark: true,
|
||
|
|
colors: {
|
||
|
|
bg: '#0f0f0f',
|
||
|
|
bgAlt: '#141414',
|
||
|
|
surface: '#1a1a1a',
|
||
|
|
surfaceHover: '#222222',
|
||
|
|
border: '#2a2a2a',
|
||
|
|
borderHover: '#3a3a3a',
|
||
|
|
text: '#e0e0e0',
|
||
|
|
textMuted: '#888888',
|
||
|
|
textInverse: '#0f0f0f',
|
||
|
|
primary: '#6366f1',
|
||
|
|
primaryHover: '#4f46e5',
|
||
|
|
primaryMuted: 'rgba(99, 102, 241, 0.15)',
|
||
|
|
secondary: '#8b5cf6',
|
||
|
|
secondaryHover: '#7c3aed',
|
||
|
|
info: '#3b82f6',
|
||
|
|
infoHover: '#2563eb',
|
||
|
|
infoMuted: 'rgba(59, 130, 246, 0.15)',
|
||
|
|
neutral: '#6b7280',
|
||
|
|
neutralHover: '#4b5563',
|
||
|
|
neutralMuted: 'rgba(107, 114, 128, 0.18)',
|
||
|
|
success: '#22c55e',
|
||
|
|
successMuted: 'rgba(34, 197, 94, 0.15)',
|
||
|
|
successHover: '#16a34a',
|
||
|
|
warning: '#f59e0b',
|
||
|
|
warningMuted: 'rgba(245, 158, 11, 0.15)',
|
||
|
|
error: '#ef4444',
|
||
|
|
errorMuted: 'rgba(239, 68, 68, 0.15)',
|
||
|
|
errorHover: '#dc2626',
|
||
|
|
link: '#6366f1',
|
||
|
|
linkVisited: '#8b5cf6',
|
||
|
|
overlay: 'rgba(0, 0, 0, 0.8)',
|
||
|
|
fieldBg: 'rgba(0, 0, 0, 0.25)',
|
||
|
|
onPrimary: '#ffffff',
|
||
|
|
},
|
||
|
|
},
|
||
|
|
|
||
|
|
'breeze-light': {
|
||
|
|
id: 'breeze-light',
|
||
|
|
name: 'Breeze Light',
|
||
|
|
description: 'Light theme inspired by the Breeze palette',
|
||
|
|
author: 'Community',
|
||
|
|
isDark: false,
|
||
|
|
colors: {
|
||
|
|
bg: '#eff0f1',
|
||
|
|
bgAlt: '#e3e5e7',
|
||
|
|
surface: '#fcfcfc',
|
||
|
|
surfaceHover: '#f4f5f6',
|
||
|
|
border: '#bdc3c7',
|
||
|
|
borderHover: '#95a5a6',
|
||
|
|
text: '#232629',
|
||
|
|
textMuted: '#707d8a',
|
||
|
|
textInverse: '#ffffff',
|
||
|
|
primary: '#3daee9',
|
||
|
|
primaryHover: '#2980b9',
|
||
|
|
primaryMuted: 'rgba(61, 174, 233, 0.15)',
|
||
|
|
secondary: '#1d99f3',
|
||
|
|
secondaryHover: '#1a8fe8',
|
||
|
|
info: '#3daee9',
|
||
|
|
infoHover: '#2980b9',
|
||
|
|
infoMuted: 'rgba(61, 174, 233, 0.15)',
|
||
|
|
neutral: '#707d8a',
|
||
|
|
neutralHover: '#4f5b66',
|
||
|
|
neutralMuted: 'rgba(112, 125, 138, 0.2)',
|
||
|
|
success: '#27ae60',
|
||
|
|
successMuted: 'rgba(39, 174, 96, 0.15)',
|
||
|
|
successHover: '#1f8a4d',
|
||
|
|
warning: '#f67400',
|
||
|
|
warningMuted: 'rgba(246, 116, 0, 0.15)',
|
||
|
|
error: '#da4453',
|
||
|
|
errorMuted: 'rgba(218, 68, 83, 0.15)',
|
||
|
|
errorHover: '#b93a46',
|
||
|
|
link: '#2980b9',
|
||
|
|
linkVisited: '#9b59b6',
|
||
|
|
overlay: 'rgba(0, 0, 0, 0.55)',
|
||
|
|
fieldBg: '#f7f7f7',
|
||
|
|
onPrimary: '#ffffff',
|
||
|
|
},
|
||
|
|
},
|
||
|
|
|
||
|
|
'breeze-dark': {
|
||
|
|
id: 'breeze-dark',
|
||
|
|
name: 'Breeze Dark',
|
||
|
|
description: 'Dark theme inspired by the Breeze palette',
|
||
|
|
author: 'Community',
|
||
|
|
isDark: true,
|
||
|
|
colors: {
|
||
|
|
bg: '#1b1e20',
|
||
|
|
bgAlt: '#121314',
|
||
|
|
surface: '#232629',
|
||
|
|
surfaceHover: '#2d3135',
|
||
|
|
border: '#3d4349',
|
||
|
|
borderHover: '#4d5459',
|
||
|
|
text: '#fcfcfc',
|
||
|
|
textMuted: '#a1a9b1',
|
||
|
|
textInverse: '#232629',
|
||
|
|
primary: '#3daee9',
|
||
|
|
primaryHover: '#2980b9',
|
||
|
|
primaryMuted: 'rgba(61, 174, 233, 0.2)',
|
||
|
|
secondary: '#1d99f3',
|
||
|
|
secondaryHover: '#1a8fe8',
|
||
|
|
info: '#3daee9',
|
||
|
|
infoHover: '#2980b9',
|
||
|
|
infoMuted: 'rgba(61, 174, 233, 0.2)',
|
||
|
|
neutral: '#a1a9b1',
|
||
|
|
neutralHover: '#6b7280',
|
||
|
|
neutralMuted: 'rgba(161, 169, 177, 0.2)',
|
||
|
|
success: '#27ae60',
|
||
|
|
successMuted: 'rgba(39, 174, 96, 0.2)',
|
||
|
|
successHover: '#1f8a4d',
|
||
|
|
warning: '#f67400',
|
||
|
|
warningMuted: 'rgba(246, 116, 0, 0.2)',
|
||
|
|
error: '#da4453',
|
||
|
|
errorMuted: 'rgba(218, 68, 83, 0.2)',
|
||
|
|
errorHover: '#b93a46',
|
||
|
|
link: '#1d99f3',
|
||
|
|
linkVisited: '#9b59b6',
|
||
|
|
overlay: 'rgba(0, 0, 0, 0.8)',
|
||
|
|
fieldBg: 'rgba(0, 0, 0, 0.25)',
|
||
|
|
onPrimary: '#ffffff',
|
||
|
|
},
|
||
|
|
},
|
||
|
|
|
||
|
|
opensuse: {
|
||
|
|
id: 'opensuse',
|
||
|
|
name: 'openSUSE',
|
||
|
|
description: 'Theme based on openSUSE branding guidelines',
|
||
|
|
author: 'openSUSE Community',
|
||
|
|
isDark: true,
|
||
|
|
colors: {
|
||
|
|
bg: '#173f4f',
|
||
|
|
bgAlt: '#1e4d5f',
|
||
|
|
surface: '#21596e',
|
||
|
|
surfaceHover: '#266a82',
|
||
|
|
border: '#2d7a94',
|
||
|
|
borderHover: '#3a8da7',
|
||
|
|
text: '#f5f5f5',
|
||
|
|
textMuted: '#a8c8d4',
|
||
|
|
textInverse: '#173f4f',
|
||
|
|
primary: '#73ba25',
|
||
|
|
primaryHover: '#6aad20',
|
||
|
|
primaryMuted: 'rgba(115, 186, 37, 0.2)',
|
||
|
|
secondary: '#35b9ab',
|
||
|
|
secondaryHover: '#2da89b',
|
||
|
|
info: '#35b9ab',
|
||
|
|
infoHover: '#2da89b',
|
||
|
|
infoMuted: 'rgba(53, 185, 171, 0.2)',
|
||
|
|
neutral: '#a8c8d4',
|
||
|
|
neutralHover: '#7aa9b9',
|
||
|
|
neutralMuted: 'rgba(168, 200, 212, 0.2)',
|
||
|
|
success: '#73ba25',
|
||
|
|
successMuted: 'rgba(115, 186, 37, 0.2)',
|
||
|
|
successHover: '#5f9d1f',
|
||
|
|
warning: '#f7a70d',
|
||
|
|
warningMuted: 'rgba(247, 167, 13, 0.2)',
|
||
|
|
error: '#e74c3c',
|
||
|
|
errorMuted: 'rgba(231, 76, 60, 0.2)',
|
||
|
|
errorHover: '#c0392b',
|
||
|
|
link: '#73ba25',
|
||
|
|
linkVisited: '#35b9ab',
|
||
|
|
overlay: 'rgba(0, 0, 0, 0.75)',
|
||
|
|
fieldBg: 'rgba(0, 0, 0, 0.18)',
|
||
|
|
onPrimary: '#ffffff',
|
||
|
|
},
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
export const DEFAULT_THEME = 'neutral';
|
||
|
|
|
||
|
|
export function getTheme(id: string): Theme {
|
||
|
|
return themes[id] || themes[DEFAULT_THEME];
|
||
|
|
}
|
||
|
|
|
||
|
|
export function getAllThemes(): Theme[] {
|
||
|
|
return Object.values(themes);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function applyTheme(theme: Theme): void {
|
||
|
|
const root = document.documentElement;
|
||
|
|
const { colors } = theme;
|
||
|
|
|
||
|
|
root.style.setProperty('--color-bg', colors.bg);
|
||
|
|
root.style.setProperty('--color-bg-alt', colors.bgAlt);
|
||
|
|
root.style.setProperty('--color-surface', colors.surface);
|
||
|
|
root.style.setProperty('--color-surface-hover', colors.surfaceHover);
|
||
|
|
root.style.setProperty('--color-border', colors.border);
|
||
|
|
root.style.setProperty('--color-border-hover', colors.borderHover);
|
||
|
|
root.style.setProperty('--color-text', colors.text);
|
||
|
|
root.style.setProperty('--color-text-muted', colors.textMuted);
|
||
|
|
root.style.setProperty('--color-text-inverse', colors.textInverse);
|
||
|
|
root.style.setProperty('--color-primary', colors.primary);
|
||
|
|
root.style.setProperty('--color-primary-hover', colors.primaryHover);
|
||
|
|
root.style.setProperty('--color-primary-muted', colors.primaryMuted);
|
||
|
|
root.style.setProperty('--color-secondary', colors.secondary);
|
||
|
|
root.style.setProperty('--color-secondary-hover', colors.secondaryHover);
|
||
|
|
root.style.setProperty('--color-info', colors.info);
|
||
|
|
root.style.setProperty('--color-info-hover', colors.infoHover);
|
||
|
|
root.style.setProperty('--color-info-muted', colors.infoMuted);
|
||
|
|
root.style.setProperty('--color-neutral', colors.neutral);
|
||
|
|
root.style.setProperty('--color-neutral-hover', colors.neutralHover);
|
||
|
|
root.style.setProperty('--color-neutral-muted', colors.neutralMuted);
|
||
|
|
root.style.setProperty('--color-success', colors.success);
|
||
|
|
root.style.setProperty('--color-success-muted', colors.successMuted);
|
||
|
|
root.style.setProperty('--color-success-hover', colors.successHover);
|
||
|
|
root.style.setProperty('--color-warning', colors.warning);
|
||
|
|
root.style.setProperty('--color-warning-muted', colors.warningMuted);
|
||
|
|
root.style.setProperty('--color-error', colors.error);
|
||
|
|
root.style.setProperty('--color-error-muted', colors.errorMuted);
|
||
|
|
root.style.setProperty('--color-error-hover', colors.errorHover);
|
||
|
|
root.style.setProperty('--color-link', colors.link);
|
||
|
|
root.style.setProperty('--color-link-visited', colors.linkVisited);
|
||
|
|
root.style.setProperty('--color-overlay', colors.overlay);
|
||
|
|
root.style.setProperty('--color-field-bg', colors.fieldBg);
|
||
|
|
root.style.setProperty('--color-on-primary', colors.onPrimary);
|
||
|
|
|
||
|
|
root.setAttribute('data-theme', theme.id);
|
||
|
|
root.setAttribute('data-theme-mode', theme.isDark ? 'dark' : 'light');
|
||
|
|
}
|
||
|
|
|
||
|
|
export function loadSavedTheme(): string {
|
||
|
|
if (typeof localStorage !== 'undefined') {
|
||
|
|
return localStorage.getItem('likwid-theme') || DEFAULT_THEME;
|
||
|
|
}
|
||
|
|
return DEFAULT_THEME;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function saveTheme(themeId: string): void {
|
||
|
|
if (typeof localStorage !== 'undefined') {
|
||
|
|
localStorage.setItem('likwid-theme', themeId);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function initTheme(): void {
|
||
|
|
const savedThemeId = loadSavedTheme();
|
||
|
|
const theme = getTheme(savedThemeId);
|
||
|
|
applyTheme(theme);
|
||
|
|
}
|