SuperAPI AI 工具集

implementing-drag-drop

前端与建站

查看项目

更新于 10-15 14:21

技能介绍

用途

该技能帮助开发者使用现代 React/TypeScript 库实现拖拽交互与可排序界面,涵盖无障碍优先方法、触摸支持和性能优化,用于创建直观的直接操作型 UI。

适用场景

在以下情况调用该技能:

  • 构建 Trello 风格看板,卡片可在列之间拖拽
  • 创建带拖拽手柄的可排序列表,用于优先级排序
  • 实现带视觉拖拽反馈的文件上传区
  • 为仪表盘组件或画廊构建可重排网格
  • 创建基于节点的可视化构建器界面
  • 实现任何需要通过直接操作进行空间重排的 UI

核心模式

  • 可排序列表:参考 references/dnd-patterns.md,包含带拖拽手柄的垂直列表、用于标签/轮播重排的水平列表、支持 2D 拖拽的网格布局、靠近边缘自动滚动。
  • 看板:参考 references/kanban-implementation.md,包含多列看板与卡片、WIP 限制与泳道、悬停卡片预览、列管理(添加/移除/折叠)。
  • 文件上传区:参考 references/file-dropzone.md,包含视觉反馈状态、文件类型校验、多文件处理、进度指示器。
  • 无障碍:参考 references/accessibility-dnd.md,包含键盘导航模式、屏幕阅读器播报、替代 UI 方案、ARIA 属性。

库选择

主要使用 dnd-kit:面向 React 的现代、无障碍且高性能的拖拽库。参考 references/library-guide.md 了解库对比(dnd-kit 与替代方案)、安装与设置、核心概念与 API、从 react-beautiful-dnd 迁移。

关键特性:内置无障碍支持;触摸、鼠标和键盘输入;零依赖(核心约 10KB);高度可定制;原生 TypeScript。

实现工作流

  1. 分析需求:确定所需拖拽模式——简单列表重排用可排序列表模式;多容器移动用看板模式;文件处理用拖放区模式;复杂交互用可视化构建器模式。
  2. 设置库:安装所需包:
npm install @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities
  1. 实现核心功能:以示例为起点——examples/sortable-list.tsx 用于基础列表;examples/kanban-board.tsx 用于多列看板;examples/file-dropzone.tsx 用于文件上传;examples/grid-reorder.tsx 用于网格布局。
  2. 添加无障碍:参考 references/accessibility-dnd.md 实现键盘导航、添加屏幕阅读器播报、提供替代控件、使用辅助技术测试。运行 scripts/validate_accessibility.js 检查实现。
  3. 优化性能:对于超过 100 项的列表,参考 references/performance-optimization.md,实现虚拟滚动,使用 scripts/calculate_drop_position.js 进行高效计算。
  4. 使用设计令牌样式:应用 design-tokens 技能进行主题化,引用设计令牌变量,实现拖拽状态(悬停、拖拽、放置),添加视觉反馈与动画。

移动端与触摸支持

参考 references/touch-support.md,包含长按启动拖拽、拖拽期间阻止滚动、触摸友好的命中区域(最小 44px)、手势冲突解决。

状态管理

参考 references/state-management.md,包含在 React 中管理拖拽状态、乐观更新、撤销/重做功能、持久化顺序变更。

脚本

  • 计算放置位置:运行 scripts/calculate_drop_position.js 确定有效放置区域、计算插入索引、处理边界情况。
  • 生成配置:运行 scripts/generate_dnd_config.js 创建 dnd-kit 配置、设置传感器与修饰符、配置动画。
  • 验证无障碍:运行 scripts/validate_accessibility.js 检查键盘导航、验证 ARIA 属性、测试屏幕阅读器兼容性。

示例

每个示例都包含完整的 TypeScript 代码与无障碍支持:

  • 可排序列表 examples/sortable-list.tsx:带拖拽手柄的垂直列表;键盘导航(空格/回车抓取,方向键移动);屏幕阅读器播报。
  • 看板 examples/kanban-board.tsx:多列与可拖拽卡片;卡片在列间移动;列管理功能;WIP 限制。
  • 文件拖放区 examples/file-dropzone.tsx:拖拽文件上传;视觉反馈状态;文件类型校验;上传进度。
  • 网格重排 examples/grid-reorder.tsx:2D 网格拖拽;放置时自动布局;响应式断点。

资源

  • TypeScript 类型 assets/drag-state-types.ts 提供:拖拽状态类型定义、事件处理器类型、配置接口。
  • 配置模式 assets/dnd-config-schema.json 定义:有效配置选项、传感器设置、动画参数。

最佳实践

视觉反馈:显示拖拽手柄(⋮⋮)表示可拖拽;改变光标(grab → grabbing);显示放置区占位符;使被拖拽项半透明;高亮有效放置目标。

性能:使用 CSS transform 而非 position 属性;为动画应用 will-change: transform;对大型列表节流拖拽事件;必要时实现虚拟滚动。

无障碍优先:始终提供键盘替代方案;包含屏幕阅读器播报;使用 NVDA/JAWS/VoiceOver 测试;提供非拖拽替代方案(按钮/表单)。

错误处理:显示无效放置反馈;实现撤销功能;成功放置后自动保存;优雅处理网络故障。

常见陷阱

避免以下问题:忘记键盘导航;缺少触摸支持;拖拽期间未阻止滚动;忽略无障碍;大型列表性能差。

解决方案:针对每个问题参考相应指南——无障碍 → references/accessibility-dnd.md;触摸 → references/touch-support.md;性能 → references/performance-optimization.md;状态 → references/state-management.md。

测试清单

部署前验证:键盘导航完全可用;屏幕阅读器播报所有操作;触摸设备可流畅拖拽;在预期数据量下性能可接受;视觉反馈清晰且响应及时;撤销/重做功能正常;为无障碍提供替代 UI;在所有目标浏览器中可用。

后续步骤

实现基础拖拽后:添加高级功能(自动滚动、多选);为移动端实现手势支持;使用 Framer Motion 添加动画润色;创建自定义拖拽预览组件;构建复杂交互(嵌套拖拽)。