11 KiB
theme-context — React context plumbing for the active theme
(no submodules)
- theme-provider — (no submodules)- theme-switcher — (no submodules) - theme-switcher — (no submodules)- dark — The dark counterpart of
lightTheme. Same variant surface, same token names, lightness anchors inverted so foreground… - high-contrast — Accessibility-first theme that meets WCAG AAA contrast for normal and large text alike. Pure-white foreground (`#FFFFFF…
- light — The default
ThemePlugininstance shipped with@suaveplan/react-ui.lightThemematches the shadcnnovatoken pre… - use-resolved-theme-tokens —
useResolvedThemeTokens()is the read-side counterpart touseThemeMutator(). It returns the live merged token state…- use-resolved-theme-tokens —
useResolvedThemeTokens()is the read-side counterpart touseThemeMutator(). It returns the live merged token state…
- use-resolved-theme-tokens —
- use-theme — (no submodules) - use-theme — (no submodules)- use-theme-mutator —
useThemeMutator()is the public surface a consumer reaches for when it wants to push CSS custom properties onto the a…- use-theme-mutator —
useThemeMutator()is the public surface a consumer reaches for when it wants to push CSS custom properties onto the a…
- use-theme-mutator —
- use-theme-tokens — (no submodules) - use-theme-tokens — (no submodules)- use-themed-variants — (no submodules) - use-themed-variants — (no submodules)- theme-context — (no submodules)- theme-provider — _(no submo…
- theme-provider — (no submodules)- theme-switcher — (no submodules)- theme-switcher — (no submodules)- dark — The dark counterpart of
lightTheme. Same variant surface, same token names, lightness anchors inverted so foreground… - high-contrast — Accessibility-first theme that meets WCAG AAA contrast for normal and large text alike. Pure-white foreground (`#FFFFFF…
- light — The default
ThemePlugininstance shipped with@suaveplan/react-ui.lightThemematches the shadcnnovatoken pre… - use-theme — (no submodules)- use-theme — (no submodules)- use-theme-tokens — (no submodules)- use-theme-tokens — (no submodules)- use-themed-variants — (no submodules)- use-themed-variants — (no submodules)- theme-context — (no submodules)- theme-provider — (no submodules)- theme-switcher — (no submodules)- theme-switcher — (no submodules)- dark — The dark counterpart of
lightTheme. Same variant surface, same token names, lightness anchors inverted so foreground… - high-contrast — Accessibility-first theme that meets WCAG AAA contrast for normal and large text alike. Pure-white foreground (`#FFFFFF…
- light — The default
ThemePlugininstance shipped with@suaveplan/react-ui.lightThemematches the shadcnnovatoken pre… - use-theme — (no submodules)- use-theme — (no submodules)- use-theme-tokens — (no submodules)- use-theme-tokens — (no submodules)- use-themed-variants — (no submodules)- use-themed-variants — (no submodules)- theme-context — (no submodules)- theme-provider — <!-- begin:…
- theme-provider — (no submodules)- theme-switcher — (no submodules)- theme-switcher — (no submodules)- dark — The dark counterpart of
lightTheme. Same variant surface, same token names, lightness anchors inverted so foreground… - high-contrast — Accessibility-first theme that meets WCAG AAA contrast for normal and large text alike. Pure-white foreground (`#FFFFFF…
- light — The default
ThemePlugininstance shipped with@suaveplan/react-ui.lightThemematches the shadcnnovatoken pre… - use-theme — (no submodules)- use-theme — (no submodules)- use-theme-tokens — (no submodules)- use-theme-tokens — (no submodules)- use-themed-variants — (no submodules)- use-themed-variants — (no submodules)- theme-context — (no submodules)- theme-provider — _(no subm…
- theme-provider — (no submodules)- theme-switcher — (no submodules) - theme-switcher — (no submodules)- dark — The dark counterpart of
lightTheme. Same variant surface, same token names, lightness anchors inverted so foreground… - high-contrast — Accessibility-first theme that meets WCAG AAA contrast for normal and large text alike. Pure-white foreground (`#FFFFFF…
- light — The default
ThemePlugininstance shipped with@suaveplan/react-ui.lightThemematches the shadcnnovatoken pre… - use-theme — (no submodules) - use-theme — (no submodules)- use-theme-tokens — (no submodules) - use-theme-tokens — (no submodules)- use-themed-variants — (no submodules) - use-themed-variants — (no submodules)- theme-context — (no submodules)
Purpose
Owns the React Context <ThemeProvider> writes into and every theme
hook (useTheme, useThemeTokens, useThemedVariants,
<ThemeSwitcher>) reads from. The context is intentionally typed as
ThemeContextValue | null — null carries "no Provider mounted" so
hooks can throw a structured ReactUiError(REACT_UI.NO_PROVIDER) in
dev mode rather than silently rendering a broken UI.
Features
- Single source-of-truth context for the chassis theme system
nulldiscriminator drives provider-missing detection in every consumer hookdisplayNameset so React DevTools showsReactUiThemeContextrather than the unhelpfulContext.Providerdefault- Exposes
reducedMotionActiveso motion-aware components can read the resolvedprefers-reduced-motionpolicy without re-queryingmatchMediathemselves
Usage: Basic example
import { useContext } from "react";
import { ThemeContext } from "@suaveplan/react-ui/theme/theme-context";
function CustomThemeAware() {
const ctx = useContext(ThemeContext);
if (!ctx) return null;
return <div data-theme={ctx.theme.name}>…</div>;
}
Usage: Advanced example
import { useContext } from "react";
import { ThemeContext, type ThemeContextValue } from "@suaveplan/react-ui/theme/theme-context";
function useThemeOrThrow(): ThemeContextValue {
const ctx = useContext(ThemeContext);
if (ctx === null) {
throw new Error("useThemeOrThrow requires <ThemeProvider>");
}
return ctx;
}
API Reference
ThemeContext: React.Context<ThemeContextValue | null>— initial valuenullso unwrapped reads can be detectedinterface ThemeContextValue—{ theme, themes, setTheme, isPending, reducedMotionActive }
Implementation notes
The setTheme callback is typed as (name: string) => Promise<void>
so the Provider can wrap the underlying state update in
useTransition() and consumers that await setTheme('dark') get the
DOM in its post-commit state. The reducedMotionActive field is
recomputed inside the Provider on prefers-reduced-motion media query
changes; consumers that need finer control over the motion policy
should read theme.motionTokens.respectReducedMotion directly via
useTheme().