Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Table With Checkbox Skeleton Block for Radix UI

A shipments table with row selection that loads in place: the toolbar count and Print labels stay while bars become orders, recipients and statuses, then every checkbox works.

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

Show a selectable table while it loads, with this table skeleton with checkboxes for React with Radix UI. A hairline frame with a plus mark on each corner holds a toolbar band, with a live count and an outline Print labels Button, over a native table of seven shipments from Davit, a shipping-label tool. The band and the column heads are real from the first paint; each cell is a Skeleton bar that becomes the recipient, the order, the carrier or a status badge with an icon and a word, and every Checkbox, the one in the head included, is a bar of its size until the row arrives. Once loaded, tick rows or tick all, the head shows a dash while only some are ticked, and the count and the polite line follow. Reload clears the selection. On a phone the order and the carrier fold under the recipient. It's built from Skeleton, Checkbox, Badge, Button and Guides, with a CSS entrance only. For order lists, inboxes and any table you act on in bulk.

FAQ

What stays local, and how do I wire it to a real query?

Nothing is fetched. The seven shipments are typed in SHIPMENTS, Load starts a 700 millisecond timer, and when it ends the phase becomes ready and the data swaps in; Reload goes back to the bars and in again. To wire it for real, delete the timer, the Load button and the polite line, and set data-state (loading or ready) and aria-busy on the region from your query's pending state, or use the bars as a Suspense fallback and render the real rows when they arrive. The bars are derived from the same array as the data, so keep one row component for both.

How does the selection work?

The ticked ids are plain state. A row's box ticks and clears its own id, the head's box ticks all or clears all and shows a dash when only some are ticked, and the count ("2 selected") and the polite line ("2 of 7 shipments selected") are derived from the same list. Ticked rows get a solid tint and a bar at their start, never a color alone.

What does Print labels do?

Nothing, and it says so: "Labels aren't printed in this demo." It stays focusable but is marked disabled while nothing is selected or the table is loading, and a press then explains why. Read the ticked ids and call your own print job.

What happens to the selection on Reload?

It resets, because the rows are fetched again and the old ticks may not apply. If your data keeps its identity across a refetch, keep the ids instead and drop any that are gone.

Does the table keep its height while it loads?

Each bar and its data sit in one grid cell, so the larger of the two sets the cell's box and the swap changes nothing around it. The table is fixed-layout with set column widths and fixed row heights, the heads and the frame are real in both phases, and the polite line reserves two lines, so the panel is exactly as tall before, during and after loading at every width.

Is it accessible?

The region is marked busy while it loads and carries a screen-reader-only "Loading shipments…", and the polite line announces what loaded once. The bars are hidden from assistive technology and the layer that isn't showing is invisible, so it is neither read nor focusable. The pulse stops when the data is in, and under reduced motion there is no pulse, no spinner and no stagger: the swap is instant. Each row's box is named for its order ("Select order DV-4821") and the head's box is named "Select all shipments".