Skip to content

Commit

Permalink
Update API
Browse files Browse the repository at this point in the history
  • Loading branch information
gaearon committed Apr 2, 2015
1 parent 00862fd commit 027a6bb
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 67 deletions.
2 changes: 2 additions & 0 deletions TODO
Expand Up @@ -12,6 +12,8 @@
* early invariants for common mistakes (e.g. missing context?)
* fix hot reloading
* higher-level components
* change sortable example to avoid indexOf
* try fun sCU optimizations with monitor

dnd-core
* smarter canDrop()
Expand Down
19 changes: 8 additions & 11 deletions examples/_customize-handles/Box.js
Expand Up @@ -52,15 +52,12 @@ const boxSource = {
};

export default configureDragDrop(Box, {
configure(props, sourceFor) {
return sourceFor(ItemTypes.BOX, boxSource);
},

inject(connect, monitor, dragSourceId) {
return {
dragPreviewRef: connect.dragSourcePreview(dragSourceId),
dragSourceRef: connect.dragSource(dragSourceId),
isDragging: monitor.isDragging(dragSourceId)
};
}
configure: (register) =>
register.dragSource(ItemTypes.BOX, boxSource),

inject: (connect, monitor, dragSourceId) => ({
dragPreviewRef: connect.dragSourcePreview(dragSourceId),
dragSourceRef: connect.dragSource(dragSourceId),
isDragging: monitor.isDragging(dragSourceId)
})
});
15 changes: 7 additions & 8 deletions examples/_sortable-simple/Card.js
Expand Up @@ -2,7 +2,7 @@

import React, { PropTypes } from 'react';
import ItemTypes from './ItemTypes';
import { configureDragDrop } from 'react-dnd';
import { configureDragDrop, joinRefs } from 'react-dnd';

