Files
pgames-manager/frontend/src/theme.ts
T
mrleo1nidandClaude Sonnet 5.5 9ee3e1ff6e UI: unified design system, light/dark themes, redesigned pages and player UI
Tokens and components in styles.css, shared Ui (dialogs, toasts), icons,
bottom tab bar on mobile, keyboard/gamepad navigation, library shelf with
filters and conversion badges, hero game page, restyled player screens.
Games list now returns per-game version counts. Adds docs/UI_DESIGN.md.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 03:43:53 +03:00

40 lines
1.2 KiB
TypeScript

import { useCallback, useEffect, useState } from "react";
export type ThemeChoice = "system" | "dark" | "light";
const KEY = "pg-theme";
function read(): ThemeChoice {
try {
const v = localStorage.getItem(KEY);
return v === "dark" || v === "light" ? v : "system";
} catch {
return "system";
}
}
function apply(choice: ThemeChoice) {
const root = document.documentElement;
if (choice === "system") delete root.dataset.theme;
else root.dataset.theme = choice;
const dark = choice === "dark" || (choice === "system" && matchMedia("(prefers-color-scheme: dark)").matches);
document.querySelector('meta[name="theme-color"]')?.setAttribute("content", dark ? "#0e1016" : "#f4f1ec");
}
export function useTheme() {
const [choice, setChoice] = useState<ThemeChoice>(read);
useEffect(() => {
apply(choice);
try {
if (choice === "system") localStorage.removeItem(KEY);
else localStorage.setItem(KEY, choice);
} catch {
/* private mode */
}
}, [choice]);
const cycle = useCallback(
() => setChoice((c) => (c === "system" ? "dark" : c === "dark" ? "light" : "system")),
[],
);
return { choice, setChoice, cycle };
}