Skip to content

Commit

Permalink
Add sortable-cancelable example. Addresses #144
Browse files Browse the repository at this point in the history
  • Loading branch information
gaearon committed May 5, 2015
1 parent 21b1792 commit 6aec28c
Show file tree
Hide file tree
Showing 5 changed files with 211 additions and 1 deletion.
82 changes: 82 additions & 0 deletions examples/_sortable-cancelable/Card.js
@@ -0,0 +1,82 @@
'use strict';

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

const style = {
border: '1px dashed gray',
backgroundColor: 'white',
padding: '0.5rem',
margin: '0.5rem'
};

const CardSource = {
beginDrag(props) {
return {
id: props.id,
originalIndex: props.findCard(props.id).index
};
},

endDrag(props, monitor) {
const { id: droppedId, originalIndex } = monitor.getItem();
const didDrop = monitor.didDrop();

if (!didDrop) {
props.moveCard(droppedId, originalIndex);
}
}
};

const CardTarget = {
canDrop() {
return false;
},

hover(props, monitor) {
const { id: draggedId } = monitor.getItem();
const { id: overId } = props;

if (draggedId !== overId) {
const { index: overIndex } = props.findCard(overId);
props.moveCard(draggedId, overIndex);
}
}
};

@configureDragDrop(
register => ({
cardSource: register.dragSource(ItemTypes.CARD, CardSource),
cardTarget: register.dropTarget(ItemTypes.CARD, CardTarget)
}),

({ cardSource, cardTarget }) => ({
connectDragSource: cardSource.connect(),
connectDropTarget: cardTarget.connect(),
isDragging: cardSource.isDragging()
})
)
export default class Card {
static propTypes = {
connectDragSource: PropTypes.func.isRequired,
connectDropTarget: PropTypes.func.isRequired,
isDragging: PropTypes.bool.isRequired,
id: PropTypes.any.isRequired,
text: PropTypes.string.isRequired,
moveCard: PropTypes.func.isRequired,
findCard: PropTypes.func.isRequired
};

render() {
const { text, isDragging, connectDragSource, connectDropTarget } = this.props;
const opacity = isDragging ? 0 : 1;

return (
<div ref={c => { connectDragSource(c); connectDropTarget(c); }}
style={{ ...style, opacity }}>
{text}
</div>
);
}
}
104 changes: 104 additions & 0 deletions examples/_sortable-cancelable/Container.js
@@ -0,0 +1,104 @@
'use strict';

import React, { Component, PropTypes } from 'react';
import update from 'react/lib/update';
import Card from './Card';
import { configureDragDrop, configureDragDropContext } from 'react-dnd';
import HTML5Backend from 'react-dnd/modules/backends/HTML5';
import ItemTypes from './ItemTypes';

const style = {
width: 320
};

const CardDropTarget = {
drop() {
}
};

@configureDragDropContext(HTML5Backend)
@configureDragDrop(
register =>
register.dropTarget(ItemTypes.CARD, CardDropTarget),

cardTarget => ({
connectDropTarget: cardTarget.connect()
})
)
export default class Container extends Component {
static propTypes = {
connectDropTarget: PropTypes.func.isRequired
};

constructor(props) {
super(props);
this.moveCard = this.moveCard.bind(this);
this.findCard = this.findCard.bind(this);
this.state = {
cards: [{
id: 1,
text: 'Write a cool JS library'
}, {
id: 2,
text: 'Make it generic enough'
}, {
id: 3,
text: 'Write README'
}, {
id: 4,
text: 'Create some examples'
}, {
id: 5,
text: 'Spam in Twitter and IRC to promote it'
}, {
id: 6,
text: '???'
}, {
id: 7,
text: 'PROFIT'
}]
};
}

moveCard(id, atIndex) {
const { card, index } = this.findCard(id);
this.setState(update(this.state, {
cards: {
$splice: [
[index, 1],
[atIndex, 0, card]
]
}
}));
}

findCard(id) {
const { cards } = this.state;
const card = cards.filter(c => c.id === id)[0];

return {
card,
index: cards.indexOf(card)
};
}

render() {
const { connectDropTarget } = this.props;
const { cards } = this.state;

return (
<div ref={connectDropTarget}
style={style}>
{cards.map((card, index) => {
return (
<Card key={card.id}
id={card.id}
text={card.text}
moveCard={this.moveCard}
findCard={this.findCard} />
);
})}
</div>
);
}
}
5 changes: 5 additions & 0 deletions examples/_sortable-cancelable/ItemTypes.js
@@ -0,0 +1,5 @@
'use strict';

export default {
CARD: 'card'
};
17 changes: 17 additions & 0 deletions examples/_sortable-cancelable/index.js
@@ -0,0 +1,17 @@
'use strict';

import React from 'react';
import Container from './Container';

export default class SortableCancelable {
render() {
return (
<div>
<Container />
<hr />
<p>
</p>
</div>
);
}
}
4 changes: 3 additions & 1 deletion examples/index.js
Expand Up @@ -11,6 +11,7 @@ import DustbinStress from './_dustbin-stress';
import NestingTargets from './_nesting-targets';
import NestingSources from './_nesting-sources';
import SortableSimple from './_sortable-simple';
import SortableCancelable from './_sortable-cancelable';
import SortableStress from './_sortable-stress';
import CustomizeHandles from './_customize-handles';
import CustomizeEffects from './_customize-effects';
Expand All @@ -24,7 +25,7 @@ const App = React.createClass({
<li>Drag Around (<Link to='drag-around-naive'>naive</Link>, <Link to='drag-around-custom'>custom</Link>)</li>
<li>Dustbin (<Link to='dustbin-simple'>simple</Link>, <Link to='dustbin-interesting'>interesting</Link>, <Link to='dustbin-stress'>stress test</Link>)</li>
<li>Nesting (<Link to='nesting-sources'>drag sources</Link>, <Link to='nesting-targets'>drop targets</Link>)</li>
<li>Sortable (<Link to='sortable-simple'>simple</Link>, <Link to='sortable-stress'>stress test</Link>)</li>
<li>Sortable (<Link to='sortable-simple'>simple</Link>, <Link to='sortable-cancelable'>cancel on drop outside</Link>, <Link to='sortable-stress'>stress test</Link>)</li>
<li>Customize (<Link to='customize-handles'>drag handles</Link>, <Link to='customize-effects'>drop effects</Link>)</li>
</ul>
<hr />
Expand All @@ -44,6 +45,7 @@ const routes = (
<Route name='nesting-sources' path='nesting-sources' handler={NestingSources} />
<Route name='nesting-targets' path='nesting-targets' handler={NestingTargets} />
<Route name='sortable-simple' path='sortable-simple' handler={SortableSimple} />
<Route name='sortable-cancelable' path='sortable-cancelable' handler={SortableCancelable} />
<Route name='sortable-stress' path='sortable-stress' handler={SortableStress} />
<Route name='customize-handles' path='customize-handles' handler={CustomizeHandles} />
<Route name='customize-effects' path='customize-effects' handler={CustomizeEffects} />
Expand Down

0 comments on commit 6aec28c

Please sign in to comment.