useModal y useGlobalSearch
useModal — Control de modales
Section titled “useModal — Control de modales”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()Ejemplo típico
Section titled “Ejemplo típico”<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>Variantes con scroll
Section titled “Variantes con scroll”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 originaluseGlobalSearch — Búsqueda reactiva
Section titled “useGlobalSearch — Búsqueda reactiva”Sistema de búsqueda y filtrado reactivo sobre arrays de items.
Búsqueda simple (un array)
Section titled “Búsqueda simple (un array)”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>Búsqueda multi-source (varios arrays)
Section titled “Búsqueda multi-source (varios arrays)”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.
Ejemplo de UI con resultados agrupados
Section titled “Ejemplo de UI con resultados agrupados”<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>