Документация/API

Модификаторы и коллизии

Функции, которые меняют, куда идёт перетаскиваемый элемент, и функции, которые выбирают цель под ним.

Редактировать страницу

Страница переведена ИИ и может содержать неточности. Читать английский оригинал

Live

Загружаем демо…

<script setup lang="ts">
import { ref } from 'vue';
import { DnDProvider, closestCenter, closestCorners, pointerFirst, pointerWithin, rectIntersection } from '@vue-dnd-kit/core';
import ModifierLab from './ModifierLab.vue';

// Collision detection is the provider's: it picks the target, here one of the two pads.
const COLLISIONS = { pointerFirst, pointerWithin, rectIntersection, closestCenter, closestCorners };
const collision = ref<keyof typeof COLLISIONS>('pointerFirst');
</script>

<template>
  <DnDProvider :collision="COLLISIONS[collision]">
    <div class="demo">
      <code class="call">&lt;DnDProvider :collision="{{ collision }}"&gt;</code>
      <div class="collisions" role="radiogroup" aria-label="collision">
        <label v-for="name in Object.keys(COLLISIONS)" :key="name" :class="{ on: collision === name }">
          <input v-model="collision" type="radio" :value="name" />
          {{ name }}
        </label>
      </div>
      <ModifierLab />
    </div>
  </DnDProvider>
</template>

<style scoped>
.demo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.collisions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 2px;
  max-width: 100%;
  padding: 3px;
  border-radius: 9px;
  background: color-mix(in srgb, currentColor 7%, transparent);
}

.call {
  font: 11px/1.4 ui-monospace, Menlo, Consolas, monospace;
  color: #42b883;
}

label {
  padding: 4px 8px;
  border-radius: 6px;
  font: 11px/1.3 ui-monospace, Menlo, Consolas, monospace;
  cursor: pointer;
}

label.on {
  background: Canvas;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.25);
  font-weight: 600;
}

label:has(input:focus-visible) {
  outline: 2px solid #42b883;
}

input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
</style>

Модификаторы

import { restrictToParent, snapToGrid } from '@vue-dnd-kit/core';

makeSortableList(list, { items, modifiers: [restrictToParent] });
makeDragArea(board, { modifiers: [snapToGrid({ x: 24, y: 24, smooth: true })] });

Модификатор принимает смещение драга и возвращает новое. Модификаторы выполняются по порядку: modifiers провайдера, области перетаскивания, собственные модификаторы перетаскиваемого элемента (или его списка), затем границы области (restrictToArea) и последней — фиксация axis. См. оси, границы и сетки.

Modifier

Двигает только по вертикали: по горизонтали остаётся с содержимым, в котором начался драг (containerShift), как бы ни прокручивалась страница. Опция axis: 'y' делает то же самое, последней.

Modifier

Двигает только по горизонтали: по вертикали остаётся с содержимым, в котором начался драг (containerShift), как бы ни прокручивалась страница. Опция axis: 'x' делает то же самое, последней.

Modifier

Держит оверлей внутри окна.

Modifier

Держит оверлей внутри контейнера, в котором начался драг: сортируемого списка (а не его DOM-родителя) или, для обычных перетаскиваемых элементов, родительского элемента.

(target: MaybeElementRef) => Modifier

Держит оверлей внутри элемента: сам элемент, ref или геттер.

Modifier

Держит оверлей внутри первого прокручиваемого предка перетаскиваемого элемента.

(size: number | SnapToGridOptions) => Modifier

Привязывает оверлей к сетке, к ближайшей ячейке: число — размер квадратных ячеек; опции задают каждую ось, начало сетки и плавное скольжение между ячейками (SnapToGridOptions).

Modifier

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

Опции snapToGrid.

x?
number

Ширина ячейки в px. Без неё (или при 0) драг свободно движется по x.

y?
number

Высота ячейки в px. Без неё (или при 0) драг свободно движется по y: { y: 15 } привязывает только время события в календаре.

'container' | 'delta'

'container' (по умолчанию): левый верхний угол оверлея попадает на линии сетки, проведённые от левого верхнего угла контейнера (containerRect: сортируемый список или родительский элемент). 'delta': округляется смещение драга, так что элемент, начавший вне сетки, остаётся вне её.

boolean | AnimationOptions

Плавно перемещать оверлей между привязанными позициями (по умолчанию 80 мс). Определение цели при этом сразу использует привязанную позицию.

Меняет, куда движется перетаскиваемый элемент: получает смещение драга (transform) и возвращает новое.

type Modifier = (args: ModifierArgs) => Coordinates

Что получает модификатор при каждом движении драга.

Coordinates

Смещение от начала драга с учётом предыдущих модификаторов.

Active

Драг.

Rect

Прямоугольник перетаскиваемого элемента в начале драга.

Rect

Прямоугольник блока оверлея, если сдвинуть его на transform, в его нынешнем размере. При overlayFit: 'slot' блок меняет размер вокруг указателя, поэтому это не всегда activeRect, сдвинутый на transform.

Coordinates

Позиция указателя в начале драга.

Rect | null

Контейнер сортируемого списка (или родительский элемент) перетаскиваемого элемента, там, где он сейчас (он следует за прокруткой).

Coordinates

Насколько содержимое, в котором начался драг, сдвинулось на экране с начала драга: сдвинулся сам контейнер (прокрутилась страница или контейнер вокруг него, сместилась раскладка), а его содержимое прокрутилось внутри него. Фиксация оси держит другую ось на этом сдвиге, так что драг остаётся на своей строке или в своей колонке этого содержимого.

Rect

Прямоугольник окна (вьюпорт).

Over | null

Цель под драгом, какой она была найдена в последний раз; null, если драг ни над чем.

Определение коллизий

import { closestCorners } from '@vue-dnd-kit/core';
<DnDProvider :collision="closestCorners" />

collision провайдера выбирает цель; лучший кандидат идёт первым.

CollisionDetection

По умолчанию: то, что под указателем, иначе то, что перекрывает оверлей.

CollisionDetection

Цели под указателем, по результатам hit-testing: учитывает z-порядок, оверлеи и shadow root.

CollisionDetection

Цели, которые перекрывает оверлей: сначала больший приоритет, затем более глубокая вложенность, затем intersection over union.

CollisionDetection

Все цели, по расстоянию между центрами.

CollisionDetection

Все цели, по сумме расстояний между углами (подходит для целей, наложенных друг на друга, например колонок канбана).

Возвращает id кандидатов, лучшие — первыми.

type CollisionDetection = (args: CollisionArgs) => Key[]

Что получает определение цели при каждом движении драга.

Coordinates

Указатель в координатах вьюпорта, после модификаторов.

Rect | null

Прямоугольник перетаскиваемого блока (оверлея или самого элемента при overlay: false) там, куда его сдвинул драг.

CollisionCandidate[]

Все цели, куда мог бы попасть драг, независимо от того, принимает ли драг их правило accept.

Key[]

Цели под указателем по результатам hit-testing (с учётом z-порядка и shadow root), лучшие — первыми.

Цель, которую может выбрать определение цели: включённая, есть на странице и не обрезана целиком.

Key

Id цели.

Rect

Видимая часть цели: обрезанная её скролл-контейнерами и вьюпортом.

number

priority цели (по умолчанию 0): побеждает большее значение, когда цели перекрываются без вложенности. Элементы сортируемых списков побеждают контейнеры.

number

Уровень вложенности среди целей: 0 на верхнем уровне, у более глубоких целей значения больше.