Documentación/API

makeSortableList

Convierte un contenedor en una lista ordenable — un borrador que se reordena mientras arrastras y que se escribe al soltar.

Editar esta página

Esta página la ha traducido una IA y puede contener imprecisiones. Leer el original en inglés

function makeSortableList<T>(  target: MaybeElementRef,  options: SortableListOptions<T>,): SortableListReturn<T>;

Convierte un contenedor en una lista ordenable. Renderiza los items devueltos (el orden del borrador), no tu array: el drop se escribe de vuelta en options.items, después de onDrop, salvo que event.preventDefault() te deje event.result a ti.

const list = useTemplateRef<HTMLElement>('list');
const { items } = makeSortableList(list, { items: tasks, group: 'board' });

Sus filas llaman a makeSortableItem. Consulta Listas ordenables y Listas que comparten ítems.

Live

Cargando la demo…

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

const strategy = ref<'vertical' | 'horizontal' | 'grid'>('grid');
const placeholder = ref<'item' | 'indicator'>('item');
const behavior = ref<'sort' | 'swap'>('sort');
</script>

<template>
  <DnDProvider>
    <div class="demo">
      <div class="switches">
        <Segmented v-model="strategy" name="strategy" :options="['vertical', 'horizontal', 'grid']" />
        <Segmented v-model="placeholder" name="placeholder" :options="['item', 'indicator']" />
        <Segmented v-model="behavior" name="behavior" :options="['sort', 'swap']" />
      </div>
      <code class="call">makeSortableList(el, { strategy: '{{ strategy }}', placeholder: '{{ placeholder }}', behavior: '{{ behavior }}' })</code>
      <Tiles :strategy="strategy" :placeholder="placeholder" :behavior="behavior" />
    </div>
  </DnDProvider>
</template>

<style scoped>
.demo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  max-width: 100%;
}

.switches {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 16px;
}

.call {
  max-width: 100%;
  padding: 6px 10px;
  overflow-x: auto;
  border-radius: 8px;
  background: color-mix(in srgb, currentColor 6%, transparent);
  font: 11px/1.4 ui-monospace, Menlo, Consolas, monospace;
  white-space: nowrap;
  color: #42b883;
}
</style>

Opciones

Opciones de makeSortableList. Un componente puede crear varias listas (y árboles): cada ítem renderizado en él se une a la más interior cuyo elemento lo contiene.

Las opciones aceptan un valor, una ref o un getter (overlay, overOverlay, dropAnimation, overDropAnimation, animation: un valor o una ref) y se leen cuando la lista las necesita, así que un cambio se aplica, como muy tarde, en el siguiente arrastre. Excepciones: id y group se leen una sola vez, al crear la lista; items es el propio modelo; las funciones (getKey, filter, clone, createItem, los callbacks) se pasan tal cual.

SortableItems<T>

La fuente de verdad. Una ref escribible recibe el nuevo array al soltar, justo después de onDrop. Una fuente de solo lectura (un getter, una ref readonly, un computed) no puede: llama a event.preventDefault() y aplica event.result tú mismo. Las builds de desarrollo avisan de un drop que se deja ahí en manos de la biblioteca, que entonces no cambia nada.

(item: T) => Key

Por defecto: item.id, o el propio ítem en el caso de los primitivos. También da la clave de makeSortableItem({ item }).

(item: T) => boolean

Muestra solo los ítems para los que devuelve true (una búsqueda, una etiqueta): items (el que se devuelve) los contiene, y un arrastre ordena entre ellos. Los demás conservan su sitio en el origen: un drop escribe el array entero, con cada ítem oculto todavía después del visible al que seguía (después del más cercano que se quedó quieto, si ese se movió). Reactiva: lo que lee (una ref de búsqueda) se aplica al momento. e.to.index y activeIndex cuentan los ítems visibles.

Key

Por defecto: useId(), estable entre el renderizado en el servidor y en el cliente. Se lee una vez.

stringvalor · ref · getter

El nombre que la gente le da a la lista: los textos para lectores de pantalla lo dicen en lugar de su id (position 2 of 5 in Garden).

unknownvalor · ref · getter

Cualquier cosa que contar sobre la lista como destino de drop: los eventos lo llevan como over.data mientras un arrastre está sobre ella.

ActivationOptionsvalor · ref · getter

Cómo una pulsación sobre los ítems de esta lista inicia un arrastre, en lugar de la activation del provider (la propia de un ítem tiene prioridad). Se lee cuando empieza una pulsación.

Componentvalor · ref

Componente de overlay para los ítems de esta lista (el overlay propio de un ítem tiene prioridad). Recibe OverlayProps y se mantiene durante todo el arrastre, también sobre otras listas, salvo que el destino bajo el arrastre tenga un overlay propio (overOverlay). Una ref cambiada a mitad del arrastre lo cambia al instante.

