{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "markdown-blocks",
  "title": "Markdown Blocks",
  "description": "Extracted document regions rendered as markdown, each one selectable.",
  "dependencies": [
    "react-markdown@^10.1.0",
    "remark-gfm@^4.0.1"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/default/markdown-blocks/markdown-blocks.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport Markdown from \"react-markdown\"\nimport remarkGfm from \"remark-gfm\"\nimport { cn } from \"@/lib/utils\"\n\nexport type MarkdownBlockKind =\n  \"heading\" | \"paragraph\" | \"table\" | \"list\" | \"figure\" | \"footer\"\n\nexport type MarkdownBlock = {\n  id: string\n  kind?: MarkdownBlockKind\n  content: string\n  page?: number\n  label?: string\n}\n\nexport type MarkdownBlocksProps = Omit<\n  React.HTMLAttributes<HTMLElement>,\n  \"children\" | \"onSelect\"\n> & {\n  blocks: MarkdownBlock[]\n  activeId?: string | null\n  defaultActiveId?: string | null\n  onActiveChange?: (id: string | null) => void\n  showKinds?: boolean\n  label?: string\n}\n\nconst kindLabel: Record<MarkdownBlockKind, string> = {\n  heading: \"Heading\",\n  paragraph: \"Paragraph\",\n  table: \"Table\",\n  list: \"List\",\n  figure: \"Figure\",\n  footer: \"Footer\",\n}\n\nexport function MarkdownBlocks({\n  blocks,\n  activeId,\n  defaultActiveId = null,\n  onActiveChange,\n  showKinds = true,\n  label = \"Document blocks\",\n  className,\n  ...rootProps\n}: MarkdownBlocksProps) {\n  const [uncontrolled, setUncontrolled] = React.useState(defaultActiveId)\n  const selected = activeId === undefined ? uncontrolled : activeId\n\n  const select = (id: string) => {\n    const next = selected === id ? null : id\n    if (activeId === undefined) setUncontrolled(next)\n    onActiveChange?.(next)\n  }\n\n  return (\n    <section\n      data-slot=\"markdown-blocks\"\n      aria-label={label}\n      className={cn(\n        \"border-border bg-card text-card-foreground rounded-[var(--radius)] border\",\n        className\n      )}\n      {...rootProps}\n    >\n      <ol className=\"grid gap-1 p-2\">\n        {blocks.map((block) => {\n          const isActive = block.id === selected\n\n          return (\n            <li key={block.id}>\n              <button\n                type=\"button\"\n                data-slot=\"markdown-block\"\n                data-kind={block.kind}\n                data-active={isActive || undefined}\n                aria-pressed={isActive}\n                className={cn(\n                  \"focus-visible:ring-ring w-full rounded-[calc(var(--radius)-0.25rem)] border border-transparent px-3 py-2 text-left text-sm focus-visible:ring-2 focus-visible:outline-none\",\n                  isActive\n                    ? \"border-primary bg-primary/5\"\n                    : \"hover:border-border hover:bg-muted/40 transition-colors duration-150 motion-reduce:transition-none\"\n                )}\n                onClick={() => select(block.id)}\n              >\n                {showKinds && block.kind ? (\n                  <span className=\"text-muted-foreground mb-1 flex items-center gap-2 text-[0.65rem] font-bold tracking-[0.08em] uppercase\">\n                    {block.label ?? kindLabel[block.kind]}\n                    {block.page != null ? (\n                      <span className=\"font-[family-name:var(--font-mono),monospace] normal-case\">\n                        p.{block.page}\n                      </span>\n                    ) : null}\n                  </span>\n                ) : null}\n\n                <div className=\"[&_a]:underline [&_a]:underline-offset-4 [&_h1]:text-lg [&_h1]:font-semibold [&_h2]:text-base [&_h2]:font-semibold [&_h3]:font-semibold [&_li]:my-0.5 [&_ol]:list-decimal [&_ol]:pl-5 [&_p]:leading-relaxed [&_table]:w-full [&_table]:border-collapse [&_td]:border [&_td]:px-2 [&_td]:py-1 [&_th]:border [&_th]:px-2 [&_th]:py-1 [&_th]:text-left [&_ul]:list-disc [&_ul]:pl-5 [&>*+*]:mt-2\">\n                  <Markdown remarkPlugins={[remarkGfm]}>\n                    {block.content}\n                  </Markdown>\n                </div>\n              </button>\n            </li>\n          )\n        })}\n      </ol>\n    </section>\n  )\n}\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "document",
    "markdown",
    "layout",
    "ai"
  ],
  "type": "registry:ui"
}