Skip to content

Commit 0dc7220

Browse files
committed
feat: add search bar in header, hide connector on mobile, add back button to settings page
1 parent 1f74353 commit 0dc7220

7 files changed

Lines changed: 99 additions & 46 deletions

File tree

app/app.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const router = useRouter()
77
// Initialize accent color before hydration to prevent flash
88
initAccentOnPrehydrate()
99
10-
const isHomepage = computed(() => route.path === '/')
10+
const isHomepage = computed(() => route.name === 'index')
1111
1212
useHead({
1313
titleTemplate: titleChunk => {

app/components/AppHeader.vue

Lines changed: 75 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,24 @@ withDefaults(
1313
const { isConnected, npmUser } = useConnector()
1414
1515
const router = useRouter()
16+
const route = useRoute()
17+
18+
const searchQuery = ref('')
19+
const isSearchFocused = ref(false)
20+
21+
const showSearchBar = computed(() => {
22+
return route.name === 'search' || route.name === 'index'
23+
})
24+
25+
async function handleSearchInput() {
26+
const query = searchQuery.value.trim()
27+
await router.push({
28+
name: 'search',
29+
query: query ? { q: query } : undefined,
30+
})
31+
searchQuery.value = ''
32+
}
33+
1634
onKeyStroke(',', e => {
1735
// Don't trigger if user is typing in an input
1836
const target = e.target as HTMLElement
@@ -45,40 +63,66 @@ onKeyStroke(',', e => {
4563
<span v-else class="w-1" />
4664
</div>
4765

48-
<!-- Center: Main nav items -->
49-
<ul class="flex-1 flex items-center justify-center gap-4 sm:gap-6 list-none m-0 p-0">
50-
<li class="flex items-center">
51-
<NuxtLink
52-
to="/search"
53-
class="link-subtle font-mono text-sm inline-flex items-center gap-2"
54-
aria-keyshortcuts="/"
55-
>
56-
{{ $t('nav.search') }}
57-
<kbd
58-
class="hidden sm:inline-flex items-center justify-center w-5 h-5 text-xs bg-bg-muted border border-border rounded"
59-
aria-hidden="true"
60-
>
61-
/
62-
</kbd>
63-
</NuxtLink>
64-
</li>
65-
66-
<!-- Packages dropdown (when connected) -->
67-
<li v-if="isConnected && npmUser" class="flex items-center">
68-
<HeaderPackagesDropdown :username="npmUser" />
69-
</li>
70-
71-
<!-- Orgs dropdown (when connected) -->
72-
<li v-if="isConnected && npmUser" class="flex items-center">
73-
<HeaderOrgsDropdown :username="npmUser" />
74-
</li>
75-
</ul>
66+
<!-- Center: Search bar + nav items -->
67+
<div class="flex-1 flex items-center justify-center gap-4 sm:gap-6">
68+
<!-- Search bar (shown on all pages except home and search) -->
69+
<search v-if="showSearchBar" class="hidden sm:block flex-1 max-w-md">
70+
<form role="search" class="relative" @submit.prevent="handleSearchInput">
71+
<label for="header-search" class="sr-only">
72+
{{ $t('search.label') }}
73+
</label>
74+
75+
<div class="relative group" :class="{ 'is-focused': isSearchFocused }">
76+
<div class="search-box relative flex items-center">
77+
<span
78+
class="absolute left-3 text-fg-subtle font-mono text-sm pointer-events-none transition-colors duration-200 motion-reduce:transition-none group-focus-within:text-accent z-1"
79+
>
80+
/
81+
</span>
82+
83+
<input
84+
id="header-search"
85+
v-model="searchQuery"
86+
type="search"
87+
name="q"
88+
:placeholder="$t('search.placeholder')"
89+
v-bind="noCorrect"
90+
class="w-full bg-bg-subtle border border-border rounded-md pl-7 pr-3 py-1.5 font-mono text-sm text-fg placeholder:text-fg-subtle transition-border-color duration-300 motion-reduce:transition-none focus:border-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/50"
91+
autocomplete="off"
92+
@input="handleSearchInput"
93+
@focus="isSearchFocused = true"
94+
@blur="isSearchFocused = false"
95+
/>
96+
</div>
97+
</div>
98+
</form>
99+
</search>
100+
101+
<ul class="flex items-center gap-4 sm:gap-6 list-none m-0 p-0">
102+
<!-- Packages dropdown (when connected) -->
103+
<li v-if="isConnected && npmUser" class="flex items-center">
104+
<HeaderPackagesDropdown :username="npmUser" />
105+
</li>
106+
107+
<!-- Orgs dropdown (when connected) -->
108+
<li v-if="isConnected && npmUser" class="flex items-center">
109+
<HeaderOrgsDropdown :username="npmUser" />
110+
</li>
111+
</ul>
112+
</div>
76113

77114
<!-- Right: User status + GitHub -->
78-
<div class="flex-shrink-0 flex items-center gap-6">
115+
<div class="flex-shrink-0 flex items-center gap-4 sm:gap-6 ml-auto sm:ml-0">
116+
<NuxtLink
117+
to="/about"
118+
class="sm:hidden link-subtle font-mono text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/50 rounded"
119+
>
120+
{{ $t('footer.about') }}
121+
</NuxtLink>
122+
79123
<NuxtLink
80124
to="/settings"
81-
class="link-subtle font-mono text-sm inline-flex items-center gap-2"
125+
class="link-subtle font-mono text-sm inline-flex items-center gap-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/50 rounded"
82126
aria-keyshortcuts=","
83127
>
84128
{{ $t('nav.settings') }}
@@ -90,19 +134,9 @@ onKeyStroke(',', e => {
90134
</kbd>
91135
</NuxtLink>
92136

93-
<div v-if="showConnector">
137+
<div v-if="showConnector" class="hidden sm:block">
94138
<ConnectorStatus />
95139
</div>
96-
97-
<a
98-
href="https://github.com/npmx-dev/npmx.dev"
99-
target="_blank"
100-
rel="noopener noreferrer"
101-
class="link-subtle"
102-
:aria-label="$t('header.github')"
103-
>
104-
<span class="i-carbon-logo-github w-5 h-5" aria-hidden="true" />
105-
</a>
106140
</div>
107141
</nav>
108142
</header>

app/pages/settings.vue

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script setup lang="ts">
2+
const router = useRouter()
23
const { settings } = useSettings()
34
const { locale, locales, setLocale } = useI18n()
45
const colorMode = useColorMode()
@@ -7,13 +8,27 @@ const availableLocales = computed(() =>
78
locales.value.map(l => (typeof l === 'string' ? { code: l, name: l } : l)),
89
)
910
11+
function goBack() {
12+
router.back()
13+
}
14+
1015
useSeoMeta({
1116
title: 'Settings - npmx',
1217
})
1318
</script>
1419

1520
<template>
1621
<main class="container py-8 sm:py-12 w-full">
22+
<!-- Back button -->
23+
<button
24+
type="button"
25+
class="inline-flex items-center gap-2 mb-6 text-sm text-fg-muted hover:text-fg transition-colors duration-150 motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/50 rounded"
26+
@click="goBack"
27+
>
28+
<span class="i-carbon-arrow-left w-4 h-4" aria-hidden="true" />
29+
{{ $t('nav.back') }}
30+
</button>
31+
1732
<div class="space-y-1 p-4 rounded-lg bg-bg-muted border border-border">
1833
<button
1934
type="button"

i18n/locales/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
"nav": {
4141
"popular_packages": "Popular packages",
4242
"search": "search",
43-
"settings": "settings"
43+
"settings": "settings",
44+
"back": "Back"
4445
},
4546
"settings": {
4647
"relative_dates": "Relative dates",

i18n/locales/fr.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
"nav": {
4141
"popular_packages": "Paquets populaires",
4242
"search": "recherche",
43-
"settings": "paramètres"
43+
"settings": "paramètres",
44+
"back": "Retour"
4445
},
4546
"settings": {
4647
"relative_dates": "Dates relatives",

i18n/locales/it.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333
"nav": {
3434
"popular_packages": "Pacchetti popolari",
3535
"search": "cerca",
36-
"settings": "impostazioni"
36+
"settings": "impostazioni",
37+
"back": "Indietro"
3738
},
3839
"settings": {
3940
"relative_dates": "Date relative",

i18n/locales/zh-CN.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
"nav": {
4141
"popular_packages": "热门软件包",
4242
"search": "搜索",
43-
"settings": "设置"
43+
"settings": "设置",
44+
"back": "返回"
4445
},
4546
"settings": {
4647
"relative_dates": "相对时间",

0 commit comments

Comments
 (0)