Theme Switcher
A light/dark/system theme toggle. Comes in two variants: a dropdown listing all three options and a compact icon-only toggle. Requires next-themes ThemeProvider in the root layout.
Dropdown (left) · Icon toggle (right)
import { ThemeSwitcher } from "@aetherstack/patterns"
Installation
terminal
npx aether-ui add theme-switcherImport
import.tsx
import { ThemeSwitcher, ThemeSwitcherToggle, ThemeSwitcherDropdown } from "@aetherstack/patterns"Usage
theme-switcher.tsx
// In layout.tsx — wrap the app with ThemeProvider
import { ThemeProvider } from "next-themes"
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html suppressHydrationWarning>
<body>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
{children}
</ThemeProvider>
</body>
</html>
)
}
// In your navigation bar
import { ThemeSwitcherDropdown, ThemeSwitcherToggle } from "@aetherstack/patterns"
export function Navbar() {
return (
<nav>
{/* compact icon-only toggle */}
<ThemeSwitcherToggle />
{/* or a dropdown with light / dark / system options */}
<ThemeSwitcherDropdown />
</nav>
)
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| — | — | — | ThemeSwitcherDropdown and ThemeSwitcherToggle take no required props. They read and write the active theme via next-themes internally. |
| className | string | — | Additional classes on the trigger button (both variants). |
* Required
Accessibility
- →Each button carries an aria-label describing the action ("Toggle theme" or the active theme name).
- →The dropdown uses role="menu" with radio-style aria-checked items for each theme option.
- →Active theme is communicated via aria-checked="true" on the selected menu item.
- →Icons are aria-hidden; labels are the sole source of accessible name.