WebberUI

Filter Composer Bar

Linear 式過濾器組合列:點「加入條件」挑欄位,膠囊 chip 以 spring 彈入;chip 內可原地展開選單換值,移除時其餘 chip 以 FLIP 收攏補位。

載入預覽⋯

Playground

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

<FilterComposerBar />

安裝

npx shadcn@latest add https://webberui.com/r/filter-composer-bar.json

或在 components.json 設定 registries 後,改用 @webberui/filter-composer-bar 安裝。

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

npm install motion lucide-react clsx tailwind-merge

使用

import { FilterComposerBar } from "@/components/ui/filter-composer-bar";

<FilterComposerBar
  fields={[
    {
      key: "status",
      label: "狀態",
      options: [
        { value: "active", label: "進行中" },
        { value: "done", label: "已完成" },
      ],
    },
    {
      key: "priority",
      label: "優先級",
      options: [
        { value: "high", label: "高" },
        { value: "low", label: "低" },
      ],
    },
  ]}
  onChange={(conditions) => console.log(conditions)}
/>

未提供 value 時由元件內部管理狀態(非受控);提供 value 搭配 onChange 則為受控模式。onChange 在新增、換值、移除時都會帶入最新的 FilterCondition[]

Props

Prop型別預設值說明
fieldsFilterField[]可用欄位清單,每項為 { key, label, options: { value, label }[] },每個欄位同時最多一個條件
valueFilterCondition[]受控條件陣列,每項為 { key, value };未提供時由元件內部管理
onChange(conditions: FilterCondition[]) => void條件變更時觸發(新增、換值、移除),帶入最新條件陣列
addLabelstring"加入條件"「加入條件」按鈕的文字
classNamestring附加到最外層容器的 class

細節

  • 三段式 chip:欄位名(靜態)/值(可點擊)/移除 ×,以細分隔線切成一顆膠囊,仿 Linear 的過濾器語彙
  • 彈入進場:選定欄位後,chip 以 scale + y 的 spring 從下方彈入排列,新增條件預設取該欄位第一個選項
  • 原地換值:點 chip 的值段,小選單以縮放淡入展開並錨定於該 chip 下方,選取後即時更新值文字,不需離開組合列
  • FLIP 收攏:點 × 時該 chip 縮小退場(AnimatePresence mode="popLayout" 先脫離文件流),其餘 chip 與「加入條件」按鈕同時以 layout FLIP 平滑補位;多條件時以 flex-wrap 自動換行
  • 點外關閉:popover 以絕對定位錨定,掛載 document 的 pointerdown 監聽點擊外部即關閉(unmount 時清理);同一時間只會有一個選單開啟
  • 每個欄位同時最多一個條件;欄位全部用完時「加入條件」按鈕停用

可及性

  • 使用者系統開啟「減少動態效果」時,彈入、FLIP 與選單縮放全部停用,狀態直接切換(DOM 結構與 SSR 一致)
  • chip 各段皆為原生 <button>,可 Tab 循序聚焦;值段與「加入條件」按鈕帶 aria-haspopup / aria-expanded 標示選單狀態
  • 值選單項目為 menuitemradio 並以 aria-checked 標示目前值;移除按鈕帶「移除某欄位條件」的 aria-label
  • 按 Esc 關閉選單並把焦點還給觸發按鈕;focus-visible 時顯示外框

On this page