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

Сенсоры

Что превращает ввод в драги — встроенные сенсоры указателя и клавиатуры и API для собственных.

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

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

import { defineSensor, useSensor, pointerSensor, keyboardSensor } from '@vue-dnd-kit/core';
Sensor

Мышь, касание и перо через Pointer Events. По умолчанию есть в sensors.

Sensor

Space/Enter, стрелки и Escape (переназначаются опцией keyboard провайдера). По умолчанию есть в sensors; он также отменяет по Escape драги указателем и собственные драги, даже при keyboard: false.

(sensor: Sensor) => Sensor

Определяет сенсор (см. Sensor): только помогает с типами и возвращает свой аргумент.

(sensor: Sensor) => void

Запускает сенсор в провайдере выше, пока живёт вызвавший компонент (или effect scope), рядом с sensors провайдера. Его драг отменяется при размонтировании.

Сенсор лишь говорит «тащи этот элемент отсюда», затем — куда он сдвинулся и что его бросили или отменили; остальное проверяет провайдер (что можно перетаскивать, активацию, один драг за раз). См. сенсоры и программное перетаскивание.

Ниже небольшой собственный сенсор (запущенный через useSensor) перетаскивает фигуры доски с миникарты, рядом с собственными сенсорами провайдера.

Live

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

<script setup lang="ts">
import { DnDProvider } from '@vue-dnd-kit/core';
import SensorDesk from './SensorDesk.vue';
</script>

<template>
  <DnDProvider>
    <SensorDesk />
  </DnDProvider>
</template>

Sensor

Ввод, который начинает драги: указатель, клавиатура или ваш собственный (геймпад, экранный джойстик, голос, драги из скрипта). setup выполняется один раз на провайдер, только в браузере, внутри effect scope, который заканчивается вместе с провайдером (или когда сенсор уходит из sensors, или когда размонтируется компонент, вызвавший useSensor). Регистрируйте слушатели через useEventListener или верните функцию очистки; драг, который в этот момент ещё идёт, отменяется.

Чтобы обернуть сенсор, вызовите его setup со своим контекстом. Object.create(context, { activate: { value: … } }) сохраняет живые геттеры (status, drag, props), а spread заморозил бы их.

string

Для отладки.

(context: SensorContext) => void | (() => void)

Начинает слушать ввод, один раз на провайдер: вызовите context.activate(), когда ввод хочет начать драг. Может вернуть функцию очистки, которая выполнится, когда сенсор остановится.

Что сенсор получает от провайдера, в котором работает.

Readonly<DnDProviderProps>

Пропсы провайдера (например, activation, keyboard). Читайте их, когда они нужны: они могут меняться.

DnDStatus

Статус драга провайдера, какой бы сенсор им ни управлял.

SensorDrag | null

Драг провайдера — ожидающий или идущий, какой бы сенсор его ни начал; null, если драга нет. Сенсоры могут управлять драгами друг друга: сенсор клавиатуры двигает и бросает любой драг с клавиатуры, например начатый кнопкой «Move» (@vue-dnd-kit/actions).

(activation: SensorActivation) => SensorDrag | null

Запрашивает драг элемента. Провайдер проверяет, что он свободен (один драг за раз и ни одного, пока приземляется бросок), что цель — его собственный перетаскиваемый элемент и он не отключён, куда пришёлся ввод (см. target) и canDrag перетаскиваемого элемента. Затем ждёт ограничение активации и начинает драг. Возвращает драг (ожидающий или уже идущий, если ждать нечего) или null, если драг начать нельзя.

() => void

Отменяет драг провайдера или ожидающую активацию, какой бы сенсор ими ни управлял (Escape, скрытая вкладка).

Активация

Что сенсор запрашивает, когда его ввод хочет начать драг (SensorContext.activate()).

Element | Key

Куда пришёлся ввод: элемент внутри перетаскиваемого элемента или id перетаскиваемого элемента. Элемент должен принадлежать этому провайдеру. Для драгов 'pointer' он должен быть на ручке, если она есть, и не на интерактивном потомке (кнопке, поле ввода); для драгов 'keyboard' он должен быть целью фокуса перетаскиваемого элемента (ручкой, а без неё — самим элементом) и не редактируемым полем. С id эти проверки пропускаются: драг начинается с элемента, где бы ни был ввод.

SensorType

Как движется драг. 'pointer' (по умолчанию): он следует за точками, переданными в move(), цели ищутся в этих точках, контейнеры автоматически прокручиваются у краёв, а страница показывает курсор захвата. 'keyboard': он перемещается по элементам через step() и place(), как стрелки; цели прокручиваются в видимую область вместо автоскролла, а по окончании фокус возвращается на элемент. Какой из двух — показывает Active.sensor.

Coordinates

Где начинается драг, в координатах вьюпорта. По умолчанию — центр перетаскиваемого элемента.

