Steps

Show the current position and progress in a multi-step task.

Live preview
Interact with the component to see results here.
View code
HTML
<sy-steps
  current="1"
  start-index="0"
  type="horizontal"
  size="medium"
  clickable
  id="sample"
>
  <sy-step description="Enter the basic information.">Enter information
  </sy-step>
  <sy-step description="Review the entered information.">Review</sy-step>
  <sy-step description="The task is complete.">Complete</sy-step>
</sy-steps>

<script type="module">
  await (root => {
    const steps = root.querySelector('sy-steps');
    steps.addEventListener('selected', event => {
      steps.current = event.detail.index;
    });
  })(document);
</script>

Usage guide

#

Show ordered workflows, such as applications or setup. Use Tabs for independent view switching.

  1. Set steps and the current position

    current is zero-based by default.

  2. Set the starting number and completion state

    Setting startIndex to 1 makes both step numbers and current start at 1. Apply complete when the whole process finishes.

  3. Handle navigation requests

    Enable clickable and read selected.detail.index. Validate the current step before changing current.

Examples

#

Task progress

Steps before the current step appear complete; later steps appear pending.

View code
HTML
<sy-steps current="1" id="sample">
  <sy-step description="Enter the basic information.">Enter information
  </sy-step>
  <sy-step description="Review the entered information.">Review</sy-step>
  <sy-step description="The task is complete.">Complete</sy-step>
</sy-steps>

<script type="module">
  await (root => {
    const steps = root.querySelector('sy-steps');
    steps.addEventListener('selected', event => {
      steps.current = event.detail.index;
    });
  })(document);
</script>

Step selection

Includes app code that updates current when a step is clicked or selected with the keyboard.

View code
HTML
<sy-steps
  current="0"
  clickable
  id="sample"
>
  <sy-step description="Enter the basic information.">Enter information
  </sy-step>
  <sy-step description="Review the entered information.">Review</sy-step>
  <sy-step description="The task is complete.">Complete</sy-step>
</sy-steps>

<script type="module">
  await (root => {
    const steps = root.querySelector('sy-steps');
    steps.addEventListener('selected', event => {
      steps.current = event.detail.index;
    });
  })(document);
</script>

Vertical layout

Use a vertical layout for long step descriptions or narrow areas.

View code
HTML
<sy-steps
  current="1"
  type="vertical"
  id="sample"
>
  <sy-step description="Enter the basic information.">Enter information
  </sy-step>
  <sy-step description="Review the entered information.">Review</sy-step>
  <sy-step description="The task is complete.">Complete</sy-step>
</sy-steps>

<script type="module">
  await (root => {
    const steps = root.querySelector('sy-steps');
    steps.addEventListener('selected', event => {
      steps.current = event.detail.index;
    });
  })(document);
</script>

Error and loading

Use each step's status and loading properties to show its state clearly.

View code
HTML
<div style="display:grid;gap:16px;width:100%">
  <sy-steps current="1">
    <sy-step description="Enter the basic information.">Enter information
    </sy-step>
    <sy-step description="Review the entered information." status="error">Review
    </sy-step>
    <sy-step description="The task is complete.">Complete</sy-step>
  </sy-steps>
  <sy-steps current="1" size="small">
    <sy-step description="Enter the basic information.">Enter information
    </sy-step>
    <sy-step description="Review the entered information." loading>Review
    </sy-step>
    <sy-step description="The task is complete.">Complete</sy-step>
  </sy-steps>
</div>

Completion and starting number

Set startIndex to 1 and show every step as complete.

View code
HTML
<sy-steps
  start-index="1"
  current="3"
  complete
  id="sample"
>
  <sy-step description="Enter the basic information.">Enter information
  </sy-step>
  <sy-step description="Review the entered information.">Review</sy-step>
  <sy-step description="The task is complete.">Complete</sy-step>
</sy-steps>

<script type="module">
  await (root => {
    const steps = root.querySelector('sy-steps');
    steps.addEventListener('selected', event => {
      steps.current = event.detail.index;
    });
  })(document);
</script>

Restrict navigation

Use disabled to prevent selection of a specific step.

