OGE logoOGE

Progress & Loading

Three canonical loading visuals — the linear oge-progress-bar, the ring oge-load-indicator and the oge-skeleton placeholder — replacing the hand-drawn spinners and shimmers every OGE surface carried before. All announce as role="progressbar" with the ARIA rule most libraries miss: indeterminate omits aria-valuenow entirely rather than pinning a sentinel.

Not a meter: the APG is explicit that a current measurement within a known range — battery, disk usage — is role="meter", and "the meter should not be used to indicate progress… use the progressbar role instead". The inverse holds too. (Where a native <progress> suffices, MDN recommends it over the role — these components exist for the styled, token-driven cases.)

role=progressbar indeterminate skeleton severity

Determinate bar

Transform-driven fill (no layout work per frame, mirrors in RTL), value changes glide on a token transition. formatLabel replaces the percent label and feeds aria-valuetext — display and announcement never diverge.

value showLabel formatLabel
80%
80 MB

Indeterminate & buffer

value: null (the default) renders the sliding bar and omits aria-valuenow — the ARIA rule for the unknown state. bufferValue adds the second layer Material uses for media pre-loading.

value: null bufferValue no aria-valuenow

Chunks & severity

chunkCount renders the segmented variant for step-based flows; severity recolors the fill with the card/toast vocabulary.

chunkCount severity
92%
45%

Load indicator

The suite's canonical ring — deliberately indeterminate-only: a circle filling toward completion is the progress bar's job. Under prefers-reduced-motion the spin slows rather than stops, because a frozen ring reads as finished.

size inheritSize slows, never stops

Skeleton

Always aria-hidden decoration — the loading region owns the announcement: put aria-busy (plus a visually-hidden status text where the change should be announced) on the container. shimmer is the card/accordion gradient; pulse is the data grid's beat.

shape animation aria-hidden

A real async flow

Indeterminate while the total is unknown, determinate once it is, and a one-shot completed at the end — fired once per arrival at max, again only after a reset.

indeterminate → determinate completed