Componentvalor · ref

Lo que muestra el overlay mientras un arrastre que esta lista acepta está sobre ella, venga de la lista que venga: un componente que recibe OverlayProps y el overlay propio del arrastre como su slot por defecto (consulta DroppableOptions.overOverlay). Se lee en vivo.

DropAnimationvalor · ref

Cómo aterriza el overlay cuando termina un arrastre de los ítems de esta lista, en lugar de la dropAnimation del provider (la propia de un ítem tiene prioridad; la de un destino de drop tiene prioridad sobre ambas). Se lee al soltar.

DropAnimationvalor · ref

Cómo aterriza el overlay cuando se suelta en esta lista, venga de la lista que venga: tiene prioridad sobre la dropAnimation del ítem arrastrado y la del provider. Se lee al soltar.

Modifier[]valor · ref · getter

Modificadores para los arrastres de los ítems de esta lista, aplicados después de los modifiers del provider (los modifiers propios de un ítem tienen prioridad): por ejemplo [restrictToVerticalAxis] para mantener en su eje los ítems de una lista vertical. Se leen cuando empieza el arrastre.

'x' | 'y'valor · ref · getter

Bloquea en un eje los arrastres de los ítems de esta lista: 'y' para una lista vertical, 'x' para una horizontal (el axis propio de un ítem tiene prioridad). El bloqueo va después de los modificadores, así que se mantiene hagan lo que hagan. Se lee cuando empieza el arrastre.

string | SortableGroupOptions<T>

Las listas con el mismo nombre de grupo intercambian ítems. Por defecto: un grupo propio. Se lee una vez.

AcceptModevalor · ref · getter

Multi-drag de ítems de varios tipos: deben aceptarse 'all' (por defecto) o 'some' (group.put).

SortableStrategyvalor · ref · getter

'vertical' por defecto.

SortableBehaviorvalor · ref · getter

'swap': el ítem arrastrado intercambia su sitio con aquel sobre el que está, en vivo; volver sobre él o salir de las listas lo revierte. Las listas de un mismo grupo que intercambian las dos se pasan ítems entre ellas: el ítem sobre el que se está pasa al sitio del arrastrado, así que debe poder salir de su lista (group.pull: true) y entrar en la del ítem arrastrado (group.put). Un multi-drag ordena en su lugar. 'sort' por defecto.

SortablePlaceholdervalor · ref · getter

'indicator': la lista no se mueve, indicator indica adónde va el drop. 'item' por defecto.

MultipleModevalor · ref · getter

Modo de multi-drag de los arrastres que empiezan en esta lista. 'group' por defecto. Se lee cuando empieza el arrastre.

booleanvalor · ref · getter

false: los ítems no se pueden reordenar dentro de esta lista (paletas).

(item: T) => T

Crea copias (pull: 'clone', la tecla modificadora de copia). Necesaria para copiar.

(active: Active) => T | T[]

Acepta elementos arrastrables simples de fuera: crea el ítem que se va a insertar. Con el teclado, una flecha hacia la lista mete en ella el elemento arrastrable (a su misma altura, como en los movimientos entre listas), y el ítem creado se mueve luego por huecos como cualquier otro.

Con un arrastre desde fuera de la página (external), se le pregunta dos veces: mientras se mantiene, por el ítem que muestra adónde va (entonces solo se conocen active.external.fileTypes y types), y al soltar, con sus datos (active.external.ready), por lo que se inserta. Un array de ítems se inserta entero donde estaba el hueco: uno por archivo.

ExternalAcceptvalor · ref · getter

Acepta arrastres desde fuera de la página: archivos, enlaces, texto (consulta ExternalAccept). La lista les hace sitio como a un elemento arrastrable simple, con createItem, que necesita. Los ítems de su grupo arrastrados desde otra ventana de la app (native) no necesitan ninguna de las dos opciones: entran tal cual. Un valor, una ref o un getter, que se lee en vivo.

DropOutsidevalor · ref · getter

Un drop fuera de todo destino: dejar los ítems donde está el placeholder, cancelar o quitarlos. 'placeholder' por defecto ('cancel' con placeholder: 'indicator'). Se lee al soltar.

LayoutAnimationvalor · ref

Animación FLIP de esta lista; por defecto, la animation del provider. Un valor o una ref (una función es una animación personalizada).

AutoAnimationvalor · ref · getter

Anima los cambios de items que no vienen de un arrastre: ítems añadidos, quitados, movidos y filtrados (consulta AutoAnimation). Por defecto: el animateChanges del provider, desactivado salvo que se active ahí. Se lee cuando cambia items.

booleanvalor · ref · getter

