Acronis UIKit
Components

Stepper

The root of a step sequence — a row of steps on wide viewports, a two-line text summary on narrow ones.

Usage

import { Stepper, StepperItem } from '@acronis-platform/ui-react';

Stepper renders a sequence two ways and lets CSS pick one:

  • At 1024px and above — the StepperItem children you pass, in a start-aligned row that wraps.
  • Below 1024px — a two-line text summary instead: Step 3 of 5: Choose a plan, then Next: Confirm and pay. No step items at all.

Both subtrees are always in the DOM and a real viewport media query (Tailwind's lg:) displays one and hides the other — there is no ResizeObserver, no measuring pass, and nothing mounts or unmounts as the window resizes. Because the component cannot see which layout is live, you supply both: the children for the row, and currentStep / totalSteps / current / next for the summary.

On the last step, omit next and the whole Next: … line is left out rather than rendered empty.

Every string the component generates itself — stepLabel ("Step"), ofLabel ("of"), nextLabel ("Next:"), and separatorLabel (": ", the punctuation before the step's name) — is a prop so it can be translated. Everything else it renders is yours.

Figma names the two variants 0-1024 and >1025. The implementation uses the kit's pinned lg breakpoint — exactly 1024px — so 1024px renders the wide row, one pixel lower than the Figma label implies. That keeps the component on the shared breakpoint scale rather than minting a bespoke 1025px query.

As of the 2026-08-24 Figma sync, this component consumes a dedicated --ui-stepper-breakpoint-* token tier from @acronis-platform/tokens-pd — the summary's line gap, the item row's gap, and both summary text colors are Stepper-owned tokens rather than borrowed from the semantic scale, the same treatment StepperItem carries.

Examples

A full sequence:

<Stepper
  currentStep={2}
  totalSteps={3}
  current="Choose a plan"
  next="Confirm and pay"
>
  <StepperItem
    variant="completed"
    label="Create an account"
    avatar={
      <Avatar color="green" className="[box-shadow:none]">
        <CheckIcon size={16} />
      </Avatar>
    }
  />
  <StepperItem
    variant="current"
    label="Choose a plan"
    avatar={
      <Avatar
        color="blue"
        className="[box-shadow:none] text-[var(--ui-stepper-item-current-label-color)]"
      >
        <AvatarFallback>2</AvatarFallback>
      </Avatar>
    }
  />
  <StepperItem
    variant="future"
    label="Confirm and pay"
    avatar={
      <Avatar
        color="gray"
        className="[box-shadow:none] text-[var(--ui-stepper-item-future-label-color)]"
      >
        <AvatarFallback>3</AvatarFallback>
      </Avatar>
    }
  />
</Stepper>

Avatar always paints a 2px outset ring meant to separate overlapping avatars in an AvatarGroup. Figma's Stepper avatars carry no such stroke, so left on, the ring shows as an unwanted halo on a filled step container. Switch it off with className="[box-shadow:none]" on each composed Avatar, as shown above — see StepperItem for the full note.

The last step — no next, so the compact layout shows a single line:

<Stepper currentStep={3} totalSteps={3} current="Confirm and pay">
  {/* … */}
</Stepper>

Translated summary copy:

<Stepper
  currentStep={2}
  totalSteps={3}
  current="Choisissez une formule"
  next="Confirmer et payer"
  stepLabel="Étape"
  ofLabel="sur"
  nextLabel="Suivante :"
  separatorLabel=" : "
>
  {/* … */}
</Stepper>

Accessibility

Only one layout is ever announced: the hidden one is display: none, which removes it from the accessibility tree, so a screen-reader user hears the text summary below 1024px and the step items above it — never both. The root is a plain <div> with no role and no tab stops of its own; if the sequence should announce as an ordered list, or the current step as aria-current="step", compose that on the StepperItem children via their render prop.

API Reference

Prop

Type

Edit on GitHub

On this page