Skip to content

useModal y useGlobalSearch

Composable simple para manejar la visibilidad de modales y pasar datos a ellos.

const {
showModal, // Ref<boolean> — visibilidad
dataModal, // Ref<any> — datos del modal
useOpenModal, // () => void — abre
useCloseModal, // () => void — cierra
useOpenModalWithData, // <T>(data: T) => void — abre con datos
useAutoCloseModal, // () => void — abre y se cierra solo tras 5s
useOpenScrollableModal, // () => void — abre + bloquea scroll del body
useCloseScrollableModal // () => void — cierra + restaura scroll
} = useModal()
<template>
<button @click="useOpenModalWithData(selectedCourse)">Ver detalle</button>
<AETheModal :show="showModal" @close="useCloseModal">
<CourseDetail :course="dataModal" />
</AETheModal>
</template>
<script setup lang="ts">
const { showModal, dataModal, useOpenModalWithData, useCloseModal } = useModal()
</script>

Para modales que cubren toda la pantalla y necesitan bloquear el scroll del contenido de fondo:

useOpenScrollableModal() // abre + document.documentElement.style.overflow = 'hidden'
useCloseScrollableModal() // cierra + restaura overflow original

Sistema de búsqueda y filtrado reactivo sobre arrays de items.

const {
searchQuery, // Ref<string> — el texto de búsqueda
searchResults, // Computed — resultados filtrados
hasResults, // Computed<boolean>
totalResults, // Computed<number>
setSearchQuery, // (query: string) => void
clearSearch // () => void
} = useGlobalSearch(items, {
keys: ['title', 'description'], // campos donde buscar
threshold: 0.3 // tolerancia de fuzzy matching
})

Ejemplo en template:

<AESearchBar v-model="searchQuery" />
<AEMainCardGrid :items="searchResults" />
<p v-if="!hasResults">No se encontraron resultados</p>

Para la búsqueda global que busca en cursos, libros, canales, etc. simultáneamente:

const {
searchQuery,
groupedResults, // grupos no vacíos con sus resultados
flatResults, // todos los resultados planos
resultsBySource, // resultados por fuente individual
groupCount, // número de grupos con resultados
isSearching // boolean: hay query activo
} = useMultipleSearch({
courses: {
items: coursesRef,
keys: ['title', 'description'],
aliases: ['cursos', 'courses', 'formación'] // escribir "cursos" activa este grupo
},
books: {
items: booksRef,
keys: ['title', 'author'],
aliases: ['libros', 'books', 'biblioteca']
}
})

Los aliases permiten que si el usuario escribe “cursos” exactamente, se muestren todos los items de ese grupo — actuando como un atajo/filtro por categoría.

<div v-for="group in groupedResults" :key="group.name">
<h3>{{ group.name }} ({{ group.count }})</h3>
<AEMainCard v-for="item in group.items" :key="item.id" v-bind="item" />
</div>