-
Notifications
You must be signed in to change notification settings - Fork 7
Droppable doesn't work if used on an element with display: contents #10
Copy link
Copy link
Open
Labels
bugSomething isn't workingSomething isn't workinghelp wantedExtra attention is neededExtra attention is needed
Description
Hi, I found this bug while using your library. I am willing to create a PR to fix this if you'd like.
Steps to reproduce
- Use
display: contentson an element - Make a Droppable with it
- It doesn't work (the Droppable only uses the bounding box of the container to calculate the droppable area, which is always [0,0,0,0] on elements with
display: contents)
Expected behavior
If the bounding box is [0,0,0,0], the Droppable should use the union of the bounding boxes of any not-absolutely-positioned children as the droppable area.
Code
This code doesn't work
import agnosticDraggable from "https://cdn.skypack.dev/agnostic-draggable@1.4.3";
const { Draggable, Droppable } = agnosticDraggable
const app = document.createElement("div")
const data = [
{ name: "foo", number: 100, date: new Date(Date.now() - 2 * 60 * 1000).toLocaleString() },
{ name: "bar", number: 200, date: new Date(Date.now() - 60 * 1000).toLocaleString() },
{ name: "baz", number: 300, date: new Date(Date.now()).toLocaleString() }
]
const table = document.createElement("table")
table.style.width = "calc(100% - 40px)"
table.style.margin = "20px"
table.style.display = "grid"
table.style.gridTemplateColumns = "auto auto auto"
const thead = document.createElement("thead")
thead.style.display = "contents"
const tbody = document.createElement("tbody")
tbody.style.display = "contents"
const tr = document.createElement("tr")
tr.style.display = "contents"
for (const col of Object.keys(data[0])) {
const th = document.createElement("th")
th.style.background = "rgba(127, 127, 127, .1)"
th.style.padding = "8px"
th.style.border = "solid rgb(127,127,127)"
th.style.borderWidth = "1px 0"
th.textContent = col
tr.appendChild(th)
}
thead.appendChild(tr)
for (const row of data) {
const tr = document.createElement("tr")
tr.style.display = "contents"
const cells = Object.values(row).map((cell) => {
const td = document.createElement("td")
td.style.padding = "8px"
td.style.border = "solid rgb(127,127,127)"
td.style.borderWidth = "1px 0"
td.textContent = cell
tr.appendChild(td)
})
tbody.appendChild(tr)
new Droppable(
tr,
{
tolerance: "pointer",
},
{
"droppable:over": () => {
tr.style.background = "blue"
},
"droppable:out": () => {
tr.style.background = ""
},
"droppable:drop": () => {
tr.style.background = ""
const td = tr.querySelector("td:nth-child(2)")
td.textContent = parseInt(td.textContent) + 1
}
}
)
}
table.appendChild(thead)
table.appendChild(tbody)
app.appendChild(table)
const addDiv = document.createElement("div")
addDiv.style.display = "inline-block"
addDiv.style.margin = "20px"
addDiv.style.padding = "8px"
addDiv.style.background = "rgb(127,127,127)"
addDiv.textContent = "Drop me on a row to add 1"
app.appendChild(addDiv)
document.body.appendChild(app)
let listener = (e) => {
e.preventDefault()
}
new Draggable(
addDiv,
{
revert: true,
},
{
"drag:start": () => {
document.body.addEventListener("selectstart", listener)
},
"drag:stop": () => {
document.body.removeEventListener("selectstart", listener)
}
}
)This code works
import agnosticDraggable from "https://cdn.skypack.dev/agnostic-draggable@1.4.3";
const { Draggable, Droppable } = agnosticDraggable
const app = document.createElement("div")
const data = [
{ name: "foo", number: 100, date: new Date(Date.now() - 2 * 60 * 1000).toLocaleString() },
{ name: "bar", number: 200, date: new Date(Date.now() - 60 * 1000).toLocaleString() },
{ name: "baz", number: 300, date: new Date(Date.now()).toLocaleString() }
]
const table = document.createElement("table")
table.style.width = "calc(100% - 40px)"
table.style.margin = "20px"
const thead = document.createElement("thead")
const tbody = document.createElement("tbody")
const tr = document.createElement("tr")
for (const col of Object.keys(data[0])) {
const th = document.createElement("th")
th.style.background = "rgba(127, 127, 127, .1)"
th.style.padding = "8px"
th.style.border = "solid rgb(127,127,127)"
th.style.borderWidth = "1px 0"
th.textContent = col
tr.appendChild(th)
}
thead.appendChild(tr)
for (const row of data) {
const tr = document.createElement("tr")
const cells = Object.values(row).map((cell) => {
const td = document.createElement("td")
td.style.padding = "8px"
td.style.border = "solid rgb(127,127,127)"
td.style.borderWidth = "1px 0"
td.textContent = cell
tr.appendChild(td)
})
tbody.appendChild(tr)
new Droppable(
tr,
{
tolerance: "pointer",
},
{
"droppable:over": () => {
tr.style.background = "blue"
},
"droppable:out": () => {
tr.style.background = ""
},
"droppable:drop": () => {
tr.style.background = ""
const td = tr.querySelector("td:nth-child(2)")
td.textContent = parseInt(td.textContent) + 1
}
}
)
}
table.appendChild(thead)
table.appendChild(tbody)
app.appendChild(table)
const addDiv = document.createElement("div")
addDiv.style.display = "inline-block"
addDiv.style.margin = "20px"
addDiv.style.padding = "8px"
addDiv.style.background = "rgb(127,127,127)"
addDiv.textContent = "Drop me on a row to add 1"
app.appendChild(addDiv)
document.body.appendChild(app)
let listener = (e) => {
e.preventDefault()
}
new Draggable(
addDiv,
{
revert: true,
},
{
"drag:start": () => {
document.body.addEventListener("selectstart", listener)
},
"drag:stop": () => {
document.body.removeEventListener("selectstart", listener)
}
}
)Suggested solution
- If the Droppable element has a bounding box of [0,0,0,0], search deeply for any children (excluding
position: absoluteorposition: fixed) that have a not-zero bounding box - Use those bounding boxes to test whether a Draggable is over the Droppable
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workinghelp wantedExtra attention is neededExtra attention is needed