Next Themes

@natu/next-themes

Easy to use themes (dark, light, and custom)

Themes' support for Next.js done using the external next-themes ↗ (opens in a new tab) package.

Usage

To use this package in the app import this package as a dependency in its individual package.json file:

"dependencies": {
  "@natu/next-themes": "*",
}

Then use the ThemeProvider:

Providers.tsx
import { ReactNode } from 'react';
import { ThemeProvider } from '@natu/next-themes';
 
interface ProvidersProps {
  children?: ReactNode;
}
 
export const Providers = ({ children }: ProvidersProps) => (
  <ThemeProvider attribute="class" defaultTheme={'system'} enableSystem disableTransitionOnChange>
    {children}
  </ThemeProvider>
);

And ThemeModeSwitcher component which handles the theme switching for users:

Navigation.tsx
import { ThemeModeSwitcher } from '@natu/next-themes';
 
export const Navigation = ({ children }: Props) => (
  <nav>
    {children}
    <ThemeModeSwitcher />
  </nav>
);
ℹ️

More infromation can be found in the next-themes documentation ↗ (opens in a new tab).

API Reference

ThemeProvider

Props are the same as in the next-themes documentation (opens in a new tab).

ThemeModeSwitcher

All props provided to this component, will be added to the parent DropdownMenu.

ThemeModeSwitcher.tsx
'use client';
 
import { Moon, Sun } from 'lucide-react';
import { useTheme } from 'next-themes';
 
import {
  Button,
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@natu/ui';
 
export const ThemeModeSwitcher = ({ ...rest }) => {
  const { setTheme } = useTheme();
 
  return (
    <DropdownMenu {...rest}>
      <DropdownMenuTrigger asChild>
        <Button className="rounded-lg" variant="outline" size="icon">
          <Sun className="h-5 w-5 rotate-0 text-black scale-100 transition-all dark:-rotate-90 dark:scale-0" />
          <Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
          <span className="sr-only">Toggle theme</span>
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        <DropdownMenuItem onClick={() => setTheme('light')}>Light</DropdownMenuItem>
        <DropdownMenuItem onClick={() => setTheme('dark')}>Dark</DropdownMenuItem>
        <DropdownMenuItem onClick={() => setTheme('system')}>System</DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  );
};