Skip to content

Instantly share code, notes, and snippets.

@thomd
Last active October 7, 2024 19:24
Show Gist options
  • Save thomd/d77cdfa4fa1358f91e45a0979c33d656 to your computer and use it in GitHub Desktop.
Save thomd/d77cdfa4fa1358f91e45a0979c33d656 to your computer and use it in GitHub Desktop.
Simple Example for React DragDrop Library @hello-pangea/dnd

Setup

npx create-react-app myapp --template @thomd/cra-template-simple
cd myapp
npm install @hello-pangea/dnd --sav

Then update App.jsx and npm start

import React, { useState } from 'react'
import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd'
// fake data generator
const getItems = (count, offset = 0) =>
Array.from({ length: count }, (v, k) => k).map((k) => ({
id: `item-${k + offset}-${new Date().getTime()}`,
content: `item ${k + offset}`,
}))
const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list)
const [removed] = result.splice(startIndex, 1)
result.splice(endIndex, 0, removed)
return result
}
// move item from one list to another list.
const move = (source, destination, droppableSource, droppableDestination) => {
const sourceClone = Array.from(source)
const destClone = Array.from(destination)
const [removed] = sourceClone.splice(droppableSource.index, 1)
destClone.splice(droppableDestination.index, 0, removed)
const result = {}
result[droppableSource.droppableId] = sourceClone
result[droppableDestination.droppableId] = destClone
return result
}
const getItemStyle = (isDragging, draggableStyle) => ({
userSelect: 'none',
padding: '1rem',
margin: `0 0 1rem 0`,
background: isDragging ? 'lightgreen' : 'grey',
...draggableStyle,
})
const getListStyle = (isDraggingOver) => ({
background: isDraggingOver ? 'lightblue' : 'lightgrey',
padding: '1rem',
width: '16rem',
})
export default function App() {
const [state, setState] = useState([getItems(4), getItems(4, 4)])
function onDragEnd(result) {
const { source, destination } = result
if (!destination) {
return
}
const sInd = +source.droppableId
const dInd = +destination.droppableId
if (sInd === dInd) {
const items = reorder(state[sInd], source.index, destination.index)
const newState = [...state]
newState[sInd] = items
setState(newState)
} else {
const result = move(state[sInd], state[dInd], source, destination)
const newState = [...state]
newState[sInd] = result[sInd]
newState[dInd] = result[dInd]
setState(newState.filter((group) => group.length))
}
}
return (
<div>
<div style={{ display: 'flex' }}>
<DragDropContext onDragEnd={onDragEnd}>
{state.map((el, ind) => (
<Droppable key={ind} droppableId={`${ind}`}>
{(provided, snapshot) => (
<div ref={provided.innerRef} style={getListStyle(snapshot.isDraggingOver)} {...provided.droppableProps}>
{el.map((item, index) => (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(snapshot.isDragging, provided.draggableProps.style)}>
<div
style={{
display: 'flex',
justifyContent: 'space-around',
}}>
{item.content}
</div>
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
))}
</DragDropContext>
</div>
</div>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment