Files
Remote-Terminal-for-MeshCore/frontend/src/utils/theme.ts
2026-03-10 19:32:22 -07:00

87 lines
2.2 KiB
TypeScript

export interface Theme {
id: string;
name: string;
/** 6 hex colors for the swatch preview: [bg, card, primary, accent, warm, cool] */
swatches: [string, string, string, string, string, string];
/** Hex background color for the PWA theme-color meta tag */
metaThemeColor: string;
}
export const THEME_CHANGE_EVENT = 'remoteterm-theme-change';
export const THEMES: Theme[] = [
{
id: 'original',
name: 'Original',
swatches: ['#111419', '#181b21', '#27a05c', '#282c33', '#f59e0b', '#3b82f6'],
metaThemeColor: '#111419',
},
{
id: 'light',
name: 'Light',
swatches: ['#F8F7F4', '#FFFFFF', '#1B7D4E', '#EDEBE7', '#D97706', '#3B82F6'],
metaThemeColor: '#F8F7F4',
},
{
id: 'cyberpunk',
name: 'Cyberpunk',
swatches: ['#07080A', '#0D1112', '#00FF41', '#141E17', '#FAFF00', '#FF2E6C'],
metaThemeColor: '#07080A',
},
{
id: 'high-contrast',
name: 'High Contrast',
swatches: ['#000000', '#141414', '#3B9EFF', '#1E1E1E', '#FFB800', '#FF4757'],
metaThemeColor: '#000000',
},
{
id: 'obsidian-glass',
name: 'Obsidian Glass',
swatches: ['#0C0E12', '#151821', '#D4A070', '#1E2230', '#D4924A', '#5B82B4'],
metaThemeColor: '#0C0E12',
},
{
id: 'solar-flare',
name: 'Solar Flare',
swatches: ['#0D0607', '#151012', '#FF0066', '#2D1D22', '#FF8C1A', '#30ACD4'],
metaThemeColor: '#0D0607',
},
];
const THEME_KEY = 'remoteterm-theme';
export function getSavedTheme(): string {
try {
return localStorage.getItem(THEME_KEY) ?? 'original';
} catch {
return 'original';
}
}
export function applyTheme(themeId: string): void {
try {
localStorage.setItem(THEME_KEY, themeId);
} catch {
// localStorage may be unavailable
}
if (themeId === 'original') {
delete document.documentElement.dataset.theme;
} else {
document.documentElement.dataset.theme = themeId;
}
// Update PWA theme-color meta tag
const theme = THEMES.find((t) => t.id === themeId);
if (theme) {
const meta = document.querySelector('meta[name="theme-color"]');
if (meta) {
meta.setAttribute('content', theme.metaThemeColor);
}
}
if (typeof window !== 'undefined') {
window.dispatchEvent(new CustomEvent(THEME_CHANGE_EVENT, { detail: themeId }));
}
}