Docs/API
makeDroppable
Makes an element a drop target, with rules for what it takes and hooks for the drop.
function makeDroppable<TData = unknown>( target: MaybeElementRef, options?: DroppableOptions<TData>,): DroppableReturn;Makes an element a drop target.
const zone = useTemplateRef<HTMLElement>('zone');
const { isOver, isAccepting } = makeDroppable(zone, {
accept: 'image',
onDrop: (e) => move(e.active.id),
});
See Drag and drop and Deciding a drop.
Loading the demo…
<script setup lang="ts">
import { reactive } from 'vue';
import { DnDProvider, type Key } from '@vue-dnd-kit/core';
import FileChip from './FileChip.vue';
import Zone from './Zone.vue';
import { FILES } from './files';
/** Which zone each file is in. */
const where = reactive<Record<string, string>>(Object.fromEntries(FILES.map((file) => [file.id, 'desk'])));
const filesIn = (zone: string) => FILES.filter((file) => where[file.id] === zone);
const move = (zone: string, file: Key) => (where[String(file)] = zone);
</script>
<template>
<DnDProvider>
<div class="zones">
<Zone title="Desktop" rule="takes anything" class="desk" @drop="move('desk', $event)">
<FileChip v-for="file in filesIn('desk')" :key="file.id" :file="file" />
</Zone>
<Zone title="Images" rule="accept: 'image'" accept="image" @drop="move('images', $event)">
<FileChip v-for="file in filesIn('images')" :key="file.id" :file="file" />
</Zone>
<Zone title="Media" rule="accept: ['image', 'audio']" :accept="['image', 'audio']" @drop="move('media', $event)">
<FileChip v-for="file in filesIn('media')" :key="file.id" :file="file" />
</Zone>
<Zone title="Archive" rule="disabled: true" disabled @drop="move('archive', $event)" />
</div>
</DnDProvider>
</template>
<style scoped>
.zones {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 12px;
width: min(720px, 100%);
}
.desk {
grid-column: 1 / -1;
}
@media (max-width: 560px) {
.zones {
grid-template-columns: minmax(0, 1fr);
}
}
</style>Options
Options of makeDroppable.
Drop into an item. A drop target on a sortable item's element (or inside it) works as everywhere else, with one rule while that item's list would sort the drag: it counts only while the pointer is in the middle of the item (25–75% along the list's axis; x in grids), where the drop goes into the target and the list doesn't move for it. Near the item's edges the list sorts as usual. A target whose accept refuses the drag is left out, so the list sorts over the item like over any other (no need to disable it). The keyboard stops on such a target before moving past its item. A drag never targets what it carries: no target in (or on) a dragged item, nor in the slot one lands in. To move the items out of their list in onDrop, call e.source.remove().
Every option but the callbacks takes a value, a ref or a getter (accept, overOverlay, overDropAnimation: a value or a ref) and is read live, while a drag looks for its target.
Keyvalue · ref · getterDefault: useId(), stable between server and client render.
TDatavalue · ref · getterAnything to tell about the target: events carry it as over.data.
stringvalue · ref · getterWhat people call it: screen reader texts say it instead of the id (over Trash); events carry it as over.label.
AcceptRulevalue · refWhat this target takes. Inside a sortable item, one that refuses the drag lets the list sort over it. A value or a ref: a function is a rule.
AcceptModevalue · ref · getterDefault 'all'.
booleanvalue · ref · gettertrue: drags pass over it as if it weren't there.
numbervalue · ref · getterHigher wins when targets overlap without nesting (default 0). Sortable items beat containers.
Componentvalue · refWhat the overlay shows while a drag this target accepts is over it: a component that gets OverlayProps, rendered instead of the drag's own overlay (the dragged item's component, the provider's slot or the clone), which it gets as its default slot to wrap or leave out (<slot />). It stays while the drop lands here. Drags without an overlay (overlay: false) keep none. A value or a ref, read live; the change of component animates with the provider's overlayTransition. (On draggables, items and lists, overlay is the drag's own overlay; sortable lists and trees take this one as overOverlay too.)
DropAnimationvalue · refHow the overlay lands when it is dropped here, instead of the dragged item's and the provider's dropAnimation: false leaves it where it was dropped (an overlay component's own animation, a splash, plays there), a function animates it. A value or a ref, read at the drop.
(event: DnDEvent) => voidA drag came over this target, whether it accepts the drag or not (event.over.accepted).
(event: DnDEvent) => voidThe drag left this target.
(event: DnDEvent) => MaybePromise<BeforeDropResult>Asked before a drop on this target goes through, after the monitors' onBeforeDrop, if it accepts the drag (see BeforeDropResult). May be async: the overlay waits where it was dropped. An error rejects the drop.
(event: DnDEndEvent) => voidA drop on this target went through: do what it means (move the item, upload the file). When an onBeforeDrop took only some of the dragged items, event.accepted has their ids and event.rejected the others, which fly back; active is still the whole drag.
ExternalAcceptvalue · ref · getterTakes drags from outside the page: files from the desktop, a link or text from another app or tab (the browser's drag and drop). They work as the library's drags do (isOver, isAccepting, the events), and e.external has their data at the drop. Targets without external ignore them. A value, a ref or a getter, read live.
Returns
What makeDroppable returns.
ComputedRef<Key>The target's id: the id option, or the one made for it.
ComputedRef<boolean>A drag is over it (one from outside the page too, with external).
ComputedRef<boolean>Something is being dragged and this target accepts it.
ComputedRef<Placement | null>Pointer position relative to the target's halves while it is hovered.
Accept rules
'*' or omitted accepts everything. Untyped items fit any string rule (v2 groups: [] parity).
type AcceptRule = | '*' | string | string[] | ((context: AcceptContext) => boolean)What a function accept rule is asked with.
'all': every dragged item must match; 'some': at least one (the rest can be rejected in onBeforeDrop).
type AcceptMode = 'all' | 'some'From outside the page
What external takes from drags that come from outside the page, and what such a drag
carries (e.external). See files and other apps.
What a drop target, list or tree takes from drags that come from outside the page: files from the desktop, a link or text from another app or tab (external).
boolean | string | readonly string[] | ((file: ExternalFile) => boolean)Files: true takes any. Or as <input accept> has it: MIME types (image/*, application/pdf) and extensions (.md), a string with commas or a list; extensions are checked at the drop. Or a function asked about each file (false refuses it). Folders are never taken.
booleanSeveral files at once (default true); false refuses a drag of more than one.
booleanLinks (text/uri-list): an address dragged from another tab, a link from a page.
booleanPlain text (text/plain): a selection dragged from another app.
readonly string[]Other MIME types it takes, exactly as other apps offer them.
A drag from outside the page (Active.external, DnDEvent.external). While it is held the browser tells what it carries, not the data: the files, links and text come at the drop (ready).
readonly string[]The MIME types it offers (Files, text/uri-list, text/plain, an app's own).
readonly string[]The MIME types of its files, one per file ('' when the browser can't tell).
readonly File[]At the drop: the files the target takes (folders and refused files left out).
readonly string[]At the drop: its links (text/uri-list).
stringAt the drop: its plain text.
stringAt the drop: its HTML.
(type: string) => stringAt the drop: the data of any type it offers ('' before, and for a type it doesn't offer).
booleanIt was dropped: the data above is there.
stringItems of the library dragged in from another window of the app (native): the name of their sortable group. The lists of that group take them as if they came from one of their own lists; active.items has them.
A file of a drag from outside, as ExternalAccept.files is asked about it. While the files are held over the page the browser tells their types only: name and size come at the drop.