Skip to main content

Progress

Info:Feedback
43

A progress bar or capacity meter: a linear bar or circular ring with value thresholds that recolor and pulse.

meter gauge capacity threshold disk battery usage quota score

Live demo

live · @xtyle/astro

Progress

Linear, six tones

accent
64%
neutral
40%
info
52%
success
100%
warn
78%
danger
22%

Every tone

Accents

accent
accent-2
accent-3
accent-4
neutral

Statuses

success
info
warn
danger

Named hues

red
orange
yellow
green
blue
purple
brown
pink
cyan
gray
white
black

Value readouts

percent
33%
value
123
of max
123/456

Thresholds, tone & pulse

12%
12%
38%
38%
76%
76%

Capacity meter (role="meter")

System 90 GB free of 1 TB
910/1000 GB
Media 1.2 TB free of 2 TB
800/2000 GB
Projects 90 GB free of 500 GB
410/500 GB

Value ramp (ramp)

Solid thermal, colored by value

18%
18%
42%
42%
68%
68%
88%
88%
100%
100%

Gradient sweep (ramp-mode="gradient", pure CSS)

35%
70%
100%

Schemes

accent
thermal
status
26%
26%
58%
58%
90%
90%

Inset readout

66%
92%

Circular ring

64%
accent
40%
neutral
52%
info
100%
success
78%
warn
22%
danger

Sizes & indeterminate

Small
Medium
Large
48%
Indeterminate — linear
Indeterminate — circular

Progress shows how far along a task is, or how full a capacity is. The variant axis picks the shape (a horizontal linear bar or a circular svg ring) and the tone axis picks the color from the full roster (the six semantic roles, the accent variants, the twelve named hues).

A determinate bar fills to value between min and max; an indeterminate mode animates a moving sweep when the amount of work is unknown. Declarative <threshold below tone pulse> children turn it into a self-coloring meter: each band names a percentage ceiling, and the active band (the first the current value falls under) overrides the tone and can pulse the fill (slow or fast) to flag a critical level, the pulse routed through motion tokens so the reduced-motion base rule stills it. Set meter to report role="meter" (a measurement against a capacity, like disk used) instead of the default role="progressbar" (a task advancing); either way it carries aria-valuenow/aria-valuemin/aria-valuemax. An optional inline readout (show-value) shows the percentage, the raw value, or value/max (value-format), sits at the end or inset over the bar (value-position), and can take the active tone (colorize-value).

When to use

How this component composes with the rest of the set.

Pair with a status Badge or text label to spell out the percentage in words when show-value alone is not enough.
Drive value from an upload/download stream; flip to indeterminate for the indefinite handshake phase.
Use the success tone on completion and danger on a stalled or failed transfer to reinforce state with color.

Props

18 props, straight from the manifest.

PropTypeDefaultBindingsDescription
variant ProgressVariant
linear circular
linear
html svelte astro
Shape of the meter: a horizontal bar or a circular ring.
tone FullTone
accent neutral danger success warn info accent-2 accent-3 accent-4 red orange yellow green blue purple brown pink cyan gray white black
accent
html svelte astro
Semantic color of the filled indicator.
size ProgressSize
sm md
md
html svelte astro
Meter size; `sm` thins the bar or shrinks the ring.
value number 0
html svelte astro
Current amount of work done, clamped between `min` and `max`.
min number 0
html svelte astro
Lower bound of the range.
max number 100
html svelte astro
Upper bound of the range.
indeterminate boolean false
html svelte astro
Animates a moving sweep instead of a fixed fill when progress is unknown; drops `aria-valuenow`.
showValue boolean false
html svelte astro
Renders an inline readout beside (or inside) the bar.
valueFormat ProgressValueFormat
percent value value-max
percent
html svelte astro
How `show-value` reads: `percent` (`80%`), `value` (the raw number), or `value-max` (`80/100`).
unit string
html svelte astro
A unit appended to the `value` / `value-max` readout (e.g. ` GB`); the `percent` format ignores it (the `%` is the unit).
valuePosition "end" | "inset"
end inset
end
html svelte astro
Where the `show-value` readout sits: after the bar (`end`) or laid over the fill (`inset`).
colorizeValue boolean false
html svelte astro
Tints the `show-value` readout with the active tone (the threshold tone when a band is active).
meter boolean false
html svelte astro
Reports `role="meter"` (a measurement against a capacity, e.g. disk used) instead of `role="progressbar"` (a task advancing); the visual treatment is unchanged.
ramp RampScheme | string[]
accent thermal status
html svelte astro
Colors the fill by its own value along a ramp instead of the flat `tone`: a built-in scheme (`accent`, `thermal`, `status`), a JSON array of stop colors (`["#00f","#f00"]`), or a comma-separated stop list. Reinforces magnitude with temperature, so a fuller bar also reads hotter.
rampMode "solid" | "gradient"
solid gradient
solid
html svelte astro
How a `ramp` paints: `solid` samples one color at the current value off the live cascade (needs the runtime); `gradient` paints the whole scale as a pure-CSS sweep clipped to the fill (zero-JS, SSR-safe, linear only, a circular ring falls back to `solid`).
reverse boolean false
html svelte astro
Flips a `ramp` end for end (hot-to-cold).
threshold <threshold below tone pulse>
html svelte astro
Declarative config children, not a prop: each `<threshold below="<pct>" tone="<tone>" pulse="slow|fast">` names a percentage ceiling; the active band (the first the current value falls under, bands sorted ascending) overrides `tone` and may `pulse` the fill; place them as direct children of the element.
ariaLabel string
html svelte astro
Accessible name for the meter. Required. A progressbar with no name is not announced.

