Канбан-доски

Dragula — это легковесная библиотека для реализации перетаскивания элементов между контейнерами в браузере. Она ориентирована на простоту использования и совместимость с различными структурами DOM, что делает её идеальной для создания интерактивных интерфейсов, таких как канбан-доски.

Для подключения Dragula достаточно добавить библиотеку через npm или CDN. После этого создается экземпляр dragula с указанием контейнеров, элементы которых будут перетаскиваться:

import dragula from 'dragula';

const containers = [document.querySelector('#todo'), document.querySelector('#in-progress'), document.querySelector('#done')];
const drake = dragula(containers);

Здесь containers — массив DOM-элементов, которые поддерживают перетаскивание. Любой элемент внутри этих контейнеров может быть перемещен по умолчанию.

Настройка поведения

Dragula предоставляет гибкие возможности конфигурации через объект опций:

const drake = dragula(containers, {
    moves: (el, source, handle, sibling) => handle.classList.contains('handle'),
    copy: false,
    revertOnSpill: true,
    direction: 'vertical'
});
  • moves — функция, определяющая, какие элементы могут быть перетаскиваемыми.
  • copy — если true, элементы копируются вместо перемещения.
  • revertOnSpill — возвращает элемент на исходное место, если он был «выброшен» за пределы контейнера.
  • direction — направление перемещения: 'vertical' или 'horizontal'.

Использование handle позволяет создавать элементы с конкретными зонами захвата, что особенно полезно для карточек канбан-доски с кнопками или другими интерактивными элементами.

Работа с событиями

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

  • drag — начало перетаскивания.
  • drop — успешное перемещение элемента.
  • over — элемент находится над контейнером.
  • out — элемент покидает контейнер.
  • remove — элемент удален, если не был помещен в контейнер.

Пример использования события drop для обновления состояния канбан-доски:

drake.on('drop', (el, target, source, sibling) => {
    const newColumn = target.id;
    const itemId = el.dataset.id;
    updateBoardState(itemId, newColumn);
});

Здесь updateBoardState — функция, синхронизирующая состояние фронтенда с бэкендом, чтобы изменения в канбан-доске сохранялись.

Перетаскивание между колонками

Dragula автоматически поддерживает перенос элементов между разными контейнерами. При этом важно учитывать ключевые аспекты для канбан-досок:

  1. Ограничение типов карточек. Можно использовать функцию accepts для контроля, какие элементы разрешено перемещать в конкретный контейнер:
accepts: (el, target, source, sibling) => {
    return target.id !== 'done' || el.dataset.priority !== 'high';
}
  1. Поддержка порядка элементов. Dragula сохраняет визуальный порядок, перемещая элементы относительно соседей. Это особенно важно для сортировки задач по приоритету.

  2. Кастомизация визуальной подсказки. Событие drag позволяет изменить стили элемента в момент перемещения:

drake.on('drag', el => {
    el.style.opacity = '0.5';
});
drake.on('dragend', el => {
    el.style.opacity = '';
});

Работа с динамическими контейнерами

В канбан-досках часто добавляются новые колонки и карточки. Dragula поддерживает динамическое добавление контейнеров через метод drake.containers.push(newContainer):

const newColumn = document.querySelector('#new-column');
drake.containers.push(newColumn);

Это позволяет расширять доску без необходимости пересоздавать экземпляр Dragula.

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

Dragula легко интегрируется с React, Vue или Angular. Основной принцип — передавать DOM-узлы контейнеров в Dragula и отслеживать события для синхронизации состояния с виртуальным DOM:

  • В React используют useRef для получения DOM-элементов колонок.
  • В Vue используют ref и mounted для инициализации dragula после рендеринга.
  • В Angular используют ViewChild и AfterViewInit.

Поддержка копирования и клонирования карточек

Для сценариев, где задача должна дублироваться (например, создание шаблонов), используется опция copy:

const drake = dragula(containers, { copy: true });

При этом оригинальный элемент остается на месте, а перемещенный — создается новый экземпляр.

Пользовательские эффекты и анимация

Dragula не предоставляет встроенной анимации, но с помощью CSS и событий можно создавать плавные эффекты:

.gu-mirror {
    transition: transform 0.2s ease;
}
.gu-transit {
    opacity: 0.7;
}
  • gu-mirror — копия элемента, следящая за курсором.
  • gu-transit — стиль элемента во время перетаскивания.

Использование этих классов позволяет сделать интерфейс канбан-доски более отзывчивым и наглядным.

Рекомендации по структуре канбан-доски

  1. Каждая колонка как отдельный контейнер. Это упрощает управление перетаскиванием и позволяет использовать Dragula «из коробки».
  2. Карточки с уникальными идентификаторами через data-id. Обеспечивает корректную синхронизацию состояния при событиях drop и remove.
  3. Обособленные зоны захвата (handles) для предотвращения случайного перемещения при клике на кнопки внутри карточек.
  4. События для бэкендаdrop, remove и out используются для обновления базы данных или локального хранилища.

Dragula сочетает в себе минимализм и мощь управления DOM, что делает его идеальным инструментом для реализации интерактивных канбан-досок с поддержкой перетаскивания, динамических колонок и сложных пользовательских сценариев.