Hold to Confirm
長按填充確認按鈕:按住時進度由左到右填滿、接近完成時輕微震顫,填滿才觸發,防止危險操作誤觸。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
1.2
<HoldToConfirm />
安裝
npx shadcn@latest add https://webberui.com/r/hold-to-confirm.json安裝時會一併寫入 --wb-duration-fast CSS 變數到你的全域樣式。
安裝依賴後,複製 hold-to-confirm.tsx(亦可從 registry JSON 的 files[0].content 取得原始碼)到你的 components/ui/ 目錄,並在全域 CSS 加入:
npm install motion clsx tailwind-merge:root {
--wb-duration-fast: 200ms;
}使用
import { HoldToConfirm } from "@/components/ui/hold-to-confirm";
<HoldToConfirm
onConfirm={() => deleteAccount()}
confirmedChildren="已刪除"
>
按住刪除帳號
</HoldToConfirm>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
holdDuration | number | 1.2 | 需按住多久(秒)才觸發確認,填充以此時長等速填滿 |
onConfirm | () => void | — | 填充填滿時觸發,每次成功只觸發一次 |
confirmedChildren | ReactNode | — | 確認成功後顯示的內容,未提供時沿用 children |
variant | 'danger' | 'default' | 'danger' | danger 紅系(危險操作用)、default 中性色 |
className | string | — | 覆蓋預設樣式 |
children | ReactNode | — | 按鈕內容 |
其餘 <button> 屬性(disabled、aria-* 等)皆直接透傳。點擊不會觸發確認——長按是唯一的確認手勢。
細節
- 等速填充:pointer 按下(或按住空白鍵)時,填充層以
scaleX從左到右線性填滿;提早放開時中途鬆手,再按下會從目前進度以相同速度續跑 - 臨界震顫:進度超過 65% 後按鈕開始微幅左右抖動,振幅隨進度放大,為「即將生效」加強張力
- spring 回退:提早放開時填充以 spring(
stiffness: 500, damping: 42)快速彈回 0 - 成功態:填滿即觸發
onConfirm,按鈕轉為綠色、勾勾以畫線動畫進場,並顯示confirmedChildren;成功後元件停在成功態,要重玩可換key重新掛載(見 demo) - 鍵盤支援:空白鍵 keydown 開始填充、keyup 取消,與滑鼠長按行為一致;
e.repeat已過濾,按住不會重複觸發 - 無障礙:以
aria-describedby掛上「按住以確認」的說明,成功後透過aria-live="polite"宣告「已確認」 - 使用者系統開啟「減少動態效果」時:按住時長與線性填充完全保留(功能不變),僅移除震顫,回退改為快速線性
touch-none+select-none避免觸控長按時觸發捲動與選字;pointer 離開按鈕或事件被取消(pointercancel)、鍵盤按住期間失焦,都會視為放開並取消