拖曳排序清單
長按拖曳重排的清單,其他項目讓位流動,附把手。
抓住左側把手即可拖起項目:拖起時浮升放大、微傾斜帶陰影,其他項目以彈簧讓位流動,放下時回彈落位;也支援純鍵盤重排(空白鍵抓取+方向鍵移動),並透過 aria-live 即時播報位置。
載入預覽⋯
安裝
npx shadcn@latest add https://webberui.com/r/drag-reorder-list.json或在 components.json 設定 registries 後,改用 @webberui/drag-reorder-list 安裝。
安裝依賴後,從 registry JSON(/r/drag-reorder-list.json 的 files[0].content)複製 drag-reorder-list.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion lucide-react clsx tailwind-merge使用
import { DragReorderList } from "@/components/ui/drag-reorder-list";
const items = [
{ id: "changelog", icon: "📝", label: "撰寫更新日誌" },
{ id: "deploy", icon: "🚀", label: "部署到正式環境" },
{ id: "newsletter", icon: "✉️", label: "發送電子報" },
];
<DragReorderList items={items} onReorder={(next) => console.log(next)} />Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
items | DragReorderItem[] | — | 清單項目;id 序列改變(受控更新或換資料)時內部順序會同步 |
onReorder | (items: DragReorderItem[]) => void | — | 順序改變時回呼,拖曳換位、鍵盤移動、Esc 還原都會收到最新陣列 |
showIndex | boolean | true | 是否顯示位置編號徽章,換位時會彈跳更新 |
className | string | — | 透傳到最外層容器 |
DragReorderItem 欄位:
| 欄位 | 型別 | 說明 |
|---|---|---|
id | string | 唯一識別碼,作為 key 與排序追蹤依據 |
label | string | 主標題文字 |
description | string(可選) | 次要說明文字 |
icon | React.ReactNode(可選) | 左側裝飾,emoji 字串或任意節點 |
可及性
- 把手為原生
button:聚焦後按空白鍵或 Enter 抓取,上下方向鍵移動,再按空白鍵放下,Esc 取消並還原原順序 - 抓取、移動、放下與頂端/底端邊界皆透過
aria-live區域即時播報(例如「移至位置 2 / 5」) - 把手帶完整
aria-label(項目名稱與目前位置)與aria-pressed抓取狀態;編號徽章與 emoji 對輔助科技隱藏 - 系統開啟「減少動態效果」時,讓位與回彈的彈簧動畫改為瞬間完成
- 拖曳僅由把手觸發(
touch-action: none只作用於把手),清單其餘區域在觸控裝置上仍可正常捲動