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 theSteppercomponentstep: Maps to theStepcomponenttitle: Maps to theStepTitlecomponentdescription: Maps to theStepDescriptioncomponentindicator: Maps to theStepIndicatorcomponentseparator: Maps to theStepSeparatorcomponenticon: Maps to theStepIconcomponentnumber: Maps to theStepNumbercomponent
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.