A linear progress indicator showing completion percentage; supports determinate and indeterminate modes.
Restructure — collapse 11 percentage variants into one component with a continuous <code>progress</code> value
Progress is a scalar — not an enum. The current schema cannot represent 37% or 62%, and every variant ships two raster PNGs for what should be two token-bound rectangles. Rebuild as a single component: progress: Float (0–1), state: determinate | indeterminate | success | error. Replace the raster back / front layers with vector strokes bound to main/progress-bar/color/border-track and main/progress-bar/color/border. Native side maps 1:1 to ProgressView / LinearProgressIndicator.
In Context
Progress Bar appears above or below task content to show completion — KYC steps, file upload progress, multi-step form wizards.
Live Preview
Content
progress
value45%
Properties (proposed)
state
DS Health
Reusable
Pass
Generic task-progress primitive — fits anywhere a linear completion indicator is needed (KYC, uploads, wizards).
Self-contained
Warn
Renders via raster back / front image layers instead of shape layers. Ships 11 PNGs worth of assets for what should be two rectangles.
Consistent
Fail
Progress modelled as a discrete percentage enum with 11 variants — cannot express 37%, 62%, or any non-decile value. Every other slider-style value in the DS is continuous.
Composable
Partial
Fixed 312-px width with 2-px horizontal padding hugs a single canonical layout; doesn't stretch responsively inside a fill container today.
Behavior
State
iOS
Android
Figma Property
Notes
Determinate
Yes
Yes
percentage=0…100
Fill grows left-to-right in 10% steps today. Should be continuous (0–1).
Indeterminate
N/A
N/A
Not modeled
Not modeled in Figma. Native primitives support it out of the box — add a variant so designers can spec it.
Success
N/A
N/A
Not modeled
Green fill at 100%. Used to confirm the task completed cleanly (file uploaded, verification passed).
Error
N/A
N/A
Not modeled
Red fill at the point of failure. Used when the task fails mid-progress (upload retry, network dropped).
Buffered
N/A
N/A
Not modeled
Compose supports a secondary buffered fill. Optional — only add if media streaming is a real use case.
Open Issues
Progress is an enum of 10% steps, not a value. The Figma component exposes percentage as 11 discrete options (0, 10, 20, …, 100). Consumers can't spec 37% or animate smoothly — they must pick the closest variant. Every scalar value in the DS should be continuous. C2 · Variant & Property Naming
Track and fill are raster PNGs. The back and front layers are <img> assets, not shape layers. Blocks token-driven theming, breaks at non-1× resolutions, and ships 11 PNG pairs for what should be two rectangles. C6 · Asset & Icon Quality
Layer names are structural (back / front), not semantic. Should be Track and Fill to match native parlance and make the inspector readable for handoff. C1 · Layer Structure & Naming
No indeterminate, success, or error state modeled. Native ProgressView and LinearProgressIndicator both support indeterminate natively; product flows (KYC failure, upload retry) need success / error color states. Today Figma has only the determinate-blue variants. C5 · Interaction State Coverage
Property name percentage reads as a unit, not a ratio. Native APIs use progress as a 0–1 Float. Renaming to progress (with a 0–1 range, or 0–100 if kept as integer) aligns the DS with iOS / Compose conventions. C2 · Variant & Property Naming
Code Connect mappings not registered. Cannot land until the progress value is parameterized and the raster layers are replaced with token-bound shapes. C7 · Code Connect Linkability
Design Recommendations
Collapse 11 percentage variants into a single component with a continuous progress value. Delete the percentage = 0 | 10 | … | 100 enum. Expose progress: Float (0–1). In Figma, drive the fill width by layout — either a single variant with a layer the designer resizes, or a published component that lives as a native primitive on the dev side. Variant math drops from 11 to 1 (+ state). Property
Replace raster back / front images with token-bound rectangles. Two filled rectangles (or stroked lines) bound to main/progress-bar/color/border-track and main/progress-bar/color/border. Same visual output, theme-able, resolution-independent, no PNG pairs to ship. Asset
Rename layers back → Track and front → Fill. Matches native terminology (track / tint in SwiftUI, trackColor / color in Compose) and reads better in the inspector. Rename
Add state variant: determinate / indeterminate / success / error. Indeterminate is a looping animation designers should be able to spec. Success (positive green) and error (negative red) cover KYC / upload result states. Token references: main/progress-bar/color/success and main/progress-bar/color/error — add to the collection. State
Reuse existing semantic color tokens for success / error. Don't mint new hex values. Align with Alert / Badge semantic colors (text/positive, text/negative) so the progress fill reads the same as the rest of the system. Token
Evaluate whether a bespoke EBProgressBar is needed at all. SwiftUI ProgressView(value:) and Compose LinearProgressIndicator are 1:1 matches for this component. If the only custom requirement is token-bound colors, a lightweight theming wrapper suffices; otherwise use the native primitive directly. Document either way. Composition
Make the component width-flexible. Today it's locked to 312 px with 2-px horizontal padding. Spec as fill-container so a designer can drop it into any column width. Property
Document accessibility expectations.role="progressbar", aria-valuenow / aria-valuemin / aria-valuemax for determinate; announce a localized label for indeterminate ("Loading…"). Both native APIs handle this automatically, but the web/hybrid consumer needs the spec. A11y
Styles
Determinate
DESDEV
Linear fill with a light-blue track and a brand-blue fill. The 11 Figma variants step through <code>percentage = 0, 10, 20, …, 100</code> — each variant swaps a pre-sized raster pair. The target implementation renders a single component with a continuous <code>progress</code> value.
Properties
State
Progress
Properties
Modedeterminate
Progress60%
Range0–100%
Track stylerounded
Colors
Track#D2E5FF
Fill#005CE5
Properties (today)
percentage0 | 10 | 20 | … | 100
Fill implementationraster <img>
Track implementationraster <img>
Width312 (fixed)
Layout
Total width312
Horizontal padding2
Inner track width308
Stroke height4 (raster-baked)
Corner radius0 (radius/radius-0)
Typography
No text—
Label pairingexternal
Progress Bar is a graphic-only primitive; labels and percentage text are the consumer's responsibility.
EBProgressBar(value: 0.6)
Track + Fill — Colors
Two-zone bar: a static track and an animated fill segment driven by the percentage variant.
Rename back → Track, front → Fill. Otherwise structurally clean.
C2
Variant & Property Naming
Requires Rework
percentage is a discrete enum; should be a continuous progress: Float (0–1).
C3
Token Coverage
Ready
Track + fill colors bound to main/progress-bar/color/*. Add success / error tokens once states are introduced.
C4
Native Mappability
Ready
Maps 1:1 to ProgressView(value:) / LinearProgressIndicator. No custom gesture or web-only patterns.
C5
Interaction State Coverage
Requires Rework
Missing indeterminate, success, error. Only determinate (in 10% steps) modeled today.
C6
Asset & Icon Quality
Requires Rework
Track + fill are raster <img>. Replace with token-bound rectangles or vector strokes.
C7
Code Connect Linkability
Not Mapped
Blocked until progress is parameterized and rasters replaced.
Variants Inventory (11 total)
A single percentage axis with 11 discrete values (0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100) = 11 variants. The target architecture collapses this axis into a continuous progress value — variant count drops to 1 (plus the new state axis for indeterminate / success / error).
#
Node
percentage
Fill width
Layer pair
1
27:64947
0
0 / 308
back only (no front rendered)
2
27:64949
10
~31 / 308
back + front raster
3
27:64953
20
~62 / 308
back + front raster
4
27:64957
30
~92 / 308
back + front raster
5
27:64961
40
~123 / 308
back + front raster
6
27:64965
50
~154 / 308
back + front raster
7
27:64969
60
~185 / 308
back + front raster
8
27:64973
70
~216 / 308
back + front raster
9
27:64977
80
~246 / 308
back + front raster
10
27:64981
90
~277 / 308
back + front raster
11
27:64985
100
308 / 308
back + front raster
1.0.0 — April 2026Major
Initial Assessment · node 18577:13227
Verdict: Restructure — Collapse 11 percentage variants into a single component with continuous progress: Float (0–1). Add state axis (determinate / indeterminate / success / error). Replace raster back/front with token-bound rectangles. Open
Schema
C1 — Layer naming — Rename back → Track and front → Fill. Aligns with native terminology. Open
C1
C2 — Continuous value — Replace percentage: 0 | 10 | … | 100 enum with progress: Float (0–1). Renaming from percentage to progress aligns with iOS / Compose conventions. Open
C2
C5 — Missing states — Add indeterminate, success, error variants. Native ProgressView / LinearProgressIndicator support these out of the box. Open
C5
C6 — Raster fills — Replace <img> back/front layers with token-bound rectangles using main/progress-bar/color/border-track and main/progress-bar/color/border. Open
C6
C7 — Code Connect — Mappings pending restructure. Blocked until progress is parameterized and rasters replaced. Open