Skip to content
This repository was archived by the owner on Sep 19, 2024. It is now read-only.

Commit 1243b34

Browse files
authored
Merge pull request #15 from assembl/fix-external-node
External node can now be dropped as tree child node as expected
2 parents 53ce600 + 14b5e9d commit 1243b34

File tree

2 files changed

+144
-142
lines changed

2 files changed

+144
-142
lines changed

src/tree-node.tsx

+143-140
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { Children, cloneElement } from 'react'
1+
import React, { Children, Component, cloneElement } from 'react'
22
import { ConnectDropTarget } from 'react-dnd'
33
import { classnames } from './utils/classnames'
44
import './tree-node.css'
@@ -49,164 +49,167 @@ const defaultProps = {
4949
rowDirection: 'ltr',
5050
}
5151

52-
const TreeNode: React.FC<TreeRendererProps> = (props) => {
53-
props = { ...defaultProps, ...props }
54-
const {
55-
children,
56-
listIndex,
57-
swapFrom,
58-
swapLength,
59-
swapDepth,
60-
scaffoldBlockPxWidth,
61-
lowerSiblingCounts,
62-
connectDropTarget,
63-
isOver,
64-
draggedNode,
65-
canDrop,
66-
treeIndex,
67-
rowHeight,
68-
treeId: _treeId, // Delete from otherProps
69-
getPrevRow: _getPrevRow, // Delete from otherProps
70-
node: _node, // Delete from otherProps
71-
path: _path, // Delete from otherProps
72-
rowDirection,
73-
...otherProps
74-
} = props
75-
76-
const rowDirectionClass = rowDirection === 'rtl' ? 'rst__rtl' : undefined
77-
78-
// Construct the scaffold representing the structure of the tree
79-
const scaffoldBlockCount = lowerSiblingCounts.length
80-
const scaffold: any[] = []
81-
for (const [i, lowerSiblingCount] of lowerSiblingCounts.entries()) {
82-
let lineClass = ''
83-
if (lowerSiblingCount > 0) {
84-
// At this level in the tree, the nodes had sibling nodes further down
85-
86-
if (listIndex === 0) {
87-
// Top-left corner of the tree
52+
class TreeNodeComponent extends Component<TreeRendererProps> {
53+
render() {
54+
const props = { ...defaultProps, ...this.props }
55+
const {
56+
children,
57+
listIndex,
58+
swapFrom,
59+
swapLength,
60+
swapDepth,
61+
scaffoldBlockPxWidth,
62+
lowerSiblingCounts,
63+
connectDropTarget,
64+
isOver,
65+
draggedNode,
66+
canDrop,
67+
treeIndex,
68+
rowHeight,
69+
treeId: _treeId, // Delete from otherProps
70+
getPrevRow: _getPrevRow, // Delete from otherProps
71+
node: _node, // Delete from otherProps
72+
path: _path, // Delete from otherProps
73+
rowDirection,
74+
...otherProps
75+
} = props
76+
77+
const rowDirectionClass = rowDirection === 'rtl' ? 'rst__rtl' : undefined
78+
79+
// Construct the scaffold representing the structure of the tree
80+
const scaffoldBlockCount = lowerSiblingCounts.length
81+
const scaffold: any[] = []
82+
for (const [i, lowerSiblingCount] of lowerSiblingCounts.entries()) {
83+
let lineClass = ''
84+
if (lowerSiblingCount > 0) {
85+
// At this level in the tree, the nodes had sibling nodes further down
86+
87+
if (listIndex === 0) {
88+
// Top-left corner of the tree
89+
// +-----+
90+
// | |
91+
// | +--+
92+
// | | |
93+
// +--+--+
94+
lineClass = 'rst__lineHalfHorizontalRight rst__lineHalfVerticalBottom'
95+
} else if (i === scaffoldBlockCount - 1) {
96+
// Last scaffold block in the row, right before the row content
97+
// +--+--+
98+
// | | |
99+
// | +--+
100+
// | | |
101+
// +--+--+
102+
lineClass = 'rst__lineHalfHorizontalRight rst__lineFullVertical'
103+
} else {
104+
// Simply connecting the line extending down to the next sibling on this level
105+
// +--+--+
106+
// | | |
107+
// | | |
108+
// | | |
109+
// +--+--+
110+
lineClass = 'rst__lineFullVertical'
111+
}
112+
} else if (listIndex === 0) {
113+
// Top-left corner of the tree, but has no siblings
88114
// +-----+
89115
// | |
90116
// | +--+
91-
// | | |
92-
// +--+--+
93-
lineClass = 'rst__lineHalfHorizontalRight rst__lineHalfVerticalBottom'
117+
// | |
118+
// +-----+
119+
lineClass = 'rst__lineHalfHorizontalRight'
94120
} else if (i === scaffoldBlockCount - 1) {
95-
// Last scaffold block in the row, right before the row content
121+
// The last or only node in this level of the tree
96122
// +--+--+
97123
// | | |
98124
// | +--+
99-
// | | |
100-
// +--+--+
101-
lineClass = 'rst__lineHalfHorizontalRight rst__lineFullVertical'
102-
} else {
103-
// Simply connecting the line extending down to the next sibling on this level
104-
// +--+--+
105-
// | | |
106-
// | | |
107-
// | | |
108-
// +--+--+
109-
lineClass = 'rst__lineFullVertical'
110-
}
111-
} else if (listIndex === 0) {
112-
// Top-left corner of the tree, but has no siblings
113-
// +-----+
114-
// | |
115-
// | +--+
116-
// | |
117-
// +-----+
118-
lineClass = 'rst__lineHalfHorizontalRight'
119-
} else if (i === scaffoldBlockCount - 1) {
120-
// The last or only node in this level of the tree
121-
// +--+--+
122-
// | | |
123-
// | +--+
124-
// | |
125-
// +-----+
126-
lineClass = 'rst__lineHalfVerticalTop rst__lineHalfHorizontalRight'
127-
}
128-
129-
scaffold.push(
130-
<div
131-
key={`pre_${1 + i}`}
132-
style={{ width: scaffoldBlockPxWidth }}
133-
className={classnames(
134-
'rst__lineBlock',
135-
lineClass,
136-
rowDirectionClass ?? ''
137-
)}
138-
/>
139-
)
140-
141-
if (treeIndex !== listIndex && i === swapDepth) {
142-
// This row has been shifted, and is at the depth of
143-
// the line pointing to the new destination
144-
let highlightLineClass = ''
145-
146-
if (listIndex === swapFrom! + swapLength! - 1) {
147-
// This block is on the bottom (target) line
148-
// This block points at the target block (where the row will go when released)
149-
highlightLineClass = 'rst__highlightBottomLeftCorner'
150-
} else if (treeIndex === swapFrom) {
151-
// This block is on the top (source) line
152-
highlightLineClass = 'rst__highlightTopLeftCorner'
153-
} else {
154-
// This block is between the bottom and top
155-
highlightLineClass = 'rst__highlightLineVertical'
125+
// | |
126+
// +-----+
127+
lineClass = 'rst__lineHalfVerticalTop rst__lineHalfHorizontalRight'
156128
}
157129

158-
const style =
159-
rowDirection === 'rtl'
160-
? {
161-
width: scaffoldBlockPxWidth,
162-
right: scaffoldBlockPxWidth * i,
163-
}
164-
: {
165-
width: scaffoldBlockPxWidth,
166-
left: scaffoldBlockPxWidth * i,
167-
}
168-
169130
scaffold.push(
170131
<div
171-
key={i}
172-
style={style}
132+
key={`pre_${1 + i}`}
133+
style={{ width: scaffoldBlockPxWidth }}
173134
className={classnames(
174-
'rst__absoluteLineBlock',
175-
highlightLineClass,
135+
'rst__lineBlock',
136+
lineClass,
176137
rowDirectionClass ?? ''
177138
)}
178139
/>
179140
)
141+
142+
if (treeIndex !== listIndex && i === swapDepth) {
143+
// This row has been shifted, and is at the depth of
144+
// the line pointing to the new destination
145+
let highlightLineClass = ''
146+
147+
if (listIndex === swapFrom! + swapLength! - 1) {
148+
// This block is on the bottom (target) line
149+
// This block points at the target block (where the row will go when released)
150+
highlightLineClass = 'rst__highlightBottomLeftCorner'
151+
} else if (treeIndex === swapFrom) {
152+
// This block is on the top (source) line
153+
highlightLineClass = 'rst__highlightTopLeftCorner'
154+
} else {
155+
// This block is between the bottom and top
156+
highlightLineClass = 'rst__highlightLineVertical'
157+
}
158+
159+
const style =
160+
rowDirection === 'rtl'
161+
? {
162+
width: scaffoldBlockPxWidth,
163+
right: scaffoldBlockPxWidth * i,
164+
}
165+
: {
166+
width: scaffoldBlockPxWidth,
167+
left: scaffoldBlockPxWidth * i,
168+
}
169+
170+
scaffold.push(
171+
<div
172+
key={i}
173+
style={style}
174+
className={classnames(
175+
'rst__absoluteLineBlock',
176+
highlightLineClass,
177+
rowDirectionClass ?? ''
178+
)}
179+
/>
180+
)
181+
}
180182
}
181-
}
182183

183-
const style =
184-
rowDirection === 'rtl'
185-
? { right: scaffoldBlockPxWidth * scaffoldBlockCount }
186-
: { left: scaffoldBlockPxWidth * scaffoldBlockCount }
184+
const style =
185+
rowDirection === 'rtl'
186+
? { right: scaffoldBlockPxWidth * scaffoldBlockCount }
187+
: { left: scaffoldBlockPxWidth * scaffoldBlockCount }
187188

188-
let calculatedRowHeight = rowHeight
189-
if (typeof rowHeight === 'function') {
190-
calculatedRowHeight = rowHeight(treeIndex, _node, _path)
191-
}
192-
return connectDropTarget(
193-
<div
194-
{...otherProps}
195-
style={{ height: `${calculatedRowHeight}px` }}
196-
className={classnames('rst__node', rowDirectionClass ?? '')}>
197-
{scaffold}
198-
199-
<div className="rst__nodeContent" style={style}>
200-
{Children.map(children, (child: any) =>
201-
cloneElement(child, {
202-
isOver,
203-
canDrop,
204-
draggedNode,
205-
})
206-
)}
189+
let calculatedRowHeight = rowHeight
190+
if (typeof rowHeight === 'function') {
191+
calculatedRowHeight = rowHeight(treeIndex, _node, _path)
192+
}
193+
return connectDropTarget(
194+
<div
195+
{...otherProps}
196+
style={{ height: `${calculatedRowHeight}px` }}
197+
className={classnames('rst__node', rowDirectionClass ?? '')}
198+
ref={(node) => (this.node = node)}>
199+
{scaffold}
200+
201+
<div className="rst__nodeContent" style={style}>
202+
{Children.map(children, (child: any) =>
203+
cloneElement(child, {
204+
isOver,
205+
canDrop,
206+
draggedNode,
207+
})
208+
)}
209+
</div>
207210
</div>
208-
</div>
209-
)
211+
)
212+
}
210213
}
211214

212-
export default TreeNode
215+
export default TreeNodeComponent

src/utils/dnd-manager.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,7 @@ const getTargetDepth = (
106106
dragSourceInitialDepth = 0
107107

108108
if (component) {
109-
const rawComponent = component.getDecoratedComponentInstance()
110-
const relativePosition = rawComponent.node.getBoundingClientRect()
109+
const relativePosition = component.node.getBoundingClientRect()
111110
const leftShift =
112111
monitor.getSourceClientOffset().x - relativePosition.left
113112
blocksOffset = Math.round(

0 commit comments

Comments
 (0)