拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Pragmatic Drag and Drop 全解析:跨技术栈的底层拖放工具链

Pragmatic Drag and Drop 全解析跨技术栈的底层拖放工具链【免费下载链接】pragmatic-drag-and-dropFast drag and drop for any experience on any tech stack项目地址: https://gitcode.com/GitHub_Trending/pr/pragmatic-drag-and-drop导读Pragmatic drag and drop仓库根目录 README.md 的完整介绍是 Atlassian 开源的底层拖放drag and drop工具链它让开发者能够安全、高效地驾驭浏览器内置拖放能力同时适用于 React、Svelte、Vue、Angular 等任意视图层并已支撑 Trello、Jira、Confluence 等大型 Web 产品。读完本文你将掌握它的核心设计理念、三层能力体系低层行为、可选视觉输出、可选无障碍控制、atlaskit包族的按需引入机制以及如何在自己的设计系统与设计语言下搭建拖放体验。一、这是什么一个低层拖放工具链Pragmatic drag and drop 定位为low level drag and drop toolchain低层拖放工具链而不是开箱即用的完整组件库。它围绕浏览器原生的 Drag and Drop API 提供一层可靠的封装帮助你避免直接操作原生 API 时常见的坑事件时序、跨浏览器差异、移动端支持等并在此之上自由构建任何拖放体验。几个关键事实均可在根目录 README.md 中确认框架无关不绑定任何视图层可配合react、svelte、vue、angular使用生产验证已被 Trello、Jira、Confluence 等大型产品使用开源形态本仓库是 Atlassian 内部 monorepo 的单向镜像目的是公开代码现阶段不接受代码贡献但欢迎提交 issue 与建议所有文档与npm包均公开可用。值得强调的设计基调是对视觉语言与无障碍不预设观点核心包不依赖 Atlassian Design System你可以完全掌控渲染与样式。仓库镜像机制本仓库当前为内部 monorepo 的单向镜像镜像仓库每天同步一次而npm包在内部仓库合并新版本后会立即发布。这意味着代码可能比镜像仓库早最多 24 小时出现在npm上README.md 的 npm release and repo sync timing 一节。因此查看最新发布能力以npm包为准查看完整源码与文档以本仓库为准。二、三层能力体系README 将项目能力划分为三个高层次的组成部分这也是理解整个项目结构的主线。1. 低层拖放行为核心包 可选包Pragmatic drag and drop 由一个core 包和多个可选包optional packages组成提供构建任意拖放体验的零件。核心包与可选包具备以下特征极小Tiny核心包约4.7kBREADME 中声明的核心包体积增量Incremental只引入你需要的零件避免全量加载无头Headless完整的渲染与样式控制权交给你框架无关Framework agnostic兼容任意前端框架延迟加载兼容Deferred compatible可以推迟加载核心包与可选包进一步优化页面加载速度灵活Flexible拖拽过程中可以随时调整体验做任何你想做的修改全平台支持Works everywhereFirefox、Safari、Chrome 以及 iOS、Android 均具备完整功能支持虚拟化支持Virtualization support可以构建任意虚拟化列表体验。2. 可选视觉输出项目提供了一些可选的视觉输出例如 drop indicator 放置指示器用于快速构建一致的 Atlassian 风格用户体验。非 Atlassian 使用者可以直接使用这些输出仿照其视觉风格创建自己的组件或完全走不同的方向。也就是说视觉输出是可替换、可借鉴、可绕过的。3. 可选无障碍控制并非所有用户都能完成基于指针的拖放。为此项目提供了一套工具链让你能够为无障碍技术用户快速接入高性能、友好的拖放流程。这些可选控制基于 Atlassian Design System如果你不想使用该设计系统可以依据项目的无障碍指南替换为自有组件或用其他方式实现无障碍支持。三、atlaskit包族与按需引入所有 Pragmatic drag and drop 包都发布在npm的atlaskit命名空间下。README 给出的标准导入示例import { draggable } from atlaskit/pragmatic-drag-and-drop/element/adapter;atlaskit是 Atlassian 内部 monorepo 发布公共包所用的命名空间。README 说明未来可能会为 Pragmatic drag and drop 单独建立命名空间若发生变更官方会提供自动化切换工具。为什么用子路径入口subpath entry points在核心包 packages/core/package.json 中可以看到包通过exports字段暴露了大量细粒度的子路径入口例如./element/adapter./element/set-custom-native-drag-preview./element/center-under-pointer./element/preserve-offset-on-source./external/adapter./external/file、./external/text、./external/url./text-selection/adapter./combine、./once、./reorder、./prevent-unhandled./types根入口 packages/core/src/index.ts 刻意不导出任何 API仅export default {}注释明确写道Please use individual entry points in order to always obtain minimum kbs.—— 即通过独立入口引入以保证始终获得最小体积。这正是 README 所述极小增量延迟加载兼容等特性的工程化落地打包器可以精确 tree-shake只把用到的拖放能力包含进产物。三种适配器Adapter从核心包的 入口目录结构 可以看到三种适配器分别对应三类拖放场景适配器入口用途Element adapterelement/adapter拖拽页面内的 DOM 元素最常用External adapterexternal/adapter从浏览器外部拖入数据文件、文本、URL、HTML 等Text selection adaptertext-selection/adapter拖拽页面内的文本选区当前 element adapter 入口 标注为 deprecated 的转发 shim推荐改用新的导入路径atlaskit/pragmatic-drag-and-drop/adapter/element-adapterdropTargetForElements、monitorForElements同理。external 与 text-selection 适配器入口也遵循相同的迁移策略见 external adapter 入口 与 text-selection adapter 入口。适配器内部makeAdapter 架构三种适配器由统一的工厂 make-adapter.ts 生成。它接收typeKey如element、mount、dispatchEventToSource、defaultDropEffect等配置返回registerUsage、dropTarget、monitor三个能力。事件分发顺序固定为转发给拖拽源source转发给相关的 drop target转发给 monitor执行 post-dispatch 钩子用于 honey-pot 修复等。这套统一工厂保证了三种适配器行为一致也是任意拖放体验可以复用的底层骨架。四、核心 API 实战element adapter以最常用的 element adapter 为例其核心 API 定义在 element-adapter.ts由三组函数构成draggable(args)让一个HTMLElement可被拖拽返回CleanupFn用于卸载dropTargetForElements(args)注册元素放置目标monitorForElements(args)监听整个拖放过程。draggable 参数详解参数类型说明elementHTMLElement挂载拖拽行为的元素同时是 draggable 的唯一键只有HTMLElement能设置draggable属性dragHandleElement可选用于控制整个元素拖拽的手柄手柄必须包含在element内部canDrag(args) boolean条件性允许拖拽在拖拽开始前调用getInitialData(args) Recordstring, unknown为拖拽操作附加数据仅在本页面的 drag 操作中可用getInitialDataForExternal(args) { [Key in NativeMediaType]?: string }把数据写入原生拖放数据存储dataTransfer可被其他页面/应用读取不会触发当前页面的 external adapterdraggable()内部做了三项工作对应 element-adapter.ts 中draggable的实现将参数注册进WeakMap注册表draggableRegistry并以element为键调用adapter.registerUsage()确保适配器事件监听随第一个 draggable 挂载、随最后一个 draggable 卸载——这就是按需引入、用完即走的生命周期管理给元素添加draggabletrue属性。事件与反馈函数draggable、dropTargetForElements、monitorForElements都支持一组事件onDragStart、onDrag、onDrop、onGenerateDragPreview等以及反馈函数如canDrag、canDrop、canMonitor。源码注释展示了一个典型反馈参数结构DraggableGetFeedbackArgstype DraggableGetFeedbackArgs { input: Input; // 拖拽尝试开始时的用户输入initial input element: HTMLElement; // draggable 元素 dragHandle: Element | null; // draggable 的拖拽手柄 };平台兼容细节源码佐证在 element-adapter.ts 的dragstart监听器中可以看到大量平台细节处理反映 README 所述Works everywhere的实现深度AndroidisAndroid()时如果原生数据存储中没有text/plain或text/uri-list类型会写入一个 fallback 文本否则 Android 上根本不会启动拖拽iOS 15 / Firefox为让iOS15正常工作必须设置至少一种媒体类型同时写入elementAdapterNativeDataKey标记让 external adapter 能识别此拖拽已被 element adapter 接管拖拽手柄校验配置了dragHandle时会用getElementFromPointWithoutHoneypot获取指针下的元素只有指针落在手柄或其子元素内才允许拖拽否则preventDefault()取消操作开发期守护非生产环境会警告手柄必须包含在 draggable 内同一元素重复注册等问题。这些细节说明README 中的安全、成功使用浏览器内置拖放功能并非空话而是将多年浏览器兼容经验沉淀进工具链的结果。五、可选包全景按需组合的能力矩阵仓库采用 yarn workspaces 管理多包 monorepo见根目录 package.json 的workspaces: [packages/*]。除了核心包packages/下还有一系列可选包每个包的name都以atlaskit/pragmatic-drag-and-drop-开头可选包仓库路径定位auto-scrollpackages/auto-scroll拖拽到边缘/元素附近时自动滚动over-element 与 overflow 两种模式hitboxpackages/hitbox计算最近边缘closest edge、生成排序指令、列表/树重排工具react-drop-indicatorpackages/react-drop-indicatorReact 放置指示器border、line、outline、box、group、list-item、tree-item 等视觉形态flourishpackages/flourish拖放后的动效装饰如triggerPostMoveFlashlive-regionpackages/live-region无障碍实时区域screen reader 播报react-accessibilitypackages/react-accessibilityReact 无障碍组件如 drag handle buttonreact-beautiful-dnd-autoscrollpackages/react-beautiful-dnd-autoscroll移植自 react-beautiful-dnd 的自动滚动算法react-beautiful-dnd-migrationpackages/react-beautiful-dnd-migration从 react-beautiful-dnd 迁移的工具链含 codemodsunit-testingpackages/unit-testing单测辅助DragEventpolyfill、DOMRectpolyfill这些包正是 README 所述可选视觉输出与可选无障碍控制的实现react-drop-indicator、flourish对应视觉输出live-region、react-accessibility对应无障碍控制hitbox、auto-scroll则属于低层行为的可选增强。你可以按需挑选组合完全不依赖 Atlassian 设计系统也能使用核心能力。公共工具函数核心包还提供几个无 UI 的小工具位于 packages/core/src/public-utilscombine把多个CleanupFn合并为一个一次调用全部清理适配器内部也大量使用once保证函数只执行一次并缓存结果用于防止 cleanup 被重复调用reorder不可变地重排数组返回新数组且不改动原数组与元素prevent-unhandled阻止未处理的拖放导致默认浏览器行为。这些工具在 packages/core/package.json 的exports中都有独立入口./combine、./once、./reorder、./prevent-unhandled同样遵循按需引入原则。六、自己的设计系统与设计语言可以吗README 明确回答了社区最关心的两个问题Q我能搭配自己的设计系统使用吗可以。核心包很小可选包可以自由组合。部分可选包对样式方案如emotion、视图库如react或 Atlassian 额外产物如atlaskit/tokens有依赖项目刻意将这些带依赖的可选包分离出来便于你用自研的零件基于自己的技术栈与视觉输出替换它们。Q我能使用自己的设计语言吗可以。项目提供了体现自身设计理念的 guidelines见 documentation 包中的设计指南其中一部分决策固化进了可选包但你可以自由使用任何设计语言包括直接沿用项目自带的那套。换言之核心是纯逻辑工具链视觉与交互语言完全由你决定。七、测试与质量保障仓库为多包配置了统一的测试体系根目录 jest.config.jstest脚本为jest --forceExit。每个包都包含两类测试unit 单测例如 core 包的 unit 测试覆盖适配器、事件顺序、生命周期、异常恢复等playwright 浏览器测试例如 core 包的 playwright 测试覆盖 iframe、honey-pot、文本选择、外部文件拖放、粘性stickiness等真实浏览器行为。此外还有专门的 unit-testing 包 提供DragEvent与DOMRect的 polyfill帮助你在 jsdom 单测环境中正确模拟原生拖放事件。若你计划自行扩展或深入理解实现这些测试是绝佳的行为规格说明书。八、总结何时选择 Pragmatic drag and drop你需要对拖放体验有绝对控制权自定义视觉、自定义交互、任意框架你需要可靠的浏览器与移动端兼容Chrome、Firefox、Safari、iOS、Android而不想自己踩坑你重视包体积与加载性能希望按需引入、延迟加载、极小的核心包你需要无障碍友好的拖放方案且愿意按官方指南接入自己的组件你需要从 react-beautiful-dnd 迁移官方提供了专门的 migration 包与 codemods。如果你需要的是开箱即用的完整拖放组件自带外观与交互那么应基于本工具链自行封装如果你需要的是任意体验、任意技术栈上的底层可靠能力Pragmatic drag and drop 提供了模块化、可组合、经大型产品验证的解决方案。相关资源仓库内项目总览README.md核心包说明与导出地图packages/core/package.json核心包源码入口packages/core/src/index.tsElement 适配器实现packages/core/src/adapter/element-adapter.ts统一适配器工厂packages/core/src/make-adapter/make-adapter.ts核心示例board、拖拽手柄、虚拟列表等packages/documentation/examples设计指南packages/documentation/constellation/08-design-guidelines/index.mdx【免费下载链接】pragmatic-drag-and-dropFast drag and drop for any experience on any tech stack项目地址: https://gitcode.com/GitHub_Trending/pr/pragmatic-drag-and-drop创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门