覆蓋層與回饋
確認對話框
需要明確回應的確認對話框:遮罩淡入、面板微縮放進場,焦點鎖定與捲動鎖定,危險操作可改為長按填滿才觸發。
刪除、離開、覆寫這類動作需要使用者明確回應的確認對話框。開啟時遮罩淡入、面板從 95% 微縮放進場(預設 100ms),焦點鎖在面板內、背景加上 inert 並鎖住頁面捲動;關閉後焦點回到觸發元素。variant 決定語意與關閉方式:alert 只能按鈕或 Escape 關閉,plain 點遮罩也能關,destructive 換成紅色主鈕與警示圖示。危險操作可以把 confirmMode 設為 hold,主鈕要按住到填滿才會觸發,避免手滑。onConfirm 回傳 Promise 時主鈕顯示載入中,成功才關閉、失敗保持開啟。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add confirm-dialogPlayground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
100
1600
編輯中的呼叫預設屬性
<ConfirmDialog/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add https://webberui.com/r/confirm-dialog.json或在 components.json 設定 registries 後,改用 @webberui/confirm-dialog 安裝。
使用
import { ConfirmDialog } from "@/components/ui/confirm-dialog";
<ConfirmDialog
trigger={<button type="button">刪除專案</button>}
variant="destructive"
confirmMode="hold"
title="刪除這個專案?"
description="刪除後 30 天內可從封存區還原,之後將永久移除。"
confirmLabel="刪除專案"
onConfirm={async () => {
// 回傳 Promise:成功後關閉,失敗保持開啟
await deleteProject();
}}
/>也可以不給 trigger,改用 open/onOpenChange 從外部控制;關閉時焦點會還給開啟當下的焦點元素。
Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
open | boolean | — | 受控的開啟狀態;不傳則由元件內部管理 |
defaultOpen | boolean | false | 非受控模式的初始開啟狀態 |
onOpenChange | (open: boolean) => void | — | 開啟狀態變更時的回呼 |
trigger | ReactNode | — | 觸發元素;元素會被接上 onClick,字串會包成預設按鈕;關閉後焦點回到它 |
title | ReactNode | — | 對話框標題(aria-labelledby 指向它) |
description | ReactNode | — | 標題下方的說明(aria-describedby 指向它) |
children | ReactNode | — | 說明下方的自訂內容,例如確認用的輸入框 |
cancelLabel | string | "取消" | 取消鈕文字 |
confirmLabel | string | "確認" | 確認鈕文字 |
onConfirm | () => void | Promise<void> | — | 確認時呼叫;回傳 Promise 時顯示載入中,resolve 後關閉、reject 時保持開啟 |
onCancel | () => void | — | 按取消鈕、Escape 或(plain)點遮罩時呼叫 |
variant | "plain" | "alert" | "destructive" | "alert" | 對話框語意與外觀 |
confirmMode | "click" | "hold" | "click" | hold 時主鈕需按住到填滿才確認 |
holdDuration | number | 1600 | hold 模式需按住的時長(毫秒) |
confirmDisabled | boolean | false | 停用確認鈕 |
hideCancel | boolean | false | 隱藏取消鈕,僅 plain 有效 |
duration | number | 100 | 遮罩與面板進退場時長(毫秒),同時寫入 --wb-confirm-dialog-duration |
className | string | — | 追加到對話框面板 |
另外具名匯出型別 ConfirmDialogVariant 與 ConfirmDialogConfirmMode。
細節
- 三種變體:
alert與destructive使用role="alertdialog",點遮罩不會關閉,只能按鈕或 Escape;plain使用role="dialog",點遮罩即取消。 - 開啟時的初始焦點:
alert/destructive落在取消鈕,避免連按 Enter 誤觸危險操作;plain落在面板內第一個可聚焦元素。 - 捲動鎖定會補上捲軸寬度的
padding-right,背景版面不會因捲軸消失而跳動;關閉時還原原本的樣式。 - hold 模式:按下(滑鼠、觸控、Space 或 Enter)時填充條以等速由左到右填滿,放開或移出即在 200ms 內退回;超過 85% 時按鈕輕微震顫;填滿才呼叫
onConfirm。 - 非同步確認期間取消鈕與 Escape 都會暫時失效,避免結果回來時對話框已關閉。
- 時長變數:按鈕的顏色過渡讀取
--wb-confirm-dialog-duration,可在主題層統一覆寫。
可及性
- 面板設定
aria-modal="true",aria-labelledby/aria-describedby分別指向標題與說明 - Tab/Shift+Tab 在面板內循環,背景節點加上
inert,螢幕閱讀器與鍵盤都進不去 - Escape 關閉(IME 組字中按 Escape 只會取消組字);關閉後焦點回到觸發元素或開啟前的焦點元素
- 非同步確認期間主鈕設定
aria-busy;hold 模式主鈕以aria-describedby連到「按住以確認」說明 - 使用者系統開啟「減少動態效果」時,面板只淡入不縮放;hold 填充改為原地加深並以文字倒數「按住 2 秒…1 秒…」呈現,不震顫