Назначение и поведение

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


Основные концепции

  1. Draggable – главный класс библиотеки, который создаёт область для перетаскивания элементов. Экземпляр класса привязывается к контейнеру и его дочерним элементам, которые можно перемещать.
  2. Mirror – визуальная копия перетаскиваемого элемента, которая создаётся при начале перетаскивания. Позволяет избежать смещения оригинального элемента и даёт возможность плавно перемещать объект по странице.
  3. Sensors – модули, которые определяют источник ввода для начала и завершения перетаскивания. Например, MouseSensor или TouchSensor.
  4. Plugins – расширения, добавляющие новые функции: сортировку элементов, создание областей для отмены или ограничения перетаскивания, поддержку сетки.

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

Инициализация Draggable выполняется следующим образом:

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

const draggable = new Draggable(document.querySelectorAll('.container'), {
  draggable: '.item',
  mirror: {
    constrainDimensions: true,
  },
  delay: 0,
});

Пояснения:

  • document.querySelectorAll('.container') – контейнеры, внутри которых элементы будут перетаскиваться.
  • draggable: '.item' – селектор дочерних элементов, которые становятся перетаскиваемыми.
  • mirror.constrainDimensions: true – зеркало будет копией размеров оригинального элемента.
  • delay – задержка перед началом перетаскивания в миллисекундах, полезно для предотвращения случайных перемещений.

События и управление поведением

Draggable предоставляет богатый набор событий, разделённых на этапы:

  1. start – инициируется при начале перетаскивания.

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

    В объекте события доступен event.source – оригинальный элемент, который начал перетаскиваться.

  2. move – происходит при перемещении элемента или зеркала. Позволяет отслеживать позицию и изменять поведение динамически:

    draggable.on('drag:move', (event) => {
      console.log('Текущие координаты', event.sensorEvent.clientX, event.sensorEvent.clientY);
    });
  3. over/out – события при наведении на допустимые цели. Используются в связке с Droppable:

    draggable.on('drag:over', (event) => {
      console.log('Элемент над зоной', event.over);
    });
  4. stop – завершение перетаскивания, моментальное или после отпускания мыши/пальца. Здесь часто реализуют перемещение оригинального элемента или отправку данных на сервер:

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

Поведение зеркала

Создание зеркала (mirror) полностью контролируется библиотекой:

  • По умолчанию создаётся копия элемента, которая перемещается по координатам указателя.
  • Параметры constrainDimensions и x/yAxis позволяют ограничивать размеры и направление перемещения.
  • События зеркала, такие как mirror:created и mirror:destroy, дают возможность добавлять анимации или эффект затемнения оригинала.
draggable.on('mirror:created', (event) => {
  event.mirror.style.transition = 'transform 0.2s ease';
});

Ограничения и управление зонами

Draggable позволяет задавать зоны, где перемещение разрешено или запрещено:

  • droppable – селекторы контейнеров, куда элементы могут быть помещены.
  • invalid – селекторы элементов, которые нельзя перетаскивать.
  • handle – селектор для «ручки», по которой разрешено начинать перетаскивание.

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

const draggable = new Draggable(document.querySelectorAll('.container'), {
  draggable: '.item',
  handle: '.drag-handle',
  invalid: ['.disabled'],
});

Интеграция с сортировкой

С помощью плагина Sortable можно реализовать динамическую перестановку элементов внутри контейнера:

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

const sortable = new Sortable(document.querySelectorAll('.container'), {
  draggable: '.item',
  swapAnimation: {
    duration: 200,
    easingFunction: 'ease-in-out',
  },
});
  • swapAnimation добавляет плавный визуальный эффект перемещения элементов.
  • События sortable:sorted и sortable:stop позволяют отслеживать изменения порядка и синхронизировать их с данными на сервере.

Рекомендации по поведению

  • Для улучшения UX важно всегда использовать mirror, чтобы оригинальный элемент не смещался внезапно.
  • Использование handle предотвращает случайные перетаскивания при кликах по интерактивным элементам внутри draggable.
  • Для сложных интерфейсов комбинируются Draggable, Droppable и Sortable, чтобы обеспечить полный контроль над взаимодействием пользователя с элементами.

Поведение элементов в Shopify Draggable полностью настраивается через события, зеркала и плагины, что делает библиотеку гибким инструментом для создания интерактивных интерфейсов, сортируемых списков и drag-and-drop областей любого уровня сложности.