Conversation
Response Feedback
Thumbs up or down under an answer; a down vote opens reason chips and a note, then settles into a thank-you.
2 variantsMIT
Preview
Cache resized images by content hash in .pressd/cache. On each build, hash the source and the resize options; if the key exists, copy the cached output instead of running sharp again.
Installation
Copies the component into components/ui and installs its dependencies and theme tokens.
pnpm dlx shadcn@latest add https://tuffui.com/r/response-feedback.jsonUsage
Pass your own data and wire the callbacks to your agent runtime.
import { ResponseFeedback } from "@/components/ui/response-feedback";
export function AnswerActions({ message }: { message: Message }) {
return (
<ResponseFeedback
onRate={(rating) => analytics.track("answer_rated", { id: message.id, rating })}
onSubmit={({ rating, reasons, note }) =>
api.feedback.create({ messageId: message.id, rating, reasons, note })
}
onUndo={() => api.feedback.delete({ messageId: message.id })}
onCopy={() => navigator.clipboard.writeText(message.text)}
onRegenerate={() => thread.regenerate(message.id)}
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| value | Feedback | — | Controlled state: rating, reasons, note and status. Leave it out and the component keeps its own. |
| onValueChange | (value: Feedback) => void | — | Called on every change of the controlled state. |
| onRate | (rating: FeedbackRating) => void | — | Called on a thumbs up or down, or when a 1–5 rating is picked. Pressing the same thumb again clears it. |
| onSubmit | (feedback: { rating: FeedbackRating; reasons: string[]; note: string }) => void | — | Called when the reasons form is sent. Needs at least one reason or a note. |
| onUndo | () => void | — | Shows Undo in the thank-you for `undoMs`; reopens the form. |
| undoMs | number | 5000 | How long Undo stays after a submit. |
| onCopy | () => void | — | Shows a copy button that confirms with a check. |
| onRegenerate | () => void | — | Shows a regenerate button. |
| reasons | string[] | ["Inaccurate", "Not helpful", "Too long", "Unsafe", "Other"] | Reason chips, multi-select. |
| variant | "inline" | "detailed" | "inline" | Thumbs under an answer that open reasons on a down vote, or a card with a 1–5 rating and reasons always shown. |
| className | string | — | Extra classes for the root element. |
type FeedbackRating = "up" | "down" | 1 | 2 | 3 | 4 | 5;
type Feedback = {
rating: FeedbackRating | null;
reasons: string[];
note: string;
status: "idle" | "open" | "sent";
};