JSFiddle - React, Tailwind, and code Playground
HTML
<div class="card-container">
<div class="card" draggable="true"><div class="card-body">1</div></div>
<div class="card" draggable="true"><div class="card-body">2</div></div>
<div class="card" draggable="true"><div class="card-body">3</div></div>
<div class="card" draggable="true"><div class="card-body">4</div></div>
<div class="card" draggable="true"><div class="card-body">5</div></div>
<div class="card" draggable="true"><div class="card-body">6</div></div>
<div class="card" draggable="true"><div class="card-body">7</div></div>
<div class="card" draggable="true"><div class="card-body">8</div></div>
<div class="card" draggable="true"><div class="card-body">9</div></div>
</div>
CSS
.card-container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding-top: 10px;
}
.card {
box-sizing: border-box;
margin-bottom: 10px;
width: calc(1/3 * 100% - (1 - 1/3) * 10px);
border: 1px solid #000;
background-color: #fff;
cursor: move;
}
.card-body {
padding: 10px;
font-family: sans-serif;
font-size: 32px;
text-align: center;
}
.ready-for-drop {
background-color: #0c0;
}
JavaScript
function dragstart_handler(e) {
dragging = e.target;
e.dataTransfer.setData('text', '');
}
function dragend_handler() {
dragging = null;
}
function dragenter_handler(e, el) {
if (dragging && dragging != el) {
el.classList.add('ready-for-drop');
}
}
function dragleave_handler(e, el) {
if (dragging && dragging != el && !el.contains(e.relatedTarget)) {
el.classList.remove('ready-for-drop');
}
}
function dragover_handler(e) {
e.preventDefault();
}
function drop_handler(e, el) {
e.preventDefault();
if (dragging && dragging != el) {
el.classList.remove('ready-for-drop');
var cards_array = Array.prototype.slice.call(cards);
var old_index = cards_array.indexOf(dragging);
var new_index = cards_array.indexOf(el);
if (old_index < new_index) {
el.parentNode.insertBefore(dragging, el.nextSibling);
}
else {
card_container.insertBefore(dragging, el);
}
}
}
var dragging = null;
var card_container = document.getElementsByClassName('card-container')[0];
var cards = document.getElementsByClassName('card');
for (var i = cards.length - 1; i >= 0; i--) {
cards[i].addEventListener('dragstart', dragstart_handler);
cards[i].addEventListener('dragend', dragend_handler);
cards[i].addEventListener('dragenter', function(e) {
dragenter_handler(e, this);
});
cards[i].addEventListener('dragleave', function(e) {
dragleave_handler(e, this);
});
cards[i].addEventListener('dragover', dragover_handler);
cards[i].addEventListener('drop', function(e) {
drop_handler(e, this);
});
}