Components / Controls
ThemeToggle
A light, dark or system switch with sun, moon and monitor icons. It is a SegmentedControl wired to useColorMode. Pair it with CynosureTheme so the chosen mode is applied.
When to useLink to "When to use"
- A colour-mode switch in an app header, settings page or extension popup.
Use something else when:
- you need a different set of modes or other labels and icons: SegmentedControl
UsageLink to "Usage"
Uncontrolled, it manages and persists the mode itself. Pass the mode to CynosureTheme through useColorMode:
import { CynosureTheme, ThemeToggle, useColorMode } from "@arshad-shah/cynosure";
function App() {
const { mode } = useColorMode();
return (
<CynosureTheme mode={mode}>
<ThemeToggle />
{/* app */}
</CynosureTheme>
);
}Controlled useLink to "Controlled use"
Pass value and onChange(mode) to own the state. mode is "light", "dark" or "system".
<ThemeToggle value={mode} onChange={setMode} size="sm" />PersistenceLink to "Persistence"
Uncontrolled mode is stored in localStorage by default. Pass storage (any { get, set } object, sync or async, such as one backed by chrome.storage) to persist elsewhere.
PropsLink to "Props"
| Prop | What it does | Type | Default |
|---|---|---|---|
value | Controlled mode; omit to manage and persist it internally. | ColorMode | |
onChange | Called with the mode the person picks. | ((mode: ColorMode) => void) | |
storage | Persistence for uncontrolled use (localStorage by default; chrome.storage works too). | ColorModeStorage | |
storageKey | The key the mode is saved under, for uncontrolled use. Give each product on a shared origin its own, and pass the same one to themeInitScript({ key }) so the saved mode is applied before the first paint. Default "cy-color-mode". | string | "cy-color-mode" |
size | Size of the control. Default "md". | Size | "md" |
variant | segmented (default): three choices side by side. cycle: one icon button that steps light → dark → system (for tight headers); its name says the current mode and the next one ("Colour mode: Light. Switch to Dark"). | "segmented" | "cycle" | |
labels | Replace the built-in English text: the control's name and the names of the three modes. | { label?: string; light?: string; dark?: string; system?: string; cycle?: (current: string, next: string) => string; } | |
className | Added to the control, for layout. | string | |
style | Layout only. | CSSProperties |
Generated from the type definitions in @arshad-shah/cynosure 0.5.0.
Behaviour and accessibilityLink to "Behaviour and accessibility"
- Names: the group is named "Colour mode" and the options "Light", "Dark" and "System". Override them with
labels(label,light,dark,system) when you localise. - Keyboard: it behaves as its SegmentedControl: arrow keys move and select, and activating the current option does nothing.
- Icon-only: the icons carry no visible text, but each option keeps its accessible name.
ThemingLink to "Theming"
ThemeToggle has no tokens of its own. It uses the SegmentedControl tokens: --cy-segmented-control-{radius,track-bg,active-bg,padding}.
createTheme({ components: { segmentedControl: { radius: "999px" } } });RelatedLink to "Related"
These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.