QUI React

Stepper

Steps provide a visualization of a set of related steps or sequence of processes in a workflow.

import {
QStepper,
QStep,
QStepIndicator,
QStepContent,
QStepLabel,
QStepDescription,
} from "@qui/react"

Overview

QUI exports 6 components to help you build steppers:

  • QStepper: the root component that handles shared state and provides context for each step.
  • QStep: layout component that wraps each step's indicator and content.
  • QStepIndicator: status indicator for each step.
  • QStepContent: layout component that wraps the step's labels.
  • QStepLabel: each step's primary message.
  • QStepDescription: each step's secondary message.

Examples

Showcase

The useSteps hook is exported to help manage the state of the stepper.

import {ReactNode} from "react"
import {Check} from "lucide-react"
import {
QIcon,
QStep,
QStepContent,
QStepDescription,
QStepIndicator,
QStepLabel,
QStepper,
useSteps,
} from "@qui/react"
const steps = [
{description: "Contact Info", label: "First"},
{description: "Date & Time", label: "Second"},
{description: "Select Rooms", label: "Third"},
]
export default function Showcase(): ReactNode {
const {index, setIndex} = useSteps({count: steps.length, index: 1})
return (
<div className="flex w-full max-w-[400px]">
<QStepper index={index}>
{steps.map((step, index) => {
return (
<QStep key={step.label} as="button" onClick={() => setIndex(index)}>
<QStepIndicator complete={<QIcon icon={Check} />} />
<QStepContent>
<QStepLabel>{step.label}</QStepLabel>
<QStepDescription>{step.description}</QStepDescription>
</QStepContent>
</QStep>
)
})}
</QStepper>
</div>
)
}

Variants

The stepper provides two variants which govern the style of the indicator.

1
FirstContact Info
2
SecondDate & Time
3
ThirdSelect Rooms
FirstContact Info
SecondDate & Time
ThirdSelect Rooms
import {ReactNode} from "react"
import {Check} from "lucide-react"
import {QStepVariant} from "@qui/base"
import {
QIcon,
QStep,
QStepContent,
QStepDescription,
QStepIndicator,
QStepLabel,
QStepper,
useSteps,
} from "@qui/react"
const steps = [
{description: "Contact Info", label: "First"},
{description: "Date & Time", label: "Second"},
{description: "Select Rooms", label: "Third"},
]
export default function Variants(): ReactNode {
const {index, setIndex} = useSteps({count: steps.length})
const variants: QStepVariant[] = ["counter", "dot"]
return (
<div className="flex w-full max-w-[360px] flex-col gap-6 sm:max-w-[500px]">
{variants.map((variant) => (
<div key={variant} className="flex flex-col gap-3">
<div className="text-primary q-font-metadata-md">{variant}</div>
<QStepper index={index} variant={variant}>
{steps.map((step, index) => {
return (
<QStep
key={step.label}
className="cursor-pointer"
onClick={() => setIndex(index)}
>
<QStepIndicator complete={<QIcon icon={Check} />} />
<QStepContent>
<QStepLabel>{step.label}</QStepLabel>
<QStepDescription>{step.description}</QStepDescription>
</QStepContent>
</QStep>
)
})}
</QStepper>
</div>
))}
</div>
)
}

Layouts

The layout prop determines where the labels are positioned relative to the indicator.

