2.9 KiB
useTheme() — read the active theme registry
(no submodules)
Purpose
The primary read-side hook for the chassis theme system. Returns the
active theme, the registered theme list, the setTheme callback, the
React-transition isPending flag, and the live
reducedMotionActive boolean. Throws
ReactUiError(REACT_UI.NO_PROVIDER) outside of a <ThemeProvider> so
misuses fail fast rather than silently render an unthemed UI.
Features
- Returns a
ThemeContextValuesnapshot — every field is required - Throws when called outside a Provider so consumer code surfaces the misuse at the call site rather than silently degrading
- Pairs cleanly with
useTheme().setTheme(name)for an awaitable transition; consumers canawait setTheme('dark')and inspectgetComputedStyle(document.documentElement)immediately after
Usage: Basic example
import { useTheme } from "@suaveplan/react-ui/theme/use-theme";
function CurrentThemeBadge() {
const { theme } = useTheme();
return <span data-theme-name={theme.name}>{theme.name}</span>;
}
Usage: Advanced example
import { useTheme } from "@suaveplan/react-ui/theme/use-theme";
function ThemeButtons() {
const { themes, theme, setTheme, isPending } = useTheme();
return (
<div role="group" aria-busy={isPending}>
{themes.map((t) => (
<button
key={t.name}
type="button"
onClick={() => {
void setTheme(t.name);
}}
aria-pressed={t.name === theme.name}
>
{t.name}
</button>
))}
</div>
);
}
API Reference
useTheme(): ThemeContextValuetheme: ThemePlugin— currently active themethemes: readonly ThemePlugin[]— every theme registered with the surrounding<ThemeProvider>setTheme: (name: string) => Promise<void>— async because the chassis wraps the transition inuseTransition;awaitresolves after the React commit but<html data-theme>mutation runs in the following effect cycleisPending: boolean— true while asetThemetransition is in flightreducedMotionActive: boolean— liveprefers-reduced-motionflag resolved by the Provider
- Throws
ReactUiError(REACT_UI.NO_PROVIDER)on missing Provider.
Implementation notes
The hook is a thin useContext reader; the heavy lifting lives in
<ThemeProvider>. Keeping it slim means it can be called freely in
any component without added rerender cost — a setTheme invocation
re-emits the context value (because theme and isPending change),
which causes every reader to re-render once. Components that should
only re-render on TOKEN changes (not theme name changes) read
useThemeTokens() instead of pulling theme.cssVariables from
useTheme().