Feedback & status

AppProgress

A determinate progress bar — a task's completion from 0 to a known total.

<app-progress value="60" max="100" tone="success" label="60%" />

<app-progress> shows how far a task has gotten toward a known total — an upload, a multi-step import, storage used against a quota. It is Bootstrap's .progress / .progress-bar, tinted by the theme.

It only makes sense when there is a real amount to report. For a "working…" wait with no known duration or amount, use <app-spinner> instead — see below.

Its look comes entirely from the shared @webority/theme, so the Razor <app-progress> and the React <AppProgress> render identically on every Webority surface.

Playground

Every attribute, live. Each change re-renders the real tag helper on the server, so the markup underneath is the exact call that produced the bar above it.

<app-progress value="60" label="Sync progress" />

Tones

Five tones map to intent, the same vocabulary as app-alert and app-banner — pick the tone by meaning, not by colour.

The five tones
Each bar here is at the same 60% so only the fill colour changes.
Show code
<app-progress value="60" tone="info" label="Sync progress" />
<app-progress value="60" tone="success" label="Sync progress" />
<app-progress value="60" tone="warning" label="Sync progress" />
<app-progress value="60" tone="danger" label="Sync progress" />
<app-progress value="60" tone="neutral" label="Sync progress" />

A visible label

label is always the accessible name for the bar. Add show-label to also render it inside the fill, once there is enough width for the text to sit comfortably.

Label shown inside the bar
72%
Show code
<app-progress value="72" max="100" tone="success" label="72%" show-label="true" />

Any scale, not just percent

value and max don't have to be 0–100 — pass whatever the real total is and app-progress works out the fill width.

Partial value against a real total
30 of 60 storage credits used — the bar reads the same as 50%, but the label can say the real numbers.
30 of 60 credits used
Show code
<app-progress value="30" max="60" tone="info" label="30 of 60 credits used" show-label="true" />
Near complete
A value clamps into 0…max, so a caller that overshoots (a 101% rounding glitch, a stale total) can't render a bar wider than its track.
97%
Show code
<app-progress value="97" max="100" tone="warning" label="97%" show-label="true" />

Striped & animated fill

striped adds a diagonal stripe overlay; animated moves it (and implies striped) — use it to signal the bar is actively working, not just a static split.

Striped
Show code
<app-progress value="55" tone="info" label="55%" striped="true" />
Animated
The stripes move — a stronger cue than a static bar that the task is still running.
Show code
<app-progress value="55" tone="info" label="55%" animated="true" />

Indeterminate

When the total or the pace isn't known yet but the layout calls for a bar shape (a table row, a slim inline strip) rather than a spinner, indeterminate drops the value and label for an animated sweep.

Unknown duration
Show code
<app-progress indeterminate="true" tone="info" label="Working…" />

Compact size

size="sm" renders a thin 4px bar for inline or table use, where a full-height bar would crowd the row.

size="sm"
Show code
<app-progress value="80" max="100" tone="success" size="sm" label="80%" />
Indeterminate wait? Use app-spinner<app-progress> needs a real value — it always renders a specific fill width. When you don't know how much is done or how long it will take, that's <app-spinner>'s job, not a progress bar frozen at some arbitrary width.

When to use

Use it when

  • The task has a known total and a real, changing amount completed — an upload, an import, a quota.
  • You can compute a percentage (or a value/max pair) at any moment during the wait.
  • Showing how much is left is genuinely useful to the reader, not just decoration.

Reach for something else when

  • There is no known amount or duration — it's just "working". → app-spinner
  • Content with a known shape is loading, not a quantified task. → app-skeleton
  • A button is submitting a single request. → app-button loading

Best practices

Do
Importing 45 of 100 rows
A real value with a label that states the actual amount, not just a bare percentage.
Don't
A progress bar pinned at 100% (or any fixed value) to fake a spinner — that's app-spinner's job.

Every option

The whole surface of the component, one cell per value.

tone — all five

tone="info"
tone="success"
tone="warning"
tone="danger"
tone="neutral"

size — both

size="md"
size="sm"

label / show-label

(no label)
label (accessible name only)
label + show-label
60%
show-label with a long label (overflow)
Importing customer records from the legacy system

striped / animated

(default, flat fill)
striped
animated (implies striped)
striped="false" animated (still implies striped)

value / max — clamping and non-percent scales

value="0" (empty track)
value="100" max="100" (full)
value="150" max="100" (clamps to 100%)
value="-20" max="100" (clamps to 0%)
value="30" max="60" (non-100 total)
30 of 60

indeterminate

indeterminate
indeterminate show-label (label dropped from the bar, kept for a11y)
indeterminate size="sm"

Attributes

AttributeTypeDefaultDescription
value *number—Current amount (0…max); clamped into range.
maxnumber100The full amount.
toneinfo | success | warning | danger | neutralinfoThe fill colour.
sizesm | mdmdBar thickness — sm is a thin 4px bar for inline/table use.
labelstring—Accessible name for the bar; also shown inside it when show-label.
show-labelboolfalseRender the label text inside the bar (ignored when indeterminate).
stripedboolfalseDiagonal stripe overlay.
animatedboolfalseAnimate the stripes (implies striped).
indeterminateboolfalseUnknown-duration sweep; drops the value/label.