Progress steps

Where a reader is in a flow of named stages: four layouts on one Progress namespace. Three types, two orientations, two sizes, nothing interactive.

Demo

Every layout with its own props. The steps are the sheet’s four, carried typed — an untyped array widens the statuses.

Completed

Your details

Name and email

Current step

Company details

Website and location

Not started

Invite your team

Start collaborating

Not started

Add your socials

Automatic sharing

Component
type
orientation
size
import { Progress } from "@/components/application/progress-steps/progress-steps"; import type { ProgressIconType } from "@/components/application/progress-steps/progress-types"; const steps: ProgressIconType[] = [ { title: "Your details", description: "Name and email", status: "complete", }, { title: "Company details", description: "Website and location", status: "current", }, { title: "Invite your team", description: "Start collaborating", status: "incomplete", }, { title: "Add your socials", description: "Automatic sharing", status: "incomplete", }, ]; <Progress.IconsWithText orientation="horizontal" items={steps} />

Status is data, not state

Each item carries its own status, and nothing in the kit changes it: no click, no key, no handler. The playground switches between the sheet’s two status sets as you flip the orientation, which is why the horizontal row is on step 2 and the vertical column on step 3; it swaps the supporting text with them, for the reason the Icons with text section gives.

Contextual demo

A progress row only makes sense beside the form it tracks. The preview puts all four layouts in a real screen, each beside the fields it belongs to.

Five consumers already ship it

The kit’s own sign-up assets render three of the four layouts: signup-progress-02 and both sidebar versions draw IconsWithText with the featured-icon type, signup-progress-03 draws TextWithLine, and signup-progress-01 draws MinimalIconsConnected twice, once with orientation="vertical", which is inert. The fixtures on this page are their copy.

The family

Four layouts on one Progress namespace, eight step bases, and the shared status map. Three files, three import paths.

The components in this family, with their descriptions and import paths
ComponentDescriptionImport from
Progress.IconsWithTextThe full layout: a step icon, number, or featured icon with a title and supporting text, joined by connectors, in a column or a row of equal grid columns. Type and orientation pick one of six step bases.@/​components/​application/​progress-steps/​progress-steps
Progress.MinimalIconsA “Step N of M” label and a row of bare status circles, centered, in the icon or the number type. No connectors, no titles.@/​components/​application/​progress-steps/​progress-steps
Progress.MinimalIconsConnectedThe same bare circles joined by connectors, capped at 320px or 360px and centered: solid and status-colored in the icon type, dashed gray with 6px gaps in the number type. Its orientation prop is accepted and does nothing.@/​components/​application/​progress-steps/​progress-steps
Progress.TextWithLineA 4px bar over a title and supporting text, one equal column per step. The only layout with no icon.@/​components/​application/​progress-steps/​progress-steps
NumberOnlyThe numbered circle, added 2026-08-31 so the minimal layouts can draw the sheet’s Number variants: bg-success-solid with a tick when complete, otherwise bg-primary with a 1px ring and the numeral in text-secondary when current and text-quaternary when not. It takes the step number and, unlike the number step bases, dims nothing.@/​components/​application/​progress-steps/​progress-step-base
NumberConnectorThe dashed gray line between two numbered circles in the connected row, as a flex child: a 2px stroke with a 0.1/6 round-capped dash, the same at every status.@/​components/​application/​progress-steps/​progress-step-base
IconOnlyThe 24px or 32px status circle the icon type and both minimal layouts draw: a dot, a brand halo, or a tick, with a screen-reader status inside, and aria-current on its own span unless a base that marks its root passes markCurrent={false}. The number bases draw their own circle and the featured bases a FeaturedIcon.@/​components/​application/​progress-steps/​progress-step-base
IconTop, IconLeftThe icon type’s horizontal and vertical step bases: IconOnly, a solid connector, and the text block. Titles and supporting text turn brand on the current step.@/​components/​application/​progress-steps/​progress-step-base
IconTopNumber, IconLeftNumberThe number type’s pair: a numbered circle, green with a tick when complete, and a dashed SVG connector. They take a step prop the layout supplies.@/​components/​application/​progress-steps/​progress-step-base
FeaturedIconTop, FeaturedIconLeftThe featured-icon type’s pair: the kit’s FeaturedIcon in its modern gray theme holding the item’s own icon, over a solid connector.@/​components/​application/​progress-steps/​progress-step-base
TextLineOne column of TextWithLine: the bar, the title, and the supporting text. No connector prop.@/​components/​application/​progress-steps/​progress-step-base
statuses, numberStatuses, statusLabelsThe two shared status maps — the icon type’s (icon, dot, connector, title, and description classes per status) and the number type’s, which the two number step bases and NumberOnly all read since 2026-08-31 — plus the three screen-reader strings: Not started, Current step, Completed.@/​components/​application/​progress-steps/​progress-step-base

