Onboarding Stepper
Navigation @bhaskar Stars:0 Views:0
"use client";
const css = `
.st-list{position:relative;display:grid;margin:0;padding:0;list-style:none;font:13px/1.4 system-ui,sans-serif}
.st-list::before,.st-list::after{content:"";position:absolute;top:15px;height:2px;background:#d8deeb}
.st-list::after{background:#1659f5;transition:width .45s cubic-bezier(.2,.8,.2,1)}
.st-list li{position:relative;z-index:1;display:grid;justify-items:center;gap:6px;color:#5c627c;text-align:center}
.st-dot{width:32px;height:32px;border-radius:50%;display:grid;place-items:center;font-weight:700;background:#fff;border:2px solid #d8deeb;transition:all .3s}
.st-list li.done .st-dot{background:#1659f5;border-color:#1659f5;color:#fff}
.st-list li[aria-current=step]{color:#0b1020;font-weight:600}
.st-list li[aria-current=step] .st-dot{border-color:#1659f5;color:#1659f5;box-shadow:0 0 0 4px rgba(22,89,245,.18)}
@media (prefers-reduced-motion:reduce){.st-list::after,.st-dot{transition:none}}`;
export function OnboardingStepper({ steps, current }: { steps: string[]; current: number }) {
const n = steps.length;
const edge = 50 / n;
const track = 100 - edge * 2;
const progress = n > 1 ? current / (n - 1) : 1;
const dynamic = `.st-list::before,.st-list::after{left:${edge}%}.st-list::before{width:${track}%}.st-list::after{width:${track * progress}%}`;
return (
<>
<style>{css + dynamic}</style>
<ol className="st-list" style={{ gridTemplateColumns: `repeat(${n}, 1fr)` }}>
{steps.map((label, i) => {
const done = i < current || (current === n - 1 && i === current);
return (
<li key={label} className={done ? "done" : undefined} aria-current={i === current ? "step" : undefined}>
<span className="st-dot">{done ? "✓" : i + 1}</span>
{label}
</li>
);
})}
</ol>
</>
);
}