DragAndDrop
DragAndDrop.tsx
import { useState } from 'react';
interface DragAndDropProps {
items: Array<{ id: number; name: string }>;
}
const DragAndDrop = ({ items }: DragAndDropProps) => {
const [draggedItem, setDraggedItem] = useState<{ id: number; name: string } | null>(null);
const [draggedOverIndex, setDraggedOverIndex] = useState<number | null>(null);
const [newItems, setNewItems] = useState(items);
const onDragStart = (event: React.DragEvent<HTMLDivElement>, index: number) => {
event.dataTransfer.setData('text/plain', '');
setDraggedItem(items[index]);
};
const onDragEnter = (event: React.DragEvent<HTMLDivElement>, index: number) => {
event.preventDefault();
setDraggedOverIndex(index);
};
const onDragEnd = () => {
if (draggedOverIndex !== null && draggedItem !== null) {
const newItemsCopy = [...newItems];
newItemsCopy.splice(newItemsCopy.indexOf(draggedItem), 1);
newItemsCopy.splice(draggedOverIndex, 0, draggedItem);
setNewItems(newItemsCopy);
}
setDraggedItem(null);
setDraggedOverIndex(null);
};
return (
<div className="drag-and-drop-container">
{newItems.map((item, index) => (
<div
key={item.id}
className={`drag-and-drop-item${draggedOverIndex === index ? ' dragged-over' : ''}`}
draggable
onDragStart={(event) => onDragStart(event, index)}
onDragEnter={(event) => onDragEnter(event, index)}
onDragEnd={onDragEnd}
>
{item.name}
</div>
))}
</div>
);
};
export default DragAndDrop;
DragAndDrop.module.css
.drag-and-drop-container {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.drag-and-drop-item {
display: flex;
align-items: center;
justify-content: center;
width: 120px;
height: 80px;
background-color: #eee;
border: 1px solid #ccc;
border-radius: 4px;
cursor: grab;
}
.dragged-over {
background-color: #ccc;
}