appearance-config.ts RawHistoryFolder
1/**
2 * Appearance Configuration Module
3 *
4 * Handles application appearance configuration including color palettes and fonts.
5 * This config is injected by the native layer at startup and made available to all
6 * injected modules and components.
7 */
8
9export interface ColorPalette {
10 background: string;
11 surface: string;
12 surfaceVariant: string;
13 text: string;
14 muted: string;
15 accent: string;
16 border: string;
17}
18
19export interface AppearanceConfig {
20 theme: "light" | "dark";
21 palettes: {
22 light: ColorPalette;
23 dark: ColorPalette;
24 };
25 fonts: {
26 sans: string;
27 serif: string;
28 monospace: string;
29 defaultSize: number;
30 };
31}
32
33declare global {
34 interface Window {
35 __dumber_appearance_config?: AppearanceConfig;
36 __dumber_applyPalette?: (theme: "light" | "dark") => void;
37 }
38}
39
40/**
41 * Applies the appearance configuration to the document
42 * Sets CSS custom properties for colors and fonts
43 */
44export function applyAppearanceConfig(): void {
45 const config = window.__dumber_appearance_config;
46 if (!config) {
47 console.warn("[dumber] Appearance config not available");
48 return;
49 }
50
51 const theme = config.theme || "light";
52 const palette = config.palettes[theme];
53 const root = document.documentElement;
54
55 // Apply color palette as CSS custom properties
56 root.style.setProperty("--color-background", palette.background);
57 root.style.setProperty("--color-surface", palette.surface);
58 root.style.setProperty("--color-surface-variant", palette.surfaceVariant);
59 root.style.setProperty("--color-text", palette.text);
60 root.style.setProperty("--color-muted", palette.muted);
61 root.style.setProperty("--color-accent", palette.accent);
62 root.style.setProperty("--color-border", palette.border);
63
64 // Apply font families
65 root.style.setProperty("--font-sans", config.fonts.sans);
66 root.style.setProperty("--font-serif", config.fonts.serif);
67 root.style.setProperty("--font-mono", config.fonts.monospace);
68
69 console.log(`[dumber] Applied ${theme} appearance config`);
70
71 // Dispatch event for components that need to react to appearance changes
72 document.dispatchEvent(
73 new CustomEvent("dumber:appearance-applied", {
74 detail: { theme, palette, fonts: config.fonts },
75 }),
76 );
77}
78
79/**
80 * Gets the current theme from appearance config
81 */
82export function getCurrentTheme(): "light" | "dark" {
83 return window.__dumber_appearance_config?.theme || "light";
84}
85
86/**
87 * Gets the current color palette for the active theme
88 */
89export function getCurrentPalette(): ColorPalette | null {
90 const config = window.__dumber_appearance_config;
91 if (!config) return null;
92
93 return config.palettes[config.theme];
94}
95
96/**
97 * Expose palette application function globally for integration with color-scheme module
98 */
99window.__dumber_applyPalette = (theme: "light" | "dark") => {
100 const config = window.__dumber_appearance_config;
101 if (!config) return;
102
103 const palette = config.palettes[theme];
104 const root = document.documentElement;
105
106 root.style.setProperty("--color-background", palette.background);
107 root.style.setProperty("--color-surface", palette.surface);
108 root.style.setProperty("--color-surface-variant", palette.surfaceVariant);
109 root.style.setProperty("--color-text", palette.text);
110 root.style.setProperty("--color-muted", palette.muted);
111 root.style.setProperty("--color-accent", palette.accent);
112 root.style.setProperty("--color-border", palette.border);
113
114 console.log(`[dumber] Switched to ${theme} palette`);
115};
116
117// Auto-initialize if config is already available
118if (window.__dumber_appearance_config) {
119 applyAppearanceConfig();
120}
121
122// Listen for config injection and apply
123document.addEventListener("DOMContentLoaded", () => {
124 if (window.__dumber_appearance_config) {
125 applyAppearanceConfig();
126 }
127});
128
129export default {
130 applyAppearanceConfig,
131 getCurrentTheme,
132 getCurrentPalette,
133};