schon/storefront/app/composables/search/useSearchUi.ts
2026-02-27 21:59:51 +03:00

68 lines
1.5 KiB
TypeScript

import { useSearch } from '@composables/search';
import { useDebounceFn } from '@vueuse/core';
export function useSearchUI() {
const query = ref('');
const isSearchActive = ref<boolean>(false);
const { search, loading, searchResults } = useSearch();
const filteredSearchResults = computed(() => {
if (!searchResults.value) return {};
return Object.entries(searchResults.value).reduce<Record<string>>((acc, [category, blocks]) => {
if (Array.isArray(blocks) && blocks.length > 0) {
acc[category] = blocks;
}
return acc;
}, {});
});
const hasResults = computed(() => {
if (!searchResults.value) return false;
return Object.values(searchResults.value).some((blocks) => Array.isArray(blocks) && blocks.length > 0);
});
function getBlockTitle(category: string) {
return category.charAt(0).toUpperCase() + category.slice(1);
}
function clearSearch() {
query.value = '';
searchResults.value = null;
}
function toggleSearch(value: boolean) {
isSearchActive.value = value !== undefined ? value : !isSearchActive.value;
}
const debouncedSearch = useDebounceFn(async () => {
if (query.value) {
await search(query.value);
} else {
searchResults.value = null;
}
}, 750);
watch(
() => query.value,
async () => {
await debouncedSearch();
},
{
immediate: false,
},
);
return {
query,
isSearchActive,
loading,
searchResults,
filteredSearchResults,
hasResults,
getBlockTitle,
clearSearch,
toggleSearch,
};
}