🌙 Theme Toggle Module
A comprehensive dark mode solution with theme provider and multiple toggle variants.
Multiple Variants
Simple toggle and dropdown with system detection
Theme Provider
Complete theme management with persistence
System Detection
Automatic system theme detection and sync
Smooth Transitions
Beautiful animations and icon transitions
npx shadcn@latest add "https://supremetoolkit.in/r/theme-toggle"
This installs:
- • ThemeProvider component for app-wide theme management
- • ThemeToggle component with sun/moon icons
- • ThemeToggleDropdown with Light/Dark/System options
- • Complete theme configuration and CSS variables
- • Required dependencies (next-themes)
No Environment Variables Required
The theme toggle module works out of the box with no additional configuration needed. Just install and add to your layout!
1. Add ThemeProvider to your layout:
// app/layout.tsx
import { ThemeProvider } from '@/components/theme-provider';
export default function RootLayout({ children }) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
</ThemeProvider>
</body>
</html>
);
}
2. Add theme toggle to your navigation:
// components/navigation.tsx
import { ThemeToggleDropdown } from '@/components/ui/theme-toggle-dropdown';
// or
import { ThemeToggle } from '@/components/ui/theme-toggle';
export function Navigation() {
return (
<nav className="flex items-center justify-between p-4">
<div>Your Logo</div>
<div className="flex items-center space-x-4">
<ThemeToggleDropdown />
{/* or <ThemeToggle /> for simple toggle */}
</div>
</nav>
);
}
3. Ensure your CSS supports dark mode:
Make sure your global CSS includes dark mode variables. If using shadcn/ui, this is already configured.
/* globals.css */
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
/* ... other light theme variables */
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
/* ... other dark theme variables */
}
Important: suppressHydrationWarning
Always add suppressHydrationWarning
to your html element to prevent hydration warnings when the theme is determined client-side.
ThemeToggle
Simple sun/moon toggle button with smooth transitions
<ThemeToggle />
ThemeToggleDropdown
Advanced dropdown with Light, Dark, and System options
<ThemeToggleDropdown />
Simple theme toggle:
import { ThemeToggle } from "@/components/ui/theme-toggle";
export default function Header() {
return (
<header className="flex items-center justify-between p-4">
<h1>My App</h1>
<ThemeToggle />
</header>
);
}
Dropdown theme toggle:
import { ThemeToggleDropdown } from "@/components/ui/theme-toggle-dropdown";
export default function Navigation() {
return (
<nav className="flex items-center gap-4">
<a href="/home">Home</a>
<a href="/about">About</a>
<ThemeToggleDropdown />
</nav>
);
}
Usage
1. Add the theme provider to your layout
// app/layout.tsx
import { ThemeProvider } from "@/components/theme-provider";
export default function RootLayout({ children }) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
</ThemeProvider>
</body>
</html>
);
}
2. Use the toggle components
import { ThemeToggle } from "@/components/ui/theme-toggle";
import { ThemeToggleDropdown } from "@/components/ui/theme-toggle-dropdown";
export default function Navigation() {
return (
<nav className="flex items-center justify-between p-4">
<div>Your Logo</div>
<div className="flex items-center space-x-4">
{/* Simple toggle */}
<ThemeToggle />
{/* Or dropdown toggle */}
<ThemeToggleDropdown />
</div>
</nav>
);
}
API Reference
ThemeProvider
Wrap your app with the theme provider to enable theme management.
Prop | Type | Default | Description |
---|---|---|---|
attribute | string | "class" | HTML attribute to use for theme |
defaultTheme | string | "system" | Default theme ("light" | "dark" | "system") |
enableSystem | boolean | true | Enable system theme detection |
disableTransitionOnChange | boolean | false | Disable CSS transitions during theme change |
ThemeToggle
Simple toggle button that switches between light and dark themes.
ThemeToggleDropdown
Advanced dropdown with all theme options including system preference.
Examples
Custom Hook Usage
import { useTheme } from "next-themes";
export function CustomComponent() {
const { theme, setTheme, systemTheme } = useTheme();
return (
<div>
<p>Current theme: {theme}</p>
<p>System theme: {systemTheme}</p>
<button onClick={() => setTheme('dark')}>
Switch to Dark
</button>
</div>
);
}
Conditional Rendering
import { useTheme } from "next-themes";
export function ThemedContent() {
const { theme } = useTheme();
return (
<div>
{theme === 'dark' ? (
<p>🌙 Dark mode is active</p>
) : (
<p>☀️ Light mode is active</p>
)}
</div>
);
}
Theme Aware Component
import { ThemeAware } from "@/components/ui/theme-aware";
export function Example() {
return (
<ThemeAware
light={<span>☀️ Light mode content</span>}
dark={<span>🌙 Dark mode content</span>}
system={<span>🖥️ System mode content</span>}
/>
);
}
useThemeAware Hook
import { useThemeAware } from "@/components/ui/theme-aware";
export function Example() {
const { isDark, isLight, isSystem, resolvedTheme } = useThemeAware();
return (
<div className={isDark ? 'bg-black text-white' : 'bg-white text-black'}>
<p>Current theme: {resolvedTheme}</p>
<p>Is dark: {isDark ? 'Yes' : 'No'}</p>
<p>Is system: {isSystem ? 'Yes' : 'No'}</p>
</div>
);
}