# Steps

URL: https://ark-ui.com/docs/components/steps
LLM: https://ark-ui.com/llms.txt/components/steps

Used to guide users through a series of steps in a process

---



## Anatomy



```tsx
<Steps.Root>
  <Steps.List>
    <Steps.Item>
      <Steps.Trigger>
        <Steps.Indicator />
      </Steps.Trigger>
      <Steps.Separator />
    </Steps.Item>
  </Steps.List>
  <Steps.Content />
  <Steps.CompletedContent />
  <Steps.PrevTrigger />
  <Steps.NextTrigger />
</Steps.Root>
```

## Examples

### Basic

Here's a basic example of the `Steps` component.

```tsx
import { Steps } from '@ark-ui/react/steps'
import button from 'styles/button.module.css'
import styles from 'styles/steps.module.css'

const items = [
  { value: 'first', title: 'First', description: 'Contact Info' },
  { value: 'second', title: 'Second', description: 'Date & Time' },
  { value: 'third', title: 'Third', description: 'Select Rooms' },
]

export const Basic = () => {
  return (
    <Steps.Root className={styles.Root} count={items.length}>
      <Steps.List className={styles.List}>
        {items.map((item, index) => (
          <Steps.Item className={styles.Item} key={index} index={index}>
            <Steps.Trigger className={styles.Trigger}>
              <Steps.Indicator className={styles.Indicator}>{index + 1}</Steps.Indicator>
              <span>{item.title}</span>
            </Steps.Trigger>
            <Steps.Separator className={styles.Separator} />
          </Steps.Item>
        ))}
      </Steps.List>

      {items.map((item, index) => (
        <Steps.Content className={styles.Content} key={index} index={index}>
          {item.title} - {item.description}
        </Steps.Content>
      ))}

      <Steps.CompletedContent className={styles.CompletedContent}>
        Steps Complete - Thank you for filling out the form!
      </Steps.CompletedContent>

      <div className={styles.Actions}>
        <Steps.PrevTrigger className={button.Root}>Back</Steps.PrevTrigger>
        <Steps.NextTrigger className={button.Root} data-variant="solid">
          Next
        </Steps.NextTrigger>
      </div>
    </Steps.Root>
  )
}
```

### Controlled

Using the `RootProvider` component, you can control the active step by using the `step` prop and handling the
`onStepChange` event.

```tsx
import { Steps } from '@ark-ui/react/steps'
import { useState } from 'react'
import button from 'styles/button.module.css'
import styles from 'styles/steps.module.css'

const items = [
  { value: 'first', title: 'First', description: 'Contact Info' },
  { value: 'second', title: 'Second', description: 'Date & Time' },
  { value: 'third', title: 'Third', description: 'Select Rooms' },
]

export const Controlled = () => {
  const [step, setStep] = useState(0)

  return (
    <div className="stack">
      <output>current step: {step + 1}</output>

      <Steps.Root
        className={styles.Root}
        count={items.length}
        step={step}
        onStepChange={(details) => setStep(details.step)}
      >
        <Steps.List className={styles.List}>
          {items.map((item, index) => (
            <Steps.Item className={styles.Item} key={index} index={index}>
              <Steps.Trigger className={styles.Trigger}>
                <Steps.Indicator className={styles.Indicator}>{index + 1}</Steps.Indicator>
                <span>{item.title}</span>
              </Steps.Trigger>
              <Steps.Separator className={styles.Separator} />
            </Steps.Item>
          ))}
        </Steps.List>

        {items.map((item, index) => (
          <Steps.Content className={styles.Content} key={index} index={index}>
            {item.title} - {item.description}
          </Steps.Content>
        ))}

        <Steps.CompletedContent className={styles.CompletedContent}>
          Steps Complete - Thank you for filling out the form!
        </Steps.CompletedContent>

        <div className={styles.Actions}>
          <Steps.PrevTrigger className={button.Root}>Back</Steps.PrevTrigger>
          <Steps.NextTrigger className={button.Root} data-variant="solid">
            Next
          </Steps.NextTrigger>
        </div>
      </Steps.Root>
    </div>
  )
}
```

