Import#
import { StepIndicator } from '@dnb/eufemia'
Description#
The step indicator (progress indicator) is a visual representation of a user's progress through a set of steps or series of actions. Their purpose is to both guide the user through the process and to help them create a mental model of the amount of time and effort that is required to fulfill the process.
Relevant links#
If the user should be able to navigate back and forth, use the mode="loose" property. More about the modes further down.
The current active step is set with the currentStep property or within the data with the isCurrent object property.
NB: Whenever possible, ensure you bind the currentStep to the browsers path location. See the example below.
Modes#
The mode property is mandatory. It tells the component how it should behave.
Strict mode#
Use strict for a chronological step order.
The user can navigate between the visited steps and the current step. The component keeps track of these reached steps.
Loose mode#
Use loose if the user should be able to navigate freely between all steps. Also, those which are not visited before.
Static mode#
Use static for non-interactive steps.
Modify a step#
You can easily modify a step – e.g. should one step not be interactive, you can use the inactive property on that step:
const steps = [{ title: 'Active' },{ title: 'Not active', inactive: true },]
More details about modifying steps in the properties panel.
Accessibility#
When openOnFind is enabled, find-in-page support is powered by HeightAnimation; see its accessibility notes for behavior details and browser support.
Related components#
StepIndicator is part of the Navigation category. Other components for similar needs:
- Breadcrumb — to show where someone is and let them move back up the path.
- InfinityScroller — to load more content automatically as people scroll.
- Pagination — to split long content into pages or load more content as people move through it.
- SkipContent — to help keyboard users jump past large or repeated content.
- Tabs — to let people switch between related views on the same page.
Demos#
StepIndicator in loose mode#
Every step can be clicked.
const InteractiveDemo = () => { const [step, setStep] = useState(1) return ( <div style={{ display: 'flex', }} > <Space stretch> <StepIndicator mode="loose" currentStep={step} onChange={({ currentStep }) => { setStep(currentStep) }} data={[ 'Cum odio si bolig bla et ta', 'Auctor tortor vestibulum placerat bibendum sociis aliquam nunc sed venenatis massa eget duis', 'Bibendum sociis', ]} bottom /> <Button variant="secondary" onClick={() => { setStep((step) => { if (step >= 2) { step = -1 } return step + 1 }) }} > Next step </Button> </Space> </div> ) } render(<InteractiveDemo />)
StepIndicator in strict mode#
Every visited step can be clicked, including the current step.
<StepIndicator mode="strict" currentStep={1} onChange={({ currentStep }) => { console.log('onChange', currentStep) }} data={[ { title: 'Velg mottaker', }, { title: 'Bestill eller erstatt', onClick: ({ currentStep }) => console.log('currentStep:', currentStep), status: 'Du må velge bestill nytt kort eller erstatt kort for å kunne fullføre bestillingen din.', }, { title: 'Oppsummering', }, ]} />
StepIndicator in static mode#
None of the steps are clickable.
<StepIndicator mode="static" currentStep={1} onChange={({ currentStep }) => { console.log('onChange', currentStep) }} data={[ { title: 'Om din nye bolig', }, { title: 'Ditt lån og egenkapital', onClick: ({ currentStep }) => console.log(currentStep), }, { title: 'Oppsummering', }, ]} />
StepIndicator with a router#
const StepIndicatorWithRouter = () => { const [currentStep, setCurrentStep] = useState(1) useEffect(() => { const step = parseFloat(window.location.search?.replace(/[?]/, '')) || 1 setCurrentStep(step) }, []) return ( <> <StepIndicator mode="loose" currentStep={currentStep - 1} onChange={({ currentStep }) => { const step = currentStep + 1 setCurrentStep(step) window.history.pushState({}, '', '?' + step) }} data={[ { title: 'Om din nye bolig', }, { title: 'Ditt lån og egenkapital', }, { title: 'Oppsummering', }, ]} /> </> ) } render(<StepIndicatorWithRouter />)
StepIndicator customized#
Completely customized step indicator.
function CustomStepIndicator({ children, data, ...props }) { const [step, setStep] = useState(0) return ( <> <StepIndicator mode="loose" data={data} currentStep={step} onChange={({ currentStep }) => setStep(currentStep)} bottom {...props} /> <Section variant="information" innerSpace> {children(step)} </Section> </> ) } render( <CustomStepIndicator data={[ { title: 'First', isCurrent: true, }, { title: 'Second', }, { title: 'Last', }, ]} > {(step) => { switch (step) { case 0: return <>Step One</> case 1: return <>Step Two</> default: return <>Fallback</> } }} </CustomStepIndicator> )
StepIndicator with text only#
This example also demonstrates the expandedInitially property.
<StepIndicator expandedInitially mode="static" currentStep={1} data={['Om din nye bolig', 'Ditt lån og egenkapital', 'Oppsummering']} />
With skeleton#
<StepIndicator mode="static" skeleton currentStep={1} expandedInitially data={[ { title: 'Om din nye bolig', }, { title: 'Ditt lån og egenkapital', }, { title: 'Oppsummering', }, ]} />