Stepper Component with RiotJS (Material Design)

Stepper Component with RiotJS (Material Design)

This article covers creating a Riot Stepper component, using the Material Design CSS BeerCSS, and change the step when a button is clicked.

Before starting, make sure you have a base application running, or read my previous article Setup Riot + BeerCSS + Vite.

These articles form a series focusing on RiotJS paired with BeerCSS, designed to guide you through creating components and mastering best practices for building production-ready applications. I assume you have a foundational understanding of Riot; however, feel free to refer to the documentation if needed: https://riot.js.org/documentation/

Steppers display progress through a multi-step process. Users intuitively know where they are in the process and how many steps remain, for instance, a checkout flow, login, or a form.

Stepper Component Base

The goal is to create a Riot app with a Stepper that shows a progression when a button is clicked and prints the corresponding page.

Open the index.riot file at the root of your Vite project, then add the following code. The HTML comes from the BeerCSS documentation and I added RiotJS syntax for the logic:

<index-riot>
<div style=“width:800px;padding:20px;”>
<nav class=“scroll”>
<button class=“circle small” onclick={ () => changeStep(1)}>
<template if={ state.active === 1 }>1</template>
<i if={ state.active > 1}>done</i>
</button>
<div class=“max divider”></div>
<button class=“circle small” disabled={ state.active < 2 } onclick={ () => changeStep(2)}>
<template if={ state.active <= 2 }>2</template>
<i if={ state.active > 2}>done</i>
</button>
<div class=“max divider”></div>
<button class=“circle small” disabled={ state.active < 3 } onclick={ () => changeStep(3)}>
<template if={ state.active <= 3 }>3</template>
<i if={ state.active > 3}>done</i>
</button>
</nav>
<br>
<div class=“page padding { state.active === 1 ? ‘active’ : null}” if={ state.active === 1 }>
<h5>Page { state.active }</h5><br>
<button onclick={ () => { changeStep(2) }}>Next</button>
</div>
<div class=“page padding { state.active === 2 ? ‘active’ : null}” if={ state.active === 2 }>
<h5>Page { state.active }</h5><br>
<button onclick={ () => { changeStep(3) }}>Next</button>
</div>
<div class=“page padding { state.active === 3 ? ‘active’ : null}” if={ state.active === 3 }>
<h5>Page { state.active }</h5><br>
<button onclick={ () => { changeStep(4) }}>Next</button>
</div>
<div class=“page padding { state.active === 4 ? ‘active’ : null}” if={ state.active === 4 }>
<h5>Done!</h5>
</div>
</div>
<script>
export default {
state: {
active: 1,
},
changeStep(value) {
this.update({
active: value
})
}
}
</script>
</index-riot>

Source Code: https://github.com/steevepay/riot-beercss/blob/main/examples/index.stepper.riot

Let’s break down the code:

The Stepper is made of Buttons and Dividers, the state of a step is defined by:

Completed: when the checked icon is displayed and the number is hidden with <template if={ state.active === 1 }>1</template>.

Completing: when the number is displayed and the checked icon is hidden with <i if={ state.active > 1}>done</i>.

Next Step upcoming: when the button is disabled with the condition disabled={ state.active < 2 }

The state of the Stepper is stored into a state:{} Riot Object under the state.active value.
The state.active will print pages 1, 2 or 3 with the expression <div class=”page padding” if={ state.active === 1 }>.
If one of the step buttons is clicked, it will directly update state.active with the selected step number: The function changeStep is fired when the event “Click” is caught, such as: onclick={ () => changeStep(1)}. Changing the step can be used to request an API and then load a specific page.

Stepper Component Testing

It exists two methods for testing the Stepper component, and it is covered in two different articles:

Test with Vitest and Riot-SSR in a Node Environment
Test with Vitest in a JsDom Environment

Conclusion

Voilà 🎉 We made a Stepper Riot Component using Material Design elements with BeerCSS.

Feel free to comment if you have questions or need help with RiotJS.

Have a great day! Cheers 🍻

Leave a Reply

Your email address will not be published. Required fields are marked *