1
FirstContact Info
2
SecondDate & Time
3
ThirdSelect Rooms
1
FirstContact Info
2
SecondDate & Time
3
ThirdSelect Rooms
1
FirstContact Info
2
SecondDate & Time
3
ThirdSelect Rooms
1
FirstContact Info
2
SecondDate & Time
3
ThirdSelect Rooms
import {ReactNode} from "react"
import {Check} from "lucide-react"
import {QStepLayout} from "@qui/base"
import {
QIcon,
QStep,
QStepContent,
QStepDescription,
QStepIndicator,
QStepLabel,
QStepper,
useSteps,
} from "@qui/react"
const steps = [
{description: "Contact Info", label: "First"},
{description: "Date & Time", label: "Second"},
{description: "Select Rooms", label: "Third"},
]
export default function Layout(): ReactNode {
const {index, setIndex} = useSteps({count: steps.length})
const layouts: QStepLayout[] = [
"column",
"column-reverse",
"row",
"row-reverse",
]
return (
<div className="flex w-full max-w-[360px] flex-col gap-6 sm:max-w-[500px]">
{layouts.map((layout) => (
<div key={layout} className="flex flex-col gap-3">
<div className="text-primary q-font-metadata-md">{layout}</div>
<QStepper index={index} layout={layout}>
{steps.map((step, index) => {
return (
<QStep
key={step.label}
className="cursor-pointer"
onClick={() => setIndex(index)}
>
<QStepIndicator complete={<QIcon icon={Check} />} />
<QStepContent>
<QStepLabel>{step.label}</QStepLabel>
<QStepDescription>{step.description}</QStepDescription>
</QStepContent>
</QStep>
)
})}
</QStepper>
</div>
))}
</div>
)
}

Step Status

By default, the status of a step will change to 'complete' when the active index advances beyond the step's index. You can override this by supplying the status prop on the step. In the following example, the first step is always 'complete'.

import {ReactNode} from "react"
import {Check} from "lucide-react"
import {QStepStatus} from "@qui/base"
import {
QIcon,
QStep,
QStepContent,
QStepDescription,
QStepIndicator,
QStepLabel,
QStepper,
useSteps,
} from "@qui/react"
const steps = [
{description: "Contact Info", label: "First"},
{description: "Date & Time", label: "Second"},
{description: "Select Rooms", label: "Third"},
]
export default function Status(): ReactNode {
const {index, setIndex} = useSteps({count: steps.length, index: 0})
function getStepStatus(stepIndex: number): QStepStatus {
// in this example, step 1 is always complete.
if (stepIndex === 0) {
return "complete"
}
return stepIndex >= index ? "incomplete" : "complete"
}
return (
<div className="flex w-full max-w-[400px]">
<QStepper index={index}>
{steps.map((step, stepIndex) => {
return (
<QStep
key={step.label}
as="button"
onClick={() => setIndex(stepIndex)}
status={getStepStatus(stepIndex)}
>
<QStepIndicator complete={<QIcon icon={Check} />} />
<QStepContent>
<QStepLabel>{step.label}</QStepLabel>
<QStepDescription>{step.description}</QStepDescription>
</QStepContent>
</QStep>
)
})}
</QStepper>
</div>
)
}

Status Indicators

Provide props to the QStepIndicator component to customize the elements that are rendered based on the step's current status.

complete
warning
error
incomplete

New statuses added in 1.8.0

success
pending
aborted
running
initializing
import {ReactNode} from "react"
import {
AlertCircleIcon,
AlertTriangleIcon,
BanIcon,
CheckIcon,
ClockIcon,
HelpCircleIcon,
LoaderIcon,
} from "lucide-react"
import {QStepStatus} from "@qui/base"
import {
QIcon,
QProgressCircle,
QStep,
QStepContent,
QStepIndicator,
QStepLabel,
QStepper,
} from "@qui/react"
const status: QStepStatus[] = ["complete", "warning", "error", "incomplete"]
// Added in 1.8.0
const statusExtra: QStepStatus[] = [
"success",
"pending",
"aborted",
"running",
"initializing",
]
export default function StatusIndicators(): ReactNode {
return (
<div className="flex w-full max-w-[500px] flex-col items-center">
<QStepper index={-1}>
{status.map((status) => {
return (
<QStep key={status} status={status}>
<QStepIndicator
complete={<QIcon icon={CheckIcon} />}
error={<QIcon icon={AlertCircleIcon} />}
incomplete={<QIcon icon={HelpCircleIcon} />}
warning={<QIcon icon={AlertTriangleIcon} />}
/>
<QStepContent>
<QStepLabel>{status}</QStepLabel>
</QStepContent>
</QStep>
)
})}
</QStepper>
<h2 className="q-text-1-primary mb-4 mt-6 q-font-heading-xs">
New statuses added in 1.8.0
</h2>
<QStepper index={-1}>
{statusExtra.map((status) => {
return (
<QStep key={status} status={status}>
<QStepIndicator
aborted={<QIcon icon={BanIcon} />}
initializing={<QIcon icon={LoaderIcon} />}
pending={<QIcon icon={ClockIcon} />}
running={<QProgressCircle color="inherit" size="xxs" />}
success={<QIcon icon={CheckIcon} />}
/>
<QStepContent>
<QStepLabel>{status}</QStepLabel>
</QStepContent>
</QStep>
)
})}
</QStepper>
</div>
)
}

