{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "button",
  "title": "Button",
  "description": "A component to display a button and allows a user to trigger an action.",
  "registryDependencies": [],
  "files": [
    {
      "path": "ui/button.tsx",
      "content": "import { cva, type VariantProps } from \"class-variance-authority\";\nimport {\n  Children,\n  cloneElement,\n  createContext,\n  useContext,\n  useMemo,\n} from \"react\";\nimport { ActivityIndicator, Pressable, Text } from \"react-native\";\nimport { cn } from \"@/lib/utils\";\n\n// Types\ntype InternalButtonContextType = VariantProps<typeof buttonVariants> & {\n  busy?: boolean;\n  disabled?: boolean;\n};\n\ntype ButtonChildProps = {\n  children: React.ReactNode;\n  className?: string;\n};\n\nexport type ButtonProps = React.ComponentProps<typeof Pressable> &\n  InternalButtonContextType & {\n    children: React.ReactNode;\n  };\n\n// Context\nconst ButtonContext = createContext<InternalButtonContextType | null>(null);\n\nconst useButtonContext = () => {\n  const context = useContext(ButtonContext);\n  if (!context) {\n    throw new Error(\"useButtonContext must be used within a Button component\");\n  }\n  return context;\n};\n\n// Components\nexport const Button = ({\n  className,\n  variant,\n  size,\n  busy,\n  disabled,\n  children,\n  accessibilityRole = \"button\",\n  ...props\n}: ButtonProps) => {\n  const ctx = useMemo(() => {\n    return {\n      busy,\n      disabled,\n      size,\n      variant,\n    };\n  }, [variant, size, busy, disabled]);\n\n  return (\n    <ButtonContext.Provider value={ctx}>\n      <Pressable\n        accessibilityRole={accessibilityRole}\n        accessibilityState={{ busy, disabled }}\n        className={cn(\n          buttonVariants({ className, size, variant }),\n          disabled && \"opacity-50\"\n        )}\n        disabled={disabled || busy}\n        {...props}\n      >\n        {Children.map(children, (child) => {\n          if (typeof child === \"string\") {\n            if (size === \"icon\") {\n              // Icon buttons shouldn't render text\n              return null;\n            }\n            return <ButtonText>{child}</ButtonText>;\n          }\n\n          return child;\n        })}\n        {busy ? <ButtonSpinner /> : null}\n      </Pressable>\n    </ButtonContext.Provider>\n  );\n};\n\nexport const ButtonText = (props: ButtonChildProps) => {\n  const ctx = useButtonContext();\n\n  return (\n    <Text\n      {...props}\n      className={cn(\n        buttonTextVariants(ctx),\n        ctx.busy && \"opacity-0\",\n        props.className\n      )}\n    />\n  );\n};\n\nexport const ButtonIcon = ({ children, ...props }: ButtonChildProps) => {\n  const ctx = useButtonContext();\n\n  const child = Children.only(children);\n\n  if (!child) {\n    if (__DEV__) {\n      throw new Error(\"ButtonIcon expects a single React element as children\");\n    }\n    return null;\n  }\n\n  return cloneElement(child as React.ReactElement<ButtonChildProps>, {\n    ...props,\n    className: cn(\n      buttonIconVariants(ctx),\n      ctx.busy && \"opacity-0\",\n      props.className\n    ),\n  });\n};\n\nconst ButtonSpinner = () => {\n  const ctx = useButtonContext();\n\n  return (\n    <ActivityIndicator\n      className=\"absolute\"\n      colorClassName={buttonSpinnerVariants(ctx)}\n    />\n  );\n};\n\n// Styles\nexport const buttonVariants = cva(\n  \"flex w-full shrink-0 flex-row items-center justify-center gap-2 whitespace-nowrap rounded-lg font-medium text-sm\",\n  {\n    defaultVariants: {\n      size: \"default\",\n      variant: \"default\",\n    },\n    variants: {\n      size: {\n        default: \"h-12 px-4\",\n        icon: \"size-12\",\n        \"icon-lg\": \"size-14\",\n        \"icon-sm\": \"size-8\",\n        lg: \"h-14 px-6\",\n        sm: \"h-8 gap-1 px-3\",\n      },\n      variant: {\n        default: \"bg-primary active:bg-primary/80\",\n        destructive:\n          \"bg-destructive active:bg-destructive/80 dark:bg-destructive/60\",\n        ghost: \"bg-background active:bg-accent/90 dark:active:bg-accent/50\",\n        link: \"h-auto w-auto p-0 active:opacity-50\",\n        outline:\n          \"border border-border bg-background active:bg-accent/90 dark:border-input dark:bg-input/30 dark:active:bg-input/50\",\n        secondary: \"bg-secondary active:bg-secondary/50\",\n      },\n    },\n  }\n);\n\nexport const buttonTextVariants = cva(\n  \"whitespace-nowrap font-semibold text-sm\",\n  {\n    defaultVariants: {\n      size: \"default\",\n      variant: \"default\",\n    },\n    variants: {\n      size: {\n        default: \"text-lg\",\n        icon: \"\",\n        \"icon-lg\": \"\",\n        \"icon-sm\": \"\",\n        lg: \"text-xl\",\n        sm: \"text-sm\",\n      },\n      variant: {\n        default: \"text-primary-foreground\",\n        destructive: \"text-white\",\n        ghost: \"text-accent-foreground\",\n        link: \"text-primary\",\n        outline: \"text-foreground dark:text-accent-foreground\",\n        secondary: \"text-secondary-foreground\",\n      },\n    },\n  }\n);\n\nexport const buttonIconVariants = cva(\"\", {\n  defaultVariants: {\n    size: \"default\",\n    variant: \"default\",\n  },\n  variants: {\n    size: {\n      default: \"size-6\",\n      icon: \"size-7\",\n      \"icon-lg\": \"size-8\",\n      \"icon-sm\": \"size-6\",\n      lg: \"size-7\",\n      sm: \"size-5\",\n    },\n    variant: {\n      default: \"text-primary-foreground\",\n      destructive: \"text-white\",\n      ghost: \"text-accent-foreground\",\n      link: \"text-primary\",\n      outline: \"text-foreground dark:text-accent-foreground\",\n      secondary: \"text-secondary-foreground\",\n    },\n  },\n});\n\nexport const buttonSpinnerVariants = cva(\"\", {\n  defaultVariants: {\n    variant: \"default\",\n  },\n  variants: {\n    variant: {\n      default: \"accent-primary-foreground\",\n      destructive: \"accent-white\",\n      ghost: \"accent-accent-foreground\",\n      link: \"accent-primary\",\n      outline: \"accent-foreground dark:accent-accent-foreground\",\n      secondary: \"accent-secondary-foreground\",\n    },\n  },\n});\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}
