Components

Progress

A React progress bar with a linear Liquid Glass track, determinate and indeterminate states, and five sizes.

Progress renders a linear glass track. It supports determinate values, an indeterminate state, an optional label and description, and a formatted value readout.

The component composes the root, label, value, track, and indicator internally, so you use one component instead of assembling the parts yourself.

Basic example

Pass value between min and max. The default range is 0 to 100, and the visible value uses the current locale's percentage format.

Exporting data
You can keep working while the export runs.x

Indeterminate

Set value={null} when the duration is unknown. The bar animates horizontally and exposes an indeterminate state to assistive technology.

Preparing workspace
This can take a few moments.x

Sizes

Five sizes are available: xs, sm, md, lg, and xl. Track height, spacing, and text size scale together.

Size xs
x
Size sm
x
Size md
x
Size lg
x
Size xl
x

Formatting

Use format for Intl.NumberFormat options. The formatted value is also used for the default aria-valuetext.

Uploading assets
Seven of ten files have been uploaded.x

Custom range

min and max define the scale and value stays the current position. The visible number and aria-valuetext use format.

Temperature
The value sits inside a custom -20 to 40 range.x
Storage used
With a custom minimum, the default label reports the percentage of the range.x

Accessibility

A visible label gives the progress bar its accessible name. When no visible label is rendered, provide aria-label or aria-labelledby yourself.

The default aria-valuetext is the formatted percentage. Use getAriaValueText when the value needs a more meaningful description, such as “7 of 10 files uploaded”.

An indeterminate bar has no aria-valuenow; it is announced as indeterminate progress. See the accessibility guide for announcement patterns.

API reference

PropTypeDefaultDescription
valuenumber | nullnullCurrent value. Use null for an indeterminate progress bar.
labelReactNode—Visible label for the progress bar.
descriptionReactNode—Supporting text under the bar. It is linked automatically through aria-describedby.
size"xs" | "sm" | "md" | "lg" | "xl""md"Controls track height, spacing, and text size.
minnumber0The minimum value.
maxnumber100The maximum value.
formatIntl.NumberFormatOptions—Options used to format the visible value and the default aria-valuetext.
localeIntl.LocalesArgument—The locale used by Intl.NumberFormat. Defaults to the runtime locale.
getAriaValueText(formattedValue: string, value: number | null) => string—Returns a human-readable text alternative for the current value.
aria-valuetextstring—Overrides the accessible value text.
aria-labelstring—Accessible name when no visible label is rendered.
aria-labelledbystring—ID reference for an external accessible name.
aria-describedbystring—ID reference for external supporting text. A visible description is merged with this value.
renderReactElement | ((props, state) => ReactElement)—Replaces the rendered root element.
refRef<HTMLDivElement>—Ref forwarded to the root element.
classNamestring—Tailwind classes merged into the root.
styleCSSProperties—Inline styles merged into the same element as className.
ui{ root?: ClassValue; header?: ClassValue; label?: ClassValue; value?: ClassValue; track?: ClassValue; indicator?: ClassValue; description?: ClassValue }—Tailwind classes for internal slots, keyed by data-slot.
AttributeDescription
data-completePresent when the progress has completed.
data-indeterminatePresent when the progress is indeterminate.
data-progressingPresent while the progress is progressing.
data-slotMarks internal parts (root, header, label, value, track, indicator, description) for styling.

Theming

The bar stays neutral by design. Override the component-scoped tokens from src/theme/progress.ts to change the material:

.my-progress {
  --ui-progress-height: 8px;
  --ui-progress-track: color-mix(in srgb, var(--ui-ink) 16%, transparent);
  --ui-progress-fill-from: var(--ui-ink);
  --ui-progress-fill-to: var(--ui-ink-active);
  --ui-progress-glow: color-mix(in srgb, var(--ui-ink) 32%, transparent);
}

Use className and style for layout, and tune the --ui-progress-* tokens for theme changes. Both props merge into the root, not the track surface.

  • Toast — For transient status messages.
  • Slider — For an interactive numeric value.
  • Scroll Area — For scroll position rather than task completion.