WebberUI

Control Center Panel

玻璃模組控制網格,長按任一方塊原地彈簧放大為精細控制卡(滑桿、分段切換),背景同步模糊下沉,放開回彈歸位。

載入預覽⋯

Playground

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

2
<ControlCenterPanel />

安裝

npx shadcn@latest add https://webberui.com/r/control-center-panel.json

或在 components.json 設定 registries 後,改用 @webberui/control-center-panel 安裝。

安裝依賴後,從 registry JSON(/r/control-center-panel.jsonfiles[0].content)複製 control-center-panel.tsx 原始碼到你的 components/ui/ 目錄:

npm install motion clsx tailwind-merge

使用

import {
  ControlCenterPanel,
  ControlTile,
} from "@/components/ui/control-center-panel";

const [brightness, setBrightness] = React.useState(72);
const [appearance, setAppearance] = React.useState("auto");

<ControlCenterPanel columns={2}>
  <ControlTile
    id="brightness"
    label="亮度"
    icon={<Sun />}
    value={brightness}
    onValueChange={setBrightness}
    formatValue={(v) => `${v}%`}
  />
  <ControlTile
    id="appearance"
    label="外觀"
    icon={<Palette />}
    control="segmented"
    value={appearance}
    onValueChange={setAppearance}
    options={[
      { label: "淺色", value: "light" },
      { label: "深色", value: "dark" },
      { label: "自動", value: "auto" },
    ]}
  />
</ControlCenterPanel>;

Props

ControlCenterPanel

Prop型別預設值說明
columnsnumber2網格欄數(2–4)
valuestring | null受控模式:目前展開的 tile idnull 為全部收合)
defaultValuestring | nullnull非受控模式的初始展開 id
onValueChange(id: string | null) => void展開/收合變更時觸發
classNamestring覆蓋面板容器樣式
childrenReactNode放入 ControlTile 子元件

ControlTile(共用)

Prop型別預設值說明
idstringtile 唯一識別,面板以此協調「同時僅一個展開」
labelstring標題(如「亮度」)
iconReactNode左上角圖示,建議傳 lucide-react 圖示
control'slider' | 'segmented''slider'控制型別
onValueChange(value) => void數值/選擇變更時觸發
classNamestring覆蓋 tile 樣式

ControlTile — control="slider"

Prop型別預設值說明
valuenumber目前數值(受控)
minnumber0最小值
maxnumber100最大值
stepnumber1級距
formatValue(v: number) => string(v) => `${v}`compact 讀數與展開卡的顯示格式化

ControlTile — control="segmented"

Prop型別預設值說明
valuestring目前選中的 value(受控)
options{ label: ReactNode; value: string }[]分段選項,等寬排列

細節

  • 長按展開:pointer 按住方塊超過約 380ms 才展開;按住期間方塊微幅縮下蓄勢,提前放開會以 spring 回彈歸位(不觸發展開)
  • 原地形變:方塊與展開卡共用 layoutId,以減速回彈 spring 從原格位無縫放大為精細控制卡;一次僅一個 tile 展開
  • 背景下沉:展開時整面網格被半透明遮罩覆蓋並 backdrop-blur 模糊,營造背景後退聚焦的層次
  • 精細滑桿:展開卡內的滑桿支援 pointer 拖曳與鍵盤(方向鍵 ±stepPageUp/Down ±10%、Home/End 到端點),填充與滑鈕以 spring 追隨
  • 分段切換:等寬選項,高亮以索引推算位置滑動切換(避開巢狀 layout 動畫),方向鍵可循環切換
  • 收合:點背景遮罩或按 Esc 收合,展開卡以相同 spring 形變回原格位

可及性

  • 方塊為 role="button"aria-haspopup="dialog"aria-expandedEnterSpace 可直接展開(鍵盤操作不需長按)
  • 展開卡為 role="dialog" aria-modal,開啟時焦點移入卡片、網格加上 inert 移出 tab 序,收合後焦點還給原方塊
  • 滑桿為 role="slider"aria-valuemin/max/nowaria-valuetext;分段為 role="radiogroup" / role="radio" 並以 aria-checked 標記
  • 使用者系統開啟「減少動態效果」時:長按展開與所有控制功能完全保留,僅移除形變位移與蓄勢縮放,改為短暫淡入淡出

On this page