From 14b5e9d796ea7c73d54a24e4c86ee8778cc21746 Mon Sep 17 00:00:00 2001 From: Paul Vanlerberghe Date: Mon, 7 Feb 2022 11:55:38 +0100 Subject: [PATCH] External node can now be dropped as tree child node as expected --- src/tree-node.tsx | 283 ++++++++++++++++++++------------------- src/utils/dnd-manager.ts | 3 +- 2 files changed, 144 insertions(+), 142 deletions(-) diff --git a/src/tree-node.tsx b/src/tree-node.tsx index 6d64c71c..15ffa001 100644 --- a/src/tree-node.tsx +++ b/src/tree-node.tsx @@ -1,4 +1,4 @@ -import React, { Children, cloneElement } from 'react' +import React, { Children, Component, cloneElement } from 'react' import { ConnectDropTarget } from 'react-dnd' import { classnames } from './utils/classnames' import './tree-node.css' @@ -49,164 +49,167 @@ const defaultProps = { rowDirection: 'ltr', } -const TreeNode: React.FC = (props) => { - props = { ...defaultProps, ...props } - const { - children, - listIndex, - swapFrom, - swapLength, - swapDepth, - scaffoldBlockPxWidth, - lowerSiblingCounts, - connectDropTarget, - isOver, - draggedNode, - canDrop, - treeIndex, - rowHeight, - treeId: _treeId, // Delete from otherProps - getPrevRow: _getPrevRow, // Delete from otherProps - node: _node, // Delete from otherProps - path: _path, // Delete from otherProps - rowDirection, - ...otherProps - } = props - - const rowDirectionClass = rowDirection === 'rtl' ? 'rst__rtl' : undefined - - // Construct the scaffold representing the structure of the tree - const scaffoldBlockCount = lowerSiblingCounts.length - const scaffold: any[] = [] - for (const [i, lowerSiblingCount] of lowerSiblingCounts.entries()) { - let lineClass = '' - if (lowerSiblingCount > 0) { - // At this level in the tree, the nodes had sibling nodes further down - - if (listIndex === 0) { - // Top-left corner of the tree +class TreeNodeComponent extends Component { + render() { + const props = { ...defaultProps, ...this.props } + const { + children, + listIndex, + swapFrom, + swapLength, + swapDepth, + scaffoldBlockPxWidth, + lowerSiblingCounts, + connectDropTarget, + isOver, + draggedNode, + canDrop, + treeIndex, + rowHeight, + treeId: _treeId, // Delete from otherProps + getPrevRow: _getPrevRow, // Delete from otherProps + node: _node, // Delete from otherProps + path: _path, // Delete from otherProps + rowDirection, + ...otherProps + } = props + + const rowDirectionClass = rowDirection === 'rtl' ? 'rst__rtl' : undefined + + // Construct the scaffold representing the structure of the tree + const scaffoldBlockCount = lowerSiblingCounts.length + const scaffold: any[] = [] + for (const [i, lowerSiblingCount] of lowerSiblingCounts.entries()) { + let lineClass = '' + if (lowerSiblingCount > 0) { + // At this level in the tree, the nodes had sibling nodes further down + + if (listIndex === 0) { + // Top-left corner of the tree + // +-----+ + // | | + // | +--+ + // | | | + // +--+--+ + lineClass = 'rst__lineHalfHorizontalRight rst__lineHalfVerticalBottom' + } else if (i === scaffoldBlockCount - 1) { + // Last scaffold block in the row, right before the row content + // +--+--+ + // | | | + // | +--+ + // | | | + // +--+--+ + lineClass = 'rst__lineHalfHorizontalRight rst__lineFullVertical' + } else { + // Simply connecting the line extending down to the next sibling on this level + // +--+--+ + // | | | + // | | | + // | | | + // +--+--+ + lineClass = 'rst__lineFullVertical' + } + } else if (listIndex === 0) { + // Top-left corner of the tree, but has no siblings // +-----+ // | | // | +--+ - // | | | - // +--+--+ - lineClass = 'rst__lineHalfHorizontalRight rst__lineHalfVerticalBottom' + // | | + // +-----+ + lineClass = 'rst__lineHalfHorizontalRight' } else if (i === scaffoldBlockCount - 1) { - // Last scaffold block in the row, right before the row content + // The last or only node in this level of the tree // +--+--+ // | | | // | +--+ - // | | | - // +--+--+ - lineClass = 'rst__lineHalfHorizontalRight rst__lineFullVertical' - } else { - // Simply connecting the line extending down to the next sibling on this level - // +--+--+ - // | | | - // | | | - // | | | - // +--+--+ - lineClass = 'rst__lineFullVertical' - } - } else if (listIndex === 0) { - // Top-left corner of the tree, but has no siblings - // +-----+ - // | | - // | +--+ - // | | - // +-----+ - lineClass = 'rst__lineHalfHorizontalRight' - } else if (i === scaffoldBlockCount - 1) { - // The last or only node in this level of the tree - // +--+--+ - // | | | - // | +--+ - // | | - // +-----+ - lineClass = 'rst__lineHalfVerticalTop rst__lineHalfHorizontalRight' - } - - scaffold.push( -
- ) - - if (treeIndex !== listIndex && i === swapDepth) { - // This row has been shifted, and is at the depth of - // the line pointing to the new destination - let highlightLineClass = '' - - if (listIndex === swapFrom! + swapLength! - 1) { - // This block is on the bottom (target) line - // This block points at the target block (where the row will go when released) - highlightLineClass = 'rst__highlightBottomLeftCorner' - } else if (treeIndex === swapFrom) { - // This block is on the top (source) line - highlightLineClass = 'rst__highlightTopLeftCorner' - } else { - // This block is between the bottom and top - highlightLineClass = 'rst__highlightLineVertical' + // | | + // +-----+ + lineClass = 'rst__lineHalfVerticalTop rst__lineHalfHorizontalRight' } - const style = - rowDirection === 'rtl' - ? { - width: scaffoldBlockPxWidth, - right: scaffoldBlockPxWidth * i, - } - : { - width: scaffoldBlockPxWidth, - left: scaffoldBlockPxWidth * i, - } - scaffold.push(
) + + if (treeIndex !== listIndex && i === swapDepth) { + // This row has been shifted, and is at the depth of + // the line pointing to the new destination + let highlightLineClass = '' + + if (listIndex === swapFrom! + swapLength! - 1) { + // This block is on the bottom (target) line + // This block points at the target block (where the row will go when released) + highlightLineClass = 'rst__highlightBottomLeftCorner' + } else if (treeIndex === swapFrom) { + // This block is on the top (source) line + highlightLineClass = 'rst__highlightTopLeftCorner' + } else { + // This block is between the bottom and top + highlightLineClass = 'rst__highlightLineVertical' + } + + const style = + rowDirection === 'rtl' + ? { + width: scaffoldBlockPxWidth, + right: scaffoldBlockPxWidth * i, + } + : { + width: scaffoldBlockPxWidth, + left: scaffoldBlockPxWidth * i, + } + + scaffold.push( +
+ ) + } } - } - const style = - rowDirection === 'rtl' - ? { right: scaffoldBlockPxWidth * scaffoldBlockCount } - : { left: scaffoldBlockPxWidth * scaffoldBlockCount } + const style = + rowDirection === 'rtl' + ? { right: scaffoldBlockPxWidth * scaffoldBlockCount } + : { left: scaffoldBlockPxWidth * scaffoldBlockCount } - let calculatedRowHeight = rowHeight - if (typeof rowHeight === 'function') { - calculatedRowHeight = rowHeight(treeIndex, _node, _path) - } - return connectDropTarget( -
- {scaffold} - -
- {Children.map(children, (child: any) => - cloneElement(child, { - isOver, - canDrop, - draggedNode, - }) - )} + let calculatedRowHeight = rowHeight + if (typeof rowHeight === 'function') { + calculatedRowHeight = rowHeight(treeIndex, _node, _path) + } + return connectDropTarget( +
(this.node = node)}> + {scaffold} + +
+ {Children.map(children, (child: any) => + cloneElement(child, { + isOver, + canDrop, + draggedNode, + }) + )} +
-
- ) + ) + } } -export default TreeNode +export default TreeNodeComponent diff --git a/src/utils/dnd-manager.ts b/src/utils/dnd-manager.ts index 268b0c5a..c7a6e89a 100644 --- a/src/utils/dnd-manager.ts +++ b/src/utils/dnd-manager.ts @@ -106,8 +106,7 @@ const getTargetDepth = ( dragSourceInitialDepth = 0 if (component) { - const rawComponent = component.getDecoratedComponentInstance() - const relativePosition = rawComponent.node.getBoundingClientRect() + const relativePosition = component.node.getBoundingClientRect() const leftShift = monitor.getSourceClientOffset().x - relativePosition.left blocksOffset = Math.round(