WebberUI

Multi-step Form

多步驟表單容器,方向感知的滑動過場搭配可切換款式的進度指示。

載入預覽⋯

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

<MultiStepForm />

安裝

npx shadcn@latest add https://webberui.com/r/multi-step-form.json

或在 components.json 設定 registries 後,改用 @webberui/multi-step-form 安裝。

安裝依賴後,從 registry JSON(/r/multi-step-form.jsonfiles[0].content)複製 multi-step-form.tsx 原始碼到你的 components/ui/ 目錄:

npm install motion lucide-react clsx tailwind-merge

使用

<MultiStepFormStep> 宣告每一個步驟,容器會依目前步驟做方向感知的滑動過場,並自動渲染進度指示與上一步/下一步控制列。

import {
  MultiStepForm,
  MultiStepFormStep,
} from "@/components/ui/multi-step-form";

<MultiStepForm variant="steps" onComplete={() => console.log("done")}>
  <MultiStepFormStep label="帳號">{/* ...欄位 */}</MultiStepFormStep>
  <MultiStepFormStep label="個人資料">{/* ...欄位 */}</MultiStepFormStep>
  <MultiStepFormStep label="確認">{/* ...摘要 */}</MultiStepFormStep>
</MultiStepForm>;

自訂控制列

controls 設為 false,改用 useMultiStepForm() hook 在任意位置自組導覽(可加入驗證後才 next()):

import { useMultiStepForm } from "@/components/ui/multi-step-form";

function Footer() {
  const { back, next, isFirst, isLast } = useMultiStepForm();
  return (
    <div>
      <button onClick={back} disabled={isFirst}>
        上一步
      </button>
      <button onClick={next}>{isLast ? "送出" : "下一步"}</button>
    </div>
  );
}

受控模式

傳入 steponStepChange 即可完全掌控目前步驟,適合搭配表單驗證做步驟守門。

const [step, setStep] = React.useState(0);

<MultiStepForm step={step} onStepChange={(next) => setStep(next)}>
  {/* ...steps */}
</MultiStepForm>;

Props

MultiStepForm

Prop型別預設值說明
childrenReactNode步驟宣告,皆為 <MultiStepFormStep>
stepnumber受控目前步驟索引;不傳則為非受控
defaultStepnumber0非受控模式的初始步驟索引
onStepChange(step: number, direction: 1 | -1) => void步驟變更時觸發,帶入新索引與方向
onComplete() => void於最後一步按下「完成」時觸發
variant"bar" | "dots" | "steps" | false"steps"進度指示款式;false 不顯示
controlsbooleantrue是否渲染內建控制列
backLabelstring"上一步"上一步按鈕文字
nextLabelstring"下一步"下一步按鈕文字
completeLabelstring"完成"末步按鈕文字

MultiStepFormStep

Prop型別預設值說明
labelstring進度指示顯示的步驟標題
childrenReactNode步驟內容
classNamestring追加到步驟容器的 className

useMultiStepForm()

回傳 { step, total, direction, isFirst, isLast, goTo, next, back, reducedMotion },供自訂控制列或進度指示使用。

細節

  • 三種進度款式:bar 進度條、dots 圓點(目前點延伸為膠囊)、steps 編號步驟(完成打勾、連接線依進度上色)。
  • 方向感知:前進時新步驟自右側滑入、舊步驟往左退場;後退則相反。方向於 render 期間依前次索引推導,受控與非受控皆正確。
  • 檢視區採 overflow-hidden 裁切水平滑動,並以 popLayout 讓退場步驟脫離流排、由進場步驟決定容器高度,避免過場時高度塌陷。

可及性

  • 進度指示中「目前與先前」的步驟可點擊回跳(goTo),未到達的步驟停用,維持填寫順序。
  • 目前步驟標上 aria-current="step";進度條提供 role="progressbar"aria-valuenow
  • 步驟切換透過 aria-live="polite" 區塊朗讀「步驟 x / y」。
  • 內建控制列為原生 button,可鍵盤操作並具 focus-visible 外框;第一步時上一步鈕停用。
  • 使用者系統開啟「減少動態效果」時,滑動退化為短暫淡入淡出,進度填充直接跳位。

On this page