{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"avatar","type":"registry:component","title":"Avatar","description":"Round avatar whose image fades in on load and crossfades to initials if it fails.","author":"Ryan","dependencies":["clsx","tailwind-merge"],"registryDependencies":[],"files":[{"path":"components/motion/avatar.tsx","type":"registry:component","target":"@components/motion/avatar.tsx","content":"\"use client\";\n// easeui.dev/components/motion/avatar\n\nimport { useState } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface AvatarProps {\n  src?: string;\n  alt?: string;\n  /** Shown while there is no image, or once it fails to load. */\n  fallback: string;\n  className?: string;\n}\n\n/** A round avatar. The image fades in on load and crossfades to the fallback if it fails. */\nexport function Avatar({ src, alt = \"\", fallback, className }: AvatarProps) {\n  const [loaded, setLoaded] = useState(false);\n  const [errored, setErrored] = useState(false);\n  const showImage = Boolean(src) && !errored;\n\n  return (\n    <span\n      className={cn(\n        \"relative inline-flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-full bg-muted text-sm font-medium text-muted-foreground shadow-[0_0_0_1px_var(--border)]\",\n        className,\n      )}\n    >\n      <span\n        aria-hidden={showImage && loaded}\n        className={cn(\n          \"transition-opacity duration-150 ease-out\",\n          showImage && loaded ? \"opacity-0\" : \"opacity-100\",\n        )}\n      >\n        {fallback}\n      </span>\n      {showImage ? (\n        // A plain img, not next/image: this ships as source a consumer copies\n        // into their own app, which may not have next/image configured.\n        // biome-ignore lint/performance/noImgElement: portable across non-Next apps.\n        <img\n          src={src}\n          alt={alt}\n          onLoad={() => setLoaded(true)}\n          onError={() => setErrored(true)}\n          className={cn(\n            \"absolute inset-0 h-full w-full object-cover opacity-0 transition-opacity duration-150 ease-out\",\n            loaded && \"opacity-100\",\n          )}\n        />\n      ) : null}\n    </span>\n  );\n}\n"},{"path":"lib/utils.ts","type":"registry:lib","target":"@lib/utils.ts","content":"import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"}]}