Appearance

Variants

linear

.xtyle-progress--linear

A horizontal bar that fills left-to-right.

circular

.xtyle-progress--circular

An SVG ring whose stroked arc sweeps clockwise from the top.

Sizes

sm

.xtyle-progress--sm

Thin bar / small ring.

md

default
.xtyle-progress

Default.

States

indeterminate

.xtyle-progress--indeterminate

Work of unknown duration; the indicator animates a continuous sweep.

pulse

.xtyle-progress--pulse-slow, .xtyle-progress--pulse-fast

An active <threshold pulse> band; the fill breathes (slow or fast) to flag a critical level, stilled under reduced-motion.

focus-visible

.xtyle-progress:focus-visible

Keyboard focus: a token-colored ring, plus a transparent outline that becomes real in forced-colors mode.

Anatomy

The named parts that make up the component, with their selectors.

progress

.xtyle-progress

The root element carrying the variant, tone, and size classes and the progressbar (or meter) role.

--font-sans --fg-1 --space-2

track

.xtyle-progress__track

The unfilled groove (a bar rail or an SVG ring) the indicator runs along.

--neutral-bg --radius-full --space-1 --space-2

indicator

.xtyle-progress__indicator

The filled portion, colored by tone: a bar segment or a stroked arc.

--accent --duration-base --ease-emphasized

value

.xtyle-progress__value

The optional inline readout shown when show-value is set.

--text-sm --text-xs --fg-2 --fg-1

Tokens & coverage

What the component consumes, checked live against what the algorithm produces.

Success:fully covered 43/43 consumed tokens produced default register: 299 tokens

Live coverage check against the xtyle-default register (derive(xtyleDefault, { anchors })coverComponent(manifest, register)). Every token this component consumes must be a key the algorithm produces.

--accent --accent-2 --accent-3 --accent-4 --bg-0 --black --blue --border-normal --border-thick --brown --cyan --danger --duration-base --ease-emphasized --ease-standard --fg-0 --fg-1 --fg-2 --font-sans --gray --green --info --neutral --neutral-bg --orange --pink --purple --radius-full --radius-sm --red --ring --space-1 --space-2 --space-3 --space-6 --space-8 --success --text-body --text-sm --text-xs --warn --white --yellow

Slots

value
html svelte astro

Optional custom content for the readout, in place of the built-in show-value text (e.g. a formatted label).

default
html svelte astro

The <threshold below tone pulse> config children (hidden from view); the bar reads them to recolor and pulse by value.

Accessibility

