{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "elements-canvas-split",
  "type": "registry:component",
  "title": "Canvas",
  "description": "The thread steps aside and the document takes the room, still being written as you read.",
  "registryDependencies": [
    "https://r.assistant-ui.com/elements-surfaces.json"
  ],
  "dependencies": [
    "lucide-react"
  ],
  "files": [
    {
      "type": "registry:component",
      "path": "components/assistant-ui/elements/canvas-split.tsx",
      "content": "\"use client\";\n\nimport type { ComponentProps } from \"react\";\nimport { CheckIcon, CopyIcon, FileTextIcon, XIcon } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { field, ghostButton, mono, paper } from \"./surfaces\";\n\nexport function CanvasSplit({ className, ...props }: ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"canvas-split\"\n      className={cn(\n        paper,\n        \"flex w-full max-w-3xl flex-col overflow-hidden rounded-[20px] md:h-80 md:flex-row\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function CanvasSplitThread({\n  className,\n  ...props\n}: ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"canvas-split-thread\"\n      className={cn(\n        \"border-foreground/[0.07] flex flex-col gap-3 border-b p-4 md:w-[15rem] md:shrink-0 md:overflow-y-auto md:border-r md:border-b-0\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function CanvasSplitMessage({\n  speaker,\n  className,\n  ...props\n}: ComponentProps<\"div\"> & { speaker: \"user\" | \"assistant\" }) {\n  return (\n    <div\n      data-slot=\"canvas-split-message\"\n      data-speaker={speaker}\n      className={cn(\n        \"fade-in animate-in fill-mode-both text-[13px] leading-relaxed duration-300\",\n        speaker === \"user\"\n          ? cn(field, \"text-foreground/80 ms-auto rounded-2xl px-3 py-2\")\n          : \"text-foreground/60\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function CanvasSplitDocument({\n  className,\n  ...props\n}: ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"canvas-split-document\"\n      className={cn(\"flex min-w-0 flex-1 flex-col\", className)}\n      {...props}\n    />\n  );\n}\n\nexport function CanvasSplitHeader({\n  title,\n  version,\n  saved,\n  onCopy,\n  onClose,\n  className,\n  ...props\n}: Omit<ComponentProps<\"div\">, \"children\" | \"title\"> & {\n  title: string;\n  version: number;\n  saved: boolean;\n  onCopy?: () => void;\n  onClose?: () => void;\n}) {\n  return (\n    <div\n      data-slot=\"canvas-split-header\"\n      className={cn(\n        \"border-foreground/[0.07] flex items-center gap-2 border-b px-3.5 py-2.5\",\n        className,\n      )}\n      {...props}\n    >\n      <FileTextIcon className=\"text-foreground/35 size-3.5 shrink-0\" />\n      <span className=\"min-w-0 flex-1 truncate text-[13px] font-medium\">\n        {title}\n      </span>\n      <span className={cn(mono, \"text-foreground/30 shrink-0\")}>\n        v{version}\n      </span>\n      <span\n        className={cn(\n          mono,\n          \"shrink-0 transition-colors duration-300\",\n          saved\n            ? \"text-emerald-600 dark:text-emerald-400\"\n            : \"text-foreground/30\",\n        )}\n      >\n        {saved ? (\n          <span className=\"flex items-center gap-1\">\n            <CheckIcon className=\"size-3\" />\n            saved\n          </span>\n        ) : (\n          \"editing\"\n        )}\n      </span>\n      <button\n        type=\"button\"\n        aria-label={`Copy ${title}`}\n        onClick={onCopy}\n        disabled={!onCopy}\n        className={cn(\n          ghostButton,\n          \"size-7 shrink-0 disabled:pointer-events-none disabled:opacity-30\",\n        )}\n      >\n        <CopyIcon className=\"size-3.5\" />\n      </button>\n      <button\n        type=\"button\"\n        aria-label=\"Close the canvas\"\n        onClick={onClose}\n        disabled={!onClose}\n        className={cn(\n          ghostButton,\n          \"size-7 shrink-0 disabled:pointer-events-none disabled:opacity-30\",\n        )}\n      >\n        <XIcon className=\"size-3.5\" />\n      </button>\n    </div>\n  );\n}\n\nexport function CanvasSplitBody({\n  writing,\n  className,\n  children,\n  ...props\n}: ComponentProps<\"div\"> & { writing?: boolean }) {\n  return (\n    <div\n      data-slot=\"canvas-split-body\"\n      className={cn(\n        \"flex min-h-[9rem] flex-1 flex-col gap-1.5 overflow-y-auto p-4\",\n        className,\n      )}\n      {...props}\n    >\n      {children}\n      {writing && (\n        <span\n          aria-hidden\n          className=\"bg-foreground/70 h-[1.05em] w-[2px] animate-pulse rounded-full motion-reduce:animate-none\"\n        />\n      )}\n    </div>\n  );\n}\n\nexport function CanvasSplitLine({\n  heading,\n  className,\n  ...props\n}: ComponentProps<\"p\"> & { heading?: boolean }) {\n  return (\n    <p\n      data-slot=\"canvas-split-line\"\n      className={cn(\n        \"fade-in slide-in-from-bottom-1 animate-in fill-mode-both text-[13px] leading-relaxed duration-300\",\n        heading ? \"text-foreground/95 font-medium\" : \"text-foreground/65\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n"
    }
  ]
}