Siteplane UI

Theme Toggles

Switch between light and dark mode with an animated sun and moon toggle.

Markdown
"use client";

import { SunMoonMorphToggle } from "@/siteplane/components/theme-toggles";

export default function Example() {
  return <SunMoonMorphToggle />;
}

Installation

pnpm dlx shadcn@4.18.0 add @siteplane/theme-toggles

Complete the one-time setup first. Registry JSON lists source files and dependencies.

Usage

import { SunMoonMorphToggle } from "@/siteplane/components/theme-toggles";

<SunMoonMorphToggle />;

Application theme

Pass your resolved theme to pressed (true for dark) and switch themes in onPressedChange; application-wide dark mode shows the complete provider. Both toggles show the sun in light mode and the moon in dark mode.

"use client";

import { LayeredThemeToggle } from "@/siteplane/components/theme-toggles";
import { useState } from "react";

export default function Example() {
  const [dark, setDark] = useState(false);
  return <LayeredThemeToggle onPressedChange={setDark} pressed={dark} />;
}

Sizes

size accepts sm, md, lg, and xl; without it, the toggle follows SiteplaneUIProvider.

"use client";

import { SunMoonMorphToggle } from "@/siteplane/components/theme-toggles";

export default function Example() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      {(["sm", "md", "lg", "xl"] as const).map((size) => (
        <SunMoonMorphToggle key={size} size={size} />
      ))}
    </div>
  );
}

API reference

Component properties
PropTypeDefaultDescription
pressed / defaultPressedbooleanfalseControlled or initial state; true means dark mode and shows the moon. checked and defaultChecked are deprecated aliases.
onPressedChange(pressed: boolean, eventDetails) => voidunsetToggle’s pressed callback. onCheckedChange is a deprecated alias.
sizesm | md | lg | xlprovider / lgControl/icon size.
aria-labelstringDark modeAccessible name.
idstringgenerated for SunMoon; unset for LayeredButton ID; SunMoon also derives an SVG mask ID.
classNamestringunsetStyles the outer span.
disabledbooleanfalsePrevents interaction.

SunMoonMorphToggleProps and LayeredThemeToggleProps extend Toggle props without children or size. Both render a borderless, square icon toggle; other native button attributes pass through. The shared ThemeToggleInputProps type is internal.

Read the installed source.

Usage notes

Keep theme choice synchronized with your app provider, including portaled overlays. A pressed visual alone does not apply dark mode. Keep the accessible name constant; aria-pressed reports whether dark mode is on. Keyboard and reduced-motion behavior come from Toggle and the recipe styles.