The active step index
Stepper
A stepper component is used to indicate progress through a multi-step process.
Import#
Chakra UI exports the followings components:
import {Step,StepDescription,StepIcon,StepIndicator,StepNumber,StepSeparator,StepStatus,StepTitle,Stepper,useSteps,} 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 (<Stepper index={activeStep}>{steps.map((step, index) => (<Step key={index}><StepIndicator><StepStatuscomplete={<StepIcon />}incomplete={<StepNumber />}active={<StepNumber />}/></StepIndicator><Box flexShrink='0'><StepTitle>{step.title}</StepTitle><StepDescription>{step.description}</StepDescription></Box><StepSeparator /></Step>))}</Stepper>)}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 (<Stepper index={activeStep} orientation='vertical' height='400px' gap='0'>{steps.map((step, index) => (<Step key={index}><StepIndicator><StepStatuscomplete={<StepIcon />}incomplete={<StepNumber />}active={<StepNumber />}/></StepIndicator><Box flexShrink='0'><StepTitle>{step.title}</StepTitle><StepDescription>{step.description}</StepDescription></Box><StepSeparator /></Step>))}</Stepper>)}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 (<Stepper size='lg' index={activeStep}>{steps.map((step, index) => (<Step key={index}><StepIndicator><StepStatuscomplete={<StepIcon />}incomplete={<StepNumber />}active={<StepNumber />}/></StepIndicator><Box flexShrink='0'><StepTitle>{step.title}</StepTitle><StepDescription>{step.description}</StepDescription></Box><StepSeparator /></Step>))}</Stepper>)}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 (<Stepper size='lg' colorScheme='red' index={activeStep}>{steps.map((step, index) => (<Step key={index}><StepIndicator><StepStatuscomplete={<StepIcon />}incomplete={<StepNumber />}active={<StepNumber />}/></StepIndicator><Box flexShrink='0'><StepTitle>{step.title}</StepTitle><StepDescription>{step.description}</StepDescription></Box><StepSeparator /></Step>))}</Stepper>)}render(<Example />)
Changing the step indicator's content#
In some cases you might want to render custom icons or elements within the
StepIndicator
component.
To do this, you can leverage the StepStatus
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 (<Stepper size='lg' colorScheme='yellow' index={activeStep}>{steps.map((step, index) => (<Step key={index}><StepIndicator><StepStatus complete={`β `} incomplete={`π `} active={`π`} /></StepIndicator><Box flexShrink='0'><StepTitle>{step.title}</StepTitle><StepDescription>{step.description}</StepDescription></Box><StepSeparator /></Step>))}</Stepper>)}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 (<Stepper size='lg' index={activeStep}>{steps.map((step, index) => (<Step key={index} onClick={() => setActiveStep(index)}><StepIndicator><StepStatuscomplete={<StepIcon />}incomplete={<StepNumber />}active={<StepNumber />}/></StepIndicator><Box flexShrink='0'><StepTitle>{step.title}</StepTitle><StepDescription>{step.description}</StepDescription></Box><StepSeparator /></Step>))}</Stepper>)}render(<Example />)
Adding a progress bar#
You can replace the StepSeparator 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 activeStepText = steps[activeStep].descriptionconst max = steps.length - 1const progressPercent = (activeStep / max) * 100return (<Box position='relative'><Stepper size='sm' index={activeStep} gap='0'>{steps.map((step, index) => (<Step key={index} gap='0'><StepIndicator bg='white'><StepStatus complete={<StepIcon />} /></StepIndicator></Step>))}</Stepper><Progressvalue={progressPercent}position='absolute'height='3px'width='full'top='10px'zIndex={-1}/></Box>)}render(<Example />)
Customizing the indicator#
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 (<Stepper index={activeStep} height='400px' gap='0'>{steps.map((step, index) => (<Step key={index}><StepIndicatorsx={{'[data-status=complete] &': {background: 'purple',borderColor: 'black',},'[data-status=active] &': {background: 'yellow',borderColor: 'black',},'[data-status=incomplete] &': {background: 'red',borderColor: 'black',},}}><StepStatuscomplete={<StepIcon />}incomplete={<StepNumber />}active={<StepNumber />}/></StepIndicator><Box flexShrink='0'><StepTitle>{step.title}</StepTitle><StepDescription>{step.description}</StepDescription></Box><StepSeparator _horizontal={{ backgroundColor: 'red' }} /></Step>))}</Stepper>)}
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 activeStepText = steps[activeStep].descriptionreturn (<Stack><Stepper size='sm' index={activeStep} gap='0'>{steps.map((step, index) => (<Step key={index} gap='0'><StepIndicator><StepStatus complete={<StepIcon />} /></StepIndicator><StepSeparator _horizontal={{ ml: '0' }} /></Step>))}</Stepper><Text>Step {activeStep + 1}: <b>{activeStepText}</b></Text></Stack>)}render(<Example />)
Props#
Stepper Props#
index
required
index
required
number
children
children
The children of the stepper. Must be Step
components
ReactElement[]
StepStatus Props#
complete
complete
The element to show when the step is complete
React.ReactNode | ((props: StepContext) => React.ReactNode)
incomplete
incomplete
The element to show when the step is incomplete
React.ReactNode | ((props: StepContext) => React.ReactNode)
active
active
The element to show when the step is current
React.ReactNode | ((props: StepContext) => React.ReactNode)
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.