Skip to content

Instantly share code, notes, and snippets.

@atherdon
Created December 7, 2018 09:13
Show Gist options
  • Save atherdon/74eaf433eee18b03317dc61909a90a13 to your computer and use it in GitHub Desktop.
Save atherdon/74eaf433eee18b03317dc61909a90a13 to your computer and use it in GitHub Desktop.
Sortable list with React-DnD
<div id="root" class="container mt-5"></div>
const Card = props => {
const style = props.isDragging
? `card text-white border-light text-light`
: `card text-${ props.color }`;
return props.connectDropTarget(
<article className="pt-1 pb-1">
{ props.connectDragSource(
<div className={style}>
<div className="card-body">
<h5>{props.title}</h5>
</div>
</div>
) }
</article>
);
}
const typeCard = Symbol.for('@@Type::Card');
const specTarget = {
drop(props) {
return {
id: props.id,
index: props.index,
};
}
};
const specSource = {
beginDrag(props) {
return {
id: props.id,
};
},
endDrag(props, monitor) {
if (!monitor.didDrop()) {
return;
}
const source = monitor.getItem();
const target = monitor.getDropResult();
if (source.id === target.id) {
return;
}
props.moveCard(source.id, target.index);
}
};
const collectTarget = connect => ({
connectDropTarget: connect.dropTarget(),
});
const collectSource = (connect, monitor) => ({
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging()
});
const CardWithDnD = ReactDnD.DropTarget(typeCard, specTarget, collectTarget)(
ReactDnD.DragSource(typeCard, specSource, collectSource)(Card)
);
class App extends React.Component {
constructor(props) {
super(props);
this.moveCard = this.moveCard.bind(this);
this.state = {
cards: [{
id: '--0',
title: '#1 Test',
color: "success"
}, {
id: '--1',
title: '#2 Text',
color: "primary"
}, {
id: '--2',
title: '#3 Task',
color: "warning"
}, {
id: '--3',
title: '#4 Some text',
color: "info"
}, {
id: '--4',
title: '#5 New row',
color: "danger"
}, {
id: '--5',
title: '#6 Next item',
color: "dark"
},
]
};
}
moveCard (id, index) {
const { cards } = this.state;
const sourceCard = cards.find(card => card.id === id);
const sortCards = cards.filter(card => card.id !== id)
sortCards.splice(index, 0, sourceCard);
this.setState({ cards: sortCards });
}
render() {
const { cards } = this.state;
return (
<div className="offset-2 col-8">
{ cards.map((card, i) => (
<CardWithDnD
key={card.id}
index={i}
moveCard={this.moveCard}
{...card}
/>
)) }
</div>
);
}
}
ReactDOM.render(
<ReactDnD.DragDropContextProvider backend={ReactDnDHTML5Backend}>
<App />
</ReactDnD.DragDropContextProvider>,
document.getElementById('root'),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/react-dnd@2.4.0/dist/ReactDnD.min.js"></script>
<script src="https://unpkg.com/react-dnd-html5-backend@2.4.1/dist/ReactDnDHTML5Backend.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment