{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "copy-for-ai",
  "title": "Copy for AI",
  "description": "Hands a documentation page to an assistant as markdown.",
  "dependencies": [
    "lucide-react@^1.31.0"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/default/copy-for-ai/copy-for-ai.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Check, ChevronDown, Copy, FileText } from \"lucide-react\"\nimport { cn } from \"@/lib/utils\"\n\nexport type AiDestination = {\n  id: string\n  name: string\n  /** Builds the address opened for this destination. */\n  href: (prompt: string) => string\n  icon?: React.ReactNode\n}\n\nexport type CopyForAiProps = Omit<\n  React.HTMLAttributes<HTMLDivElement>,\n  \"children\"\n> & {\n  /** The page as markdown. This is what the main button copies. */\n  markdown: string\n  /** Where the same markdown is served, for reading and for handing to an assistant. */\n  markdownUrl?: string\n  /** The instruction sent to a destination. Defaults to reading the markdown. */\n  prompt?: string\n  destinations?: readonly AiDestination[]\n  copyLabel?: string\n  copiedLabel?: string\n  viewLabel?: string\n  menuLabel?: string\n}\n\nexport const defaultDestinations: readonly AiDestination[] = [\n  {\n    id: \"chatgpt\",\n    name: \"ChatGPT\",\n    href: (prompt) =>\n      `https://chatgpt.com/?hints=search&q=${encodeURIComponent(prompt)}`,\n  },\n  {\n    id: \"claude\",\n    name: \"Claude\",\n    href: (prompt) => `https://claude.ai/new?q=${encodeURIComponent(prompt)}`,\n  },\n]\n\nexport function CopyForAi({\n  markdown,\n  markdownUrl,\n  prompt,\n  destinations = defaultDestinations,\n  copyLabel = \"Copy page\",\n  copiedLabel = \"Copied\",\n  viewLabel = \"View as Markdown\",\n  menuLabel = \"More page actions\",\n  className,\n  ...rootProps\n}: CopyForAiProps) {\n  const [copyState, setCopyState] = React.useState<\"idle\" | \"copied\" | \"error\">(\n    \"idle\"\n  )\n  const [open, setOpen] = React.useState(false)\n  const rootRef = React.useRef<HTMLDivElement>(null)\n\n  const instruction =\n    prompt ?? (markdownUrl ? `Read ${markdownUrl}.` : markdown)\n\n  React.useEffect(() => {\n    if (!open) return\n\n    const close = (event: MouseEvent) => {\n      if (!rootRef.current?.contains(event.target as Node)) setOpen(false)\n    }\n    const onEscape = (event: KeyboardEvent) => {\n      if (event.key === \"Escape\") setOpen(false)\n    }\n\n    document.addEventListener(\"pointerdown\", close)\n    document.addEventListener(\"keydown\", onEscape)\n\n    return () => {\n      document.removeEventListener(\"pointerdown\", close)\n      document.removeEventListener(\"keydown\", onEscape)\n    }\n  }, [open])\n\n  const copy = async () => {\n    try {\n      await navigator.clipboard.writeText(markdown)\n      setCopyState(\"copied\")\n    } catch {\n      // Denied permission, an insecure context, or a sandboxed frame.\n      setCopyState(\"error\")\n    }\n    setOpen(false)\n    window.setTimeout(() => setCopyState(\"idle\"), 1400)\n  }\n\n  const item =\n    \"hover:bg-muted flex items-center gap-2.5 rounded-[calc(var(--radius)-0.25rem)] px-2.5 py-2 text-sm whitespace-nowrap text-inherit no-underline transition-colors duration-150 motion-reduce:transition-none\"\n\n  return (\n    <div\n      ref={rootRef}\n      data-slot=\"copy-for-ai\"\n      className={cn(\"relative inline-flex\", className)}\n      {...rootProps}\n    >\n      <button\n        type=\"button\"\n        data-slot=\"copy-for-ai-copy\"\n        className=\"border-border bg-card hover:bg-muted focus-visible:ring-ring inline-flex min-h-8 items-center gap-2 rounded-l-[calc(var(--radius)-0.2rem)] border px-2.5 text-xs font-semibold transition-colors duration-150 focus-visible:ring-2 focus-visible:outline-none motion-reduce:transition-none\"\n        onClick={copy}\n      >\n        {copyState === \"copied\" ? (\n          <Check aria-hidden=\"true\" size={13} />\n        ) : (\n          <Copy aria-hidden=\"true\" size={13} />\n        )}\n        {copyState === \"copied\" ? copiedLabel : copyLabel}\n      </button>\n\n      <button\n        type=\"button\"\n        aria-expanded={open}\n        aria-haspopup=\"menu\"\n        aria-label={menuLabel}\n        className=\"border-border bg-card hover:bg-muted focus-visible:ring-ring inline-flex min-h-8 w-7 items-center justify-center rounded-r-[calc(var(--radius)-0.2rem)] border border-l-0 transition-colors duration-150 focus-visible:ring-2 focus-visible:outline-none motion-reduce:transition-none\"\n        onClick={() => setOpen((current) => !current)}\n      >\n        <ChevronDown aria-hidden=\"true\" size={13} />\n      </button>\n\n      {open ? (\n        <div\n          role=\"menu\"\n          aria-label={menuLabel}\n          className=\"border-border bg-card absolute top-full right-0 z-50 mt-1.5 grid min-w-56 gap-0.5 rounded-[var(--radius)] border p-1.5 shadow-lg\"\n        >\n          {markdownUrl ? (\n            <a\n              className={item}\n              href={markdownUrl}\n              rel=\"noreferrer noopener\"\n              role=\"menuitem\"\n              target=\"_blank\"\n            >\n              <FileText aria-hidden=\"true\" size={15} />\n              {viewLabel}\n            </a>\n          ) : null}\n\n          {destinations.map((destination) => (\n            <a\n              key={destination.id}\n              className={item}\n              href={destination.href(instruction)}\n              rel=\"noreferrer noopener nofollow\"\n              role=\"menuitem\"\n              target=\"_blank\"\n            >\n              {destination.icon ?? <Copy aria-hidden=\"true\" size={15} />}\n              Open in {destination.name}\n            </a>\n          ))}\n        </div>\n      ) : null}\n\n      <span aria-live=\"polite\" className=\"sr-only\">\n        {copyState === \"copied\" ? \"Page markdown copied.\" : \"\"}\n      </span>\n    </div>\n  )\n}\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "docs",
    "ai",
    "markdown",
    "copy"
  ],
  "type": "registry:ui"
}