### Root Provider

An alternative way to control the steps is to use the `RootProvider` component and the `useSteps` hook. This way you can
access the state and methods from outside the component.

```tsx
import { Steps, useSteps } from '@ark-ui/react/steps'
import button from 'styles/button.module.css'
import styles from 'styles/steps.module.css'

const items = [
  { value: 'first', title: 'First', description: 'Contact Info' },
  { value: 'second', title: 'Second', description: 'Date & Time' },
  { value: 'third', title: 'Third', description: 'Select Rooms' },
]

export const RootProvider = () => {
  const steps = useSteps({ count: items.length })

  return (
    <div className="stack">
      <output>current step: {steps.value + 1}</output>

      <Steps.RootProvider className={styles.Root} value={steps}>
        <Steps.List className={styles.List}>
          {items.map((item, index) => (
            <Steps.Item className={styles.Item} key={index} index={index}>
              <Steps.Trigger className={styles.Trigger}>
                <Steps.Indicator className={styles.Indicator}>{index + 1}</Steps.Indicator>
                <span>{item.title}</span>
              </Steps.Trigger>
              <Steps.Separator className={styles.Separator} />
            </Steps.Item>
          ))}
        </Steps.List>

        {items.map((item, index) => (
          <Steps.Content className={styles.Content} key={index} index={index}>
            {item.title} - {item.description}
          </Steps.Content>
        ))}

        <Steps.CompletedContent className={styles.CompletedContent}>
          Steps Complete - Thank you for filling out the form!
        </Steps.CompletedContent>

        <div className={styles.Actions}>
          <Steps.PrevTrigger className={button.Root}>Back</Steps.PrevTrigger>
          <Steps.NextTrigger className={button.Root} data-variant="solid">
            Next
          </Steps.NextTrigger>
        </div>
      </Steps.RootProvider>
    </div>
  )
}
```

### Vertical

Use the `orientation` prop to display the steps vertically.

```tsx
import { Steps } from '@ark-ui/react/steps'
import button from 'styles/button.module.css'
import styles from 'styles/steps.module.css'

const items = [
  { value: 'first', title: 'First', description: 'Contact Info' },
  { value: 'second', title: 'Second', description: 'Date & Time' },
  { value: 'third', title: 'Third', description: 'Select Rooms' },
]

export const Vertical = () => {
  return (
    <Steps.Root className={styles.Root} count={items.length} orientation="vertical">
      <Steps.List className={styles.List}>
        {items.map((item, index) => (
          <Steps.Item className={styles.Item} key={index} index={index}>
            <Steps.Trigger className={styles.Trigger}>
              <Steps.Indicator className={styles.Indicator}>{index + 1}</Steps.Indicator>
              <span>{item.title}</span>
            </Steps.Trigger>
            <Steps.Separator className={styles.Separator} />
          </Steps.Item>
        ))}
      </Steps.List>

      {items.map((item, index) => (
        <Steps.Content className={styles.Content} key={index} index={index}>
          <div className="vstack">
            <span>
              {item.title} - {item.description}
            </span>
            <div className={styles.Actions}>
              <Steps.PrevTrigger className={button.Root}>Back</Steps.PrevTrigger>
              <Steps.NextTrigger className={button.Root} data-variant="solid">
                Next
              </Steps.NextTrigger>
            </div>
          </div>
        </Steps.Content>
      ))}

      <Steps.CompletedContent className={styles.CompletedContent}>
        <div className="vstack">
          <span>Steps Complete - Thank you for filling out the form!</span>
          <Steps.PrevTrigger className={button.Root}>Back</Steps.PrevTrigger>
        </div>
      </Steps.CompletedContent>
    </Steps.Root>
  )
}
```

## API Reference

### Props

### Root

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

**`count`**
Type: `number`
Required: false
Default Value: `undefined`
Description: The total number of steps

**`defaultStep`**
Type: `number`
Required: false
Default Value: `undefined`
Description: The initial value of the stepper when rendered.
Use when you don't need to control the value of the stepper.

