Progress
Headless Progress; covers HTML progress, WAI-ARIA progressbar, React Aria ProgressBar.
| Package | @vizejs/ui/progress |
| Maturity | stable |
| Own the source | vize lib pull progress |
| Requires | id |
| Aliases | native progress, loading progress, task progress |
| Covers | HTML progress, WAI-ARIA progressbar, React Aria ProgressBar |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/ui
Add the public import below to <script setup lang="ts">. Components provide behavior without styles; the preview uses optional Paper styles.
import { Progress } from "@vizejs/ui/progress";
Or copy the source into your project with vize lib pull progress (see Source Distribution).
Try it
This is the basic example maintained with the component source, using the public package imports. The preview adds the optional Paper styles.
Open the interactive example · Styling these components
Copy the example
<!-- Native determinate progressbar labelled by visible text. -->
<script setup lang="ts">
import { useId } from "vue";
import { Progress } from "@vizejs/ui/progress";
const labelId = useId();
</script>
<template>
<div>
<span :id="labelId">Uploading photos</span>
<Progress :value="40" :max="100" :aria-labelledby="labelId">
<template #default="{ percent }">{{ percent }}%</template>
</Progress>
</div>
</template>
API
Progress
Source: src/families/feedback/progress/progress.vue
Props
| Prop | Type | Default | Description |
|---|---|---|---|
id |
string | null |
undefined |
Consumer-owned progressbar id. |
value |
number | null |
null |
Current determinate value. null, undefined, and non-finite numbers render indeterminate. |
max |
number | null |
100 |
Positive maximum value. Non-positive and non-finite numbers fall back to 100. |
ariaLabel |
string |
undefined |
Accessible name when no visible label or aria-labelledby supplies one. |
ariaLabelledby |
string |
undefined |
Space-separated ids that label the progressbar. |
ariaDescribedby |
string |
undefined |
Space-separated ids that describe the progressbar. |
ariaValueText |
string |
undefined |
Human-readable value text for assistive technology. |
Slots
| Slot | Slot props | Description |
|---|---|---|
default |
ProgressSlotState |
Optional fallback contents. Receives normalized Progress state for composition. |
Exposed
| Member | Type | Description |
|---|---|---|
value |
number | null |
Current normalized value, or null when the progressbar is indeterminate. |
max |
number |
Positive normalized maximum value used by the native progressbar. |
percent |
number | null |
Current completion percentage from 0 to 100, or null when indeterminate. |
indeterminate |
boolean |
Whether no determinate value is available. |
complete |
boolean |
Whether the normalized value has reached the normalized maximum. |
state |
ProgressState |
Stable state token for styling and tests. |
element |
HTMLProgressElement | null |
Rendered native progress element. |
Behavior
Normative state/input -> outcome table for progress.vue
(@vizejs/ui/progress). Every row is proven by the named mounted-DOM, SSR,
runtime-conformance, renderer, type, size, or tree-shaking gate.
| # | State | Input | Outcome | Proven by |
|---|---|---|---|---|
| P1 | any | state normalization | finite determinate values clamp to 0..max; invalid maximum values fall back to 100; non-finite is unknown |
normalizes determinate, complete, and indeterminate state |
| P2 | determinate | render | native <progress>, implicit progressbar, deterministic or explicit id, accessible name, and value attrs |
renders a named native determinate progressbar |
| P3 | determinate | render | exposes data-state, data-value, data-max, data-percent, data-complete, and part="root" |
renders a named native determinate progressbar |
| P4 | indeterminate | render | omits the native value attribute and sets data-state="indeterminate" |
omits the native value for indeterminate progress |
| P5 | out of range | prop update | native attributes, DOM properties, data attributes, slot state, and exposed state all use the normalized value | clamps native attributes to the safe progress range |
| P6 | prop-driven | prop update | slot props and exposed state update without local mutable progress state | updates slot and exposed state from props |
| P7 | any | Tab / render | remains non-interactive, does not enter sequential focus, and does not create a live region by default | does not enter the tab order or create a live region by default |
| P8 | SSR | isolated requests | server markup is byte-stable and keeps native progress semantics | progress-ssr.test.ts |
| P9 | SSR/hydration | runtime fixture | server markup is stable and hydrates without warnings or node replacement | runtime-conformance.test.ts |
| P10 | public types | invalid state | TypeScript rejects closed-contract misuse | src/families/feedback/progress/progress.types.test-d.ts |
The Progress primitive is headless. It ships no CSS, exposes no live-region
policy by default, and relies on the native progress element for platform
semantics. Consumers that need spoken milestones should compose Progress with
@vizejs/ui/announcer and coalesce updates there.