react-sortable-tree-node
Version:
react-sortable-tree-node
316 lines (267 loc) • 10.2 kB
JavaScript
"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;