autofocus search field on search page

This commit is contained in:
Ruidy 2024-12-17 21:26:39 +01:00
parent 5bd9f2c382
commit 7decbe7cbe
No known key found for this signature in database
GPG key ID: E00F51288CB857CC
2 changed files with 28 additions and 13 deletions

View file

@ -9,7 +9,8 @@
placeholder="Search recipes..." placeholder="Search recipes..."
@focus="isFocused = true" @focus="isFocused = true"
@blur="isFocused = false" @blur="isFocused = false"
> :autofocus="autofocus"
/>
<kbd <kbd
class="hidden md:inline-block kbd kbd-sm" class="hidden md:inline-block kbd kbd-sm"
:class="{ 'opacity-50': !isFocused }" :class="{ 'opacity-50': !isFocused }"
@ -27,6 +28,9 @@
<script setup lang="ts"> <script setup lang="ts">
const model = defineModel<string>(); const model = defineModel<string>();
const props = defineProps<{
autofocus?: boolean;
}>();
const isFocused = ref(false); const isFocused = ref(false);
// Debounced navigation // Debounced navigation

View file

@ -4,18 +4,24 @@ import type { Recipe } from "~/types/recipe";
const route = useRoute(); const route = useRoute();
const searchQuery = computed(() => route.query.q as string); const searchQuery = computed(() => route.query.q as string);
const searchResults = ref<Recipe[]>([]); const searchResults = ref<Recipe[]>([]);
const loading = ref(false);
const { data, status, error } = await useRecipeSearch(searchQuery.value || ""); if (searchQuery.value) {
if (error.value) { loading.value = true;
throw createError({ const { data, error } = await useRecipeSearch(searchQuery.value);
statusCode: 500, if (error.value) {
message: error.value.message, throw createError({
}); statusCode: 500,
message: error.value.message,
});
}
searchResults.value = data.value!;
loading.value = false;
} }
searchResults.value = data.value;
watch(searchQuery, async (newQuery) => { watch(searchQuery, async (newQuery) => {
loading.value = true;
const { data, error } = await useRecipeSearch(newQuery.trim()); const { data, error } = await useRecipeSearch(newQuery.trim());
if (error.value) { if (error.value) {
throw createError({ throw createError({
@ -24,21 +30,26 @@ watch(searchQuery, async (newQuery) => {
}); });
} }
searchResults.value = data.value; searchResults.value = data.value!;
loading.value = false;
}); });
</script> </script>
<template> <template>
<div class="container mx-auto px-4"> <div class="container mx-auto px-4">
<div v-if="status === 'pending'" class="flex justify-center my-8"> <recipe-search
class="md:hidden mb-6"
:initial-query="searchQuery"
:autofocus="true"
/>
<div v-if="loading" class="flex justify-center my-8">
<span class="loading loading-spinner loading-lg text-primary" /> <span class="loading loading-spinner loading-lg text-primary" />
</div> </div>
<div <div
v-else-if="searchResults.length > 0" v-if="searchResults.length > 0"
class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 my-8" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 my-8"
> >
<recipe-search class="md:hidden mb-6" :initial-query="searchQuery" />
<div <div
v-for="recipe in searchResults" v-for="recipe in searchResults"
:key="recipe.id" :key="recipe.id"