Настройка swap-зон

В библиотеке Shopify Draggable swap-зоны (или swap containers) позволяют задавать области, внутри которых объекты можно менять местами. Они обеспечивают гибкую организацию интерфейса, позволяя создавать динамические списки, сетки и канвасы, где элементы можно перетаскивать и переставлять.

Swap-зоны управляются через контейнеры и сортируемые списки. В отличие от обычных drag-and-drop областей, swap-зоны не создают копий элементов — они перемещают объекты внутри определённых контейнеров, сохраняя их структуру и события.


Создание swap-зоны

Для начала необходимо определить контейнер, который будет служить swap-зоной:

import { Draggable } from '@shopify/draggable';

const container = document.querySelector('.swap-zone');

const draggable = new Draggable(container, {
  draggable: '.draggable-item',
  mirror: {
    constrainDimensions: true
  },
  plugins: [Draggable.Plugins.Sortable]
});

Ключевые параметры:

  • draggable — селектор элементов, которые можно перемещать.
  • mirror.constrainDimensions — сохраняет размеры зеркального отображения при перетаскивании.
  • plugins — подключение плагинов, таких как Sortable, обеспечивающих функционал перестановки внутри swap-зоны.

Swap-зона может содержать элементы любой структуры, но важно, чтобы они имели идентифицируемый селектор для корректной работы.


Управление поведением элементов в swap-зоне

Для более точной настройки используются события библиотеки:

  • sortable:start — инициируется при начале перетаскивания. Можно использовать для добавления классов активности.
  • sortable:sort — срабатывает при перемещении элемента между позициями.
  • sortable:stop — завершает перетаскивание, позволяет обновить состояние DOM или синхронизировать данные.

Пример использования событий:

draggable.on('sortable:start', (event) => {
  event.dragEvent.source.classList.add('dragging');
});

draggable.on('sortable:stop', (event) => {
  event.dragEvent.source.classList.remove('dragging');
});

Ограничение перемещения элементов между swap-зонами

Если на странице несколько swap-зон, можно определить, какие контейнеры могут обмениваться элементами. Для этого используется свойство containers:

const containerA = document.querySelector('.swap-zone-a');
const containerB = document.querySelector('.swap-zone-b');

const draggable = new Draggable([containerA, containerB], {
  draggable: '.draggable-item',
  plugins: [Draggable.Plugins.Sortable]
});

Элементы можно перемещать только между контейнерами, указанных в массиве [containerA, containerB].

Для запрета перемещения некоторых элементов между зонами применяют селекторы или кастомные условия в обработчике события sortable:sort:

draggable.on('sortable:sort', (event) => {
  if (event.over && event.over.classList.contains('no-swap')) {
    event.cancel();
  }
});

Настройка визуальной обратной связи

Для swap-зон важно наглядно показывать, куда элемент может быть перемещён. Shopify Draggable поддерживает классы и зеркала:

  • mirror — отображение перетаскиваемого элемента поверх страницы.
  • classes — добавление кастомных классов для активного состояния, placeholder или элемента под курсором.

Пример:

const draggable = new Draggable(container, {
  draggable: '.draggable-item',
  mirror: {
    constrainDimensions: true,
    appendTo: 'body'
  },
  classes: {
    mirror: 'mirror-element',
    chosen: 'chosen-element',
    placeholder: 'placeholder-element'
  },
  plugins: [Draggable.Plugins.Sortable]
});

Продвинутая синхронизация состояния

Для сложных интерфейсов swap-зоны часто требуют синхронизации с данными на сервере или локальным хранилищем. Лучший подход — обрабатывать событие sortable:stop:

draggable.on('sortable:stop', (event) => {
  const updatedOrder = Array.from(container.querySelectorAll('.draggable-item'))
    .map(item => item.dataset.id);

  fetch('/update-order', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ order: updatedOrder })
  });
});

Такой подход обеспечивает сохранение нового порядка элементов после перестановки без потери интерактивности.


Комбинирование swap-зон с другими плагинами

Shopify Draggable позволяет подключать дополнительные плагины:

  • Collidable — проверяет столкновение элементов при перетаскивании.
  • Swappable — упрощает обмен элементами между swap-зонами.
  • Plugins.Sortable — обеспечивает перестановку внутри одного контейнера.

Использование нескольких плагинов позволяет создать гибкие интерфейсы с drag-and-drop и swap-функционалом в реальном времени.


Итоговые рекомендации по swap-зонам

  • Всегда явно указывайте контейнеры swap-зон для предотвращения случайного перемещения элементов.
  • Используйте события sortable:start, sortable:sort, sortable:stop для управления состоянием и визуальной обратной связью.
  • Ограничивайте перемещение через селекторы или кастомные условия, чтобы интерфейс оставался предсказуемым.
  • Поддерживайте синхронизацию с сервером для сохранения порядка элементов.

Эти практики обеспечивают корректную работу swap-зон и позволяют строить сложные, интерактивные интерфейсы на базе Shopify Draggable.