1import { resolveTextScaleVariables } from "./appearancePreferences";
2import { BUILT_IN_THEME_IDS, type BuiltInThemeId } from "@t3tools/shared/themePalettes";
3import {
4 DEFAULT_MOBILE_THEME_ID,
5 type MobileThemeAppearance,
6 type MobileThemeId,
7 type MobileThemeMode,
8} from "./mobileTheme";
9
10export type MobileUniwindThemeName =
11 | MobileThemeAppearance
12 | `${BuiltInThemeId}-${MobileThemeAppearance}`;
13
14export interface MobileThemeRuntimeState {
15 readonly baseFontSize: number;
16 readonly themeAppearance: MobileThemeAppearance;
17 readonly themeMode: MobileThemeMode;
18}
19
20export type MobileThemeRuntimeOperation =
21 | {
22 readonly kind: "update-text-variables";
23 readonly themeName: "light" | "dark" | MobileUniwindThemeName;
24 readonly variables: Readonly<Record<string, number>>;
25 }
26 | {
27 readonly kind: "set-appearance-mode";
28 readonly appearance: MobileThemeAppearance;
29 readonly themeMode: MobileThemeMode;
30 };
31
32const UNIWIND_THEME_NAMES: ReadonlyArray<"light" | "dark" | MobileUniwindThemeName> = [
33 "light",
34 "dark",
35 ...BUILT_IN_THEME_IDS.flatMap((themeId) => [
36 `${themeId}-light` as const,
37 `${themeId}-dark` as const,
38 ]),
39];
40
41export function getMobileUniwindThemeName(
42 themeId: MobileThemeId,
43 appearance: MobileThemeAppearance,
44): MobileUniwindThemeName {
45 return themeId === DEFAULT_MOBILE_THEME_ID || themeId === "material-you"
46 ? appearance
47 : `${themeId}-${appearance}`;
48}
49
50export function createMobileThemeRuntimeOperations(
51 previous: MobileThemeRuntimeState | null,
52 next: MobileThemeRuntimeState,
53): ReadonlyArray<MobileThemeRuntimeOperation> {
54 const operations: MobileThemeRuntimeOperation[] = [];
55
56 if (previous === null || previous.baseFontSize !== next.baseFontSize) {
57 const variables = resolveTextScaleVariables(next.baseFontSize);
58 for (const themeName of UNIWIND_THEME_NAMES) {
59 operations.push({ kind: "update-text-variables", themeName, variables });
60 }
61 }
62
63 if (previous === null || previous.themeMode !== next.themeMode) {
64 operations.push({
65 kind: "set-appearance-mode",
66 appearance: next.themeAppearance,
67 themeMode: next.themeMode,
68 });
69 }
70
71 return operations;
72}