{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "mode-toggler",
  "type": "registry:ui",
  "title": "Mode Toggler",
  "description": "A minimal Sun / Moon theme toggle button built on next-themes. Supports an optional click sound, composable className, and dynamic aria-label.",
  "author": "Aditya Ojha <https://akoder.xyz>",
  "categories": [
    "theming",
    "toggle",
    "dark-mode",
    "accessibility"
  ],
  "dependencies": [
    "lucide-react",
    "next-themes"
  ],
  "registryDependencies": [
    "button"
  ],
  "meta": {
    "docs": "https://akoder.xyz/components/mode-toggler",
    "source": "https://github.com/AdityaKodez/adityaojha/blob/main/components/ui/mode-toggler.tsx"
  },
  "files": [
    {
      "path": "components/ui/mode-toggler.tsx",
      "content": "﻿\"use client\";\n\nimport { Moon, Sun } from \"lucide-react\";\nimport { useTheme } from \"next-themes\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport { Button } from \"@/components/ui/button\";\n\ninterface ModeTogglerProps {\n  /** Extra classes applied to the button wrapper. */\n  className?: string;\n  /** Play an audio clip when the theme switches. Pass a public URL. */\n  audioSrc?: string;\n  /** Delay (ms) between the audio playing and the theme switching. Default 200. */\n  audioDelay?: number;\n}\n\n/**\n * A minimal Sun <-> Moon theme toggle button.\n * Reads and writes next-themes resolved theme. Works with class-based dark mode.\n */\nexport function ModeToggler({\n  className,\n  audioSrc,\n  audioDelay = 200,\n}: ModeTogglerProps) {\n  const { setTheme, resolvedTheme } = useTheme();\n  const audioRef = useRef<HTMLAudioElement | null>(null);\n\n  useEffect(() => {\n    if (audioSrc) {\n      audioRef.current = new Audio(audioSrc);\n    }\n  }, [audioSrc]);\n\n  const toggle = useCallback(() => {\n    if (audioRef.current) {\n      audioRef.current.currentTime = 0;\n      audioRef.current.play().catch(() => {});\n    }\n    const next = resolvedTheme === \"dark\" ? \"light\" : \"dark\";\n    if (audioRef.current) {\n      setTimeout(() => setTheme(next), audioDelay);\n    } else {\n      setTheme(next);\n    }\n  }, [resolvedTheme, setTheme, audioDelay]);\n\n  return (\n    <Button\n      variant=\"outline\"\n      size=\"icon\"\n      className={className}\n      onClick={toggle}\n      aria-label={\n        resolvedTheme === \"dark\" ? \"switch to light mode\" : \"switch to dark mode\"\n      }\n    >\n      <Sun className=\"h-[1.1rem] w-[1.1rem] fill-yellow-400 rotate-0 scale-100 transition-transform duration-300 dark:-rotate-90 dark:scale-0\" />\n      <Moon className=\"absolute h-[1.1rem]  fill-gray-400 rotate-90 scale-0 transition-transform duration-300 dark:rotate-0 dark:scale-100\" />\n    </Button>\n  );\n}\n",
      "type": "registry:ui"
    }
  ],
  "docs": "## Installation\n\n```bash\nnpx shadcn@latest add @akoder/mode-toggler\n```\n\n## Usage\n\n```tsx\nimport { ModeToggler } from \"@/components/ui/mode-toggler\";\n\nexport function Header() {\n  return (\n    <header className=\"flex items-center justify-between px-4 h-12\">\n      <span>my app</span>\n      <ModeToggler />\n    </header>\n  );\n}\n```"
}