UNPKG

react-sortable-tree-node

Version:
316 lines (267 loc) 10.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _reactDnd = require("react-dnd"); var _reactDndHtml5Backend = _interopRequireDefault(require("react-dnd-html5-backend")); var _reactDom = require("react-dom"); var _treeDataUtils = require("./tree-data-utils"); var _memoizedTreeDataUtils = require("./memoized-tree-data-utils"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var DndManager = /*#__PURE__*/function () { function DndManager(treeRef) { _classCallCheck(this, DndManager); this.treeRef = treeRef; } _createClass(DndManager, [{ key: "startDrag", get: function get() { return this.treeRef.startDrag; } }, { key: "dragHover", get: function get() { return this.treeRef.dragHover; } }, { key: "endDrag", get: function get() { return this.treeRef.endDrag; } }, { key: "drop", get: function get() { return this.treeRef.drop; } }, { key: "treeId", get: function get() { return this.treeRef.treeId; } }, { key: "dndType", get: function get() { return this.treeRef.dndType; } }, { key: "treeData", get: function get() { return this.treeRef.state.draggingTreeData || this.treeRef.props.treeData; } }, { key: "getNodeKey", get: function get() { return this.treeRef.props.getNodeKey; } }, { key: "customCanDrop", get: function get() { return this.treeRef.props.canDrop; } }, { key: "maxDepth", get: function get() { return this.treeRef.props.maxDepth; } }, { key: "getTargetDepth", value: function getTargetDepth(dropTargetProps, monitor, component) { var dropTargetDepth = 0; var rowAbove = dropTargetProps.getPrevRow(); if (rowAbove) { var path = rowAbove.path; var aboveNodeCannotHaveChildren = !this.treeRef.canNodeHaveChildren(rowAbove.node); if (aboveNodeCannotHaveChildren) { path = path.slice(0, path.length - 1); } // Limit the length of the path to the deepest possible dropTargetDepth = Math.min(path.length, dropTargetProps.path.length); } var blocksOffset; var dragSourceInitialDepth = (monitor.getItem().path || []).length; // When adding node from external source if (monitor.getItem().treeId !== this.treeId) { // Ignore the tree depth of the source, if it had any to begin with dragSourceInitialDepth = 0; if (component) { var relativePosition = (0, _reactDom.findDOMNode)(component).getBoundingClientRect(); // eslint-disable-line react/no-find-dom-node var leftShift = monitor.getSourceClientOffset().x - relativePosition.left; blocksOffset = Math.round(leftShift / dropTargetProps.scaffoldBlockPxWidth); } else { blocksOffset = dropTargetProps.path.length; } } else { // handle row direction support var direction = dropTargetProps.rowDirection === 'rtl' ? -1 : 1; blocksOffset = Math.round(direction * monitor.getDifferenceFromInitialOffset().x / dropTargetProps.scaffoldBlockPxWidth); } var targetDepth = Math.min(dropTargetDepth, Math.max(0, dragSourceInitialDepth + blocksOffset - 1)); // If a maxDepth is defined, constrain the target depth if (typeof this.maxDepth !== 'undefined' && this.maxDepth !== null) { var draggedNode = monitor.getItem().node; var draggedChildDepth = (0, _treeDataUtils.getDepth)(draggedNode); targetDepth = Math.max(0, Math.min(targetDepth, this.maxDepth - draggedChildDepth - 1)); } return targetDepth; } }, { key: "canDrop", value: function canDrop(dropTargetProps, monitor) { if (!monitor.isOver()) { return false; } var rowAbove = dropTargetProps.getPrevRow(); var abovePath = rowAbove ? rowAbove.path : []; var aboveNode = rowAbove ? rowAbove.node : {}; var targetDepth = this.getTargetDepth(dropTargetProps, monitor, null); // Cannot drop if we're adding to the children of the row above and // the row above is a function if (targetDepth >= abovePath.length && typeof aboveNode.children === 'function') { return false; } if (typeof this.customCanDrop === 'function') { var _monitor$getItem = monitor.getItem(), node = _monitor$getItem.node; var addedResult = (0, _memoizedTreeDataUtils.memoizedInsertNode)({ treeData: this.treeData, newNode: node, depth: targetDepth, getNodeKey: this.getNodeKey, minimumTreeIndex: dropTargetProps.listIndex, expandParent: true }); return this.customCanDrop({ node: node, prevPath: monitor.getItem().path, prevParent: monitor.getItem().parentNode, prevTreeIndex: monitor.getItem().treeIndex, // Equals -1 when dragged from external tree nextPath: addedResult.path, nextParent: addedResult.parentNode, nextTreeIndex: addedResult.treeIndex }); } return true; } }, { key: "wrapSource", value: function wrapSource(el) { var _this = this; var nodeDragSource = { beginDrag: function beginDrag(props) { _this.startDrag(props); return { node: props.node, parentNode: props.parentNode, path: props.path, treeIndex: props.treeIndex, treeId: props.treeId }; }, endDrag: function endDrag(props, monitor) { _this.endDrag(monitor.getDropResult()); }, isDragging: function isDragging(props, monitor) { var dropTargetNode = monitor.getItem().node; var draggedNode = props.node; return draggedNode === dropTargetNode; } }; function nodeDragSourcePropInjection(connect, monitor) { return { connectDragSource: connect.dragSource(), connectDragPreview: connect.dragPreview(), isDragging: monitor.isDragging(), didDrop: monitor.didDrop() }; } return (0, _reactDnd.DragSource)(this.dndType, nodeDragSource, nodeDragSourcePropInjection)(el); } }, { key: "wrapTarget", value: function wrapTarget(el) { var _this2 = this; var nodeDropTarget = { drop: function drop(dropTargetProps, monitor, component) { var result = { node: monitor.getItem().node, path: monitor.getItem().path, treeIndex: monitor.getItem().treeIndex, treeId: _this2.treeId, minimumTreeIndex: dropTargetProps.treeIndex, depth: _this2.getTargetDepth(dropTargetProps, monitor, component) }; _this2.drop(result); return result; }, hover: function hover(dropTargetProps, monitor, component) { var targetDepth = _this2.getTargetDepth(dropTargetProps, monitor, component); var draggedNode = monitor.getItem().node; var needsRedraw = // Redraw if hovered above different nodes dropTargetProps.node !== draggedNode || // Or hovered above the same node but at a different depth targetDepth !== dropTargetProps.path.length - 1; if (!needsRedraw) { return; } _this2.dragHover({ node: draggedNode, path: monitor.getItem().path, minimumTreeIndex: dropTargetProps.listIndex, depth: targetDepth }); }, canDrop: this.canDrop.bind(this) }; function nodeDropTargetPropInjection(connect, monitor) { var dragged = monitor.getItem(); return { connectDropTarget: connect.dropTarget(), isOver: monitor.isOver(), canDrop: monitor.canDrop(), draggedNode: dragged ? dragged.node : null }; } return (0, _reactDnd.DropTarget)(this.dndType, nodeDropTarget, nodeDropTargetPropInjection)(el); } }, { key: "wrapPlaceholder", value: function wrapPlaceholder(el) { var _this3 = this; var placeholderDropTarget = { drop: function drop(dropTargetProps, monitor) { var _monitor$getItem2 = monitor.getItem(), node = _monitor$getItem2.node, path = _monitor$getItem2.path, treeIndex = _monitor$getItem2.treeIndex; var result = { node: node, path: path, treeIndex: treeIndex, treeId: _this3.treeId, minimumTreeIndex: 0, depth: 0 }; _this3.drop(result); return result; } }; function placeholderPropInjection(connect, monitor) { var dragged = monitor.getItem(); return { connectDropTarget: connect.dropTarget(), isOver: monitor.isOver(), canDrop: monitor.canDrop(), draggedNode: dragged ? dragged.node : null }; } return (0, _reactDnd.DropTarget)(this.dndType, placeholderDropTarget, placeholderPropInjection)(el); } }], [{ key: "wrapRoot", value: function wrapRoot(el) { return (0, _reactDnd.DragDropContext)(_reactDndHtml5Backend.default)(el); } }]); return DndManager; }(); exports.default = DndManager;