Stepper
A stepper component is used to indicate progress through a multi-step process.
Import#
import { Steps } from '@chakra-ui/react'
Usage#
Use the step indicator component to show the user's position in and progress through a multi-step process. Step indicators are often used on application forms or workflow screens.
The useSteps
hook is exported to help manage the state of stepper and the
active step index.
Here's a basic example of a horizontal stepper:
const steps = [{ title: 'First', description: 'Contact Info' },{ title: 'Second', description: 'Date & Time' },{ title: 'Third', description: 'Select Rooms' },]function Example() {const { activeStep } = useSteps({index: 1,count: steps.length,})return (<Steps.Root index={activeStep}>{steps.map((step, index) => (<Steps.Item key={index}><Steps.Indicator /><Box flexShrink='0'><Steps.Title>{step.title}</Steps.Title><Steps.Description>{step.description}</Steps.Description></Box><Steps.Separator /></Steps.Item>))}</Steps.Root>)}render(<Example />)
Changing the orientation#
const steps = [{ title: 'First', description: 'Contact Info' },{ title: 'Second', description: 'Date & Time' },{ title: 'Third', description: 'Select Rooms' },]function Example() {const { activeStep } = useSteps({index: 1,count: steps.length,})return (<Steps.Rootindex={activeStep}orientation='vertical'height='400px'gap='0'>{steps.map((step, index) => (<Steps.Item key={index}><Steps.Indicator /><Box flexShrink='0'><Steps.Title>{step.title}</Steps.Title><Steps.Description>{step.description}</Steps.Description></Box><Steps.Separator /></Steps.Item>))}</Steps.Root>)}render(<Example />)
Changing the size#
To change the size of the step indicator, you can pass the size
prop to the
Stepper
component, setting it to either sm
, md
or lg
.
const steps = [{ title: 'First', description: 'Contact Info' },{ title: 'Second', description: 'Date & Time' },{ title: 'Third', description: 'Select Rooms' },]function Example() {const { activeStep } = useSteps({index: 1,count: steps.length,})return (<Steps.Root size='lg' index={activeStep}>{steps.map((step, index) => (<Steps.Item key={index}><Steps.Indicator /><Box flexShrink='0'><Steps.Title>{step.title}</Steps.Title><Steps.Description>{step.description}</Steps.Description></Box><Steps.Separator /></Steps.Item>))}</Steps.Root>)}render(<Example />)
Changing the color scheme#
The stepper uses a blue color scheme by default. To change the colorScheme, you
can pass the colorScheme
prop to Stepper
component to any color in the
theme.
const steps = [{ title: 'First', description: 'Contact Info' },{ title: 'Second', description: 'Date & Time' },{ title: 'Third', description: 'Select Rooms' },]function Example() {const { activeStep } = useSteps({index: 1,count: steps.length,})return (<Steps.Root size='lg' colorPalette='red' index={activeStep}>{steps.map((step, index) => (<Steps.Item key={index}><Steps.Indicator /><Box flexShrink='0'><Steps.Title>{step.title}</Steps.Title><Steps.Description>{step.description}</Steps.Description></Box><Steps.Separator /></Steps.Item>))}</Steps.Root>)}render(<Example />)
Changing the step indicator's content#
In some cases you might want to render custom icons or elements within the
Steps.Indicator
component.
To do this, you can leverage the Steps.Status
component to show custom React
elements based on the step's status.
const steps = [{ title: 'First', description: 'Contact Info' },{ title: 'Second', description: 'Date & Time' },{ title: 'Third', description: 'Select Rooms' },]function Example() {const { activeStep } = useSteps({index: 1,count: steps.length,})return (<Steps.Root size='lg' colorPalette='yellow' index={activeStep}>{steps.map((step, index) => (<Steps.Item key={index}><Steps.Indicator><Steps.Status completed={`✅`} incomplete={`😅`} current={`📍`} /></Steps.Indicator><Box flexShrink='0'><Steps.Title>{step.title}</Steps.Title><Steps.Description>{step.description}</Steps.Description></Box><Steps.Separator /></Steps.Item>))}</Steps.Root>)}render(<Example />)
Setting the active step with click#
const steps = [{ title: 'First', description: 'Contact Info' },{ title: 'Second', description: 'Date & Time' },{ title: 'Third', description: 'Select Rooms' },]function Example() {const { activeStep, setActiveStep } = useSteps({index: 1,count: steps.length,})return (<Steps.Root size='lg' index={activeStep}>{steps.map((step, index) => (<Steps.Item key={index} onClick={() => setActiveStep(index)}><Steps.Indicator /><Box flexShrink='0'><Steps.Title>{step.title}</Steps.Title><Steps.Description>{step.description}</Steps.Description></Box><Steps.Separator /></Steps.Item>))}</Steps.Root>)}render(<Example />)
Adding a progress bar#
You can replace the Steps.Separator component with a custom progress indicator,
e.g. the Progress
component for more custom experience.
const steps = [{ title: 'First', description: 'Contact Info' },{ title: 'Second', description: 'Date & Time' },{ title: 'Third', description: 'Select Rooms' },]function Example() {const { activeStep, setActiveStep } = useSteps({index: 1,count: steps.length,})const desc = steps[activeStep].descriptionconst max = steps.length - 1return (<Box position='relative'><Steps.Root size='sm' index={activeStep} gap='0'>{steps.map((step, index) => (<Steps.Item key={index} gap='0'><Steps.Indicator bg='white'><Steps.Status complete={<StepIcon />} /></Steps.Indicator></Steps.Item>))}</Steps.Root><Progress.Rootmin={0}max={3}value={activeStep}size='sm'position='absolute'height='3px'width='full'top='10px'zIndex={-1}><Progress.Track><Progress.FilledTrack /></Progress.Track></Progress.Root></Box>)}render(<Example />)
Showing step summary#
A step summary can be shown when labels are hidden. The step summary allows the user to see the label of the current step directly below the step group and is recommended for smaller screens and responsive mobile views.
const steps = [{ title: 'First', description: 'Contact Info' },{ title: 'Second', description: 'Date & Time' },{ title: 'Third', description: 'Select Rooms' },]function Example() {const { activeStep, setActiveStep } = useSteps({index: 1,count: steps.length,})const desc = steps[activeStep].descriptionreturn (<Stack><Steps.Root size='sm' index={activeStep} gap='0'>{steps.map((step, index) => (<Steps.Item key={index} gap='0'><Steps.Indicator><Steps.Status complete={<StepIcon />} /></Steps.Indicator><Steps.Separator _horizontal={{ ml: '0' }} /></Steps.Item>))}</Steps.Root><Text>Step {activeStep + 1}: <b>{desc}</b></Text></Stack>)}render(<Example />)
Props#
Stepper Props#
StepStatus Props#
All other components are passed through to their underlying components.
Theming#
The Stepper
component is a multipart component. The styling needs to be
applied to each part specifically.
Anatomy#
The Stepper theming is made up of the following parts:
stepper
: Maps to theStepper
componentstep
: Maps to theStep
componenttitle
: Maps to theStepTitle
componentdescription
: Maps to theStepDescription
componentindicator
: Maps to theStepIndicator
componentseparator
: Maps to theStepSeparator
componenticon
: Maps to theStepIcon
componentnumber
: Maps to theStepNumber
component
Customizing a component#
Let's say we want to override the step indicator to use a square instead of a circle. Here's how we'll go about that:
// themes/stepper.tsconst baseStyle = {// select the indicator partindicator: {// change the default border radius to 0borderRadius: 0,},}const stepperTheme = {baseStyle,}const theme = extendTheme({components: {Stepper: stepperTheme,},})
Changing the styles for a specific size#
In addition to the baseStyle
, you can also change the styles for a specific
size. Let's say we want to change the step title's font size for the lg
size.
// themes/stepper.tsconst baseStyle = {indicator: {borderRadius: 0,},}const sizes = {lg: {// select the title parttitle: {// change the font size to lgfontSize: 'lg',},},}const stepperTheme = {baseStyle,sizes,}const theme = extendTheme({components: {Stepper: stepperTheme,},})
The styling for a stepper component can be overriden at any level, whether it's
variant
or size
, it's completely up to you.
To learn more about styling multipart components, visit the Component Style page.