Skip to content

Commit

Permalink
Add sortable
Browse files Browse the repository at this point in the history
  • Loading branch information
gaearon committed Mar 26, 2015
1 parent b29eae2 commit 3764e2b
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 92 deletions.
90 changes: 40 additions & 50 deletions examples/_sortable-simple/Card.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,7 @@

import React, { PropTypes } from 'react';
import ItemTypes from './ItemTypes';
import { DragSource, DropTarget, ObservePolyfill } from 'react-dnd';

class CardDragSource extends DragSource {
beginDrag() {
return {
item: {
id: this.component.props.id
}
};
}
}

class CardDropTarget extends DropTarget {
over(monitor) {
const item = monitor.getItem();
this.component.props.moveCard(item.id, this.component.props.id);
}
}
import { configureDragDrop } from 'react-dnd';

const style = {
border: '1px dashed gray',
Expand All @@ -28,48 +11,55 @@ const style = {
margin: '0.5rem'
};

const Card = React.createClass({
contextTypes: {
dragDrop: PropTypes.object.isRequired
},

mixins: [ObservePolyfill({
constructor() {
this.dragSource = new CardDragSource(this);
//this.dropTarget = new CardDropTarget(this);
},
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
};

observe() {
return {
dragSource: this.dragSource.connectTo(this.context.dragDrop, ItemTypes.CARD),
//dropTarget: this.dropTarget.connectTo(this.context.dragDrop, ItemTypes.CARD)
};
class Card {
componentWillReceiveProps(nextProps) {
if (!this.props.overlappingCardId && nextProps.overlappingCardId) {
const { id, overlappingCardId } = nextProps;
if (overlappingCardId !== id) {
this.props.moveCard(overlappingCardId, id);
}
}
})],

propTypes: {
id: PropTypes.any.isRequired,
text: PropTypes.string.isRequired,
moveCard: PropTypes.func.isRequired
},
}

render() {
const { text } = this.props;

// TODO: refs totally suck here.
// Need to rethink this.

const { isDragging, ref: sourceRef } = this.state.data.dragSource;
//const { ref: targetRef } = this.state.data.dropTarget;
const { text, isDragging, connectDragDrop } = this.props;
const opacity = isDragging ? 0 : 1;

return (
<div ref={sourceRef}
<div ref={connectDragDrop}
style={{ ...style, opacity }}>
{text}
</div>
);
}
});
}

export default Card;
export default configureDragDrop(Card, {
getHandlers(props, sourceFor, targetFor) {
return {
cardSource: sourceFor(ItemTypes.CARD, {
beginDrag(props) {
return { id: props.id };
}
}),
cardTarget: targetFor(ItemTypes.CARD)
};
},

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)
};
}
});
27 changes: 13 additions & 14 deletions examples/_sortable-simple/Container.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
'use strict';

import React from 'react';
import React, { Component } from 'react';
import update from 'react/lib/update';
import Card from './Card';
import { DragDropContext, HTML5Backend } from 'react-dnd';
import { configureDragDropContext, HTML5Backend } from 'react-dnd';

const Container = React.createClass({
mixins: [DragDropContext({
dragDrop: HTML5Backend
})],

getInitialState() {
return {
class Container extends Component {
constructor(props) {
super(props);
this.state = {
cards: [{
id: 1,
text: 'Write a cool JS library'
Expand All @@ -35,7 +32,7 @@ const Container = React.createClass({
text: 'PROFIT'
}]
};
},
}

moveCard(id, afterId) {
const { cards } = this.state;
Expand All @@ -53,7 +50,7 @@ const Container = React.createClass({
]
}
}));
},
}

render() {
const { cards } = this.state;
Expand All @@ -65,12 +62,14 @@ const Container = React.createClass({
<Card key={card.id}
id={card.id}
text={card.text}
moveCard={this.moveCard} />
moveCard={(id, afterId) => this.moveCard(id, afterId)} />
);
})}
</div>
);
}
});
}

