Components · Feedback
Progress
BetaShows how far a task has come, such as program completion.
- Source
components/ui/progress.tsx - shadcn/ui Progress
- Figma: not linked yet (Q13)
When to use
- To show how far a client is through something with a known end: a program ("Week 3 of 12"), a habit streak, onboarding steps.
- To show a task that is running and will finish: uploading progress photos, importing a client list.
When not to use
- When the length is unknown: use a spinner on the button that started the action, or a Skeleton for content that is loading. The bar has no indeterminate style.
- For a value the coach sets: use a slider.
- To compare values, such as macros against targets across days: use a chart.
- For a score or a health metric that isn't "done" at 100%, such as body fat: show the number, not a bar.
Anatomy
- 1. Label: names what is measured, and labels the bar for screen readers
- 2. Value text: the same value in words, such as Week 3 of 12
- 3. Track: the full length of the task
- 4. Indicator: the part that is done, filling from the start edge
The component is the track and the indicator. The label and value text are yours: put them in the layout above the bar and connect the label with aria-labelledby.
Variants
There is one visual style. What changes is how the value is written and whether it updates live.
| Use | Value text | Updates |
|---|---|---|
| Program or plan completion | In the program's own unit: "Week 3 of 12", "Day 18 of 30" | When the coach opens the page |
| Upload or import | A percentage: "60%" | Live; announce the result once with a status message |
States
| State | What changes | Token |
|---|---|---|
Not started (value={0}) | Track only. Say so in the value text: "Not started" | bg-primary/20 |
| In progress | Indicator fills to the value | bg-primary |
Complete (value={100}) | Indicator fills the track. The value text says "Completed" | bg-primary |
Indeterminate (value={null}) | Radix sets data-state="indeterminate", but the component draws an empty track | none |
| Changing | The indicator slides to the new value | transition-all (Tailwind default, not a motion token) |
Usage guidelines
- Always pair the bar with visible value text. The bar shows the shape; the text gives the number.
- Use the unit the coach thinks in. A program is "Week 3 of 12", not "25%".
- Don't animate from 0 on every page load. Animate only when the value changes while the coach watches.
- A progress bar doesn't announce its changes. For uploads, announce the result once in a
role="status"message.
Content guidelines
- Label: the thing being measured, as a noun: "12-week strength", "Progress photo: front.jpg".
- Value text: "Week 3 of 12", "Day 18 of 30", "60%". Sentence case. "Completed" at the end, "Not started" at 0.
- Arabic: "الأسبوع 3 من 12". Western digits in both languages (QUESTIONS Q22).
Accessibility
The bar isn't focusable, so it has no keyboard behavior.
- Rendered as
role="progressbar"witharia-valuemin="0",aria-valuemax="100"andaria-valuenow. - Give it a name with
aria-labelledbypointing at the visible label, oraria-label. - Pass
getValueLabelto setaria-valuetextin words. Without it, Radix writes a percentage. A screen reader then announces "12-week strength, progress bar, Week 3 of 12" instead of "25%". - Changes to the value are not announced. For something the coach waits for, put the result in a
role="status"message: "Photo uploaded to Sara's progress tab."
RTL
The indicator fills from the start edge: from the right in RTL. The label sits at the start and the value text at the end, so they swap sides. Numbers stay Western digits and read the same.
Tokens used
Read from components/ui/progress.tsx at build time, so this list changes when the component does. Opacity modifiers such as /90 are shadcn hover and focus tints on top of the token.
| Token | Utilities | SuperCoach | Coach |
|---|---|---|---|
| --primary | bg-primary/20 bg-primary | brand-600 | orange-500 |
- Motion
duration-(--duration-base) - Motion
ease-standard - Radius
rounded-full
Props
<Progress>
Also takes every prop of Radix Progress.Root
No props of its own.
value (0 to 100), max and getValueLabel(value, max) come from Radix Progress.
Replaces in coach-admin
From the read-only audit of coach-admin: 29 style values, 32 uses.
coach-admin's progress bar component and the AI section's loading bar become this component. The AI loader's indeterminate fill has no equivalent yet; use a spinner or a skeleton for unknown durations.
Classes and selectors
.progress-loader__bar-fill--indeterminate5.progress-loader__bar-fill4.progress-loader__title3.progress-loader__bar-container3.progress-loader__percentage1.progress-bar1.progress-loader1
Files
src/components/AiSection/ProgressLoader.scss29src/reusableComponents/progress-bar/progress-bar.scss4src/reusableComponents/progress-bar/ProgressBar.tsx1
The inventory lists the first 12 locations of each value, so file counts are a lower bound.