Frontend Lab
← 回到所有模式
PC04🧭 Navigation · 導航流程

Stepper

步驟條

難度 ★★★★★標籤 stepper · 進度 · 流程3 min read

模式簡述

Stepper:多步驟流程的進度指示。註冊、結帳、設定精靈。讓使用者知道走到哪、還有多遠。

1
登入
2
驗證
3
付款
4
完成
第 1 步|首步 active

Claude Code Prompt

💬 Claude Code Prompt
參考:PC04 stepper
組件:Stepper.tsx

Stepper:多步驟流程的進度指示。註冊、結帳、設定精靈。讓使用者知道走到哪、還有多遠。

限制:
- 沒標明可不可回頭
- 步驟超過 5 個
- 手機端橫排擠

完整程式碼

Stepper.tsx
"use client";
import { Check, X } from "lucide-react";
import { cn } from "@/lib/utils";

type State = "step1" | "step3" | "done" | "error";
const STEPS = ["登入", "驗證", "付款", "完成"];

export function Stepper({ state = "step1" }: { state?: State }) {
const activeIdx = state === "step1" ? 0 : state === "step3" ? 2 : state === "done" ? 4 : 2;
const errorIdx = state === "error" ? 1 : -1;

return (
  <div className="w-full max-w-md">
    <div className="flex items-center">
      {STEPS.map((label, i) => {
        const isDone = i < activeIdx;
        const isActive = i === activeIdx && state !== "done";
        const isError = i === errorIdx;
        return (
          <div key={i} className="flex flex-1 items-center last:flex-none">
            <div className="flex flex-col items-center gap-2">
              <div
                className={cn(
                  "grid h-7 w-7 place-items-center rounded-full border-2 font-mono text-xs",
                  isError && "border-red-500 bg-red-500/10 text-red-500",
                  !isError && isDone && "border-lab-accent bg-lab-accent text-background",
                  !isError && isActive && "border-lab-accent text-lab-accent",
                  !isError && !isDone && !isActive && "border-border text-muted-foreground/60",
                )}
              >
                {isError ? <X className="h-3.5 w-3.5" /> : isDone ? <Check className="h-3.5 w-3.5" /> : i + 1}
              </div>
              <span
                className={cn(
                  "text-[11px]",
                  isError && "text-red-500",
                  !isError && (isDone || isActive) ? "text-foreground" : "text-muted-foreground",
                )}
              >
                {label}
              </span>
            </div>
            {i < STEPS.length - 1 && (
              <div
                className={cn(
                  "mx-2 h-0.5 flex-1 -translate-y-3",
                  i < activeIdx - 1 || (i === activeIdx - 1 && state === "done")
                    ? "bg-lab-accent"
                    : "bg-border",
                )}
              />
            )}
          </div>
        );
      })}
    </div>
  </div>
);
}

何時用

  • ✅ 註冊 / onboarding 流程
  • ✅ 結帳 checkout
  • ✅ 複雜表單分步填寫

何時別用

  • ❌ 步驟少於 3 個(直接做完)
  • ❌ 步驟順序不重要(用 tabs)
  • ❌ 步驟數量會變(用 progress bar)

我踩過的坑

  1. 沒標明可不可回頭:使用者不知道點過去的步驟是否能改。明確顯示「已完成」icon。

  2. 步驟超過 5 個:使用者放棄。能分組就分組,或用 progress + 標題。

  3. 手機端橫排擠:手機改垂直 stepper,每步驟一行。

相關模式

  • PC01
  • PA05

搜尋

按 ⌘K 隨時開啟