feat(ui): add light theme toggle

This commit is contained in:
vince 2026-06-20 00:49:22 +02:00
parent bbc81cea0d
commit cdb269e505
17 changed files with 415 additions and 24 deletions

View file

@ -3,7 +3,11 @@ import type { DashboardRuntimeState } from "$lib/server/dashboard";
import {
DashboardFrame,
SystemState,
ThemeToggle,
dashboardDocumentToUiDashboard,
persistUiTheme,
resolveInitialUiTheme,
type UiTheme,
type UiSeverity,
} from "$lib/ui";
@ -16,13 +20,23 @@ const loadingDashboardState: DashboardRuntimeState = {
export function AppStateView({
dashboard,
onThemeChange,
theme,
}: {
dashboard: DashboardRuntimeState;
onThemeChange?: (theme: UiTheme) => void;
theme?: UiTheme;
}) {
const themeToggle =
theme && onThemeChange ? (
<ThemeToggle theme={theme} onThemeChange={onThemeChange} />
) : null;
if (dashboard.state === "ready") {
return (
<DashboardFrame
dashboard={dashboardDocumentToUiDashboard(dashboard.document)}
actions={themeToggle}
/>
);
}
@ -32,6 +46,9 @@ export function AppStateView({
return (
<main className="state-shell" data-dashboard-state={dashboard.state}>
{themeToggle ? (
<div className="state-shell__actions">{themeToggle}</div>
) : null}
<SystemState
title={dashboard.title}
detail={detail}
@ -73,6 +90,11 @@ export function resolveDocumentMetadata(dashboard: DashboardRuntimeState): {
export default function App() {
const [dashboard, setDashboard] =
useState<DashboardRuntimeState>(loadingDashboardState);
const [theme, setTheme] = useState<UiTheme>(() => {
if (typeof window === "undefined") return "dark";
return resolveInitialUiTheme(window.localStorage);
});
useEffect(() => {
const metadata = resolveDocumentMetadata(dashboard);
@ -89,6 +111,11 @@ export default function App() {
description.content = metadata.description;
}, [dashboard]);
useEffect(() => {
document.documentElement.dataset.uiTheme = theme;
persistUiTheme(theme, window.localStorage);
}, [theme]);
useEffect(() => {
let cancelled = false;
let refreshTimer: number | undefined;
@ -126,7 +153,13 @@ export default function App() {
};
}, []);
return <AppStateView dashboard={dashboard} />;
return (
<AppStateView
dashboard={dashboard}
theme={theme}
onThemeChange={setTheme}
/>
);
}
function stateSeverity(state: DashboardRuntimeState["state"]): UiSeverity {