Кастомные стили для placeholder

В библиотеке Shopify Draggable элемент placeholder создаётся автоматически при перетаскивании элементов и служит визуальным индикатором места, куда будет перемещён элемент после завершения drag-события. По умолчанию placeholder использует стандартные классы и стили, которые могут не подходить под дизайн приложения. Для полного контроля над внешним видом placeholder необходимо использовать кастомные стили и правильно работать с событиями Draggable.


Подключение кастомного класса к placeholder

Для того чтобы задать свои стили, достаточно определить собственный CSS-класс и указать его в конфигурации Draggable через параметр classes.placeholder.

Пример:

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

const draggable = new Draggable(document.querySelectorAll('.list'), {
  draggable: '.item',
  classes: {
    // Кастомный класс для placeholder
    'placeholder': 'custom-placeholder'
  }
});

В CSS:

.custom-placeholder {
  background-color: #f0f4ff;
  border: 2px dashed #2b6cb0;
  min-height: 50px;
  border-radius: 4px;
  transition: all 0.2s ease;
}

Важно: placeholder создаётся динамически на момент начала перетаскивания и удаляется после завершения drag, поэтому обычные стили для статических элементов на placeholder не распространяются.


Динамическое изменение стилей через события

Draggable предоставляет ряд событий, позволяющих управлять placeholder во время drag:

  • drag:start – вызывается при начале перетаскивания
  • drag:move – вызывается при каждом перемещении
  • drag:stop – вызывается при завершении перетаскивания

Можно динамически изменять свойства placeholder через event.data.placeholder.

Пример динамического изменения высоты placeholder:

draggable.on('drag:start', (event) => {
  const placeholder = event.data.dragEvent.data.placeholder;
  placeholder.style.height = `${event.source.offsetHeight}px`;
  placeholder.style.opacity = '0.5';
});

draggable.on('drag:move', (event) => {
  const placeholder = event.data.dragEvent.data.placeholder;
  placeholder.style.backgroundColor = event.over ? '#c3dafe' : '#f0f4ff';
});

draggable.on('drag:stop', (event) => {
  const placeholder = event.data.dragEvent.data.placeholder;
  placeholder.style.transition = 'opacity 0.3s';
  placeholder.style.opacity = '0';
});

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


Управление размером и формой placeholder

Placeholder автоматически наследует размеры перетаскиваемого элемента, но при необходимости можно полностью контролировать его размеры и форму:

draggable.on('drag:start', (event) => {
  const placeholder = event.data.dragEvent.data.placeholder;
  const sourceRect = event.source.getBoundingClientRect();

  placeholder.style.width = `${sourceRect.width}px`;
  placeholder.style.height = `${sourceRect.height}px`;
  placeholder.style.borderRadius = '8px';
});

Эта техника особенно полезна, когда элементы в списке имеют переменную высоту или когда требуется сделать placeholder более заметным для пользователя.


Комбинирование с CSS-переходами и трансформациями

Для плавного отображения placeholder можно использовать CSS-переходы и трансформации:

.custom-placeholder {
  transition: transform 0.2s ease, background-color 0.2s ease, opacity 0.3s ease;
}

.custom-placeholder.active {
  transform: scale(1.05);
  background-color: #bee3f8;
  opacity: 0.8;
}

В Jav * aScript:

draggable.on('drag:over', (event) => {
  const placeholder = event.data.dragEvent.data.placeholder;
  placeholder.classList.add('active');
});

draggable.on('drag:out', (event) => {
  const placeholder = event.data.dragEvent.data.placeholder;
  placeholder.classList.remove('active');
});

Такой подход позволяет создавать динамические визуальные эффекты, которые улучшают UX при работе с draggable-списками.


Использование кастомного элемента в качестве placeholder

Вместо стандартного <div> можно использовать полностью кастомный элемент:

const draggable = new Draggable(document.querySelectorAll('.list'), {
  draggable: '.item',
  mirror: {
    constrainDimensions: true
  },
  plugins: [Draggable.Plugins.Placeholder]
});

draggable.on('drag:start', (event) => {
  const placeholder = document.createElement('div');
  placeholder.classList.add('custom-placeholder');
  placeholder.textContent = 'Здесь будет элемент';
  event.data.dragEvent.data.placeholder.replaceWith(placeholder);
});

Это даёт максимальную гибкость: можно добавлять текст, иконки, прогресс-бары или другие визуальные компоненты внутрь placeholder.


Практические рекомендации

  • Всегда задавать min-height и min-width для placeholder, чтобы избежать «миганий» и изменения размеров контейнера при drag.
  • Использовать CSS-переходы для плавного появления и исчезновения placeholder.
  • В случаях сложной кастомизации применять события drag:start и drag:move для динамического управления стилями.
  • При кастомных элементах placeholder убедиться, что их позиционирование и размеры корректно наследуются от исходного элемента, иначе может возникнуть визуальный «скачок» при drag.

Эти методы позволяют полностью контролировать внешний вид placeholder в Shopify Draggable, создавая плавный, адаптивный и визуально привлекательный интерфейс.