Skip to content
Magma Design System
Stepper bar<mds-stepper-bar>Generated from @maggioli-design-system/magma@2.3.0dist/documentation.json. Encapsulation: shadow.
Common incorrect uses of <mds-stepper-bar>. Each entry pairs the wrong form with the right one and a one-line reason. System-wide rules (boolean-as-string, shadow piercing, Tailwind color utilities, raw native event listening) live in agents/anti-patterns.md - they apply here too but are not repeated.
Do Not Mutate Child State Directly
done and current on <mds-stepper-bar-item> are managed exclusively by the parent; writing them from outside bypasses the synchronization logic and breaks content panel visibility, scroll centering, and the mdsStepperBarChange event. Drive progress through items-done on the parent instead.
<!-- INCORRECT -->
<mds-stepper-bar>
<mds-stepper-bar-item done icon="mi/baseline/person" icon-checked="mi/baseline/done" label="Account"></mds-stepper-bar-item>
<mds-stepper-bar-item current icon="mi/baseline/badge" icon-checked="mi/baseline/done" label="Profilo"></mds-stepper-bar-item>
</mds-stepper-bar>
<!-- CORRECT -->
<mds-stepper-bar items-done="2">
<mds-stepper-bar-item icon="mi/baseline/person" icon-checked="mi/baseline/done" label="Account"></mds-stepper-bar-item>
<mds-stepper-bar-item icon="mi/baseline/badge" icon-checked="mi/baseline/done" label="Profilo"></mds-stepper-bar-item>
</mds-stepper-bar>
Do Not Listen for Native change Events
<mds-stepper-bar> emits mdsStepperBarChange - not a native change event. Native DOM events do not bubble out of shadow DOM reliably, so listening for change will silently never fire.
<!-- INCORRECT -->
<mds-stepper-bar id="stepper" items-done="1">...</mds-stepper-bar>
<script>
document.getElementById('stepper').addEventListener('change', handler);
</script>
<!-- CORRECT -->
<mds-stepper-bar id="stepper" items-done="1">...</mds-stepper-bar>
<script>
document.getElementById('stepper').addEventListener('mdsStepperBarChange', handler);
</script>
Do Not Use <mds-stepper-bar-item> Outside <mds-stepper-bar>
<mds-stepper-bar-item> is a compound child; it relies on the parent to receive its done/current state. Outside the parent it renders without state management and will not advance any stepper.
<!-- INCORRECT -->
<div class="custom-steps">
<mds-stepper-bar-item icon="mi/baseline/person" icon-checked="mi/baseline/done" label="Account"></mds-stepper-bar-item>
<mds-stepper-bar-item icon="mi/baseline/badge" icon-checked="mi/baseline/done" label="Profilo"></mds-stepper-bar-item>
</div>
<!-- CORRECT -->
<mds-stepper-bar items-done="1">
<mds-stepper-bar-item icon="mi/baseline/person" icon-checked="mi/baseline/done" label="Account"></mds-stepper-bar-item>
<mds-stepper-bar-item icon="mi/baseline/badge" icon-checked="mi/baseline/done" label="Profilo"></mds-stepper-bar-item>
</mds-stepper-bar>
Do Not Wrap Items in Extra Elements
The indicator track lays out its direct slot children (flex row, --mds-stepper-bar-gap, scroll snapping): a wrapper becomes a single item of the track, so the steps lose that layout. Compound children must be direct children of the parent.
<!-- INCORRECT -->
<mds-stepper-bar items-done="1">
<div class="step-group">
<mds-stepper-bar-item icon="mi/baseline/person" icon-checked="mi/baseline/done" label="Account"></mds-stepper-bar-item>
<mds-stepper-bar-item icon="mi/baseline/badge" icon-checked="mi/baseline/done" label="Profilo"></mds-stepper-bar-item>
</div>
</mds-stepper-bar>
<!-- CORRECT -->
<mds-stepper-bar items-done="1">
<mds-stepper-bar-item icon="mi/baseline/person" icon-checked="mi/baseline/done" label="Account"></mds-stepper-bar-item>
<mds-stepper-bar-item icon="mi/baseline/badge" icon-checked="mi/baseline/done" label="Profilo"></mds-stepper-bar-item>
</mds-stepper-bar>
Do Not Supply Fewer slot="content" Panels than Items
The component pairs panels to items by index position; if a panel is missing for a given index, the content region for that step will be empty with no warning. Always provide exactly one slot="content" element per <mds-stepper-bar-item>.
<!-- INCORRECT - three items, only two content panels -->
<mds-stepper-bar items-done="1">
<mds-stepper-bar-item icon="mi/baseline/person" icon-checked="mi/baseline/done" label="Account"></mds-stepper-bar-item>
<mds-stepper-bar-item icon="mi/baseline/badge" icon-checked="mi/baseline/done" label="Profilo"></mds-stepper-bar-item>
<mds-stepper-bar-item icon="mi/baseline/done" icon-checked="mi/baseline/done" label="Conferma"></mds-stepper-bar-item>
<div slot="content"><mds-text>Account</mds-text></div>
<div slot="content"><mds-text>Profilo</mds-text></div>
</mds-stepper-bar>
<!-- CORRECT - one panel per item -->
<mds-stepper-bar items-done="1">
<mds-stepper-bar-item icon="mi/baseline/person" icon-checked="mi/baseline/done" label="Account"></mds-stepper-bar-item>
<mds-stepper-bar-item icon="mi/baseline/badge" icon-checked="mi/baseline/done" label="Profilo"></mds-stepper-bar-item>
<mds-stepper-bar-item icon="mi/baseline/done" icon-checked="mi/baseline/done" label="Conferma"></mds-stepper-bar-item>
<div slot="content"><mds-text>Account</mds-text></div>
<div slot="content"><mds-text>Profilo</mds-text></div>
<div slot="content"><mds-text>Conferma</mds-text></div>
</mds-stepper-bar>
Do Not Set items-done as a Boolean
items-done is a number, not a flag. Setting it as a bare boolean attribute sends the string "", which parses to NaN: no step is marked current or done. Always pass a numeric value.
<!-- INCORRECT -->
<mds-stepper-bar items-done>...</mds-stepper-bar>
<!-- CORRECT -->
<mds-stepper-bar items-done="1">...</mds-stepper-bar>