Skip to main content
Urbicon UI

Progress

Shows task progress as a linear bar or circular ring.

Playground

Upload progress 65%
Size Style variant
Shape
<script lang="ts">
  import { Progress } from '@urbicon-ui/blocks';

  let value = $state(65);
</script>

<Progress
  {value}
  showValue
/>

01 Purpose

A progress indicator reports how far a task has advanced. Give it a value for determinate progress. The scale runs from 0 to max, which defaults to 100, so a percentage works on its own and passing max counts in bytes, steps or any other unit. Omit value for a task that is running but whose duration you cannot predict.

IndicatorReach for it when
Progress (determinate)You can measure how far along a task is: bytes uploaded, steps done, a percentage.
Progress (indeterminate)A task is running in place but its duration is unknown, and a labelled bar fits the layout.
SpinnerThe wait is short and unmeasured, and a bar would overstate the precision.
SkeletonContent itself is loading and you can hint at its shape in place.

02 Examples

File upload

On a linear bar, label and showValue render their own header row above the track, so a file name and a byte count need no markup of your own. striped animated reads as an active transfer, and it settles to a solid success bar on completion.
project-assets.zip 0.0 MB / 18.6 MB
<div
  class="border-border-subtle bg-surface-elevated w-full max-w-md space-y-3 rounded-2xl border p-5"
>
  <Progress
    value={uploadedMb}
    max={totalMb}
    label="project-assets.zip"
    showValue
    formatValue={(v, m) => `${v.toFixed(1)} MB / ${m} MB`}
    intent={uploadedMb >= totalMb ? 'success' : 'primary'}
    size="sm"
    striped={uploading}
    animated={uploading}
  />
  <Button variant="outlined" size="sm" onclick={simulateUpload} disabled={uploading}>
    {uploadButtonLabel}
  </Button>
</div>

Indeterminate

Omit value when a task is running but its duration is unknown. The bar loops until the work resolves. Always pass a label so the announcement is meaningful.
Processing payment…

Please keep this window open.

<div class="border-border-subtle bg-surface-elevated w-full max-w-md rounded-2xl border p-5">
  <Progress label="Processing payment…" intent="primary" size="sm" />
  <p class="text-text-tertiary mt-3 text-xs">Please keep this window open.</p>
</div>

Custom value format

Turn on showValue to print the percentage. formatValue replaces it with other units, like step counters or storage limits.
Onboarding 3 of 5 steps
Storage 750 MB
<Progress
  value={3}
  max={5}
  label="Onboarding"
  showValue
  formatValue={(v, m) => `${v} of ${m} steps`}
/>
<Progress
  value={750}
  max={1000}
  intent="warning"
  label="Storage"
  showValue
  formatValue={(v) => `${v} MB`}
/>

Circular metrics

shape=circular renders a ring with the value in its centre, and size sets the diameter. A ring draws no visible label, so label names it for screen readers while the caption below it is your own markup.
92%
Uptime
67%
CPU
34%
Memory
<div class="flex gap-8">
  <div class="flex flex-col items-center gap-2">
    <Progress
      value={92}
      shape="circular"
      intent="success"
      label="Uptime"
      showValue
      size="lg"
    />
    <span class="text-text-secondary text-xs font-medium">Uptime</span>
  </div>
  <div class="flex flex-col items-center gap-2">
    <Progress value={67} shape="circular" intent="warning" label="CPU" showValue size="lg" />
    <span class="text-text-secondary text-xs font-medium">CPU</span>
  </div>
  <div class="flex flex-col items-center gap-2">
    <Progress
      value={34}
      shape="circular"
      intent="primary"
      label="Memory"
      showValue
      size="lg"
    />
    <span class="text-text-secondary text-xs font-medium">Memory</span>
  </div>
</div>

03 Customization

Pill meter

class reaches the root wrapper, so a track restyle goes through slotClasses. Track and fill take their height from size, which means an override has to reach both or the fill sits short of the track.
Storage used 72%
<Progress
  value={72}
  intent="primary"
  label="Storage used"
  showValue
  slotClasses={{
    track: 'h-3 rounded-full bg-primary/10',
    fill: 'h-3 rounded-full'
  }}
/>

This is one of five ways to restyle a block. See Customization for class, slotClasses, unstyled, preset and provider-level overrides.

04 Accessibility

ARIA progressbar

Renders with role="progressbar" and aria-valuemin / aria-valuemax. In determinate mode it adds aria-valuenow. In indeterminate mode aria-valuenow is omitted to signal that progress is unknown.

Label

The label prop becomes the aria-label on the progressbar. On a linear bar it also renders as visible text above the track. A ring draws no label, so give it a caption of your own next to the label. Leave the prop off and the announcement falls back to the translated word for progress, which names no task, so an indeterminate bar in particular needs one.

Reduced motion

Under prefers-reduced-motion the striped and indeterminate linear animations stop, and the width transition collapses to an instant update.

05 API Reference

20 props
20 props
Prop
Type
Default
Description

06 Types

Local type definitions used by this component.

3 types
Name
Kind
Category
Used by
Description

07 Installation

Import

import { Progress } from '@urbicon-ui/blocks';