Something went wrong. Try again.
Client side atproto account migrator in your web browser, along with services for backups and adversarial migrations. pdsmoover.com
pds atproto migrations moo cow
Something went wrong. Try again.
1.7 kB · 39 lines
Svelte
at oauth
12345678910111213141516171819202122232425262728293031323334353637383940<script lang="ts" generics="T extends number"> // Shared wizard progress indicator: numbered pill buttons joined by arrows. The current step // is highlighted, completed steps are clickable via onselect, and later steps are locked // (disabled). Whether a jump is actually allowed stays the parent's decision in onselect. interface StepDef { n: T; label: string; }
type Props = { steps: StepDef[]; /** The step the wizard is currently on */ step: T; /** Called when a completed step's pill is clicked */ onselect: (n: T) => void; };
let {steps, step, onselect}: Props = $props();</script>
<ol class="mt-7.5 flex flex-wrap items-center justify-center gap-x-2 gap-y-2 text-[0.8em]"> {#each steps as s, i (s.n)} <li class="flex items-center gap-2"> <button type="button" class="flex items-center gap-1.5 rounded-full border px-2.5 py-1 transition-colors {s.n === step ? 'border-accent bg-accent-soft font-semibold' : 'border-[rgba(128,128,128,0.4)]'} {s.n < step ? 'cursor-pointer' : 'cursor-default'}" disabled={s.n >= step} aria-current={s.n === step ? 'step' : undefined} onclick={() => onselect(s.n)}> <span class="flex h-5 w-5 items-center justify-center rounded-full border border-current text-[0.75em] font-bold">{s.n}</span> {s.label} </button> {#if i < steps.length - 1} <span class="text-muted" aria-hidden="true">→</span> {/if} </li> {/each}</ol>