Skip to content

Stepper

A set of steps that are used to indicate progress through a multi-step process.
Step 2 of 0
vue
<script setup lang="ts">
import { Icon } from '@iconify/vue'

import { StepperDescription, StepperIndicator, StepperItem, StepperRoot, StepperSeparator, StepperTitle, StepperTrigger } from 'radix-vue'

const steps = [{
  step: 1,
  title: 'Address',
  description: 'Add your address here',
  icon: 'radix-icons:home',
}, {
  step: 2,
  title: 'Shipping',
  description: 'Set your preferred shipping method',
  icon: 'radix-icons:archive',
}, {
  step: 3,
  title: 'Trade-in',
  description: 'Add any trade-in items you have',
  icon: 'radix-icons:update',
}, {
  step: 4,
  title: 'Payment',
  description: 'Add any payment information you have',
  icon: 'radix-icons:sketch-logo',
}, {
  step: 5,
  title: 'Checkout',
  description: 'Confirm your order',
  icon: 'radix-icons:check',
}]
</script>

<template>
  <StepperRoot
    :default-value="2"
    class="flex gap-2"
  >
    <StepperItem
      v-for="item in steps"
      :key="item.step"
      class="flex items-center gap-2 cursor-pointer group data-[disabled]:pointer-events-none"
      :step="item.step"
      aria-describedby="undefined"
    >
      <StepperTrigger class="flex flex-col items-center text-center gap-2">
        <StepperIndicator
          class="inline-flex items-center group-data-[disabled]:text-gray-400 group-data-[state=active]:bg-black group-data-[state=active]:text-white justify-center rounded-full text-grass11 w-10 h-10 shrink-0 bg-white group-data-[state=active]:shadow-black group-data-[state=completed]:bg-violet9 group-data-[state=completed]:text-white group-data-[state=completed]:shadow-violet9 shadow-[0_0_0_2px] "
        >
          <Icon
            :icon="item.icon"
            class="w-6 h-6"
          />
        </StepperIndicator>
        <div class="flex flex-col">
          <StepperTitle class="text-xs text-black font-medium">
            {{ item.title }}
          </StepperTitle>
          <StepperDescription class="text-xs text-black">
            {{ item.description }}
          </StepperDescription>
        </div>
      </StepperTrigger>
      <StepperSeparator
        v-if="item.step !== steps[steps.length - 1].step"
        class="w-[20px] h-[1px] group-data-[state=active]:bg-black group-data-[disabled]:bg-gray-300 group-data-[state=completed]:bg-violet9 bg-green5 shrink-0"
      />
    </StepperItem>
  </StepperRoot>
</template>

Features

  • Can be controlled or uncontrolled.
  • Supports horizontal/vertical orientation.
  • Supports linear/non-linear activation.
  • Full keyboard navigation.

Installation

Install the component from your command line.

sh
$ npm add radix-vue

Anatomy

Import all parts and piece them together.

vue
<script setup>
import { StepperDescription, StepperIndicator, StepperItem, StepperRoot, StepperTitle, StepperTrigger } from 'radix-vue'
</script>

<template>
  <StepperRoot>
    <StepperItem>
      <StepperTrigger>
        <StepperIndicator />
        <StepperTitle />
        <StepperDescription />
      </StepperTrigger>
      <StepperSeparator />
    </StepperItem>
  </StepperRoot>
</template>

API Reference

Root

Contains all the stepper component parts.

PropDefaultType
as
'div'
AsTag | Component

The element or component this component should render as. Can be overwrite by asChild

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

defaultValue
1
number

The value of the tab that should be active when initially rendered. Use when you do not need to control the state of the tabs

dir
'ltr' | 'rtl'

The reading direction of the combobox when applicable.
If omitted, inherits globally from DirectionProvider or assumes LTR (left-to-right) reading mode.

linear
true
boolean

Whether or not the steps must be completed in order

modelValue
number

The controlled value of the tab to activate. Can be bound as v-model.

orientation
'horizontal'
'vertical' | 'horizontal'

The orientation the tabs are laid out. Mainly so arrow navigation is done accordingly (left & right vs. up & down)

EmitPayload
update:modelValue
[payload: number]

Event handler called when the value changes

Slots (default)Payload
modelValue
number | undefined

Current step

Data AttributeValue
[data-orientation]"vertical" | "horizontal"
[data-linear]Present when linear

Item

The step item component.

PropDefaultType
as
'li'
AsTag | Component

The element or component this component should render as. Can be overwrite by asChild

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

completed
false
boolean

Shows whether the step is completed.

disabled
false
boolean

When true, prevents the user from interacting with the tab.

step*
number

A unique value that associates the stepper item with an index

Slots (default)Payload
state
'active' | 'completed' | 'inactive'

The current state of the stepper item

Data AttributeValue
[data-state]"active" | "inactive" | "completed"
[data-disabled]Present when disabled
[data-orientation]"vertical" | "horizontal"

Trigger

The trigger that toggles the step.

PropDefaultType
as
'button'
AsTag | Component

The element or component this component should render as. Can be overwrite by asChild

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

Data AttributeValue
[data-state]"active" | "inactive" | "completed"
[data-disabled]Present when disabled
[data-orientation]"vertical" | "horizontal"

Indicator

The indicator for the step.

PropDefaultType
as
'div'
AsTag | Component

The element or component this component should render as. Can be overwrite by asChild

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

Title

An accessible title to be announced when the dialog is opened.

If you want to hide the title, wrap it inside our Visually Hidden utility like this <VisuallyHidden asChild>.

PropDefaultType
as
'h4'
AsTag | Component

The element or component this component should render as. Can be overwrite by asChild

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

Description

An optional accessible description to be announced when the dialog is opened.

If you want to hide the description, wrap it inside our Visually Hidden utility like this <VisuallyHidden asChild>. If you want to remove the description entirely, remove this part and pass aria-describedby="undefined} to StepperItem.

PropDefaultType
as
'li'
AsTag | Component

The element or component this component should render as. Can be overwrite by asChild

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

completed
false
boolean

Shows whether the step is completed.

disabled
false
boolean

When true, prevents the user from interacting with the tab.

step*
number

A unique value that associates the stepper item with an index

Slots (default)Payload
state
'active' | 'completed' | 'inactive'

The current state of the stepper item

Examples

Vertical

You can create vertical tabs by using the orientation prop.

vue
<script setup>
import { StepperDescription, StepperIndicator, StepperItem, StepperList, StepperRoot, StepperTitle } from 'radix-vue'
</script>

<template>
  <StepperRoot
    :default-value="1"
    orientation="vertical"
  >
    <StepperList aria-label="stepper example">
      <StepperItem>
        <StepperIndicator />
        <StepperTitle />
        <StepperDescription />
      </StepperItem>
      <StepperItem>
        <StepperIndicator />
        <StepperTitle />
        <StepperDescription />
      </StepperItem>
    </StepperList>
  </StepperRoot>
</template>

Accessibility

Keyboard Interactions

KeyDescription
Tab
When focus moves onto the steps, focuses the first step .
ArrowDown
Moves focus to the next step depending on orientation.
ArrowRight
Moves focus to the next step depending on orientation .
ArrowUp
Moves focus to the previous step depending on orientation .
ArrowLeft
Moves focus to the previous step depending on orientation .
EnterSpace
Selects the focused step.