Charcoal UI

Theme Toggle

The sun eclipses into a moon, and the new theme spreads from the button as a circle.

  • Category: Display
  • Licence: Free, MIT
  • Built with: React 19, Tailwind CSS 4, Motion
  • Dependencies: motion, clsx, tailwind-merge

Examples

Theme Toggle

API reference

PropTypeDefaultDescription
theme"light" | "dark"—Omit to let the toggle manage the <html> class.
onThemeChange(theme) => void—
revealbooleantrueCircular reveal via View Transitions.
storageKeystring"charcoal-theme"

About Theme Toggle

Theme Toggle switches light and dark mode with a sun that eclipses into a moon, and the new theme spreads out from the button as a circle. It makes a dark mode switch feel delightful.

Theme Toggle is a display component for React 19, styled with Tailwind CSS 4 and animated with Motion. It drops into Next.js, Vite, Remix or Astro through the shadcn CLI as a single file you own.

When to use Theme Toggle

  • Site headers.
  • App settings.
  • Docs sites.
  • Portfolio corners.

How it works

The reveal uses the View Transitions API with a clip-path circle from the button, falling back to an instant switch where unsupported. It is a button with aria-pressed.

Interactive parts are buttons or links with accessible names, decorative layers are hidden from assistive tech, and everything is reachable by keyboard. With prefers-reduced-motion on, it holds still or settles instantly instead of animating.

Customizing Theme Toggle

Every prop is documented in the API reference above with its type and default. The ones you will reach for first are listed here.

The Customize panel next to the preview lets you change reveal, hint live, and the Code tab updates to match, so the snippet you copy already carries your values.

  • theme ("light" | "dark"): Omit to let the toggle manage the <html> class.
  • reveal (boolean, default true): Circular reveal via View Transitions.
  • storageKey (string, default "charcoal-theme").

Goes well with Theme Toggle

Theme Toggle is already composed into a ready-made section, so you can see it in context or install the whole block.

  • Footer Newsletter: Footer section
  • Accordion: An animated React accordion: height springs open, the chevron flips, content fades in
  • Number Ticker: An animated React number ticker: each digit rolls on its own wheel
  • Marquee: A CSS-only infinite React marquee with faded edges and pause on hover
  • Avatar Group: Overlapping React avatars that fan apart on hover with names that spring up
  • Copy Button: A React copy button whose icon blurs into a drawn check, then swaps back

Install Theme Toggle

npx shadcn@latest add https://charcoalui.com/r/theme-toggle.json

Theme Toggle is free and MIT licensed. The command copies theme-toggle.tsx into components/ui and installs clsx, tailwind-merge; you can also copy the source from the Code tab by hand.

It pairs well with Gooey, a Pro piece: Liquid UI: pieces that touch melt into one another and stretch apart like goo, while text and icons stay perfectly crisp. An SVG filter plus springs, so it works with any markup.

Frequently asked questions

How do I install Theme Toggle?
Run npx shadcn@latest add https://charcoalui.com/r/theme-toggle.json. The shadcn CLI copies theme-toggle.tsx into components/ui and installs motion, clsx, tailwind-merge. You can also copy the source from this page by hand.
Is Theme Toggle free for commercial use?
Yes. Theme Toggle is MIT licensed: use it in any personal or commercial project and change it however you like.
Does Theme Toggle work with Next.js?
Yes. It is a client component for React 19 styled with Tailwind CSS 4, so it works in the Next.js App Router and Pages Router, Vite, Remix and Astro.
Can an AI coding agent install Theme Toggle?
Yes. Connect the Charcoal UI MCP server (https://charcoalui.com/mcp) to Claude Code, Cursor or any MCP client; get_component returns Theme Toggle's props and source and get_install_command returns the exact command.

Theme Toggle as Markdown · llms.txt