Skip to content

Commit 953c9ac

Browse files
committed
Extend react-smooth-dnd to lanes
1 parent 047b931 commit 953c9ac

5 files changed

Lines changed: 60 additions & 12 deletions

File tree

src/actions/LaneActions.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ export const moveCardAcrossLanes = createAction('MOVE_CARD')
66
export const updateCards = createAction('UPDATE_CARDS')
77
export const updateLanes = createAction('UPDATE_LANES')
88
export const paginateLane = createAction('PAGINATE_LANE')
9+
export const moveLane = createAction('MOVE_LANE')

src/components/BoardContainer.js

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {BoardDiv} from '../styles/Base'
66
import {bindActionCreators} from 'redux'
77
import {connect} from 'react-redux'
88
import Lane from './Lane'
9+
import {Container, Draggable} from 'react-smooth-dnd'
910

1011
import * as boardActions from '../actions/BoardActions'
1112
import * as laneActions from '../actions/LaneActions'
@@ -59,6 +60,20 @@ class BoardContainer extends Component {
5960
return this.props.reducerData.lanes.find(lane => lane.id === laneId).cards[cardIndex]
6061
}
6162

63+
onDragStart = (index, payload) => {
64+
const {handleLaneDragStart} = this.props
65+
handleLaneDragStart(payload.id)
66+
}
67+
68+
onLaneDrop = ({removedIndex, addedIndex, payload}) => {
69+
const {actions, handleLaneDragEnd} = this.props
70+
actions.moveLane({oldIndex: removedIndex, newIndex: addedIndex})
71+
handleLaneDragEnd(payload.id, addedIndex)
72+
}
73+
74+
getLaneDetails = (index) => {
75+
return this.props.reducerData.lanes[index]
76+
}
6277

6378
render() {
6479
const {reducerData, style, ...otherProps} = this.props
@@ -85,22 +100,31 @@ class BoardContainer extends Component {
85100
])
86101

87102
return (
88-
<BoardDiv style={style} {...otherProps} draggable={false}>
103+
<BoardDiv style={style} {...otherProps} draggable={false}>
104+
<Container
105+
orientation="horizontal"
106+
onDragStart={this.onDragStart}
107+
onDrop={this.onLaneDrop}
108+
getChildPayload={index => this.getLaneDetails(index)}
109+
groupName="TrelloBoard">
89110
{reducerData.lanes.map((lane, index) => {
90111
const {id, droppable, ...otherProps} = lane
91112
return (
92-
<Lane
93-
key={id}
94-
id={id}
95-
getCardDetails={this.getCardDetails}
96-
index={index}
97-
droppable={droppable === undefined ? true : droppable}
98-
{...otherProps}
99-
{...passthroughProps}
100-
/>
113+
<Draggable key={lane.id}>
114+
<Lane
115+
key={id}
116+
id={id}
117+
getCardDetails={this.getCardDetails}
118+
index={index}
119+
droppable={droppable === undefined ? true : droppable}
120+
{...otherProps}
121+
{...passthroughProps}
122+
/>
123+
</Draggable>
101124
)
102125
})}
103-
</BoardDiv>
126+
</Container>
127+
</BoardDiv>
104128
)
105129
}
106130
}
@@ -124,6 +148,8 @@ BoardContainer.propTypes = {
124148
hideCardDeleteIcon: PropTypes.bool,
125149
handleDragStart: PropTypes.func,
126150
handleDragEnd: PropTypes.func,
151+
handleLaneDragStart: PropTypes.func,
152+
handleLaneDragEnd: PropTypes.func,
127153
customCardLayout: PropTypes.bool,
128154
newCardTemplate: PropTypes.node,
129155
customLaneHeader: PropTypes.element,
@@ -135,6 +161,8 @@ BoardContainer.defaultProps = {
135161
onDataChange: () => {},
136162
handleDragStart: () => {},
137163
handleDragEnd: () => {},
164+
handleLaneDragStart: () => {},
165+
handleLaneDragEnd: () => {},
138166
editable: false,
139167
hideCardDeleteIcon: false,
140168
draggable: false,

src/helpers/LaneHelper.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ const LaneHelper = {
8080

8181
updateLanes: (state, lanes) => {
8282
return {...state, ...{lanes: lanes}}
83+
},
84+
85+
moveLane: (state, {oldIndex, newIndex}) => {
86+
const laneToMove = state.lanes[oldIndex]
87+
const tempState = update(state, {lanes: {$splice: [[oldIndex, 1]]}});
88+
return update(tempState, {lanes: {$splice: [[newIndex, 0, laneToMove]]}})
8389
}
8490
}
8591

src/reducers/BoardReducer.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ const boardReducer = (state = {lanes: []}, action) => {
1717
return Lh.updateLanes(state, payload)
1818
case 'PAGINATE_LANE':
1919
return Lh.paginateLane(state, payload)
20+
case 'MOVE_LANE':
21+
return Lh.moveLane(state, payload)
2022
default:
2123
return state
2224
}

stories/DragDrop.story.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const data = require('./data/base.json')
88

99
storiesOf('Drag-n-Drop', module).add(
1010
'Basic',
11-
withInfo('A demonstration of onDragStart and onDragEnd hooks')(() => {
11+
withInfo('A demonstration of onDragStart and onDragEnd hooks for card and lanes')(() => {
1212
const handleDragStart = (cardId, laneId) => {
1313
console.log('drag started')
1414
console.log(`cardId: ${cardId}`)
@@ -23,6 +23,15 @@ storiesOf('Drag-n-Drop', module).add(
2323
console.log(`newPosition: ${position}`)
2424
}
2525

26+
const handleLaneDragStart = (laneId) => {
27+
console.log(`lane drag started for ${laneId}`)
28+
}
29+
30+
const handleLaneDragEnd = (laneId, newPosition) => {
31+
console.log(`lane drag ended for ${laneId}`)
32+
console.log(`New lane position: ${newPosition}`)
33+
}
34+
2635
const shouldReceiveNewData = nextData => {
2736
console.log('data has changed')
2837
console.log(nextData)
@@ -35,6 +44,8 @@ storiesOf('Drag-n-Drop', module).add(
3544
onDataChange={shouldReceiveNewData}
3645
handleDragStart={handleDragStart}
3746
handleDragEnd={handleDragEnd}
47+
handleLaneDragStart={handleLaneDragStart}
48+
handleLaneDragEnd={handleLaneDragEnd}
3849
/>
3950
)
4051
})

0 commit comments

Comments
 (0)