Skip to content

Commit

Permalink
feat(dragAndDrop):feature added
Browse files Browse the repository at this point in the history
  • Loading branch information
pritam-ea committed May 17, 2024
1 parent 0a72eed commit ef98894
Show file tree
Hide file tree
Showing 5 changed files with 245 additions and 19 deletions.
114 changes: 114 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"dnd-multi-backend": "^8.0.3",
"immutability-helper": "^3.1.1",
"react": "^18.3.1",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dnd-touch-backend": "^16.0.1",
"react-dom": "^18.3.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
Expand Down
26 changes: 7 additions & 19 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
import logo from './logo.svg';
import './App.css';
import React from 'react';
import CardList from './CardList';

function App() {
const App = () => {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
<h1>Drag and Drop Cards</h1>
<CardList />
</div>
);
}
};

export default App;
export default App;
64 changes: 64 additions & 0 deletions src/Card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from 'react';
import { useDrag, useDrop } from 'react-dnd';

const Card = ({ id, text, index, moveCard }) => {
const ref = React.useRef(null);

const [, drop] = useDrop({
accept: 'CARD',
hover(item, monitor) {
if (!ref.current) {
return;
}
const dragIndex = item.index;
const hoverIndex = index;

if (dragIndex === hoverIndex) {
return;
}

const hoverBoundingRect = ref.current?.getBoundingClientRect();
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
const clientOffset = monitor.getClientOffset();
const hoverClientY = clientOffset.y - hoverBoundingRect.top;

if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
return;
}

if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
return;
}

moveCard(dragIndex, hoverIndex);
item.index = hoverIndex;
},
});

const [{ isDragging }, drag] = useDrag({
type: 'CARD',
item: { id, index },
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});

drag(drop(ref));

return (
<div
ref={ref}
style={{
opacity: isDragging ? 0.5 : 1,
padding: '16px',
margin: '4px',
backgroundColor: 'lightblue',
cursor: 'move',
}}
>
{text}
</div>
);
};

export default Card;
55 changes: 55 additions & 0 deletions src/CardList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React, { useState, useCallback } from 'react';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { TouchBackend } from 'react-dnd-touch-backend';
import { MultiBackend, TouchTransition } from 'dnd-multi-backend';
import update from 'immutability-helper';
import Card from './Card';

const CardList = () => {
const [cards, setCards] = useState([
{ id: 1, text: 'Card 1' },
{ id: 2, text: 'Card 2' },
{ id: 3, text: 'Card 3' },
{ id: 4, text: 'Card 4' },
]);

const moveCard = useCallback((dragIndex, hoverIndex) => {
const dragCard = cards[dragIndex];
setCards(
update(cards, {
$splice: [
[dragIndex, 1],
[hoverIndex, 0, dragCard],
],
})
);
}, [cards]);

return (
<DndProvider
backend={MultiBackend}
options={{
backends: [
{
backend: HTML5Backend,
},
{
backend: TouchBackend,
options: { enableMouseEvents: true },
preview: true,
transition: TouchTransition,
},
],
}}
>
<div style={{ width: '200px', margin: '0 auto' }}>
{cards.map((card, index) => (
<Card key={card.id} index={index} id={card.id} text={card.text} moveCard={moveCard} />
))}
</div>
</DndProvider>
);
};

export default CardList;

0 comments on commit ef98894

Please sign in to comment.