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: {
2026-03-30 10:38:01 +02:00
background: "#f5efe6",
surface: "#fffdf8",
surfaceAlt: "#efe4d5",
text: "#162132",
textMuted: "#6d6559",
border: "#d7c8b5",
borderMuted: "#e8decf",
primary: "#162132",
primaryText: "#fffaf2",
secondary: "#e7dac9",
secondaryText: "#162132",
accent: "#b49053",
accentText: "#241a08",
accentSurface: "#f8eedf",
danger: "#a13b2d",
warningSurface: "#f5e8c8",
warningBorder: "#dec89a",
warningText: "#8b621d",
warningTextStrong: "#67470b",
brandSurface: "#162132",
brandSurfaceAlt: "#23314a",
brandText: "#fff8ee",
brandTextMuted: "#cfbea0",
brandAccent: "#b49053",
brandAccentText: "#241a08",
avatarSurface: "#23314a",
avatarText: "#fff8ee",
chipBackground: "#fffaf2",
chipBorder: "#dfd0bd",
chipText: "#162132",
chipActiveBackground: "#162132",
chipActiveText: "#fff8ee",
listAvatarBackground: "#ede1cf",
listAvatarText: "#7a6135",
bubbleMe: "#efe3d2",
inputBackground: "#fffaf2",
inputText: "#162132",
placeholder: "#9e907b",
tabActive: "#162132",
tabInactive: "#978b78",
headerBackground: "#fff8ee",
headerText: "#162132",
action: "#162132",
actionText: "#fff8ee",
radioBorder: "#d4c1a0",
2026-02-03 13:48:56 +01:00
},
};
const darkTheme: AppTheme = {
dark: true,
colors: {
2026-03-30 10:38:01 +02:00
background: "#0e1420",
surface: "#141d2c",
surfaceAlt: "#1a2537",
text: "#f8f2e7",
textMuted: "#b1a48e",
border: "#243248",
borderMuted: "#2d3c55",
primary: "#f4ead9",
primaryText: "#162132",
secondary: "#243248",
secondaryText: "#f8f2e7",
accent: "#c5a56a",
accentText: "#251a08",
accentSurface: "#2c2417",
danger: "#ef8b7f",
warningSurface: "#342712",
warningBorder: "#715426",
warningText: "#e5b96a",
warningTextStrong: "#f3d598",
brandSurface: "#121a29",
brandSurfaceAlt: "#1a2740",
brandText: "#fff8ee",
brandTextMuted: "#cebda0",
brandAccent: "#c5a56a",
brandAccentText: "#251a08",
avatarSurface: "#26344d",
avatarText: "#fff8ee",
chipBackground: "#141d2c",
chipBorder: "#32425e",
chipText: "#f8f2e7",
chipActiveBackground: "#c5a56a",
chipActiveText: "#251a08",
listAvatarBackground: "#2d2418",
listAvatarText: "#e4c688",
bubbleMe: "#26311b",
inputBackground: "#101828",
inputText: "#f8f2e7",
placeholder: "#7d8aa0",
tabActive: "#f8f2e7",
tabInactive: "#7f8ca2",
headerBackground: "#121a29",
headerText: "#f8f2e7",
action: "#f4ead9",
actionText: "#162132",
radioBorder: "#43526e",
2026-02-03 13:48:56 +01:00
},
};
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,
},
};
}