stepper

Stepper with icons and badges

Stepper with icons and badges

Загрузка превью…

src/stepper/c-stepper-7.vue

<script setup lang="ts">
import { ref } from "vue"
import { Badge } from "@/components/reui/badge"
import { Stepper, StepperContent, StepperIndicator, StepperItem, StepperNav, StepperPanel, StepperSeparator, StepperTitle, StepperTrigger } from "@/components/reui/stepper"
import { Button } from "@/components/ui/button"

const steps = [
  { title: "User Details" },
  { title: "Payment Info" },
  { title: "Auth OTP" },
]

const currentStep = ref(2)
</script>

<template>
  <Stepper
    v-model:value="currentStep"
    class="w-full max-w-xl space-y-8"
  >
    <template #indicator-completed>
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width="24"
        height="24"
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        stroke-width="2"
        stroke-linecap="round"
        stroke-linejoin="round"
        class="size-3.5"
      >
        <path d="M20 6 9 17l-5-5" />
      </svg>
    </template>
    <template #indicator-loading>
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width="24"
        height="24"
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        stroke-width="2"
        stroke-linecap="round"
        stroke-linejoin="round"
        class="size-3.5 animate-spin"
      >
        <path d="M21 12a9 9 0 1 1-6.219-8.56" />
      </svg>
    </template>

    <StepperNav class="gap-3">
      <StepperItem
        v-for="(step, index) in steps"
        :key="index"
        :step="index + 1"
        class="relative flex-1 items-start"
      >
        <StepperTrigger
          class="flex grow flex-col items-start justify-center gap-2.5"
          as-child
        >
          <StepperIndicator
            class="data-[state=inactive]:border-border data-[state=inactive]:text-muted-foreground data-[state=completed]:bg-success size-8 border-2 data-[state=completed]:text-white data-[state=inactive]:bg-transparent"
          >
            <svg
              v-if="index === 0"
              xmlns="http://www.w3.org/2000/svg"
              width="24"
              height="24"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
              class="size-4"
            >
              <path d="M15 13a3 3 0 1 0-6 0" />
              <path
                d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20"
              />
              <circle cx="12" cy="8" r="2" />
            </svg>
            <svg
              v-else-if="index === 1"
              xmlns="http://www.w3.org/2000/svg"
              width="24"
              height="24"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
              class="size-4"
            >
              <rect width="20" height="14" x="2" y="5" rx="2" />
              <line x1="2" x2="22" y1="10" y2="10" />
            </svg>
            <svg
              v-else
              xmlns="http://www.w3.org/2000/svg"
              width="24"
              height="24"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
              class="size-4"
            >
              <rect width="18" height="11" x="3" y="11" rx="2" ry="2" />
              <path d="M7 11V7a5 5 0 0 1 10 0v4" />
            </svg>
          </StepperIndicator>
          <div class="flex flex-col items-start gap-1">
            <div class="text-muted-foreground text-[10px] font-semibold uppercase">Step {{ index + 1 }}</div>
            <StepperTitle
              class="group-data-[state=inactive]/step:text-muted-foreground text-start text-base font-semibold"
            >{{ step.title }}</StepperTitle>
            <div>
              <Badge
                size="sm"
                variant="primary-light"
                class="hidden group-data-[state=active]/step:inline-flex"
              >In Progress</Badge>
              <Badge
                variant="success-light"
                size="sm"
                class="hidden group-data-[state=completed]/step:inline-flex"
              >Completed</Badge>
              <Badge
                variant="secondary"
                size="sm"
                class="text-muted-foreground hidden group-data-[state=inactive]/step:inline-flex"
              >Pending</Badge>
            </div>
          </div>
        </StepperTrigger>

        <StepperSeparator
          v-if="steps.length > index + 1"
          class="group-data-[state=completed]/step:bg-success absolute inset-x-0 start-9 top-4 m-0 group-data-[orientation=horizontal]/stepper-nav:w-[calc(100%-2rem)] group-data-[orientation=horizontal]/stepper-nav:flex-none"
        />
      </StepperItem>
    </StepperNav>

    <StepperPanel class="text-sm">
      <StepperContent
        v-for="(step, index) in steps"
        :key="index"
        :value="index + 1"
        class="flex items-center justify-center"
      >{{ step.title }} content</StepperContent>
    </StepperPanel>

    <div class="flex items-center justify-between gap-2.5">
      <Button
        variant="outline"
        :disabled="currentStep === 1"
        @click="currentStep = currentStep - 1"
      >Previous</Button>
      <Button
        variant="outline"
        :disabled="currentStep === steps.length"
        @click="currentStep = currentStep + 1"
      >Next</Button>
    </div>
  </Stepper>
</template>

Установка

npx shadcn-vue@latest add https://revueui.rootapi.dev/r/c-stepper-7.json

Зависимости реестра

Источник: порт из ReUI (Keenthemes, MIT)