按鈕與切換
實體按鍵
兩層結構的實體按鍵 React 元件:面板浮在底座上,滑過微沉 2px、按下沉到底,實心色塊做出深度,不靠陰影模糊。
像實體鍵盤一樣有行程的按鈕。<button> 內有兩層:底座往下偏移一個行程深度,面板浮在上方;滑鼠滑過時面板微沉 2px,按下(或用鍵盤按住空白鍵/Enter)時沉到與底座齊平。深度完全由實心色塊構成,沒有模糊陰影也沒有 spring,節奏與色彩都外露成 --wb-tactile-* 變數。支援三種尺寸、深淺兩種配色、左側圖示,以及寬度不跳動的載入狀態。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add tactile-buttonPlayground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
6
150
編輯中的呼叫預設屬性
<TactileButton/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add https://webberui.com/r/tactile-button.json或在 components.json 設定 registries 後,改用 @webberui/tactile-button 安裝。
使用
import { Download } from "lucide-react";
import { TactileButton } from "@/components/ui/tactile-button";
<TactileButton onClick={() => console.log("已儲存")}>儲存</TactileButton>
<TactileButton variant="light" icon={<Download />} depth={8}>
下載報表
</TactileButton>
<TactileButton size="lg" loading>
付款中
</TactileButton>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
children | React.ReactNode | — | 按鍵文字或內容 |
size | "sm" | "md" | "lg" | "md" | 尺寸:sm 高 36px、md 高 44px、lg 高 52px;行程深度不隨尺寸改變 |
variant | "dark" | "light" | "dark" | 配色:dark 深色面板、light 淺色面板;深色模式下各自改用對應的一組色票 |
depth | number | 6 | 行程深度(px):面板浮在底座上方的高度,按到底時剛好與底座齊平 |
icon | React.ReactNode | — | 文字左側的圖示,會依尺寸自動設為 16/18/20px |
loading | boolean | false | 載入中:面板內容換成小 spinner、設定 aria-busy 並暫停點擊,寬度不變 |
disabled | boolean | false | 停用:45% 不透明、游標改為禁止,且不會有任何位移 |
ref | React.Ref<HTMLButtonElement> | — | 轉發到原生 <button> 的 ref |
className | string | — | 併入最外層 <button> 的 class |
其餘原生 <button> 屬性(onClick、type、aria-*、form 等)全部透傳,type 預設為 "button"。
CSS 變數
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
--wb-tactile-face | color | 依 variant | 面板顏色(dark:neutral-700;light:neutral-100) |
--wb-tactile-base | color | 依 variant | 底座顏色(dark:neutral-900;light:neutral-300) |
--wb-tactile-highlight | color | 依 variant | 面板頂緣 1px 內高光(dark:neutral-600;light:white) |
--wb-tactile-content | color | 依 variant | 文字與圖示顏色(dark:neutral-100;light:neutral-900) |
--wb-tactile-duration | time | 150ms | 面板位移的時長 |
--wb-tactile-ease | easing | cubic-bezier(0.23,1,0.32,1) | 面板位移的緩動曲線 |
細節
- 按鈕本身以
padding-bottom保留整段行程,面板下沉時外框尺寸不變,周圍版面不會跳動。 - 滑過下沉只在
(hover: hover) and (pointer: fine)的裝置生效,觸控螢幕不會在點擊後卡在半沉狀態。 - 三種位移狀態(滑過、按下、鍵盤按住)的選擇器互斥,只改一個
--tactile-y變數,不依賴 CSS 先後順序。 - 色彩一律讀
var(--wb-tactile-*, 配色預設值):在任何祖先元素設定--wb-tactile-*即可整站換色;深色模式下 dark 配色反轉成淺色面板,light 配色改成深色面板。 - 載入狀態用 grid 疊層:原本的文字隱形占位,spinner 疊在同一格,寬度維持不變;載入中不使用原生
disabled,焦點不會因此跳走。
可及性
- 使用原生
<button>,type預設"button",空白鍵與 Enter 都能觸發 focus-visible時整顆按鍵(含底座)外圍顯示 2px 外框,與面板位移互不干擾- 鍵盤按住空白鍵或 Enter 時以
data-pressed呈現與滑鼠按下相同的下沉,不依賴瀏覽器對鍵盤:active的支援 - 載入中設定
aria-busy與aria-disabled,原本的文字仍留在 DOM 中作為可及名稱;spinner 對輔助科技隱藏 - 只放圖示的按鍵請傳
aria-label;icon外層已設aria-hidden - 使用者系統開啟「減少動態效果」時,面板不再位移,按下時改為即時降低亮度(brightness 95%)