@6thquake/react-material
Version:
React components that implement Google's Material Design.
147 lines (128 loc) • 3.46 kB
JavaScript
/**
* @ignore - do not document.
*/
import React, { Component } from 'react';
import update from 'immutability-helper';
import { TargetWrapper, DragSource } from '../DragBase';
const rootstyles = {
width: '600px',
border: '1px solid',
height: '280px',
position: 'relative'
};
export function snapToGrid(x, y) {
const snappedX = Math.round(x / 32) * 32;
const snappedY = Math.round(y / 32) * 32;
return [snappedX, snappedY];
}
class TargetBox extends TargetWrapper {
constructor(props) {
super(props);
this.drop = (props, monitor, component) => {
const item = monitor.getItem();
const delta = monitor.getDifferenceFromInitialOffset();
let left = Math.round(item.left + delta.x);
let top = Math.round(item.top + delta.y);
if (this.props.snapToGrid) {
[left, top] = snapToGrid(left, top);
}
if (!item.component) {
// 内部元素被拖动
this.hasDroped = true;
this.moveBox(item.sortFrom, left, top);
}
if (item.component) {
// 外部元素
const temp = this.state.childComponents;
temp.push({
component: item.component,
left,
top
});
this.setState({
childComponents: temp
});
}
};
this.removeComponent = index => {
if (!index && index != 0) {
return;
}
if (this.hasDroped) {// 说明drop在了panel内部 不作处理
} else {
// 说明drop在了panle外部 需要删除指定index
const _cc = this.state.childComponents;
if (!_cc) {
return;
}
_cc.splice(index, 1);
this.setState({
childComponents: _cc
});
}
this.hasDroped = false;
};
this.state = {
childComponents: [],
droptTargetTop: 0,
droptTargetLeft: 0
};
}
moveBox(sortFrom, left, top) {
this.state.childComponents.map((currentV, index) => {
this.setState(update(this.state, {
childComponents: {
[sortFrom]: {
$merge: {
left,
top
}
}
}
}));
});
}
componentDidMount() {
this.props.register(this);
this.setState({
droptTargetLeft: this.dragBox.getBoundingClientRect().left,
droptTargetTop: this.dragBox.getBoundingClientRect().top
});
let acceptSource = ['BoxA'];
acceptSource = [...acceptSource, ...this.props.acceptItem];
this.props.accept(acceptSource); // 给DropTartget传递自己的acceptItem
}
render() {
const {
childComponents,
droptTargetLeft,
droptTargetTop
} = this.state;
let _childComponents = null;
if (childComponents.length > 0) {
const tempChild = childComponents.map((o, i) => {
return React.cloneElement(o.component, {
key: Math.random(),
type: 'INNERITEM',
left: o.left,
top: o.top,
droptTargetLeft,
droptTargetTop
});
});
_childComponents = tempChild.map((currentValue, index) => {
return React.createElement(DragSource, {
index: index,
remove: this.removeComponent
}, currentValue);
});
}
return React.createElement("div", {
style: rootstyles,
ref: box => {
this.dragBox = box;
}
}, _childComponents);
}
}
export default TargetBox;