DHxWhy

Sun Moon Dark Mode Theme Toggle

Component 183

About

Animated dark mode toggle for React and Tailwind CSS (shadcn/ui): a sun and moon swap inside a tiny sky. It is built to turn a utility switch into a small moment of delight: the sun and moon show the current mode at a glance, and the slow, rewindable motion invites people to flip it just to watch. The moon starts slow, then swoops off to the lower left while a starry night cross-fades into a blue day and the sun pops up from the lower right; dark mode plays it in reverse, and clicking mid-flight rewinds it. Toggles the .dark class while the page colors fade over the same duration, syncs with other toggles, persists to localStorage, respects reduced motion.

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Sun Moon Dark Mode Theme Toggle to your project and fits it to your theme.

Code

How Sun Moon Dark Mode Theme Toggle is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

"use client";

import * as React from "react";
import { SunMoonThemeToggle } from "@/components/ui/sun-moon-theme-toggle";

const settings = {
  size: 50,
  duration: 1740,
  autoplay: true,
  sky: true,
};

const CCGATHER_URL = "https://ccgather.com/?utm_source=21st&utm_medium=component&utm_campaign=theme_toggle";

export default function Demo(props: Partial<typeof settings>) {
  const s = { ...settings, ...props };
  const toggleRef = React.useRef<HTMLButtonElement>(null);

  React.useEffect(() => {
    const button = toggleRef.current;
    if (!s.autoplay || !button) return;
    const timers = [900, 900 + s.duration + 1400].map((delay) => window.setTimeout(() => button.click(), delay));
    const stop = () => timers.forEach((timer) => window.clearTimeout(timer));
    window.addEventListener("pointerdown", stop, { once: true });
    window.addEventListener("keydown", stop, { once: true });
    return () => {
      stop();
      window.removeEventListener("pointerdown", stop);
      window.removeEventListener("keydown", stop);
    };
  }, [s.autoplay, s.duration]);

  return (
    <div className="flex min-h-screen w-full flex-col items-center justify-center gap-5 bg-background p-6">
      <SunMoonThemeToggle ref={toggleRef} size={s.size} duration={s.duration} sky={s.sky} />
      <div className="space-y-1 text-center">
        <p className="text-sm font-medium text-foreground">The moon sets, the sun rises</p>
        <p className="text-xs text-muted-foreground">
          Theme toggle from the{" "}
          <a
            href={CCGATHER_URL}
            target="_blank"
            rel="noreferrer"
            className="underline underline-offset-4 transition-colors hover:text-foreground"
          >
            CCgather
          </a>{" "}
          header
        </p>
      </div>
    </div>
  );
}

Dependencies

More by DHxWhy

View all
  • Country Flags Globe

    Country Flags Globe

    109
  • Live Notification Feed

    Live Notification Feed

    108
  • Airplane Window Gallery

    Airplane Window Gallery

    94
  • Domino Scroll Image Gallery

    Domino Scroll Image Gallery

    93
  • QR Code Scan Login Form with Password Fallback

    QR Code Scan Login Form with Password Fallback

    81
  • Constellation Image Gallery

    Constellation Image Gallery

    79
  • Ferris Wheel Image Gallery

    Ferris Wheel Image Gallery

    71
  • What's New Changelog Timeline

    What's New Changelog Timeline

    69