В библиотеке Shopify Draggable drag-and-drop
взаимодействия строятся вокруг трёх основных компонентов:
Draggable, Droppable и Sortable.
Drop-зона — это элемент, на который можно «бросить» перетаскиваемый
объект. Она управляет событиями входа, выхода и завершения
перетаскивания, а также обеспечивает визуальную обратную связь.
Drop-зона создаётся путём подключения плагина Droppable
к контейнеру, который должен принимать элементы. Структура инициализации
выглядит так:
import { Draggable, Droppable } from '@shopify/draggable';
const draggable = new Draggable(document.querySelectorAll('.draggable-item'), {
draggable: '.item'
});
const droppable = new Droppable(document.querySelectorAll('.drop-zone'), {
draggable: '.item'
});
Здесь '.draggable-item' — элементы, которые можно
перемещать, а '.drop-zone' — контейнеры, способные
принимать эти элементы.
Drop-зона поддерживает множество событий, которые позволяют контролировать процесс перетаскивания:
droppable:over — срабатывает, когда
draggable входит в зону.droppable:out — вызывается при выходе
draggable из зоны.droppable:dropped — фиксирует успешное
«бросание» элемента.droppable:returned — срабатывает, если
элемент возвращается в исходное место.Пример подписки на события:
droppable.on('droppable:over', (event) => {
event.over.classList.add('highlight');
});
droppable.on('droppable:out', (event) => {
event.over.classList.remove('highlight');
});
droppable.on('droppable:dropped', (event) => {
console.log('Элемент успешно перемещён:', event.dragEvent.source);
});
Ключевой объект события — event, содержащий
dragEvent.source (перетаскиваемый элемент),
over (текущая drop-зона) и другие свойства.
Drop-зоны можно конфигурировать через опции:
dropzone — CSS-селектор для
контейнеров.mirror — опции зеркала (визуальное
отображение перетаскиваемого объекта).ignoreInputTextSelection —
предотвращение срабатывания drag на текстовых полях.delay — задержка перед началом
перетаскивания.Пример расширенной инициализации:
const droppable = new Droppable(document.querySelectorAll('.drop-zone'), {
draggable: '.item',
delay: 150,
mirror: {
constrainDimensions: true,
xAxis: false,
yAxis: false
}
});
Поддержка нескольких зон позволяет создавать сложные интерфейсы, например, перемещение элементов между колонками. Для этого достаточно передать коллекцию элементов:
const droppable = new Droppable(document.querySelectorAll('.drop-zone, .secondary-drop-zone'), {
draggable: '.item'
});
События автоматически различают, в какую зону был брошен объект,
через свойство event.over.
Добавление CSS-классов для состояний drop-зоны улучшает UX. Основные подходы:
highlight — при наведении draggable.active — когда элемент находится в зоне.invalid — если drop запрещён.Пример:
droppable.on('droppable:over', ({ over }) => over.classList.add('highlight'));
droppable.on('droppable:out', ({ over }) => over.classList.remove('highlight'));
droppable.on('droppable:dropped', ({ over }) => {
over.classList.remove('highlight');
over.classList.add('active');
});
Drop-зоны можно комбинировать с Sortable, чтобы
одновременно поддерживать перетаскивание между контейнерами с
перестановкой элементов:
import { Sortable } from '@shopify/draggable';
const sortable = new Sortable(document.querySelectorAll('.sortable-list'), {
draggable: '.item',
mirror: { constrainDimensions: true }
});
Drop-зона и сортируемый список могут работать параллельно, где
события droppable:dropped и sortable:stop
позволяют синхронизировать данные и выполнять действия, например,
обновление состояния на сервере.
accept
условие) через кастомные события.mirror) для ограничения перемещения
за пределы видимой области.Пример фильтрации допустимых элементов:
droppable.on('droppable:dropped', (event) => {
if (!event.dragEvent.source.matches('.allowed')) {
event.dragEvent.cancel();
}
});
mirror.constrainDimensions, чтобы уменьшить
нагрузку на рендеринг.Droppable с настройками.over, out,
dropped, returned).Sortable и другими
плагинами.Эта последовательность позволяет строить гибкие и динамичные интерфейсы с drag-and-drop, полностью используя возможности Shopify Draggable.