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/APITypeDefaultDescription
value`"light""dark""system"`
defaultValue`"light""dark""system"`
onValueChange(value: ThemeSwitcherValue) => void-Called after a menu option is selected.
optionsreadonly ThemeSwitcherOption[]Light, Dark, SystemConfigures available modes, menu order, labels, and optional icons.
size`"sm""md""lg"`
showIconbooleantrueShows the current theme icon.
showLabelbooleantrueShows the current theme label.
aria-labelstringgenerated for icon-only useOverrides the trigger's accessible name.
trigger propsDropdownMenuTrigger 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.

On this page