Skip to main content

Installation

npx @soft-ui/cli add progress

Usage

import { Progress } from '@soft-ui/react/progress'

export default function Example() {
  return (
    <Progress.Root value={60}>
      <Progress.Track>
        <Progress.Indicator />
      </Progress.Track>
    </Progress.Root>
  )
}

Examples

Sizes

Two sizes available: s (default) and m.
<Progress.Root size="s" value={60}>
  <Progress.Track>
    <Progress.Indicator />
  </Progress.Track>
</Progress.Root>

<Progress.Root size="m" value={60}>
  <Progress.Track>
    <Progress.Indicator />
  </Progress.Track>
</Progress.Root>

Tones

Four semantic tones for different states.
<Progress.Root tone="default" value={60}>
  <Progress.Track>
    <Progress.Indicator />
  </Progress.Track>
</Progress.Root>

<Progress.Root tone="success" value={100}>
  <Progress.Track>
    <Progress.Indicator />
  </Progress.Track>
</Progress.Root>

<Progress.Root tone="warning" value={75}>
  <Progress.Track>
    <Progress.Indicator />
  </Progress.Track>
</Progress.Root>

<Progress.Root tone="danger" value={25}>
  <Progress.Track>
    <Progress.Indicator />
  </Progress.Track>
</Progress.Root>

With Label

Add a descriptive label above the progress bar.
<Progress.Root value={60}>
  <Progress.Label>Uploading files</Progress.Label>
  <Progress.Track>
    <Progress.Indicator />
  </Progress.Track>
</Progress.Root>

With Value Display

Show the numeric value alongside the progress bar.
<Progress.Root value={60}>
  <div className="flex items-center justify-between">
    <Progress.Label>Processing</Progress.Label>
    <Progress.Value />
  </div>
  <Progress.Track>
    <Progress.Indicator />
  </Progress.Track>
</Progress.Root>

Indeterminate

For unknown progress duration (loading state).
<Progress.Root value={null}>
  <Progress.Track>
    <Progress.Indicator />
  </Progress.Track>
</Progress.Root>

Dynamic Updates

Progress animates smoothly when value changes.
const [value, setValue] = useState(0)

useEffect(() => {
  const timer = setInterval(() => {
    setValue((prev) => (prev >= 100 ? 0 : prev + 10))
  }, 500)
  return () => clearInterval(timer)
}, [])

<Progress.Root value={value}>
  <Progress.Track>
    <Progress.Indicator />
  </Progress.Track>
</Progress.Root>

API Reference

Progress.Root

value
number | null
Current progress value (0-100). Use null for indeterminate state.
min
number
default:0
Minimum value.
max
number
default:100
Maximum value.
tone
string
default:"default"
Semantic color tone: default, success, warning, danger.
size
string
default:"s"
Size of the progress bar: s, m.

Progress.Label

Accessible label for the progress indicator. Automatically associated with the progress element.
children
ReactNode
Label text.

Progress.Track

Background track for the progress indicator.

Progress.Indicator

Filled portion showing progress. Width animates based on value.

Progress.Value

Displays the current value as text (e.g., “60%”).
children
(value: number, max: number) => ReactNode
Optional render function to customize value display. Defaults to ”%”.

Accessibility

  • Uses Base UI Progress primitive with proper ARIA attributes
  • Progress.Label automatically associates with progress via aria-labelledby
  • aria-valuenow, aria-valuemin, and aria-valuemax automatically managed
  • Indeterminate state properly communicated to screen readers
  • Visual progress changes announced to assistive technology

Design Tokens

Progress uses design tokens for consistent styling:
  • Spacing: --space-4, --space-6, --space-8
  • Border radius: --radius-max for rounded ends
  • Colors: --color-surface-interactive-default (track), --color-content-* (indicator)
  • Typography: --font-size-s, --line-height-s, --font-weight-medium
  • Animation: 300ms ease-out transition

Build docs developers (and LLMs) love