Skip to content

Instantly share code, notes, and snippets.

@nrfm
Created April 17, 2018 21:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nrfm/fef4d7c4599de5793df294d6a435506e to your computer and use it in GitHub Desktop.
Save nrfm/fef4d7c4599de5793df294d6a435506e to your computer and use it in GitHub Desktop.
wrapping dnd for easier interop with reagent
import React from 'react';
import {DragDropContext, Draggable, Droppable} from 'react-beautiful-dnd';
// a little function to help us with reordering the result
const reorder = (boarddata, {index: sourceIndex, droppableId: sourceId}, {index: destIndex, droppableId: destId}) => {
const result = Object.assign(boarddata);
const [removed] = result.subBoards[sourceId].splice(sourceIndex, 1);
result.subBoards[destId].splice(destIndex, 0, removed);
return result;
};
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
boardData: this.props.boardData
}
this.onDragEnd = this.onDragEnd.bind(this);
}
onDragEnd({source, destination}) {
// dropped outside the list
if (!destination) {
return;
}
const items = reorder(
this.state.boardData,
source,
destination
);
this.setState({
items
});
}
// Normally you would want to split things out into separate components.
// But in this example everything is just done in one place for simplicity
render() {
const {name, subBoards} = this.props.boardData;
const {getListStyle, getItemStyle} = this.props;
return (
<div className='cf'>
{/*<div>*/}
{/*<pre>{JSON.stringify(this.props.boardData,null,4)}</pre>*/}
{/*</div>*/}
<h1>
name : {name}
</h1>
<DragDropContext onDragEnd={this.onDragEnd} className='cf'>
{Object.entries(subBoards).map(([boardName, subBoard]) => {
return (<Droppable droppableId={boardName} key={boardName}>
{(provided, snapshot) => (
<div className='fl'
ref={provided.innerRef}
style={getListStyle(boardName, snapshot.isDraggingOver)}
{...provided.droppableProps}>
{subBoard.map((item, index) => {
return (<Draggable
key={item.id}
draggableId={item.id}
index={index}>
{(provided, snapshot) => (
<div>
<div
ref={provided.innerRef}
{...provided.dragHandleProps}
{...provided.draggableProps}
style={getItemStyle(
provided.draggableProps.style,
snapshot.isDragging
)}>
{this.props.itemRenderer ?
this.props.itemRenderer(item.content, item.n)
:item.content}
</div>
{provided.placeholder}
</div>
)}
</Draggable>)
})}
{provided.placeholder}
</div>
)}
</Droppable>);
})}
</DragDropContext>
</div>
);
}
}
export default App;
import App from 'dndWrapper';
const grid = 8;
const getListStyle = (boardName,isDraggingOver) => ({
background: isDraggingOver ? 'lightblue' : 'lightgrey',
padding: grid,
width: 400
});
const getItemStyle = (draggableStyle, isDragging) => ({
// some basic styles to make the items look a bit nicer
// height: 200,
userSelect: 'none',
// transition: 'all 0.3s',
// padding: isDragging ? grid * 5 : grid * 2,
//padding: grid * 2,
margin: `0 0 ${grid}px 0`,
// change background colour if dragging
background: isDragging ? 'lightgreen' : 'white',
// height: isDragging ? 400 : 'auto',
// styles we need to apply on draggables
...draggableStyle
});
// fake data generator
const getItems = (count) => Array.from({length: count}, (v, k) => k).map(k => ({
id: "id" + Math.random() * 100000,
n: 2 + Math.random() * 5 >> 0,
content: 'item' + (Math.random() * 10000 )
}));
const getItemRenderer = (content,n) => {
return (<div className='pa4'>
<article class="dt w-100 bb b--black-05 pb2 mt2" href="#0">
<div class="dtc w2 w3-ns v-mid">
<img src={`http://mrmrs.github.io/photos/p/${n}.jpg`} class="ba b--black-10 db br-100 w2 w3-ns h2 h3-ns"/>
</div>
<div class="dtc v-mid pl3">
<h1 class="f6 f5-ns fw6 lh-title black mv0">Young Gatchell </h1>
<h2 class="f6 fw4 mt0 mb0 black-60">@yg</h2>
</div>
<div class="dtc v-mid">
<form class="w-100 tr">
<button class="f6 button-reset bg-white ba b--black-10 dim pointer pv1 black-60" type="submit">+ Follow</button>
</form>
</div>
</article>
</div>)
}
const boardData = {
name : "a board £500",
subBoards: {
one : getItems(1)
}
};
const boardData2 = {
name : "a board £500",
subBoards: {
one1 : getItems(4),
two1 : getItems(10)
}
};
ReactDOM.render(<div className='cf'>
<App boardData={boardData}
getItemStyle={getItemStyle}
getListStyle={getListStyle}
itemRenderer={getItemRenderer}/>
<hr/>
<App boardData={boardData2}
getItemStyle={getItemStyle}
getListStyle={getListStyle}
itemRenderer={getItemRenderer}/></div>,mountNode);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment