JSFiddle - React, Tailwind, and code Playground
by Ben Schnell
HTML
<ul class="container" data-alignment="horizontal">
<li class="draggable" draggable="true"><span>0</span> Colorado</li>
<li class="draggable" draggable="true"><span>1</span> Montana</li>
<li class="draggable" draggable="true"><span>2</span> Utah</li>
<li class="draggable" draggable="true"><span>3</span> Montana</li>
<li class="draggable" draggable="true"><span>4</span> Wyoming</li>
</ul>
<ul class="container">
<li class="draggable" draggable="true"><span>0</span> Maine</li>
<li class="draggable" draggable="true"><span>1</span> North Carolina</li>
<li class="draggable" draggable="true"><span>2</span> Florida</li>
<li class="draggable" draggable="true"><span>3</span> Virginia</li>
<li class="draggable" draggable="true"><span>4</span> New York</li>
</ul>
CSS
.container {
max-width: 300px;
display: flex;
flex-wrap: wrap;
}
.container li {
height: 30px;
background-color: #fafafa;
border: 1px solid #888;
display: flex;
align-items: center;
}
.dragging {
opacity: 0.5;
}
.container li span {
background-color: #000;
margin-right: 10px;
color: #fff;
padding: 0 10px;
height: 100%;
display: flex;
align-items: center;
}
JavaScript
const draggables = document.querySelectorAll('.draggable')
const containers = document.querySelectorAll('.container')
draggables.forEach(draggable => {
draggable.addEventListener('dragstart', () => {
draggable.classList.add('dragging')
})
draggable.addEventListener('dragend', (e) => {
draggable.classList.remove('dragging');
dragUpdateNr();
})
})
containers.forEach(container => {
container.addEventListener('dragover', dragOver);
})
function dragOver(e) {
e.preventDefault()
const afterElement = getDragAfterElement(this, e);
const draggable = document.querySelector('.dragging')
if (afterElement == null) {
this.appendChild(draggable)
} else {
this.insertBefore(draggable, afterElement)
}
}
function getDragAfterElement(container, event) {
const dataAlignment = container.getAttribute('data-alignment');
const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')];
return draggableElements.find((draggableElement) => {
const box = draggableElement.getBoundingClientRect();
const x = event.clientX;
const y = event.clientY;
const boxLeftSideBounds = [box.x, ]
if () {
return true;
} else {
return false;
}
console.log(box, x, y);
});
/* return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect()
const offset = (dataAlignment === 'horizontal') ?
event.clientX - box.right - box.width / 2 :
event.clientY - box.top - box.height / 2;
if (offset < 0 && offset > closest.offset) {
return { offset: offset, element: child }
} else {
return closest
}
}, { offset: Number.NEGATIVE_INFINITY }).element */
}
function dragUpdateNr() {
let uls = document.querySelectorAll('ul.container');
uls.forEach(ul => {
let lis = ul.querySelectorAll('li.draggable');
for (let i=0; i<lis.length; i++) {
let li = lis[i];
...