輸入元件

旋鈕

可拖曳轉動的旋鈕輸入:外圈 SVG 刻度、吸附點微震、指針彈簧到位、讀數逐位滾動,支援滾輪與方向鍵。

像實體設備上的旋鈕一樣調整數值。按住旋鈕繞圈拖曳(或切換成上下拖曳),外圈 SVG 刻度與填色弧線即時標出目前位置;指針以彈簧追隨目標角度,快速轉動時有輕微滯後與到位感。設定 detents 後,拖到吸附點附近會「卡」進去並輕輕一震;下方讀數逐位滾動、可接單位。也支援滑鼠滾輪與完整的鍵盤操作,並提供受控/非受控雙模式。

把這個效果裝進你的專案

在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。

npx webberui@latest add dial-knob

還沒有專案,或安裝遇到問題?看快速開始 →

Playground

即時調整 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型別預設值說明
labelstring—旋鈕名稱,作為 aria-label 並顯示於讀數下方(必填)
valuenumber—受控值;未提供時由元件內部管理
defaultValuenumbermin非受控模式的初始值
onValueChange(value: number) => void—值變動時回呼,拖曳中會連續觸發
onValueCommit(value: number) => void—放開拖曳、按鍵後或滾輪停止約 200ms 後回呼
minnumber0最小值
maxnumber100最大值
stepnumber1每一步的增量,值會依此量化
detentsnumber[]—吸附點,例如 [0, 50, 100]
snapThresholdnumber範圍的 3%拖曳時距離吸附點多近會被吸過去
arcnumber270可轉動的總角度(度),以正上方為中心左右對稱
dragMode"angle" | "vertical""angle"繞中心轉動,或上下拖曳(每 200px 走完整個範圍)
ticksnumber27外圈刻度數量,每 5 根一根長刻度
size"sm" | "md" | "lg" | number"md"64/96/140 px,或直接給像素數字
unitstring—讀數後綴,例如 "%"、"°C"
formatValue(value: number) => string—自訂讀數格式,也用於 aria-valuetext;預設依 step 的小數位數輸出
stiffnessnumber320指針彈簧剛性(damping 固定 22),越大越快到位
disabledbooleanfalse停用所有互動
classNamestring—透傳到最外層容器

細節

  • 角度映射:值線性對應到 -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 自身的朗讀重複
  • 使用者系統開啟「減少動態效果」時,指針直接到位(不用彈簧)、不做吸附微震、讀數不滾動