diff --git a/app/app.vue b/app/app.vue index b8582a1719..3a860a9c9b 100644 --- a/app/app.vue +++ b/app/app.vue @@ -7,7 +7,7 @@ const router = useRouter() // Initialize accent color before hydration to prevent flash initAccentOnPrehydrate() -const isHomepage = computed(() => route.path === '/') +const isHomepage = computed(() => route.name === 'index') useHead({ titleTemplate: titleChunk => { diff --git a/app/components/AppHeader.vue b/app/components/AppHeader.vue index 332cdda933..1a0800b563 100644 --- a/app/components/AppHeader.vue +++ b/app/components/AppHeader.vue @@ -13,6 +13,24 @@ withDefaults( const { isConnected, npmUser } = useConnector() const router = useRouter() +const route = useRoute() + +const searchQuery = ref('') +const isSearchFocused = ref(false) + +const showSearchBar = computed(() => { + return route.name !== 'search' && route.name !== 'index' +}) + +async function handleSearchInput() { + const query = searchQuery.value.trim() + await router.push({ + name: 'search', + query: query ? { q: query } : undefined, + }) + searchQuery.value = '' +} + onKeyStroke(',', e => { // Don't trigger if user is typing in an input const target = e.target as HTMLElement @@ -45,40 +63,73 @@ onKeyStroke(',', e => { - - + + +
+ +
+ + + + + -
+
+ + {{ $t('footer.about') }} + + {{ $t('nav.settings') }} @@ -90,19 +141,9 @@ onKeyStroke(',', e => { -
+ - - -
diff --git a/app/components/PackageList.vue b/app/components/PackageList.vue index c697ba789d..4a5c221dd1 100644 --- a/app/components/PackageList.vue +++ b/app/components/PackageList.vue @@ -3,6 +3,9 @@ import type { NpmSearchResult } from '#shared/types' import type { WindowVirtualizerHandle } from '~/composables/useVirtualInfiniteScroll' import { WindowVirtualizer } from 'virtua/vue' +/** Number of items to render statically during SSR */ +const SSR_COUNT = 20 + const props = defineProps<{ /** List of search results to display */ results: NpmSearchResult[] @@ -96,31 +99,52 @@ defineExpose({