Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Pricing Card Skeleton Block for Radix UI

A single plan card that loads in place: the plan name, price, blurb and six features come in over bars, and the Choose button says plans are not sold in this demo.

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 plan card while its page loads, then swap the plan in without moving anything, with this pricing card skeleton for React with Radix UI. A hairline frame with a plus mark on each corner holds the Studio plan of Squinch, a notes app, in four bands: the name, the price with its blurb, six features and the button. The check marks, the "/month" and the fine print are real from the first paint; the plan name, the price, the two-line blurb and the six features are Skeleton bars that become the plan in the same place. The card's one Shine Button, Choose Studio, is unavailable until the plan is in, then says plans aren't sold in this demo. It's built from Skeleton, Skeleton Text, Shine Button, Button and Guides, with a CSS entrance only. For a plan page, an upgrade prompt or any single offer that waits for a query.

FAQ

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

Nothing is fetched. The plan is typed in PLAN, 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 from it. Keep one component for the bars and the data so they can't drift apart.

How is the price stored and shown?

As integer cents (1400), turned into whole dollars with thousands separators by priceOf, and set in its own left-to-right span so it reads the same in right-to-left languages. Keep prices as integers in your data and format at the edge; for a plan with cents, show two decimals the way billing-invoice-history does.

Why doesn't the card jump when the data arrives?

Every value shares a grid cell with its bar, the blurb's bars and words share one cell, and the Choose button and the fine print are real in both phases. The features can wrap to a second line on a phone in the same way before and after loading. The polite line reserves two lines, so the card is exactly as tall before, during and after loading.

Why is the button there before the plan is?

A button's place is part of the card, so it is drawn from the first paint and made aria-disabled until the data is in: it keeps its place in the tab order and focus never moves. Pressing it after loading only says plans aren't sold in this demo.

Is it accessible?

The region is marked busy while it loads and carries a screen-reader-only "Loading plan…", 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 button is unavailable, not hidden, so its label is read from the start. 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.