Exposes role="progressbar" (or role="meter" with the meter attribute) carrying aria-valuemin, aria-valuemax, and aria-valuenow so assistive tech announces the current amount; pick meter for a capacity reading and progressbar for a task in motion.
Threshold recoloring and the pulse animation are presentational; the value the screen reader announces is the same aria-valuenow either way, so a critical level never rides on color or motion alone (pair it with a danger tone word or a label if the level itself must be announced).
indeterminate drops aria-valuenow (the value is unknown) while keeping the min/max bounds.
Requires an accessible name via aria-label; the binding warns at runtime when one is missing.
The visual fill is presentational; progress state lives in the ARIA value attributes, not the geometry.
Focus is shown with a token ring and a transparent outline that the forced-colors base rule promotes to a real system outline.
Motion (the indeterminate sweep) is routed through duration/easing tokens, so the reduced-motion base rule neutralizes it.

Code

Linear and circular

Both shapes carry any tone; add show-value for a readout or indeterminate for unknown work.

<xtyle-progress value="42" aria-label="Upload progress"></xtyle-progress>

<xtyle-progress value="80" tone="success" show-value aria-label="Storage used"></xtyle-progress>

<xtyle-progress variant="circular" value="65" tone="info" show-value aria-label="Sync"></xtyle-progress>

<xtyle-progress variant="circular" indeterminate aria-label="Loading"></xtyle-progress>
<script lang="ts">
	import { Progress } from "@xtyle/svelte";

	let value = $state(42);
</script>

<Progress {value} ariaLabel="Upload progress" />

<Progress value={80} tone="success" showValue ariaLabel="Storage used" />

<Progress variant="circular" value={65} tone="info" showValue ariaLabel="Sync" />

<Progress variant="circular" indeterminate ariaLabel="Loading" />
---
import { Progress } from "@xtyle/astro";
---

<Progress value={42} aria-label="Upload progress" />

<Progress value={80} tone="success" showValue aria-label="Storage used" />

<Progress variant="circular" value={65} tone="info" showValue aria-label="Sync" />

<Progress variant="circular" indeterminate aria-label="Loading" />

A capacity meter with thresholds

Set meter for the measurement role and add <threshold below tone pulse> children: the bar greens under 75%, ambers past it, and reds and pulses once it crosses 90% full, the value/max readout carrying its unit. This is the gauge use once served by a separate Meter.

<xtyle-progress meter value="910" max="1000" show-value value-format="value-max" unit=" GB" colorize-value aria-label="Disk usage">
	<threshold below="75" tone="success"></threshold>
	<threshold below="90" tone="warn"></threshold>
	<threshold below="101" tone="danger" pulse="fast"></threshold>
</xtyle-progress>
<Progress meter value={910} max={1000} showValue valueFormat="value-max" unit=" GB" colorizeValue ariaLabel="Disk usage">
	<threshold below="75" tone="success" />
	<threshold below="90" tone="warn" />
	<threshold below="101" tone="danger" pulse="fast" />
</Progress>
<Progress meter value={910} max={1000} showValue valueFormat="value-max" unit=" GB" colorizeValue aria-label="Disk usage">
	<threshold below="75" tone="success" />
	<threshold below="90" tone="warn" />
	<threshold below="101" tone="danger" pulse="fast" />
</Progress>

A fill that colors by its value

Set ramp to color the fill along a scale by its own value instead of a flat tone: solid (the default) samples one color at the current value, so a busier bar reads hotter; ramp-mode="gradient" sweeps the whole scale as pure CSS. Both track the theme's own hues, so the ramp restyles with the algorithm.

<xtyle-progress ramp="thermal" value="30" aria-label="Load, cool"></xtyle-progress>
<xtyle-progress ramp="thermal" value="70" aria-label="Load, warm"></xtyle-progress>
<xtyle-progress ramp="thermal" value="95" aria-label="Load, hot"></xtyle-progress>

<xtyle-progress ramp="thermal" ramp-mode="gradient" value="80" aria-label="Capacity sweep"></xtyle-progress>
<Progress ramp="thermal" value={30} ariaLabel="Load, cool" />
<Progress ramp="thermal" value={70} ariaLabel="Load, warm" />
<Progress ramp="thermal" value={95} ariaLabel="Load, hot" />

<Progress ramp="thermal" rampMode="gradient" value={80} ariaLabel="Capacity sweep" />
<Progress ramp="thermal" value={30} aria-label="Load, cool" />
<Progress ramp="thermal" value={70} aria-label="Load, warm" />
<Progress ramp="thermal" value={95} aria-label="Load, hot" />

<Progress ramp="thermal" rampMode="gradient" value={80} aria-label="Capacity sweep" />