輸入元件
旋鈕
可拖曳轉動的旋鈕輸入:外圈 SVG 刻度、吸附點微震、指針彈簧到位、讀數逐位滾動,支援滾輪與方向鍵。
像實體設備上的旋鈕一樣調整數值。按住旋鈕繞圈拖曳(或切換成上下拖曳),外圈 SVG 刻度與填色弧線即時標出目前位置;指針以彈簧追隨目標角度,快速轉動時有輕微滯後與到位感。設定 detents 後,拖到吸附點附近會「卡」進去並輕輕一震;下方讀數逐位滾動、可接單位。也支援滑鼠滾輪與完整的鍵盤操作,並提供受控/非受控雙模式。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add dial-knobPlayground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
1
320
編輯中的呼叫預設屬性
<DialKnob/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add https://webberui.com/r/dial-knob.json或在 components.json 設定 registries 後,改用 @webberui/dial-knob 安裝。
使用
import { DialKnob } from "@/components/ui/dial-knob";
const [temp, setTemp] = React.useState(26);
<DialKnob
label="溫度"
value={temp}
onValueChange={setTemp}
onValueCommit={(v) => console.log(`送出 ${v}°C`)}
min={16}
max={30}
step={0.5}
detents={[24]}
unit="°C"
formatValue={(v) => v.toFixed(1)}
/>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
label | string | — | 旋鈕名稱,作為 aria-label 並顯示於讀數下方(必填) |
value | number | — | 受控值;未提供時由元件內部管理 |
defaultValue | number | min | 非受控模式的初始值 |
onValueChange | (value: number) => void | — | 值變動時回呼,拖曳中會連續觸發 |
onValueCommit | (value: number) => void | — | 放開拖曳、按鍵後或滾輪停止約 200ms 後回呼 |
min | number | 0 | 最小值 |
max | number | 100 | 最大值 |
step | number | 1 | 每一步的增量,值會依此量化 |
detents | number[] | — | 吸附點,例如 [0, 50, 100] |
snapThreshold | number | 範圍的 3% | 拖曳時距離吸附點多近會被吸過去 |
arc | number | 270 | 可轉動的總角度(度),以正上方為中心左右對稱 |
dragMode | "angle" | "vertical" | "angle" | 繞中心轉動,或上下拖曳(每 200px 走完整個範圍) |
ticks | number | 27 | 外圈刻度數量,每 5 根一根長刻度 |
size | "sm" | "md" | "lg" | number | "md" | 64/96/140 px,或直接給像素數字 |
unit | string | — | 讀數後綴,例如 "%"、"°C" |
formatValue | (value: number) => string | — | 自訂讀數格式,也用於 aria-valuetext;預設依 step 的小數位數輸出 |
stiffness | number | 320 | 指針彈簧剛性(damping 固定 22),越大越快到位 |
disabled | boolean | false | 停用所有互動 |
className | string | — | 透傳到最外層容器 |
細節
- 角度映射:值線性對應到
-arc/2到+arc/2(0° 為正上方),外圈刻度、填色弧線與指針都用同一套換算。 - 角度拖曳以「指標相對中心的角度變化」累加,並把每次變化折回 ±180° 之內,繞過 6 點鐘方向時不會跳值;超出範圍後往回轉會立即反應。
- 吸附只作用在拖曳:內部保留未吸附的連續值,離開吸附距離就會脫離。鍵盤與滾輪則照
step一格一格走,避免在吸附點旁被吸回去;任何方式落在吸附點上時,旋鈕本體都會做一次 120ms 的小幅抖動,支援的手機會再震 8ms。 - 滾輪事件以
passive: false原生綁定,只有指標停在旋鈕上時才攔截頁面捲動;觸控板的連續小量會累積成一格再動。 - 強調色走
--wb-dial-accent變數(預設淺色 neutral-900、深色 neutral-100),填色弧線與指針線共用;過渡時長沿用--wb-duration-fast與--wb-ease-out。
可及性
- 旋鈕本身是
role="slider"、tabIndex=0,帶aria-valuemin、aria-valuemax、aria-valuenow,aria-valuetext為格式化後的值加單位(例如「24.0°C」),aria-label取自label - 鍵盤:←/↓ 減一步、→/↑ 加一步、PageUp/PageDown 加減 10 步、Home/End 到最小/最大值
- 聚焦時以
focus-visible外圈標示;disabled時設定aria-disabled並移出 Tab 順序 - 可視讀數與名稱對輔助科技隱藏,避免與 slider 自身的朗讀重複
- 使用者系統開啟「減少動態效果」時,指針直接到位(不用彈簧)、不做吸附微震、讀數不滾動