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.
Example
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.
Feedback
Group that holds at most one rating. Owns a DOM element.
FeedbackButton
A toggle button for one rating. Owns a DOM element.
Step by step
- 1
Add the main part
Wrap two FeedbackButton parts in Feedback and name the group.
- 2
Add the supporting parts
Give the buttons text names: Good response and Bad response. Hide any icon from assistive technology.
- 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
import { Feedback, FeedbackButton } from "@comp0/react";Feedback
DOM elementGroup that holds at most one rating.
| Prop | Type | Description |
|---|---|---|
value | "good" | "bad" | "" | Controlled rating; empty is unrated. |
defaultValue | "good" | "bad" | "" | Initial rating; empty is unrated. |
onChange | (value: "good" | "bad" | "") => void | Receives the next rating. |
as | ElementType | Renders another element in place of the div. |
FeedbackButton
DOM elementA toggle button for one rating.
| Prop | Type | Description |
|---|---|---|
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 hook | Meaning |
|---|---|
[data-selected] | This rating is chosen. |