Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Dashboard Chart Skeleton Block for React Aria

A signup trend chart that loads in place: the title, a 7d, 30d and 90d range group and the gridlines stay while three channel lines grow in, told apart by width and dash, with a text table.

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 trend chart while its series load, then grow the lines in without moving anything, with this dashboard chart skeleton for React with React Aria. A hairline frame with a plus mark on each corner holds the chart's title and sentence, a range Toggle Group (7d, 30d, 90d), a 256 pixel plot of three lines of new accounts a day from Anneal, a product-growth tool, and a legend foot. The title, the range group, the gridlines and the legend's line swatches are real from the first paint; the scale, the dates, the lines, their end labels and each legend total are Skeleton bars that become the data in the same box, the lines growing from the start edge when you press Load. Choosing another range loads its own typed series. The channels are told apart by line width and dash, never by color, and a text table of the same values sits in the figure for people who can't see the chart. On a phone the end labels drop and the legend wraps. It's built from Skeleton, Toggle Group, Button and Guides, with a CSS entrance only. For growth charts, usage trends and any series with a range.

FAQ

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

Nothing is fetched. The three series for each range are generated from fixed numbers by seriesOf, and typed in WEEK, MONTH and QUARTER, 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 figures when they arrive. The bars are derived from the same data as the figures, so keep one component for both. Key your query on the range.

What does the range group do?

It is a single choice that can't be empty, so one range is always pressed. Choosing another goes back to the bars and loads that range's series with its own dates and scale. The group is real from the first paint, because it describes the request rather than the result.

How do the lines appear?

The chart sits in the same box as its placeholder. When the data arrives it is revealed with a clip that opens from the start edge over 700 milliseconds, after the bar fades. The clip is a CSS transition on the ChartBox wrapper, so it needs no animation library, it opens left to right in every reading direction (the plot is always laid out left to right), and under reduced motion it is off.

How are the three lines told apart without color?

By width and dash: Web is a solid thick line with a light area under it, Mobile is dashed and Referral is dotted. Each line also has a direct label at its end, the legend repeats the swatch with the name and the total, and the text table gives every channel's first, highest and latest day.

Does the chart 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 plot is a fixed 256 pixels, and the scale, the dates and the end labels reserve their boxes. The labels, headings and frames are real in both phases and the polite line reserves two lines, so the block 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 the signup chart…", 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 plot is hidden from assistive technology; the figure carries a table with a caption, one row per channel, and the range group is named "Range". The pulse stops when the data is in, and under reduced motion there is no pulse, no spinner, no stagger and no growing: the swap is instant.