Files
message-inbox-web-frontend-sdk/packages/messaging-inbox-sdk/src/theme.ts
T
2026-07-17 21:48:37 +05:30

66 lines
2.0 KiB
TypeScript

import type { ThemeConfig, ThemeTokens } from "./config";
/** Turns a ThemeConfig + active scheme into the CSS variables Tailwind reads. */
export function tokensToCssVars(
theme: ThemeConfig,
scheme: "light" | "dark",
): Record<string, string> {
const t: ThemeTokens = scheme === "dark" ? theme.dark : theme.light;
return {
"--c-bg": t.bg,
"--c-surface": t.surface,
"--c-panel": t.panel,
"--c-elevated": t.elevated,
"--c-hover": t.hover,
"--c-border": t.border,
"--c-border-strong": t.borderStrong,
"--c-ink": t.ink,
"--c-muted": t.muted,
"--c-dim": t.dim,
"--c-accent": t.accent,
"--c-accent-fg": t.accentFg,
"--c-accent-soft": t.accentSoft,
"--c-success": t.success,
"--c-warning": t.warning,
"--c-danger": t.danger,
"--c-info": t.info,
"--r-card": theme.radiusCard,
"--r-control": theme.radiusControl,
"--r-pill": theme.radiusPill,
"--font-sans": theme.fontSans,
"--font-mono": theme.fontMono,
"--brand-gradient": theme.gradient,
};
}
/** Imperatively apply theme vars + the `dark` class to <html>. */
export function applyTheme(
el: HTMLElement,
theme: ThemeConfig,
scheme: "light" | "dark",
): void {
const vars = tokensToCssVars(theme, scheme);
for (const [k, v] of Object.entries(vars)) el.style.setProperty(k, v);
el.classList.toggle("dark", scheme === "dark");
el.style.colorScheme = scheme;
}
/** Resolve a "system" mode against the OS preference. */
export function resolveScheme(mode: ThemeConfig["mode"]): "light" | "dark" {
if (mode === "light" || mode === "dark") return mode;
if (typeof window !== "undefined" && window.matchMedia) {
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
}
return "dark";
}
/** SSR-safe inline style string for the initial <html> render (prevents flash). */
export function themeStyleString(
theme: ThemeConfig,
scheme: "light" | "dark",
): string {
return Object.entries(tokensToCssVars(theme, scheme))
.map(([k, v]) => `${k}:${v}`)
.join(";");
}