Feedback stepperworkflow
Step Tracker
Multi-stage progress tracker.
Preview
1
Details 2
Payment 3
Finish Usage
Copy the full block below to use this component with its imports.
astro
---
import { StepTracker } from 'astro-component-kit';
---
<StepProgress activeIndex={1} steps={[{label: "Step 1"}, {label: "Step 2"}, {label: "Step 3"}]} /> ---
import { StepTracker } from 'astro-component-kit';
---
<StepProgress activeIndex={1} steps={[{label: "Step 1"}, {label: "Step 2"}, {label: "Step 3"}]} /> Manual Installation
If you are not using the npm package, create a new file src/components/lib/StepTracker.astro and paste the following code:
astro
---
/**
* StepProgress — A multi-stage stepper indicating flow through several discrete points.
*
* @param {Array<{label: string}>} steps - List of steps to represent.
* @param {number} activeIndex - The index (0-based) of the current step. Default is 0.
*/
interface Props {
steps?: Array<{ label: string }>;
activeIndex?: number;
}
const {
steps = [
{ label: 'Details' },
{ label: 'Payment' },
{ label: 'Finish' }
],
activeIndex = 0
} = Astro.props;
---
<div class="steps-container">
<div class="steps-line" aria-hidden="true" style={`--progress: ${(activeIndex / (steps.length - 1)) * 100}%`}></div>
<div class="steps-list">
{steps.map((step, i) => (
<div
class:list={['step-item', { 'step-item--active': i === activeIndex, 'step-item--complete': i < activeIndex }]}
aria-current={i === activeIndex ? "step" : undefined}
>
<div class="step-circle">{i + 1}</div>
<span class="step-label">{step.label}</span>
</div>
))}
</div>
</div>
<style>
.steps-container { position: relative; margin-bottom: var(--sp-8, 2rem); width: 100%; padding: 0 var(--sp-4, 1rem); box-sizing: border-box; }
.steps-line {
position: absolute;
top: 16px; left: 0; right: 0;
height: 3px;
background: var(--c-bg-elev, rgba(255,255,255,0.05));
z-index: 0;
}
.steps-line::after {
content: "";
position: absolute;
left: 0; top: 0;
height: 100%;
width: var(--progress);
background: var(--c-primary, #6366f1);
transition: width 0.4s ease-in-out;
box-shadow: 0 0 10px rgba(99,102,241,0.3);
}
.steps-list { display: flex; justify-content: space-between; position: relative; z-index: 1; }
.step-circle {
width: 32px; height: 32px;
border-radius: var(--r-full, 50%);
background: var(--c-bg, #1e293b);
color: var(--c-text-2, #64748b);
border: 2px solid var(--c-border, rgba(255,255,255,0.1));
display: grid; place-items: center;
font-size: 0.85rem; font-weight: 800;
transition: 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.step-item--active .step-circle {
background: var(--c-primary, #6366f1);
border-color: var(--c-primary, #6366f1);
color: #fff;
box-shadow: 0 0 20px rgba(99,102,241,0.5);
transform: scale(1.1);
}
.step-item--complete .step-circle {
background: var(--c-primary, #6366f1);
border-color: var(--c-primary, #6366f1);
color: #fff;
}
.step-label {
position: absolute;
top: 100%; left: 50%;
transform: translateX(-50%);
margin-top: 8px;
font-size: 0.7rem;
font-weight: 700;
white-space: nowrap;
color: var(--c-text-2, #64748b);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.step-item--active .step-label, .step-item--complete .step-label { color: var(--c-text-1, #fff); }
</style> ---
/**
* StepProgress — A multi-stage stepper indicating flow through several discrete points.
*
* @param {Array<{label: string}>} steps - List of steps to represent.
* @param {number} activeIndex - The index (0-based) of the current step. Default is 0.
*/
interface Props {
steps?: Array<{ label: string }>;
activeIndex?: number;
}
const {
steps = [
{ label: 'Details' },
{ label: 'Payment' },
{ label: 'Finish' }
],
activeIndex = 0
} = Astro.props;
---
<div class="steps-container">
<div class="steps-line" aria-hidden="true" style={`--progress: ${(activeIndex / (steps.length - 1)) * 100}%`}></div>
<div class="steps-list">
{steps.map((step, i) => (
<div
class:list={['step-item', { 'step-item--active': i === activeIndex, 'step-item--complete': i < activeIndex }]}
aria-current={i === activeIndex ? "step" : undefined}
>
<div class="step-circle">{i + 1}</div>
<span class="step-label">{step.label}</span>
</div>
))}
</div>
</div>
<style>
.steps-container { position: relative; margin-bottom: var(--sp-8, 2rem); width: 100%; padding: 0 var(--sp-4, 1rem); box-sizing: border-box; }
.steps-line {
position: absolute;
top: 16px; left: 0; right: 0;
height: 3px;
background: var(--c-bg-elev, rgba(255,255,255,0.05));
z-index: 0;
}
.steps-line::after {
content: "";
position: absolute;
left: 0; top: 0;
height: 100%;
width: var(--progress);
background: var(--c-primary, #6366f1);
transition: width 0.4s ease-in-out;
box-shadow: 0 0 10px rgba(99,102,241,0.3);
}
.steps-list { display: flex; justify-content: space-between; position: relative; z-index: 1; }
.step-circle {
width: 32px; height: 32px;
border-radius: var(--r-full, 50%);
background: var(--c-bg, #1e293b);
color: var(--c-text-2, #64748b);
border: 2px solid var(--c-border, rgba(255,255,255,0.1));
display: grid; place-items: center;
font-size: 0.85rem; font-weight: 800;
transition: 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.step-item--active .step-circle {
background: var(--c-primary, #6366f1);
border-color: var(--c-primary, #6366f1);
color: #fff;
box-shadow: 0 0 20px rgba(99,102,241,0.5);
transform: scale(1.1);
}
.step-item--complete .step-circle {
background: var(--c-primary, #6366f1);
border-color: var(--c-primary, #6366f1);
color: #fff;
}
.step-label {
position: absolute;
top: 100%; left: 50%;
transform: translateX(-50%);
margin-top: 8px;
font-size: 0.7rem;
font-weight: 700;
white-space: nowrap;
color: var(--c-text-2, #64748b);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.step-item--active .step-label, .step-item--complete .step-label { color: var(--c-text-1, #fff); }
</style>
Quick Info
- Category
- Feedback
- Filename
StepTracker.astro- Dependencies
- None — pure Astro + CSS
- Tags
- stepperworkflow