Skip to content
Template Empire / components

Search components

10 results

Browse components

Sun Moon Morph

A free React theme toggle where the sun morphs into a crescent moon.

  • Automated axe check
  • Reduced-motion tested
  • SSR build verified
  • Motion
  • 1 runtime package

Sun Moon Morph is a free React theme toggle for Next.js, styled with Tailwind, that switches between light and dark mode with a spring-physics morph: eight sun rays retract with a 20ms stagger while a mask circle slides in to carve the sun's core into a crescent moon. It is a real button with aria-pressed and an accessible name that announces the action, so it works as a drop-in dark mode switch.

The component is fully controlled: you pass the current theme and receive the next one in onToggle, so persistence, system preference detection and next-themes wiring stay in your app. Only SVG transforms and opacity ever animate, the button box never changes size, and reduced-motion users get an instant icon swap instead of the morph.

Pick your side of the sky

Currently in dark mode.

This panel carries its own scoped theme. The toggle is a controlled button, so your app decides where the theme lives: local state, next-themes or anything else.

Customise

Component settings update the preview and generated code together.

Appearance

40px

Behaviour

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/theme-sun-moon

Usage

"use client";

import { useState } from "react";

import { ThemeSunMoon } from "@/components/ui/theme-sun-moon";

export default function Page() {
  const [theme, setTheme] = useState<"light" | "dark">("dark");

  return <ThemeSunMoon theme={theme} onToggle={setTheme} />;
}

Props

PropTypeDefaultDescription
theme"light" | "dark"requiredControlled current theme.
onToggle(next: "light" | "dark") => voidrequiredCalled with the next theme when the button is activated.
sizenumber40Button size in px. The box is fixed; only the icon animates inside it.
classNamestringundefinedAdditional classes merged onto the button.

Customisation

The toggle consumes the semantic tokens directly: the disc uses bg-background, the icon uses text-foreground via currentColor, and the focus ring uses the ring token. Restyle it by merging utilities through className, for example a brand-coloured icon on a borderless button, and scale it with the size prop.

<ThemeSunMoon
  theme={theme}
  onToggle={setTheme}
  size={48}
  className="border-none text-primary"
/>

Frequently asked questions

Is Sun Moon Morph free for commercial use?
Yes. Sun Moon Morph is MIT licensed, so you can use it in personal and commercial projects without attribution.
Is Sun Moon Morph accessible and performant?
Yes. It renders a real button with aria-pressed reflecting the dark state and an accessible name that announces the action, updated per state, with a visible focus ring. The SVG is decorative and hidden from assistive technology. The morph animates only SVG transforms and opacity inside a fixed button box, so there is no layout shift, and users who prefer reduced motion get an instant opacity swap with no morph or stagger.
How do I customise the Sun Moon Morph toggle?
Use the size prop to scale the button and pass Tailwind utilities through className to change the disc, border or icon colour. The icon inherits currentColor, so a class such as text-primary retints the whole sun and moon while the semantic tokens keep both themes readable.
Does Sun Moon Morph work with next-themes or my own theme state?
Yes. The component is fully controlled through the theme and onToggle props and stores nothing itself. Wire it to useState for a scoped section, or pass the values from next-themes or any context provider to switch your whole app, including persistence and system preference detection handled by your store.

Related components

Want the full page this belongs to?Template Empire builds complete Next.js templates with this motion system throughout. Browse the paid templates that pair with these free components.Explore Template Empire templates