Built from

Four pieces make up the steps; one has its own docs page.

Component
Where it’s used here
FeaturedIconThe featured-icon type’s tile, in color gray and theme modern, at size md for sm steps and lg for md steps. The item’s icon goes in through its icon prop on both the top and, since 2026-08-23, the left variant.

Icons with text

Three types at two sizes, horizontal then vertical, live with the sheet’s own statuses. Narrow screens scroll the rows.

horizontal, size sm
Completed

Your details

Name and email

Current step

Company details

Website and location

Not started

Invite your team

Start collaborating

Not started

Add your socials

Automatic sharing

type icon
Completed

Your details

Name and email

Current step2

Company details

Website and location

Not started3

Invite your team

Start collaborating

Not started4

Add your socials

Automatic sharing

type number
Completed

Your details

Name and email

Current step

Company details

Website and location

Not started

Invite your team

Start collaborating

Not started

Add your socials

Automatic sharing

type featured-icon
horizontal, size md
Completed

Your details

Name and email

Current step

Company details

Website and location

Not started

Invite your team

Start collaborating

Not started

Add your socials

Automatic sharing

type icon
Completed

Your details

Name and email

Current step2

Company details

Website and location

Not started3

Invite your team

Start collaborating

Not started4

Add your socials

Automatic sharing

type number
Completed

Your details

Name and email

Current step

Company details

Website and location

Not started

Invite your team

Start collaborating

Not started

Add your socials

Automatic sharing

type featured-icon

Two supporting-text sets, one per orientation

The sheet draws the horizontal and the vertical forms as two components, and gives them different supporting text. “Progress icons centered” carries the short set the rows above use — “Name and email”, “Website and location”, “Start collaborating”, “Automatic sharing”, 14 to 20 characters — because a step there is a 240px column. “Progress icons with text” carries the long set the columns below use, 32 to 35 characters in a 400px row. The playground swaps the two with the orientation and its snippet emits whichever it drew. Read 2026-08-31 from 1141:81478 and 1254:144282. TextWithLine is the exception: the sheet draws the long set there in both orientations, so it keeps it below.

The sheet has a three-step variant; the kit has an array

“Progress icons centered” carries a boolean 4th step property that drops the last column, so the sheet ships a three-step and a four-step form of every horizontal symbol. There is no counterpart prop in code and none is needed: the step count is items.length, and three items draw three columns. The States section below is the three-step form.

The number type’s top connector is hidden below 768px

IconTopNumber’s dashed connector carries max-md:hidden, the family’s only responsive rule, read from the source. It does not turn the row vertical; it deletes the line and leaves the numbered circles floating. The sheet’s Mobile variant is the vertical step base instead, so flip orientation yourself below md, which the Guidelines tab and the preview both show.
vertical, size sm
Completed

Your details

Please provide your name and email

Completed

Company details

A few details about your company

Current step

Invite your team

Start collaborating with your team

Not started

Add your socials

Share posts to your social accounts

type icon
Completed

Your details

Please provide your name and email

Completed

Company details

A few details about your company

Current step3

