marcospont / agnostic-draggable Goto Github PK
View Code? Open in Web Editor NEWAn agnostic set of libraries implementing draggable, droppable, sortable and resizable behaviors inspired by the jQuery UI implementation
License: MIT License
An agnostic set of libraries implementing draggable, droppable, sortable and resizable behaviors inspired by the jQuery UI implementation
License: MIT License
Hi, I found this bug while using your library. I am willing to create a PR to fix this if you'd like.
display: contents
on an elementdisplay: contents
)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.
import agnosticDraggable from "https://cdn.skypack.dev/[email protected]";
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)
}
}
)
import agnosticDraggable from "https://cdn.skypack.dev/[email protected]";
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)
}
}
)
position: absolute
or position: fixed
) that have a not-zero bounding boxWhen you have:
const drag = new Draggable(document.querySelector('.square-2'), {
helper: "clone",
scroll: false,
zIndex: 3,
});
const drop = new Droppable(document.querySelector(".action-button-use"), {
accept: function(d: any){ console.log(d); },
})
every time you move the draggable div
on droppable div
it triggers the accept function
.
Could you build upon the documentation to clarify some of the data that is returned?
Immediately, I am looking to use peerSortable
but I do not know the nature of its data and if it is always present and/or reliable, and if it is always the previously connected sortable or something else.
Hi, I found this bug while using your library. I don't know how to fix this one.
Text won't deselect:
Selection can't be used:
Text selection should stay normal when interacting with other elements when using the library.
import agnosticDraggable from "https://cdn.skypack.dev/[email protected]";
const { Sortable } = agnosticDraggable
const app = document.createElement("div")
const ipsum = document.createElement("div")
ipsum.textContent = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tincidunt pretium quam, a pellentesque erat tempor eget. Ut nec ex porttitor, interdum dolor nec, consequat lectus. Sed orci orci, sodales ac tincidunt in, accumsan in neque. Phasellus rutrum eros eget purus aliquet, vitae tincidunt lacus eleifend. Proin ultricies efficitur dui sit amet feugiat. Sed vel suscipit augue, posuere scelerisque massa. In vulputate laoreet lacinia. Aliquam erat volutpat. Etiam scelerisque dictum sodales. Mauris auctor egestas nunc in suscipit. Nullam hendrerit neque a feugiat eleifend. Integer et ornare velit, vitae sodales sapien. Vestibulum sollicitudin pulvinar ligula, at scelerisque ex molestie vel.`
app.appendChild(ipsum)
document.body.appendChild(app)
const container = document.createElement("div")
const els = new Array(10).fill(null).map(() => document.createElement("div"))
els.forEach((el, i) => {
el.textContent = "Item: " + (i + 1)
container.appendChild(el)
})
app.appendChild(container)
new Sortable(container)
mousedown
event on the html
element via devtools makes text selection normal againsortable.destroy()
after creating a Sortable doesn't fix the issue, so it's possible that an event listener also isn't properly removedIs it possible to update disabled option on draggable component ? It doesnt seem to update if i create it like this (this.lock = prop):
new Draggable(this.$refs.Item, { helper: "clone", containment: "body", zIndex: 5, disabled: this.lock });
Hi, I found this bug while using your library. I am willing to create a PR to fix this if you'd like.
Item should stay the same size before, during, and after dragging.
import agnosticDraggable from "https://cdn.skypack.dev/[email protected]";
const { Sortable } = agnosticDraggable
const container = document.createElement("div")
container.style.padding = "4px 0"
const els = new Array(10).fill(null).map(() => document.createElement("div"))
els.forEach((el, i) => {
el.textContent = "Item: " + (i + 1)
el.style.padding = "8px"
el.style.margin = "4px 8px"
el.style.background = "rgba(127, 127, 127, .1)"
container.appendChild(el)
})
document.body.appendChild(container)
new Sortable(container)
Option 1: Don't compute a height and width for dragged elements (would have effects on elements that inherit size from the positioning in the container, for example flexbox and grid elements)
Option 2: Account for padding+border in getting the size of the element (has to account for box-sizing)
I have been exploring all the events currently available, and it appears the most relevant event to an element being reordered in the same sortable is sortable:update
, however that returns all the data for the sortable the element is connected to, not the element itself.
More appropriately, the sortable:remove
and sortable:receive
events return data about the elements themselves when they are added/removed from a sortable, but there appears to be no equivalent event for when an element is reordered within the sortable it is already a part of. I understand that technically, many elements are reordered simultaneously when one element is reordered, however, if there were some separate sortable:reorder
event fired for the element actually dragged and dropped including its previous and new position/index within the list, the rest could be easily inferred.
In the case of linked arrays, this would be helpful so I could splice the element from its previous position/index to its new one.
Hey, how do i properly listen to events?
new Draggable(document.querySelector(`#Item${index}`),null, {
revert: "invalid",
helper: "clone",
zIndex: 1000,
"drag:start": function (event) {
event.cancel();
},
});
gives me an error if i dont delete revert, helper and zIndex
Also what does that null mean?
Will you ever add support for mobile devices by any chance? Or is there a way to make dragndrop working on mobile?
Hi @marcospont
I really appreciate work done for agnostic-draggable
. It's easy to use and it's filling all the gaps that I had after using packages like sortablejs
or @shopify/draggable
๐
Just wondering, if there is a way to make the bundle size smaller? Currently, it's quite big like showing on bundlephobia below:
https://bundlephobia.com/package/[email protected]
Similar packages seems to be smaller, so maybe there is a chance to optimize? (ESM output?)
Thank you in advance for all your work done for this package ๐ป
what the title says
line 133 in sensor/mouse-sensor.js
-> document.removeEventListener('contextmenu', preventDefault, true);
Hello community,
I haven't found in the docs how to remove the event from the Element
.
Is there a way to do so ?
Thanks
Hello,
at first, thanks a lot for this wonderful contribution: for quite a while, I thought about implementing s.th. similar myself - but always withdrew that idea because of the foreseeable effort.
But now, everything I had to do was to write a trivial wrapper around your module in order to use it with Svelte.
However, that work raised a few questions, two of them are:
Thanks in advance for your effort!
Kind regards,
Andreas Rozek
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.