UNPKG

ivue-material-plus

Version:

A high quality UI components Library with Vue.js

1 lines 18 kB
{"version":3,"file":"useDragNode.mjs","sources":["../../../../../../src/components/ivue-tree/hooks/useDragNode.ts"],"sourcesContent":["import { provide, reactive } from 'vue';\r\nimport { removeClass, addClass } from '../../../utils/assist';\r\nimport { NODE_KEY } from '../utils';\r\n\r\n// type\r\nimport type { InjectionKey } from 'vue';\r\nimport type Node from '../store/node';\r\nimport type { NodeDropType } from '../types/tree';\r\n\r\ninterface TreeNode {\r\n node: Node;\r\n $el?: HTMLElement;\r\n}\r\n\r\ninterface DragOptions {\r\n event: DragEvent;\r\n treeNode: TreeNode;\r\n}\r\n\r\n// 拖动方法\r\nexport interface DragEvents {\r\n treeNodeDragStart: (options: DragOptions) => void;\r\n treeNodeDragOver: (options: DragOptions) => void;\r\n treeNodeDragEnd: (event: DragEvent) => void;\r\n}\r\n\r\n// 拖动元素key\r\nexport const dragEventsKey: InjectionKey<DragEvents> =\r\n Symbol('IvueTreeDragEvents');\r\n\r\n// 拖动方法\r\nexport function useDragNodeHandler({\r\n props,\r\n ctx,\r\n treeRef,\r\n dropIndicator,\r\n store,\r\n}) {\r\n // 拖动状态\r\n const dragState = reactive({\r\n showDropIndicator: false,\r\n draggingStartNode: null,\r\n dropNode: null,\r\n allowDrop: true,\r\n dropType: null,\r\n });\r\n\r\n // 节点开始拖动\r\n const treeNodeDragStart = ({ event, treeNode }: DragOptions) => {\r\n // 判断节点能否被拖拽\r\n if (\r\n typeof props.allowDrag === 'function' &&\r\n !props.allowDrag(treeNode.node)\r\n ) {\r\n event.preventDefault();\r\n\r\n return false;\r\n }\r\n\r\n // 一个项目可能会被移动到一个新的位置\r\n event.dataTransfer.effectAllowed = 'move';\r\n\r\n // 当第一个参数是 'text/plain' 时,包装在 try catch 中以解决 IE 的错误\r\n try {\r\n // setData is required for draggable to work in FireFox\r\n // the content has to be '' so dragging a node out of the tree won't open a new tab in FireFox\r\n event.dataTransfer.setData('text/plain', '');\r\n } catch {\r\n /* empty */\r\n }\r\n\r\n // 开始拖动的节点\r\n dragState.draggingStartNode = treeNode;\r\n\r\n // 节点开始拖拽时触发的事件\r\n ctx.emit(\r\n 'on-node-drag-start',\r\n // 被拖拽节点对应的 Node\r\n treeNode.node,\r\n event\r\n );\r\n };\r\n\r\n // 拖动到目标\r\n const treeNodeDragOver = ({ event, treeNode }: DragOptions) => {\r\n // 拖动到目标的元素\r\n const dropNode = treeNode;\r\n\r\n // 上一个拖动到目标的元素\r\n const oldDropNode = dragState.dropNode;\r\n\r\n // 上一个拖动到目标的元素 !== 拖动到目标的元素 删除拖动下划线\r\n if (oldDropNode && oldDropNode !== dropNode) {\r\n removeClass(oldDropNode.$el, 'ivue-tree-drop-indicator');\r\n }\r\n\r\n // 开始拖动的节点\r\n const draggingStartNode = dragState.draggingStartNode;\r\n\r\n // 没有开始拖动的节点 || 没有拖动到目标的元素\r\n if (!draggingStartNode || !dropNode) {\r\n return;\r\n }\r\n\r\n // 放置在目标节点前\r\n let dropPrev = true;\r\n // 插入至目标节点\r\n let dropInner = true;\r\n // 放置在目标节点后\r\n let dropNext = true;\r\n // 是否可以放置在元素内\r\n let userAllowDropInner = true;\r\n\r\n // 拖拽时判定目标节点能否成为拖动目标位置\r\n if (typeof props.allowDrop === 'function') {\r\n dropPrev = props.allowDrop(draggingStartNode.node, dropNode.node, 'prev');\r\n\r\n // 插入至目标节点\r\n dropInner = props.allowDrop(\r\n draggingStartNode.node,\r\n dropNode.node,\r\n 'inner'\r\n );\r\n\r\n userAllowDropInner = dropInner;\r\n\r\n // 放置在目标节点后\r\n dropNext = props.allowDrop(draggingStartNode.node, dropNode.node, 'next');\r\n }\r\n\r\n // 设置在拖放操作\r\n event.dataTransfer.dropEffect =\r\n dropInner || dropPrev || dropNext ? 'move' : 'none';\r\n\r\n // 可以拖动 && 上一个拖动到目标的元素 !== 拖动到目标的元素\r\n if ((dropInner || dropPrev || dropNext) && oldDropNode !== dropNode) {\r\n // 上一个拖动到目标的元素\r\n if (\r\n oldDropNode &&\r\n oldDropNode.node.data[NODE_KEY] !== dropNode.node.data[NODE_KEY]\r\n ) {\r\n // 拖拽离开某个节点时触发的事件\r\n ctx.emit(\r\n 'on-node-drag-leave',\r\n // 被拖拽节点对应的 Node\r\n draggingStartNode.node,\r\n // 所离开节点对应的 Node\r\n oldDropNode.node,\r\n event\r\n );\r\n }\r\n\r\n // 拖拽进入其他节点时触发的事件\r\n ctx.emit(\r\n 'on-node-drag-enter',\r\n // 被拖拽节点对应的 Node\r\n draggingStartNode.node,\r\n // 当前进入节点对应的 Node\r\n dropNode.node,\r\n event\r\n );\r\n }\r\n\r\n // 是否可以拖动到目标元素\r\n if (dropPrev || dropInner || dropNext) {\r\n // 拖动到目标的元素\r\n dragState.dropNode = dropNode;\r\n }\r\n\r\n // 下一个兄弟节点 === 开始拖动的节点 不能放置在目标节点后\r\n if (dropNode.node.nextSibling === draggingStartNode.node) {\r\n dropNext = false;\r\n }\r\n\r\n // 上一个兄弟节点 === 开始拖动的节点 不能放置在目标节点前\r\n if (dropNode.node.prevSibling === draggingStartNode.node) {\r\n dropPrev = false;\r\n }\r\n\r\n // 拖动到目标的元素是否包含开始拖动的节点 不能放置在目标节点前\r\n if (dropNode.node.contains(draggingStartNode.node, false)) {\r\n dropInner = false;\r\n }\r\n\r\n if (\r\n // 拖动开始节点 === 拖动到目标的元素\r\n draggingStartNode.node === dropNode.node ||\r\n // 拖动开始的节点包含拖动到目标的元素\r\n draggingStartNode.node.contains(dropNode.node)\r\n ) {\r\n // 重置数据\r\n dropPrev = false;\r\n dropInner = false;\r\n dropNext = false;\r\n }\r\n\r\n // 当前目标元素位置\r\n const targetPosition = dropNode.$el.getBoundingClientRect();\r\n // tree位置\r\n const treePosition = treeRef.value.getBoundingClientRect();\r\n\r\n // 节点拖动类型\r\n let dropType: NodeDropType;\r\n\r\n // 放置在元素上面百分比差值\r\n const prevPercent = dropPrev\r\n ? dropInner\r\n ? 0.25\r\n : dropNext\r\n ? 0.45\r\n : 1\r\n : -1;\r\n\r\n // 放置在元素下面百分比差值\r\n const nextPercent = dropNext ? (dropInner ? 0.75 : dropPrev ? 0.55 : 0) : 1;\r\n\r\n let indicatorTop = -9999;\r\n\r\n // 拖动到目标的元素与拖动到目标节点\r\n const distance = event.clientY - targetPosition.top;\r\n\r\n // 插入到 拖动到目标的元素 前面\r\n if (distance < targetPosition.height * prevPercent) {\r\n dropType = 'before';\r\n }\r\n // 插入到 拖动到目标的元素 后面\r\n else if (distance > targetPosition.height * nextPercent) {\r\n dropType = 'after';\r\n }\r\n // 插入到 拖动到目标的元素 中间\r\n else if (dropInner) {\r\n dropType = 'inner';\r\n } else {\r\n dropType = 'none';\r\n }\r\n\r\n // 展开图标位置\r\n const iconPosition = dropNode.$el\r\n .querySelector('.ivue-tree-node--expand-icon')\r\n .getBoundingClientRect();\r\n\r\n // 下划线\r\n const _dropIndicator = dropIndicator.value;\r\n\r\n // 设置下划线位置\r\n if (dropType === 'before') {\r\n indicatorTop = iconPosition.top - treePosition.top;\r\n } else if (dropType === 'after') {\r\n indicatorTop = iconPosition.bottom - treePosition.top;\r\n }\r\n\r\n _dropIndicator.style.top = `${indicatorTop}px`;\r\n _dropIndicator.style.left = `${iconPosition.right - treePosition.left}px`;\r\n\r\n // 如果是插入到中间添加样式\r\n if (dropType === 'inner') {\r\n addClass(dropNode.$el, 'is-drop-inner');\r\n }\r\n // 移除中间样式\r\n else {\r\n removeClass(dropNode.$el, 'is-drop-inner');\r\n oldDropNode && removeClass(oldDropNode.$el, 'is-drop-inner');\r\n }\r\n\r\n // 是否显示拖动下划线\r\n dragState.showDropIndicator = dropType === 'before' || dropType === 'after';\r\n\r\n // 拖拽时判定目标节点能否成为拖动目标位置\r\n dragState.allowDrop = dragState.showDropIndicator || userAllowDropInner;\r\n\r\n // 节点拖动类型\r\n dragState.dropType = dropType;\r\n\r\n // 在拖拽节点时触发的事件\r\n ctx.emit(\r\n 'on-node-drag-over',\r\n // 被拖拽节点对应的 Node\r\n draggingStartNode.node,\r\n // 当前进入节点对应的 Node\r\n dropNode.node,\r\n event\r\n );\r\n };\r\n\r\n // 拖动结束\r\n const treeNodeDragEnd = (event: DragEvent) => {\r\n const { draggingStartNode, dropNode, dropType } = dragState;\r\n\r\n // 设置在拖放操作\r\n event.dataTransfer.dropEffect = 'move';\r\n\r\n // 有开始拖动节点 && 有拖动到目标节点\r\n if (draggingStartNode && dropNode) {\r\n const draggingStartNodeCopy = { data: draggingStartNode.node.data };\r\n\r\n // 删除节点\r\n if (dropType !== 'none') {\r\n draggingStartNode.node.remove();\r\n }\r\n\r\n // 插入到节点前面\r\n if (dropType === 'before') {\r\n dropNode.node.parent.insertBefore(draggingStartNodeCopy, dropNode.node);\r\n }\r\n // 插入到节点后面\r\n else if (dropType === 'after') {\r\n dropNode.node.parent.insertAfter(draggingStartNodeCopy, dropNode.node);\r\n }\r\n // 插入到节点中间\r\n else if (dropType === 'inner') {\r\n dropNode.node.insertChild(draggingStartNodeCopy);\r\n }\r\n\r\n // 注册节点\r\n if (dropType !== 'none') {\r\n store.value.registerNode(draggingStartNodeCopy);\r\n }\r\n\r\n // 删除拖动下划线样式\r\n removeClass(dropNode.$el, 'is-drop-inner');\r\n\r\n // 拖拽结束时触发的事件\r\n ctx.emit(\r\n 'on-node-drag-end',\r\n // 被拖拽节点对应的 Node\r\n draggingStartNode.node,\r\n // 结束拖拽时最后进入的节点\r\n dropNode.node,\r\n // 被拖拽节点的放置位置\r\n dropType,\r\n event\r\n );\r\n\r\n // 拖拽成功完成时触发的事件\r\n if (dropType !== 'none') {\r\n ctx.emit(\r\n 'on-node-drop',\r\n // 被拖拽节点对应的 Node\r\n draggingStartNode.node,\r\n // 结束拖拽时最后进入的节点\r\n dropNode.node,\r\n // 被拖拽节点的放置位置\r\n dropType,\r\n event\r\n );\r\n }\r\n }\r\n\r\n // 拖拽结束时未成功触发的事件\r\n if (draggingStartNode && !dropNode) {\r\n ctx.emit(\r\n 'on-node-drag-end',\r\n draggingStartNode.node,\r\n null,\r\n dropType,\r\n event\r\n );\r\n }\r\n\r\n // 初始化数据\r\n dragState.showDropIndicator = false;\r\n dragState.draggingStartNode = null;\r\n dragState.dropNode = null;\r\n dragState.allowDrop = true;\r\n };\r\n\r\n // provide\r\n provide(dragEventsKey, {\r\n treeNodeDragStart,\r\n treeNodeDragOver,\r\n treeNodeDragEnd,\r\n });\r\n\r\n return {\r\n dragState,\r\n };\r\n}\r\n"],"names":[],"mappings":"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"}