Группировка элементов

Библиотека Shopify Draggable предоставляет мощный инструмент для управления перетаскиванием элементов на веб-странице. Одним из ключевых аспектов её использования является возможность группировки элементов, что позволяет объединять элементы в логические блоки и управлять ими как единым целым.


Создание контейнеров и групп

Для организации элементов необходимо определить контейнеры, внутри которых будет осуществляться drag-and-drop. Контейнер задаётся через CSS-селектор при создании экземпляра Draggable:

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

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

const draggable = new Draggable(container, {
  draggable: '.draggable-item',
  delay: 0,
  mirror: {
    constrainDimensions: true,
  }
});
  • .draggable-container — родительский элемент, объединяющий элементы группы.
  • .draggable-item — элементы, которые будут перетаскиваться внутри контейнера.
  • Параметр mirror.constrainDimensions гарантирует, что копия элемента будет сохранять размеры оригинала при перетаскивании.

Использование нескольких контейнеров

Draggable позволяет работать с несколькими контейнерами, что необходимо для перемещения элементов между группами. Это достигается через передачу массива элементов:

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

const draggable = new Draggable(containers, {
  draggable: '.item',
  swapAnimation: {
    duration: 200,
    easingFunction: 'ease-in-out',
  }
});
  • Параметр swapAnimation задаёт плавное перемещение элементов при смене позиции.
  • При множественных контейнерах элементы можно перетаскивать между разными группами, сохраняя порядок внутри каждого контейнера.

Создание вложенных групп

Draggable поддерживает вложенные группы, когда внутри одного контейнера находятся несколько подгрупп. Для этого используется иерархия селекторов:

const nestedDraggable = new Draggable(document.querySelectorAll('.parent-group'), {
  draggable: '.child-item',
  handle: '.handle',
  mirror: {
    constrainDimensions: true,
  }
});
  • handle — элемент, за который можно захватывать и перемещать дочерний элемент, что предотвращает случайное перетаскивание всего контейнера.
  • Вложенные группы можно объединять с событиями, чтобы реализовать специфическую логику, например, запрет перемещения между определёнными подгруппами.

События группировки

Draggable предоставляет богатый набор событий, которые позволяют отслеживать действия с группами и элементами:

draggable.on('drag:start', (evt) => {
  console.log('Начало перетаскивания', evt.source);
});

draggable.on('drag:stop', (evt) => {
  console.log('Элемент перемещён в группу', evt.source.parentNode);
});

draggable.on('sortable:stop', (evt) => {
  console.log('Элементы внутри группы переставлены');
});

Ключевые моменты:

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

Ограничения и контроль групп

Для управления перемещением элементов между группами можно использовать скрытые классы и фильтры:

const draggable = new Draggable(containers, {
  draggable: '.item',
  handle: '.handle',
  invalid: ['.no-drag'],
});
  • invalid — список селекторов, которые нельзя перетаскивать.
  • Использование фильтров помогает создавать комплексные правила для группировки, например, запрет перемещения товаров определённого типа в конкретную категорию.

Динамическое добавление и удаление элементов

Draggable поддерживает работу с динамическими группами:

const container = document.querySelector('.draggable-container');

const draggable = new Draggable(container, {
  draggable: '.item'
});

// Добавление нового элемента
const newItem = document.createElement('div');
newItem.classList.add('item');
container.appendChild(newItem);

// Обновление Draggable
draggable.addContainer(container);
  • Метод addContainer позволяет подключить новые контейнеры без полной перезагрузки Draggable.
  • Для удаления элементов можно просто удалить DOM-узел, и Draggable автоматически прекратит отслеживание.

Продвинутая группировка с сортировкой

Для реализации интерактивных интерфейсов часто используется сортировка внутри групп:

const sortable = new Draggable(containers, {
  draggable: '.item',
  delay: 100,
  sortable: true,
  swapAnimation: {
    duration: 300,
    easingFunction: 'ease-in-out',
  }
});
  • sortable — ключевой параметр для возможности переставлять элементы внутри контейнера.
  • delay помогает избежать случайного срабатывания при кликах по элементам.
  • Анимация swapAnimation делает перемещение визуально плавным.

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

  • Каждый контейнер должен иметь чёткий CSS-селектор для корректного разделения групп.
  • Вложенные группы реализуются через использование дочерних селекторов и handle-элементов.
  • Для динамического интерфейса использовать addContainer и события Draggable для обновления данных.
  • Ограничение перемещений и фильтры помогают создавать безопасные и предсказуемые группы.
  • Анимации и sortable делают интерфейс удобным и наглядным для пользователя.

Грамотно настроенная группировка в Shopify Draggable позволяет создавать сложные интерактивные интерфейсы с множеством уровней вложенности и контролируемым перемещением элементов.