I've built a simple drag-and-drop function in React. There are 2 columns that div
s can be dragged between and a third is not allowed. The CSS dynamically changes if one is to drag over the noDrop
div. The last part, however, is that I'd like the cursor to also change to cursor: not-allowed
. All of the CSS works except for this line. How can I get the cursor to change?
Edit: I have tried moving the cursor: not-allowed
into the "thing" div, but it didn't work either. I've updated the code to reflect this.
Code Sandbox: https://codesandbox.io/s/stack-overflow-cursor-question-tiv71?file=/src/Dnd.js
Dnd.js:
import React, { useState } from "react";
import "./Dnd.scss";
export default function Dnd() {
const initialItems = [
{ id: 1, group: "group1", value: "drag 1" },
{ id: 2, group: "group1", value: "drag 2" },
{ id: 3, group: "group1", value: "drag 3" }
];
const groups = ["group1", "group2", "noDrop"];
const [items, setItems] = useState(initialItems);
const [dragData, setDragData] = useState({});
const [noDrop, setNoDrop] = useState("");
const handleDragStart = (e, id, group) => {
setDragData({ id: id, initialGroup: group });
};
const handleDragEnter = (e, group) => {
if (group === "noDrop") {
setNoDrop("noDrop");
}
};
const handleDragLeave = (e) => {
setNoDrop("");
};
const handleDragOver = (e) => {
e.preventDefault();
};
const changeCategory = (itemId, group) => {
const newItems = [...items];
newItems[itemId - 1].group = group;
setItems([...newItems]);
};
const handleDrop = (e, group) => {
setNoDrop("");
const selected = dragData.id;
if (group === "noDrop") {
console.log("nuh uh");
} else {
changeCategory(selected, group);
}
};
return (
<>
<div className="groups">
{groups.map((group) => (
<div
className={`${
group === "noDrop" && noDrop === "noDrop" ? noDrop : "group"
}`}
onDragOver={handleDragOver}
onDragEnter={(e) => handleDragEnter(e, group)}
onDrop={(e) => handleDrop(e, group)}
onDragLeave={handleDragLeave}
key={group}
>
<h1 className="title">{group}</h1>
<div>
{items
.filter((item) => item.group === group)
.map((item) => (
<div
key={item.id}
id={item.id}
className={`${
group === "noDrop" && noDrop === "noDrop"
? "notAllowed"
: "thing"
}`} draggable
onDragStart={(e) => handleDragStart(e, item.id, group)}
>
{item.value}
</div>
))}
</div>
</div>
))}
</div>
</>
);
}
Dnd.scss
.groups {
display: flex;
margin: 20px;
padding: 20px;
flex-wrap: wrap;
.group {
margin: 20px;
padding: 20px;
min-height: 16rem;
background-color: green;
.title{
color: white;
padding: 0;
margin-top: 0;
}
}
.noDrop {
margin: 20px;
padding: 20px;
min-height: 16rem;
background-color: red;
.title{
color: white;
padding: 0;
margin-top: 0;
}
}
}
.thing {
background-color: yellow;
color: blue;
margin: 5px;
padding: 5px;
border: 2px green;
cursor: grab;
}
.notAllowed {
background-color: yellow;
color: blue;
margin: 5px;
padding: 5px;
border: 2px green;
cursor: not-allowed !important;
}