🌙 Theme Toggle Module

A comprehensive dark mode solution with theme provider and multiple toggle variants.

✨ Features
Toggle

Multiple Variants

Simple toggle and dropdown with system detection

Provider

Theme Provider

Complete theme management with persistence

System

System Detection

Automatic system theme detection and sync

Smooth

Smooth Transitions

Beautiful animations and icon transitions

🚀 Installation
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)
🔧 Setup Instructions

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.

🎨 Preview
Simple Toggle
Clean sun/moon toggle with smooth icon transitions
Dropdown Toggle
Advanced dropdown with Light, Dark, and System options
📦 What's Included

ThemeToggle

Simple sun/moon toggle button with smooth transitions

<ThemeToggle />

ThemeToggleDropdown

Advanced dropdown with Light, Dark, and System options

<ThemeToggleDropdown />
🔧 Usage Examples

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.

PropTypeDefaultDescription
attributestring"class"HTML attribute to use for theme
defaultThemestring"system"Default theme ("light" | "dark" | "system")
enableSystembooleantrueEnable system theme detection
disableTransitionOnChangebooleanfalseDisable CSS transitions during theme change

ThemeToggle

Simple toggle button that switches between light and dark themes.

No propsAnimated iconsAccessible

ThemeToggleDropdown

Advanced dropdown with all theme options including system preference.

No propsLight/Dark/SystemSSR safe

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> ); }