11<script setup lang="ts">
2- import { debounce } from ' perfect-debounce'
32import { normalizeSearchParam } from ' #shared/utils/url'
43
54withDefaults (
@@ -22,12 +21,14 @@ const showSearchBar = computed(() => {
2221
2322// Local input value (updates immediately as user types)
2423const searchQuery = shallowRef (' ' )
24+ onMounted (() => {
25+ searchQuery .value = normalizeSearchParam (route .query .q )
26+ })
2527
2628// Pages that have their own local filter using ?q
2729const pagesWithLocalFilter = new Set ([' ~username' , ' org' ])
2830
29- // Debounced URL update for search query
30- const updateUrlQuery = debounce ((value : string ) => {
31+ const updateUrlQuery = (value : string ) => {
3132 // Don't navigate away from pages that use ?q for local filtering
3233 if (pagesWithLocalFilter .has (route .name as string )) {
3334 return
@@ -46,28 +47,7 @@ const updateUrlQuery = debounce((value: string) => {
4647 q: value ,
4748 },
4849 })
49- }, 250 )
50-
51- // Sync input with URL when navigating (e.g., back button)
52- watch (
53- () => route .query .q ,
54- urlQuery => {
55- // Don't sync from pages that use ?q for local filtering
56- if (pagesWithLocalFilter .has (route .name as string )) {
57- return
58- }
59- const value = normalizeSearchParam (urlQuery )
60- if (searchQuery .value !== value ) {
61- searchQuery .value = value
62- }
63- },
64- { immediate: true },
65- )
66-
67- // Watch input and debounce URL updates
68- watch (searchQuery , value => {
69- updateUrlQuery (value )
70- })
50+ }
7151
7252function handleSearchBlur() {
7353 emit (' blur' )
@@ -76,6 +56,8 @@ function handleSearchFocus() {
7656 emit (' focus' )
7757}
7858
59+ const inputRef = useTemplateRef (' inputRef' )
60+
7961function handleSubmit() {
8062 if (pagesWithLocalFilter .has (route .name as string )) {
8163 router .push ({
@@ -85,12 +67,13 @@ function handleSubmit() {
8567 },
8668 })
8769 } else {
88- updateUrlQuery . flush ( )
70+ updateUrlQuery ( searchQuery . value )
8971 }
72+
73+ inputRef .value ?.focus ()
9074}
9175
9276// Expose focus method for parent components
93- const inputRef = useTemplateRef (' inputRef' )
9477function focus() {
9578 inputRef .value ?.focus ()
9679}
@@ -103,8 +86,10 @@ defineExpose({ focus })
10386 {{ $t('search.label') }}
10487 </label >
10588
106- <div class =" relative group" >
107- <div class =" search-box relative flex items-center" >
89+ <div
90+ class =" relative group bg-bg-subtle border border-border rounded-md transition-[border-color,outline-color] duration-300 hover:border-fg-subtle outline-2 outline-transparent focus-within:border-accent focus-visible:(outline-2 outline-accent/70)"
91+ >
92+ <div class =" flex items-center" >
10893 <span
10994 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"
11095 >
@@ -119,11 +104,15 @@ defineExpose({ focus })
119104 name =" q"
120105 :placeholder =" $t('search.placeholder')"
121106 v-bind =" noCorrect"
122- class =" w-full min-w-25 bg-bg-subtle border border-border rounded-md ps-7 pe-3 py-1.5 font-mono text-sm text-fg placeholder:text-fg-subtle transition-[border-color, outline-color] duration-300 hover:border-fg-subtle outline-2 outline-transparent focus:border-accent focus-visible:(outline-2 outline-accent/70) "
107+ class =" w-full ps-7 pe-3 py-1.5 font-mono text-sm text-fg placeholder:text-fg-subtle outline-none "
123108 @focus =" handleSearchFocus"
124109 @blur =" handleSearchBlur"
125110 />
126- <button type =" submit" class =" sr-only" >{{ $t('search.button') }}</button >
111+
112+ <button type =" submit" class =" flex items-center justify-center p-2" >
113+ <span class =" sr-only" >{{ $t('search.button') }}</span >
114+ <span class =" i-carbon-search w-4 h-4" aria-hidden =" true" />
115+ </button >
127116 </div >
128117 </div >
129118 </form >
0 commit comments