Installation
terminal
npx shadcn@latest add https://ui.thilina.dev/r/theme-toggle.jsonUsage
Requires next-themes with the class attribute strategy:
app/layout.tsx
import { ThemeProvider } from "next-themes";
export default function RootLayout({ children }) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
{children}
</ThemeProvider>
</body>
</html>
);
}components/header.tsx
import { ThemeToggle } from "@/components/theme-toggle";
export function Header() {
return <ThemeToggle />;
}The incoming theme sweeps across the page on a diagonal clip-path riding the View Transitions API. The sun/moon swap is CSS-only, so the button renders correctly during SSR without a mounted check.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Classes merged onto the button. |
Accessibility
The button carries aria-label="Switch theme" and a visible focus ring.
Browsers without the View Transitions API switch instantly, and
prefers-reduced-motion zeroes the sweep so the theme just flips.