fix(theme): reactive ThemeToggle component with visible label
build-and-publish / test (push) Has been cancelled
build-and-publish / image (push) Has been cancelled

Previous topbar theme button used useApp.getState() inline in JSX
which doesn't subscribe — clicking changed state but the icon never
re-rendered. Replace with proper component that subscribes via hook.

Also add visible 'DARK'/'LIGHT' label so the button is discoverable
without hover-tooltip-only labelling.

Confidence: high
Scope-risk: trivial
This commit is contained in:
2026-06-14 11:39:53 +04:00
parent b26ea1ee9c
commit 6f8832d222
2 changed files with 22 additions and 3 deletions
+19 -3
View File
@@ -133,9 +133,8 @@ export default function App() {
<Layers size={12} /> Console
{apiLogCount > 0 && <span className="badge mono">{apiLogCount}</span>}
</button>
<button className="link-btn" onClick={() => useApp.getState().setTheme(useApp.getState().theme === "dark" ? "light" : "dark")} title="Toggle theme">
{useApp.getState().theme === "dark" ? <Sun size={13} /> : <Moon size={13} />}
</button>
<ThemeToggle />
<button className="link-btn" onClick={() => setCmdOpen(true)}>
<Cmd size={13} /> <kbd>K</kbd>
</button>
@@ -159,3 +158,20 @@ export default function App() {
</div>
);
}
function ThemeToggle() {
const theme = useApp((s) => s.theme);
const setTheme = useApp((s) => s.setTheme);
const isDark = theme === "dark";
return (
<button
className="link-btn theme-toggle"
onClick={() => setTheme(isDark ? "light" : "dark")}
title={isDark ? "Switch to light theme" : "Switch to dark theme"}
aria-label={isDark ? "Switch to light theme" : "Switch to dark theme"}
>
{isDark ? <Sun size={13} /> : <Moon size={13} />}
<span className="theme-toggle-label">{isDark ? "LIGHT" : "DARK"}</span>
</button>
);
}