{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "link-preview",
  "title": "Link Preview",
  "description": "A horizontal link preview with an image, seller details, and optional product pricing and ratings.",
  "dependencies": [
    "@solar-icons/react@^2.2.0",
    "cn@^0.3.0"
  ],
  "registryDependencies": [
    "https://pastaui.com/r/pastaui-styles.json"
  ],
  "files": [
    {
      "path": "src/components/ai/link-preview.tsx",
      "content": "import { StarIcon } from '@solar-icons/react/bold/star'\nimport { GlobalIcon as Globe2Icon } from '@solar-icons/react/linear/global'\nimport * as React from 'react'\n\nimport { cn } from 'cn'\n\ninterface LinkPreviewProps extends React.ComponentProps<'article'> {\n  description?: string\n  imageSrc?: string\n  price?: string\n  seller?: string\n  rating?: number\n  reviewCount?: string\n  onOpen?: () => void\n  siteName?: string\n  title: string\n  url: string\n}\n\nfunction LinkPreview({\n  className,\n  description,\n  imageSrc,\n  price,\n  seller,\n  rating,\n  reviewCount,\n  onOpen,\n  siteName,\n  title,\n  url,\n  ...props\n}: LinkPreviewProps) {\n  const [imageLoaded, setImageLoaded] = React.useState(false)\n  let hostname = url\n  try {\n    hostname = new URL(url).hostname.replace('www.', '')\n  } catch {\n    hostname = url\n  }\n\n  return (\n    <article\n      data-slot=\"link-preview\"\n      className={cn(\n        'flex items-center gap-4 rounded-[16px] font-sans text-sm leading-5 font-[450] tracking-[-0.05px] text-muted-foreground sm:gap-6',\n        className,\n      )}\n      {...props}\n    >\n      <div className=\"flex size-24 shrink-0 items-center justify-center overflow-hidden rounded-[16px] bg-muted sm:size-40\">\n        {imageSrc ? (\n          <img\n            alt=\"\"\n            className={cn(\n              'size-full object-cover transition-opacity duration-200 ease-[cubic-bezier(0.23,1,0.32,1)]',\n              !imageLoaded && 'opacity-0',\n            )}\n            height={160}\n            loading=\"lazy\"\n            onLoad={() => setImageLoaded(true)}\n            ref={(image) => {\n              if (image?.complete) setImageLoaded(true)\n            }}\n            src={imageSrc}\n            width={160}\n          />\n        ) : (\n          <Globe2Icon className=\"size-6 text-muted-foreground\" />\n        )}\n      </div>\n      <div className=\"flex min-w-0 flex-1 flex-col gap-2\">\n        <h3 className=\"card-heading leading-6 text-foreground\">\n          <a\n            href={url}\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n            className=\"rounded-sm outline-none hover:underline focus-visible:ring-2 focus-visible:ring-ring\"\n            onClick={(event) => {\n              if (onOpen) {\n                event.preventDefault()\n                onOpen()\n              }\n            }}\n          >\n            {title}\n          </a>\n        </h3>\n        <p className=\"text-muted-foreground\">\n          {price && (\n            <>\n              <span className=\"tabular-nums\">{price}</span>\n              <span aria-hidden=\"true\"> · </span>\n            </>\n          )}\n          {siteName ?? hostname}\n          {seller && ` – ${seller}`}\n        </p>\n        {rating !== undefined && (\n          <p\n            className=\"flex items-center gap-2 text-muted-foreground\"\n            aria-label={`${rating} out of 5 stars${reviewCount ? `, ${reviewCount} reviews` : ''}`}\n          >\n            <StarIcon aria-hidden=\"true\" className=\"size-4 shrink-0\" />\n            <span>\n              {rating.toFixed(1)}\n              {reviewCount && ` (${reviewCount})`}\n            </span>\n          </p>\n        )}\n        {description && (\n          <p className=\"line-clamp-2 text-xs leading-5 text-muted-foreground\">{description}</p>\n        )}\n      </div>\n    </article>\n  )\n}\n\nexport { LinkPreview }\nexport type { LinkPreviewProps }\n",
      "type": "registry:component",
      "target": "@components/ai/link-preview.tsx"
    }
  ],
  "type": "registry:component"
}