{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "button",
  "type": "registry:ui",
  "title": "Button",
  "description": "Shadcn compatible React button on Base UI with eight variants, nine sizes including icon sizes, a pressed state and render prop support for links.",
  "dependencies": [
    "@base-ui/react",
    "class-variance-authority"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/ui/button.tsx",
      "type": "registry:ui",
      "target": "components/ui/button.tsx",
      "content": "\"use client\"\nimport * as React from \"react\"\nimport { Button as ButtonPrimitive } from \"@base-ui/react/button\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"@/lib/utils\"\n\n/**\n * Button — the Hairline keycap.\n * Solid variants carry an inner top highlight + inner bottom edge (shadow-ink),\n * outline carries a 1px bottom \"key\" edge (shadow-key). Hover changes one\n * property. Press sinks 0.5px. Nothing shifts layout.\n */\nconst buttonVariants = cva(\n  [\n    \"group/button relative inline-flex shrink-0 items-center justify-center gap-1.5 align-middle\",\n    \"rounded-lg border border-transparent bg-clip-padding\",\n    \"text-sm font-medium whitespace-nowrap\",\n    \"outline-none select-none cursor-pointer\",\n    \"transition-[color,background-color,border-color,box-shadow,transform,opacity] duration-[140ms] ease-hairline\",\n    \"focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-bg\",\n    \"active:translate-y-[0.5px]\",\n    \"disabled:pointer-events-none disabled:opacity-45 data-[disabled]:pointer-events-none data-[disabled]:opacity-45\",\n    \"aria-invalid:ring-2 aria-invalid:ring-danger/40\",\n    \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  ].join(\" \"),\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-ink text-on-ink shadow-ink hover:bg-ink-hover [&_svg]:text-on-ink/80\",\n        accent:\n          \"bg-accent text-on-accent shadow-ink hover:bg-accent-hover\",\n        outline:\n          \"border-border bg-surface text-fg shadow-key hover:border-border-strong hover:bg-sunken/50 active:shadow-highlight [&_svg]:text-fg-muted\",\n        secondary:\n          \"bg-sunken text-fg hover:bg-border/70 [&_svg]:text-fg-muted\",\n        ghost:\n          \"text-fg-muted hover:bg-sunken hover:text-fg data-[pressed]:bg-sunken data-[pressed]:text-fg\",\n        soft:\n          \"bg-accent-soft text-accent-fg hover:bg-accent/15\",\n        destructive:\n          \"bg-danger text-white shadow-ink hover:bg-danger/90\",\n        link:\n          \"h-auto rounded-sm px-0 text-accent-fg underline decoration-accent-line decoration-1 underline-offset-4 hover:decoration-accent\",\n      },\n      size: {\n        xs: \"h-7 min-h-7 gap-1 rounded-md px-2 text-xs [&_svg:not([class*='size-'])]:size-3.5\",\n        sm: \"h-8 min-h-8 px-2.5 text-[0.8125rem] [&_svg:not([class*='size-'])]:size-3.5\",\n        default: \"h-9 min-h-9 px-3.5\",\n        lg: \"h-11 min-h-11 rounded-[0.625rem] px-5 text-[0.9375rem] tracking-[-0.005em]\",\n        xl: \"h-12 min-h-12 rounded-xl px-6 text-base tracking-[-0.01em]\",\n        icon: \"size-9\",\n        \"icon-xs\": \"size-7 rounded-md\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-11 rounded-[0.625rem]\",\n      },\n    },\n    compoundVariants: [\n      { variant: \"link\", size: [\"xs\", \"sm\", \"default\", \"lg\", \"xl\"], className: \"h-auto min-h-0 px-0\" },\n    ],\n    defaultVariants: { variant: \"default\", size: \"default\" },\n  }\n)\n\nfunction Button({\n  className,\n  variant = \"default\",\n  size = \"default\",\n  render,\n  nativeButton,\n  ...props\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\n  // Base UI defaults nativeButton=true. When `render` swaps in a Link/<a>,\n  // that must be false or it warns and a11y/forms semantics break.\n  const resolvedNative = nativeButton ?? (render != null ? false : true)\n\n  return (\n    <ButtonPrimitive\n      data-slot=\"button\"\n      data-variant={variant}\n      className={cn(buttonVariants({ variant, size, className }))}\n      render={render}\n      nativeButton={resolvedNative}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
    }
  ]
}