Playground

Layout
Orientation
Variant
TSX
const props: QStepperProps = {
index: 0,
layout: "column",
orientation: "horizontal",
variant: "counter",
}

API

QStepperProps

Name & DescriptionOption(s)Default
The current step index.
number
The component used for the root node. It can be a React component or element.
| ElementType
| ComponentType
'div'
React children prop.
ReactNode
The className property of the Element interface gets and sets the value of the class attribute of the specified element.
string
The layout of step labels relative to the step indicator.
  • column: the labels are placed below the indicator.
  • column-reverse: the labels are placed above the indicator.
  • row: the labels are placed to the right of the indicator.
  • row-reverse: the labels are placed to the left of the indicator.
| 'column'
| 'column-reverse'
| 'row'
| 'row-reverse'
'column'
The orientation of the steps.
  • horizontal: steps are displayed left-to-right.
  • vertical: steps are displayed top-to-bottom.
| 'horizontal'
| 'vertical'
'horizontal'
The style global attribute contains CSS styling declarations to be applied to the element.
CSSProperties
The style variant of each step.
| 'dot'
| 'counter'
'counter'
Type
number
Description
The current step index.
Type
| ElementType
| ComponentType
Default
'div'
Description
The component used for the root node. It can be a React component or element.
Description
React children prop.
Type
string
Description
The className property of the Element interface gets and sets the value of the class attribute of the specified element.
Type
| 'column'
| 'column-reverse'
| 'row'
| 'row-reverse'
Default
'column'
Description
The layout of step labels relative to the step indicator.
  • column: the labels are placed below the indicator.
  • column-reverse: the labels are placed above the indicator.
  • row: the labels are placed to the right of the indicator.
  • row-reverse: the labels are placed to the left of the indicator.
Type
| 'horizontal'
| 'vertical'
Default
'horizontal'
Description
The orientation of the steps.
  • horizontal: steps are displayed left-to-right.
  • vertical: steps are displayed top-to-bottom.
Description
The style global attribute contains CSS styling declarations to be applied to the element.
Type
| 'dot'
| 'counter'
Default
'counter'
Description
The style variant of each step.

QStepProps

