Skip to content
This repository was archived by the owner on Nov 3, 2021. It is now read-only.

Commit e79907f

Browse files
authored
Merge pull request #919 from intellihr/intellihr/engineering/guilds/front-end#14403
Add onChange prop to DraggableList
2 parents 00b6666 + 4ffd1b2 commit e79907f

File tree

2 files changed

+54
-37
lines changed

2 files changed

+54
-37
lines changed

src/domain/Lists/DraggableList/DraggableList.examples.md

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
#### Draggable List
22

3+
DraggableList can work as both a standalone component or within a ReduxForm
4+
5+
`onChange` returns the source and destination indexes for you to handle setting the state once the drag ends.
6+
7+
When using ReduxForm's FieldArray, simply pass the `fields.move` to the `onChange` and it will handle the state management for you.
8+
9+
_setItems_ is deprecated and should no longer be used.
10+
311
```jsx
412
initialState = {
513
items: [
@@ -10,28 +18,19 @@ initialState = {
1018
]
1119
};
1220

13-
/*
14-
useState Hooks version - this is ideally what you would use, but we can't show this as an example in styleguidist
15-
16-
const [items, setItems] = useState(['lisa', 'needs', 'braces', 'dental plan!'])
17-
18-
<DraggableList setItems={setItems}>
19-
{state.items.map(item => (
20-
<div>
21-
{item}
22-
</div>
23-
))}
24-
</DraggableList>
25-
*/
26-
2721
<DraggableList
2822
droppableId='b4bb0ac5-0474-4760-8bbb-6bf92d60b2ba'
29-
setItems={(itemsCallback) => {
30-
return setState((prevState) => {
31-
return { items: itemsCallback(prevState.items)}
23+
onChange={(sourceIndex, destinationIndex) => {
24+
setState((prevState) => {
25+
// You can use something like npm array-move instead of the following code
26+
const clonedItems = Array.from(prevState.items)
27+
const element = clonedItems[sourceIndex]
28+
clonedItems.splice(sourceIndex, 1)
29+
clonedItems.splice(destinationIndex, 0, element)
30+
return { items: clonedItems }
3231
})
33-
}
34-
}>
32+
}}
33+
>
3534
{state.items.map(item => (
3635
<div>
3736
{item}
@@ -80,12 +79,17 @@ initialState = {
8079

8180
<DraggableList
8281
droppableId='b4bb0ac5-0474-4760-8bbb-6bf92d60b2ba'
83-
setItems={(itemsCallback) => {
84-
return setState((prevState) => {
85-
return { items: itemsCallback(prevState.items)}
82+
onChange={(sourceIndex, destinationIndex) => {
83+
setState((prevState) => {
84+
// You can use something like npm array-move instead of the following code
85+
const clonedItems = Array.from(prevState.items)
86+
const element = clonedItems[sourceIndex]
87+
clonedItems.splice(sourceIndex, 1)
88+
clonedItems.splice(destinationIndex, 0, element)
89+
return { items: clonedItems }
8690
})
87-
}
88-
}>
91+
}}
92+
>
8993
{state.items.map((item, index) => (
9094
<div>
9195
{item}
@@ -135,12 +139,17 @@ initialState = {
135139

136140
<DraggableList
137141
droppableId='b4bb0ac5-0474-4760-8bbb-6bf92d60b2ba'
138-
setItems={(itemsCallback) => {
139-
return setState((prevState) => {
140-
return { items: itemsCallback(prevState.items)}
142+
onChange={(sourceIndex, destinationIndex) => {
143+
setState((prevState) => {
144+
// You can use something like npm array-move instead of the following code
145+
const clonedItems = Array.from(prevState.items)
146+
const element = clonedItems[sourceIndex]
147+
clonedItems.splice(sourceIndex, 1)
148+
clonedItems.splice(destinationIndex, 0, element)
149+
return { items: clonedItems }
141150
})
142-
}
143-
}>
151+
}}
152+
>
144153
{state.items.map((item, index) => (
145154
<RadioSet
146155
key={item.id}

src/domain/Lists/DraggableList/DraggableList.tsx

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ import { StyledDraggableList, StyledListArea, StyledListItem } from './style'
1212
interface IDraggableListProps<T> {
1313
/** Droppable area id - this allows us to have more than one per page */
1414
droppableId: string
15+
/** DEPRECATED // useState hook to update the array of items when they have been re-arranged */
16+
setItems?: React.Dispatch<React.SetStateAction<T[]>>
1517
/** useState hook to update the array of items when they have been re-arranged */
16-
setItems: React.Dispatch<React.SetStateAction<T[]>>
18+
onChange?: (sourceIndex: number, destinationIndex: number) => void
1719
/** An array of ReactElements that should represent the array of items */
1820
children: React.ReactElement[]
1921
/** The margins around the component */
@@ -22,19 +24,25 @@ interface IDraggableListProps<T> {
2224
componentContext?: string
2325
}
2426

25-
const DraggableList = <T extends {}> ({ droppableId, setItems, children, margins, componentContext }: IDraggableListProps<T>) => {
27+
const DraggableList = <T extends {}> ({ droppableId, onChange, setItems, children, margins, componentContext }: IDraggableListProps<T>) => {
2628
const onDragEnd = (result: DropResult) => {
2729
if (!result.destination) {
2830
return
2931
}
3032
const { source, destination } = result
3133

32-
setItems((previousItems) => {
33-
const newItems = [...previousItems]
34-
const [removed] = newItems.splice(source.index, 1)
35-
newItems.splice(destination.index, 0, removed)
36-
return newItems
37-
})
34+
if (onChange) {
35+
onChange(source.index, destination.index)
36+
}
37+
38+
if (setItems) {
39+
setItems((previousItems) => {
40+
const newItems = [...previousItems]
41+
const [removed] = newItems.splice(source.index, 1)
42+
newItems.splice(destination.index, 0, removed)
43+
return newItems
44+
})
45+
}
3846
}
3947

4048
return (

0 commit comments

Comments
 (0)