Skip to main content

Overview

Step provides a sequential navigation system for multi-step workflows. It extends single selection with navigation methods (first, last, next, prev, step) and supports both automatic and manual activation modes.

Sub-Components

  • Step.Root: Renderless container that manages step state
  • Step.Item: Individual step item

Usage

<script lang="ts" setup>
import { ref } from 'vue'
import { Step } from '@vuetify/v0'

const currentStep = ref('account')
</script>

<template>
  <Step.Root v-model="currentStep">
    <Step.Item value="account">Account</Step.Item>
    <Step.Item value="profile">Profile</Step.Item>
    <Step.Item value="review">Review</Step.Item>
  </Step.Root>
</template>

Step.Root

Props

namespace
string
default:"'v0:step'"
Namespace for dependency injection (must match StepItem namespace)
disabled
boolean
default:"false"
Disables the entire step instance
enroll
boolean
default:"false"
Auto-select non-disabled items on registration
mandatory
boolean | 'force'
default:"false"
Controls mandatory step behavior:
  • false (default): No mandatory step enforcement
  • true: Prevents deselecting the last selected item
  • 'force': Automatically selects the first non-disabled item on registration

Model

v-model
T | T[]
Current step value(s)

Slot Props

isDisabled
boolean
Whether the step instance is disabled
first
() => void
Select the first item
last
() => void
Select the last item
next
() => void
Select the next item
prev
() => void
Select the previous item
step
(count: number) => void
Step forward or backward by a specific count
select
(id: ID) => void
Select an item by ID
unselect
(id: ID) => void
Unselect an item by ID
toggle
(id: ID) => void
Toggle an item’s step state by ID
attrs
object
Attributes including aria-multiselectable: false

Step.Item

Props

id
string
Unique identifier (auto-generated if not provided)
label
string
Optional display label (passed through to slot, not used in registration)
value
V
Value associated with this item
disabled
MaybeRef<boolean>
Disables this specific item
namespace
string
default:"'v0:step'"
Namespace for dependency injection

Slot Props

id
string
Unique identifier
label
string
Optional display label
value
V | undefined
Value associated with this item
isSelected
boolean
Whether this item is currently selected
isDisabled
boolean
Whether this item is disabled
select
() => void
Select this item
unselect
() => void
Unselect this item
toggle
() => void
Toggle this item’s step state
attrs
object
Attributes including aria-selected, aria-disabled, data-selected, and data-disabled

Examples

<script setup>
import { ref } from 'vue'
import { Step } from '@vuetify/v0'

const currentStep = ref('account')
</script>

<template>
  <Step.Root v-model="currentStep">
    <Step.Item value="account" v-slot="{ isSelected }">
      <div :class="{ 'font-bold': isSelected }">
        Account Setup
      </div>
    </Step.Item>

    <Step.Item value="profile" v-slot="{ isSelected }">
      <div :class="{ 'font-bold': isSelected }">
        Profile Information
      </div>
    </Step.Item>

    <Step.Item value="review" v-slot="{ isSelected }">
      <div :class="{ 'font-bold': isSelected }">
        Review & Submit
      </div>
    </Step.Item>
  </Step.Root>
</template>

Accessibility

  • Step.Root provides aria-multiselectable="false" to indicate single selection
  • Step.Item provides ARIA attributes for selection and disabled state
  • Items expose data-selected and data-disabled attributes for styling
<template>
  <Step.Root v-model="currentStep">
    <Step.Item value="account" v-slot="{ attrs }">
      <div v-bind="attrs">
        Account Setup
      </div>
    </Step.Item>
  </Step.Root>
</template>

SSR

Step is fully compatible with SSR as it is renderless by default:
<template>
  <Step.Root v-model="currentStep">
    <Step.Item value="account">Account</Step.Item>
    <Step.Item value="profile">Profile</Step.Item>
    <Step.Item value="review">Review</Step.Item>
  </Step.Root>
</template>

Build docs developers (and LLMs) love