{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "avatar",
  "type": "registry:component",
  "title": "Avatar",
  "description": "Identifies a person or group. 32px image or initials; broken images fall back automatically.",
  "registryDependencies": [
    "https://vlak.dev/r/vlak-base.json",
    "https://vlak.dev/r/inter.json",
    "https://vlak.dev/r/vlak-lib.json"
  ],
  "dependencies": [
    "@stylexjs/stylex"
  ],
  "devDependencies": [
    "@stylexjs/babel-plugin"
  ],
  "docs": "Vlak leaves are StyleX. Compile them with @stylexjs/babel-plugin (Vite: @stylexjs/unplugin, Next: @stylexjs/nextjs-plugin). If you would rather not run a compiler, import @noorddev/vlak-react instead: it ships precompiled with one stylesheet.",
  "files": [
    {
      "path": "vlak/avatar.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport * as stylex from \"@stylexjs/stylex\";\nimport { vlak } from \"./tokens.stylex\";\nimport { rs } from \"./rs\";\n\nexport interface AvatarProps extends React.HTMLAttributes<HTMLSpanElement> {\n  src?: string;\n  /** Image text. Defaults to `name`, then `initials`; pass \"\" for a decorative avatar. */\n  alt?: string;\n  /** Who this is. Names the image, and the initials when there is no image. */\n  name?: string;\n  /** Shown when there is no image, or when it fails to load. */\n  initials?: string;\n  size?: \"sm\" | \"md\" | \"lg\";\n}\n\nconst AvatarRowContext = React.createContext(false);\n\nconst styles = stylex.create({\n  avatar: {\n    width: \"2rem\",\n    height: \"2rem\",\n    borderRadius: \"50%\",\n    backgroundColor: vlak.dividerSubtle,\n    color: vlak.ink,\n    display: \"inline-flex\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n    fontSize: \"0.75rem\",\n    fontWeight: 600,\n    letterSpacing: \"-0.01em\",\n    overflow: \"hidden\",\n    flexShrink: 0,\n    userSelect: \"none\",\n  },\n  sm: {\n    width: \"1.5rem\",\n    height: \"1.5rem\",\n    fontSize: \"0.625rem\",\n  },\n  lg: {\n    width: \"3rem\",\n    height: \"3rem\",\n    fontSize: \"1rem\",\n  },\n  image: {\n    width: \"100%\",\n    height: \"100%\",\n    objectFit: \"cover\",\n  },\n  row: {\n    display: \"flex\",\n  },\n  inRow: {\n    borderWidth: 2,\n    borderStyle: \"solid\",\n    borderColor: vlak.paper,\n    marginInlineStart: {\n      default: \"-0.5rem\",\n      \":first-child\": 0,\n    },\n  },\n});\n\nexport const Avatar = React.forwardRef<HTMLSpanElement, AvatarProps>(function Avatar(\n  { src, alt, name, initials, size = \"md\", className, style, ...props },\n  ref,\n) {\n  const [failedSrc, setFailedSrc] = React.useState<string>();\n  const inRow = React.useContext(AvatarRowContext);\n  const showImage = src && src !== failedSrc;\n  const altText = alt ?? name ?? initials ?? \"\";\n  const sx = rs([\"rs-avatar\", size === \"sm\" && \"rs-avatar-sm\", size === \"lg\" && \"rs-avatar-lg\", className, inRow && \"rs-avatar-in-row\"], styles.avatar, size === \"sm\" && styles.sm, size === \"lg\" && styles.lg, inRow && styles.inRow);\n  const img = rs([\"rs-avatar-image\"], styles.image);\n  /* Initials stand in for a name only when one is given; otherwise they read as plain text. */\n  const named = !showImage && name ? { role: \"img\" as const, \"aria-label\": name } : null;\n  return (\n    <span ref={ref} {...named} {...props} className={sx.className} style={{ ...sx.style, ...style }}>\n      {showImage ? (\n        <img className={img.className} style={img.style} src={src} alt={altText} onError={() => setFailedSrc(src)} />\n      ) : (\n        initials\n      )}\n    </span>\n  );\n});\n\n/** Overlapping row with paper seams. */\nexport const AvatarRow = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(function AvatarRow(\n  { className, style, ...props },\n  ref,\n) {\n  const sx = rs([\"rs-avatar-row\", className], styles.row);\n  return (\n    <AvatarRowContext.Provider value={true}>\n      <div ref={ref} {...props} className={sx.className} style={{ ...sx.style, ...style }} />\n    </AvatarRowContext.Provider>\n  );\n});\n",
      "type": "registry:component",
      "target": "components/vlak/avatar.tsx"
    },
    {
      "path": "vlak/styles/avatar.css",
      "content": "/* ── avatar: generated from packages/react/src/components/avatar.tsx ── */\n.rs-avatar{width:2rem;height:2rem;border-radius:50%;background-color:var(--divider-subtle);color:var(--text);display:inline-flex;align-items:center;justify-content:center;font-size:0.75rem;font-weight:600;letter-spacing:-0.01em;overflow:hidden;flex-shrink:0;user-select:none}\n.rs-avatar-sm{width:1.5rem;height:1.5rem;font-size:0.625rem}\n.rs-avatar-lg{width:3rem;height:3rem;font-size:1rem}\n.rs-avatar-image{width:100%;height:100%;object-fit:cover}\n.rs-avatar-row{display:flex}\n.rs-avatar-in-row{border-width:2px;border-style:solid;border-color:var(--bg);margin-inline-start:-0.5rem}\n.rs-avatar-in-row:first-child{margin-inline-start:0}\n",
      "type": "registry:file",
      "target": "styles/vlak/avatar.css"
    }
  ],
  "meta": {
    "vlak": {
      "category": "content",
      "classes": [
        "rs-avatar",
        "rs-avatar-sm",
        "rs-avatar-lg",
        "rs-avatar-row",
        "rs-avatar-image",
        "rs-avatar-in-row"
      ],
      "snippet": "<div class=\"rs-avatar-row\"><span class=\"rs-avatar\">RV</span><span class=\"rs-avatar\">NO</span><span class=\"rs-avatar\">+3</span></div>",
      "cssOnly": false,
      "registryDependencies": [
        "vlak-lib"
      ],
      "aliases": [
        "Avatar",
        "Profile picture",
        "User image",
        "Avatar group"
      ],
      "example": "import { Avatar, AvatarRow } from \"@noorddev/vlak-react\";\n\n<Avatar src=\"/renn.jpg\" name=\"Renn\" initials=\"RV\" size=\"lg\" />\n<AvatarRow>\n  <Avatar name=\"Renn\" initials=\"RV\" />\n  <Avatar name=\"Noord\" initials=\"NO\" />\n  <Avatar initials=\"+3\" alt=\"\" />\n</AvatarRow>",
      "usage": {
        "use": [
          "A person or organisation next to their name, or a row of collaborators.",
          "initials as the fallback while the image loads or fails."
        ],
        "avoid": [
          "Logos and product images; use AspectRatio.",
          "Decorative circles without a subject."
        ]
      },
      "a11y": [
        "The image alt defaults to name, then initials; pass alt=\"\" for a decorative avatar.",
        "Initials with a name render role=\"img\" with aria-label; without a name they are plain text.",
        "A broken image falls back to the initials."
      ]
    }
  }
}
