Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Theme Selector Dropdown Menu for React

A theme picker behind a palette button, offering Light, Dark and System, with one of them checked.

A palette button opens Light, Dark, and System under Theme, each with its own icon. The demo starts on System and only stores the value.

Use it when the theme is a single choice in a navbar. Picking a row does not change the page. A choice that should stay visible can be a Select. In React, Base UI does not toggle the document theme.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

Anatomy

Dropdown Menu anatomy: trigger, label, item, shortcut, separator, sub trigger, content

Usage

<DropdownMenu>
  <DropdownMenuTrigger
    render={<Button aria-label="Theme" size="icon-md" variant="outline" />}
  >
    <PaletteIcon aria-hidden="true" />
  </DropdownMenuTrigger>
  <DropdownMenuContent className="w-48">
    <DropdownMenuRadioGroup onValueChange={setTheme} value={theme}>
      <DropdownMenuLabel>Theme</DropdownMenuLabel>
      <DropdownMenuSeparator />
      <DropdownMenuRadioItem value="light">
        <SunIcon aria-hidden="true" />
        Light
      </DropdownMenuRadioItem>
      <DropdownMenuRadioItem value="dark">
        <MoonIcon aria-hidden="true" />
        Dark
      </DropdownMenuRadioItem>
      <DropdownMenuRadioItem value="system">
        <MonitorIcon aria-hidden="true" />
        System
      </DropdownMenuRadioItem>
    </DropdownMenuRadioGroup>
  </DropdownMenuContent>
</DropdownMenu>

FAQ

How is the theme choice stored?

As one value, system to start: light, dark or system. Picking a row stores it and moves the check. DropdownMenuRadioGroup takes value, and onValueChange receives the new value.

Which icon is on each row?

A sun for Light, a moon for Dark and a monitor for System, aria-hidden before the label.

What does the trigger look like?

An outline Button with size="icon-md", a palette icon and aria-label set to Theme. The menu is w-48.

Does picking a row change the document theme?

No. The demo only stores the value. Apply it yourself: toggle the dark class on the root element, and for System follow the prefers-color-scheme media query.

Can I change the theme from the keyboard?

Yes. Open the menu with Enter, Space or Arrow Down, move with the arrow keys or type the first letter, and press Enter to pick. Escape closes the menu.

Is Theme a choice?

No. It's the DropdownMenuLabel that names the group, followed by a separator, and it can't be focused.

API Reference

Dropdown Menu

Sets onValueChange={setTheme}, value={theme}, value="light", value="dark" and value="system". The rest is on the Dropdown Menu page.

Button

Sets aria-label="Theme", size="icon-md" and variant="outline". The rest is on the Button page.