Skip to content

Commit 2ec0254

Browse files
authored
Patch: Adding drag and drop function on tag component
Patch: Adding drag and drop function on tag component
2 parents 6451f01 + 8e2e8d6 commit 2ec0254

5 files changed

Lines changed: 102 additions & 11 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"antd": "^4.16.8",
1010
"firebase": "^8.7.1",
1111
"html-react-parser": "^1.2.8",
12+
"immutability-helper": "^3.1.1",
1213
"react": "^17.0.2",
1314
"react-dnd": "^14.0.2",
1415
"react-dnd-html5-backend": "^14.0.0",

src/components/Card/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ const CardContainer = () => {
8181
{todoList?.length > 0 ? (
8282
<>
8383
<Col sm={24} md={12} lg={12}>
84-
{filterTodo().map((data, index) => {
84+
{filterTodo()?.map((data, index) => {
8585
if (index % 2 === 0) {
8686
return (
8787
<Card
@@ -95,7 +95,7 @@ const CardContainer = () => {
9595
})}
9696
</Col>
9797
<Col sm={24} md={12} lg={12}>
98-
{filterTodo().map((data, index) => {
98+
{filterTodo()?.map((data, index) => {
9999
if (index % 2 !== 0) {
100100
return (
101101
<Card

src/components/SideBar/Tag.js

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,71 @@
1-
import React, { useEffect, useState, memo, useContext } from "react";
2-
1+
import React, { useEffect, useState, memo, useContext, useRef } from "react";
2+
import { useDrag, useDrop } from "react-dnd";
33
//Scripts
44
import { dataContext } from "../../context/dataContext";
55

66
//Minor components
77
import { TagContent, Tag, DeleteIcon } from "./styles";
88

9-
const TagComponent = ({ data, index, type, style, todoAmount }) => {
9+
const TagComponent = ({ data, index, type, style, todoAmount, moveTag, id }) => {
10+
const ref = useRef(null);
11+
const [{ handlerId }, drop] = useDrop({
12+
accept: "tag",
13+
collect(monitor) {
14+
return {
15+
handlerId: monitor.getHandlerId(),
16+
};
17+
},
18+
hover(item, monitor) {
19+
if (!ref.current) {
20+
return;
21+
}
22+
const dragIndex = item.index;
23+
const hoverIndex = index;
24+
// Don't replace items with themselves
25+
if (dragIndex === hoverIndex) {
26+
return;
27+
}
28+
// Determine rectangle on screen
29+
const hoverBoundingRect = ref.current?.getBoundingClientRect();
30+
// Get vertical middle
31+
const hoverMiddleY =
32+
(hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
33+
// Determine mouse position
34+
const clientOffset = monitor.getClientOffset();
35+
// Get pixels to the top
36+
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
37+
// Only perform the move when the mouse has crossed half of the items height
38+
// When dragging downwards, only move when the cursor is below 50%
39+
// When dragging upwards, only move when the cursor is above 50%
40+
// Dragging downwards
41+
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
42+
return;
43+
}
44+
// Dragging upwards
45+
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
46+
return;
47+
}
48+
// Time to actually perform the action
49+
moveTag(dragIndex, hoverIndex);
50+
// Note: we're mutating the monitor item here!
51+
// Generally it's better to avoid mutations,
52+
// but it's good here for the sake of performance
53+
// to avoid expensive index searches.
54+
item.index = hoverIndex;
55+
},
56+
});
57+
//eslint-disable-next-line
58+
const [{ isDragging }, drag] = useDrag({
59+
type: "tag",
60+
item: () => {
61+
return { id, index };
62+
},
63+
collect: (monitor) => ({
64+
isDragging: monitor.isDragging(),
65+
}),
66+
});
67+
drag(drop(ref));
68+
1069
const [opacity, setOpacity] = useState(0);
1170
const [background, setBackground] = useState("");
1271
const [padding, setPadding] = useState(0);
@@ -86,10 +145,11 @@ const TagComponent = ({ data, index, type, style, todoAmount }) => {
86145
setOpacity(1);
87146
}, 250);
88147
}
89-
90148
return (
91149
<>
92150
<TagContent
151+
ref={ref}
152+
data-handler-id={handlerId}
93153
style={{
94154
...style,
95155
opacity: opacity,

src/components/SideBar/index.js

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React, { useState, useContext } from "react";
1+
import React, { useState, useContext, useCallback } from "react";
2+
import update from "immutability-helper";
23
//Context
34
import { dataContext } from "../../context/dataContext.js";
45

@@ -21,10 +22,25 @@ import {
2122
} from "./styles";
2223

2324
const SideBar = () => {
24-
const { tagList, todoList, relationTagTodo } = useContext(dataContext);
25+
const { tagList, setTagList, todoList, relationTagTodo } = useContext(dataContext);
2526
const [showModal, setShowModal] = useState(false);
2627
const [searchValue, setSearchValue] = useState("");
2728

29+
const moveTag = useCallback(
30+
(dragIndex, hoverIndex) => {
31+
const dragCard = tagList[dragIndex];
32+
setTagList(
33+
update(tagList, {
34+
$splice: [
35+
[dragIndex, 1],
36+
[hoverIndex, 0, dragCard],
37+
],
38+
})
39+
);
40+
},
41+
[tagList, setTagList]
42+
);
43+
2844
function handleClickAdd() {
2945
window.gtag("event", "click-event", {
3046
event_category: "Open",
@@ -52,7 +68,14 @@ const SideBar = () => {
5268
/>
5369
</SearchContent>
5470
{filterArr(searchValue, tagList, "text").map((data, index) => (
55-
<TagComponent data={data} index={index} key={index} todoAmount={relationTagTodo}/>
71+
<TagComponent
72+
data={data}
73+
index={index}
74+
key={index}
75+
id={data.id}
76+
moveTag={moveTag}
77+
todoAmount={relationTagTodo}
78+
/>
5679
))}
5780
</>
5881
) : (

src/pages/Main/app.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import React, { useContext, useState, useEffect } from "react";
22
import { Col, Drawer } from "antd";
33

4+
import { DndProvider } from "react-dnd";
5+
import { HTML5Backend } from "react-dnd-html5-backend";
6+
47
//Minor Components
58
import {
69
Container,
@@ -103,14 +106,18 @@ const App = () => {
103106
style={{ position: "absolute" }}
104107
>
105108
<SideBarContent>
106-
<SideBar />
109+
<DndProvider backend={HTML5Backend}>
110+
<SideBar />
111+
</DndProvider>
107112
</SideBarContent>
108113
</Drawer>
109114
</div>
110115
) : (
111116
<Col xs={24} sm={24} md={24} lg={6} xl={6}>
112117
<SideBarContent>
113-
<SideBar />
118+
<DndProvider backend={HTML5Backend}>
119+
<SideBar />
120+
</DndProvider>
114121
</SideBarContent>
115122
</Col>
116123
)}

0 commit comments

Comments
 (0)