Theme Toggle
A ready-made light/dark switch built on Button, with a cross-fading sun and moon.
import { ThemeToggle } from "astralis-ui";
export function ThemeToggleDemo() {
return <ThemeToggle />;
}Import#
import { ThemeToggle } from "astralis-ui";Usage#
Drop it anywhere inside an AstralisProvider — it reads and writes the theme
through the same context the whole library uses, and persists the choice to
localStorage. Every demo on this page is live: clicking one switches this
site's theme, and the icon rotates a quarter turn as sun and moon cross-fade.
The one in this site's header is this exact component.
With a label#
showLabel adds a text label that names the mode a click switches to.
Sizing follows Button's scale, and the icon scales with it.
import { ThemeToggle, HStack } from "astralis-ui";
export function ThemeToggleLabel() {
return (
<HStack gap="3" wrap="wrap" justifyContent="center">
<ThemeToggle showLabel size="sm" />
<ThemeToggle showLabel />
<ThemeToggle showLabel size="lg" />
</HStack>
);
}Variants#
Theme Toggle extends Button, so every variant,
colorScheme, size and rounded value works.
import { ThemeToggle, HStack } from "astralis-ui";
export function ThemeToggleVariants() {
return (
<HStack gap="3" wrap="wrap" justifyContent="center">
<ThemeToggle variant="solid" />
<ThemeToggle variant="subtle" />
<ThemeToggle variant="outline" />
<ThemeToggle variant="text" />
<ThemeToggle variant="subtle" colorScheme="purple" showLabel />
<ThemeToggle variant="outline" colorScheme="gray" rounded="full" />
</HStack>
);
}Reading the theme yourself#
For custom controls, the same context is available via the useTheme hook:
import { useTheme } from "astralis-ui";
function CustomSwitch() {
const { theme, resolvedTheme, setTheme } = useTheme();
// theme: "light" | "dark" | "system" — the user's setting
// resolvedTheme: "light" | "dark" — what's actually applied
return (
<button onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}>
Switch to {resolvedTheme === "dark" ? "light" : "dark"}
</button>
);
}Props#
Theme Toggle accepts every Button prop except
children and onClick (it owns both). The most relevant:
| Prop | Type | Default | Description |
|---|---|---|---|
showLabel | boolean | false | Shows a text label next to the icon — “Light Mode” or “Dark Mode”, reflecting what a click switches to. |
variant | "solid" | "subtle" | "surface" | "outline" | "text" | "link" | "outline" | Inherited from Button — every Button variant works. |
size | "xs" | "sm" | "md" | "lg" | "xl" | "md" | Inherited from Button; the icon scales with it. |
Accessibility#
- Without a label it carries
aria-label="Toggle theme"automatically; withshowLabelthe visible text is the accessible name. - Must be rendered inside an
AstralisProvider—useThemethrows otherwise.