El tamaño propio de la lista sigue a sus ítems: cuando un arrastre mete un ítem o saca uno (y al soltar, y en los cambios que muestra animateChanges), crece o se encoge hasta su nuevo tamaño con la duración y el easing de animation en lugar de saltar, y lo que hay alrededor se mueve con ella. Por defecto true; false la deja saltar. Se lee en cada cambio.

boolean | AutoScrollOptionsvalor · ref · getter

Sustituye el autoScroll del provider para el contenedor desplazable de esta lista. Se lee cuando empieza el arrastre.

MaybeElementRef

El elemento que recibe los drops de la lista, por defecto el propio elemento de la lista: por ejemplo, toda la columna alrededor de una lista corta de tarjetas, para que una tarjeta que se suelta debajo de la última siga aterrizando en la lista (al final). Los ítems se quedan en el elemento de la lista.

booleanvalor · ref · getter

true: sus ítems no se pueden arrastrar y no acepta ítems.

( event: SortableDropEvent<T>, ) => MaybePromise<BeforeDropResult>

Se consulta antes de un drop en esta lista, y antes de que dropOutside: 'remove' saque sus ítems: false lo rechaza (los ítems vuelven a su sitio), unas claves aceptan solo esos ítems. Puede ser asíncrono: el overlay espera donde se soltó. Un error también rechaza el drop. Consulta SortableDropEvent para result y preventDefault.

(event: SortableDropEvent<T>) => void

Se llama cuando se acepta un drop en esta lista, antes de escribirlo: items todavía tiene el orden antiguo y event.result el nuevo. Síncrono: la escritura sigue en cuanto retorna, salvo que haya llamado a event.preventDefault(). También se llama en la lista de la que vienen los ítems cuando se quitan (to.index es -1).

Valor devuelto

Lo que devuelve makeSortableList.

Key

El id de la lista: la opción id o el que se creó para ella.

ComputedRef<T[]>

El orden del borrador: renderiza esto, no el array de origen.

ComputedRef<boolean>

Hay un arrastre sobre la lista.

ComputedRef<boolean>

Se está arrastrando algo y esta lista lo acepta.

ComputedRef<SortableIndicator | null>

Modo indicador: adónde va el drop en esta lista; null cuando no es aquí.

ComputedRef<Key | null>

La fila que un virtualizador debe mantener montada: el hueco mientras está en esta lista (una copia, un ítem creado); si no, el ítem arrastrado; null sin arrastre.

ComputedRef<number>

Índice del ítem activo en el borrador de esta lista, -1 cuando no está aquí.

ComputedRef<Size | null>

Tamaño del ítem arrastrado al empezar el arrastre: p. ej., para el tamaño de una fila virtual que ocupa.

() => void

Anima los cambios de layout que no causó la biblioteca (por ejemplo, una nueva medición de un virtualizador).

Grupos

El grupo de una lista: las listas que intercambian ítems, y si los ítems pueden salir de esta y entrar en ella.

string

Las listas y los árboles con el mismo nombre intercambian ítems.

boolean | 'clone'

Si los ítems pueden salir de esta lista: moverse, copiarse ('clone', una paleta) o no salir en absoluto.

boolean | string | string[] | ((context: SortablePutContext<T>) => boolean)

Si los ítems pueden entrar en esta lista: true (por defecto), false, un tipo o tipos que deben tener los ítems (como el accept de un destino de drop: con acceptMode, todos o algunos), o una función del arrastre.

Con qué se llama a un group.put que es una función: los ítems que entrarían en la lista.

Key[]

Claves de los ítems.

T[]

Los ítems (para un elemento arrastrable simple, el ítem que creó createItem).

string[]

Los tipos de los ítems, juntos.

Key | null

Lista de origen, null para los elementos arrastrables externos.

Key

Id de la lista consultada.

El evento de drop

Lo que reciben onBeforeDrop y onDrop.

Un drop sobre una lista o un árbol ordenable. Sus hooks se ejecutan en orden: onBeforeDrop decide, onDrop recibe el aviso, luego la acción por defecto escribe result en los items de cada lista que menciona, y el overlay aterriza. preventDefault() en cualquiera de los dos hooks omite esa escritura, para que apliques result tú mismo.

Key[]

Claves de los ítems arrastrados.

T[]

Los ítems que aterrizan: los arrastrados, sus copias (mode: 'copy') o el ítem que creó createItem ('insert').

Key[]

Las claves que pasan: todas, salvo que la lista u onBeforeDrop acepten solo algunas.

Key[]

Las claves que vuelven a donde estaban.

{ list: Key | null; index: number }

Dónde empezó el arrastre: la lista y el índice del ítem activo. list es null para un elemento arrastrable simple que viene de fuera.

{ list: Key; index: number }

index es -1 cuando no aterrizó nada: los ítems salieron de sus listas (e.source.remove(), dropOutside: 'remove').

boolean

El drop se queda en la lista donde empezó el arrastre.

