shadcn.io is an independent project built on shadcn/ui
Three equal tabs labeled Step 1, Step 2 and Step 3. Step 1 is selected and shows Basic Information, with Project Name and Description as labeled hints. Previous is disabled. Next sits beside it.
Use stepped tabs for a setup people can also jump by clicking a step. If steps must not be skipped, a Dialog with one step at a time is stricter. Ark UI in Vue does not move Previous and Next.
Installation
Anatomy

Usage
<div class="flex w-full max-w-2xl flex-col gap-4">
<Tabs @value-change="handleValueChange" :value="activeTab">
<TabsList class="grid w-full grid-cols-3">
<TabsTrigger v-for="step in steps" :key="step.value" :value="step.value">
{{ step.label }}
</TabsTrigger>
</TabsList>
<TabsContent v-for="step in steps" :key="step.value" :value="step.value">
<div class="rounded-lg border bg-card p-6 text-card-foreground shadow-sm">
<h3 class="mb-2 font-semibold text-lg">{{ step.title }}</h3>
<p class="mb-4 text-muted-foreground text-sm">{{ step.description }}</p>
<div class="flex flex-col gap-4">
<div v-for="field in step.fields" class="rounded-md border p-4" :key="field.label">
<p class="font-medium text-sm">{{ field.label }}</p>
<p class="mt-1 text-muted-foreground text-sm">{{ field.hint }}</p>
</div>
</div>
</div>
</TabsContent>
</Tabs>
<div class="flex justify-between">
<Button :disabled="index === 0" @click="handlePrevious" variant="outline">
Previous
</Button>
<Button :disabled="index === steps.length - 1" @click="handleNext">Next</Button>
</div>
</div>FAQ
How does this demo control the selected tab?
The selected value is kept in state, starting at step1, and passed back to Tabs. Clicking a trigger or a button writes the same state.
The Vue file binds :value and listens to @value-change, which receives details.value.
When are Previous and Next disabled?
Previous is disabled on the first step and Next on the last. Each button moves one place in the steps array.
Can the reader still click a step?
Yes. The three triggers are not disabled. Clicking one updates the same state the buttons write, so the buttons stay in sync.
Why are the three steps equal width?
TabsList has grid w-full grid-cols-3, so each of Step 1, Step 2 and Step 3 fills a column. The group is w-full max-w-2xl.
API Reference
Tabs
Sets value-change="handleValueChange", value="activeTab", v-for="step in steps", key="step.value" and value="step.value". The rest is on the Tabs page.
Button
Sets disabled="index === 0", click="handlePrevious", variant="outline", disabled="index === steps.length - 1" and click="handleNext". The rest is on the Button page.





