createStep
Extends createSingle with bounded or circular navigation. Built for wizards, multi-step forms, and onboarding flows.
Usage
The createStep composable manages a list of steps and allows navigation between them with configurable circular (wrapping) or bounded (stopping at edges) behavior. You register each step (with an id and value) in the order they should be navigated, then use the navigation methods to move
import { createStep } from '@vuetify/v0'
// Bounded navigation (default) - for wizards, forms
const wizard = createStep({ circular: false })
wizard.onboard([
{ id: 'step1', value: 'Account Info' },
{ id: 'step2', value: 'Payment' },
{ id: 'step3', value: 'Confirmation' },
])
wizard.first() // Go to step1
wizard.next() // Go to step2
wizard.next() // Go to step3
wizard.next() // Stays at step3 (bounded)
// Circular navigation - for carousels, theme switchers
const carousel = createStep({ circular: true })
carousel.onboard([
{ id: 'slide1', value: 'First' },
{ id: 'slide2', value: 'Second' },
{ id: 'slide3', value: 'Third' },
])
carousel.last() // Go to slide3
carousel.next() // Wraps to slide1
carousel.prev() // Wraps to slide3Context / DI
Use createStepContext to share a step navigation instance across a component tree:
import { createStepContext } from '@vuetify/v0'
export const [useWizard, provideWizard, wizard] =
createStepContext({ namespace: 'my:wizard', circular: false })
// In parent component
provideWizard()
// In child component
const step = useWizard()
step.next()Architecture
createStep extends createSingle with directional navigation:
Reactivity
Step navigation state is always reactive. Use selectedIndex to derive disabled states for navigation buttons.
| Property/Method | Reactive | Notes |
|---|---|---|
selectedId | Computed — current step ID | |
selectedIndex | Computed — current step position | |
selectedItem | Computed — current step ticket | |
selectedValue | Computed — current step value | |
step(count) | Move by count positions — positive forward, negative backward[1] |
Navigation button state Derive boundary checks from selectedIndex and registry size:
const atFirst = toRef(() => selection.selectedIndex.value === 0)
const atLast = toRef(() => selection.selectedIndex.value === selection.size - 1)In circular mode, buttons are never disabled.
Examples
Cart
Review the items in your basket before you check out.
Step 1 of 5 · Gift wrap is unavailable and is skipped automatically · 0% complete
FAQ
With circular: false (default) next()/prev() clamp at the first and last steps; with circular: true they wrap around — next() from the last step returns to the first. Use bounded for wizards, circular for carousels.
circular only affects next()/prev(). Boundary guards like isFirst/isLast are derived from the index (0 and size - 1), so they’re still true at the edges. Drop those guards in circular mode if you want the buttons to wrap too.
next(), prev(), and step(count) skip tickets marked disabled: true automatically — no manual guard needed — and select() on a disabled ticket is a no-op, so it stays unreachable from every entry point.
Reach for createStep when you’re building custom wizard or carousel UI and only need the navigation logic. The Step component wraps it as a ready-made compound surface. For exclusive selection without next()/prev(), drop down to createSingle.
step(-2)moves back two positions;step(3)skips ahead three. In circular mode it wraps at both ends; in bounded mode it clamps at the first and last steps. Disabled steps are skipped automatically. ↩︎