{
  "title": "Progress",
  "description": "Linear progress bar — determinate when you know the percentage, indeterminate when you don't.",
  "url": "/docs/components/progress",
  "since": "0.3.0",
  "tags": [
    "feedback",
    "loading"
  ],
  "platform": "both",
  "source": "---\ntitle: Progress\ndescription: Linear progress bar — determinate when you know the percentage, indeterminate when you don't.\nsince: 0.3.0\ntags: [feedback, loading]\nplatform: both\ncategory: feedback\n---\n\nimport { BundleSize } from '@/components/bundle-size';\nimport { Preview } from '@/components/preview';\nimport { PropsTable } from '@/components/props-table';\n\n<BundleSize component=\"Progress\" />\n\n## At a glance\n\n- Maps to `role=\"progressbar\"` with `aria-valuemin` / `aria-valuemax` / `aria-valuenow`. Always pass `label`, `aria-label`, or `aria-labelledby` so the bar is named.\n- The track is always pill-shaped (border-radius = height/2).\n\n## Preview\n\n<Preview name=\"progress-basic\" />\n\n## `value` and `max`\n\n`value` runs from `0` to `max` (default `100`). The fill width is\n`(value / max) * 100%`. Omit `value` to switch to indeterminate (see\nbelow).\n\n```tsx\n<Progress value={42} />              // 42 / 100\n<Progress value={3} max={5} />       // step 3 of 5 — 60%\n```\n\n## Indeterminate\n\nOmit `value` to render a 30%-wide shuttle that loops across the track\nevery ~1.5s. Use this when the operation has no measurable progress\n— an initial fetch, a streaming response, an upload before headers\narrive.\n\n<Preview name=\"progress-indeterminate\" />\n\n## `tone`\n\nColor of the fill / shuttle. Pick by what kind of work is happening\n— `success` after a confirmation, `warning` during risky operations,\n`danger` while recovering from a failure.\n\n| Value             | Use for                                    |\n|-------------------|--------------------------------------------|\n| `primary` (default) | Generic progress, brand-color fill       |\n| `info`            | Neutral status                             |\n| `success`         | \"Almost done\" / completion phases          |\n| `warning`         | Slow / pending operations                  |\n| `danger`          | Failure recovery, retry phases             |\n\n<Preview name=\"progress-tones\" />\n\n```tsx\n<Progress value={80} tone=\"success\" />\n```\n\n## `size`\n\nTrack height. Width always fills the parent.\n\n| Value          | Track height |\n|----------------|--------------|\n| `sm`           | 4 px         |\n| `md` (default) | 8 px         |\n| `lg`           | 12 px        |\n\n```tsx\n<Progress value={42} size=\"lg\" />\n```\n\n## `label` and `hidePercentage`\n\n`label` renders text above the bar. For determinate progress the\npercentage is auto-rendered on the right; pass `hidePercentage` to\nsuppress it (useful when the label itself already conveys the number,\ne.g. \"Step 3 of 5\").\n\n```tsx\n<Progress value={42} label=\"Uploading photos\" />\n<Progress value={3} max={5} label=\"Step 3 of 5\" hidePercentage />\n```\n\n## `aria-label` / `aria-labelledby`\n\nWhen you don't render a visible `label`, name the bar via `aria-label`\nor `aria-labelledby` so screen readers announce it. Without one of\nthose three, an unnamed progressbar is a silent progressbar.\n\n```tsx\n<Progress value={42} aria-label=\"Upload progress\" />\n```\n\n## Props\n\n<PropsTable component=\"Progress\" />\n"
}
