ThemeSwitcher
Theme menu trigger for selecting light, dark, or system appearance.
Quick Preview
Select a mode to update the scoped preview surface.
Selected theme: light
Usage
The component owns its menu and selection UI. The application remains responsible for applying and persisting the selected theme.
import {
ThemeSwitcher,
type ThemeSwitcherValue,
} from "@giddaa-housing/ui/theme-switcher";
const [theme, setTheme] = useState<ThemeSwitcherValue>("system");
<ThemeSwitcher value={theme} onValueChange={setTheme} />;For an uncontrolled selector, use defaultValue:
<ThemeSwitcher defaultValue="system" />Configure the available modes, their order, labels, and icons with options:
const options = [
{ value: "dark", label: "Night", icon: <MoonStarIcon /> },
{ value: "system", label: "Automatic", icon: <LaptopIcon /> },
] as const;
<ThemeSwitcher options={options} defaultValue="dark" />Examples
Sizes and visible parts
The Figma sizes are 32px, 40px, and 48px. The chevron remains visible when the leading icon or label is hidden.
Small
Medium
Large
Icon only
Label only
Custom options
Props
| Prop/API | Type | Default | Description |
|---|---|---|---|
value | `"light" | "dark" | "system"` |
defaultValue | `"light" | "dark" | "system"` |
onValueChange | (value: ThemeSwitcherValue) => void | - | Called after a menu option is selected. |
options | readonly ThemeSwitcherOption[] | Light, Dark, System | Configures available modes, menu order, labels, and optional icons. |
size | `"sm" | "md" | "lg"` |
showIcon | boolean | true | Shows the current theme icon. |
showLabel | boolean | true | Shows the current theme label. |
aria-label | string | generated for icon-only use | Overrides the trigger's accessible name. |
| trigger props | DropdownMenuTrigger props | - | Passed to the accessible menu trigger. |
Integration
ThemeSwitcher deliberately does not mutate <html>, access storage, or depend on
a particular theme provider. Connect onValueChange to the theme solution used by
your application. For scoped Giddaa themes, apply .light or .dark to the desired
ancestor; system mode should follow the application's operating-system preference.
Accessibility
- The trigger and radio menu support keyboard navigation and selection through the shared menu primitive.
- A check icon and radio semantics identify the selected option without relying on color.
- Keep either the visible label or an
aria-label; icon-only mode generates an accessible name automatically.