{
  "$schema": "https://ethereal-ui.saefulrohman.dev/schema/registry-item.json",
  "name": "button",
  "title": "Button",
  "type": "registry:primitives",
  "description": "Interactive button primitive with six semantic variants, four sizes, and built-in loading spinner support.",
  "dependencies": [
    "@radix-ui/react-slot",
    "class-variance-authority",
    "lucide-react"
  ],
  "usage": "import { Button } from \"@etherealui/react\"\n\nexport function ButtonDemo() {\n  return (\n    <div className=\"flex flex-wrap items-center gap-2.5\">\n      <Button variant=\"default\">Default</Button>\n      <Button variant=\"primary\">Primary</Button>\n      <Button variant=\"secondary\">Secondary</Button>\n      <Button variant=\"outline\">Outline</Button>\n      <Button variant=\"ghost\">Ghost</Button>\n      <Button variant=\"destructive\">Delete</Button>\n    </div>\n  )\n}",
  "files": [
    {
      "path": "packages/ui/src/primitives/button.tsx",
      "target": "components/ui/button.tsx",
      "type": "registry:primitives",
      "content": "import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Loader2, X } from \"lucide-react\"\nimport { cn } from \"../utils/cn\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/30 disabled:pointer-events-none disabled:opacity-50 cursor-pointer select-none\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-zinc-900 text-white hover:bg-zinc-800 dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-zinc-200 shadow-2xs\",\n        primary:\n          \"bg-blue-600 text-white hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-500 shadow-2xs\",\n        glow:\n          \"bg-blue-600 text-white hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-500 shadow-2xs\",\n        secondary:\n          \"bg-zinc-100 text-zinc-900 hover:bg-zinc-200 dark:bg-zinc-800 dark:text-zinc-100 dark:hover:bg-zinc-700\",\n        outline:\n          \"border border-zinc-200 bg-white text-zinc-700 hover:bg-zinc-50 hover:text-zinc-900 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100 dark:hover:bg-zinc-800\",\n        ghost:\n          \"text-zinc-600 hover:bg-zinc-100 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-100\",\n        destructive:\n          \"bg-rose-600 text-white hover:bg-rose-700 dark:bg-rose-600 dark:hover:bg-rose-500\",\n      },\n      size: {\n        default: \"h-9 px-3.5 py-2 text-xs\",\n        sm: \"h-8 rounded-md px-2.5 text-xs\",\n        lg: \"h-10 rounded-lg px-5 text-sm\",\n        icon: \"h-8 w-8\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nexport interface ButtonProps\n  extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n    VariantProps<typeof buttonVariants> {\n  asChild?: boolean\n  loading?: boolean\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n  ({ className, variant, size, asChild = false, loading = false, children, disabled, ...props }, ref) => {\n    const Comp = asChild ? Slot : \"button\"\n    return (\n      <Comp\n        className={cn(buttonVariants({ variant, size, className }))}\n        ref={ref}\n        disabled={disabled || loading}\n        {...props}\n      >\n        {loading && <Loader2 className=\"h-3.5 w-3.5 animate-spin shrink-0\" />}\n        {children}\n      </Comp>\n    )\n  }\n)\nButton.displayName = \"Button\"\n\nexport interface CloseButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n  size?: \"sm\" | \"default\"\n}\n\nconst CloseButton = React.forwardRef<HTMLButtonElement, CloseButtonProps>(\n  ({ className, size = \"default\", ...props }, ref) => (\n    <button\n      ref={ref}\n      type=\"button\"\n      aria-label=\"Close\"\n      className={cn(\n        \"inline-flex items-center justify-center rounded-lg text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-700 dark:hover:bg-zinc-800 dark:hover:text-zinc-200 cursor-pointer\",\n        size === \"sm\" ? \"h-6 w-6\" : \"h-8 w-8\",\n        className\n      )}\n      {...props}\n    >\n      <X className={size === \"sm\" ? \"h-3.5 w-3.5\" : \"h-4 w-4\"} />\n    </button>\n  )\n)\nCloseButton.displayName = \"CloseButton\"\n\nexport interface ButtonGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n  attached?: boolean\n}\n\nconst ButtonGroup = React.forwardRef<HTMLDivElement, ButtonGroupProps>(\n  ({ className, attached = true, ...props }, ref) => (\n    <div\n      ref={ref}\n      role=\"group\"\n      className={cn(\n        \"inline-flex items-center\",\n        attached\n          ? \"rounded-lg border border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900 p-0.5 [&>button]:border-0 [&>button]:rounded-md [&>button]:shadow-none\"\n          : \"gap-2\",\n        className\n      )}\n      {...props}\n    />\n  )\n)\nButtonGroup.displayName = \"ButtonGroup\"\n\nexport interface ToggleGroupItem {\n  value: string\n  label: React.ReactNode\n  icon?: React.ReactNode\n}\n\nexport interface ToggleGroupProps {\n  items: ToggleGroupItem[]\n  value: string\n  onValueChange: (value: string) => void\n  size?: \"sm\" | \"default\"\n  className?: string\n}\n\nconst ToggleGroup: React.FC<ToggleGroupProps> = ({\n  items,\n  value,\n  onValueChange,\n  size = \"default\",\n  className,\n}) => {\n  return (\n    <div\n      role=\"group\"\n      className={cn(\n        \"inline-flex items-center rounded-lg border border-zinc-200 bg-zinc-100/80 dark:border-zinc-800 dark:bg-zinc-900 p-0.5 gap-0.5\",\n        className\n      )}\n    >\n      {items.map((item) => {\n        const active = item.value === value\n        return (\n          <button\n            key={item.value}\n            type=\"button\"\n            onClick={() => onValueChange(item.value)}\n            className={cn(\n              \"inline-flex items-center gap-1.5 rounded-md font-medium transition-all cursor-pointer\",\n              size === \"sm\" ? \"px-2.5 py-1 text-xs\" : \"px-3 py-1.5 text-xs\",\n              active\n                ? \"bg-white text-zinc-900 shadow-2xs dark:bg-zinc-800 dark:text-zinc-100\"\n                : \"text-zinc-500 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-200\"\n            )}\n          >\n            {item.icon}\n            {item.label}\n          </button>\n        )\n      })}\n    </div>\n  )\n}\nToggleGroup.displayName = \"ToggleGroup\"\n\nexport { Button, CloseButton, ButtonGroup, ToggleGroup, buttonVariants }\n"
    }
  ]
}