const style = {
border: '1px dashed gray',
Expand All @@ -17,16 +17,17 @@ const propTypes = {
text: PropTypes.string.isRequired,
isDragging: PropTypes.bool.isRequired,
moveCard: PropTypes.func.isRequired,
dragDropRef: PropTypes.func.isRequired
dragSourceRef: PropTypes.func.isRequired,
dropTargetRef: PropTypes.func.isRequired
};

class Card {
render() {
const { text, isDragging, dragDropRef } = this.props;
const { text, isDragging, dragSourceRef, dropTargetRef } = this.props;
const opacity = isDragging ? 0 : 1;

return (
<div ref={dragDropRef}
<div ref={joinRefs(dragSourceRef, dropTargetRef)}
style={{ ...style, opacity }}>
{text}
</div>
Expand Down Expand Up @@ -59,9 +60,7 @@ export default configureDragDrop(Card, {

inject: (connect, monitor, { cardSourceId, cardTargetId }) => ({
isDragging: monitor.isDragging(cardSourceId),
dragDropRef: [
connect.dragSource(cardSourceId),
connect.dropTarget(cardTargetId)
]
dragSourceRef: connect.dragSource(cardSourceId),
dropTargetRef: connect.dropTarget(cardTargetId)
})
});
14 changes: 12 additions & 2 deletions modules/backends/HTML5.js
Expand Up @@ -79,6 +79,8 @@ export default class HTML5Backend {
this.handleTopDrop = this.handleTopDrop.bind(this);
this.handleTopDropCapture = this.handleTopDropCapture.bind(this);
this.endDragIfSourceWasRemovedFromDOM = this.endDragIfSourceWasRemovedFromDOM.bind(this);
this.setSourceNode = this.setSourceNode.bind(this);
this.setTargetNode = this.setTargetNode.bind(this);
}

setup() {
Expand Down Expand Up @@ -381,7 +383,15 @@ export default class HTML5Backend {
}
}

updateSourceNode(sourceHandle, node) {
getConnector() {
return {
dragSource: this.setSourceNode,
dragSourcePreview: () => {},
dropTarget: this.setTargetNode
};
}

setSourceNode(sourceHandle, node) {
let nodeHandlers = this.nodeHandlers[sourceHandle];
if (nodeHandlers && nodeHandlers.node === node) {
return;
Expand All @@ -405,7 +415,7 @@ export default class HTML5Backend {
}
}

updateTargetNode(targetHandle, node) {
setTargetNode(targetHandle, node) {
let nodeHandlers = this.nodeHandlers[targetHandle];
if (nodeHandlers && nodeHandlers.node === node) {
return;
Expand Down
79 changes: 34 additions & 45 deletions modules/configureDragDrop.js
Expand Up @@ -6,9 +6,8 @@ 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' }) {
export default function configureDragDrop(InnerComponent, { configure, inject, managerName = 'dragDropManager' }) {
class DragDropContainer extends Component {
shouldComponentUpdate(nextProps, nextState) {
return !shallowEqual(nextProps, this.props) ||
Expand All @@ -17,15 +16,15 @@ export default function configureDragDrop(InnerComponent, { getHandlers, getProp

constructor(props, context) {
super(props);

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

this.manager = context[managerName];
invariant(this.manager, 'Could not read manager from context.');

this.handles = {};
this.handlers = {};

this.connector = this.createConnector();
this.attachHandlers(this.getNextHandlers(props));
this.state = this.getCurrentState();
}
Expand Down Expand Up @@ -53,8 +52,7 @@ export default function configureDragDrop(InnerComponent, { getHandlers, getProp
const monitor = this.manager.getMonitor();
monitor.removeChangeListener(this.handleChange);
this.detachHandlers();

this.memoizedConnectRefTo = {};
this.connector = null;
}

handleChange() {
Expand All @@ -65,18 +63,19 @@ export default function configureDragDrop(InnerComponent, { getHandlers, getProp
}

getNextHandlers(props) {
function sourceFor(type, spec) {
return new ComponentDragSource(type, spec, props);
}

function targetFor(type, spec) {
return new ComponentDropTarget(type, spec, props);
}
const register = {
dragSource(type, spec) {
return new ComponentDragSource(type, spec, props);
},
dropTarget(type, spec) {
return new ComponentDropTarget(type, spec, props);
}
};

let handlers = getHandlers(props, sourceFor, targetFor);
let handlers = configure(register, props);
if (handlers instanceof ComponentDragSource ||
handlers instanceof ComponentDropTarget
) {
handlers instanceof ComponentDropTarget) {

handlers = {
[DEFAULT_KEY]: handlers
};
Expand Down Expand Up @@ -162,33 +161,6 @@ export default function configureDragDrop(InnerComponent, { getHandlers, getProp
this.attachHandler(key, nextHandler);
}

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

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() {
const monitor = this.manager.getMonitor();

Expand All @@ -197,7 +169,24 @@ export default function configureDragDrop(InnerComponent, { getHandlers, getProp
handles = handles[DEFAULT_KEY];
}

return getProps(this.connectRefTo, monitor, handles);
return inject(this.connector, monitor, handles);
}

createConnector() {
const backend = this.manager.getBackend();
const connector = backend.getConnector();
const wrappedConnector = {};

Object.keys(connector).forEach(function (key) {
wrappedConnector[key] = function (handle) {
return function (componentOrNode) {
const node = findDOMNode(componentOrNode);
return connector[key].call(connector, handle, node);
};
};
});

return wrappedConnector;
}

render() {
Expand Down
3 changes: 2 additions & 1 deletion modules/index.js
@@ -1,4 +1,5 @@
export { default as HTML5Backend } from './backends/HTML5';
export { default as NativeTypes } from './NativeTypes';
export { default as configureDragDrop } from './configureDragDrop';
export { default as configureDragDropContext } from './configureDragDropContext';
export { default as configureDragDropContext } from './configureDragDropContext';
export { default as joinRefs } from './joinRefs';
6 changes: 6 additions & 0 deletions modules/joinRefs.js
@@ -0,0 +1,6 @@
export default function joinRefs(refA, refB) {
return function (instance) {
refA(instance);
refB(instance);
};
}

0 comments on commit 027a6bb

Please sign in to comment.