**`ids`**
Type: `ElementIds`
Required: false
Default Value: `undefined`
Description: The custom ids for the stepper elements

**`isStepSkippable`**
Type: `(index: number) => boolean`
Required: false
Default Value: `() => false`
Description: Whether a step can be skipped during navigation.
Skippable steps are bypassed when using next/prev.

**`isStepValid`**
Type: `(index: number) => boolean`
Required: false
Default Value: `() => true`
Description: Whether a step is valid. Invalid steps block forward navigation in linear mode.

**`linear`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: If `true`, the stepper requires the user to complete the steps in order

**`onStepChange`**
Type: `(details: StepChangeDetails) => void`
Required: false
Default Value: `undefined`
Description: Callback to be called when the value changes

**`onStepComplete`**
Type: `VoidFunction`
Required: false
Default Value: `undefined`
Description: Callback to be called when a step is completed

**`onStepInvalid`**
Type: `(details: StepInvalidDetails) => void`
Required: false
Default Value: `undefined`
Description: Called when navigation is blocked due to an invalid step.

**`orientation`**
Type: `'horizontal' | 'vertical'`
Required: false
Default Value: `"horizontal"`
Description: The orientation of the stepper

**`step`**
Type: `number`
Required: false
Default Value: `undefined`
Description: The controlled value of the stepper

#### Data Attributes

**`data-scope`**: steps
**`data-part`**: root
**`data-orientation`**: The orientation of the steps

### CompletedContent

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### Content

#### Props

**`index`**
Type: `number`
Required: true
Default Value: `undefined`
Description: undefined

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: steps
**`data-part`**: content
**`data-state`**: "open" | "closed"
**`data-orientation`**: The orientation of the content

### Indicator

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: steps
**`data-part`**: indicator
**`data-complete`**: Present when the indicator value is complete
**`data-current`**: Present when current
**`data-incomplete`**: 

### Item

#### Props

**`index`**
Type: `number`
Required: true
Default Value: `undefined`
Description: undefined

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: steps
**`data-part`**: item
**`data-orientation`**: The orientation of the item
**`data-skippable`**: 

### List

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: steps
**`data-part`**: list
**`data-orientation`**: The orientation of the list

### NextTrigger

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### PrevTrigger

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### Progress

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: steps
**`data-part`**: progress
**`data-complete`**: Present when the progress value is complete

### RootProvider

#### Props

**`value`**
Type: `UseStepsReturn`
Required: true
Default Value: `undefined`
Description: undefined

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### Separator

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: steps
**`data-part`**: separator
**`data-orientation`**: The orientation of the separator
**`data-complete`**: Present when the separator value is complete
**`data-current`**: Present when current
**`data-incomplete`**: 

### Trigger

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: steps
**`data-part`**: trigger
**`data-state`**: "open" | "closed"
**`data-orientation`**: The orientation of the trigger
**`data-complete`**: Present when the trigger value is complete
**`data-current`**: Present when current
**`data-incomplete`**: 

### Context

**API:**

| Property | Type | Description |
|----------|------|-------------|
| `value` | `number` | The value of the stepper. |
| `percent` | `number` | The percentage of the stepper. |
| `count` | `number` | The total number of steps. |
| `hasNextStep` | `boolean` | Whether the stepper has a next step. |
| `hasPrevStep` | `boolean` | Whether the stepper has a previous step. |
| `isCompleted` | `boolean` | Whether the stepper is completed. |
| `isStepValid` | `(index: number) => boolean` | Check if a specific step is valid (lazy evaluation) |
| `isStepSkippable` | `(index: number) => boolean` | Check if a specific step can be skipped |
| `setStep` | `(step: number) => void` | Function to set the value of the stepper. |
| `goToNextStep` | `VoidFunction` | Function to go to the next step. |
| `goToPrevStep` | `VoidFunction` | Function to go to the previous step. |
| `resetStep` | `VoidFunction` | Function to go to reset the stepper. |
| `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of the item at the given index. |
