{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "doc-1",
  "registryDependencies": [
    "@fulldev/button",
    "@fulldev/card",
    "@fulldev/dropdown-menu",
    "@fulldev/section",
    "@fulldev/toc",
    "@fulldev/typography",
    "@fulldev/icon"
  ],
  "files": [
    {
      "path": "src/components/blocks/doc-1.astro",
      "content": "---\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\nimport { buttonVariants } from \"@/components/ui/button/button-variants\"\nimport {\n  Card,\n  CardDescription,\n  CardFooter,\n  CardHeader,\n} from \"@/components/ui/card\"\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { Icon } from \"@/components/ui/icon\"\nimport { SectionContainer } from \"@/components/ui/section\"\nimport {\n  Toc,\n  TocMenu,\n  TocMenuItem,\n  TocMenuLink,\n  TocTitle,\n} from \"@/components/ui/toc\"\nimport {\n  Typography,\n  TypographyH1,\n  TypographyLead,\n} from \"@/components/ui/typography\"\n\ntype Props = {\n  class?: string\n  title: string\n  description?: string\n  copyButton?: {\n    id: string\n    source: string\n  }\n  markdownUrl?: string\n  tocItems: {\n    depth: number\n    href: string\n    label: string\n  }[]\n  callout?: {\n    description: string\n    button: {\n      label: string\n      href: string\n      variant?: \"default\" | \"outline\" | \"secondary\" | \"ghost\"\n    }\n  }\n  previousPage?: {\n    href: string\n    title: string\n  }\n  nextPage?: {\n    href: string\n    title: string\n  }\n  labels: {\n    copyMarkdown: string\n    openIn: string\n    openInMarkdown: string\n    openInChatGPT: string\n    openInClaude: string\n    openInCursor: string\n    pagination: {\n      previous: string\n      next: string\n      ariaLabel: string\n    }\n    toc: string\n  }\n}\n\nconst {\n  class: className,\n  title,\n  description,\n  copyButton,\n  markdownUrl,\n  tocItems,\n  callout,\n  previousPage,\n  nextPage,\n  labels,\n} = Astro.props\nconst showCopyButton = Boolean(copyButton)\nconst showOpenButton = Boolean(markdownUrl)\nconst showPagination = Boolean(previousPage || nextPage)\nconst assistantPrompt = markdownUrl\n  ? `Read ${markdownUrl}, I want to ask questions about it.`\n  : \"\"\nconst openLinks = markdownUrl\n  ? [\n      {\n        label: labels.openInMarkdown,\n        href: markdownUrl,\n        icon: \"markdown\",\n      },\n      {\n        label: labels.openInChatGPT,\n        href: `https://chatgpt.com/?hints=search&q=${encodeURIComponent(assistantPrompt)}`,\n        icon: \"chatgpt\",\n      },\n      {\n        label: labels.openInClaude,\n        href: `https://claude.ai/new?q=${encodeURIComponent(assistantPrompt)}`,\n        icon: \"claude\",\n      },\n      {\n        label: labels.openInCursor,\n        href: `https://cursor.com/link/prompt?text=${encodeURIComponent(assistantPrompt)}`,\n        icon: \"cursor\",\n      },\n    ]\n  : []\n---\n\n<SectionContainer\n  class={cn(\n    \"gap-10 pt-10 pb-8 sm:pt-12 sm:pb-10 xl:grid xl:grid-cols-[minmax(0,1fr)_16rem] xl:items-start xl:gap-x-16\",\n    className\n  )}\n>\n  <div class=\"mx-auto flex w-full max-w-3xl min-w-0 flex-col gap-10\">\n    <header\n      class=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\"\n    >\n      <div class=\"flex min-w-0 flex-1 flex-col gap-2\">\n        <TypographyH1\n          size=\"sm\"\n          class=\"text-foreground text-left tracking-tight\"\n        >\n          {title}\n        </TypographyH1>\n        {\n          description && (\n            <TypographyLead class=\"max-w-2xl text-base! leading-7\">\n              {description}\n            </TypographyLead>\n          )\n        }\n      </div>\n      <div class=\"flex shrink-0 items-center gap-2 self-start\">\n        {\n          showCopyButton && (\n            <Button\n              id={copyButton?.id}\n              type=\"button\"\n              variant=\"outline\"\n              size=\"xs\"\n              data-source={copyButton?.source}\n              aria-label={labels.copyMarkdown}\n            >\n              <Icon\n                name=\"copy\"\n                data-copy-icon\n                class=\"docs-copy-icon size-3.5\"\n              />\n              <Icon\n                name=\"check\"\n                data-check-icon\n                class=\"docs-check-icon hidden size-3.5\"\n              />\n              <span>{labels.copyMarkdown}</span>\n            </Button>\n          )\n        }\n        {\n          showOpenButton && (\n            <DropdownMenu>\n              <DropdownMenuTrigger\n                class={buttonVariants({ variant: \"outline\", size: \"xs\" })}\n              >\n                <span>{labels.openIn}</span>\n                <Icon name=\"chevron-down\" class=\"size-3.5 opacity-70\" />\n              </DropdownMenuTrigger>\n              <DropdownMenuContent align=\"end\" sideOffset={6} class=\"w-56\">\n                {openLinks.map((link) => (\n                  <a\n                    href={link.href}\n                    target=\"_blank\"\n                    rel=\"noreferrer noopener\"\n                    class=\"hover:bg-accent hover:text-accent-foreground flex items-center gap-2 rounded-sm px-2 py-1.5 text-sm transition-colors outline-none\"\n                  >\n                    {link.icon === \"markdown\" && (\n                      <Icon name=\"markdown\" class=\"size-4 fill-current\" />\n                    )}\n                    {link.icon === \"chatgpt\" && (\n                      <svg\n                        role=\"img\"\n                        viewBox=\"0 0 24 24\"\n                        fill=\"currentColor\"\n                        class=\"size-4\"\n                        aria-hidden=\"true\"\n                      >\n                        <path d=\"M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.182a5.985 5.985 0 0 0-3.998 2.9 6.046 6.046 0 0 0 .743 7.097 5.98 5.98 0 0 0 .511 4.91 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.989 5.989 0 0 0 3.998-2.9 6.056 6.056 0 0 0-.748-7.073ZM13.26 22.43a4.476 4.476 0 0 1-2.876-1.04l.142-.081 4.778-2.758a.795.795 0 0 0 .393-.681v-6.737l2.02 1.169a.071.071 0 0 1 .038.052v5.583a4.504 4.504 0 0 1-4.495 4.494Zm-9.66-4.125a4.471 4.471 0 0 1-.535-3.014l.142.085 4.783 2.758a.771.771 0 0 0 .781 0l5.843-3.368v2.332a.08.08 0 0 1-.034.062L9.74 19.95a4.499 4.499 0 0 1-6.14-1.646ZM2.34 7.896a4.485 4.485 0 0 1 2.366-1.973V11.6a.766.766 0 0 0 .388.677l5.814 3.354-2.02 1.169a.076.076 0 0 1-.071 0l-4.83-2.787A4.504 4.504 0 0 1 2.34 7.872Zm16.596 3.856-5.833-3.388L15.12 7.2a.076.076 0 0 1 .071 0l4.83 2.791a4.494 4.494 0 0 1-.676 8.104v-5.677a.79.79 0 0 0-.407-.667Zm2.011-3.024-.142-.085-4.774-2.782a.776.776 0 0 0-.785 0L9.409 9.23V6.897a.066.066 0 0 1 .028-.061l4.83-2.787a4.499 4.499 0 0 1 6.68 4.66ZM8.307 12.863l-2.02-1.164a.08.08 0 0 1-.038-.057V6.074a4.499 4.499 0 0 1 7.376-3.453l-.142.08-4.778 2.758a.795.795 0 0 0-.393.681Zm1.097-2.365 2.602-1.5 2.607 1.5v2.999l-2.597 1.5-2.607-1.5Z\" />\n                      </svg>\n                    )}\n                    {link.icon === \"claude\" && (\n                      <Icon name=\"claude\" class=\"size-4 fill-current\" />\n                    )}\n                    {link.icon === \"cursor\" && (\n                      <Icon name=\"cursor\" class=\"size-4 fill-current\" />\n                    )}\n                    <span>{link.label}</span>\n                    <Icon\n                      name=\"external-link\"\n                      class=\"text-muted-foreground ml-auto size-3.5\"\n                    />\n                  </a>\n                ))}\n              </DropdownMenuContent>\n            </DropdownMenu>\n          )\n        }\n      </div>\n    </header>\n\n    <Typography as=\"article\" size=\"sm\">\n      <slot />\n    </Typography>\n\n    {\n      showPagination && (\n        <nav\n          class=\"flex items-center justify-between gap-3\"\n          aria-label={labels.pagination.ariaLabel}\n        >\n          {previousPage ? (\n            <Button\n              as=\"a\"\n              href={previousPage.href}\n              variant=\"outline\"\n              class=\"h-auto min-w-0 items-center justify-start gap-2 px-3 py-2 whitespace-normal\"\n            >\n              <Icon name=\"arrow-left\" class=\"size-4\" />\n              <span class=\"truncate text-sm font-medium\">\n                {previousPage.title}\n              </span>\n            </Button>\n          ) : (\n            <div aria-hidden=\"true\" />\n          )}\n\n          {nextPage ? (\n            <Button\n              as=\"a\"\n              href={nextPage.href}\n              variant=\"outline\"\n              class=\"h-auto min-w-0 items-center justify-end gap-2 px-3 py-2 text-right whitespace-normal\"\n            >\n              <span class=\"truncate text-sm font-medium\">{nextPage.title}</span>\n              <Icon name=\"arrow-right\" class=\"size-4\" />\n            </Button>\n          ) : (\n            <div aria-hidden=\"true\" />\n          )}\n        </nav>\n      )\n    }\n  </div>\n\n  {\n    (tocItems.length > 0 || callout) && (\n      <aside class=\"hidden w-64 xl:sticky xl:top-12 xl:mr-0 xl:ml-auto xl:block xl:self-start\">\n        <div class=\"flex flex-col gap-6\">\n          {tocItems.length > 0 && (\n            <Toc aria-label={labels.toc}>\n              <TocTitle>{labels.toc}</TocTitle>\n              <TocMenu>\n                {tocItems.map((item) => (\n                  <TocMenuItem>\n                    <TocMenuLink href={item.href} depth={item.depth}>\n                      {item.label}\n                    </TocMenuLink>\n                  </TocMenuItem>\n                ))}\n              </TocMenu>\n            </Toc>\n          )}\n\n          {callout && (\n            <Card size=\"sm\">\n              <CardHeader>\n                <CardDescription>{callout.description}</CardDescription>\n              </CardHeader>\n              <CardFooter>\n                <Button\n                  as=\"a\"\n                  href={callout.button.href}\n                  variant={callout.button.variant}\n                  size=\"sm\"\n                  target=\"_blank\"\n                  rel=\"noreferrer\"\n                >\n                  {callout.button.label}\n                </Button>\n              </CardFooter>\n            </Card>\n          )}\n        </div>\n      </aside>\n    )\n  }\n</SectionContainer>\n\n<script is:inline>\n  const copyIcon = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"></rect><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"></path></svg>`\n  const checkIcon = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6 9 17l-5-5\"></path></svg>`\n  document.querySelectorAll(\"[data-slot='typography'] > pre\").forEach((pre) => {\n    if (pre.closest(\".docs-code-block\")) return\n    const wrapper = document.createElement(\"div\")\n    const button = document.createElement(\"button\")\n    wrapper.className = \"docs-code-block\"\n    button.type = \"button\"\n    button.className = \"docs-code-copy\"\n    button.ariaLabel = \"Copy code\"\n    button.innerHTML = `<span data-copy-icon>${copyIcon}</span><span data-check-icon class=\"hidden\">${checkIcon}</span>`\n    pre.before(wrapper)\n    wrapper.append(pre, button)\n  })\n\n  const writeToClipboard = async (text) => {\n    if (navigator.clipboard && window.isSecureContext) {\n      try {\n        await navigator.clipboard.writeText(text)\n        return true\n      } catch {\n        return false\n      }\n    }\n\n    return false\n  }\n\n  const showCopySuccess = (button) => {\n    button.querySelector(\"[data-copy-icon]\")?.classList.add(\"hidden\")\n    button.querySelector(\"[data-check-icon]\")?.classList.remove(\"hidden\")\n    setTimeout(() => {\n      button.querySelector(\"[data-copy-icon]\")?.classList.remove(\"hidden\")\n      button.querySelector(\"[data-check-icon]\")?.classList.add(\"hidden\")\n    }, 1200)\n  }\n\n  document.addEventListener(\"click\", async (event) => {\n    const button = event.target?.closest?.(\n      \"[id^='docs-copy-page-'], .docs-code-copy\"\n    )\n    if (!button) return\n    const source =\n      button.dataset.source ??\n      button\n        .closest(\".docs-code-block\")\n        ?.querySelector(\"pre\")\n        ?.textContent?.replace(/\\n$/, \"\")\n    if (!source) return\n\n    const copied = await writeToClipboard(source)\n    if (copied) showCopySuccess(button)\n  })\n</script>\n",
      "type": "registry:block"
    }
  ],
  "type": "registry:block"
}