View code
HTML
<sy-steps clickable id="sample">
  <sy-step description="Enter the basic information.">Enter information
  </sy-step>
  <sy-step description="Review the entered information." disabled>Review
  </sy-step>
  <sy-step description="The task is complete.">Complete</sy-step>
</sy-steps>

<script type="module">
  await (root => {
    const steps = root.querySelector('sy-steps');
    steps.addEventListener('selected', event => {
      steps.current = event.detail.index;
    });
  })(document);
</script>

Events and payloads

Interact with the component and inspect the latest event name and detail. The code includes subscriptions to events emitted by this component and its children.

View code
HTML
<sy-steps
  current="1"
  start-index="0"
  type="horizontal"
  size="medium"
  clickable
  id="sample"
>
  <sy-step description="Enter the basic information.">Enter information
  </sy-step>
  <sy-step description="Review the entered information.">Review</sy-step>
  <sy-step description="The task is complete.">Complete</sy-step>
</sy-steps>
<output id="demo-events" aria-live="polite">Interact with the component to see
  its latest event and payload.</output>

<script type="module">
  const describeResult = value => JSON.stringify(value, (_key, item) => {
    if (item instanceof File) return {
      name: item.name,
      size: item.size,
      type: item.type
    };
    if (item instanceof Element) return `<${item.localName}>`;
    return item;
  }) ?? 'Done';
  await (root => {
    const steps = root.querySelector('sy-steps');
    steps.addEventListener('selected', event => {
      steps.current = event.detail.index;
    });
  })(document);
  for (const name of ["selected"]) {
    document.addEventListener(name, event => {
      document.querySelector('#demo-events').textContent =
        `${event.target.localName} · ${name}: ${describeResult(event.detail)}`;
    });
  }
</script>

Number steps from one

Start the displayed step numbers at one and highlight the second step.

View code
HTML
<sy-steps
  current="2"
  start-index="1"
  type="horizontal"
  size="medium"
  clickable
  id="sample"
>
  <sy-step description="Enter the basic information.">Enter information
  </sy-step>
  <sy-step description="Review the entered information.">Review</sy-step>
  <sy-step description="The task is complete.">Complete</sy-step>
</sy-steps>

<script type="module">
  const component1 = document.querySelector("#sample");
  Object.assign(component1, {
    "startIndex": 1,
    "current": 2
  });
  await (root => {
    const steps = root.querySelector('sy-steps');
    steps.addEventListener('selected', event => {
      steps.current = event.detail.index;
    });
  })(document);
</script>

API reference

#

Hover over a name or focus it with the keyboard to see the code. On touch screens, tap the name.

<sy-steps>

Properties

Attribute / PropertyTypeDefaultDescription
number0Index of the current step.
booleanfalseAllow user selection and emit the selected event.
booleanfalseMark every step as complete.
"horizontal" | "vertical""horizontal"Arrange steps horizontally (horizontal) or vertically (vertical).
"small" | "medium""medium"Component size.
number0Starting step number.

Slots

SlotDescription
Component body or child items.

<sy-step>

Properties

Attribute / PropertyTypeDefaultDescription
string""Description shown below the step title.
booleanfalseBlock user interaction and keyboard focus.
booleanfalseIndicate that processing is in progress.
"finish" | "current" | "wait" | "error" | "none""none"none derives the state from the current index. Set an individual state with finish, current, wait, or error.
booleanfalseLegacy compatibility property. Use size="small" to change the size.
booleanfalseAllow user selection and emit the selected event.
number0Item index calculated by the parent.
number0Index of the current step.
"small" | "medium""medium"Component size.
"finish" | "current" | "wait" | "error" | "none""none"Completion state passed down by the parent Steps component.
"finish" | "current" | "wait" | "error" | "none""none"Displayed step state, calculated from status and current.
"horizontal" | "vertical""horizontal"Horizontal or vertical layout, passed down by the parent Steps component.
booleanfalseHide the connector after the last step. Set by the parent.

Events

EventDetailDescription
CustomEvent<{ index: number; step: HTMLSyStepElement }>Requested step. Assign its index to the parent current after app validation.

Slots

SlotDescription
Component body or child items.