feat(machine): add BounceDots and StepIndicator components

BounceDots: three animated dots replacing Skeleton shimmer loaders.
StepIndicator: dot-line-dot progress with active/complete states,
split into separate dots and labels rows for proper alignment.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Patrick Mulligan 2026-03-01 12:10:14 -05:00
commit acb4a8ccaf
2 changed files with 59 additions and 0 deletions

View file

@ -0,0 +1,19 @@
<script setup lang="ts">
defineProps<{
class?: string
}>()
</script>
<template>
<div :class="['flex items-center justify-center gap-3', $props.class]">
<div
class="h-4 w-4 rounded-full bg-primary animate-dot-bounce"
style="animation-delay: -0.32s"
/>
<div
class="h-4 w-4 rounded-full bg-primary animate-dot-bounce"
style="animation-delay: -0.16s"
/>
<div class="h-4 w-4 rounded-full bg-primary animate-dot-bounce" />
</div>
</template>

View file

@ -0,0 +1,40 @@
<script setup lang="ts">
defineProps<{
steps: string[]
currentStep: number
}>()
</script>
<template>
<div class="flex flex-col items-center gap-1">
<!-- Dots and lines row -->
<div class="flex items-center">
<template v-for="(step, i) in steps" :key="step">
<div
v-if="i > 0"
class="step-indicator__line"
:class="{ 'step-indicator__line--complete': i <= currentStep }"
/>
<div
class="step-indicator__dot"
:class="{
'step-indicator__dot--active': i === currentStep,
'step-indicator__dot--complete': i < currentStep,
}"
/>
</template>
</div>
<!-- Labels row -->
<div class="flex">
<template v-for="(step, i) in steps" :key="step">
<div v-if="i > 0" class="w-[60px]" />
<span
class="w-[14px] text-center text-xs"
:class="i === currentStep ? 'text-primary font-medium' : 'text-muted-foreground'"
>
{{ step }}
</span>
</template>
</div>
</div>
</template>