CoompanionApp/mobile/src/theme.ts

182 lines
4.5 KiB
TypeScript
Raw Normal View History

2026-02-03 13:48:56 +01:00
import { useColorScheme } from "react-native";
import {
DarkTheme,
DefaultTheme,
type Theme as NavigationTheme,
} from "@react-navigation/native";
export type AppTheme = {
dark: boolean;
colors: {
background: string;
surface: string;
surfaceAlt: string;
text: string;
textMuted: string;
border: string;
borderMuted: string;
primary: string;
primaryText: string;
secondary: string;
secondaryText: string;
accent: string;
accentText: string;
accentSurface: string;
danger: string;
warningSurface: string;
warningBorder: string;
warningText: string;
warningTextStrong: string;
brandSurface: string;
brandSurfaceAlt: string;
brandText: string;
brandTextMuted: string;
brandAccent: string;
brandAccentText: string;
avatarSurface: string;
avatarText: string;
chipBackground: string;
chipBorder: string;
chipText: string;
chipActiveBackground: string;
chipActiveText: string;
listAvatarBackground: string;
listAvatarText: string;
bubbleMe: string;
inputBackground: string;
inputText: string;
placeholder: string;
tabActive: string;
tabInactive: string;
headerBackground: string;
headerText: string;
action: string;
actionText: string;
radioBorder: string;
};
};
const lightTheme: AppTheme = {
dark: false,
colors: {
background: "#f7f7f9",
surface: "#ffffff",
surfaceAlt: "#f6f8fa",
text: "#0b1a2b",
textMuted: "#6b7280",
border: "#d8dee5",
borderMuted: "#e2e8f0",
primary: "#1b8b75",
primaryText: "#ffffff",
secondary: "#e7ecef",
secondaryText: "#0c1824",
accent: "#14b8a6",
accentText: "#042f2e",
accentSurface: "#ecfdf9",
danger: "#b91c1c",
warningSurface: "#fff6e5",
warningBorder: "#fde7c1",
warningText: "#b45309",
warningTextStrong: "#7c2d12",
brandSurface: "#0b1a2b",
brandSurfaceAlt: "#1f334d",
brandText: "#f8fafc",
brandTextMuted: "#9fb3c8",
brandAccent: "#14b8a6",
brandAccentText: "#042f2e",
avatarSurface: "#0f172a",
avatarText: "#e2e8f0",
chipBackground: "#ffffff",
chipBorder: "#e2e8f0",
chipText: "#0f172a",
chipActiveBackground: "#0f172a",
chipActiveText: "#f8fafc",
listAvatarBackground: "#e6f6f2",
listAvatarText: "#1b8b75",
bubbleMe: "#dff7ef",
inputBackground: "#ffffff",
inputText: "#0b1a2b",
placeholder: "#9aa6b2",
tabActive: "#0f172a",
tabInactive: "#94a3b8",
headerBackground: "#ffffff",
headerText: "#0b1a2b",
action: "#0f172a",
actionText: "#f8fafc",
radioBorder: "#cbd5f5",
},
};
const darkTheme: AppTheme = {
dark: true,
colors: {
background: "#0b0f14",
surface: "#111922",
surfaceAlt: "#0f1620",
text: "#f8fafc",
textMuted: "#a7b4c5",
border: "#1f2a37",
borderMuted: "#243244",
primary: "#1fbf98",
primaryText: "#ffffff",
secondary: "#1f2a37",
secondaryText: "#e2e8f0",
accent: "#2dd4bf",
accentText: "#04221b",
accentSurface: "#0f2a24",
danger: "#f87171",
warningSurface: "#2a1f0b",
warningBorder: "#5f3b11",
warningText: "#f59e0b",
warningTextStrong: "#fbbf24",
brandSurface: "#101a27",
brandSurfaceAlt: "#1b2b3f",
brandText: "#f8fafc",
brandTextMuted: "#9fb3c8",
brandAccent: "#2dd4bf",
brandAccentText: "#04221b",
avatarSurface: "#1e293b",
avatarText: "#e2e8f0",
chipBackground: "#111922",
chipBorder: "#273244",
chipText: "#e2e8f0",
chipActiveBackground: "#2dd4bf",
chipActiveText: "#04221b",
listAvatarBackground: "#0f2a24",
listAvatarText: "#5eead4",
bubbleMe: "#103128",
inputBackground: "#0f1620",
inputText: "#f8fafc",
placeholder: "#7f90a6",
tabActive: "#e2e8f0",
tabInactive: "#64748b",
headerBackground: "#111922",
headerText: "#f8fafc",
action: "#e2e8f0",
actionText: "#0b1a2b",
radioBorder: "#334155",
},
};
export function useTheme(): AppTheme {
const scheme = useColorScheme();
return scheme === "dark" ? darkTheme : lightTheme;
}
export function getNavigationTheme(theme: AppTheme): NavigationTheme {
const baseTheme = theme.dark ? DarkTheme : DefaultTheme;
return {
...baseTheme,
dark: theme.dark,
colors: {
...baseTheme.colors,
primary: theme.colors.primary,
background: theme.colors.background,
card: theme.colors.headerBackground,
text: theme.colors.headerText,
border: theme.colors.border,
notification: theme.colors.accent,
},
};
}