Components Feedback
Progress
StableA linear progress bar for uploads, deployments and multi-step tasks.
Use Progress when an operation takes more than a couple of seconds and you can measure it. Omit value for indeterminate work. Prefer formatted value text people understand, such as "12 of 48 users", over bare percentages.
Overview
Uploading contract.pdf
import { Progress } from '@bindshq/stance-react';
export function Basic() {
return <Progress label="Uploading contract.pdf" value={64} showValue />;
}Light, dark and high contrast
Every Stance component is designed and tested in all three appearance modes.
Uploading contract.pdf
Uploading contract.pdf
Uploading contract.pdf
Import
import { Progress } from '@bindshq/stance-react';Platforms
Progress has native counterparts. They share Stance tokens and intent, and use each platform’s own controls and conventions. The live previews on this page are the web implementation.
import { Progress } from '@bindshq/stance-react';Playground
Deploying signatures
<Progress />Examples
Syncing users from Azure AD
import { Progress } from '@bindshq/stance-react';
export function ValueText() {
return (
<Progress
label="Syncing users from Azure AD"
value={12}
max={48}
showValue
formatValue={(v, m) => `${v} of ${m} users`}
/>
);
}Storage
Mailboxes updated
Seat usage
Deliveries failed
import { Progress } from '@bindshq/stance-react';
export function Tones() {
return (
<div style={{ display: 'grid', gap: 16 }}>
<Progress label="Storage" value={42} size="sm" showValue />
<Progress label="Mailboxes updated" value={100} tone="success" showValue />
<Progress
label="Seat usage"
value={46}
max={50}
tone="warning"
size="lg"
showValue
formatValue={(v, m) => `${v}/${m} seats`}
/>
<Progress label="Deliveries failed" value={8} tone="danger" showValue />
</div>
);
}Connecting to Exchange relay
import { Progress } from '@bindshq/stance-react';
export function Indeterminate() {
return <Progress label="Connecting to Exchange relay" />;
}Deploying Sales 2026
import * as React from 'react';
import { Button, Progress } from '@bindshq/stance-react';
export function Live() {
const [value, setValue] = React.useState(0);
React.useEffect(() => {
if (value >= 100) return;
const t = setTimeout(() => setValue((v) => Math.min(100, v + 7)), 300);
return () => clearTimeout(t);
}, [value]);
return (
<div style={{ display: 'grid', gap: 12 }}>
<Progress
label="Deploying Sales 2026"
value={value}
showValue
tone={value >= 100 ? 'success' : 'default'}
/>
<div>
<Button size="sm" variant="outline" onClick={() => setValue(0)}>
Restart
</Button>
</div>
</div>
);
}API reference
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | null | None | Current value; null or omitted is indeterminate. |
max | number | 100 | Maximum value. |
label | ReactNode | None | Visible label and accessible name. |
showValue | boolean | false | Show the formatted value. |
formatValue | (value: number, max: number) => string | percentage | Display text and aria-valuetext. |
size | 'sm' | 'md' | 'lg' | 'md' | Track height 4, 8 or 12px. |
tone | 'default' | 'success' | 'warning' | 'danger' | 'default' | Indicator colour. |
Accessibility
- Uses role="progressbar" with aria-valuemin, aria-valuemax, aria-valuenow and aria-valuetext.
- Indeterminate bars omit aria-valuenow, as the ARIA spec requires.
- Named by its visible label; pass aria-label when there is none.
- Indeterminate motion stops for people who prefer reduced motion.
Usage guidelines
Do
- Announce completion separately, e.g. with a Toast.
Don’t
- Use progress bars for scores or capacity; use a meter-style StatCard instead.