MultiSelect

Componente para selección múltiple con opciones personalizables y soporte para animaciones

Uso

Ejemplo de Implementación

A continuación, se muestra cómo puedes importar y utilizar el componente MultiSelect en una página o componente de Vue 3.

<template lang="pug">
MultiSelect(
  :options="opciones"
  v-model="valoresSeleccionados"
  placeholder="Selecciona opciones"
  :animation="0.3"
  :maxCount="3"
  @select="manejarSeleccion"
)
</template>

<script setup lang="ts">
import { ref } from 'vue'

// Define las opciones disponibles
const opciones = [
  { label: 'Opción 1', value: 'op1' },
  { label: 'Opción 2', value: 'op2' },
  { label: 'Opción 3', value: 'op3' },
  { label: 'Opción 4', value: 'op4' }
]

// Almacena los valores seleccionados
const valoresSeleccionados = ref([])

// Define la función que manejará el evento `select`
const manejarSeleccion = (valores) => {
  console.log('Valores seleccionados:', valores)
  // Aquí puedes realizar acciones adicionales con los valores seleccionados
}
</script>

Ejemplo en un Formulario

El siguiente ejemplo muestra cómo integrar el componente MultiSelect dentro de un formulario con validación:

<template lang="pug">
FormField(name="asignaturas", v-slot="{ componentField }")
  FormItem
    FormLabel Asignaturas
    FormControl
      MultiSelect(
        v-model="asignaturasSeleccionadas"
        placeholder="Elegir Asignatura(s)"
        :max-count="3"
        @select="(value) => { form.setFieldValue('asignaturas', value) }"
        :options="asignaturasOptions"
      )
    FormMessage
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'

// Valores seleccionados
const asignaturasSeleccionadas = ref<string[]>([])

// Opciones computadas desde una lista de asignaturas
const asignaturasOptions = computed(() => {
  return listaAsignaturas.value?.map((a) => {
    return {
      label: a.alias || a.asignaturaSige?.nombre || a.asignaturaCurricular?.nombre || '',
      value: `${a.id}`
    }
  })
})

// Ejemplo de integración con un formulario (con zod o similar)
const form = useForm({
  validationSchema: formSchema,
  initialValues: {
    asignaturas: []
  }
})

// Actualizar valores cuando cambia el curso
watch(() => form.values.cursoId, async (newValue) => {
  if (newValue) {
    // Obtener asignaturas relacionadas con el curso seleccionado
    const response = await obtenerAsignaturasPorCurso(newValue)
    listaAsignaturas.value = response
    
    // Resetear selección
    form.setFieldValue('asignaturas', [])
    asignaturasSeleccionadas.value = []
  }
})
</script>

Props

PropTipoDescripciónRequeridoValor por defecto
optionsarrayArray de objetos con estructura { label: string, value: string }-
modelValuearrayArray de strings con los valores seleccionadosNo[]
placeholderstringTexto que se muestra cuando no hay elementos seleccionadosNo-
animationnumberDuración de la animación en segundosNo-
maxCountnumberNúmero máximo de elementos a mostrar antes de agruparNo3
modalPopoverbooleanDetermina si el popover debe comportarse como modalNofalse
asChildbooleanDetermina si el componente debe renderizarse como hijoNofalse
classNamestringClases CSS adicionales para el componenteNo-
variantstringVariante de estilo ('default', 'secondary', 'destructive', 'inverted')No'default'

Eventos Emitidos

EventoDescripciónDatos emitidos
update:modelValueEmitido cuando cambia la selección para actualizar el v-modelArray de valores seleccionados
selectEmitido cuando el usuario selecciona o deselecciona una opciónArray de valores seleccionados

Comportamiento

  • Selección Múltiple: Permite seleccionar varias opciones que se muestran como badges.
  • Búsqueda: Incluye un campo de búsqueda para filtrar las opciones disponibles.
  • Animaciones: Soporta animaciones para los elementos seleccionados mediante la prop animation.
  • Límite de Visualización: Muestra un número limitado de elementos (definido por maxCount) y agrupa el resto bajo un indicador "+X más".
  • Selección Rápida: Incluye opciones para seleccionar o deseleccionar todas las opciones con un solo clic.
  • Personalización Visual: Soporta diferentes variantes visuales a través de la prop variant.

Funcionalidades Adicionales

  • Teclado: Soporta navegación por teclado y eliminación del último elemento seleccionado con la tecla Backspace.
  • Limpieza: Incluye botones para eliminar selecciones individuales o limpiar todas las selecciones.
  • Retroalimentación Visual: Los elementos seleccionados se muestran claramente con un estilo diferenciado.

Notas

  • El componente utiliza Popover y Command de tu biblioteca de UI para la interfaz de selección.
  • Para un rendimiento óptimo, se recomienda limitar la cantidad de opciones a menos de 5 elementos.
  • Las animaciones son opcionales y pueden desactivarse no proporcionando la prop animation.