shadcn.io is not affiliated with official shadcn/ui
Horizontal Tabs Skeleton Block for React Aria
A plan's detail tabs that reload on every press: Overview, Usage, Limits and History each swap bars for a paragraph and facts, four meters, five rates or four dated entries.
Installation
Overview
Show a set of tabs while its panel loads, then swap the panel in without moving anything, with this horizontal tabs skeleton for React with React Aria. A hairline frame with a plus mark on each corner holds a line Tabs list (Overview, Usage, Limits, History) over the open tab's read-only panel from Keemun, a power company: a paragraph and four facts, four usage meters, five rates, or four dated entries. The tab names, every label and the foot line are real from the first paint; the facts, the meters, the rates and the entries are Skeleton bars that become the data in the same place. Pressing a tab is a reload, so the open panel goes back to bars and comes in again, and only the open tab's panel is on the page. The tab list scrolls on a phone. It's built from Skeleton, Skeleton Text, Tabs and Guides, with a CSS entrance only. For account pages, plan details and any tabbed view that loads per tab.
FAQ
What stays local, and how do I wire it to a real query?
Nothing is fetched. The plan is typed in FACTS, METERS, RATES and ENTRIES, 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. Keep one component for the bars and the data so they can't drift apart.
Why does pressing a tab reload?
Each tab is its own request in a real app, so pressing one restarts the 700 millisecond timer and shows its bars again. Only the open tab's panel is mounted, so there are no duplicate ids and a hidden panel never loads in the background. In your app, fetch on the tab change and show the bars while it is pending.
How is the height held between tabs?
The four panels have different content, so an unseen copy of all four sits in the open panel's grid cell, hidden from sight, assistive technology and the keyboard; the tallest sets the box, and the live panel is flex-none, not flex, which would override its hidden state. Rows have fixed heights, so the copy matches the live panel.
How are the usage meters built?
As a decorative track with a fill whose width comes from a CSS variable (--p, a whole percent worked out from the used amount and the cap), next to a text value ("142 of 200 kWh") that carries the meaning. The track is hidden from assistive technology and is set left-to-right, so it fills the same way in every language.
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 tab list has arrow-key movement and each tab names its panel, and the dates are time elements. 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.