Color Mode Switcher

An icon-only pill control for switching between system, light, and dark colour modes.

<ColorModeSwitcher />

Usage

import { ColorModeSwitcher } from "@reva/ui";
<ColorModeSwitcher />

The control binds directly to the app's next-themes context, so it needs the tree to be wrapped in ThemeProvider (exported from @reva/ui) with enableSystem. Selecting a segment calls setTheme immediately — there is no controlled value API. Where the browser supports the View Transitions API, the switch cross-fades the whole page; reduced-motion users and older browsers get the instant swap. The selected segment reflects the stored preference (including System), not the resolved scheme, so System stays selected when the operating system flips between light and dark.

It is a thin wrapper over SegmentedControl in control-only usage: the pill shape, icon set, bold icon weight, and per-segment tooltips (shared 1s delay) are baked in, and the raised active indicator follows the pill radius. Selecting a mode on this page switches the docs site's theme — the same effect as the D shortcut.

Examples

In a header row

The intended habitat: pinned to the trailing edge of a brand or page-header row.

Whitfield Wealth

<Flex align="center" className="w-full max-w-md" justify="between">  <Heading size="lg">Whitfield Wealth</Heading>  <ColorModeSwitcher /></Flex>

Accessibility

  • Each icon-only segment reveals a tooltip after a 1s hover (moving between segments skips the delay) and carries a matching aria-label — Use system theme, Switch to light mode, Switch to dark mode — so the visible and announced names stay in lockstep. The control itself is a Radix tablist: Arrow keys move between segments (tooltips also show on keyboard focus) and the active segment is announced as selected.
  • The raised indicator's slide respects prefers-reduced-motion (it snaps instead of springing), matching SegmentedControl.

Props

ColorModeSwitcher renders a SegmentedControl root and accepts its props, except the selection trio it owns (value, defaultValue, onValueChange) and children.

PropTypeDefaultDescription
classNamestringMerged onto the root (default w-fit).

On this page