Skip to main content

Stepper
New

Stepper is used to create wizard-like workflows by dividing content into logical steps. The user can navigate backwards by clicking on the header of a completed step.

Examples

Open in new window
<duet-stepper>
<duet-step heading="Your name">
<duet-input label="First name" expand></duet-input>
<duet-input label="Last name" expand></duet-input>
<duet-spacer></duet-spacer>
<duet-button margin="none" variation="primary" class="next">Next</duet-button>
</duet-step>

<duet-step heading="Favourite food">
<duet-radio-group responsive label="Choose" direction="vertical" value="pizza" name="group1">
<duet-radio value="pizza" label="Pizza"></duet-radio>
<duet-radio value="burger" label="Burger"></duet-radio>
<duet-radio value="salad" label="Salad"></duet-radio>
</duet-radio-group>
<duet-button margin="none" variation="primary" class="next">Next</duet-button>
</duet-step>

<duet-step heading="Final step">
<duet-textarea
expand
label="Write something about yourself"
placeholder="Placeholder text"
debounce="500"
>
</duet-textarea>
</duet-step>
</duet-stepper>

<script>
var stepper = document.querySelector("duet-stepper")
var nextButtons = document.querySelectorAll("duet-button.next")

// when "next" button is clicked, advance to next step
nextButtons.forEach(function(button) {
button.addEventListener("click", function() {
stepper.selected++
})
})

// duetStepChange event is raised whenever a step heading is clicked
// when this happens, change to that step
stepper.addEventListener("duetStepChange", function(e) {
stepper.selected = e.detail.toStep
console.log("step change:", "from", e.detail.fromStep, "to", e.detail.toStep)
})
</script>
Open in new window
<duet-stepper>
<duet-step heading="Your name">
<div slot="heading-content">
<duet-caption margin="none">
The heading-content slot allows for additional content
</duet-caption>
</div>
<duet-input label="First name" expand></duet-input>
<duet-input label="Last name" expand></duet-input>
<duet-spacer></duet-spacer>
<duet-button margin="none" variation="primary" class="next">Next</duet-button>
</duet-step>

<duet-step heading="Favourite food">
<duet-radio-group responsive label="Choose" direction="vertical" value="pizza" name="group1">
<duet-radio value="pizza" label="Pizza"></duet-radio>
<duet-radio value="burger" label="Burger"></duet-radio>
<duet-radio value="salad" label="Salad"></duet-radio>
</duet-radio-group>
<duet-button margin="none" variation="primary" class="next">Next</duet-button>
</duet-step>

<duet-step heading="Final step">
<duet-textarea
expand
label="Write something about yourself"
placeholder="Placeholder text"
debounce="500"
>
</duet-textarea>
</duet-step>
</duet-stepper>

<script>
var stepper = document.querySelector("duet-stepper")
var nextButtons = document.querySelectorAll("duet-button.next")

nextButtons.forEach(function(button) {
button.addEventListener("click", function() {
stepper.selected++
})
})

stepper.addEventListener("duetStepChange", function(e) {
stepper.selected = e.detail.toStep
})
</script>
Open in new window
<duet-stepper>
<duet-step heading="First step">
<duet-input label="First name" expand></duet-input>
<duet-input label="Last name" expand></duet-input>
<duet-spacer></duet-spacer>
<duet-button margin="none" variation="primary" class="next">Next</duet-button>
</duet-step>

<duet-step heading="Second step">
<duet-paragraph>Try un-checking the checkbox below. If it is unchecked, you will be prevented from navigating to the first step when you click on its heading.</duet-paragraph>
<duet-checkbox checked label="Allow navigating backwards"></duet-checkbox>
</duet-step>
</duet-stepper>

<script>
var stepper = document.querySelector("duet-stepper")
var nextButton = document.querySelector("duet-button.next")

nextButton.addEventListener("click", function() {
stepper.selected++
})

// This is purely for the purpose of this example.
var checkbox = document.querySelector("duet-checkbox")

