Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Amenities Checkbox Grid Form Block for React Aria

A listing editor panel with twelve amenities as checkbox tiles in a container-query grid, a count with Clear, and a Save that needs at least one amenity.

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

Let people tick several options at a glance with this checkbox tile grid form for React with React Aria. A compact header sits over a hairline frame with a plus mark on each corner. A band holds twelve amenities of a short-stay listing (Wi-Fi, Kitchen, Free parking and nine more) as tiles on shared hairlines, each with a glyph, a name and its box. The grid answers the width of the panel, not the screen: two columns on a phone, three from a 32rem panel and four from 42rem, so it fits a wide page, a sidebar or a narrow drawer alike. A ticked tile is filled and ringed in foreground tones, the heading row counts "5 of 12 chosen" and Clear empties the set. Save needs at least one amenity: pressed with none it says so under the grid and puts focus on the first box, and it stays quiet while nothing has changed. It's built from the Checkbox, Label, Shine Button and Guides, with a CSS entrance only. For amenity lists, feature sets, interest pickers and any choice of a dozen or so short options.

FAQ

How does the grid pick its number of columns?

The tiles sit in a container-query box, so the columns follow the width of the panel rather than the viewport: grid-cols-2, then @lg:grid-cols-3 and @2xl:grid-cols-4. Twelve divides evenly by all three counts, so no row is left half empty. Change the breakpoints, or the tile list in AMENITIES, to suit your options.

How is a ticked tile shown without colour?

The tile gets a soft fill and a one-pixel foreground ring inside the hairlines, and the box turns solid foreground with a check. Neither depends on the primary colour, so it reads the same in every theme, and the count in the heading row says it in words as well.

How does it work with a keyboard and a screen reader?

The twelve boxes are one group named by the "Amenities" heading, each box named by its tile's text. Tab moves from box to box and Space ticks. The whole tile is the label, so a press anywhere on it ticks the box. Pressing Save with none chosen moves focus to the first box, and the problem is read from the group's description and from the status line.

How does it look on a phone?

The tiles stay two across, with the glyph and box on top and the name under, so a long name wraps instead of being cut. The foot is pinned to the bottom of the screen with Save at full width.

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

The saved set lives in the block's state and nothing is sent: the foot says "Saved in this demo. Nothing was sent." In your app, replace the comment in submit with a request that sends the chosen ids, and treat the server's answer as the new saved set.

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

With react-hook-form, keep the chosen ids as one array field and call field.onChange from flip; the "at least one" rule becomes a min check on that array. TanStack Form works the same way with an array field and its handleChange.