Сделал упрощенный на ванильном js вариант.
Пока единственный вариант видится в блоке проверки на движение в лево или право, но тут уже начинаются
заморочки с dom и действиями над ним. Пока вопрос открыт и не совсем ясно как менять вложенность элементов при движении его влево/право.
if (prevX > e.pageX) {
console.log("dragged left");
} else if (prevX + 40 < e.pageX) {
console.log("dragged right");
}
ссылка на песочницу
https://codesandbox.io/s/vibrant-dre...le=/index.html
const tasksListElement = document.querySelectorAll(`.tasks-tree__list`);
const taskElements = document.querySelectorAll(`.tasks-tree__item`);
// link example [url]https://frontend-collective.github.io/react-sortable-tree/?path=/story/basics--treedata-import-export[/url]
// link example [url]https://dbushell.github.io/Nestable/[/url]
for (const task of taskElements) {
task.draggable = true;
}
const onDragStart = (e) => {
e.stopPropagation();
e.target.classList.add(`selected`);
};
const onDragEnd = (e) => {
e.stopPropagation();
e.target.classList.remove(`selected`);
};
let prevX = -1;
const onDragOver = (e) => {
e.preventDefault();
e.stopPropagation();
const selectedElement = document.querySelector(`.selected`);
const currentHoveredElement = e.target;
if (prevX == -1) {
prevX = e.pageX;
return false;
}
const isMoveable = currentHoveredElement.classList.contains(
`tasks-tree__item`
);
if (!isMoveable) {
return;
}
if (prevX > e.pageX) {
console.log("dragged left");
} else if (prevX + 40 < e.pageX) {
console.log("dragged right");
}
const nextElement =
currentHoveredElement === selectedElement?.nextElementSibling
? currentHoveredElement?.nextElementSibling
: currentHoveredElement;
currentHoveredElement?.parentNode.insertBefore(selectedElement, nextElement);
};
taskElements.forEach((el) => {
el.addEventListener(`dragstart`, onDragStart);
el.addEventListener(`dragover`, (e) => onDragOver(e));
el.addEventListener(`dragend`, (e) => onDragEnd(e));
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./style.css">
<title>Document</title>
</head>
<body>
<div class="container">
<section class="tasks">
<ul class="tasks-tree__list">
<li class="tasks-tree__item"><div>Item 1</div></li>
<li class="tasks-tree__item"><div>Item 2</div></li>
<li class="tasks-tree__item"><div>Item 3</div></li>
<li class="tasks-tree__item"><div>Item 4</div></li>
<li class="tasks-tree__item"><div>Item 5</div></li>
<li class="tasks-tree__item">
<div>Item 6</div>
<ul class="tasks-tree__list">
<li class="tasks-tree__item"><div>Item 1-2</div></li>
<li class="tasks-tree__item"><div>Item 2-2</div></li>
<li class="tasks-tree__item"><div>Item 3-2</div></li>
<li class="tasks-tree__item">
<div>Item 4-2</div>
<ul class="tasks-tree__list">
<li class="tasks-tree__item"><div>Item 1-3</div></li>
<li class="tasks-tree__item"><div>Item 2-3</div></li>
<li class="tasks-tree__item"><div>Item 3-3</div></li>
<li class="tasks-tree__item"><div>Item 4-3</div></li>
</ul>
</li>
</ul>
</li>
</ul>
</section>
</div>
<script src="./todo-tree.js" type="module"></script>
</body>
</html>
<style>
html, body {
margin: 0;
padding: 0;
}
body {
font-family: "Tahoma", sans-serif;
font-size: 18px;
line-height: 25px;
color: #164a44;
background-color: #b2d9d0;
}
.container {
display: flex;
justify-content: center;
}
.tasks__title {
margin: 50px 0 20px 0;
text-align: center;
text-transform: uppercase;
}
.tasks__list {
margin: 0;
padding: 0;
list-style: none;
}
.tasks__item {
max-width: 250px;
margin-bottom: 10px;
padding: 5px;
text-align: center;
border: 2px dashed #b2d9d0;
border-radius: 10px;
cursor: move;
background-color: #dff2ef;
transition: background-color 0.5s;
}
.tasks__item:last-child {
margin-bottom: 0;
}
.selected {
opacity: 0.6;
}
.tasks-tree__list {
margin-top: 16px;
list-style: none;
}
.tasks-tree__item {
max-width: 250px;
margin-bottom: 10px;
padding: 5px;
/* text-align: center; */
/* border: 2px dashed #b2d9d0; */
/* border-radius: 10px; */
cursor: move;
/* background-color: #dff2ef; */
transition: background-color 0.5s;
}
.tasks-tree__item div{
background-color: #dff2ef;
border: 2px dashed #b2d9d0;
}
</style>