Skip to content

Commit 8707d17

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/201
2 parents 3c54fb7 + 92c7a85 commit 8707d17

18 files changed

Lines changed: 1635 additions & 56 deletions

CONTRIBUTING.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ The connector will check your npm authentication, generate a connection token, a
105105

106106
## Code style
107107

108+
When committing changes, try to keep an eye out for unintended formatting updates. These can make a pull request look noisier than it really is and slow down the review process. Sometimes IDEs automatically reformat files on save, which can unintentionally introduce extra changes.
109+
110+
To help with this, the project uses `oxfmt` to handle formatting via a pre-commit hook. The hook will automatically reformat files when needed. If something can’t be fixed automatically, it will let you know what needs to be updated before you can commit.
111+
112+
If you want to get ahead of any formatting issues, you can also run `pnpm lint:fix` before committing to fix formatting across the whole project.
113+
108114
### Typescript
109115

110116
- We care about good types – never cast things to `any` 💪

app/components/AppHeader.vue

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,19 @@ function expandMobileSearch() {
3030
})
3131
}
3232
33+
watch(
34+
isOnSearchPage,
35+
visible => {
36+
if (!visible) return
37+
38+
searchBoxRef.value?.focus()
39+
nextTick(() => {
40+
searchBoxRef.value?.focus()
41+
})
42+
},
43+
{ flush: 'sync' },
44+
)
45+
3346
function handleSearchBlur() {
3447
showFullSearch.value = false
3548
// Collapse expanded search on mobile after blur (with delay for click handling)

app/components/PackageSkeleton.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@
150150
</div>
151151

152152
<!-- Sidebar: order-1 lg:order-2 space-y-8 -->
153-
<aside class="order-1 lg:order-2 space-y-8">
153+
<div class="order-1 lg:order-2 space-y-8">
154154
<!-- Maintainers -->
155155
<section>
156156
<h2
@@ -249,7 +249,7 @@
249249
</li>
250250
</ul>
251251
</section>
252-
</aside>
252+
</div>
253253
</div>
254254
</article>
255255
</template>

app/components/SearchBox.vue

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
<script setup lang="ts">
22
import { debounce } from 'perfect-debounce'
33
4-
const isMobile = useIsMobile()
5-
64
withDefaults(
75
defineProps<{
86
inputClass?: string
@@ -107,7 +105,6 @@ defineExpose({ focus })
107105
<input
108106
id="header-search"
109107
ref="inputRef"
110-
:autofocus="!isMobile"
111108
v-model="searchQuery"
112109
type="search"
113110
name="q"

app/pages/[...package].vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ function handleClick(event: MouseEvent) {
936936
</a>
937937
</h2>
938938
<!-- eslint-disable vue/no-v-html -- HTML is sanitized server-side -->
939-
<div
939+
<article
940940
v-if="readmeData?.html"
941941
class="readme-content prose prose-invert max-w-[70ch]"
942942
v-html="readmeData.html"
@@ -952,7 +952,7 @@ function handleClick(event: MouseEvent) {
952952

953953
<div class="area-sidebar">
954954
<!-- Sidebar -->
955-
<aside class="sticky top-20 space-y-6 sm:space-y-8 min-w-0 overflow-hidden">
955+
<div class="sticky top-20 space-y-6 sm:space-y-8 min-w-0 overflow-hidden">
956956
<!-- Maintainers (with admin actions when connected) -->
957957
<PackageMaintainers :package-name="pkg.name" :maintainers="pkg.maintainers" />
958958

@@ -1060,7 +1060,7 @@ function handleClick(event: MouseEvent) {
10601060
:peer-dependencies-meta="displayVersion.peerDependenciesMeta"
10611061
:optional-dependencies="displayVersion.optionalDependencies"
10621062
/>
1063-
</aside>
1063+
</div>
10641064
</div>
10651065
</article>
10661066

app/pages/index.vue

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
<script setup lang="ts">
22
import { debounce } from 'perfect-debounce'
33
4-
const router = useRouter()
54
const searchQuery = shallowRef('')
65
const searchInputRef = useTemplateRef('searchInputRef')
76
const { focused: isSearchFocused } = useFocus(searchInputRef)
87
9-
const isMobile = useIsMobile()
10-
11-
const debouncedNavigate = debounce(() => {
12-
router.push({
8+
async function search() {
9+
const query = searchQuery.value.trim()
10+
await navigateTo({
1311
path: '/search',
14-
query: searchQuery.value.trim() ? { q: searchQuery.value.trim() } : undefined,
12+
query: query ? { q: query } : undefined,
1513
})
16-
}, 250)
17-
18-
function handleSearch() {
19-
// If input is empty, navigate immediately (no need to debounce)
20-
return searchQuery.value.trim() ? debouncedNavigate() : router.push('/search')
14+
const newQuery = searchQuery.value.trim()
15+
if (newQuery !== query) {
16+
await search()
17+
}
2118
}
2219
20+
const handleInput = isTouchDevice()
21+
? search
22+
: debounce(search, 250, { leading: true, trailing: true })
23+
2324
useSeoMeta({
2425
title: () => $t('seo.home.title'),
2526
description: () => $t('seo.home.description'),
@@ -64,7 +65,7 @@ defineOgImageComponent('Default', {
6465
class="w-full max-w-xl motion-safe:animate-slide-up motion-safe:animate-fill-both"
6566
style="animation-delay: 0.2s"
6667
>
67-
<form method="GET" action="/search" class="relative" @submit.prevent="handleSearch">
68+
<form method="GET" action="/search" class="relative" @submit.prevent.trim="search">
6869
<label for="home-search" class="sr-only">
6970
{{ $t('search.label') }}
7071
</label>
@@ -89,11 +90,11 @@ defineOgImageComponent('Default', {
8990
v-model="searchQuery"
9091
type="search"
9192
name="q"
93+
autofocus
9294
:placeholder="$t('search.placeholder')"
9395
v-bind="noCorrect"
94-
:autofocus="!isMobile"
9596
class="w-full bg-bg-subtle border border-border rounded-lg ps-8 pe-24 py-4 font-mono text-base text-fg placeholder:text-fg-subtle transition-border-color duration-300 focus:border-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/50"
96-
@input="handleSearch"
97+
@input="handleInput"
9798
/>
9899

99100
<button

app/utils/responsive.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/** @public */
2+
export function isTouchDevice() {
3+
if (import.meta.server) {
4+
return false
5+
}
6+
return 'ontouchstart' in window || navigator.maxTouchPoints > 0
7+
}

config/i18n.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,15 @@ const locales: (LocaleObjectData | (Omit<LocaleObjectData, 'code'> & { code: str
134134
file: 'de-DE.json',
135135
name: 'Deutsch',
136136
},
137-
/*{
138-
code: 'hu-HU',
139-
file: 'hu-HU.json',
140-
name: 'Magyar',
141-
},*/
137+
{
138+
code: 'hu-HU',
139+
file: 'hu-HU.json',
140+
name: 'Magyar',
141+
pluralRule: (choice: number) => {
142+
const name = new Intl.PluralRules('hu-HU').select(choice)
143+
return { zero: 0, one: 0, two: 1, few: 1, many: 1, other: 1 }[name]
144+
},
145+
},
142146
{
143147
code: 'zh-CN',
144148
file: 'zh-CN.json',

i18n/locales/de-DE.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
"description": "Ein besserer Browser für die npm Registry. Pakete suchen, durchstöbern und erkunden mit einer modernen Oberfläche."
66
}
77
},
8+
"version": "Version",
9+
"built_at": "gebaut",
10+
"alt_logo": "npmx Logo",
811
"tagline": "ein besserer Browser für die npm Registry",
912
"non_affiliation_disclaimer": "nicht verbunden mit npm, Inc.",
1013
"trademark_disclaimer": "npm ist eine eingetragene Marke von npm, Inc. Diese Seite ist nicht mit npm, Inc. verbunden.",
@@ -111,6 +114,7 @@
111114
"not_latest": "(nicht aktuell)",
112115
"verified_provenance": "Verifizierte Herkunft",
113116
"view_permalink": "Permalink für diese Version anzeigen",
117+
"copy_name": "Paketnamen kopieren",
114118
"deprecation": {
115119
"package": "Dieses Paket ist veraltet.",
116120
"version": "Diese Version ist veraltet.",
@@ -559,7 +563,8 @@
559563
"markdown_view_mode": {
560564
"preview": "Vorschau",
561565
"code": "Code"
562-
}
566+
},
567+
"file_path": "Dateipfade"
563568
},
564569
"badges": {
565570
"provenance": {

i18n/locales/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,8 @@
571571
"markdown_view_mode": {
572572
"preview": "preview",
573573
"code": "code"
574-
}
574+
},
575+
"file_path": "File path"
575576
},
576577
"badges": {
577578
"provenance": {

0 commit comments

Comments
 (0)