Invite your team

Start collaborating with your team

Not started4

Add your socials

Share posts to your social accounts

type number
Completed

Your details

Please provide your name and email

Completed

Company details

A few details about your company

Current step

Invite your team

Start collaborating with your team

Not started

Add your socials

Share posts to your social accounts

type featured-icon
vertical, size md
Completed

Your details

Please provide your name and email

Completed

Company details

A few details about your company

Current step

Invite your team

Start collaborating with your team

Not started

Add your socials

Share posts to your social accounts

type icon
Completed

Your details

Please provide your name and email

Completed

Company details

A few details about your company

Current step3

Invite your team

Start collaborating with your team

Not started4

Add your socials

Share posts to your social accounts

type number
Completed

Your details

Please provide your name and email

Completed

Company details

A few details about your company

Current step

Invite your team

Start collaborating with your team

Not started

Add your socials

Share posts to your social accounts

type featured-icon

Three types, three rules for the current step

Read from the source. The icon type turns the current title text-brand-secondary and the supporting text text-brand-tertiary, over a brand circle with a 2px focus-ring halo at a 2px offset. The number type keeps every title text-secondary and marks the current step only in the circle, bg-primary with a 1px ring-secondary and the number in text-secondary, and dims an incomplete step to 0.6. The featured-icon type keeps the titles gray too and works on the glyph and the text instead: the glyph is text-fg-secondary on the current step and text-fg-quaternary on every other step in the column, but only on the incomplete steps in the row; and the text block dims to 0.5 by the same split, every step that is not current in the column, the incomplete ones in the row.

Minimal

The two layouts with no titles: a label and a row of circles, or the circles joined by connectors. Both take the icon or the number type, and both center themselves.

Step 3 of 4

CompletedCompletedCurrent stepNot started
MinimalIcons, type icon, size sm: the label shows by default

Step 3 of 4

CompletedCompletedCurrent stepNot started
MinimalIcons, type icon, size md: the label shows by default

Step 3 of 4

CompletedCompletedCurrent step3Not started4
MinimalIcons, type number, size sm: the label shows by default

Step 3 of 4

CompletedCompletedCurrent step3Not started4
MinimalIcons, type number, size md: the label shows by default
CompletedCompletedCurrent stepNot started
MinimalIcons, text={false}: the icons alone

Step 2 of 4

CompletedCompletedNot startedNot started
MinimalIcons, no current step: the label falls back to the completed count
Completed
Completed
Current step
Not started
MinimalIconsConnected, type icon, size sm: capped at 320px and centered
Completed
Completed
Current step
Not started
MinimalIconsConnected, type icon, size md: capped at 360px and centered
Completed
Completed
Current step3
Not started4
MinimalIconsConnected, type number, size sm: capped at 320px and centered
Completed
Completed
Current step3
Not started4
MinimalIconsConnected, type number, size md: capped at 360px and centered

The label reads the current step

“Step 3 of 4” above is the third item’s index plus one. Until 2026-08-23 the label counted the completed steps instead, so the same array read “Step 2 of 4”, and the label was off by default. With no current step it still falls back to the completed count, which is the fourth cell. Measured 2026-08-23 against a production build: the label read “Step 3 of 4” with two complete steps and one current.

The number type, added 2026-08-31

Both minimal layouts took no type until then, so the sheet’s eight Number symbols had no counterpart and a numbered minimal row was not expressible. They now take type="icon" or type="number", drawn by the new NumberOnly circle. Read 2026-08-31 from 9367:556722, 9367:556730, 9369:557313, and 9369:557304: the numeral is the item’s position, not a count of what is done, so it reads 1·2·3·4 whatever the statuses; the circle is bg-success-solid with a tick when complete and bg-primary with a 1px ring otherwise, the numeral text-secondary when current and text-quaternary when not. Unlike the number step bases, it dims nothing — the sheet does not dim an incomplete circle in these two layouts. The connected row’s lines turn dashed gray at every status and take 6px on each side, which is the sheet’s own spacing there. There is still no featured minimal row on the sheet and none in the kit.

