# Steps `lion-steps` breaks a single goal down into dependable sub-tasks. ```js script import { html } from 'lit-html'; import './lion-step.js'; import './lion-steps.js'; export default { title: 'Navigation/Steps', }; ``` ## Features - navigate between different steps with 'previous' and 'next' functions. - keeps status of each step - untouched - entered - left - skipped - options - **initial-step**: Set to the first step of the flow, blocks calling `previous` function. - **condition**: Dynamic condition, when true the step is added to the flow. - **invert-condition**: Inverts the condition set. In many application you build multi-step workflows like multi-step forms where you want to split a long process into smaller steps making easier user's perception of it and making easier filling in data. The idea of this component is to provide a simple way to define such steps and transition from one to another while saving data between them and conditionally skip some steps based on the data. ## How to use ### Installation ```bash npm i --save @lion/steps ``` ```js import { LionSteps, LionStep } from '@lion/steps'; // or import '@lion/steps/lion-steps.js'; import '@lion/steps/lion-step.js'; ``` ### Example ```js story export const main = () => html`

Welcome

  ev.target.parentElement.controller.next()} />

Are you single?

{ ev.target.parentElement.controller.data.isSingle = true; ev.target.parentElement.controller.next(); }} />   { ev.target.parentElement.controller.data.isSingle = false; ev.target.parentElement.controller.next(); }} />

ev.target.parentElement.controller.previous()} />

You are single

ev.target.parentElement.controller.previous()} />   ev.target.parentElement.controller.next()} />

You are NOT single.

ev.target.parentElement.controller.previous()} />   ev.target.parentElement.controller.next()} />

Finish

ev.target.parentElement.controller.previous()} />
`; ``` ### Define steps We provide two components: `lion-steps` and `lion-step`. Steps need to be direct children of `lion-steps`. ```js preview-story export const defineSteps = () => html` Step 1 Step 2 ...... Step N `; ``` The first step needs to be explicitely set via `initial-step` so that it get status `entered`, while others are `untouched` by default. You can navigate between steps using `next()` and `previous()` methods, so that next step gets `entered` status, while previous one becomes `left`: ```js next() { return this.shadowRoot.getElementById('steps').next(); } previous() { return this.shadowRoot.getElementById('steps').previous(); } ``` ### Conditions You can provide a condition to a step (with or without `invert-condition` emulating if-else flow): ```html ... step where `data.smth` is set if else ... ``` If a condition was not met a step gets a status `skipped`. ### Forward only steps If you have an intermediate step loading data via AJAX request and then automatically calling `next()`, you can flag it as `forward-only`. This will ensure that navigation to previous step is possible and does not lead to another AJAX request which leads to next step again breaking flow for a user. ```html preliminary step data is loaded and next() is called automatically afterwards do smth with data ``` ### Events If you need to be notified when transition between steps happens use `transition` event providing steps data: ```html Step 1 Step 2 Step 3 ``` For notifications about specific step status change you can use individual events like this: ```html Step 1 Step 2 Step 3 ```