shadcn.io is not affiliated with official shadcn/ui
Pricing Table Skeleton Block for React Aria
Three plan columns on shared hairlines that load in place, column by column: names, prices, blurbs and five features become data, and the middle plan has the one Shine Button.
Installation
Overview
Show a pricing page while its plans load, then swap them in column by column, with this pricing table skeleton for React with React Aria. A hairline frame with a plus mark on each corner holds a band heading ("Choose a plan") over three plan cells of Torse, a design-handoff tool, on shared hairlines. The heading and the layout are real from the first paint; each plan's name, price, two-line blurb and five features are Skeleton bars that become the plan in the same cell, the first column then the next, when you press Load. The Team plan's Choose button is the one Shine Button; the other two are outline Buttons. All three are unavailable until the plans are in, then say plans aren't sold in this demo. On a phone the three plans stack. It's built from Skeleton, Skeleton Text, Shine Button, Button and Guides, with a CSS entrance only. For a pricing page, a plan picker and any set of offers that waits for a query.
FAQ
What stays local, and how do I wire it to a real query?
Nothing is fetched. The three plans are typed in PLANS, 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 content when it arrives. Choose only sets a note here; in your app, start checkout for the chosen plan from it. Keep one component for the bars and the data so they can't drift apart.
What does the column-by-column reveal do?
Each plan's cells share a delay of its column number times 120 milliseconds, so the plans fill from the start edge (the right in right-to-left languages, because the columns are laid out that way). On a phone the same order runs top to bottom. Under reduced motion the delay is zero and the swap is instant.
How are the prices stored?
As integer cents per seat per month (900, 2400, 6900), turned into whole dollars by priceOf, each in its own left-to-right span. Add yearly prices as a second field and keep the display in one helper.
Why doesn't the table jump when the data arrives?
Each value shares a grid cell with its bar, the three plans sit on a grid that stretches them to one height, and each Choose button is pushed to the foot of its cell, so a longer blurb in one plan moves nothing. The polite line reserves two lines, so the panel is exactly as tall before, during and after loading.
Is it accessible?
The region is marked busy while it loads and carries a screen-reader-only "Loading plans…", 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 three buttons are aria-disabled while loading, not hidden, and each names its plan. 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.