PointerEvent | KeyboardEvent

Событие ввода. Оно передаётся в canDrag перетаскиваемого элемента; без события (геймпад, программный драг) canDrag не вызывается. pointerType, равный 'touch', делает драг драгом касанием (haptics).

PointerKind | ActivationConstraint

Чего драг ждёт перед стартом (до этого useDnD().status равен 'activating', с прогрессом). Для типа указателя берётся опция activation перетаскиваемого элемента, затем провайдера, затем значения по умолчанию (мышь — 4px, на ручке — сразу; перо — 4px; касание — долгое нажатие 200 мс с допуском 5px). Ограничение используется как есть. По умолчанию — ничего, драг начинается сразу.

(drag: SensorDrag) => void

Драг начался после активации: например, захватите указатель.

(drag: SensorDrag) => void

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

(drag: SensorDrag) => void

Бросок, который запросил сенсор, не состоялся, и драг продолжается (onBeforeDrop ответил 'continue'): move, drop и cancel снова работают. Сенсор указателя даёт элементу следовать за указателем до следующего отпускания.

Для каждого типа указателя. По умолчанию: мышь — { distance: 4 } (на ручке — сразу), перо — { distance: 4 }, касание — { delay: 200, tolerance: 5 }.

type ActivationOptions = Partial< Record<PointerKind, ActivationConstraint> >

Что должно произойти с нажатием, прежде чем оно станет драгом: указатель проходит distance или удерживается delay — что наступит раньше. Ничего не задано: драг начинается сразу.

number

Сколько пикселей должен пройти указатель, прежде чем начнётся драг.

number

Сколько миллисекунд нужно удерживать указатель, прежде чем начнётся драг.

number

Вместе с delay: смещение в px, которое прерывает активацию, чтобы страницу можно было прокрутить.

Драг

Один драг сенсора — от activate() до конца. Любой вызов, который уже неуместен, игнорируется: перемещения до старта или после конца, повторный drop().

Key

Id перетаскиваемого элемента.

SensorType

Как движется драг — как запросил activate() (SensorActivation.type).

SensorDragState

На каком этапе драг: ждёт активации, идёт или закончился.

boolean

Драг начался, даже если с тех пор уже закончился (сенсор указателя поглощает клик, который следует за ним).

(point: Coordinates) => void

Ввод сдвинулся. Пока драг ожидает активации, проверяется ограничение активации (выход за допуск прерывает её); во время драга драг перемещается туда. Драги указателем берут одну позицию за кадр; драги с клавиатуры перемещаются сразу, после предшествующих шагов.

(direction: SensorDirection, options?: SensorStepOptions) => Promise<void>

Драги с клавиатуры: один шаг стрелкой, как у стрелок сенсора клавиатуры (следующий элемент списка, следующая принимающая цель в режиме 'droppables' или keyboard.step пикселей). Шаги встают в очередь: каждый выполняется, когда отрендерился предыдущий, а повтор клавиши (event.repeat) пропускается, пока предыдущий шаг ещё выполняется. Драги указателем это игнорируют.

(position: SortablePosition) => Promise<boolean>

Ставит элемент на позицию в сортируемом списке, как это делают перемещения с клавиатуры (другие списки берут его, только если принимают), и переносит драг на новое место. Разрешается в false, если ни один список его туда не берёт. В драгах с клавиатуры встаёт в очередь, как step().

() => Promise<boolean>

Бросает; ожидающая активация вместо этого прерывается. Разрешается, когда драг закончился и приземлился: true, если бросок прошёл, false, если его отклонили (цель, onBeforeDrop) или бросать было нечего.

() => void

Отменяет драг (элемент улетает обратно) или прерывает ожидающую активацию.

  • 'pending': ожидание ограничения активации;
  • 'dragging': от старта до решения о броске или отмены драга;
  • 'ended': активация прервана, или драг завершился броском, или отменён — сенсором или чем-то другим (Escape, скрытая вкладка, useDnD().cancel(), размонтирование провайдера).
type SensorDragState = 'pending' | 'dragging' | 'ended'

Опции SensorDrag.step().

KeyboardEvent

Нажатие клавиши, которое передаётся в getKeyboardCoordinates мониторов. По умолчанию — keydown клавиши-стрелки.

boolean

Шаг крупнее при свободном перетаскивании (как с Shift). По умолчанию — event.shiftKey.

Стрелка шага с клавиатуры.

type SensorDirection = 'up' | 'down' | 'left' | 'right'

Позиция в сортируемом списке для SensorDrag.place() (и moveItem из @vue-dnd-kit/actions). Только для списков: деревья размещают элементы по своим ключам.

Key

Id списка (SortableListOptions.id). По умолчанию — список, в котором находится элемент.

number

Индекс, на котором окажется элемент, без учёта самого элемента (блок мульти-драга считается один раз). Ограничивается размером списка; по умолчанию — конец.