{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "glass-contact-pill",
  "title": "Glass Contact Pill",
  "description": "Liquid-glass contact chip with an avatar (image or initials fallback) and name, for messaging apps",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "@glasscn/utils",
    "@glasscn/avatar",
    "@glasscn/liquid-glass"
  ],
  "files": [
    {
      "path": "components/ui/glasscn/glass-contact-pill.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { cn } from \"@/lib/utils\";\n\nimport { LiquidGlass, type LiquidGlassProps } from \"./liquid-glass\";\n\ntype GlassContactAvatarPlacement = \"top\" | \"leading\";\n\ntype GlassContactPillProps = Omit<React.ComponentProps<\"div\">, \"title\"> & {\n  /** Primary label, e.g. the contact's name. */\n  name: React.ReactNode;\n  /** Secondary line shown above the name, e.g. \"Maybe:\" or \"online\". */\n  caption?: React.ReactNode;\n  /** Avatar image source. When absent or it fails to load, the fallback is shown. */\n  src?: string;\n  /** Alt text for the avatar image. Defaults to the name when it is a string. */\n  alt?: string;\n  /**\n   * Avatar fallback content. Defaults to up-to-two initials derived from `name`\n   * (e.g. \"Alex Kostyniuk\" → \"AK\").\n   */\n  fallback?: React.ReactNode;\n  /** Where the avatar sits relative to the pill. */\n  avatarPlacement?: GlassContactAvatarPlacement;\n  /** Optional trailing content rendered after the label, e.g. a chevron or status dot. */\n  trailing?: React.ReactNode;\n  /** Props forwarded to the underlying LiquidGlass surface. */\n  liquidProps?: Omit<LiquidGlassProps, \"children\">;\n  /** Classes applied to the outer LiquidGlass surface. */\n  surfaceClassName?: string;\n};\n\nfunction initialsFromName(name: React.ReactNode) {\n  if (typeof name !== \"string\") return \"\";\n  return name\n    .trim()\n    .split(/\\s+/)\n    .slice(0, 2)\n    .map((word) => word[0]?.toUpperCase() ?? \"\")\n    .join(\"\");\n}\n\nfunction GlassContactPill({\n  name,\n  caption,\n  src,\n  alt,\n  fallback,\n  avatarPlacement = \"top\",\n  trailing,\n  liquidProps,\n  surfaceClassName,\n  className,\n  ...props\n}: GlassContactPillProps) {\n  const resolvedAlt = alt ?? (typeof name === \"string\" ? name : undefined);\n  const resolvedFallback = fallback ?? initialsFromName(name);\n  const trailingNode = trailing ?? null;\n\n  const isTop = avatarPlacement === \"top\";\n\n  const avatar = (\n    <Avatar\n      size=\"lg\"\n      className={cn(\n        \"shadow-[0_2px_10px_rgba(0,0,0,0.25)] ring-1 ring-white/40 after:border-white/30 dark:ring-white/15\",\n        isTop ? \"size-12\" : \"size-11\",\n      )}\n    >\n      {src ? <AvatarImage src={src} alt={resolvedAlt} /> : null}\n      <AvatarFallback className=\"font-medium\">{resolvedFallback}</AvatarFallback>\n    </Avatar>\n  );\n\n  const label = (\n    <div className={cn(\"flex min-w-0 flex-col\", isTop && \"items-center text-center\")}>\n      {caption ? <span className=\"text-sm leading-tight text-foreground/55\">{caption}</span> : null}\n      <span className=\"truncate text-sm leading-tight font-semibold tracking-tight\">{name}</span>\n    </div>\n  );\n\n  if (isTop) {\n    return (\n      <div\n        data-slot=\"glass-contact-pill\"\n        data-avatar-placement=\"top\"\n        className={cn(\"relative inline-flex w-fit flex-col items-center pt-9\", className)}\n        {...props}\n      >\n        <div className=\"absolute top-0 z-10\">{avatar}</div>\n        <LiquidGlass {...liquidProps} className={cn(\"w-full rounded-full\", surfaceClassName, liquidProps?.className)}>\n          <div className=\"relative flex min-w-10 items-center justify-center gap-3 px-4 pt-1 pb-1 text-foreground\">\n            {label}\n            {trailingNode ? (\n              <span className=\"flex size-5 shrink-0 items-center justify-center\">{trailingNode}</span>\n            ) : null}\n          </div>\n        </LiquidGlass>\n      </div>\n    );\n  }\n\n  return (\n    <div data-slot=\"glass-contact-pill\" data-avatar-placement=\"leading\" className={cn(\"w-fit\", className)} {...props}>\n      <LiquidGlass {...liquidProps} className={cn(\"rounded-full\", surfaceClassName, liquidProps?.className)}>\n        <div className=\"flex items-center gap-3 py-1.5 pr-5 pl-1.5 text-foreground\">\n          {avatar}\n          {label}\n          {trailingNode}\n        </div>\n      </LiquidGlass>\n    </div>\n  );\n}\n\nexport { GlassContactPill, type GlassContactPillProps, type GlassContactAvatarPlacement };\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}