@usevyre/react @usevyre/vue

Stepper

A multi-step flow indicator and controller for onboarding, checkout, and wizards. Controlled by a 0-based index; each step is automatically completed, current, or upcoming. Not Tabs — this is an ordered linear flow.


Wizard with Back / Next

StepperNav holds the Step indicators; StepPanel renders only when its index is active. With clickable, completed steps are clickable to go back.

AccountEmail & password
ProfileYour details
DoneReview

Step 1 — create your account.

import { useState } from "react";
import { Stepper, StepperNav, Step, StepPanel, Stack, Button, Text } from "@usevyre/react";

const [step, setStep] = useState(0);
const last = 2;

<Stepper value={step} onChange={setStep} clickable>
  <StepperNav>
    <Step index={0} label="Account" description="Email & password" />
    <Step index={1} label="Profile" description="Your details" />
    <Step index={2} label="Done" description="Review" />
  </StepperNav>
  <StepPanel index={0}>
    <Text>Step 1 — create your account.</Text>
  </StepPanel>
  <StepPanel index={1}>
    <Text>Step 2 — fill in your profile.</Text>
  </StepPanel>
  <StepPanel index={2}>
    <Text>Step 3 — review and finish. 🎉</Text>
  </StepPanel>
  <Stack direction="row" gap="sm" justify="between">
    <Button variant="ghost" onClick={() => setStep((s) => s - 1)} disabled={step === 0}>
      Back
    </Button>
    <Button
      variant="primary"
      onClick={() => setStep((s) => Math.min(s + 1, last))}
      disabled={step === last}
    >
      {step === last ? "Finish" : "Next"}
    </Button>
  </Stack>
</Stepper>

Vertical orientation

Set orientation="vertical" for a stacked layout — common for checkout sidebars and onboarding panels. The connector runs down the side instead of across.

Cart2 items
ShippingEnter address
PaymentCard details
ReviewConfirm order
import { useState } from "react";
import { Stepper, StepperNav, Step, Stack, Button } from "@usevyre/react";

const [step, setStep] = useState(1);

<Stepper orientation="vertical" value={step} onChange={setStep} clickable>
  <StepperNav>
    <Step index={0} label="Cart" description="2 items" />
    <Step index={1} label="Shipping" description="Enter address" />
    <Step index={2} label="Payment" description="Card details" />
    <Step index={3} label="Review" description="Confirm order" />
  </StepperNav>
  <Stack direction="row" gap="sm" justify="end">
    <Button variant="ghost" onClick={() => setStep((s) => s - 1)} disabled={step === 0}>
      Back
    </Button>
    <Button
      variant="primary"
      onClick={() => setStep((s) => Math.min(s + 1, 3))}
      disabled={step === 3}
    >
      Next
    </Button>
  </Stack>
</Stepper>

Props

Props

Prop Type Default Description
value number Controlled active step (0-based). Omit for uncontrolled.
defaultValue number 0 Initial active step when uncontrolled.
onChange (index: number) => void Emits the new active index. Not an event.
orientation "horizontal" | "vertical" "horizontal" Layout direction.
clickable boolean false Click a completed Step to jump back to it.

Step props

Step goes inside StepperNav; StepPanel takes a matching index and shows its content when active. Both require an explicit 0-based index.

Props

Prop Type Default Description
index number 0-based position (required).
label ReactNode Step label.
description ReactNode Secondary text under the label.
icon ReactNode Custom indicator (defaults to number, ✓ when completed).