orientation does nothing on the connected row

MinimalIconsConnected takes orientation from CommonProps. Until 2026-08-23 vertical swapped the fixed w-20 connector for w-12, 80px for 48, and never changed the flex direction, so it was a shorter horizontal row; since the row took the sheet’s 320 and 360px width with lines that flex to fill it, the prop reads nothing. Recorded on the Code tab; the sheet draws no vertical connected row either.

Text with line

A 4px bar over each title, brand until the current step and gray after it, in equal columns or one column. No icons.

Completed

Your details

Please provide your name and email

Current step

Company details

A few details about your company

Not started

Invite your team

Start collaborating with your team

Not started

Add your socials

Share posts to your social accounts

horizontal, size sm
Completed

Your details

Please provide your name and email

Current step

Company details

A few details about your company

Not started

Invite your team

Start collaborating with your team

Not started

Add your socials

Share posts to your social accounts

horizontal, size md
Completed

Your details

Please provide your name and email

Completed

Company details

A few details about your company

Current step

Invite your team

Start collaborating with your team

Not started

Add your socials

Share posts to your social accounts

vertical, size sm
Completed

Your details

Please provide your name and email

Completed

Company details

A few details about your company

Current step

Invite your team

Start collaborating with your team

Not started

Add your socials

Share posts to your social accounts

vertical, size md

The bar is the whole status

Read from the source: the bar is bg-fg-brand-primary_alt when current or complete and bg-quaternary when incomplete, and the title and supporting text turn brand on the current step only, so in light mode a complete step and a current one share a bar color and differ in their text. The columns are 16px apart horizontally and 20px apart vertically, the sheet’s Desktop and Mobile gaps.

In dark mode this layout cannot show which step is current

Measured 2026-08-31: in the dark palette text-brand-secondary computes the same value as text-secondary, and text-brand-tertiary the same as text-tertiary. The brand text tokens collapse onto the neutral ones, so the current step’s title and supporting text stop being brand — and since the bar is already the same color for complete and current, nothing at all separates them here. TextWithLine is the layout this breaks, because it has no icon to fall back on; the icon type keeps its halo and its tick, so a current step is still identifiable there. A theme-level fact rather than a progress-steps one, recorded on the Code tab. Until it is settled, do not use TextWithLine alone to say where a reader is on a dark surface: keep a “Step N of M” count or a heading beside it.

States

Three statuses, nothing else — nothing here is interactive. The first panel is the circle all but TextWithLine draw.

IconOnly, the status circle
Not started
incomplete, size sm
Current step
current, size sm
Completed
complete, size sm
Not started
incomplete, size md
Current step
current, size md
Completed
complete, size md
Completed

Your details

Name and email

Current step

Company details

Website and location

Not started

Invite your team

Start collaborating

The three statuses in a row, icon type: a tick, a halo, a dot
Completed

Your details

Name and email

Current step2

Company details

Website and location

Not started3

Invite your team

Start collaborating

Number type: green with a tick, a gray ring, then the same ring dimmed to 0.6
Completed

Your details

Name and email

Current step

Company details

Website and location

Not started

Invite your team

Start collaborating

Featured-icon type: the glyph turns gray and the text dims to 0.5 on the incomplete step
Completed

Your details

Name and email

Current step

Company details

Website and location

Not started

Invite your team

Start collaborating

connector={false}: the same three with no lines

The connector belongs to the step before it

Each step draws the line after itself, in its own status color, and the layout hides the last one: read from the source, connector on an item is item.connector || index !== length - 1 unless the layout’s own connector is false. So the line between a complete step and the current one is brand, and the line after the current step is gray, which is how the sheet draws progress as far as the current step and no further. In the two vertical bases with their own connector rules, IconLeftNumber and FeaturedIconLeft, the line after the current step is also dimmed to 0.6; their horizontal counterparts do not dim it.