{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "link",
  "title": "Link",
  "description": "Astro anchors for page paths, external URLs, phone numbers, and obfuscated email.",
  "dependencies": [
    "cn@0.4.0"
  ],
  "registryDependencies": [
    "@gnostic/button"
  ],
  "files": [
    {
      "path": "packages/ui/src/components/ui/link/index.ts",
      "content": "export { default as Link } from \"./link.astro\"\n\nexport type { LinkProps } from \"./types.ts\"\n",
      "type": "registry:file",
      "target": "~/src/components/ui/link/index.ts"
    },
    {
      "path": "packages/ui/src/components/ui/link/link.astro",
      "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"cn\"\nimport { buttonVariants } from \"../button/index.ts\"\nimport type { LinkProps } from \"./types.ts\"\n\n/** Anchor attributes pass through. `href` is required by `LinkProps`. */\ntype Props = Omit<HTMLAttributes<\"a\">, \"href\"> & LinkProps\n\nconst {\n  class: className,\n  \"class:list\": classList,\n  variant,\n  size = \"lg\",\n  externalInNewTab = true,\n  prefetch = true,\n  href: rawHref,\n  title,\n  target: targetProp,\n  rel: relProp,\n  ...rest\n} = Astro.props\n\nconst href = rawHref ?? \"#\"\n\nconst isExternal = href.startsWith(\"http\")\nconst isHash = href.startsWith(\"#\")\nconst isMail = href.startsWith(\"mailto:\")\nconst isTel = href.startsWith(\"tel:\")\nconst isInternal = !isExternal && !isHash && !isMail && !isTel\nconst isContact = isMail || isTel\n\nconst target =\n  targetProp ?? (isExternal && externalInNewTab ? \"_blank\" : undefined)\n\nconst rel =\n  relProp ??\n  (isExternal\n    ? \"noopener nofollow\"\n    : isInternal && prefetch\n      ? \"prefetch\"\n      : undefined)\n\n/** Prefix site BASE_URL for root-relative internal paths. */\nlet parsedUrl = href\nif (!isExternal && !isHash && href.startsWith(\"/\")) {\n  const basePrefix = (import.meta.env.BASE_URL ?? \"/\").replace(/\\/$/, \"\")\n  parsedUrl = `${basePrefix}${href}`\n}\n\n/** Obfuscate mailto/tel hrefs so scrapers don't see them in the markup. */\nlet dataContact: string | undefined\nif (isContact) {\n  parsedUrl = \"#\"\n  dataContact = btoa(href)\n}\n---\n\n<a\n  data-slot=\"button\"\n  data-size={size}\n  data-variant={variant ?? \"default\"}\n  href={parsedUrl}\n  title={title || undefined}\n  class:list={[\n    \"link\",\n    {\n      \"is-external\": isExternal,\n      \"is-internal\": isInternal,\n      \"is-hash\": isHash,\n      \"is-mail\": isMail,\n      \"is-tel\": isTel,\n    },\n    cn(buttonVariants({ variant, size }), className),\n    classList,\n  ]}\n  data-contact={dataContact}\n  target={target}\n  rel={rel}\n  {...rest}\n>\n  <slot />\n</a>\n<script>\n  /**\n   * One delegated listener for all mail/tel links. Astro already includes this\n   * script once per page; delegation avoids attaching a listener to each link\n   * and still works if a contact link is added after the initial render.\n   */\n  document.addEventListener(\"click\", (event) => {\n    const link = (event.target as Element | null)?.closest(\n      \"a.link.is-mail, a.link.is-tel\",\n    )\n    if (!(link instanceof HTMLAnchorElement)) return\n\n    const contactHrefRaw = link.getAttribute(\"data-contact\")\n    if (!contactHrefRaw) return\n\n    event.preventDefault()\n    window.location.href = atob(contactHrefRaw)\n  })\n</script>\n",
      "type": "registry:file",
      "target": "~/src/components/ui/link/link.astro"
    },
    {
      "path": "packages/ui/src/components/ui/link/types.ts",
      "content": "import type { ButtonVariantProps } from '../button/button-variants.ts'\n\n/**\n * Props for a destination anchor.\n * Standard anchor attributes such as `class`, `target`, `title`, and `rel`\n * are also accepted on the component.\n */\nexport interface LinkProps extends ButtonVariantProps {\n    /**\n     * Destination address.\n     *\n     * A site path stays on this site. An `http` URL opens in a new tab.\n     * A `mailto:` or `tel:` value is stored until the visitor clicks.\n     */\n    href: string\n    /**\n     * Open an external URL in a new tab.\n     *\n     * @default true\n     */\n    externalInNewTab?: boolean\n    /**\n     * Add `rel=\"prefetch\"` on an internal path.\n     *\n     * @default true\n     */\n    prefetch?: boolean\n}\n",
      "type": "registry:file",
      "target": "~/src/components/ui/link/types.ts"
    }
  ],
  "meta": {
    "framework": "astro",
    "source": "@gnostic/ui"
  },
  "docs": "https://ui.gnosticai.com/components/link",
  "categories": [
    "ui"
  ],
  "type": "registry:ui"
}
