Skip to content

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.json

Usage

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

PropTypeDefaultDescription
valueFeedback—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.
undoMsnumber5000How long Undo stays after a submit.
onCopy() => void—Shows a copy button that confirms with a check.
onRegenerate() => void—Shows a regenerate button.
reasonsstring[]["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.
classNamestring—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";
};