# Lightbulb Theme Toggle

> An animated theme toggle inspired by a lightbulb.

A shadcn/ui block from the [@toggles](https://toggles.dev) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/toggles/lightbulb).

- Page, with a live preview: https://shadcn.exchange/r/toggles/lightbulb
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/toggles/lightbulb-light-c07506cefee96658.png
- Registry item: https://toggles.dev/r/lightbulb.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://toggles.dev/r/lightbulb.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Files

### `src/Lightbulb.tsx`

```tsx
import { type ButtonHTMLAttributes, type CSSProperties } from "react";

export interface LightbulbProps extends Omit<
  ButtonHTMLAttributes<HTMLButtonElement>,
  "children"
> {
  duration?: number;
  /** Whether the toggle should render in its dark-theme state. */
  toggled?: boolean;
  [key: `data-${string}`]: string | number | boolean | null | undefined;
}

export function Lightbulb({
  duration = 500,
  toggled,
  className,
  type = "button",
  title = "Toggle theme",
  "aria-label": ariaLabel = "Toggle theme",
  "aria-pressed": ariaPressed,
  ...props
}: LightbulbProps) {
  return (
    <button
      {...props}
      type={type}
      title={title}
      aria-label={ariaLabel}
      aria-pressed={toggled ?? ariaPressed}
      className={[
        className,
        toggled === true ? "dark" : toggled === false ? "light" : undefined,
      ]
        .filter(Boolean)
        .join(" ")}
    >
      <svg
        width="1em"
        height="1em"
        viewBox="0 0 32 32"
        aria-hidden="true"
        strokeWidth={"2"}
        stroke={"currentColor"}
        fill={"currentColor"}
        strokeLinecap={"round"}
        style={
          { "--toggles-lightbulb--duration": `${duration}ms` } as CSSProperties
        }
      >
        <path
          strokeWidth={1}
          d={
            "M9.4 9.9c1.8-1.8 4.1-2.7 6.6-2.7 5.1 0 9.3 4.2 9.3 9.3 0 2.3-.8 4.4-2.3 6.1-.7.8-2 2.8-2.5 4.4 0 .2-.2.4-.5.4-.2 0-.4-.2-.4-.5v-.1c.5-1.8 2-3.9 2.7-4.8 1.4-1.5 2.1-3.5 2.1-5.6 0-4.7-3.7-8.5-8.4-8.5-2.3 0-4.4.9-5.9 2.5-1.6 1.6-2.5 3.7-2.5 6 0 2.1.7 4 2.1 5.6.8.9 2.2 2.9 2.7 4.9 0 .2-.1.5-.4.5h-.1c-.2 0-.4-.1-.4-.4-.5-1.7-1.8-3.7-2.5-4.5-1.5-1.7-2.3-3.9-2.3-6.1 0-2.3 1-4.7 2.7-6.5z"
          }
        />
        <path d={"M19.8 27.5h-7.6"} />
        <path d={"M19.8 29.2h-7.6"} />
        <path d={"M19.8 30.9h-7.6"} />
        <path
          pathLength={1}
          fill={"none"}
          d={
            "M14.6 27.1c0-3.4 0-6.8-.1-10.2-.2-1-1.1-1.7-2-1.7-1.2-.1-2.3 1-2.2 2.3.1 1 .9 1.9 2.1 2h7.2c1.1-.1 2-1 2.1-2 .1-1.2-1-2.3-2.2-2.3-.9 0-1.7.7-2 1.7 0 3.4 0 6.8-.1 10.2"
          }
          className="[stroke-dasharray:1.1] motion-safe:transition-[stroke-dashoffset,opacity] motion-safe:duration-(--toggles-lightbulb--duration) [stroke-dashoffset:0] opacity-100 dark:[stroke-dashoffset:1] dark:opacity-0"
        />
        <path
          d={"M16 5V1.3"}
          pathLength={1}
          strokeWidth={1.5}
          className="[stroke-dasharray:1.1] motion-safe:transition-[stroke-dashoffset,opacity] motion-safe:duration-(--toggles-lightbulb--duration) [stroke-dashoffset:0] opacity-100 dark:[stroke-dashoffset:1] dark:opacity-0"
        />
        <path
          d={"M27.5 15.8h3.9"}
          pathLength={1}
          strokeWidth={1.5}
          className="[stroke-dasharray:1.1] motion-safe:transition-[stroke-dashoffset,opacity] motion-safe:duration-(--toggles-lightbulb--duration) [stroke-dashoffset:0] opacity-100 dark:[stroke-dashoffset:1] dark:opacity-0"
        />
        <path
          d={"M23.6 7.9 26.3 5.4"}
          pathLength={1}
          strokeWidth={1.5}
          className="[stroke-dasharray:1.1] motion-safe:transition-[stroke-dashoffset,opacity] motion-safe:duration-(--toggles-lightbulb--duration) [stroke-dashoffset:0] opacity-100 dark:[stroke-dashoffset:1] dark:opacity-0"
        />
        <path
          d={"M8.4 7.9 5.7 5.4"}
          pathLength={1}
          strokeWidth={1.5}
          className="[stroke-dasharray:1.1] motion-safe:transition-[stroke-dashoffset,opacity] motion-safe:duration-(--toggles-lightbulb--duration) [stroke-dashoffset:0] opacity-100 dark:[stroke-dashoffset:1] dark:opacity-0"
        />
        <path
          d={"M4.5 15.8H.6"}
          pathLength={1}
          strokeWidth={1.5}
          className="[stroke-dasharray:1.1] motion-safe:transition-[stroke-dashoffset,opacity] motion-safe:duration-(--toggles-lightbulb--duration) [stroke-dashoffset:0] opacity-100 dark:[stroke-dashoffset:1] dark:opacity-0"
        />
      </svg>
    </button>
  );
}
```
