Containers и items

В библиотеке Shopify Draggable ключевую роль играют два основных концепта: containers и items. Понимание их работы позволяет строить гибкие интерфейсы с поддержкой перетаскивания, сортировки и драг-н-дроп взаимодействий.


Containers

Containers — это элементы, внутри которых находятся перетаскиваемые объекты. В DOM они представляют собой родительские элементы, обычно <div> или <ul>. Контейнер задаёт границы, внутри которых библиотека будет отслеживать движение items и управлять их позиционированием.

Основные свойства:
  • containers — массив DOM-элементов или селекторов, указывающий, где возможны операции drag-and-drop.
  • Поддержка нескольких контейнеров позволяет перемещать items между разными областями.
  • Контейнер управляет порядком элементов и предоставляет события, через которые можно контролировать изменения в структуре.

Пример инициализации контейнера:

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

const containers = document.querySelectorAll('.draggable-container');

const draggable = new Draggable(containers, {
  draggable: '.draggable-item',
  mirror: {
    constrainDimensions: true
  }
});

В этом примере .draggable-container является container, а .draggable-itemitem. Библиотека создаст mirror при перетаскивании, автоматически подстраивая размеры под оригинальный элемент.


Items

Items — это элементы, которые можно перетаскивать. Они обязательно должны находиться внутри контейнера. Любой DOM-элемент внутри container, который соответствует селектору draggable, становится item.

Основные моменты:
  • Каждый item имеет идентичность в рамках контейнера, которую можно использовать для сохранения порядка.
  • Items могут быть как простыми элементами списка, так и сложными карточками с вложенной структурой.
  • При перетаскивании создаётся mirror — визуальная копия элемента, которая следует за курсором, а оригинальный элемент временно скрывается или остаётся на месте в зависимости от настроек.
Пример событий для items:
draggable.on('drag:start', (evt) => {
  console.log('Начало перетаскивания:', evt.source);
});

draggable.on('drag:stop', (evt) => {
  console.log('Перетаскивание завершено:', evt.source);
});

draggable.on('sortable:stop', (evt) => {
  console.log('Порядок изменён внутри контейнера:', evt.source.parentNode.children);
});

События позволяют отслеживать и управлять поведением элементов на каждом этапе: от начала drag до завершения сортировки.


Работа с несколькими containers

Одной из сильных сторон Shopify Draggable является возможность взаимодействия между несколькими контейнерами.

  • Items могут перетаскиваться из одного container в другой.
  • Можно ограничить перемещение с помощью containers и пользовательских условий.
  • Каждое событие drag:stop или sortable:stop предоставляет доступ к исходному и целевому контейнеру.

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

const containers = document.querySelectorAll('.container');

const draggable = new Draggable(containers, {
  draggable: '.item',
  delay: 100
});

draggable.on('drag:stop', (evt) => {
  const fromContainer = evt.source.parentNode;
  const toContainer = evt.over ? evt.over.parentNode : fromContainer;
  console.log('Item перемещён из', fromContainer, 'в', toContainer);
});

Настройка и ограничения

Shopify Draggable предоставляет гибкие механизмы контроля:

  • draggable: селектор для items внутри контейнера.
  • handle: позволяет сделать элемент доступным для drag только при взаимодействии с определённой областью (например, иконкой «перетаскивать»).
  • delay: задержка перед началом перетаскивания, полезна для предотвращения случайных drag.
  • mirror и plugins: настройка визуального поведения элемента при перемещении.

Пример ограничения с помощью handle:

const draggable = new Draggable(containers, {
  draggable: '.item',
  handle: '.drag-handle'
});

В этом случае item можно перетаскивать только за .drag-handle.


Важные особенности containers и items

  1. Наследование размеров: при использовании mirror: { constrainDimensions: true } копия элемента сохраняет ширину и высоту оригинала.
  2. События drag и drop: каждое взаимодействие с items вызывает цепочку событий, которые можно использовать для обновления данных или визуальных эффектов.
  3. Поддержка динамических элементов: можно добавлять новые items в контейнер после инициализации Draggable, библиотека корректно обработает новые элементы при следующем drag.

Практический пример структуры HTML

<div class="draggable-container">
  <div class="draggable-item">Элемент 1</div>
  <div class="draggable-item">Элемент 2</div>
  <div class="draggable-item">Элемент 3</div>
</div>

<div class="draggable-container">
  <div class="draggable-item">Элемент A</div>
  <div class="draggable-item">Элемент B</div>
</div>

В этом примере два контейнера позволяют перемещать элементы между ними, сохраняя сортировку внутри каждого контейнера.


Резюме по взаимодействию containers и items

  • Containers управляют областью действия drag-and-drop и содержат items.
  • Items — это элементы, доступные для перетаскивания внутри или между контейнерами.
  • События библиотеки позволяют контролировать весь жизненный цикл drag, начиная с начала перетаскивания и заканчивая изменением порядка.
  • Правильная настройка селекторов draggable и опциональных handle обеспечивает точное управление взаимодействием элементов.

В комбинации с плагинами Shopify Draggable containers и items создают гибкую и мощную систему для любых интерфейсов с перетаскиванием и сортировкой элементов.