{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "elements-feedback-dialog",
  "type": "registry:component",
  "title": "Feedback dialog",
  "description": "A thumbs-down that asks why, so the signal arrives with a reason attached.",
  "registryDependencies": [
    "https://r.assistant-ui.com/elements-surfaces.json"
  ],
  "dependencies": [
    "lucide-react"
  ],
  "files": [
    {
      "type": "registry:component",
      "path": "components/assistant-ui/elements/feedback-dialog.tsx",
      "sourcePath": "packages/ui/src/components/react/assistant-ui/elements/feedback-dialog.tsx",
      "content": "\"use client\";\n\nimport type { ComponentProps } from \"react\";\nimport { CheckIcon, ThumbsDownIcon } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { field, inkButton, mono, paper } from \"./surfaces\";\n\nexport function FeedbackDialog({\n  reasons,\n  selected,\n  note,\n  sent,\n  onToggleReason,\n  onNoteChange,\n  onSubmit,\n  className,\n  ...props\n}: Omit<\n  ComponentProps<\"div\">,\n  | \"children\"\n  | \"reasons\"\n  | \"selected\"\n  | \"note\"\n  | \"sent\"\n  | \"onToggleReason\"\n  | \"onNoteChange\"\n  | \"onSubmit\"\n> & {\n  reasons: readonly string[];\n  selected: readonly string[];\n  note: string;\n  sent: boolean;\n  onToggleReason?: (reason: string) => void;\n  onNoteChange?: (note: string) => void;\n  onSubmit?: () => void;\n}) {\n  return (\n    <div\n      data-slot=\"feedback-dialog\"\n      className={cn(\n        paper,\n        \"flex w-full max-w-sm rounded-[20px] p-4\",\n        sent ? \"items-center gap-2.5 text-[13.5px]\" : \"flex-col gap-3\",\n        className,\n      )}\n\n      {...props}\n    >\n      {/*\n        Mounted whether or not the feedback has been sent, because a live region\n        only announces a change that happens after it is already in the tree; a\n        region created together with its text is the case AT is free to miss.\n      */}\n      <div\n        role=\"status\"\n        className={\n          sent\n            ? \"fade-in animate-in flex items-center gap-2.5 duration-300\"\n            : \"sr-only\"\n        }\n      >\n        {sent && (\n          <>\n            <CheckIcon className=\"size-4 shrink-0 text-emerald-500\" />\n            Thanks. That helps us tune the model.\n          </>\n        )}\n      </div>\n\n      {sent ? null : (\n        <>\n          <div className=\"flex items-center gap-2.5\">\n            <span className=\"bg-foreground/[0.05] text-foreground/45 flex size-7 shrink-0 items-center justify-center rounded-lg\">\n              <ThumbsDownIcon className=\"size-3.5\" />\n            </span>\n            <span className=\"text-[13.5px] font-medium\">What went wrong?</span>\n            <span className={cn(mono, \"text-foreground/30 ms-auto\")}>\n              optional\n            </span>\n          </div>\n\n          <div className=\"flex flex-wrap gap-1.5\">\n            {reasons.map((reason) => {\n              const active = selected.includes(reason);\n              return (\n                <button\n                  key={reason}\n                  type=\"button\"\n                  aria-pressed={active}\n                  onClick={() => onToggleReason?.(reason)}\n                  className={cn(\n                    \"rounded-full px-2.5 py-1 text-xs transition-[background-color,color,scale] duration-150 active:scale-[0.96]\",\n                    active\n                      ? \"bg-foreground text-background\"\n                      : cn(\n                          field,\n                          \"text-foreground/55 hover:text-foreground/90\",\n                        ),\n                  )}\n                >\n                  {reason}\n                </button>\n              );\n            })}\n          </div>\n\n          <textarea\n            value={note}\n            onChange={(event) => onNoteChange?.(event.target.value)}\n            rows={2}\n            placeholder=\"Anything else?\"\n            aria-label=\"Anything else?\"\n            className={cn(\n              field,\n              \"text-foreground/80 placeholder:text-foreground/30 focus-visible:ring-foreground/20 resize-none rounded-xl px-3 py-2 text-xs outline-none focus-visible:ring-1\",\n            )}\n          />\n\n          <button\n            type=\"button\"\n            onClick={onSubmit}\n            className={cn(\n              inkButton,\n              \"flex h-8 items-center justify-center self-end rounded-full px-3.5 text-xs font-medium\",\n            )}\n          >\n            Send feedback\n          </button>\n        </>\n      )}\n    </div>\n  );\n}\n"
    }
  ]
}