DragMode

Lo que hace el drop (consulta DragMode).

{ key: Key; item: T; from: { list: Key; index: number }; to: { list: Key; index: number } }

mode: 'swap': el ítem con el que se intercambió el arrastrado. Se movió en sentido contrario: from, el sitio que ocupó el ítem arrastrado (to arriba), y to, aquel en el que empezó el ítem arrastrado (from arriba); entre listas, a la lista del ítem arrastrado.

ReadonlyMap<Key, T[]>

Los nuevos ítems de cada lista que cambia el drop, por id de lista: exactamente lo que la escritura por defecto pone en sus items, como arrays nuevos. Los movimientos, las copias, los ítems creados, una aceptación parcial, los dos lados de un intercambio y los ítems quitados (e.source.remove() en un destino dentro de un ítem, una zona de papelera, dropOutside: 'remove') están todos ahí; una lista que el drop deja como está, no. La entrada de un árbol es un nuevo array de raíces: los nodos de las rutas modificadas son copias (withChildren), los subárboles intactos se comparten y tus nodos nunca se mutan. En onBeforeDrop es el drop tal como está antes de que responda el hook (devolver algunas claves lo cambia); onDrop recibe el definitivo.

() => void

Omite la escritura por defecto en todas las listas de result (escribir solo algunas perdería o duplicaría ítems). Aplica result tú mismo en onDrop, o antes de que se resuelva un onBeforeDrop asíncrono, y el overlay aterriza en el nuevo orden. Si no se aplica en ningún sitio, las listas se quedan como estaban y el overlay vuelve a su sitio (las copias y los ítems creados, que todavía no tienen sitio, se desvanecen).

boolean

Se llamó a preventDefault(), en onBeforeDrop o en onDrop.

ExternalData

Un arrastre desde fuera de la página (external): lo que llevaba, con sus datos (se soltó).

Indicador

Lo que contiene indicator en el modo placeholder: 'indicator'.

Adónde va el drop con placeholder: 'indicator': la lista no se mueve, tú dibujas la línea.

Key

Id de la lista (o del árbol) adonde va el drop.

number

Posición de inserción en la lista tal como se renderiza.

Key | null

Ítem al que está unido el indicador; null en una lista vacía.

'before' | 'after' | 'inside' | 'swap'

Lado de key en el que va la línea. 'inside' (árboles): el puntero está sobre el centro de una fila que acepta los nodos arrastrados, y el drop va dentro de ella como su primer hijo. 'swap' (behavior: 'swap'): key es el ítem con el que el drop hace el intercambio; marca el propio ítem.

number

Árboles: la profundidad que reciben los nodos soltados (las raíces son 0), por ejemplo para sangrar la línea.

Key | null

Árboles: el padre que reciben los nodos soltados, null en el nivel raíz.

Valores

Una fuente de ítems ordenables. Una ref escribible: la biblioteca escribe en ella cada drop. Una de solo lectura (un getter, una ref readonly, un computed: un store inmutable, estado del servidor, un store que solo cambia mediante acciones): aplicas tú cada drop desde event.result, después de event.preventDefault() (consulta SortableDropEvent).

type SortableItems = Ref<T[]> | Readonly<Ref<readonly T[]>> | (() => readonly T[])

Cómo distribuye una lista sus ítems: en columna ('vertical'), en fila ('horizontal') o en una cuadrícula que salta de línea ('grid').

type SortableStrategy = 'vertical' | 'horizontal' | 'grid'

Lo que hace pasar por encima de un ítem: 'sort' hace sitio (los ítems intermedios se desplazan), 'swap' intercambia los dos ítems.

type SortableBehavior = 'sort' | 'swap'

Cómo muestra un arrastre adónde va: 'item', el hueco del ítem arrastrado se mueve por la lista; 'indicator', la lista se queda como está e indicator dice adónde va el drop (tú dibujas la línea).

type SortablePlaceholder = 'item' | 'indicator'

Lo que hacen los demás ítems seleccionados en un multi-drag:

  • 'group': dejan su sitio y viajan con el ítem activo como placeholders contiguos, así que, mientras pasas por encima, la lista ya muestra el resultado del drop;
  • 'gaps': se quedan en su sitio hasta el drop;
  • 'stack': se recogen dentro del overlay.

El overlay por defecto muestra los ítems arrastrados en una columna en la dirección de la lista ('group', 'gaps'; una fila en las listas horizontales, una pila detrás del activo en las cuadrículas), o el activo con un contador ('stack').

type MultipleMode = 'group' | 'gaps' | 'stack'

Lo que hace un drop fuera de todos los destinos: 'placeholder' deja los ítems donde está su hueco, 'cancel' los devuelve, 'remove' los saca de su lista.

type DropOutside = 'placeholder' | 'cancel' | 'remove'