Determinate and indeterminate progress indicator bar
Tags: component feedback loading progress
A horizontal bar that communicates progress to the user. Supports both determinate (known percentage) and indeterminate (unknown duration) states.
Import
<script>
import { ProgressBar } from '@classic-homes/theme-svelte';
</script>import { ProgressBar } from '@classic-homes/theme-react';Basic Usage
<!-- Determinate -->
<ProgressBar value={45} />
<!-- Indeterminate -->
<ProgressBar />Props
| Prop | Type | Default | Description |
|---|---|---|---|
value |
number | undefined |
undefined |
Progress 0–100. Omit for indeterminate |
max |
number |
100 |
Maximum value |
size |
'sm' | 'md' | 'lg' |
'md' |
Bar height |
variant |
'default' | 'success' | 'warning' | 'destructive' |
'default' |
Fill color |
label |
string |
'Progress' |
Accessible label (aria-label) |
showValue |
boolean |
false |
Show percentage text next to the bar |
class |
string |
- | Additional CSS classes |
Determinate vs Indeterminate
Determinate
When value is provided, the bar fills proportionally:
<ProgressBar value={25} />
<ProgressBar value={50} />
<ProgressBar value={75} />
<ProgressBar value={100} />The value is clamped to [0, max].
Indeterminate
When value is omitted, the bar shows a repeating animation:
<ProgressBar />Use indeterminate mode when you don't know how long an operation will take.
Sizes
| Size | Height | Usage |
|---|---|---|
sm |
h-1 |
Subtle indicators |
md |
h-2 |
Default |
lg |
h-3 |
Prominent displays |
<ProgressBar value={60} size="sm" />
<ProgressBar value={60} size="md" />
<ProgressBar value={60} size="lg" />Color Variants
<ProgressBar value={70} variant="default" />
<ProgressBar value={70} variant="success" />
<ProgressBar value={70} variant="warning" />
<ProgressBar value={70} variant="destructive" />Use success when an operation completes, warning for approaching limits, and destructive for error states or critical thresholds.
Show Value
Display the percentage next to the bar:
<ProgressBar value={65} showValue />The percentage text only appears in determinate mode.
Examples
File Upload
<script>
let uploadProgress = $state(0);
</script>
<div class="space-y-2">
<div class="flex justify-between text-sm">
<span>Uploading document.pdf</span>
<span>{uploadProgress}%</span>
</div>
<ProgressBar value={uploadProgress} variant={uploadProgress >= 100 ? 'success' : 'default'} />
</div>Multi-Step Form
<script>
let currentStep = $state(2);
const totalSteps = 5;
</script>
<ProgressBar value={(currentStep / totalSteps) * 100} size="sm" label="Form progress" />
<p class="text-sm text-muted-foreground mt-1">
Step {currentStep} of {totalSteps}
</p>Storage Usage
<script>
const used = 7.2;
const total = 10;
const percentage = (used / total) * 100;
</script>
<ProgressBar
value={percentage}
variant={percentage > 90 ? 'destructive' : percentage > 75 ? 'warning' : 'default'}
showValue
/>
<p class="text-sm text-muted-foreground">{used} GB of {total} GB used</p>Loading with Indeterminate
<div class="space-y-2">
<p class="text-sm text-muted-foreground">Processing your request...</p>
<ProgressBar label="Processing" />
</div>Accessibility
- Uses native
role="progressbar"witharia-valuenow,aria-valuemin, andaria-valuemax aria-valuenowis omitted in indeterminate mode per WAI-ARIA specaria-labeldefaults to "Progress" — provide a descriptive label for context- Indeterminate animation respects
prefers-reduced-motion
<ProgressBar value={uploadProgress} label="File upload progress" showValue />Related Components
- Spinner - Circular indeterminate loading indicator
- Skeleton - Content placeholder during loading
- LoadingOverlay - Overlay that can use ProgressBar
- LoadingPage - Full-page loading with progress