# Theme Toggles

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

Theme toggle

[Complete TSX file](/examples/theme-toggles/default.tsx)

```tsx
"use client";

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

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

## Installation

Complete [one-time setup](/docs/installation/) first.

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

With npm: `npx shadcn@4.18.0 add @siteplane/theme-toggles`. [Registry JSON](/registry/theme-toggles.json) lists source files and dependencies.

## Usage

```tsx
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](/docs/customization/theming/#application-wide-dark-mode) shows the complete provider. Both toggles show the sun in light mode and the moon in dark mode.

Controlled theme toggle with layered icons

[Complete TSX file](/examples/theme-toggles/controlled.tsx)

```tsx
"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`.

Theme toggle sizes

[Complete TSX file](/examples/theme-toggles/sizes.tsx)

```tsx
"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

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| pressed / defaultPressed | boolean | false | Controlled or initial state; true means dark mode and shows the moon. checked and defaultChecked are deprecated aliases. |
| onPressedChange | (pressed: boolean, eventDetails) => void | unset | Toggle’s pressed callback. onCheckedChange is a deprecated alias. |
| size | sm \| md \| lg \| xl | provider / lg | Control/icon size. |
| aria-label | string | Dark mode | Accessible name. |
| id | string | generated for SunMoon; unset for Layered | Button ID; SunMoon also derives an SVG mask ID. |
| className | string | unset | Styles the outer span. |
| disabled | boolean | false | Prevents 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](/source/theme-toggles).

## 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.
