Shopify Draggable — это современная
JavaScript-библиотека для реализации drag-and-drop интерфейсов с гибкой
архитектурой событий. Она построена на модульной структуре, что
позволяет подключать только необходимые компоненты:
Draggable, Sortable, Swappable,
Droppable и плагины для расширения функциональности.
Базовый принцип работы строится на объекте Draggable, который привязывается к контейнеру и его элементам. Основные параметры конструктора:
import { Draggable } from '@shopify/draggable';
const draggable = new Draggable(document.querySelectorAll('.list'), {
draggable: '.item',
delay: 0,
mirror: {
constrainDimensions: true
}
});
draggable — CSS-селектор элементов, которые можно
перетаскивать.delay — задержка перед началом перетаскивания, полезна
для адаптации под мобильные устройства.mirror — настройка визуальной копии элемента при
перетаскивании. Опция constrainDimensions сохраняет
оригинальные размеры.Draggable использует событийный API, который позволяет реагировать на все этапы перетаскивания:
draggable.on('drag:start', (event) => {
console.log('Начало перетаскивания:', event.source);
});
draggable.on('drag:stop', (event) => {
console.log('Перетаскивание завершено:', event.source);
});
draggable.on('drag:move', (event) => {
console.log('Элемент движется:', event.source);
});
События можно фильтровать по типу действия: drag:start,
drag:move, drag:stop,
mirror:created, mirror:destroyed. Это особенно
важно для динамических интерфейсов и адаптивных тем, где элементы могут
меняться в зависимости от разрешения экрана.
Для корректной работы на мобильных устройствах необходимо учитывать тач-события и размеры сенсорной зоны. Параметры, влияющие на мобильное поведение:
delay — минимальное время удержания элемента перед
началом drag. Рекомендуется 100–200 мс для исключения случайных
свайпов.distance — минимальное смещение для начала
перетаскивания. Полезно для предотвращения конфликтов с вертикальной
прокруткой.mirror — на мобильных устройствах желательно
использовать constrainDimensions: true и
xAxis/yAxis ограничения для предотвращения
выхода элемента за пределы контейнера.Пример адаптации под мобильные устройства:
const draggableMobile = new Draggable(document.querySelectorAll('.list'), {
draggable: '.item',
delay: 150,
distance: 10,
mirror: {
constrainDimensions: true
}
});
Для соответствия стилю темы необходимо синхронизировать CSS-классы и анимацию с библиотекой. Основные подходы:
.draggable-mirror {
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
border-radius: 8px;
background-color: #fff;
}
Sortable и SwapAnimation для плавного
перемещения элементов, соответствующего дизайну интерфейса.import { Sortable, SwapAnimation } from '@shopify/draggable';
const sortable = new Sortable(document.querySelectorAll('.list'), {
draggable: '.item',
plugins: [SwapAnimation]
});
window.addEventListener('resize', () => {
draggable.destroy();
draggable = new Draggable(document.querySelectorAll('.list'), { draggable: '.item' });
});
Для улучшения UX в рамках темы проекта используются плагины:
Mirror — создание визуальной копии
элемента.SwapAnimation — плавная анимация при
перестановке.Collidable — проверка пересечения
элементов и их взаимодействие с drop-зонами.Plugins для интеграции с frameworks —
позволяет подключать Draggable к React, Vue, или другим динамическим
компонентам темы.Если элементы списка формируются динамически (например, через API Shopify), необходимо пересоздавать Draggable после рендера:
function updateDraggable() {
draggable.destroy();
draggable = new Draggable(document.querySelectorAll('.list'), { draggable: '.item' });
}
// Пример после добавления нового элемента через AJAX
document.querySelector('#add-item').addEventListener('click', () => {
// добавление элемента в DOM
updateDraggable();
});
.draggable-mirror.xAxis или
yAxis) в зависимости от сетки дизайна.drag:over и drag:out применяются
для изменения состояния drop-зон, чтобы интеграция выглядела органично с
визуальной частью темы.Такой подход позволяет создавать гибкий, адаптивный drag-and-drop интерфейс, полностью интегрированный с визуальной частью темы проекта и функциональными требованиями.