Skip to content
SuperCoach

Components · Feedback

Progress

Beta

Shows how far a task has come, such as program completion.

12-week strengthWeek 3 of 12

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

Strength blockWeek 3 of 12
  1. 1. Label: names what is measured, and labels the bar for screen readers
  2. 2. Value text: the same value in words, such as Week 3 of 12
  3. 3. Track: the full length of the task
  4. 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.

Progress photo: front.jpg0%

UseValue textUpdates
Program or plan completionIn the program's own unit: "Week 3 of 12", "Day 18 of 30"When the coach opens the page
Upload or importA percentage: "60%"Live; announce the result once with a status message

States

Mobility basicsNot started
Fat loss: phase 1Week 7 of 12
Beginner strengthCompleted
StateWhat changesToken
Not started (value={0})Track only. Say so in the value text: "Not started"bg-primary/20
In progressIndicator fills to the valuebg-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 tracknone
ChangingThe indicator slides to the new valuetransition-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.
12-week strengthWeek 3 of 12
Do.A label and value text in the program's unit, next to the bar.
Don't.A bare bar. No one can tell what it measures, and screen readers hear only 25%.

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" with aria-valuemin="0", aria-valuemax="100" and aria-valuenow.
  • Give it a name with aria-labelledby pointing at the visible label, or aria-label.
  • Pass getValueLabel to set aria-valuetext in 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.

Semantic color tokens used by this component
TokenUtilitiesSuperCoachCoach
--primarybg-primary/20 bg-primarybrand-600orange-500
  • Motionduration-(--duration-base)
  • Motionease-standard
  • Radiusrounded-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.scss29
  • src/reusableComponents/progress-bar/progress-bar.scss4
  • src/reusableComponents/progress-bar/ProgressBar.tsx1

The inventory lists the first 12 locations of each value, so file counts are a lower bound.

Skeleton, Toast, Motion.