{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "avatar",
  "type": "registry:ui",
  "title": "Avatar",
  "description": "User or brand avatar with image, automatic initials fallback, and size variants.",
  "dependencies": [
    "@radix-ui/react-avatar",
    "@saasflare/ui"
  ],
  "files": [
    {
      "path": "components/ui/avatar.tsx",
      "type": "registry:ui",
      "content": "// @toreview\n\"use client\"\n\n/**\n * @fileoverview Avatar — user profile image with size variants and hover scale animation.\n * @module packages/ui/components/ui/avatar\n * @layer core\n *\n * Self-contained implementation built on Radix Avatar primitive. Supports\n * three size variants (sm, default, lg) and includes a subtle hover scale\n * transition. Provides fallback initials when the image fails to load.\n *\n * @component\n * @example\n * import { Avatar, AvatarImage, AvatarFallback } from \"@saasflare/ui\";\n *\n * <Avatar size=\"lg\">\n *   <AvatarImage src=\"/user.jpg\" alt=\"User\" />\n *   <AvatarFallback>JD</AvatarFallback>\n * </Avatar>\n */\n\nimport * as React from \"react\"\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\"\nimport { cn } from \"@saasflare/ui\"\nimport { useSaasflareProps, type SaasflareComponentProps } from \"@saasflare/ui\"\n\n/**\n * Props for {@link Avatar}.\n *\n * Extends the Radix Avatar root props and {@link SaasflareComponentProps} so\n * `surface`, `radius`, `animated`, and `iconWeight` can be supplied\n * per-instance or inherited from <SaasflareProvider>.\n */\ninterface AvatarProps\n  extends Omit<React.ComponentProps<typeof AvatarPrimitive.Root>, keyof SaasflareComponentProps>,\n    SaasflareComponentProps {\n  /** Visual size. `\"default\"` is a deprecated alias for `\"md\"`. */\n  size?: \"sm\" | \"md\" | \"lg\" | \"default\"\n}\n\n/**\n * User avatar with size variants and a subtle hover-scale animation. Built on\n * the Radix Avatar primitive — compose with {@link AvatarImage} and\n * {@link AvatarFallback}; wrap several in {@link AvatarGroup} for an\n * overlapping stack.\n *\n * @component\n * @layer core\n *\n * @example\n * <Avatar size=\"lg\">\n *   <AvatarImage src=\"/user.jpg\" alt=\"User\" />\n *   <AvatarFallback>JD</AvatarFallback>\n * </Avatar>\n */\nfunction Avatar({\n  className,\n  size = \"md\",\n  surface,\n  radius,\n  animated,\n  iconWeight,\n  ...props\n}: AvatarProps) {\n  const sf = useSaasflareProps({ surface, radius, animated, iconWeight })\n  const resolvedSize = size === \"default\" ? \"md\" : size\n\n  return (\n    <AvatarPrimitive.Root\n      {...props}\n      data-slot=\"avatar\"\n      data-size={resolvedSize}\n      data-surface={sf.surface}\n      data-radius={sf.radius}\n      data-animated={String(sf.animated)}\n      className={cn(\n        \"group/avatar relative flex size-8 shrink-0 overflow-hidden rounded-full select-none transition-transform duration-200 data-[animated=true]:hover:scale-105 data-[size=lg]:size-10 data-[size=sm]:size-6\",\n        className\n      )}\n    />\n  )\n}\n\n/**\n * Avatar image — fills the circle once the source has loaded; until then\n * {@link AvatarFallback} renders.\n *\n * @component\n * @layer core\n */\nfunction AvatarImage({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n  return (\n    <AvatarPrimitive.Image\n      data-slot=\"avatar-image\"\n      className={cn(\"aspect-square size-full\", className)}\n      {...props}\n    />\n  )\n}\n\n/**\n * Fallback initials shown while the avatar image loads or when it fails.\n *\n * @component\n * @layer core\n */\nfunction AvatarFallback({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n  return (\n    <AvatarPrimitive.Fallback\n      data-slot=\"avatar-fallback\"\n      className={cn(\n        \"flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\n/**\n * Status badge anchored to the avatar's bottom-right corner, scaled to the\n * avatar size.\n *\n * @component\n * @layer core\n */\nfunction AvatarBadge({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"avatar-badge\"\n      className={cn(\n        \"absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground ring-2 ring-background select-none\",\n        \"group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden\",\n        \"group-data-[size=md]/avatar:size-2.5 group-data-[size=md]/avatar:[&>svg]:size-2\",\n        \"group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\n/**\n * Overlapping stack of avatars separated by background-colored rings.\n *\n * @component\n * @layer core\n */\nfunction AvatarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"avatar-group\"\n      className={cn(\n        \"group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\n/**\n * Overflow count bubble (e.g. \"+3\") rendered at the end of an\n * {@link AvatarGroup}.\n *\n * @component\n * @layer core\n */\nfunction AvatarGroupCount({\n  className,\n  ...props\n}: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"avatar-group-count\"\n      className={cn(\n        \"relative flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Avatar,\n  AvatarImage,\n  AvatarFallback,\n  AvatarBadge,\n  AvatarGroup,\n  AvatarGroupCount,\n  type AvatarProps,\n}\n",
      "target": "components/ui/avatar.tsx"
    }
  ],
  "$meta": {
    "source": "https://ui.saasflare.io/r/avatar.json"
  }
}
