Documentación/Guías
Archivos y otras apps
El arrastrar y soltar propio del navegador, como arrastres de la biblioteca — archivos, enlaces y texto de otras apps en destinos de drop y listas que les hacen sitio, ítems arrastrados fuera de la página, y entre ventanas de tu app.
Esta página la ha traducido una IA y puede contener imprecisiones. Leer el original en inglés
Los arrastres de la biblioteca viven dentro de la página. El navegador tiene un arrastrar y soltar propio que cruza los bordes de la página: archivos desde el escritorio, un enlace desde otra pestaña, texto desde otra app, y tus ítems arrastrados hacia todos esos sitios. La biblioteca también gestiona esos arrastres, como arrastres del provider: los destinos se iluminan, las listas hacen sitio, los eventos y los textos para lectores de pantalla son los de siempre.
Cargando la demo…
<script setup lang="ts">
import { DnDProvider } from '@vue-dnd-kit/core';
import Board from './Board.vue';
</script>
<template>
<DnDProvider>
<Board />
</DnDProvider>
</template>Desde fuera de la página
Un destino acepta esos arrastres con external, que dice lo que acepta. Los destinos sin esta
opción los ignoran.
const { items } = makeSortableList(grid, {
items: cards,
group: 'moodboard',
strategy: 'grid',
external: { files: 'image/*', links: true, text: true },
createItem: fromOutside,
});
external | Acepta |
|---|---|
files | Archivos: true cualquiera, tipos MIME y extensiones tal como los lee <input accept> ('image/*, .md'), o una función a la que se pregunta archivo por archivo. Carpetas nunca. |
multiple | false: un archivo cada vez. Un arrastre de varios se rechaza. |
links | Enlaces (text/uri-list): una dirección desde otra pestaña, un enlace de una página. |
text | Texto plano: una selección desde otra app. |
types | Otros tipos MIME, exactamente como los ofrecen otras apps. |
makeDroppable acepta la misma opción: una zona que acepta una imagen de avatar está en
arrastrar y soltar.
Lo que lleva el arrastre
El navegador se guarda los datos de un arrastre hasta que se suelta. Mientras se mantiene, la
página solo sabe qué tipos de datos lleva. active.external y e.external dicen lo que se sabe:
| Mientras se mantiene | Al soltar | |
|---|---|---|
types | Los tipos MIME que ofrece: Files, text/uri-list… | Los mismos |
fileTypes | Un tipo MIME por archivo | Los mismos |
files | Vacío | Los archivos que acepta el destino, como File |
urls, text, html | Vacío | Sus enlaces, su texto, su HTML |
getData(type) | '' | Los datos de cualquier tipo que ofrezca |
ready | false | true |
En una lista
Una lista le hace sitio como a un elemento arrastrable simple: con createItem, al que se le
pregunta dos veces: mientras se mantiene el arrastre, por el ítem que muestra adónde va, y
al soltar, con los datos, por lo que entra. Un array de ítems se inserta entero en ese sitio: una
tarjeta por imagen.
export const fromOutside = (active: Active): Card | Card[] | undefined => {
const { external } = active;
if (!external) return undefined;
// While it is held: a tile that says what is coming.
if (!external.ready) return { id: 'incoming', kind: 'incoming', label: incoming(external) };
// At the drop: a card each.
if (external.files.length) {
return external.files.map((file) => ({ id: uid(), kind: 'image', src: URL.createObjectURL(file), name: file.name }));
}
if (external.urls.length) return external.urls.map((url) => ({ id: uid(), kind: 'link', url, title: host(url) }));
const text = external.text.trim();
return text ? { id: uid(), kind: 'note', text } : undefined;
};
- La ficha de lo que llega es una fila de tu lista como cualquier otra: la lista la renderiza,
las filas de alrededor se apartan de su camino,
onDroprecibe los ítems reales. - Los árboles también aceptan estos arrastres, un nodo cada vez: un nodo carpeta con un hijo por archivo admite varios.
- El evento del drop tiene
e.externalcon los datos, tanto en elonDropde la lista como en el de los monitores.
Fuera de la página
Con native, un arrastre de un ítem con el ratón es el arrastre propio del navegador, así que
puede salir de la página: al escritorio, a un editor, a un chat, a otra pestaña.
makeSortableItem(el, {
item: () => props.card,
native: { data: () => toOutside(props.card) },
});
case 'link':
return { 'text/uri-list': card.url, 'text/plain': card.url };
case 'note':
return { 'text/plain': card.text };
datada a otras apps el ítem como tipos MIME y texto:text/plain,text/uri-list,text/html. Se lee cuando empieza el arrastre. Sin ella,native: truelleva ellabelcomo texto.- En la página, el arrastre funciona como cualquier otro: destinos, listas que hacen sitio, el
drop. El navegador dibuja la imagen arrastrada en lugar del overlay, y el elemento se queda en
su sitio (
transformsigue siendonullconoverlay: false). - Los arrastres táctiles y con teclado del ítem siguen siendo de la biblioteca: el navegador no tiene un arrastre propio para ellos.
effect(effectAllowed) dice qué puede hacer el sitio donde se suelta:'copyMove'por defecto. Un drop en otro sitio termina el arrastre condroppedOutside,'move','copy'o'link', enonDragEnd. Un movimiento saca los ítems de su lista; una copia los deja.
makeDraggable acepta native de la misma forma.
Entre ventanas
Un ítem con native también se lleva a sí mismo: las listas de su grupo en otra ventana de tu
app lo aceptan como si viniera de una de sus propias listas. Abre el moodboard en una segunda
ventana y arrastra una tarjeta de una a otra.
- Mientras se mantiene el arrastre, la otra ventana ya tiene el ítem: su lista lo muestra en su sitio.
- Al soltar, entra allí, y aquí sale de su lista (el drop fue un movimiento). Mantén Ctrl (Option en Mac) para copiarlo en su lugar.
- A una lista con
createItemtambién se le pregunta por estos ítems, conactive.external.groupdefinido y los ítems enactive.items[].item: devuélvelos, o copias con claves de esa ventana. SincreateItem, entran tal cual. - Los ítems viajan como JSON: las fechas se vuelven cadenas, las funciones se descartan.
Límites
- Los datos llegan solo con el drop, nunca antes: planifica sin ellos el ítem que se muestra mientras se mantiene un arrastre.
- Arrastrar archivos es cosa de quien usa ratón o trackpad. Ofrece también un
<input type="file">junto a la zona. - Un único provider de la página acepta arrastres de fuera: el primero que tenga un destino para ellos.
- En Firefox, un ítem movido a otra lista durante el arrastre y luego soltado en otra ventana no se entera de ese drop: aquí se queda donde estaba.
- Un ítem cuyo JSON pasa de 16 KB sigue yendo a otra ventana, pero esa ventana solo lo muestra al soltar.
La API está en makeDroppable y makeDraggable.