{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "button",
  "type": "registry:ui",
  "title": "Button",
  "description": "Signature tactile action button with crimson primary, secondary, outline, ghost, and danger variants.",
  "dependencies": [
    "@radix-ui/react-slot",
    "class-variance-authority"
  ],
  "registryDependencies": [
    "https://ui.arpitbhayani.me/r/aui.json"
  ],
  "files": [
    {
      "path": "ui/button.tsx",
      "content": "import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/utils\";\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 cursor-pointer select-none\",\n  {\n    variants: {\n      variant: {\n        primary:\n          \"bg-primary text-primary-foreground shadow-xs hover:opacity-95 active:scale-[0.99]\",\n        default:\n          \"bg-primary text-primary-foreground shadow-xs hover:opacity-95 active:scale-[0.99]\",\n        secondary:\n          \"bg-secondary text-secondary-foreground border border-border shadow-2xs hover:bg-muted active:scale-[0.99]\",\n        outline:\n          \"border border-border bg-transparent shadow-2xs hover:bg-secondary hover:text-secondary-foreground active:scale-[0.99]\",\n        ghost:\n          \"hover:bg-secondary hover:text-secondary-foreground\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:opacity-95 active:scale-[0.99]\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n        amber:\n          \"bg-amber-500 text-stone-950 font-semibold border border-amber-600/30 shadow-xs hover:bg-amber-600 hover:text-stone-950 active:scale-[0.99]\",\n        yellow:\n          \"bg-amber-500 text-stone-950 font-semibold border border-amber-600/30 shadow-xs hover:bg-amber-600 hover:text-stone-950 active:scale-[0.99]\",\n        warning:\n          \"bg-amber-500 text-stone-950 font-semibold border border-amber-600/30 shadow-xs hover:bg-amber-600 hover:text-stone-950 active:scale-[0.99]\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2\",\n        sm: \"h-8 rounded-md px-3 text-xs\",\n        lg: \"h-10 rounded-md px-6 text-base\",\n        icon: \"h-9 w-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"primary\",\n      size: \"default\",\n    },\n  }\n);\n\nexport interface ButtonProps\n  extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n    VariantProps<typeof buttonVariants> {\n  asChild?: boolean;\n  icon?: React.ReactNode;\n  iconPosition?: \"left\" | \"right\";\n  leftIcon?: React.ReactNode;\n  rightIcon?: React.ReactNode;\n  loading?: boolean;\n  isLoading?: boolean;\n  loadingText?: React.ReactNode;\n  spinner?: React.ReactNode;\n}\n\nconst DefaultSpinner = ({ className }: { className?: string }) => (\n  <svg\n    className={cn(\"animate-spin\", className)}\n    xmlns=\"http://www.w3.org/2000/svg\"\n    fill=\"none\"\n    viewBox=\"0 0 24 24\"\n    width=\"16\"\n    height=\"16\"\n    aria-hidden=\"true\"\n  >\n    <circle\n      className=\"opacity-25\"\n      cx=\"12\"\n      cy=\"12\"\n      r=\"10\"\n      stroke=\"currentColor\"\n      strokeWidth=\"4\"\n    />\n    <path\n      className=\"opacity-75\"\n      fill=\"currentColor\"\n      d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n    />\n  </svg>\n);\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n  (\n    {\n      className,\n      variant,\n      size,\n      asChild = false,\n      icon,\n      iconPosition = \"left\",\n      leftIcon,\n      rightIcon,\n      loading = false,\n      isLoading = false,\n      loadingText,\n      spinner,\n      children,\n      disabled,\n      ...props\n    },\n    ref\n  ) => {\n    if (asChild) {\n      return (\n        <Slot\n          className={cn(buttonVariants({ variant, size, className }))}\n          ref={ref}\n          {...props}\n        >\n          {children}\n        </Slot>\n      );\n    }\n\n    const loadingActive = Boolean(loading || isLoading);\n    const isDisabled = Boolean(disabled || loadingActive);\n    const spinnerElement = spinner || <DefaultSpinner className=\"size-4\" />;\n\n    const effectiveLeftIcon = loadingActive\n      ? (iconPosition === \"right\" && !leftIcon ? undefined : spinnerElement)\n      : leftIcon || (iconPosition === \"left\" ? icon : undefined);\n\n    const effectiveRightIcon = loadingActive\n      ? (iconPosition === \"right\" && !leftIcon ? spinnerElement : undefined)\n      : rightIcon || (iconPosition === \"right\" ? icon : undefined);\n\n    const effectiveChildren = loadingActive && loadingText ? loadingText : children;\n    const isIconOnly =\n      (effectiveChildren === undefined ||\n        effectiveChildren === null ||\n        effectiveChildren === \"\") &&\n      Boolean(effectiveLeftIcon || effectiveRightIcon);\n\n    return (\n      <button\n        className={cn(\n          buttonVariants({ variant, size, className }),\n          loadingActive && \"cursor-wait\"\n        )}\n        ref={ref}\n        disabled={isDisabled}\n        aria-busy={loadingActive ? \"true\" : undefined}\n        {...props}\n      >\n        {isIconOnly ? (\n          effectiveLeftIcon || effectiveRightIcon\n        ) : (\n          <>\n            {effectiveLeftIcon}\n            {effectiveChildren}\n            {effectiveRightIcon}\n          </>\n        )}\n      </button>\n    );\n  }\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n",
      "type": "registry:ui"
    }
  ]
}