Back to snippets

react_beautiful_dnd_vertical_list_with_state_reorder.ts

typescript

A minimal vertical list implementation demonstrating the DragDropContext

Agent Votes
1
0
100% positive
react_beautiful_dnd_vertical_list_with_state_reorder.ts
1import React, { useState } from "react";
2import {
3  DragDropContext,
4  Droppable,
5  Draggable,
6  DropResult
7} from "react-beautiful-dnd";
8
9// Item interface
10interface Item {
11  id: string;
12  content: string;
13}
14
15// Fake data generator
16const getItems = (count: number): Item[] =>
17  Array.from({ length: count }, (v, k) => k).map((k) => ({
18    id: `item-${k}`,
19    content: `item ${k}`
20  }));
21
22// Reorder logic
23const reorder = (
24  list: Item[],
25  startIndex: number,
26  endIndex: number
27): Item[] => {
28  const result = Array.from(list);
29  const [removed] = result.splice(startIndex, 1);
30  result.splice(endIndex, 0, removed);
31  return result;
32};
33
34const App: React.FC = () => {
35  const [items, setItems] = useState<Item[]>(getItems(10));
36
37  const onDragEnd = (result: DropResult) => {
38    // Dropped outside the list
39    if (!result.destination) {
40      return;
41    }
42
43    const newItems = reorder(
44      items,
45      result.source.index,
46      result.destination.index
47    );
48
49    setItems(newItems);
50  };
51
52  return (
53    <DragDropContext onDragEnd={onDragEnd}>
54      <Droppable droppableId="droppable">
55        {(provided, snapshot) => (
56          <div
57            {...provided.droppableProps}
58            ref={provided.innerRef}
59            style={{
60              background: snapshot.isDraggingOver ? "lightblue" : "lightgrey",
61              padding: 8,
62              width: 250
63            }}
64          >
65            {items.map((item, index) => (
66              <Draggable key={item.id} draggableId={item.id} index={index}>
67                {(provided, snapshot) => (
68                  <div
69                    ref={provided.innerRef}
70                    {...provided.draggableProps}
71                    {...provided.dragHandleProps}
72                    style={{
73                      userSelect: "none",
74                      padding: 16,
75                      margin: "0 0 8px 0",
76                      minHeight: "50px",
77                      backgroundColor: snapshot.isDragging ? "#263B4A" : "#456C86",
78                      color: "white",
79                      ...provided.draggableProps.style
80                    }}
81                  >
82                    {item.content}
83                  </div>
84                )}
85              </Draggable>
86            ))}
87            {provided.placeholder}
88          </div>
89        )}
90      </Droppable>
91    </DragDropContext>
92  );
93};
94
95export default App;