Openstatus
www.openstatus.dev
1export * from "./types";
2import { DRACULA_THEME } from "./dracula";
3import { GITHUB_HIGH_CONTRAST_THEME } from "./github";
4import { OPENSTATUS_ROUNDED_THEME, OPENSTATUS_THEME } from "./openstatus";
5import { SUPABASE_THEME } from "./supabase";
6import type { Theme, ThemeDefinition, ThemeMap } from "./types";
7import { assertUniqueThemeIds } from "./utils";
8// Please keep the themes ordered :)
9const THEMES_LIST = [
10 OPENSTATUS_THEME,
11 OPENSTATUS_ROUNDED_THEME,
12 SUPABASE_THEME,
13 GITHUB_HIGH_CONTRAST_THEME,
14 DRACULA_THEME,
15] satisfies Theme[];
16
17// NOTE: runtime validation to ensure that the theme IDs are unique
18assertUniqueThemeIds(THEMES_LIST);
19
20export const THEMES = THEMES_LIST.reduce<ThemeMap>((acc, theme) => {
21 acc[theme.id as keyof ThemeMap] = theme;
22 return acc;
23}, {} as ThemeMap);
24
25export const THEME_KEYS = THEMES_LIST.map((theme) => theme.id);
26export type ThemeKey = (typeof THEME_KEYS)[number];
27
28export function generateThemeStyles(
29 themeKey?: string,
30 overrides?: Partial<ThemeDefinition>,
31) {
32 let theme = themeKey ? THEMES[themeKey] : undefined;
33
34 if (!theme) {
35 // NOTE: fallback to openstatus theme if no theme is found
36 theme = OPENSTATUS_THEME;
37 }
38
39 const lightVars = Object.entries({ ...theme.light, ...overrides?.light })
40 .map(([key, value]) => `${key}: ${value};`)
41 .join("\n ");
42 const darkVars = Object.entries({ ...theme.dark, ...overrides?.dark })
43 .map(([key, value]) => `${key}: ${value};`)
44 .join("\n ");
45
46 return `
47 :root {
48 ${lightVars}
49 }
50 .dark {
51 ${darkVars}
52 }
53 `;
54}