|
|
@@ -37,12 +37,41 @@ const tutos = [
|
|
|
console.log(tutos);
|
|
|
|
|
|
class Tree extends React.Component {
|
|
|
+ constructor(props) {
|
|
|
+ super(props);
|
|
|
+ this.onDragStart = this.onDragStart.bind(this);
|
|
|
+ this.onDragOver = this.onDragOver.bind(this);
|
|
|
+ this.state = {
|
|
|
+ draggedItem: null,
|
|
|
+ draggedOver: null
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ onDragStart(draggedItem) {
|
|
|
+ console.log('tree.onDragStart', draggedItem, this);
|
|
|
+ const { draggedOver } = this.state;
|
|
|
+ this.setState((prevState, props) => ({
|
|
|
+ draggedItem, draggedOver
|
|
|
+ }));
|
|
|
+ }
|
|
|
+
|
|
|
+ onDragOver(draggedOver) {
|
|
|
+ console.log('tree.onDragOver', draggedOver, this);
|
|
|
+ const { draggedItem } = this.state;
|
|
|
+ this.setState((prevState, props) => ({
|
|
|
+ draggedItem, draggedOver
|
|
|
+ }));
|
|
|
+ }
|
|
|
+
|
|
|
render() {
|
|
|
const { items } = this.props;
|
|
|
+ const { draggedItem, draggedOver } = this.state;
|
|
|
return (
|
|
|
<div>
|
|
|
+ {(! draggedItem) ? 'X' : draggedItem.props.path} |
|
|
|
+ {(! draggedOver) ? 'Y' : draggedOver.props.path}
|
|
|
{items.map((item, i) =>
|
|
|
- <TreeNode item={item} key={item.title} index={i} level={0} />
|
|
|
+ <TreeNode tree={this} item={item} key={item.title} index={i} path={i} level={0} />
|
|
|
)}
|
|
|
</div>
|
|
|
);
|
|
|
@@ -61,9 +90,12 @@ class TreeNode extends React.Component {
|
|
|
this.onDragOver = this.onDragOver.bind(this);
|
|
|
this.onDragLeave = this.onDragLeave.bind(this);
|
|
|
this.state = {
|
|
|
- dragOver: false
|
|
|
+ dragged: false, dragOver: false, aboveMidLine: false
|
|
|
};
|
|
|
this.hid = getHandleId();
|
|
|
+ console.log('TreeNode', this.props.path, this.props.item.title)
|
|
|
+
|
|
|
+ this.drags = 0;
|
|
|
}
|
|
|
|
|
|
onMouseDown(e) {
|
|
|
@@ -79,8 +111,17 @@ class TreeNode extends React.Component {
|
|
|
|
|
|
const { draggable } = this;
|
|
|
var handle = draggable.getElementsByClassName('drag-handle')[0];
|
|
|
+ console.log('onDragStart', handle, draggable);
|
|
|
if (handle.contains(this.dragTarget)) {
|
|
|
e.dataTransfer.setData('text/plain', handle.id);
|
|
|
+ this.props.tree.onDragStart(this);
|
|
|
+ const { dragOver, aboveMidLine } = this.state;
|
|
|
+
|
|
|
+ this.setState({
|
|
|
+ dragged: true, dragOver, aboveMidLine
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
} else {
|
|
|
e.preventDefault();
|
|
|
}
|
|
|
@@ -97,13 +138,35 @@ class TreeNode extends React.Component {
|
|
|
const aboveMidLine = pageY < this.draggableMidLine;
|
|
|
// console.log(aboveMidLine);
|
|
|
|
|
|
+
|
|
|
+this.props.tree.onDragOver(this);
|
|
|
+
|
|
|
+ const { dragged } = this.state;
|
|
|
// console.log(this.draggable, e.target);
|
|
|
// if(this.draggable !== e.target) return;
|
|
|
- this.setState({
|
|
|
- dragOver: true, aboveMidLine
|
|
|
- });
|
|
|
+ // this.setState({
|
|
|
+ // dragged, dragOver: true, aboveMidLine
|
|
|
+ // });
|
|
|
console.log(this.props.index);
|
|
|
|
|
|
+
|
|
|
+ this.scheduleDragOverChange(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ scheduleDragOverChange(change) {
|
|
|
+ // const setState = this.setState.bind(this);
|
|
|
+ const self = this;
|
|
|
+ if(this.timeout) {
|
|
|
+ clearTimeout(this.timeout);
|
|
|
+ }
|
|
|
+ this.drags += change;
|
|
|
+ // const { dragged, dragOver, }
|
|
|
+ this.timeout = setTimeout(() => {
|
|
|
+ console.log('drags change/total', change, self.drags)
|
|
|
+ this.setState({
|
|
|
+ dragOver: self.drags > 0
|
|
|
+ });
|
|
|
+ }, 100);
|
|
|
}
|
|
|
|
|
|
componentDidMount() {
|
|
|
@@ -113,9 +176,10 @@ class TreeNode extends React.Component {
|
|
|
|
|
|
onDragLeave(e) {
|
|
|
e.stopPropagation();
|
|
|
- this.setState({
|
|
|
- dragOver: false
|
|
|
- });
|
|
|
+ // this.setState({
|
|
|
+ // dragOver: false
|
|
|
+ // });
|
|
|
+ this.scheduleDragOverChange(-1);
|
|
|
// console.log(e.pageY);
|
|
|
// this.dragOver = '';
|
|
|
// console.log('dragleave', this.state.dragOver);
|
|
|
@@ -123,27 +187,27 @@ class TreeNode extends React.Component {
|
|
|
|
|
|
render() {
|
|
|
const { title, items } = this.props.item;
|
|
|
- const { level } = this.props;
|
|
|
+ const { tree, path, level } = this.props;
|
|
|
const { dragOver, aboveMidLine } = this.state;
|
|
|
const paddingLeft = (level * 15) + 'px';
|
|
|
const dragPlaceholderStyles = {
|
|
|
minHeight: '39px', border: '1px dashed blue'
|
|
|
}
|
|
|
return (
|
|
|
- <div
|
|
|
+ <div draggable
|
|
|
+ ref={(div) => { this.draggable = div; }}
|
|
|
className={ "tree-node" + (dragOver ? ' drag-over' : '') }
|
|
|
style={{ paddingLeft }}
|
|
|
onMouseDown={this.onMouseDown}
|
|
|
onDragStart={this.onDragStart}
|
|
|
- onDragOver={this.onDragOver}
|
|
|
- onDragLeave={this.onDragLeave}
|
|
|
- ref={(div) => { this.draggable = div; }}
|
|
|
- draggable>
|
|
|
- <h5><i id={ this.hid } className="material-icons drag-handle">drag_handle</i><span>{ title }</span></h5>
|
|
|
- {(items || []).map((item, i) =>
|
|
|
- <TreeNode item={item} index={i} key={item.title} level={level + 1} />
|
|
|
- )}
|
|
|
- </div>
|
|
|
+ onDragEnter={this.onDragOver}
|
|
|
+ onDragLeave={this.onDragLeave}>
|
|
|
+ <h5><i id={ this.hid } className="material-icons drag-handle">drag_handle</i><span>{ title }</span></h5>
|
|
|
+ {(items || []).map((item, i) =>
|
|
|
+ <TreeNode tree={tree} item={item} index={i} key={item.title} path={ path + '.' + i} level={level + 1} />
|
|
|
+ )}
|
|
|
+ {this.state.dragOver ? <div style={dragPlaceholderStyles}></div> : ''}
|
|
|
+ </div>
|
|
|
);
|
|
|
}
|
|
|
}
|