@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
530 lines (490 loc) • 14.4 kB
Markdown
---
version: 10.104.0
generatedAt: 2026-04-17T18:46:11.947Z
checksum: 090b7d977ba4be5e2c4c04d199a30a4048416c59f443a56985df2f80629d9c40
---
## Deprecated Visual Tests – can be removed in v11
### StepIndicator in loose mode
Every step can be clicked.
You want to place `<StepIndicator.Sidebar sidebar_id="unique-id-loose" />` somewhere in your layout.
```tsx
const InteractiveDemo = () => {
const [step, setStep] = React.useState(1)
return (
<div
style={{
display: 'flex',
}}
>
<StepIndicator.Sidebar sidebar_id="unique-id-loose" />
<Space stretch>
<StepIndicator
sidebar_id="unique-id-loose"
mode="loose"
current_step={step}
on_change={({ current_step }) => {
setStep(current_step)
}}
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"
on_click={() => {
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.
You want to place `<StepIndicator.Sidebar sidebar_id="unique-id-strict" />` somewhere in your layout.
```tsx
<StepIndicator.Sidebar sidebar_id="unique-id-strict" />
<StepIndicator
sidebar_id="unique-id-strict"
mode="strict"
current_step={1}
on_change={({ current_step }) => {
console.log('on_change', current_step)
}}
data={[
{
title: 'Velg mottaker',
},
{
title: 'Bestill eller erstatt',
on_click: ({ current_step }) =>
console.log('current_step:', current_step),
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.
You want to place `<StepIndicator.Sidebar sidebar_id="unique-id-static" />` somewhere in your layout.
```tsx
render(
<StepIndicator
sidebar_id="unique-id-static"
mode="static"
current_step={1}
on_change={({ current_step }) => {
console.log('on_change', current_step)
}}
data={[
{
title: 'Om din nye bolig',
},
{
title: 'Ditt lån og egenkapital',
on_click: ({ current_step }) => console.log(current_step),
},
{
title: 'Oppsummering',
},
]}
/>
)
```
### StepIndicator with sidebar
```tsx
<StepIndicator
style={{
display: 'none',
}}
sidebar_id="unique-id-sidebar"
mode="loose"
data={[
{
title: 'Om din nye bolig',
},
{
title: 'Ditt lån og egenkapital',
},
{
title: 'Oppsummering',
is_current: true,
},
]}
/>
<StepIndicator.Sidebar sidebar_id="unique-id-sidebar" top="large" />
```
### StepIndicator with a router
```tsx
const StepIndicatorWithRouter = () => {
const [currentStep, setCurrentStep] = React.useState(1)
const [history, setInstance] = React.useState(null)
React.useEffect(() => {
const history = createBrowserHistory()
const step =
parseFloat(history.location.search?.replace(/[?]/, '')) || 1
setCurrentStep(step)
setInstance(history)
}, [])
return (
<>
<StepIndicator
sidebar_id="step-indicator-router"
mode="loose"
current_step={currentStep - 1}
on_change={({ current_step }) => {
const step = current_step + 1
setCurrentStep(step)
history.push(`?${step}`)
}}
data={[
{
title: 'Om din nye bolig',
},
{
title: 'Ditt lån og egenkapital',
},
{
title: 'Oppsummering',
},
]}
space
/>
<StepIndicator.Sidebar sidebar_id="step-indicator-router" space />
</>
)
}
render(<StepIndicatorWithRouter />)
```
### StepIndicator customized
Completely customized step indicator.
```tsx
function CustomStepIndicator({ children, data, ...props }) {
const [step, setStep] = React.useState(0)
return (
<>
<StepIndicator
sidebar_id="unique-id-customized"
mode="loose"
data={data}
current_step={step}
on_change={({ current_step }) => setStep(current_step)}
{...props}
/>
<Section style_type="lavender" spacing>
{children(step)}
</Section>
</>
)
}
render(
<CustomStepIndicator
data={[
{
title: 'First',
is_current: 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
```tsx
render(
<StepIndicator
sidebar_id="unique-id-text"
mode="static"
current_step={1}
data={['Om din nye bolig', 'Ditt lån og egenkapital', 'Oppsummering']}
/>
)
```
### StepIndicator with a custom renderer.
```tsx
render(
<StepIndicator
sidebar_id="unique-id-renderer"
mode="strict"
current_step={1}
on_change={({ current_step }) => {
console.log('on_change', current_step)
}}
on_item_render={({ StepItem }) => {
return <StepItem onClick={(e) => console.log(e)} />
}}
data={[
{
title: 'Om din nye bolig',
},
{
title: 'Ditt lån og egenkapital',
on_click: ({ current_step }) => console.log(current_step),
on_render: ({ StepItem }) => (
<StepItem onClick={(e) => console.log(e)} />
),
},
{
title: 'Oppsummering',
/**
* We can also overwrite the states
* inactive: true
* is_current: true
*/
},
]}
/>
)
```
```tsx
<StepIndicator.Sidebar sidebar_id="unique-id-statuses" />
<StepIndicator
sidebar_id="unique-id-statuses"
mode="loose"
current_step={0}
data={[
{
title: 'Current',
},
{
title: 'Warning',
status: 'Status message',
status_state: 'warn',
},
{
title: 'Error',
status: 'Status message',
status_state: 'error',
},
{
title: 'Info',
status: 'Status message',
status_state: 'info',
},
]}
/>
```
## Properties
```json
{
"props": {
"mode": {
"doc": "Defines how the StepIndicator should work. Use `static` for non-interactive steps. Use `strict` for a chronological step order, also, the user can navigate between visited steps. Use `loose` if the user should be able to navigate freely.",
"type": ["'static'", "'strict'", "'loose'"],
"status": "required"
},
"data": {
"doc": "Defines the data/steps showing up in a JavaScript Array or JSON format like `[{title,is_current}]`. See below for properties of `STEP_DATA`.",
"type": ["[Step Item](#step-item-properties)[]", "string[]"],
"status": "required"
},
"current_step": {
"doc": "Defines the initial step starting from 0. Also defines the furthest step visited when `mode=\"strict\"`. Will update to the new step if changed (but will not trigger the `on_change` event). Defaults to `0`.",
"type": "number",
"status": "optional"
},
"overview_title": {
"doc": "The title shown inside the `<StepIndicatorModal />` supplemental screen reader text for the `<StepIndicatorTriggerButton />`. Defaults to `Steps Overview`.",
"type": "string",
"status": "optional"
},
"step_title": {
"doc": "Label for `<StepIndicatorTriggerButton />` and screen reader text for `<StepIndicatorItem />`. Must contain `%step` and `%count` to interpolate `current_step` and `stepCount` into the text. Defaults to `Step %step of %count`.",
"type": "string",
"status": "optional"
},
"hide_numbers": {
"doc": "Define whether to show automatically counted numbers or not. Defaults to `false`.",
"type": "boolean",
"status": "optional"
},
"no_animation": {
"doc": "If set to `true`, the height animation on step change and list expansion will be omitted. Defaults to `false`.",
"type": "boolean",
"status": "optional"
},
"expandedInitially": {
"doc": "Set to `true` to have the list be expanded initially. Defaults to `false`.",
"type": "boolean",
"status": "optional"
},
"outset": {
"doc": "Whether or not to break out (using negative margins) on larger screens. Defaults to `false`. Same as `outset` in [Card](/uilib/components/card/properties).",
"type": "boolean",
"status": "optional"
},
"status": {
"doc": "Text for status shown below the step indicator when it is not expanded. Defaults to `undefined`.",
"type": "string",
"status": "optional"
},
"status_state": {
"doc": "The type of status shown when the `status` prop is set. Defaults to `warn`.",
"type": "['warn', 'info', 'error']",
"status": "optional"
},
"skeleton": {
"doc": "If set to `true`, an overlaying skeleton with animation will be shown.",
"type": "boolean",
"status": "optional"
},
"[Space](/uilib/layout/space/properties)": {
"doc": "Spacing properties like `top` or `bottom` are supported.",
"type": ["string", "object"],
"status": "optional"
},
"sidebar_id": {
"doc": "A unique string-based ID in order to bind together the main component and the sidebar (`<StepIndicator.Sidebar />`). Both have to get the same ID.",
"type": "string",
"status": "deprecated"
},
"step_title_extended": {
"doc": "Descriptive label for `<StepIndicatorModal />`. Must contain `%step` and `%count` to interpolate `current_step` and `stepCount` into the text. Defaults to `You are on step %step of %count`.",
"type": "string",
"status": "deprecated"
},
"on_item_render": {
"doc": "Deprecated, just use step item `title`. Callback function whose return is rendered inside each step instead of the default render. Has to return a React Node. Receives parameter `{ StepItem, element, attributes, props, context }`, where `props` also includes all props from the step object (like `title` or `status`) and the `<StepItem>` is a component that can be used to wrap your returned content.",
"type": "function",
"status": "deprecated"
}
}
}
```
## Step Item Properties
```json
{
"props": {
"title": {
"doc": "The title of the step.",
"type": ["string", "React.ReactNode"],
"status": "required"
},
"is_current": {
"doc": "If set to `true`, this item step will be set as the current selected step. This can be used instead of `current_step` on the main component.",
"type": "boolean",
"status": "optional"
},
"inactive": {
"doc": "If set to `true`, this item step will be handled as an inactive step and will not be clickable. Defaults to `false`.",
"type": "boolean",
"status": "optional"
},
"disabled": {
"doc": "If set to `true`, this step will be handled the same as `inactive` as well as getting a disabled mouseover and `aria-disabled=\"true`. Defaults to `false`.",
"type": "boolean",
"status": "optional"
},
"status": {
"doc": "Is used to set the status text.",
"type": ["string", "React.ReactNode"],
"status": "optional"
},
"status_state": {
"doc": "In case the status state should be `info` or `error`. Defaults to `warn`.",
"type": ["'warn'", "'info'", "'error'"],
"status": "optional"
},
"on_render": {
"doc": "Deprecated, just use `title`. Callback function whose return is rendered inside the step instead of the default render (or `on_item_render`). Has to return a React Node. <br/> Receives parameter `{ StepItem, element, attributes, props, context }`, where `props` also includes all props in the step object (like `title` or `status`) and the `<StepItem>` is a component that can be used to wrap your returned content.",
"type": "function",
"status": "deprecated"
}
}
}
```
## Step Items example
```js
const steps = [
{ title: 'Active' },
{ title: 'Active and marked as current', is_current: true },
{ title: 'Not active', inactive: true },
{ title: 'Disabled', disabled: true },
{
title: 'Active item with status text',
status: 'Status text',
status_state: 'warn', // defaults to warning
},
]
```
## Translations
```json
{
"locales": ["da-DK", "en-GB", "nb-NO", "sv-SE"],
"entries": {
"StepIndicator.overview_title": {
"nb-NO": "Stegoversikt",
"en-GB": "Steps Overview",
"sv-SE": "Stegöversikt",
"da-DK": "Trinoverblik"
},
"StepIndicator.step_title": {
"nb-NO": "Steg %step av %count:",
"en-GB": "Step %step of %count:",
"sv-SE": "Steg %step av %count:",
"da-DK": "Trin %step af %count:"
}
}
}
```
## Events
```json
{
"props": {
"on_click": {
"doc": "Will be called when the user clicks on any clickable step in the list. Is called right before `on_change`. Receives parameter `{ event, item, current_step, currentStep }`.",
"type": "function",
"status": "optional"
},
"on_change": {
"doc": "Will be called when the user changes step by clicking in the steps list (changing the `current_step` prop does not trigger the event). Receives parameter `{ event, item, current_step, currentStep }`.",
"type": "function",
"status": "optional"
}
}
}
```
## Step Item Events
```json
{
"props": {
"on_click": {
"doc": "Called when user clicks the step. Is called right before the main component's `on_click`. Receives parameter `{ event, item, current_step, currentStep }`",
"type": "function",
"status": "optional"
}
}
}
```