[READ-ONLY] a fast, modern browser for the npm registry
at main 65 lines 1.9 kB view raw
1<script setup lang="ts"> 2withDefaults( 3 defineProps<{ 4 inputClass?: string 5 }>(), 6 { 7 inputClass: 'inline sm:block', 8 }, 9) 10 11const emit = defineEmits(['blur', 'focus']) 12const route = useRoute() 13const isSearchFocused = shallowRef(false) 14 15const showSearchBar = computed(() => { 16 return route.name !== 'index' 17}) 18 19const { model: searchQuery, flushUpdateUrlQuery } = useGlobalSearch() 20 21function handleSubmit() { 22 flushUpdateUrlQuery() 23} 24 25// Expose focus method for parent components 26const inputRef = useTemplateRef('inputRef') 27function focus() { 28 inputRef.value?.focus() 29} 30defineExpose({ focus }) 31</script> 32<template> 33 <search v-if="showSearchBar" :class="'flex-1 sm:max-w-md ' + inputClass"> 34 <form method="GET" action="/search" class="relative" @submit.prevent="handleSubmit"> 35 <label for="header-search" class="sr-only"> 36 {{ $t('search.label') }} 37 </label> 38 39 <div class="relative group" :class="{ 'is-focused': isSearchFocused }"> 40 <div class="search-box relative flex items-center"> 41 <span 42 class="absolute inset-is-3 text-fg-subtle font-mono text-sm pointer-events-none transition-colors duration-200 motion-reduce:transition-none [.group:hover:not(:focus-within)_&]:text-fg/80 group-focus-within:text-accent z-1" 43 > 44 / 45 </span> 46 47 <InputBase 48 id="header-search" 49 ref="inputRef" 50 v-model="searchQuery" 51 type="search" 52 name="q" 53 :placeholder="$t('search.placeholder')" 54 no-correct 55 class="w-full min-w-25 ps-7" 56 @focus="isSearchFocused = true" 57 @blur="isSearchFocused = false" 58 size="small" 59 /> 60 <button type="submit" class="sr-only">{{ $t('search.button') }}</button> 61 </div> 62 </div> 63 </form> 64 </search> 65</template>