Progress
FeedbackLocal guide ↗
import { Progress } from "bits-ui" Determinate
Controls advance a task toward a known end point
Uploading research-notes.pdf
Encrypted transfer
<script lang="ts">
import { Progress, useId } from 'bits-ui';
const labelId = useId();
let value = $state(45);
function advance() {
value = Math.min(100, value + 15);
}
</script>
<div class="grid gap-4">
<div class="flex items-end justify-between gap-4">
<div>
<p id={labelId} class="text-sm font-medium text-ink-50">Uploading research-notes.pdf</p>
<p class="muted mt-1 text-xs">Encrypted transfer</p>
</div>
<span class="font-mono text-sm text-brand-400">{value}%</span>
</div>
<Progress.Root
aria-labelledby={labelId}
aria-valuetext={`${value}% uploaded`}
{value}
max={100}
class="h-3 w-full overflow-hidden rounded-full border border-ink-700 bg-ink-900"
>
<div
class="h-full w-full rounded-full bg-brand-500 transition-transform duration-300"
style={`transform: translateX(-${100 - value}%)`}
></div>
</Progress.Root>
<div class="flex flex-wrap gap-2">
<button class="btn btn-sm" onclick={() => (value = 0)}>Reset</button>
<button class="btn btn-sm" onclick={advance} disabled={value === 100}>Advance 15%</button>
<button class="btn btn-primary btn-sm" onclick={() => (value = 100)}>Complete</button>
</div>
</div>
Indeterminate
value={null} represents work whose completion cannot yet be calculated
Indexing workspace
The remaining work cannot be estimated yet
value = null · data-state = indeterminate
<script lang="ts">
import { Progress, useId } from 'bits-ui';
const labelId = useId();
</script>
<div class="grid gap-3">
<div class="flex items-center justify-between gap-4">
<div>
<p id={labelId} class="text-sm font-medium text-ink-50">Indexing workspace</p>
<p class="muted mt-1 text-xs">The remaining work cannot be estimated yet</p>
</div>
<span class="chip">Working</span>
</div>
<Progress.Root
aria-labelledby={labelId}
value={null}
class="relative h-3 w-full overflow-hidden rounded-full border border-ink-700 bg-ink-900"
>
<div
class="h-full w-full animate-pulse bg-gradient-to-r from-transparent via-brand-500 to-transparent"
></div>
</Progress.Root>
<p class="muted font-mono text-xs">value = null · data-state = indeterminate</p>
</div>
value accepts a number or null. A null value changes data-state to indeterminate and adds data-indeterminate; numeric values are interpreted between min and max, which default to 0 and 100. A visible label should be connected with aria-labelledby, or replaced by an aria-label when no label is shown.