Sakuga Back to Sakuga
Theme
Sound
Jump to a component

Core · Navigation

Stepper

Where a person is in a short multi-step flow: done steps get a check, the current one fills. Use it in the top bar of a full-screen flow, three to five steps. Never for navigation between pages.

@anicanon/sakuga/uiv1.0Used onWeb · iOS · Android

Live, from @anicanon/sakuga 2.0.0

Sakuga for iOS and Android is coming

iOS

Coming soon

Stepper for iOS is in the roughs. The tokens it will read are the ones on this page, the same on every platform.

Android

Coming soon

Stepper for Android is in the roughs. The tokens it will read are the ones on this page, the same on every platform.

Use it for
Where a person is in a short flow of three to five steps, in the top bar of a full-screen flow; variant="bar" on a phone.
Not for
  • Moving between the pages of a listPagination
  • A job's stages while it runs, with the time each tookStages
  • How far something being made has comeProgress
  • What a character is ready withReadiness

Guidelines

Motion: moving on fills the line toward the next step on motion-base; the new current step settles in and a done step's check appears with ease-enter. variant="bar" is the phone's form: a segment per step under the title, then "Step 2 of 3 · Photos". tone="media" draws it over a camera.

StepperExample.jsxReact
import { useState } from 'react';
import { Button, Stepper } from '@anicanon/sakuga/ui';

export default function StepperExample() {
  const [current, setCurrent] = useState(1);
  const steps = ['How', 'Approve', 'Portrait'];
  return (
    <>
      <Stepper steps={steps} current={current} />
      <Button
        variant="ghost"
        size="sm"
        disabled={current === 0}
        onClick={() => setCurrent(current - 1)}
      >
        Back
      </Button>
      <Button
        variant="secondary"
        size="sm"
        disabled={current === steps.length - 1}
        onClick={() => setCurrent(current + 1)}
      >
        Next
      </Button>
    </>
  );
}

PropsStepperProps

stepsrequired
string[]
Step names, short nouns.
currentrequired
number
Index of the current step.
label
string
Accessible name, default "Steps".
variant
'steps' | 'bar'
bar: the phone's form, a segment per step under the title.
tone
'media'
media: the bar drawn over a camera.
className
string
StepperExample.swiftiOS · coming soon
StepperExample.ktAndroid · coming soon

Each token reads a role, and the role lands on a value in each theme. Change the role and every component that reads it follows.

Colour

stepper-fgStepper: upcoming steps.
text-mutedneutral-600#5c5b67
text-mutedneutral-400#a3a3a7
stepper-current-fgStepper: current and done labels.
text-primaryneutral-925#0b0a10
text-primaryneutral-0#ffffff
stepper-current-bgStepper: current step number fill.
action-primaryneutral-925#0b0a10
action-primaryneutral-0#ffffff
stepper-current-numStepper: current step number.
text-inverseneutral-0#ffffff
text-inverseneutral-925#0b0a10
stepper-done-bgStepper: done step fill.
bg-fillshade-a12rgba(11,10,16,0.12)
bg-fillwhite-a14rgba(255,255,255,0.14)
stepper-ringStepper: upcoming step ring.
border-controlshade-a52rgba(11,10,16,0.52)
border-controlwhite-a45rgba(255,255,255,0.45)
stepper-sepStepper: line between steps.
border-dividershade-a12rgba(11,10,16,0.12)
border-dividerwhite-a12rgba(255,255,255,0.12)

Space and shape

stepper-gap
gap-md
8px
stepper-step-gap
gap-md
8px
stepper-n-size
icon-size-md
20px
stepper-n-radius
radius-full
9999px
stepper-n-inset-ring-width
line-strong
2px
stepper-sep-width
its own value
28px
stepper-sep-height
line-hairline
1px
stepper-check-icon-size
icon-size-xs
14px
stepbar-gap
gap-md
8px
stepbar-track-gap
gap-xs
4px
stepbar-track-i-height
its own value
4px
stepbar-track-i-radius
radius-full
9999px
stepbar-media-gap
gap-sm
6px

Type

stepper-font-family
font-sans
Funnel Sans
stepper-step-font
text-caption-strong
600 13px/18px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
stepper-n-font
text-micro
700 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
stepbar-font-family
font-sans
Funnel Sans
stepbar-label-font
text-small-strong
600 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif

Motion

stepper-step-duration
motion-base
240ms
stepper-step-easing
ease-standard
cubic-bezier(0.2, 0, 0, 1)
stepper-n-duration
motion-base
240ms
stepper-n-easing
ease-standard
cubic-bezier(0.2, 0, 0, 1)
stepper-step-current-n-settle-animation
motion-settle
sk-settle 240ms cubic-bezier(0, 0, 0, 1)
stepper-step-done-n-icon-swap-animation
motion-swap
sk-swap 160ms cubic-bezier(0, 0, 0, 1)
stepper-sep-after-duration
motion-base
240ms
stepper-sep-after-easing
ease-standard
cubic-bezier(0.2, 0, 0, 1)

Checked automatically with axe-core 4.11.4 against WCAG 2.2 A and AA, on the live preview above, in light and dark, on 26 October 2026.

Result
No issues found, in light or in dark.
By design
Not focusable; an ordered list named by label (default "Steps"), each step read as its number and name, a done one as "Done:" and its name, and the current one marked "current step". With variant "bar" it is a progress bar named like "Step 2 of 4: Cast".
Not tested
The automated check doesn't test keyboard use, focus order or what a screen reader says. The lines above are the design system's own account of them.