{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "button",
  "title": "Button",
  "description": "Rounded action button for the Circle design system.",
  "dependencies": [
    "@radix-ui/react-slot",
    "class-variance-authority"
  ],
  "registryDependencies": [
    "@circle-ui/utils"
  ],
  "files": [
    {
      "path": "registry/berlin/circle-ui/button.tsx",
      "content": "// Generated from packages/ui/src/components/button.tsx\nimport * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/registry/berlin/lib/utils\";\n\ntype IconComponent = React.ElementType<{ className?: string }>;\n\nexport const buttonVariants = cva(\n  \"inline-flex cursor-pointer items-center justify-center whitespace-nowrap rounded-full border text-center font-medium no-underline transition-[background-color,border-color,color,box-shadow] duration-200 focus-visible:outline-none disabled:pointer-events-none disabled:select-none [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n  {\n    variants: {\n      variant: {\n        primary: \"\",\n        secondary: \"\",\n      },\n      size: {\n        small:\n          \"gap-1 px-[15px] py-[7px] text-[14px] leading-[20px] [&_svg]:size-4\",\n        large:\n          \"gap-2 px-[23px] py-[11px] text-[16px] leading-[24px] [&_svg]:size-5\",\n      },\n      theme: {\n        dark: \"\",\n        light: \"\",\n      },\n    },\n    compoundVariants: [\n      {\n        variant: \"primary\",\n        theme: \"dark\",\n        className:\n          \"border-primary bg-primary text-white focus-visible:shadow-[var(--shadow-focus)] disabled:border-transparent disabled:bg-secondary disabled:text-muted-foreground\",\n      },\n      {\n        variant: \"primary\",\n        theme: \"light\",\n        className:\n          \"border-inverse-background bg-inverse-background text-inverse-foreground focus-visible:shadow-[var(--shadow-focus)] disabled:border-transparent disabled:bg-inverse-muted disabled:text-inverse-muted-foreground\",\n      },\n      {\n        variant: \"secondary\",\n        theme: \"dark\",\n        className:\n          \"focus-visible:border-foreground focus-visible:bg-foreground focus-visible:text-background disabled:border-transparent disabled:bg-secondary disabled:text-muted-foreground\",\n      },\n      {\n        variant: \"secondary\",\n        theme: \"light\",\n        className:\n          \"border-inverse-border text-inverse-background focus-visible:border-inverse-background focus-visible:bg-inverse-background focus-visible:text-inverse-foreground disabled:border-transparent disabled:bg-inverse-muted disabled:text-inverse-muted-foreground\",\n      },\n    ],\n    defaultVariants: {\n      variant: \"primary\",\n      size: \"large\",\n      theme: \"dark\",\n    },\n  },\n);\n\nexport type ButtonProps = Omit<\n  React.ComponentPropsWithoutRef<\"button\">,\n  \"type\"\n> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean;\n    block?: boolean;\n    type?: \"button\" | \"submit\" | \"reset\";\n    url?: string;\n    leftIcon?: IconComponent;\n    rightIcon?: IconComponent;\n    loading?: boolean;\n  };\n\nfunction SpinnerIcon({ className }: { className?: string }) {\n  return (\n    <svg\n      aria-hidden=\"true\"\n      className={cn(\"animate-spin\", className)}\n      width=\"20\"\n      height=\"20\"\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n    >\n      <circle\n        cx=\"12\"\n        cy=\"12\"\n        r=\"10\"\n        className=\"opacity-20\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n      />\n      <path\n        d=\"M22 12a10 10 0 0 0-10-10\"\n        className=\"opacity-90\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n      />\n    </svg>\n  );\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n  (\n    {\n      className,\n      variant,\n      size,\n      theme,\n      asChild = false,\n      block = false,\n      url,\n      leftIcon: LeftIcon,\n      rightIcon: RightIcon,\n      loading = false,\n      disabled,\n      children,\n      type = \"button\",\n      onClickCapture,\n      onKeyDownCapture,\n      role,\n      tabIndex,\n      ...props\n    },\n    ref,\n  ) => {\n    const iconClassName = size === \"small\" ? \"size-4\" : \"size-5\";\n    const Left = loading ? SpinnerIcon : LeftIcon;\n    const isDisabled = disabled || loading;\n    const content = (\n      <>\n        {Left ? <Left className={iconClassName} /> : null}\n        {children}\n        {RightIcon ? <RightIcon className={iconClassName} /> : null}\n      </>\n    );\n\n    if (url && !asChild && !isDisabled) {\n      return (\n        <a\n          className={cn(\n            block && \"flex w-full\",\n            buttonVariants({ variant, size, theme, className }),\n          )}\n          href={url}\n          {...(props as React.ComponentProps<\"a\">)}\n        >\n          {content}\n        </a>\n      );\n    }\n\n    const Comp = asChild ? Slot : \"button\";\n    const handleDisabledClickCapture: React.MouseEventHandler<Element> = (\n      event,\n    ) => {\n      (onClickCapture as React.MouseEventHandler<Element> | undefined)?.(event);\n\n      if (!isDisabled || !asChild) {\n        return;\n      }\n\n      event.preventDefault();\n      event.stopPropagation();\n    };\n    const handleDisabledKeyCapture: React.KeyboardEventHandler<Element> = (\n      event,\n    ) => {\n      (onKeyDownCapture as React.KeyboardEventHandler<Element> | undefined)?.(\n        event,\n      );\n\n      if (!isDisabled || !asChild) {\n        return;\n      }\n\n      if (event.key === \"Enter\" || event.key === \" \") {\n        event.preventDefault();\n        event.stopPropagation();\n      }\n    };\n\n    return (\n      <Comp\n        ref={ref}\n        className={cn(\n          block && \"flex w-full\",\n          asChild && isDisabled && \"pointer-events-none\",\n          buttonVariants({ variant, size, theme, className }),\n        )}\n        aria-disabled={asChild && isDisabled ? true : undefined}\n        disabled={asChild ? undefined : isDisabled}\n        onClickCapture={handleDisabledClickCapture}\n        onKeyDownCapture={handleDisabledKeyCapture}\n        role={asChild && isDisabled ? role ?? \"button\" : role}\n        tabIndex={asChild && isDisabled ? -1 : tabIndex}\n        type={asChild ? undefined : type}\n        {...props}\n      >\n        {content}\n      </Comp>\n    );\n  },\n);\n\nButton.displayName = \"Button\";\n",
      "type": "registry:ui",
      "target": "src/components/circle/ui/button.tsx"
    }
  ],
  "type": "registry:ui"
}