11<script setup lang="ts">
22import { LinkBase } from ' #components'
3- import type { NavigationConfig , NavigationConfigWithGroups } from ' ~/types'
4- import { NPMX_DOCS_SITE } from ' #shared/utils/constants'
53
6- const discord = useDiscordLink ()
74const { open : openCommandPalette } = useCommandPalette ()
85const { commandPaletteShortcutLabel } = usePlatformModifierKey ()
96
@@ -18,159 +15,16 @@ withDefaults(
1815
1916const { isConnected, npmUser } = useConnector ()
2017
21- const desktopLinks = computed <NavigationConfig >(() => [
22- {
23- name: ' Compare' ,
24- label: $t (' nav.compare' ),
25- to: { name: ' compare' },
26- keyshortcut: ' c' ,
27- type: ' link' ,
28- external: false ,
29- iconClass: ' i-lucide:git-compare' ,
30- },
31- {
32- name: ' Settings' ,
33- label: $t (' nav.settings' ),
34- to: { name: ' settings' },
35- keyshortcut: ' ,' ,
36- type: ' link' ,
37- external: false ,
38- iconClass: ' i-lucide:settings' ,
39- },
40- ])
41-
42- const mobileLinks = computed <NavigationConfigWithGroups >(() => [
43- {
44- name: ' Desktop Links' ,
45- type: ' group' ,
46- items: [... desktopLinks .value ],
47- },
48- {
49- type: ' separator' ,
50- },
51- {
52- name: ' About & Policies' ,
53- type: ' group' ,
54- items: [
55- {
56- name: ' About' ,
57- label: $t (' footer.about' ),
58- to: { name: ' about' },
59- type: ' link' ,
60- external: false ,
61- iconClass: ' i-lucide:info' ,
62- },
63- {
64- name: ' Blog' ,
65- label: $t (' footer.blog' ),
66- to: { name: ' blog' },
67- type: ' link' ,
68- external: false ,
69- iconClass: ' i-lucide:notebook-pen' ,
70- },
71- {
72- name: ' Privacy Policy' ,
73- label: $t (' privacy_policy.title' ),
74- to: { name: ' privacy' },
75- type: ' link' ,
76- external: false ,
77- iconClass: ' i-lucide:shield-check' ,
78- },
79- {
80- name: ' Accessibility' ,
81- label: $t (' a11y.title' ),
82- to: { name: ' accessibility' },
83- type: ' link' ,
84- external: false ,
85- iconClass: ' i-custom:a11y' ,
86- },
87- {
88- name: ' Translation Status' ,
89- label: $t (' translation_status.title' ),
90- to: { name: ' translation-status' },
91- type: ' link' ,
92- external: false ,
93- iconClass: ' i-lucide:languages' ,
94- },
95- {
96- name: ' Brand' ,
97- label: $t (' footer.brand' ),
98- to: { name: ' brand' },
99- type: ' link' ,
100- external: false ,
101- iconClass: ' i-lucide:palette' ,
102- },
103- ],
104- },
105- {
106- type: ' separator' ,
107- },
108- {
109- name: ' External Links' ,
110- type: ' group' ,
111- label: $t (' nav.links' ),
112- items: [
113- {
114- name: ' Docs' ,
115- label: $t (' footer.docs' ),
116- href: NPMX_DOCS_SITE ,
117- target: ' _blank' ,
118- type: ' link' ,
119- external: true ,
120- iconClass: ' i-lucide:file-text' ,
121- },
122- {
123- name: ' Source' ,
124- label: $t (' footer.source' ),
125- href: ' https://repo.npmx.dev' ,
126- target: ' _blank' ,
127- type: ' link' ,
128- external: true ,
129- iconClass: ' i-simple-icons:github' ,
130- },
131- {
132- name: ' Social' ,
133- label: $t (' footer.social' ),
134- href: ' https://social.npmx.dev' ,
135- target: ' _blank' ,
136- type: ' link' ,
137- external: true ,
138- iconClass: ' i-simple-icons:bluesky' ,
139- },
140- {
141- name: ' Chat' ,
142- label: discord .value .label ,
143- href: discord .value .url ,
144- target: ' _blank' ,
145- type: ' link' ,
146- external: true ,
147- iconClass: ' i-lucide:message-circle' ,
148- },
149- ],
150- },
151- ])
18+ const { desktopLinks } = useGlobalNavLinks ()
15219
15320const showFullSearch = shallowRef (false )
154- const showMobileMenu = shallowRef (false )
15521const { env, prNumber } = useAppConfig ().buildInfo
15622
157- // On mobile, clicking logo+search button expands search
15823const route = useRoute ()
159- const isMobile = useIsMobile ()
160- const isSearchExpandedManually = shallowRef (false )
16124const searchBoxRef = useTemplateRef (' searchBoxRef' )
16225
163- // On search page, always show search expanded on mobile
16426const isOnHomePage = computed (() => route .name === ' index' )
16527const isOnSearchPage = computed (() => route .name === ' search' )
166- const isSearchExpanded = computed (() => isOnSearchPage .value || isSearchExpandedManually .value )
167-
168- function expandMobileSearch() {
169- isSearchExpandedManually .value = true
170- nextTick (() => {
171- searchBoxRef .value ?.focus ()
172- })
173- }
17428
17529watch (
17630 isOnSearchPage ,
@@ -187,13 +41,6 @@ watch(
18741
18842function handleSearchBlur() {
18943 showFullSearch .value = false
190- // Collapse expanded search on mobile after blur (with delay for click handling)
191- // But don't collapse if we're on the search page
192- if (isMobile .value && ! isOnSearchPage .value ) {
193- setTimeout (() => {
194- isSearchExpandedManually .value = false
195- }, 150 )
196- }
19744}
19845
19946function handleSearchFocus() {
@@ -207,23 +54,12 @@ useShortcuts({
20754 </script >
20855
20956<template >
210- <header class =" sticky top-0 z-50 border-b border-border" >
57+ <header class =" hidden sm:block sticky top-0 z-50 border-b border-border" >
21158 <div class =" absolute inset-0 bg-bg/80 backdrop-blur-md" />
21259 <nav
21360 :aria-label =" $t('nav.main_navigation')"
21461 class =" relative container min-h-14 flex items-center gap-2 z-1 justify-end"
21562 >
216- <!-- Mobile: Logo (navigates home) -->
217- <LogoContextMenu v-if =" !isSearchExpanded && !isOnHomePage" class =" sm:hidden flex-shrink-0" >
218- <NuxtLink
219- to =" /"
220- :aria-label =" $t('header.home')"
221- class =" font-mono text-lg font-medium text-fg hover:text-fg transition-colors duration-200 focus-ring me-4"
222- >
223- <AppMark class =" w-6 h-auto" />
224- </NuxtLink >
225- </LogoContextMenu >
226-
22763 <!-- Desktop: Logo (navigates home) -->
22864 <LogoContextMenu v-if =" showLogo" class =" hidden sm:flex flex-shrink-0 items-center" >
22965 <NuxtLink
@@ -243,7 +79,7 @@ useShortcuts({
24379 </LogoContextMenu >
24480
24581 <NuxtLink
246- v-if =" showLogo && !isSearchExpanded && prNumber"
82+ v-if =" showLogo && prNumber"
24783 :to =" `https://github.com/npmx-dev/npmx.dev/pull/${prNumber}`"
24884 :aria-label =" $t('header.pr', { prNumber })"
24985 >
@@ -277,21 +113,19 @@ useShortcuts({
277113 <div
278114 class =" flex-1 flex items-center md:gap-6"
279115 :class =" {
280- 'hidden sm:flex': !isSearchExpanded,
281116 'justify-end': isOnHomePage,
282117 'justify-center': !isOnHomePage,
283118 }"
284119 >
285- <!-- Search bar (hidden on mobile unless expanded) -->
120+ <!-- Search bar -->
286121 <HeaderSearchBox
287122 ref =" searchBoxRef"
288- :inputClass =" isSearchExpanded ? 'w-full' : ''"
289- :class =" { 'max-w-md': !isSearchExpanded }"
123+ :class =" { 'max-w-md': !showFullSearch }"
290124 @focus =" handleSearchFocus"
291125 @blur =" handleSearchBlur"
292126 />
293127 <ul
294- v-if =" !isSearchExpanded && isConnected && npmUser"
128+ v-if =" isConnected && npmUser"
295129 :class =" { hidden: showFullSearch }"
296130 class =" hidden sm:flex items-center gap-4 sm:gap-6 list-none m-0 p-0"
297131 >
@@ -307,7 +141,7 @@ useShortcuts({
307141 </ul >
308142 </div >
309143
310- <!-- End: Desktop nav items + Mobile menu button -->
144+ <!-- End: Desktop nav items -->
311145 <div class =" hidden sm:flex flex-shrink-0 items-center gap-2" >
312146 <!-- Desktop: Explore link -->
313147 <LinkBase
@@ -323,30 +157,6 @@ useShortcuts({
323157
324158 <HeaderAccountMenu />
325159 </div >
326-
327- <!-- Mobile: Search button (expands search) -->
328- <ButtonBase
329- type =" button"
330- class =" sm:hidden ms-auto"
331- :aria-label =" $t('nav.tap_to_search')"
332- :aria-expanded =" showMobileMenu"
333- @click =" expandMobileSearch"
334- v-if =" !isSearchExpanded && !isOnHomePage"
335- classicon =" i-lucide:search"
336- />
337-
338- <!-- Mobile: Menu button (always visible, click to open menu) -->
339- <ButtonBase
340- type =" button"
341- class =" sm:hidden"
342- :aria-label =" $t('nav.open_menu')"
343- :aria-expanded =" showMobileMenu"
344- @click =" showMobileMenu = !showMobileMenu"
345- classicon =" i-lucide:menu"
346- />
347160 </nav >
348-
349- <!-- Mobile menu -->
350- <HeaderMobileMenu :links =" mobileLinks" v-model:open =" showMobileMenu" />
351161 </header >
352162</template >
0 commit comments