按鈕與切換
彈簧開關
以彈簧位移的 React 開關元件:thumb 可直接拖曳切換,可在 thumb 內放 icon 交叉淡接,另有壓下態的切換鈕變體,支援原生表單送出。
設定頁最常見的開關。點擊、按 Space/Enter,或直接抓著 thumb 拖到另一側都能切換;thumb 以彈簧位移,拖曳時 track 底色依進度漸變,放開時越過一半就切到對側、否則彈回原位。thumb 內可放開/關兩個 icon,切換時旋轉淡入交接。variant="button" 會變成壓下態的切換鈕(aria-pressed),適合文字工具列這類「按下=開啟」的場景。狀態支援受控/非受控雙模式,給 name 即可隨原生表單送出。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add switchPlayground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
500
30
編輯中的呼叫預設屬性
<Switch/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add https://webberui.com/r/switch.json或在 components.json 設定 registries 後,改用 @webberui/switch 安裝。
使用
import { Moon, Sun } from "lucide-react";
import { Switch } from "@/components/ui/switch";
const [dark, setDark] = React.useState(false);
<Switch
label="深色模式"
description="跟隨你的偏好切換介面配色"
checked={dark}
onCheckedChange={setDark}
icons={{ on: <Moon />, off: <Sun /> }}
/>
// 壓下態切換鈕
<Switch variant="button" label="粗體" defaultChecked />
// 原生表單:開啟時送出 newsletter=yes
<Switch name="newsletter" value="yes" label="訂閱電子報" />Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
checked | boolean | — | 受控的開關狀態;未提供時由元件內部管理(非受控) |
defaultChecked | boolean | false | 非受控模式的初始狀態 |
onCheckedChange | (checked: boolean) => void | — | 狀態變動時回呼,參數為切換後的新狀態 |
size | "sm" | "md" | "lg" | "md" | 尺寸:track 分別為 28×16、36×20、44×24 |
disabled | boolean | false | 停用:不可點擊、拖曳或鍵盤切換,外觀灰化 |
label | ReactNode | — | 標籤;switch 變體渲染為可點擊的 label,button 變體則成為按鈕文字 |
description | ReactNode | — | 補充說明,以 aria-describedby 關聯 |
variant | "switch" | "button" | "switch" | 外觀變體:滑動開關或壓下態切換鈕 |
icons | SwitchIcons | — | thumb 內的開/關 icon,切換時交叉淡接 |
stiffness | number | 500 | thumb 彈簧剛性 |
damping | number | 30 | thumb 彈簧阻尼 |
name | string | — | 原生表單欄位名稱;有提供時以 hidden input 隨表單送出 |
value | string | "on" | 開啟時隨表單送出的值 |
className | string | — | 透傳到最外層容器 |
SwitchIcons
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
on | ReactNode | — | 開啟時顯示的 icon |
off | ReactNode | — | 關閉時顯示的 icon |
細節
- 拖曳:在 thumb 上按下後以
setPointerCapture鎖定指標,thumb 跟隨指標並限制在 track 範圍內;放開時位置越過一半就切到對側,否則彈回原位。移動不到 3px 視為點擊;拖曳結束後會吞掉瀏覽器補發的那一次 click,避免二次切換。 - track 的開啟色是一層疊在底色上的色塊,拖曳中依進度 0–1 調整透明度,平時以
--wb-switch-duration(預設 150ms)過渡;可在全域或外層覆寫這個變數調整節奏。 - 深色模式下開啟的 track 是淺色,thumb 會改為深色以保持對比。
- 開關本身不是文字輸入,Space/Enter 交給原生
<button>處理,不會受輸入法組字影響。 - 表單送出比照原生 checkbox:只有開啟時才會帶上
name=value,關閉時不送出。
可及性
- switch 變體為
<button role="switch">,以aria-checked表示狀態;label以htmlFor關聯,點擊文字也能切換 - button 變體為
<button aria-pressed>(不是role="switch"),適合工具列;description在此變體以視覺隱藏文字提供給螢幕閱讀器 description以aria-describedby關聯;thumb 與 icon 對輔助科技隱藏- 鍵盤:Tab 聚焦後按 Space 或 Enter 切換,聚焦時顯示 focus-visible 外框;
disabled時無法聚焦與操作 - 使用者系統開啟「減少動態效果」時,thumb 不走彈簧而是直接到位、停用拖曳只保留點擊,icon 只淡入不旋轉,切換鈕按住時也不縮放