Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Feedback Rating Dialog Block for React

A help desk's ended chat with a one-tap satisfaction dialog shown open: five drawn faces from very bad to great that record the score at once, then an optional comment with a question that fits the score.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Ask how it went in one tap, with this satisfaction dialog for React with Base UI. It opens from a closed support chat in Helpwell, a help desk: the header holds an outline Rate this chat Button, and the chat itself, a log of bubbles ending in "Chat closed", is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The Dialog holds five drawn faces in a single-choice Toggle Group, each a circle with two eyes and a mouth that follows the score, named from Very bad to Great. Pressing a face records the score at once and says "Recorded: Good" in a polite line; the face stays pressed. An optional Textarea asks the question that fits the score, what went wrong, what would have helped or what worked well. The only Shine Button reads Done, or Add comment once something is typed, and the drawn chat's closing row says what was recorded. For preview the dialog is drawn open in place when the page loads; the header button opens the real Dialog, with the same faces and the same state.

FAQ

Why is the dialog already open, and what do I keep?

So you can see it without a click. On load the dialog is a copy drawn in place over the page: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Rate this chat button opens the real Dialog, modal, with its focus trap, Escape and focus return, and the copy stays closed until a reload. Both show the same RateFields component and share the block's state, so a face pressed in the copy is there in the real one. In your app keep the Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.

Why are the faces drawn instead of emoji?

Emoji look different on every system and can't take the theme's colours, and a screen reader says what each one is called, not what it means on a scale. Each face is an inline SVG of three strokes in the current text colour, hidden from assistive technology, and its button carries the name: Very bad, Bad, Okay, Good, Great. The group is single-choice and never empties: pressing the chosen face again does nothing, so a recorded score can't be lost by accident. The words at the ends are visible, and the chosen word is read out.

What does it record, and when?

The score is recorded the moment a face is pressed, not at Done, so a person who taps and closes has still answered. Closing says "Rating kept: Good" in a polite message, and the header button becomes Change rating. The comment is separate: it is kept when you press Done or Add comment, and the drawn chat then says "You rated this chat: Good, with a comment". Nothing is sent. In your app post the score from rate the moment it changes, and the comment from finish.

How is the comment prompt chosen?

From the score, in promptOf: one or two asks what went wrong, three asks what would have helped, four or five asks what worked well. Before a face is chosen the box is disabled and says "Pick a face first", and its height never changes, so the faces don't move when it wakes. The button says "Choose a face first" until then and answers a press by saying so and putting focus on the faces.

Is it accessible from the keyboard?

Yes. The real dialog is named by its title and described by its sentence, focus stays inside until it closes, and Escape and the close button return focus to the button that opened it. Arrow keys move between faces and press one; Tab goes on to the comment. The trigger is passed to DialogTrigger through render, and the dialog is controlled with open and onOpenChange. The copy shown on load moves no focus; Escape inside it and its close button close it and put focus on Rate this chat.

How does it look on a phone?

The copy shown on load docks to the foot of the frame as a bottom sheet, the faces and the comment above the button. The faces keep touch targets of 44 px, 48 from the small breakpoint, and stay in one row down to 320 px. The real dialog keeps the Dialog's own phone layout: a sheet stuck to the bottom of the screen.

  • Pro

    App Rating Dialog

    Drawers and popovers

    A water tracker's Today screen with its rating drawer shown open over a drawn phone: five stars with a word each, then a branch, where four or five stars offers the store and one to three asks what could be better, with topics and a note.

  • Pro

    Feedback Form Dialog

    Drawers and popovers

    A documentation page with a feedback card docked to its end and shown open: a kind, a message of up to 400 characters with a count, the page it is about, and an optional email that turns on when you let the team reply.

  • Pro

    Feature Request Dialog

    Feedback and reports

    A public roadmap with a request dialog shown open: the title finds similar requests as you type, each with a vote toggle and its count, voting instead closes the dialog, and a new request lands on top of the board's Considering lane.

  • Pro

    Contact Support Dialog

    Feedback and reports

    A shipments table with a support dialog shown open: a ticket form with a category, a priority and attached file names, and beside it up to three help articles picked by the category and the subject's words, each opening in place.

  • Pro

    A footer that asks whether the page was helpful: a Yes and No toggle that opens a note form with validation, a status line that thanks the reader, and two link columns.

  • Pro

    Mood Check Dialog

    Feedback and reports

    A mood journal's home with a check-in dialog shown open: five faces from Rough to Great, tags for what is behind the mood, an optional note of 200 characters, and a week strip that fills in today's cell.