Skip to content

Actions

Feedback

Rate a response with an exclusive pair of Good and Bad toggle buttons.

When to use it: Use it to collect a quick rating on a generated response. For more levels use Rating.

On this page

Example

Loading example…
Feedback.tsxtsx
import { useState } from "react";
import { Feedback, FeedbackButton } from "@comp0/react";

export function Example() {
  const [rating, setRating] = useState<"good" | "bad" | "">("");

  return (
    <div className="flex flex-col gap-2">
      <Feedback
        aria-label="Rate this response"
        value={rating}
        onChange={setRating}
        className="flex gap-2"
      >
        <FeedbackButton
          value="good"
          className="rounded border border-zinc-950/10 bg-white px-3 py-2 text-base text-zinc-900 outline-teal-600 focus-visible:outline-2 disabled:opacity-50 sm:text-sm dark:border-white/10 dark:bg-zinc-900 dark:text-zinc-100 dark:outline-teal-400 data-selected:border-teal-600 data-selected:bg-teal-50 dark:data-selected:bg-teal-950"
        >
          Good response
        </FeedbackButton>
        <FeedbackButton
          value="bad"
          className="rounded border border-zinc-950/10 bg-white px-3 py-2 text-base text-zinc-900 outline-teal-600 focus-visible:outline-2 disabled:opacity-50 sm:text-sm dark:border-white/10 dark:bg-zinc-900 dark:text-zinc-100 dark:outline-teal-400 data-selected:border-teal-600 data-selected:bg-teal-50 dark:data-selected:bg-teal-950"
        >
          Bad response
        </FeedbackButton>
      </Feedback>
      <p className="text-sm text-zinc-600 dark:text-zinc-400">Rating: {rating || "none"}</p>
    </div>
  );
}

Anatomy

Dashed frames are invisible state providers; shaded shapes own real DOM. Numbered pins match the list below.

A wireframe sketch of the assembled component. Each numbered marker matches a part in the list that follows.

  1. Feedback

    Group that holds at most one rating. Owns a DOM element.

  2. FeedbackButton

    A toggle button for one rating. Owns a DOM element.

Step by step

  1. 1

    Add the main part

    Wrap two FeedbackButton parts in Feedback and name the group.

  2. 2

    Add the supporting parts

    Give the buttons text names: Good response and Bad response. Hide any icon from assistive technology.

  3. 3

    Make the behavior clear

    Control the rating with value and onChange; pressing the active button withdraws the rating.

    Exampletsx
    <Feedback aria-label="Rate this response" value={rating} onChange={setRating}>
      <FeedbackButton value="good">Good response</FeedbackButton>
      <FeedbackButton value="bad">Bad response</FeedbackButton>
    </Feedback>;

Keyboard

↵
Presses the focused button.
Space
Presses the focused button.

Forms and accessibility

Feedback is not form-associated; send the rating from onChange.

Accessibility checklist

  • Each button announces its pressed state through aria-pressed.
  • Icon-only buttons still need a text name such as Good response.
  • Confirm that feedback was recorded with a Status message if the rating is sent to a server.

API reference

Importtsx
import { Feedback, FeedbackButton } from "@comp0/react";

Feedback

DOM element

Group that holds at most one rating.

PropTypeDescription
value"good" | "bad" | ""Controlled rating; empty is unrated.
defaultValue"good" | "bad" | ""Initial rating; empty is unrated.
onChange(value: "good" | "bad" | "") => voidReceives the next rating.
asElementTypeRenders another element in place of the div.

FeedbackButton

DOM element

A toggle button for one rating.

PropTypeDescription
value"good" | "bad"The rating this button sets.

Style hooks

Attributes that appear while a state is true. Target them with Tailwind data variants such as data-open:bg-zinc-100, or with any CSS selector.

FeedbackButton

Style hookMeaning
[data-selected]This rating is chosen.

Keep exploring