ProgressBar
Headless ProgressBar; covers WAI-ARIA progressbar role, React Aria ProgressBar, HTML progress.
| Package | @vizejs/ui/progress-bar |
| Maturity | stable |
| Own the source | vize lib pull progress-bar |
| Requires | id |
| Aliases | progress, loading progress, task progress, upload progress |
| Covers | WAI-ARIA progressbar role, React Aria ProgressBar, HTML progress |
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 { ProgressBar } from "@vizejs/ui/progress-bar";
Or copy the source into your project with vize lib pull progress-bar (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
<!-- Determinate progress bar with a visible label and value text. -->
<script setup lang="ts">
import { ProgressBar } from "@vizejs/ui/progress-bar";
</script>
<template>
<ProgressBar :value="64" label="Syncing library" value-label="64 of 100 tracks" />
</template>
API
ProgressBar
Source: src/families/feedback/progress-bar/progress-bar.vue
Props
| Prop | Type | Default | Description |
|---|---|---|---|
as |
PrimitiveAs |
"div" |
Native element, custom element, or component rendered as the root. |
id |
string | null |
undefined |
Consumer-owned progressbar id. |
value |
number | null |
null |
Current determinate value. null and undefined render indeterminate. |
min |
number | null |
0 |
Lower bound for the progress range. |
max |
number | null |
100 |
Upper bound. Values less than or equal to min are repaired to min + 100. If that addition rounds back to min, the collapsed finite range reports zero ratio/percent and invalid state without changing the completion policy. |
dir |
ProgressBarDirection |
"ltr" |
Reading direction for inline-start fill and indeterminate motion. |
label |
string |
undefined |
Optional visible label rendered in the label part. |
valueLabel |
string |
undefined |
Optional visible value text reused as aria-valuetext. |
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 assistive value text, overriding valueLabel. |
Slots
| Slot | Slot props | Description |
|---|---|---|
default |
ProgressBarSlotState |
Render consumer-owned content inside the root with normalized progress state. |
label |
ProgressBarSlotState |
Render a visible label inside the deterministic label node. |
value |
ProgressBarSlotState |
Render visible value text inside the deterministic value node. |
indicator |
ProgressBarSlotState |
Render optional content inside the indicator part. |
Exposed
| Member | Type | Description |
|---|---|---|
value |
number | null |
Current normalized value, or null when the progressbar is indeterminate. |
min |
number |
Finite lower bound. |
max |
number |
Finite upper bound, equal to min only when the default repair cannot advance it. |
percent |
number | null |
Current completion percentage from 0 to 100, or null when indeterminate. |
ratio |
number | null |
Unitless completion ratio from 0 to 1, or null when indeterminate. |
dir |
ProgressBarDirection |
Reading direction reflected to dir and data-dir. |
indeterminate |
boolean |
Whether no determinate value is available. |
complete |
boolean |
Whether the normalized value has reached the normalized maximum. |
invalid |
boolean |
Whether raw inputs had to be repaired before reaching ARIA or CSS. |
state |
ProgressBarState |
Stable state token for styling and tests. |
id |
string |
Deterministic id used by the root progressbar. |
labelId |
string |
Deterministic id used by the internal label node when rendered. |
valueId |
string |
Deterministic id used by the internal value node when rendered. |
style |
ProgressBarStyle |
Native CSS custom property hooks applied to the root. |
root |
PrimitiveElement | null |
Rendered root element or component instance. |
track |
HTMLSpanElement | null |
Rendered track element. |
indicator |
HTMLSpanElement | null |
Rendered indicator element. |
focus |
(options?: FocusOptions) => void |
Moves DOM focus to the root when the rendered host supports it. |
Behavior
Normative state x input -> outcome table for progress-bar.vue
(@vizejs/ui/progress-bar). Every row is proven by the named mounted-DOM, SSR,
runtime-conformance, renderer, type, size, or tree-shaking gate. The legacy
@vizejs/ui/progress entry remains a compatibility alias for Progress.
| # | State | Input | Outcome | Proven by |
|---|---|---|---|---|
| P1 | any | state normalization | finite values clamp to min..max, invalid bounds repair to min + 100, non-finite values are indeterminate, and invalid repairs are flagged |
normalizes determinate, complete, indeterminate, and invalid state |
| P2 | determinate | render | renders equivalent role="progressbar" semantics with deterministic or explicit id, labelled name, min/max/now/value text, and no live region |
renders a named determinate progressbar with parts and CSS hooks |
| P3 | determinate | render | exposes root, label, track, indicator, and value parts plus stable data attributes and CSS custom properties | renders a named determinate progressbar with parts and CSS hooks |
| P4 | indeterminate | render | omits aria-valuenow, keeps min/max semantics, mirrors data-state="indeterminate", and can expose authored value text |
omits value semantics for indeterminate progress |
| P5 | out of range | prop update | ARIA attributes, data attributes, slot state, CSS hooks, and exposed state all use normalized values | clamps ARIA attributes to the safe progress range |
| P6 | prop-driven | prop update | slots and exposed refs/state update without local mutable progress state | updates slot and exposed state from props |
| P7 | RTL/custom | dir="rtl" and as component |
custom hosts preserve role, deterministic label wiring, direction, parts, slots, and inline-start fill hooks | uses visible label slots, RTL direction, and consumer host components |
| P8 | 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 |
| P9 | SSR | isolated requests | renders byte-identical labelled and indeterminate server markup without request-global state | progress-bar-ssr.test.ts |
| P10 | SSR/hydration | runtime fixture | server markup hydrates without warnings or root node replacement | runtime-conformance.test.ts |
| P11 | DOM/SSR/Vapor | compile | authored SFC and consumer fixture compile in every renderer lane without warnings | scripts/check-renderers.ts |
| P12 | public types | invalid contract | TypeScript rejects unsupported direction, state, props, and malformed readonly slot/expose shapes | src/families/feedback/progress-bar/progress-bar.types.test-d.ts |
| P13 | root/subpath | consumer bundle | root and subpath consumers retain only ProgressBar and its structural CSS within gzip budgets | scripts/check-tree-shaking.mjs |
Props
| Prop | Type | Purpose | Default |
|---|---|---|---|
as |
PrimitiveAs |
Native element, custom element, or component rendered as root. | "div" |
id |
string | null |
Consumer-owned progressbar id. | undefined |
value |
number | null |
Current value; null, undefined, and non-finite values are indeterminate. |
null |
min |
number | null |
Lower bound. | 0 |
max |
number | null |
Upper bound; invalid bounds repair to min + 100. |
100 |
dir |
"ltr" | "rtl" |
Reading direction for inline-start fill and animation. | "ltr" |
label |
string |
Optional visible label rendered in the label part. | undefined |
valueLabel |
string |
Optional visible value text reused as fallback aria-valuetext. |
undefined |
ariaLabel |
string |
Accessible name when no visible label or labelledby exists. | undefined |
ariaLabelledby |
string |
Space-separated ids that label the progressbar. | undefined |
ariaDescribedby |
string |
Space-separated ids that describe the progressbar. | undefined |
ariaValueText |
string |
Human-readable value text; overrides valueLabel. |
undefined |
Slots
| Slot | Props | Purpose | Default |
|---|---|---|---|
default |
ProgressBarSlotState |
Render consumer-owned content inside the root. | none |
label |
ProgressBarSlotState |
Render a visible label in the label part. | label prop |
value |
ProgressBarSlotState |
Render visible value text in the value part. | valueLabel prop |
indicator |
ProgressBarSlotState |
Render optional content inside the indicator. | none |
Expose
| Name | Type | Purpose | Default |
|---|---|---|---|
root |
PrimitiveElement | null |
Rendered root element or component. | null |
track |
HTMLSpanElement | null |
Rendered track part. | null |
indicator |
HTMLSpanElement | null |
Rendered indicator part. | null |
focus |
(options?: FocusOptions) => void |
Moves DOM focus to the root when supported. | n/a |
value |
number | null |
Normalized current value. | null |
min |
number |
Normalized lower bound. | 0 |
max |
number |
Normalized upper bound. | 100 |
percent |
number | null |
Completion percentage. | null |
ratio |
number | null |
Completion ratio from 0 to 1. | null |
dir |
"ltr" | "rtl" |
Reflected reading direction. | "ltr" |
state |
"loading" | "complete" | "indeterminate" |
Stable progress state. | derived |
style |
ProgressBarStyle |
CSS custom property hooks applied to root. | derived |
Data Attributes
| Attribute | Host | Values | Purpose | Default |
|---|---|---|---|---|
data-vize-ui |
root | "progress-bar" |
Stable family selector. | always |
data-vize-ui |
parts | "progress-bar-label", "progress-bar-track", "progress-bar-indicator", "progress-bar-value" |
Stable part selectors. | derived |
data-dir |
root | "ltr", "rtl" |
Direction hook. | "ltr" |
data-state |
root | "loading", "complete", "indeterminate" |
Stable state hook. | derived |
data-labelled |
root | "true", "false" |
Accessible-name hook. | derived |
data-indeterminate |
root | "true", "false" |
Value policy hook. | derived |
data-complete |
root | "true", "false" |
Completion hook. | derived |
data-invalid |
root | "true" |
Raw-input repair hook. | omitted |
data-value |
root | number |
Normalized value. | omitted when indeterminate |
data-min |
root | number |
Normalized lower bound. | derived |
data-max |
root | number |
Normalized upper bound. | derived |
data-percent |
root | number |
Completion percentage. | omitted when indeterminate |
CSS Custom Properties
| Property | Host | Purpose | Default |
|---|---|---|---|
--vize-ui-progress-bar-min |
root | Normalized lower bound. | derived |
--vize-ui-progress-bar-max |
root | Normalized upper bound. | derived |
--vize-ui-progress-bar-value |
root | Normalized value or min. | derived |
--vize-ui-progress-bar-percent |
root | Completion percentage with %. |
derived |
--vize-ui-progress-bar-ratio |
root | Completion ratio. | derived |
--vize-ui-progress-bar-inline-size |
root | Root inline size. | 100% |
--vize-ui-progress-bar-gap |
root | Root grid gap. | 0.25rem |
--vize-ui-progress-bar-track-block-size |
track | Track block size. | 0.5rem |
--vize-ui-progress-bar-track-radius |
track | Track and indicator radius. | 999px |
--vize-ui-progress-bar-track-color |
track | Track background. | mixed current color |
--vize-ui-progress-bar-indicator-color |
indicator | Indicator background. | currentColor |
--vize-ui-progress-bar-duration |
indicator | Determinate transition duration. | 160ms |
--vize-ui-progress-bar-indeterminate-size |
indicator | Indeterminate indicator width. | 40% |
--vize-ui-progress-bar-indeterminate-duration |
indicator | Indeterminate animation duration. | 1.2s |
Parts
| Part | Purpose | Default |
|---|---|---|
root |
Progressbar semantics and CSS hooks. | always |
label |
Visible label container. | when labelled |
track |
Structural track. | always |
indicator |
Filled or indeterminate indicator. | always |
value |
Visible value text container. | when value text exists |
Finite numeric limits
Determinate percentages and ratios remain finite when two finite bounds have a
difference larger than Number.MAX_VALUE. A signed range from
-Number.MAX_VALUE to Number.MAX_VALUE reports 0% at the minimum, 50% at zero,
and 100% at the maximum. Only an overflowing difference uses half-scaled
arithmetic; ordinary normalization and CSS tokens keep their existing values.
Invalid upper bounds still repair to min + 100. When floating-point precision
rounds that addition back to min, the authored finite bounds remain intact.
This narrow invalid case reports ratio=0, percent=0, and invalid=true.
Completion retains its existing definition: a determinate value at the
normalized maximum is complete, including this invalid collapsed range.
Indeterminate values remain null, omit aria-valuenow and data-percent, and
use zero-valued ratio/percentage CSS hooks.
WAI-ARIA permits equal minimum and maximum bounds.
The pure range tests, mounted prop-update test, isolated SSR requests, and
progress-bar-wide-range, progress-bar-wide-endpoint,
progress-bar-collapsed-positive, and progress-bar-collapsed-negative runtime
fixtures cover these limits. Existing CSS, exports, budgets, and known-failure
ledger remain unchanged.