Skip to content

Commit 364c842

Browse files
committed
feat(search): add data attribute for global search inputs
- Added `data-global-search` attribute to search input fields in SearchBox.vue and index.vue to distinguish global search from local filters. - Updated `getFocusedSearchInputValue` function to only capture values from inputs marked with `data-global-search`, enhancing search query handling.
1 parent da1d4a5 commit 364c842

3 files changed

Lines changed: 17 additions & 4 deletions

File tree

app/components/Header/SearchBox.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ defineExpose({ focus })
5757
v-model="searchQuery"
5858
type="search"
5959
name="q"
60+
data-global-search
6061
:placeholder="$t('search.placeholder')"
6162
no-correct
6263
class="w-full min-w-25 ps-7 pe-8"

app/composables/useGlobalSearch.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,18 @@ import { debounce } from 'perfect-debounce'
66
const pagesWithLocalFilter = new Set(['~username', 'org'])
77

88
const SEARCH_DEBOUNCE_MS = 100
9+
10+
/**
11+
* Returns the value of the focused global search input, if any.
12+
* Only matches inputs explicitly marked with data-global-search attribute
13+
* to avoid capturing page-local filter inputs.
14+
*/
915
const getFocusedSearchInputValue = () => {
1016
if (!import.meta.client) return ''
1117

1218
const active = document.activeElement
1319
if (!(active instanceof HTMLInputElement)) return ''
14-
if (active.type !== 'search' && active.name !== 'q') return ''
20+
if (!active.hasAttribute('data-global-search')) return ''
1521
return active.value
1622
}
1723
export function useGlobalSearch(place: 'header' | 'content' = 'content') {
@@ -28,15 +34,18 @@ export function useGlobalSearch(place: 'header' | 'content' = 'content') {
2834

2935
// Internally used searchQuery state
3036
const searchQuery = useState<string>('search-query', () => {
37+
// Skip reading focused input on pages with local filters - they use ?q for local state
38+
if (pagesWithLocalFilter.has(route.name as string)) {
39+
return ''
40+
}
41+
3142
// Preserve fast typing before hydration (e.g. homepage autofocus search input).
43+
// Only captures inputs with data-global-search marker attribute.
3244
const focusedInputValue = getFocusedSearchInputValue()
3345
if (focusedInputValue) {
3446
return focusedInputValue
3547
}
3648

37-
if (pagesWithLocalFilter.has(route.name as string)) {
38-
return ''
39-
}
4049
return normalizeSearchParam(route.query.q)
4150
})
4251

@@ -159,8 +168,10 @@ export function useGlobalSearch(place: 'header' | 'content' = 'content') {
159168

160169
// On hydration, useState can reuse SSR payload (often empty), skipping initializer.
161170
// Recover fast-typed value from the focused input once on client mount.
171+
// Skip on pages with local filters to avoid importing local ?q state.
162172
if (import.meta.client) {
163173
onMounted(() => {
174+
if (pagesWithLocalFilter.has(route.name as string)) return
164175
const focusedInputValue = getFocusedSearchInputValue()
165176
if (!focusedInputValue) return
166177
if (searchQuery.value) return

app/pages/index.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ defineOgImage('Splash.takumi', {}, { alt: () => $t('seo.home.description') })
5959
v-model="searchQuery"
6060
type="search"
6161
name="q"
62+
data-global-search
6263
autofocus
6364
:placeholder="$t('search.placeholder')"
6465
no-correct

0 commit comments

Comments
 (0)