Skip to contentAsheeUIAsheeUI

LoadingState

The presentation of a region on its way, what is loading, and the room the content will take.

A region that is on its way is not empty, and saying so would be wrong twice over: the reader would be told there is nothing, and the page would change shape when the content arrived. LoadingState is the region's own presentation while it waits, an indicator, a label that names what is loading, and a claim on the room the content will take.

It is the region rather than an ornament inside one: while a list loads, this is what the list is. A small indeterminate wait inside a control or a row is Spinner, and the known shape of what is coming is Skeleton.

Usage

import { LoadingState } from "@asheeui/web";

<LoadingState
  label="Loading invoices"
  description="Fetching this quarter's invoices."
/>

label says what is being loaded, not that something is. It takes a node rather than a string, so the sentence can carry an emphasised word or a glyph beside the text, an icon on its own names nothing, because the text is what a reader hears. It is registered as Loading, which is a placeholder for the one sentence the reader cannot get from the page, a region that says "Loading" repeats what the spinner already said. description is the second line, for where the content is coming from or how long it tends to take.

indicator replaces the framework's spinner, which is the seam for a determinate progress bar or a product's own animation. It takes a node, so a percentage goes there while the label keeps naming the thing rather than changing on every tick.

The room it claims

minHeight is a step of the shared spacing scale rather than a pixel value: xs claims 4rem, sm 6rem, md 12rem, lg 18rem, xl 24rem and 2xl the height of the viewport, with none claiming nothing.

A claim is a floor, not a height, which is the part worth understanding: the region is never smaller than its own padding and indicator, so a claim below that changes nothing at all. What a claim buys is the arrival, the content replaces the state in room already taken, so the page below does not move when it lands.

Worth knowing when you wire it: the registered claim is md, one step above the room the registered md density already takes with its padding and its indicator, so the default pairing binds, the region reserves that much room instead of sizing itself to the spinner. A claim at or below what the density already occupies reserves nothing extra, so the two are worth changing together: raise minHeight for a taller wait, or take the density down when the region is a short one.

It is the region

The state takes the space the content will take, which is why it is drawn instead of the region rather than inside it. panel decides whether it also draws the surface: true for a region inside a dashboard or a card, where the surrounding surface is what the content will fill; false for a page that is loading as a whole and has no surface to replace.

Props

label, size, panel and minHeight resolve instance → components.loadingstate → the framework's fallback, registered as Loading, md, false and md. A product that always loads the same thing renames the label once, in configuration, and every region that does not state its own says it.

description, indicator, children and as are instance-only: what is loading, and what to put in its place, is a statement about one region. children is the slot below the label, for a cancel control or a "this is taking longer than usual" note.

Accessibility

  • The region draws its own role="status"; the announcement is not an option, the way it is on EmptyState and ErrorState. A load in progress is always a change worth reporting politely, and it always waits for the reader to finish what they are on.
  • The spinner is aria-hidden, so the label's text is the whole announcement. That is why the label has to name the thing rather than the fact: nothing else in the region will be heard.
  • description is inside the region and is read with it, so keep it to a sentence. Anything passed as indicator is announced too, which is what makes a real percentage worth passing and a decorative animation worth leaving out.
  • Nothing the state draws is focusable, a cancel control passed as children is the reader's own choice, and nothing moves focus. A wait reports itself; it does not take the reader somewhere, and it does not stop them reading the rest of the page while it finishes.

The channels, and why a busy region keeps its size, are Announcements.