Theme Toggle Button
Animated dark mode switch with View Transitions API. Beautiful theme toggles for React applications with multiple animation effects and Next.js integration.
Powered by
Installation
npx shadcn@latest add https://www.shadcn.io/registry/theme-toggle-button.json
npx shadcn@latest add https://www.shadcn.io/registry/theme-toggle-button.json
pnpm dlx shadcn@latest add https://www.shadcn.io/registry/theme-toggle-button.json
bunx shadcn@latest add https://www.shadcn.io/registry/theme-toggle-button.json
Features
- Multiple animation variants including circle, blur, polygon and custom GIF masks
- View Transitions API for smooth, hardware-accelerated theme switching
- Flexible positioning with animations starting from center, corners, or edges
- TypeScript support with complete interface definitions and IntelliSense
- Accessible controls with proper ARIA labels and keyboard navigation
- Framework agnostic works with any theme management solution
Use Cases
This free open source React component works well for:
- Dark mode toggles - Elegant theme switching for Next.js applications
- Settings interfaces - Beautiful preference controls using Tailwind CSS
- Navigation bars - Eye-catching theme buttons with shadcn/ui integration
- Landing pages - Memorable user experiences with custom animations
Usage
import {
ThemeToggleButton,
useThemeTransition,
} from "@/components/theme-toggle-button";
import { useTheme } from "next-themes";
export default function Example() {
const { theme, setTheme } = useTheme();
const { startTransition } = useThemeTransition();
const handleToggle = () => {
const newTheme = theme === "light" ? "dark" : "light";
startTransition(() => {
setTheme(newTheme);
});
};
return <ThemeToggleButton theme={theme} onClick={handleToggle} />;
}
Examples
Basic Usage
The default variant uses a circle animation from the center:
<ThemeToggleButton theme={theme} onClick={handleToggle} />
With Label
Show a text label alongside the icon:
<ThemeToggleButton theme={theme} onClick={handleToggle} showLabel />
Animation Variants
Circle Animation
The circle variant creates an expanding circle mask effect:
// From center (default)
<ThemeToggleButton
theme={theme}
onClick={handleToggle}
variant="circle"
/>
// From corners
<ThemeToggleButton
theme={theme}
onClick={handleToggle}
variant="circle"
start="top-left"
/>
<ThemeToggleButton
theme={theme}
onClick={handleToggle}
variant="circle"
start="bottom-right"
/>
Circle with Blur
Adds a gaussian blur to the circle edge for a softer transition:
<ThemeToggleButton
theme={theme}
onClick={handleToggle}
variant="circle-blur"
start="top-right"
/>
Polygon Animation
Creates a diagonal wipe effect using clip-path:
<ThemeToggleButton theme={theme} onClick={handleToggle} variant="polygon" />
Custom GIF Animation
Use any GIF as a mask for the transition:
<ThemeToggleButton
theme={theme}
onClick={handleToggle}
variant="gif"
url="https://media.giphy.com/media/your-gif-id/giphy.gif"
/>
API Reference
ThemeToggleButton
Prop | Type | Default | Description |
---|---|---|---|
theme | 'light' | 'dark' | 'light' | Current theme state |
showLabel | boolean | false | Show text label next to icon |
variant | 'circle' | 'circle-blur' | 'gif' | 'polygon' | 'circle' | Animation variant to use |
start | 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'center' | Starting position for circle animations |
url | string | undefined | URL of GIF to use as mask (required for gif variant) |
className | string | undefined | Additional CSS classes |
onClick | () => void | undefined | Click handler for theme toggle |
Hooks
useThemeTransition
A helper hook that wraps the View Transitions API:
const { startTransition } = useThemeTransition();
// Use it to wrap your theme update
startTransition(() => {
setTheme(newTheme);
// Any other DOM updates
});
This hook automatically falls back to immediate updates in browsers that don't support the View Transitions API.
Browser Support
The View Transitions API is supported in:
- Chrome/Edge 111+ with full animation support
- Opera 97+ with complete feature set
- Safari with flag enabled in Settings > Advanced > Feature Flags > View Transitions
- Firefox not yet supported, gracefully falls back
Note: To see the animations, make sure you're using a supported browser. In Safari, you need to enable the View Transitions flag manually.
Implementation Notes
- Component is UI-only, theme management handled externally
- Animations inject CSS dynamically for optimal performance
- Works with any theme solution (next-themes, custom context, etc.)
- All animations use hardware acceleration when available
- Cleanup handled automatically after transitions complete
Pixel Image
Pixelated image reveal component for React and Next.js applications. Built with TypeScript support, Tailwind CSS styling, and shadcn/ui design featuring grid animations, grayscale transitions, and customizable timing.
Counting Number
Animated counting number with spring transitions and in-view detection. Perfect for React applications requiring smooth number animations with Next.js integration and TypeScript support.