stepper.addEventListener("duetStepChange", function(e) {
// Only allow navigation if checkbox is unchecked.
// You could use whatever condition/logic you like in a real world usage
if(checkbox.checked) {
stepper.selected = e.detail.toStep
}
else {
alert("Cannot navigate while checkbox is unchecked!");
}
});
</script>
Open in new window
<duet-stepper>
<duet-step heading="Your name">
<duet-input label="First and last name" expand></duet-input>
<duet-spacer></duet-spacer>
<duet-button margin="none" variation="primary" class="next">Next</duet-button>
</duet-step>
<duet-step heading="Favourite food">
<duet-radio-group responsive label="Choose" direction="vertical" value="pizza" name="group1">
<duet-radio value="pizza" label="Pizza"></duet-radio>
<duet-radio value="burger" label="Burger"></duet-radio>
<duet-radio value="salad" label="Salad"></duet-radio>
</duet-radio-group>
<duet-button margin="none" variation="primary" class="next">Next</duet-button>
</duet-step>
<duet-step heading="Final step">
<duet-textarea
expand
label="Write something about yourself"
placeholder="Placeholder text"
debounce="500"
>
</duet-textarea>
</duet-step>
</duet-stepper>

<div class="duet-shadow-card duet-p-large duet-mb-large duet-radius-default">
<duet-grid alignment="center">
<duet-grid-item margin="none">
<div class="custom-icon duet-background-gray-darker duet-radius-circle">
<duet-icon name="messaging-checked-file" color="gray-lightest" margin="none" size="auto"></duet-icon>
</div>
</duet-grid-item>
<duet-grid-item margin="none" class="custom-grid-item">
<duet-heading margin="none" level="h4" color="gray-darker">
Additional custom step
</duet-heading>
</duet-grid-item>
</duet-grid>
</div>

<style>
/* If you need to support IE11 use Sass tokens instead of CSS Variables */
.custom-grid-item {
align-self: center;
}
.custom-icon {
display: flex;
align-items: center;
justify-content: center;
margin-right: var(--space-small);
width: var(--size-step-small);
height: var(--size-step-small);
}
.custom-icon duet-icon {
width: var(--size-icon-x-small);
height: var(--size-icon-x-small);
}
@media (min-width: 36em) {
.custom-icon {
margin-right: var(--space-large);
margin-left: var(--space-x-small);
width: var(--size-step-medium);
height: var(--size-step-medium);
}
.custom-icon duet-icon {
width: var(--size-icon-small);
height: var(--size-icon-small);
}
}
</style>

<script>
var stepper = document.querySelector("duet-stepper")
var nextButtons = document.querySelectorAll("duet-button.next")

// when "next" button is clicked, advance to next step
nextButtons.forEach(function(button) {
button.addEventListener("click", function() {
stepper.selected++
})
})

// duetStepChange event is raised whenever a step heading is clicked
// when this happens, change to that step
stepper.addEventListener("duetStepChange", function(e) {
stepper.selected = e.detail.toStep
console.log("step change:", "from", e.detail.fromStep, "to", e.detail.toStep)
})
</script>

Properties #

Property Attribute Description Type Default
accessibleLive accessible-live Format of message used to announce current step when navigating between steps. The string {current} is replaced with current the step number. The string {total} is replaced with the total number of steps. string "Lista jossa {total} kohtaa. Olet kohdassa {current}."
margin margin Controls the margin of the component. "auto" | "none" "auto"
selected selected The index of the current step. number 0
theme theme Theme of the component. "" | "default" | "turva" ""

Events #

Event Description Type
duetStepChange Event emitted when the current step is changed. Can be cancelled to prevent the change. CustomEvent<{ component: "duet-stepper"; fromStep: number; toStep: number; }>

Dependencies #

Depends on #

Graph #

graph TD;
duet-stepper --> duet-visually-hidden
style duet-stepper fill:#f9f,stroke:#333,stroke-width:4px

Integration

For integration, event and theming guidelines, please see Using Components. This documentation explains how to implement and use Duet’s components across different technologies like Angular, React or Vanilla JavaScript.



Tutorials

Follow these practical tutorials to learn how to build simple page layouts using Duet’s CSS Framework, Web Components and other features:

Tutorials

Abstract

Tutorials

Building Layouts

Tutorials

Using CLI Tools

Tutorials

Creating Custom Patterns

Tutorials

Server Side Rendering

Tutorials

Sharing Prototypes

Tutorials

Usage With Markdown

Tutorials

VS Code

Tutorials

Zeplin


Troubleshooting

If you experience any issues while using a component, please head over to the Support page for more guidelines and help.