輸入元件

單選群組

單選群組 React 元件:選中圓點以彈簧放大,卡片變體的選中外框在選項間滑動,方向鍵切換也同樣滑動;支援受控/非受控、直橫排列與表單送出。

資料驅動的單選群組:傳入 options 陣列即可,每項可帶標籤、說明、停用狀態,卡片變體還能在右上角放價格等附加資訊。dot 變體選中時內圓以彈簧放大;card 變體的選中外框是一個獨立元素,以 layoutId 在卡片之間滑動——滑鼠點擊與方向鍵切換都一樣。鍵盤操作自己實作 roving tabindex,行為與原生 radio 一致,不依賴任何 headless 套件。

把這個效果裝進你的專案

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

npx webberui@latest add radio-group

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

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

500
30
編輯中的呼叫預設屬性
<RadioGroup/>

完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。

安裝

npx webberui@latest add https://webberui.com/r/radio-group.json

或在 components.json 設定 registries 後,改用 @webberui/radio-group 安裝。

使用

import { RadioGroup } from "@/components/ui/radio-group";

<RadioGroup
  variant="card"
  aria-label="方案"
  name="plan"
  defaultValue="pro"
  options={[
    { value: "starter", label: "入門版", description: "3 個專案", meta: "NT$0/月" },
    { value: "pro", label: "專業版", description: "無限專案與版本紀錄", meta: "NT$290/月" },
    { value: "team", label: "團隊版", description: "成員管理與單一登入", meta: "NT$890/月" },
  ]}
  onValueChange={(value) => console.log(value)}
/>

Props

Prop型別預設值說明
optionsRadioGroupOption[]—選項清單(資料驅動)
valuestring—受控的選中值;未提供時由元件內部管理(非受控)
defaultValuestring—非受控模式的初始選中值
onValueChange(value: string) => void—選中值變動時回呼,參數為新選中的值
orientation"vertical" | "horizontal""vertical"排列方向,同時決定 aria-orientation
variant"dot" | "card""dot"外觀變體
stiffnessnumber500彈簧剛性(圓點放大與外框滑動共用)
dampingnumber30彈簧阻尼(圓點放大與外框滑動共用)
namestring—表單欄位名稱;提供時渲染一個 hidden input 讓表單可送出選中值
disabledbooleanfalse停用整組
aria-labelstring—群組的無障礙名稱(沒有可見標題時使用)
aria-labelledbystring—指向可見標題元素的 id,作為群組的無障礙名稱
classNamestring—透傳到最外層容器

RadioGroupOption

欄位型別預設值說明
valuestring—選項值(同一群組內不可重複)
labelReactNode—選項標籤
descriptionReactNode—補充說明,以 aria-describedby 關聯
disabledbooleanfalse停用此選項:不可點擊、方向鍵會跳過
metaReactNode—card 變體右上角的附加資訊(例如價格);dot 變體不顯示

細節

  • 選中外框只渲染在選中的那張卡片裡,靠 layoutId 讓 motion 在卡片之間補間位置與尺寸;layoutId 以 useId 為前綴,同頁多組互不干擾。
  • 取消選中的內圓不用彈簧,150ms 直接收起,避免兩顆圓點同時晃動。
  • 邊框與文字顏色過渡使用 --wb-radio-group-duration(預設 150ms)與 --wb-ease-out,可在全域或外層容器覆寫。
  • 提供 name 時只渲染一個 hidden input,值為目前選中項;未選取時送出空字串。

可及性

  • 根元素為 role="radiogroup" 並帶 aria-orientation;每項是 role="radio" 的 button,以 aria-checked 標示選中,標籤與說明分別以 aria-labelledby、aria-describedby 關聯
  • roving tabindex:整組只有一個 Tab 停靠點(選中項,沒有選中時為第一個可用項)
  • ↑/←、↓/→ 移動焦點並同時選取,跳過停用項、首尾循環;Space 選取目前聚焦項
  • 鍵盤焦點顯示 focus-visible 外框,與選中外框分開,不會混淆
  • 使用者系統開啟「減少動態效果」時,內圓不再彈簧放大、外框不再滑動,改為 100ms 淡入直接切換