{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "elements-message-queue",
  "type": "registry:component",
  "title": "Message queue",
  "description": "Turns you typed while a run was in flight, stacked and cancelable until it finishes.",
  "registryDependencies": [
    "https://r.assistant-ui.com/elements-surfaces.json"
  ],
  "dependencies": [
    "lucide-react"
  ],
  "files": [
    {
      "type": "registry:component",
      "path": "components/assistant-ui/elements/message-queue.tsx",
      "sourcePath": "packages/ui/src/components/react/assistant-ui/elements/message-queue.tsx",
      "content": "\"use client\";\n\nimport type { ComponentProps } from \"react\";\nimport { ArrowUpIcon, XIcon } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { field, ghostButton, mono, paper } from \"./surfaces\";\n\nexport interface QueuedMessage {\n  id: string;\n  text: string;\n}\n\nexport function MessageQueue({\n  running,\n  queued,\n  onCancel,\n  className,\n  ...props\n}: Omit<\n  ComponentProps<\"div\">,\n  \"children\" | \"running\" | \"queued\" | \"onCancel\"\n> & {\n  running: string;\n  queued: readonly QueuedMessage[];\n  onCancel?: (id: string) => void;\n}) {\n  return (\n    <div\n      data-slot=\"message-queue\"\n      className={cn(\"flex w-full max-w-sm flex-col gap-2\", className)}\n\n      {...props}\n    >\n      <div className={cn(paper, \"flex items-center gap-2.5 rounded-2xl p-3\")}>\n        <span className=\"relative flex size-2 shrink-0\">\n          <span className=\"absolute inline-flex size-full animate-ping rounded-full bg-blue-500/60 motion-reduce:hidden\" />\n          <span className=\"relative inline-flex size-2 rounded-full bg-blue-500 dark:bg-blue-400\" />\n        </span>\n        <span className=\"text-foreground/90 min-w-0 flex-1 truncate text-[13.5px]\">\n          {running}\n        </span>\n        <span className={cn(mono, \"text-foreground/35 shrink-0\")}>running</span>\n      </div>\n\n      {queued.length > 0 && (\n        <div className=\"flex items-baseline justify-between px-1\">\n          <span className={cn(mono, \"text-foreground/35\")}>\n            {queued.length} queued\n          </span>\n          <span className={cn(mono, \"text-foreground/35\")}>\n            sends when this finishes\n          </span>\n        </div>\n      )}\n\n      <ul className=\"flex flex-col gap-1.5\">\n        {queued.map((message, index) => (\n          <li\n            key={message.id}\n            className={cn(\n              field,\n              \"fade-in slide-in-from-bottom-1 animate-in fill-mode-both flex items-center gap-2.5 rounded-2xl py-2 pr-2 pl-3 duration-300\",\n            )}\n          >\n            <span\n              className={cn(\n                mono,\n                \"text-foreground/30 w-3 shrink-0 tabular-nums\",\n              )}\n            >\n              {index + 1}\n            </span>\n            <span className=\"text-foreground/60 min-w-0 flex-1 truncate text-[13.5px]\">\n              {message.text}\n            </span>\n            <ArrowUpIcon className=\"text-foreground/25 size-3 shrink-0\" />\n            <button\n              type=\"button\"\n              aria-label={`Remove \"${message.text}\" from the queue`}\n              onClick={() => onCancel?.(message.id)}\n              className={cn(ghostButton, \"size-6 shrink-0\")}\n            >\n              <XIcon className=\"size-3.5\" />\n            </button>\n          </li>\n        ))}\n      </ul>\n    </div>\n  );\n}\n"
    }
  ]
}