按鈕與切換

雙態文字開關

兩態文字開關(例如「詢問|自動」),玻璃質感把手以彈簧滑動,文字隨把手位置交叉淡接,適合切換助理或系統的運作模式。

只有兩個選項的文字開關:膠囊 track 兩側各放一個標籤,一顆半透明玻璃把手蓋住目前選中的那一側。點擊、方向鍵或直接拖曳把手都能切換,把手以彈簧滑過去、到位時有一下果凍形變;兩側文字的顏色與透明度跟著把手位置連續插值,而不是選中瞬間才換色。把手寬度等於它蓋住那側的標籤寬,拖曳途中在兩側寬度之間平滑過渡。適合「詢問|自動」這類運作模式、「月繳|年繳」或「預覽|編輯」。

把這個效果裝進你的專案

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

npx webberui@latest add labeled-mode-switch

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

Playground

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

500
32
編輯中的呼叫預設屬性
<LabeledModeSwitch/>

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

安裝

npx webberui@latest add https://webberui.com/r/labeled-mode-switch.json

或在 components.json 設定 registries 後,改用 @webberui/labeled-mode-switch 安裝。

使用

import { MessageCircleQuestion, Zap } from "lucide-react";
import { LabeledModeSwitch } from "@/components/ui/labeled-mode-switch";

const [mode, setMode] = React.useState("ask");

<LabeledModeSwitch
  aria-label="助理執行模式"
  value={mode}
  onValueChange={setMode}
  options={[
    { value: "ask", label: "詢問", icon: <MessageCircleQuestion /> },
    { value: "auto", label: "自動", icon: <Zap /> },
  ]}
/>

Props

Prop型別預設值說明
options[LabeledModeSwitchOption, LabeledModeSwitchOption]「詢問|自動」固定兩個選項:[左側, 右側]
valuestring—受控模式的當前值;提供後由外部完全控制
defaultValuestring左側選項的 value非受控模式的初始值
onValueChange(value: string) => void—選中值變更時的回呼
size"sm" | "md" | "lg""md"尺寸
draggablebooleantrue是否允許拖曳把手切換(點擊與鍵盤永遠可用)
stiffnessnumber500把手彈簧剛度,越大越快到位
dampingnumber32把手彈簧阻尼,越大回彈越少
disabledbooleanfalse停用整個開關
aria-labelstring—提供給輔助科技的群組名稱
classNamestring—透傳到最外層 track

LabeledModeSwitchOption

欄位型別預設值說明
valuestring—選項的唯一值
labelstring—顯示文字
iconReactNode—選填的前置圖示,顏色跟隨文字

CSS 變數

變數預設值說明
--wb-mode-switch-glassrgb(255 255 255 / 0.55)(深色模式 0.12)玻璃把手的底色
--wb-mode-switch-blur10px把手的 backdrop 模糊半徑(另加 saturate(1.6))
--wb-mode-switch-accenttransparent疊在把手上的染色層,可給把手上品牌色

細節

  • 把手寬度:掛載後量測兩側標籤的位置與寬度(ResizeObserver 追蹤字型載入與文字變動),把手寬度依位置在兩側寬度間插值,所以長短不一的標籤也能剛好蓋住。量測完成前把手先隱藏,伺服器渲染的首屏不會出現錯位。
  • 拖曳:從把手所在那側按下即可水平拖曳,限制在 track 內(dragElastic 0.1);放手時依位置是否過半決定狀態,沒過半就彈回原位。拖曳只是增強,點擊與鍵盤完全等價。
  • 點擊:點另一側選它;點目前選中那側則切換到另一側。
  • 動態:位移使用 spring(預設 stiffness 500、damping 32),切換瞬間把手 scaleX 1 → 1.08 → 1 做一次果凍形變。
  • 文字交叉淡接:每個標籤由 muted 與前景兩層疊成,前景層透明度隨把手位置連續變化,標籤整體透明度在 0.55 與 1 之間插值;圖示用 currentColor,跟著一起換色。

可及性

  • 選用 role="radiogroup" 包兩個 role="radio"(aria-checked)而不是 role="switch":兩側都有各自的語意標籤,radio 能讓螢幕閱讀器直接念出「詢問,已選取」這類完整資訊;請以 aria-label 為群組命名
  • roving tabindex:Tab 只停在選中項;左右方向鍵分別選左側/右側,上下方向鍵與空白鍵切換到另一側,焦點跟著移動
  • focus-visible 時整條 track 顯示 ring
  • disabled 時兩顆按鈕都停用,拖曳也關閉
  • 使用者系統開啟「減少動態效果」時,把手直接跳到新位置(無彈簧、無果凍形變),文字直接換色