互動編排

文件歸檔網格

文件歸檔 React 元件:散落在桌面的文件卡依分類沿弧線飛進對應資料夾,資料夾前片張開接住、闔上輕抖並滾動累加數量;可一鍵自動整理,也可拖曳或用鍵盤手動歸檔,點資料夾查看已收文件。

把「整理文件」做成看得見的動作。上方桌面上的文件卡以確定性的角度與位移散落(依 id 雜湊,SSR 與客戶端一致);開啟 autoSort 後,每隔 interval 毫秒就有一張文件沿弧線飛向它分類對應的資料夾,資料夾在文件接近時張口、落袋後闔上輕抖,右上角的計數逐位滾動 +1。也可以直接拖曳文件到資料夾:拖到上方時該資料夾張開並高亮,strict 模式下放錯會彈回原位並抖動。點資料夾展開小面板,查看已收文件;「重新散開」讓所有文件飛回桌面。資料夾全部用 CSS 漸層繪製,不用任何圖片。

把這個效果裝進你的專案

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

npx webberui@latest add folder-filing-grid

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

Playground

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

350
編輯中的呼叫預設屬性
<FolderFilingGrid/>

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

安裝

npx webberui@latest add https://webberui.com/r/folder-filing-grid.json

或在 components.json 設定 registries 後,改用 @webberui/folder-filing-grid 安裝。

使用

import { FolderFilingGrid } from "@/components/ui/folder-filing-grid";

const documents = [
  { id: "d1", title: "三月電費單", category: "invoice", meta: "NT$1,280" },
  { id: "d2", title: "員工旅遊報名表", category: "hr" },
  { id: "d3", title: "Q1 合約", category: "contract" },
];

const folders = [
  { id: "invoice", label: "發票" },
  { id: "hr", label: "人事", color: "#38bdf8" },
  { id: "contract", label: "合約", color: "#a78bfa" },
];

<FolderFilingGrid
  documents={documents}
  folders={folders}
  autoSort
  onFiledChange={(filed) => console.log(filed)}
/>

Props

Prop型別預設值說明
documentsFilingDocument[]—桌面上的文件
foldersFilingFolder[]—下方資料夾列(建議 3–5 個)
filedFiledMap—受控的歸檔結果;未提供時由元件內部管理(非受控)
defaultFiledFiledMap{}非受控模式的初始歸檔結果
onFiledChange(filed: FiledMap) => void—歸檔結果變動時回呼(每歸一份、或重新散開時觸發)
autoSortbooleanfalse自動整理:開啟時依序把桌面上的文件飛進對應資料夾
intervalnumber350自動整理每份文件之間的間隔(ms)
strictbooleantrue嚴格模式:只能放進分類相符的資料夾,放錯會彈回;關閉則任意資料夾都收
draggablebooleantrue是否允許以滑鼠/觸控拖曳文件
accentstring—資料夾預設色(寫入 --wb-folder-filing-accent);個別資料夾的 color 優先
classNamestring—透傳到最外層容器

FilingDocument

欄位型別預設值說明
idstring—唯一識別碼,也是 filed 對照表的鍵
titlestring—文件標題
categorystring—分類;對應資料夾的 id,找不到對應時歸入最後一個資料夾
metastring—補充說明(金額、日期等),顯示在標題下方
iconReactNode文件圖示自訂圖示

FilingFolder

欄位型別預設值說明
idstring—唯一識別碼,與文件的 category 對應
labelstring—資料夾名稱
colorstringvar(--wb-folder-filing-accent)資料夾顏色

FiledMap

Record<string, string>:文件 id → 資料夾 id。指向不存在資料夾的項目會被視為未歸檔。

細節

  • 節奏外露成 CSS 變數:--wb-folder-filing-fly(飛行時長,預設 560ms)、--wb-folder-filing-open(資料夾張口,預設 180ms)、--wb-folder-filing-accent(資料夾預設色,預設 #f59e0b)。元件在每次歸檔時重讀變數,執行期覆寫立即生效。
  • 飛行路徑:量測文件與資料夾開口的相對座標,水平以 [0.22, 1, 0.36, 1] 緩動、垂直於中段往上抬 40px 形成弧線,同時旋轉歸零、縮放 1 → 0.4 並在尾段淡出。
  • 資料夾前片以底邊為軸 rotateX(-28deg) 張開(perspective: 600px),在文件抵達前 --wb-folder-filing-open 的時間開始張口,剛好接住;落袋後闔上並輕抖 [0, 3, 0]。
  • 拖曳的命中判定用 getBoundingClientRect 比對文件卡中心點與各資料夾範圍;放在桌面空白處會彈回自己的位置。
  • autoSort 開啟期間計時器持續運作:按「重新散開」後文件會再被依序整理,適合做展示迴圈;想只跑一次,在 onFiledChange 看到全部歸檔後把 autoSort 關掉(見示範)。
  • 不使用 Math.random:散落角度(±8°)與位移由 id 與序號雜湊而來,首次渲染與伺服器輸出一致。

可及性

  • 文件卡是 button,以 aria-describedby 說明鍵盤操作:Enter 選取 → 方向鍵(或 Home/End)切換目標資料夾 → Enter 歸檔,Esc 取消;選取中的卡片帶 aria-pressed。也可點一下文件再點資料夾完成歸檔,不必拖曳。
  • 以鍵盤歸檔後,焦點移到下一張仍在桌面上的文件,不會掉回頁面頂端。
  • 資料夾按鈕的 aria-label 含名稱與數量(例如「發票:已收 4 份」),並以 aria-expanded/aria-controls 關聯已收文件面板;面板可按 Esc 或點外面關閉,Esc 會把焦點還給資料夾。
  • 歸檔、退回與散開的結果寫入 aria-live="polite" 區域,由螢幕閱讀器朗讀。
  • 使用者系統開啟「減少動態效果」時,文件直接消失、資料夾不張合也不抖動、計數直接更新,散開時文件直接回到原位。