Skip to content

Commit

Permalink
Use hover() for sortable
Browse files Browse the repository at this point in the history
  • Loading branch information
gaearon committed Mar 26, 2015
1 parent 3764e2b commit d2dbf37
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 36 deletions.
34 changes: 16 additions & 18 deletions examples/_sortable-simple/Card.js
Expand Up @@ -15,21 +15,11 @@ const propTypes = {
id: PropTypes.any.isRequired,
text: PropTypes.string.isRequired,
isDragging: PropTypes.bool.isRequired,
overlappingCardId: PropTypes.bool.isRequired,
moveCard: PropTypes.func.isRequired,
connectDragDrop: PropTypes.func.isRequired
};

class Card {
componentWillReceiveProps(nextProps) {
if (!this.props.overlappingCardId && nextProps.overlappingCardId) {
const { id, overlappingCardId } = nextProps;
if (overlappingCardId !== id) {
this.props.moveCard(overlappingCardId, id);
}
}
}

render() {
const { text, isDragging, connectDragDrop } = this.props;
const opacity = isDragging ? 0 : 1;
Expand All @@ -42,24 +32,32 @@ class Card {
);
}
}
Card.propTypes = propTypes;

export default configureDragDrop(Card, {
getProps(connect, monitor, handlers) {
return {
isDragging: monitor.isDragging(handlers.cardSource),
connectDragDrop: connect(handlers.cardSource, handlers.cardTarget)
};
},

getHandlers(props, sourceFor, targetFor) {
return {
cardSource: sourceFor(ItemTypes.CARD, {
beginDrag(props) {
return { id: props.id };
}
}),
cardTarget: targetFor(ItemTypes.CARD)
};
},
cardTarget: targetFor(ItemTypes.CARD, {
hover(props, monitor) {
const draggedId = monitor.getItem().id;

getProps(connect, monitor, handlers) {
return {
isDragging: monitor.isDragging(handlers.cardSource),
overlappingCardId: monitor.isOver(handlers.cardTarget) && monitor.getItem().id || null,
connectDragDrop: connect(handlers.cardSource, handlers.cardTarget)
if (draggedId !== props.id) {
props.moveCard(draggedId, props.id);
}
}
})
};
}
});
8 changes: 8 additions & 0 deletions modules/ComponentDropTarget.js
Expand Up @@ -36,6 +36,14 @@ export default class ComponentDropTarget extends DropTarget {
}
}

hover(...args) {
if (this.spec.hover) {
return this.spec.hover.call(null, this.props, ...args);
} else {
return super.hover(...args);
}
}

drop(...args) {
if (this.spec.drop) {
return this.spec.drop.call(null, this.props, ...args);
Expand Down
2 changes: 0 additions & 2 deletions modules/backends/HTML5.js
Expand Up @@ -271,7 +271,6 @@ export default class HTML5Backend {

handleDragOver(e, targetHandle) {
this.dragOverTargetHandles.unshift(targetHandle);
this.actions.hover(this.dragEnterTargetHandles);
}

handleTopDragOver(e) {
Expand Down Expand Up @@ -314,7 +313,6 @@ export default class HTML5Backend {

handleDragEnter(e, targetHandle) {
this.dragEnterTargetHandles.unshift(targetHandle);
this.actions.hover(this.dragEnterTargetHandles);
}

handleTopDragEnter(e) {
Expand Down
41 changes: 26 additions & 15 deletions modules/configureDragDrop.js
Expand Up @@ -6,6 +6,7 @@ import invariant from 'react/lib/invariant';
import shallowEqual from 'react/lib/shallowEqual';

const DEFAULT_KEY = '__default__';
const HANDLE_SEPARATOR = '🍣';

export default function configureDragDrop(InnerComponent, { getHandlers, getProps, managerName = 'dragDropManager' }) {
class DragDropContainer extends Component {
Expand All @@ -14,6 +15,7 @@ export default function configureDragDrop(InnerComponent, { getHandlers, getProp

this.handleChange = this.handleChange.bind(this);
this.connectRefTo = this.connectRefTo.bind(this);
this.memoizedConnectRefTo = {};

this.manager = context[managerName];
this.handles = {};
Expand Down Expand Up @@ -42,6 +44,8 @@ export default function configureDragDrop(InnerComponent, { getHandlers, getProp
const monitor = this.manager.getMonitor();
monitor.removeChangeListener(this.handleChange);
this.detachHandlers();

this.memoizedConnectRefTo = {};
}

handleChange() {
Expand Down Expand Up @@ -150,23 +154,30 @@ export default function configureDragDrop(InnerComponent, { getHandlers, getProp
}

connectRefTo(...handles) {
const manager = this.manager;
const key = handles.join(HANDLE_SEPARATOR);

return function (ref) {
const node = findDOMNode(ref);
const backend = manager.getBackend();
const registry = manager.getRegistry();

handles.forEach(handle => {
if (registry.isSourceHandle(handle)) {
backend.updateSourceNode(handle, node);
} else if (registry.isTargetHandle(handle)) {
backend.updateTargetNode(handle, node);
} else {
invariant(false, 'Handle is neither a source nor a target.');
}
});
if (!this.memoizedConnectRefTo[key]) {
this.memoizedConnectRefTo[key] = this.connectRefToHandles.bind(this, handles);
}

return this.memoizedConnectRefTo[key];
}

connectRefToHandles(handles, ref) {
const manager = this.manager;
const node = findDOMNode(ref);
const backend = manager.getBackend();
const registry = manager.getRegistry();

handles.forEach(handle => {
if (registry.isSourceHandle(handle)) {
backend.updateSourceNode(handle, node);
} else if (registry.isTargetHandle(handle)) {
backend.updateTargetNode(handle, node);
} else {
invariant(false, 'Handle is neither a source nor a target.');
}
});
}

getCurrentState() {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -31,7 +31,7 @@
},
"homepage": "https://github.com/gaearon/react-dnd",
"dependencies": {
"dnd-core": "^0.5.5",
"dnd-core": "^0.6.1",
"flux": "^2.0.1",
"lodash": "^3.1.0"
},
Expand Down

0 comments on commit d2dbf37

Please sign in to comment.