ThemeSwitcher
A dropdown menu component that allows users to switch between color themes and toggle between light/dark modes. Built with shadcn/ui components and fully integrated with next-themes.Located in
registry/nextjs/components/theme-switcher.tsxComponent Signature
Props
This component accepts no props. All configuration is handled internally through theuseTheme hook.
Features
- Dual Theme Controls: Separate controls for color theme and light/dark mode
- Visual Theme Previews: Color dots showing each theme’s primary color
- Current Theme Indicator: Check marks on active selections
- Scrollable Theme List: Smooth scrolling for 45+ themes
- SSR Safe: Prevents hydration mismatches with mounted state
- Keyboard Accessible: Full keyboard navigation support
Usage
UI Structure
Trigger Button
Ghost variant icon button (9×9) displaying Sun (light mode) or Moon (dark mode) icon.
Dropdown Content
The dropdown menu contains three main sections:1. Current Theme Label
Shows the current theme name with a colored preview dot.
2. Mode Toggle (Light/Dark)
Two items for switching between light and dark modes. Active mode shows a check mark.
3. Color Theme Submenu
Scrollable submenu with all 45 themes, each showing a color preview.
Internal Functions
parseTheme
Helper function to extract color theme and mode from theme string.Theme string like
"catppuccin-dark" or "vercel-light"Theme name without mode suffix (e.g.,
"catppuccin")Extracted mode from theme string, defaults to
"dark"setColorTheme
Sets the color theme while preserving the current mode.setMode
Sets the light/dark mode while preserving the current color theme.Hydration Safety
The component uses amounted state to prevent hydration mismatches:
Dependencies
Required Components (shadcn/ui)
Button- Trigger button componentDropdownMenu- Main menu containerDropdownMenuContent- Menu content wrapperDropdownMenuItem- Individual menu itemsDropdownMenuLabel- Menu section labelsDropdownMenuSeparator- Visual dividersDropdownMenuSub- Nested submenuDropdownMenuSubTrigger- Submenu triggerDropdownMenuSubContent- Submenu contentDropdownMenuPortal- Portal for submenu renderingScrollArea- Scrollable theme list
Required Icons (lucide-react)
Sun- Light mode iconMoon- Dark mode iconPalette- Theme picker iconCheck- Active selection indicator
Required Utilities
useThemefromnext-themes- Theme state managementcnfrom@/lib/utils- Class name utilitysortedThemesfrom@/lib/themes-config- Sorted theme listthemesfrom@/lib/themes-config- Theme configurations
Styling
The component uses Tailwind CSS classes and is fully customizable:Accessibility
- Screen Reader Support: Trigger button includes
<span class="sr-only">Toggle theme</span> - Keyboard Navigation: Full keyboard support via DropdownMenu
- Visual Indicators: Check marks for active selections
- Color Previews: Visual dots help users identify themes
Advanced Customization
Custom Button Styling
Wrap and style the component:Fork for Custom Behavior
Copy and modify the component to:- Filter visible themes
- Add custom theme groupings
- Change icon sets
- Modify menu structure
theme-switcher-custom.tsx
See Also
- useTheme - Theme state hook
- ThemeProvider - Provider setup
- sortedThemes - Sorted theme list
- ThemeConfig - Theme object structure