Navigation navigationbreadcrumbstepsworkflowwizard
Step Breadcrumb Bar
Multi-step workflow progress breadcrumb indicating completed, current, and upcoming stages.
Preview
Usage
Copy the full block below to use this component with its imports.
astro
---
import { StepBreadcrumbBar } from 'astro-component-kit';
---
<StepBreadcrumbBar steps={[{ label: 'Cart', status: 'completed' }, { label: 'Shipping', status: 'current' }, { label: 'Payment', status: 'upcoming' }]} /> ---
import { StepBreadcrumbBar } from 'astro-component-kit';
---
<StepBreadcrumbBar steps={[{ label: 'Cart', status: 'completed' }, { label: 'Shipping', status: 'current' }, { label: 'Payment', status: 'upcoming' }]} /> Manual Installation
If you are not using the npm package, create a new file src/components/lib/StepBreadcrumbBar.astro and paste the following code:
astro
---
/**
* StepBreadcrumbBar — Stepped workflow breadcrumb indicator for checkout, multi-step forms, or wizards.
*
* @param {Array<{step: number, label: string, status: 'complete' | 'active' | 'upcoming', href?: string}>} steps - Step definitions.
*/
interface Props {
steps?: Array<{
step: number;
label: string;
status: 'complete' | 'active' | 'upcoming';
href?: string;
}>;
}
const {
steps = [
{ step: 1, label: 'Account', status: 'complete', href: '#step-1' },
{ step: 2, label: 'Plan & Billing', status: 'active', href: '#step-2' },
{ step: 3, label: 'Preferences', status: 'upcoming', href: '#step-3' },
{ step: 4, label: 'Review', status: 'upcoming', href: '#step-4' },
],
} = Astro.props;
---
<nav class="step-nav" aria-label="Workflow progress">
<ol class="step-nav__list">
{steps.map((st, i) => (
<li class:list={['step-nav__item', `step-nav__item--${st.status}`]}>
<a href={st.href || '#'} class="step-nav__link" aria-current={st.status === 'active' ? 'step' : undefined}>
<span class="step-nav__circle">
{st.status === 'complete' ? (
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12" />
</svg>
) : (
st.step
)}
</span>
<span class="step-nav__label">{st.label}</span>
</a>
{i < steps.length - 1 && (
<div class="step-nav__line" aria-hidden="true"></div>
)}
</li>
))}
</ol>
</nav>
<style>
.step-nav {
width: 100%;
max-width: 680px;
font-family: var(--font-sans, system-ui, sans-serif);
}
.step-nav__list {
display: flex;
align-items: center;
list-style: none;
padding: 0;
margin: 0;
width: 100%;
}
.step-nav__item {
display: flex;
align-items: center;
flex: 1;
position: relative;
}
.step-nav__item:last-child {
flex: 0 0 auto;
}
.step-nav__link {
display: inline-flex;
align-items: center;
gap: 10px;
text-decoration: none;
color: var(--c-text-3, #737373);
font-size: 0.82rem;
font-weight: 600;
white-space: nowrap;
transition: color 0.2s ease;
}
.step-nav__link:hover {
color: var(--c-text-1, #ffffff);
}
.step-nav__circle {
display: grid;
place-items: center;
width: 28px;
height: 28px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.15);
color: var(--c-text-2, #a3a3a3);
font-size: 0.78rem;
font-weight: 700;
flex-shrink: 0;
transition: all 0.25s ease;
}
/* Status modifiers */
.step-nav__item--complete .step-nav__circle {
background: rgba(16, 185, 129, 0.15);
border-color: #10b981;
color: #10b981;
}
.step-nav__item--complete .step-nav__label {
color: var(--c-text-1, #ffffff);
}
.step-nav__item--active .step-nav__circle {
background: linear-gradient(135deg, #d4a017, #b8860b);
border-color: #d4a017;
color: #050505;
box-shadow: 0 0 12px rgba(212, 160, 23, 0.4);
}
.step-nav__item--active .step-nav__label {
color: var(--c-primary-light, #d4a017);
font-weight: 700;
}
.step-nav__line {
flex: 1;
height: 2px;
background: rgba(255, 255, 255, 0.08);
margin: 0 12px;
}
.step-nav__item--complete .step-nav__line {
background: #10b981;
opacity: 0.5;
}
@media (max-width: 640px) {
.step-nav__label {
display: none;
}
.step-nav__line {
margin: 0 6px;
}
}
</style> ---
/**
* StepBreadcrumbBar — Stepped workflow breadcrumb indicator for checkout, multi-step forms, or wizards.
*
* @param {Array<{step: number, label: string, status: 'complete' | 'active' | 'upcoming', href?: string}>} steps - Step definitions.
*/
interface Props {
steps?: Array<{
step: number;
label: string;
status: 'complete' | 'active' | 'upcoming';
href?: string;
}>;
}
const {
steps = [
{ step: 1, label: 'Account', status: 'complete', href: '#step-1' },
{ step: 2, label: 'Plan & Billing', status: 'active', href: '#step-2' },
{ step: 3, label: 'Preferences', status: 'upcoming', href: '#step-3' },
{ step: 4, label: 'Review', status: 'upcoming', href: '#step-4' },
],
} = Astro.props;
---
<nav class="step-nav" aria-label="Workflow progress">
<ol class="step-nav__list">
{steps.map((st, i) => (
<li class:list={['step-nav__item', `step-nav__item--${st.status}`]}>
<a href={st.href || '#'} class="step-nav__link" aria-current={st.status === 'active' ? 'step' : undefined}>
<span class="step-nav__circle">
{st.status === 'complete' ? (
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12" />
</svg>
) : (
st.step
)}
</span>
<span class="step-nav__label">{st.label}</span>
</a>
{i < steps.length - 1 && (
<div class="step-nav__line" aria-hidden="true"></div>
)}
</li>
))}
</ol>
</nav>
<style>
.step-nav {
width: 100%;
max-width: 680px;
font-family: var(--font-sans, system-ui, sans-serif);
}
.step-nav__list {
display: flex;
align-items: center;
list-style: none;
padding: 0;
margin: 0;
width: 100%;
}
.step-nav__item {
display: flex;
align-items: center;
flex: 1;
position: relative;
}
.step-nav__item:last-child {
flex: 0 0 auto;
}
.step-nav__link {
display: inline-flex;
align-items: center;
gap: 10px;
text-decoration: none;
color: var(--c-text-3, #737373);
font-size: 0.82rem;
font-weight: 600;
white-space: nowrap;
transition: color 0.2s ease;
}
.step-nav__link:hover {
color: var(--c-text-1, #ffffff);
}
.step-nav__circle {
display: grid;
place-items: center;
width: 28px;
height: 28px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.15);
color: var(--c-text-2, #a3a3a3);
font-size: 0.78rem;
font-weight: 700;
flex-shrink: 0;
transition: all 0.25s ease;
}
/* Status modifiers */
.step-nav__item--complete .step-nav__circle {
background: rgba(16, 185, 129, 0.15);
border-color: #10b981;
color: #10b981;
}
.step-nav__item--complete .step-nav__label {
color: var(--c-text-1, #ffffff);
}
.step-nav__item--active .step-nav__circle {
background: linear-gradient(135deg, #d4a017, #b8860b);
border-color: #d4a017;
color: #050505;
box-shadow: 0 0 12px rgba(212, 160, 23, 0.4);
}
.step-nav__item--active .step-nav__label {
color: var(--c-primary-light, #d4a017);
font-weight: 700;
}
.step-nav__line {
flex: 1;
height: 2px;
background: rgba(255, 255, 255, 0.08);
margin: 0 12px;
}
.step-nav__item--complete .step-nav__line {
background: #10b981;
opacity: 0.5;
}
@media (max-width: 640px) {
.step-nav__label {
display: none;
}
.step-nav__line {
margin: 0 6px;
}
}
</style>
Quick Info
- Category
- Navigation
- Filename
StepBreadcrumbBar.astro- Dependencies
- None — pure Astro + CSS
- Tags
- navigationbreadcrumbstepsworkflowwizard