A vertical progress list for onboarding, checkout, and wizard flows.

Last updated

  1. Cart (done)

    Review your items

  2. 2

    Shipping

    Add your address

  3. 3

    Payment

    Enter payment details

  4. 4

    Confirm

Show code
<Steps
items={[
  { title: 'Cart', description: 'Review your items' },
  { title: 'Shipping', description: 'Add your address' },
  { title: 'Payment', description: 'Enter payment details' },
  { title: 'Confirm' },
]}
current={2}
/>

Add

npx @ava-ui/apogee add steps

No Apogee component dependencies. Depends on @lucide/astro (renders the done-step check icon).

Usage

---
import Steps from '@/components/apogee/Steps/Steps.astro'
---
<Steps
  items={[
    { title: 'Cart' },
    { title: 'Shipping' },
    { title: 'Payment' },
  ]}
  current={2}
/>

API

@composable — exposed to Content Editors in AVA. Any other attribute passes through to the root <ol>.

Prop Type Default Description
items { title: string; description?: string; status?: 'done' | 'current' | 'upcoming'; icon? }[] — Steps in order. status overrides the state derived from current for that item; icon is used with marker="icon".
current number 1 1-based index of the active step. Earlier steps render as done.
orientation Responsive<'vertical' | 'horizontal'> 'vertical' Stacked or across; { base: 'vertical', md: 'horizontal' } switches per breakpoint in one render.
marker 'number' | 'dot' | 'icon' 'number' What the circle shows before a step is done.
size 'small' | 'medium' 'medium' Marker size (24 / 32px) and text size.
class string — Extra classes on the root <ol>, merged last.

States

A step’s visual state is derived from its position relative to current:

  • Done (n < current) — filled accent indicator with a check icon.
  • Current (n === current) — accent-outlined indicator with the step number; the list item carries aria-current="step".
  • Upcoming (n > current) — muted indicator with the step number, muted title.
  1. 1

    One

  2. 2

    Two

  3. 3

    Three

Show code
<Steps items={[{ title: 'One' }, { title: 'Two' }, { title: 'Three' }]} current={1} />
  1. One (done)

  2. 2

    Two

  3. 3

    Three

Show code
<Steps items={[{ title: 'One' }, { title: 'Two' }, { title: 'Three' }]} current={2} />
  1. One (done)

  2. Two (done)

  3. Three (done)

Show code
<Steps items={[{ title: 'One' }, { title: 'Two' }, { title: 'Three' }]} current={4} />

Orientation

One render, stacked on phones and across from md. The connector after a done step turns primary.

  1. Account (done)

    Name and email

  2. 2

    Company

    Team size

  3. 3

    Billing

    Plan and card

  4. 4

    Done

    Start using it

Show code
<Steps orientation={{ base: 'vertical', md: 'horizontal' }} current={2} items={[…]} />

Only md given: below it the default vertical applies.

  1. Cart (done)

  2. 2

    Shipping

  3. 3

    Payment

Show code
<Steps orientation={{ md: 'horizontal' }} current={2} items={[…]} />

Markers and size

  1. Cart (done)

  2. Shipping

  3. Payment

  1. Account (done)

  2. Company (done)

  3. Billing

  4. Done

Show code
<Steps marker="dot" size="small" orientation="horizontal" current={2} items={[…]} />
<Steps marker="icon" orientation="horizontal" current={3} items={[{ title: 'Account', icon: User }, …]} />

Status

items[].status marks a step done out of order (a wizard where steps can be filled in any order):

  1. Profile (done)

  2. 2

    Address

  3. 3

    Documents

  4. Photo (done)

Show code
<Steps current={2} items={[{ title: 'Profile' }, { title: 'Address' }, { title: 'Documents' }, { title: 'Photo', status: 'done' }]} />

For a bar or dots with no labels, use ProgressIndicator.

Examples

Compact, without descriptions:

  1. Draft (done)

  2. Review (done)

  3. 3

    Publish

Show code
<Steps items={[{ title: 'Draft' }, { title: 'Review' }, { title: 'Publish' }]} current={3} />

Mark the whole flow complete by setting current past the last step:

<Steps items={steps} current={steps.length + 1} />

Accessibility

  • The <ol> conveys the sequence to assistive tech on its own — it’s a real ordered list.
  • The active step’s list item gets aria-current="step", so its title is what screen readers announce as the current step.
  • The connector line and the check icon inside a done indicator are aria-hidden — decorative.
  • Native semantics, no extra ARIA needed beyond aria-current.

Tokens

Token Used for
--background-primary / --on-primary Done + current indicator border/fill, current step’s number color
--background-page Current/upcoming indicator background
--border-neutral Upcoming indicator border + connector line
--foreground-neutral / --foreground-neutral-faded Title color (current/done vs. upcoming) + description color

Do / Don’t

  • Do keep title to one to three words; put detail in description.
  • Do set current to items.length + 1 once the flow is complete, so every step shows done.
  • Don’t use Steps for parallel, unordered content — use Tabs.
  • Don’t skip numbers in the sequence — current is a plain 1-based index into items.

Content

  • title is a short noun phrase naming the step (“Shipping”), sentence case, no ending punctuation.
  • description is one short sentence or fragment — skip the trailing period for fragments, use it for full sentences.