Skip to main content

Steps

Info:Navigation
16

A horizontal step indicator for a linear flow: done, current, and upcoming at a glance.

stepper wizard progress steps checkout onboarding flow

Live demo

live · @xtyle/astro

Steps

Checkout

  1. Cart
  2. Shipping
  3. Payment
  4. Review

Nearly done

  1. Account
  2. Profile
  3. Preferences
  4. Confirm

Steps shows where a user is in a linear process: a checkout, an onboarding wizard, a multi-part form. It decorates a semantic ordered list of <li> steps and splits them by the current index: everything before it is done (a filled marker with a check), the one at it is current (an outlined marker, flagged with aria-current), and everything after is upcoming (a muted, numbered marker).

A connector track fills in behind the markers up to the current step. It renders no markup of its own beyond the classes and the aria-current it sets, so the ordered list stays the source of truth and screen readers hear the steps in order. Standalone like Table and Timeline, it needs no runtime, only the derived register the markers and track draw from.

When to use

How this component composes with the rest of the set.

Drive current from the same state that gates a wizard's Next button, so the marker moves as the user advances.
Keep labels to a word or two; the row divides the width evenly, so long labels wrap under their marker.
For a form, pair it with a heading per step and swap the panel below as current changes.

Props

1 prop, straight from the manifest.

PropTypeDefaultBindingsDescription
current number 0
html svelte astro
The zero-based index of the current step. Steps before it render as done (checked), the step at it as current (`aria-current="step"`), and steps after it as upcoming.

Appearance

States

done

.xtyle-steps__step--done

A completed step: an accent-filled marker with a check, and a filled connector into it.

current

.xtyle-steps__step--current

The active step: an accent-outlined marker and an emphasized label, carrying aria-current.

upcoming

.xtyle-steps__step--upcoming

A step not yet reached: a muted, numbered marker on the unfilled track.

Anatomy

The named parts that make up the component, with their selectors.

list

.xtyle-steps__list

The decorated ordered list, laid out as an even horizontal row of steps.

step

.xtyle-steps__step

One step: a numbered marker over its label, joined to the previous step by the connector track.

--space-2 --text-sm --fg-1 --bg-1 --fg-2 --line --border-thick --radius-full --weight-semibold

marker

.xtyle-steps__step::before

The circular step marker: a number when upcoming, a check when done, an accent outline when current.

--accent --accent-fg --accent-text --bg-0 --fg-0 --weight-medium

Tokens & coverage

What the component consumes, checked live against what the algorithm produces.

Success:fully covered 16/16 consumed tokens produced default register: 299 tokens

Live coverage check against the xtyle-default register (derive(xtyleDefault, { anchors })coverComponent(manifest, register)). Every token this component consumes must be a key the algorithm produces.

--accent --accent-fg --accent-text --bg-0 --bg-1 --border-thick --fg-0 --fg-1 --fg-2 --font-sans --line --radius-full --space-2 --text-sm --weight-medium --weight-semibold

Slots

default
html svelte astro

The ordered list. Provide an <ol> (or <ul>) whose <li> children are the steps, in order.

Accessibility

It renders a semantic ordered list, so assistive tech announces the steps in order; the current step carries aria-current="step" so it is announced as the active one.
State is not conveyed by color alone: a done step shows a check glyph and the current step is outlined and emphasized, so a color-deficient user still reads progress.
The markers and connector track are decorative (drawn as pseudo-elements) and carry no content of their own.

Code

Checkout flow

Four steps with the second active; the first is done and the rest are upcoming.

<xtyle-steps current="1">
	<ol>
		<li>Cart</li>
		<li>Shipping</li>
		<li>Payment</li>
		<li>Review</li>
	</ol>
</xtyle-steps>
<script lang="ts">
	import { Steps } from "@xtyle/svelte";

	let current = $state(1);
	const labels = ["Cart", "Shipping", "Payment", "Review"];
</script>

<Steps {current}>
	<ol>
		{#each labels as label (label)}<li>{label}</li>{/each}
	</ol>
</Steps>
---
import Steps from "@xtyle/astro/Steps.astro";
---

<Steps current={1}>
	<ol>
		<li>Cart</li>
		<li>Shipping</li>
		<li>Payment</li>
		<li>Review</li>
	</ol>
</Steps>