{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "theme-switch",
  "type": "registry:ui",
  "title": "Theme Switch",
  "description": "A flexible and accessible theme mode switcher component",
  "author": "Ahdeetai <https://aditya.is-cool.dev>",
  "registryDependencies": [],
  "dependencies": ["lucide-react", "clsx", "tailwind-merge", "next-themes"],
  "files": [
    {
      "type": "registry:ui",
      "path": "components/ui/theme-switch.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\nimport { useTheme } from 'next-themes';\nimport { cn } from '@/lib/utils';\n\ninterface ThemeSwitchProps extends React.HTMLAttributes<HTMLDivElement> {\n  modes?: string[];\n  icons?: React.ReactNode[];\n  showActiveIconOnly?: boolean;\n  showInactiveIcons?: 'all' | 'none' | 'next';\n  variant?: 'default' | 'icon-click';\n}\n\nconst ThemeSwitch = React.forwardRef<HTMLDivElement, ThemeSwitchProps>(\n  (\n    {\n      className,\n      modes = ['light', 'dark', 'system'],\n      icons = [],\n      showActiveIconOnly = false,\n      showInactiveIcons = 'all',\n      variant = 'default',\n      ...props\n    },\n    ref,\n  ) => {\n    const { theme, setTheme } = useTheme();\n\n    const currentModeIndex = React.useMemo(() => {\n      const index = modes.indexOf(theme || '');\n      return index !== -1 ? index : 0;\n    }, [theme, modes]);\n\n    const handleToggle = React.useCallback(() => {\n      const nextIndex = (currentModeIndex + 1) % modes.length;\n      setTheme(modes[nextIndex]);\n    }, [currentModeIndex, modes, setTheme]);\n\n    const [isClient, setIsClient] = React.useState(false);\n    React.useEffect(() => {\n      setIsClient(true);\n    }, []);\n\n    if (!isClient) return null;\n\n    const switchWidth = modes.length === 2 ? 'w-14' : 'w-20';\n\n    const isIconVisible = (index: number) => {\n      if (index === currentModeIndex) return true;\n      switch (showInactiveIcons) {\n        case 'none':\n          return false;\n        case 'next':\n          return index === (currentModeIndex + 1) % modes.length;\n        case 'all':\n        default:\n          return true;\n      }\n    };\n\n    return (\n      <div\n        className={cn(\n          'relative inline-flex h-8 rounded-full border border-input bg-background p-1 shadow-xs transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring',\n          switchWidth,\n          className,\n        )}\n        onClick={variant === 'default' ? handleToggle : undefined}\n        ref={ref}\n        {...props}\n      >\n        {showActiveIconOnly ? (\n          <div className='absolute inset-0 flex items-center justify-center'>\n            <div className='flex h-6 w-6 items-center justify-center rounded-full bg-foreground text-background z-10'>\n              {icons[currentModeIndex]}\n            </div>\n          </div>\n        ) : (\n          <>\n            <div className='flex w-full h-full items-center justify-between'>\n              {icons.map((icon, idx) => {\n                const key = `theme-icon-${idx}`;\n                const visible = isIconVisible(idx);\n\n                return (\n                  <div\n                    key={key}\n                    className={cn(\n                      'flex h-6 w-6 cursor-pointer items-center justify-center rounded-full z-10 transition-opacity duration-200',\n                      currentModeIndex === idx\n                        ? 'text-background'\n                        : 'text-muted-foreground',\n                      visible ? 'opacity-100' : 'opacity-0',\n                    )}\n                    onClick={(e) => {\n                      if (variant === 'icon-click') {\n                        e.stopPropagation();\n                        setTheme(modes[idx]);\n                      }\n                    }}\n                  >\n                    {React.isValidElement(icon)\n                      ? React.cloneElement(icon, { key: `icon-element-${idx}` })\n                      : icon}\n                  </div>\n                );\n              })}\n            </div>\n\n            <div\n              className={cn(\n                'absolute top-1 h-6 w-6 rounded-full bg-foreground transition-all duration-200 ease-in-out',\n                currentModeIndex === 0\n                  ? 'left-1'\n                  : currentModeIndex === 1\n                    ? modes.length === 2\n                      ? 'left-7'\n                      : 'left-[calc(50%-12px)]'\n                    : 'left-[calc(100%-28px)]',\n              )}\n            />\n          </>\n        )}\n      </div>\n    );\n  },\n);\n\nThemeSwitch.displayName = 'ThemeSwitch';\n\nexport { ThemeSwitch };\n"
    },
    {
      "type": "registry:lib",
      "path": "lib/utils.ts",
      "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}"
    }
  ]
}