Name & DescriptionOption(s)Default
The component used for the root node. It can be a React component or element.
| ElementType
| ComponentType
'div'
React children prop.
ReactNode
The className property of the Element interface gets and sets the value of the class attribute of the specified element.
string
If true, this step will appear disabled.
boolean
Override the horizontal separator element. Note that this element creates space between each step element by taking up the full width of its parent container. You will want to account for this with your component.
Related symbols:
| ReactElement
| ((
props: QStepContext,
) => ReactElement)
Layout for this step's labels. If supplied, this will override the same prop from the parent QStepper.
| 'column'
| 'column-reverse'
| 'row'
| 'row-reverse'
HTML role attribute applied to the root element.
string
'region'
Each step's status is automatically computed based on the step's index and the active index of the stepper. You can override this step's status by supplying this prop. Updated in v1.8.0 to include 5 new statuses. Refer to the Status Indicators example to learn more.
| 'incomplete'
| 'complete'
| 'warning'
| 'error'
| 'pending'
| 'success'
| 'aborted'
| 'running'
| 'initializing'
The style global attribute contains CSS styling declarations to be applied to the element.
CSSProperties
Override the vertical separator element.
Related symbols:
| ReactElement
| ((
props: QStepContext,
) => ReactElement)
Type
| ElementType
| ComponentType
Default
'div'
Description
The component used for the root node. It can be a React component or element.
Description
React children prop.
Type
string
Description
The className property of the Element interface gets and sets the value of the class attribute of the specified element.
Type
boolean
Description
If true, this step will appear disabled.
Type
| ReactElement
| ((
props: QStepContext,
) => ReactElement)
Description
Override the horizontal separator element. Note that this element creates space between each step element by taking up the full width of its parent container. You will want to account for this with your component.
Related symbols
Related symbols:
Type
| 'column'
| 'column-reverse'
| 'row'
| 'row-reverse'
Description
Layout for this step's labels. If supplied, this will override the same prop from the parent QStepper.
Type
string
Default
'region'
Description
HTML role attribute applied to the root element.
Type
| 'incomplete'
| 'complete'
| 'warning'
| 'error'
| 'pending'
| 'success'
| 'aborted'
| 'running'
| 'initializing'
Description
Each step's status is automatically computed based on the step's index and the active index of the stepper. You can override this step's status by supplying this prop. Updated in v1.8.0 to include 5 new statuses. Refer to the Status Indicators example to learn more.
Description
The style global attribute contains CSS styling declarations to be applied to the element.
Type
| ReactElement
| ((
props: QStepContext,
) => ReactElement)
Description
Override the vertical separator element.
Related symbols
Related symbols:

QStepIndicatorProps

Name & DescriptionOption(s)Default
Optional node to render when the step's status is aborted.
ReactNode
The component used for the root node. It can be a React component or element.
| ElementType
| ComponentType
'div'
The className property of the Element interface gets and sets the value of the class attribute of the specified element.
string
Optional node to render when the step's status is complete.
ReactNode
Optional node to render when the step's status is error.
ReactNode
Optional node to render when the step's status is incomplete.
ReactNode
Optional node to render when the step's status is initializing.
ReactNode
Optional node to render when the step's status is pending.
ReactNode
Optional node to render when the step's status is running.
ReactNode
The style global attribute contains CSS styling declarations to be applied to the element.
CSSProperties
Optional node to render when the step's status is success.
ReactNode
Optional node to render when the step's status is warning.
ReactNode
Description
Optional node to render when the step's status is aborted.
Type
| ElementType
| ComponentType
Default
'div'
Description
The component used for the root node. It can be a React component or element.
Type
string
Description
The className property of the Element interface gets and sets the value of the class attribute of the specified element.
Description
Optional node to render when the step's status is complete.
Description
Optional node to render when the step's status is error.
Description
Optional node to render when the step's status is incomplete.
Description
Optional node to render when the step's status is initializing.
Description
Optional node to render when the step's status is pending.
Description
Optional node to render when the step's status is running.
Description
The style global attribute contains CSS styling declarations to be applied to the element.
Description
Optional node to render when the step's status is success.
Description
Optional node to render when the step's status is warning.

QStepContentProps

Name & DescriptionOption(s)Default
The component used for the root node. It can be a React component or element.
| ElementType
| ComponentType
'div'
The className property of the Element interface gets and sets the value of the class attribute of the specified element.
string
The style global attribute contains CSS styling declarations to be applied to the element.
CSSProperties
Type
| ElementType
| ComponentType
Default
'div'
Description
The component used for the root node. It can be a React component or element.
Type
string
Description
The className property of the Element interface gets and sets the value of the class attribute of the specified element.
Description
The style global attribute contains CSS styling declarations to be applied to the element.

QStepLabelProps

Name & DescriptionOption(s)Default
The component used for the root node. It can be a React component or element.
| ElementType
| ComponentType
'span'
React children prop.
ReactNode
The className property of the Element interface gets and sets the value of the class attribute of the specified element.
string
The style global attribute contains CSS styling declarations to be applied to the element.
CSSProperties
Type
| ElementType
| ComponentType
Default
'span'
Description
The component used for the root node. It can be a React component or element.
Description
React children prop.
Type
string
Description
The className property of the Element interface gets and sets the value of the class attribute of the specified element.
Description
The style global attribute contains CSS styling declarations to be applied to the element.