export default Container;
export default configureDragDropContext(Container, {
backend: HTML5Backend
});
9 changes: 3 additions & 6 deletions examples/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Router, { Route, Link, Redirect, RouteHandler } from 'react-router';
import DustbinSimple from './_dustbin-simple';
import DustbinInteresting from './_dustbin-interesting';
import NestingSources from './_nesting-sources';
//import SortableSimple from './_sortable-simple';
import SortableSimple from './_sortable-simple';

/*
DragAroundNaive = require('./_drag-around-naive/index'),
Expand All @@ -21,6 +21,7 @@ const App = React.createClass({
<ul>
<li>Dustbin (<Link to='dustbin-simple'>simple</Link>, <Link to='dustbin-interesting'>interesting</Link>)</li>
<li>Nesting (<Link to='nesting-sources'>drag sources</Link>)</li>
<li>Sortable (<Link to='sortable-simple'>simple</Link>)</li>
</ul>
<hr />
<RouteHandler />
Expand All @@ -31,7 +32,6 @@ const App = React.createClass({

/*
<ul>
<li>Sortable (<Link to='sortable-simple'>simple</Link>)</li>
<li>Drag Around (<Link to='drag-around-naive'>naive</Link>, <Link to='drag-around-custom'>custom</Link>)</li>
</ul>
*/
Expand All @@ -41,14 +41,11 @@ const routes = (
<Route name='dustbin-simple' path='dustbin-simple' handler={DustbinSimple} />
<Route name='dustbin-interesting' path='dustbin-interesting' handler={DustbinInteresting} />
<Route name='nesting-sources' path='nesting-sources' handler={NestingSources} />
<Route name='sortable-simple' path='sortable-simple' handler={SortableSimple} />
<Redirect from='/' to='dustbin-simple' />
</Route>
);

/*
<Route name='sortable-simple' path='sortable-simple' handler={SortableSimple} />
*/

Router.run(routes,
process.env.NODE_ENV === 'production' ? Router.HashLocation : Router.HistoryLocation,
(Handler) => React.render(<Handler/>, document.body)
Expand Down
6 changes: 1 addition & 5 deletions examples/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@ module.exports = {
modulesDirectories: ['node_modules']
},
resolve: {
extensions: ['', '.js', '.jsx'],
alias: {
// TODO: temporary to work on unreleased 0.13-compat branch
'react-router': 'react-router/build/npm'
}
extensions: ['', '.js', '.jsx']
},
module: {
loaders: [
Expand Down
6 changes: 1 addition & 5 deletions examples/webpack.config.production.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ module.exports = {
modulesDirectories: ['node_modules']
},
resolve: {
extensions: ['', '.js', '.jsx'],
alias: {
// TODO: temporary to work on unreleased 0.13-compat branch
'react-router': 'react-router/build/npm'
}
extensions: ['', '.js', '.jsx']
},
module: {
loaders: [
Expand Down
2 changes: 1 addition & 1 deletion modules/ComponentDropTarget.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import isArray from 'lodash/lang/isArray';
import isObject from 'lodash/lang/isObject';

export default class ComponentDropTarget extends DropTarget {
constructor(type, spec, props) {
constructor(type, spec = {}, props) {
invariant(isString(type) || isArray(type), 'Expected type to be a string or an array.');
invariant(isObject(spec), 'Expected spec to be an object.');

Expand Down
22 changes: 12 additions & 10 deletions modules/configureDragDrop.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default function configureDragDrop(InnerComponent, { getHandlers, getProp
super(props);

this.handleChange = this.handleChange.bind(this);
this.connectTo = this.connectTo.bind(this);
this.connectRefTo = this.connectRefTo.bind(this);

this.manager = context[managerName];
this.handles = {};
Expand Down Expand Up @@ -149,21 +149,23 @@ export default function configureDragDrop(InnerComponent, { getHandlers, getProp
this.attachHandler(key, nextHandler);
}

connectTo(handle) {
connectRefTo(...handles) {
const manager = this.manager;

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

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.');
}
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.');
}
});
}
}

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

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

render() {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"dependencies": {
"dnd-core": "^0.5.5",
"flux": "^2.0.1",
"lodash": "^3.1.0",
"lodash": "^3.1.0"
},
"peerDependencies": {
"react": ">=0.12.0 <0.14.0"
Expand Down

0 comments on commit 3764e2b

Please sign in to comment.