Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Dinner Rating Input Form Block for Solid

Three required star ratings for food, service and value with named steps, keys and digits, an overall worked out as the mean in half stars, and a failed press that names the missing 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

Score a meal in three parts with this rating input form for Solid with Ark UI. A compact header sits over a hairline frame with a plus mark on each corner: three ruled rows (Food, Service and Value), each a five-star Rating with the word for the star chosen beside it, an Overall band whose read-only half-star rating is the mean of what is rated so far (printed as "4.3" with its word) and an optional Textarea note. A star takes a click, the arrow keys or a digit from 1 to 5, and every star is named in words for a screen reader ("4 of 5, Great"). All three scores are required: Log dinner with one missing says "Rate Service to continue" under the rows and puts focus on that row's first star. The stars are drawn in the foreground colour, so the Shine Button stays the one primary. It's built from Rating, Field, Textarea, Shine Button and Guides, with a CSS entrance only. For meal diaries, product reviews, course feedback and any form that asks for several scores before one verdict.

FAQ

How do I change the rows, the words and the scale?

Edit ROWS (each row's key, label and hint) and WORDS, which holds one word per star, so five words means a five-star scale. The overall, its half-star drawing, its word and the "N of 3 scores rated" line all come from the same pure helpers (meanText, halfOf, overallWord), so adding a row needs no other change beyond a field in the Scores type.

How is the overall worked out, and what does it show before every row is rated?

It is the mean of the rows rated so far, to one decimal and in whole-number arithmetic, so three scores of 4, 5 and 4 print "4.3". The read-only stars round the mean to the nearest half star. Until all three rows are rated the word says how many it comes from ("Great, from 2 of 3"), and with none rated it reads "Rate a row to start", so the figure never claims more than you gave it.

Which keys work on the stars, and is it the same everywhere?

The arrow keys move the chosen star and Home and End jump to the ends, which is the rating control's own behaviour. A digit from 1 to 5 sets that score directly while focus is on a row's stars: the block takes the key before the control sees it, so it works the same in every version. Each star is named in words ("3 of 5, Good"), and the word chosen is printed beside the row, so the score never depends on colour or on counting stars.

Why is Log dinner not disabled while a score is missing?

A disabled button gives no reason and drops out of the tab order. Here the button stays pressable: pressing it with a row unrated names the first missing one under the rows, says "Not logged" in the foot and moves focus to that row's first star, so a keyboard user lands where the answer goes. Rating the row clears the message.

What stays local, and how do I connect it for real?

Nothing is published or sent: a good press only says "Logged in this demo. Nothing was sent." To make it real, send the three scores and the note from the submit handler, and show the server's answer in the same status line. Keep the overall as a derived value rather than storing it, so it can never disagree with the rows.

How do I connect it to react-hook-form or TanStack Form?

Treat each row as a field whose value is a number from 0 to 5, with 0 meaning not rated. react-hook-form is a React library; use TanStack Form's adapter for your framework and set each score from the rating's value handler. With TanStack Form, give every row its own field and a validator that returns the same "Rate Service to continue" message.