QStepDescriptionProps

Name & DescriptionOption(s)Default
The component used for the root node. It can be a React component or element.
| ElementType
| ComponentType
'span'
React children prop.
ReactNode
The className property of the Element interface gets and sets the value of the class attribute of the specified element.
string
The style global attribute contains CSS styling declarations to be applied to the element.
CSSProperties
Type
| ElementType
| ComponentType
Default
'span'
Description
The component used for the root node. It can be a React component or element.
Description
React children prop.
Type
string
Description
The className property of the Element interface gets and sets the value of the class attribute of the specified element.
Description
The style global attribute contains CSS styling declarations to be applied to the element.

QStepContext

Some props like the horizontalSeparator and verticalSeparator provide the step's context in the form of render props. The data type of this context is documented here. Refer to the separators demo for an example.

Name & DescriptionOption(s)Default
Whether the step is currently active.
boolean
The current active step index.
number
The total number of steps.
number
The index of the step.
number
Whether the step is the first step.
boolean
Whether the step is the last step.
boolean
The layout of the step's indicator and labels.
| 'column'
| 'column-reverse'
| 'row'
| 'row-reverse'
The orientation of the stepper.
| 'horizontal'
| 'vertical'
The status of the step. Updated in v1.8.0 to include 5 new statuses. Refer to the Status Indicators example to learn more.
| 'incomplete'
| 'complete'
| 'warning'
| 'error'
| 'pending'
| 'success'
| 'aborted'
| 'running'
| 'initializing'
The style variant of the step.
| 'dot'
| 'counter'
Whether the step is disabled.
boolean
Type
boolean
Description
Whether the step is currently active.
Type
number
Description
The current active step index.
Type
number
Description
The total number of steps.
Type
number
Description
The index of the step.
Type
boolean
Description
Whether the step is the first step.
Type
boolean
Description
Whether the step is the last step.
Type
| 'column'
| 'column-reverse'
| 'row'
| 'row-reverse'
Description
The layout of the step's indicator and labels.
Type
| 'horizontal'
| 'vertical'
Description
The orientation of the stepper.
Type
| 'incomplete'
| 'complete'
| 'warning'
| 'error'
| 'pending'
| 'success'
| 'aborted'
| 'running'
| 'initializing'
Description
The status of the step. Updated in v1.8.0 to include 5 new statuses. Refer to the Status Indicators example to learn more.
Type
| 'dot'
| 'counter'
Description
The style variant of the step.
Type
boolean
Description
Whether the step is disabled.

QStepperOrientation

Unsupported Doc Props Interface: QStepperOrientation
Please ensure that the following is accounted for:
  • The entity exists.
  • The entity is exported from the package's entrypoint (typicallysrc/index.ts)
  • The entity is tagged with the required JSDoc tags:
/**
* @interface
* @public
*/
export type QStepperOrientation = {
...
}

QStepLayout

Unsupported Doc Props Interface: QStepLayout
Please ensure that the following is accounted for:
  • The entity exists.
  • The entity is exported from the package's entrypoint (typicallysrc/index.ts)
  • The entity is tagged with the required JSDoc tags:
/**
* @interface
* @public
*/
export type QStepLayout = {
...
}

QStepStatus

Unsupported Doc Props Interface: QStepStatus
Please ensure that the following is accounted for:
  • The entity exists.
  • The entity is exported from the package's entrypoint (typicallysrc/index.ts)
  • The entity is tagged with the required JSDoc tags:
/**
* @interface
* @public
*/
export type QStepStatus = {
...
}

QStepVariant

Unsupported Doc Props Interface: QStepVariant
Please ensure that the following is accounted for:
  • The entity exists.
  • The entity is exported from the package's entrypoint (typicallysrc/index.ts)
  • The entity is tagged with the required JSDoc tags:
/**
* @interface
* @public
*/
export type QStepVariant = {
...
}