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.

Revisions

  1. thomd revised this gist Oct 7, 2024. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion App.jsx
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,4 @@
    import React, { useState } from 'react'
    import ReactDOM from 'react-dom'
    import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd'

    // fake data generator
  2. thomd revised this gist Oct 7, 2024. 2 changed files with 106 additions and 1 deletion.
    105 changes: 105 additions & 0 deletions App.jsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,105 @@
    import React, { useState } from 'react'
    import ReactDOM from 'react-dom'
    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>
    )
    }
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -4,4 +4,4 @@
    cd myapp
    npm install @hello-pangea/dnd --sav

    Then update `App.jsx`
    Then update `App.jsx` and `npm start`
  3. thomd created this gist Oct 7, 2024.
    7 changes: 7 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    ## Setup

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

    Then update `App.jsx`