Created
August 13, 2018 14:50
-
-
Save shlomitc/7c1bc3ab760de7b127388d0ef63fff4b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import {findDOMNode} from 'react-dom'; | |
import css from './App.scss'; | |
import HTML5Backend from 'react-dnd-html5-backend'; | |
import {DragDropContext, DragSource, DropTarget} from 'react-dnd'; | |
//PHASE | |
class Phase extends React.Component { | |
constructor() { | |
super(); | |
this.state = { | |
cards: [{id: 'A', content: 'Card A'}, {id: 'B', content: 'Card B'}] | |
}; | |
this.moveCard = this.moveCard.bind(this); | |
} | |
moveCard(dragIndex, hoverIndex) { | |
const {cards} = this.state; | |
const dragCard = cards[dragIndex]; | |
const moshe = cards.filter(c => c.id !== dragCard.id); | |
const mashu = [...moshe.splice(0, hoverIndex), dragCard, ...moshe.splice(hoverIndex)]; | |
this.setState({cards: mashu}); | |
} | |
render() { | |
return ( | |
<div className={css.phase}> | |
{ | |
this.state.cards.map( | |
(cardData, index) => | |
<Card key={cardData.id} | |
id={cardData.id} | |
index={index} | |
moveCard={this.moveCard} | |
> | |
{cardData.content} | |
</Card> | |
) | |
} | |
</div> | |
); | |
} | |
} | |
//CARD | |
class CardRaw extends React.Component { | |
render() { | |
const {isDragging, connectDragSource, connectDropTarget} = this.props; | |
return connectDropTarget(connectDragSource( | |
<div className={css.card}> | |
{this.props.children} | |
</div> | |
)); | |
} | |
} | |
const cardSource = { | |
canDrag: () => { | |
return true; | |
}, | |
isDragging: (props, monitor) => { | |
return monitor.getItem().id === props.id; | |
}, | |
beginDrag: props => { | |
return { | |
id: props.id, | |
index: props.index | |
}; | |
}, | |
endDrag: () => null | |
}; | |
const cardSourceCollect = (connect, monitor) => { | |
return { | |
isDragging: monitor.isDragging(), | |
connectDragSource: connect.dragSource() | |
}; | |
}; | |
const cardTarget = { | |
hover(props, monitor, component) { | |
if (!component) { | |
return null; | |
} | |
const dragIndex = monitor.getItem().index; | |
const hoverIndex = props.index; | |
// Don't replace items with themselves | |
if (dragIndex === hoverIndex) { | |
return; | |
} | |
// Determine rectangle on screen | |
const hoverBoundingRect = findDOMNode(component).getBoundingClientRect(); | |
// Get vertical middle | |
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2; | |
// Determine mouse position | |
const clientOffset = monitor.getClientOffset(); | |
// Get pixels to the top | |
const hoverClientY = (clientOffset).y - hoverBoundingRect.top; | |
// Only perform the move when the mouse has crossed half of the items height | |
// When dragging downwards, only move when the cursor is below 50% | |
// When dragging upwards, only move when the cursor is above 50% | |
// Dragging downwards | |
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) { | |
return; | |
} | |
// Dragging upwards | |
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) { | |
return; | |
} | |
// Time to actually perform the action | |
props.moveCard(dragIndex, hoverIndex); | |
// Note: we're mutating the monitor item here! | |
// Generally it's better to avoid mutations, | |
// but it's good here for the sake of performance | |
// to avoid expensive index searches. | |
monitor.getItem().index = hoverIndex | |
}, | |
}; | |
const cardTargetCollect = (connect) => ({ | |
connectDropTarget: connect.dropTarget() | |
}); | |
const Card = DropTarget('card', cardTarget, cardTargetCollect)(DragSource('card', cardSource, cardSourceCollect)(CardRaw)); | |
//APP | |
class App extends React.Component { | |
state = {disabled: false}; | |
render() { | |
return ( | |
<div className={css.wrapper}> | |
<Phase/> | |
</div> | |
); | |
} | |
} | |
export default DragDropContext(HTML5Backend)(App); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment