Skip to content
46 changes: 34 additions & 12 deletions app/pages/package/[[org]]/[name]/versions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ const groupDownloadsMap = computed(() => {
return map
})

function getDownloadsAriaLabel(downloads: number): string {
return `${numberFormatter.value.format(downloads)} ${t('package.downloads.title')}`
function getDownloadsAriaLabel(downloads: number, version: string): string {
return `${numberFormatter.value.format(downloads)} ${t('package.downloads.version_distribution_title', { version })}`
}

// ─── Phase 2: full metadata (fired automatically after phase 1 completes) ────
Expand Down Expand Up @@ -377,9 +377,19 @@ const flatItems = computed<FlatItem[]>(() => {
<span
v-if="getVersionDownloads(latestTagRow!.version)"
class="w-28 grid grid-flow-col auto-cols-max items-center gap-1 text-xs text-fg-muted tabular-nums justify-end"
:aria-label="getDownloadsAriaLabel(getVersionDownloads(latestTagRow!.version)!)"
:aria-label="
getDownloadsAriaLabel(
getVersionDownloads(latestTagRow!.version)!,
latestTagRow!.version,
)
"
dir="ltr"
:title="getDownloadsAriaLabel(getVersionDownloads(latestTagRow!.version)!)"
:title="
getDownloadsAriaLabel(
getVersionDownloads(latestTagRow!.version)!,
latestTagRow!.version,
)
"
>
<span>{{ numberFormatter.format(getVersionDownloads(latestTagRow!.version)!) }}</span>
<span class="i-lucide:chart-line" aria-hidden="true"></span>
Expand Down Expand Up @@ -446,9 +456,9 @@ const flatItems = computed<FlatItem[]>(() => {
<span
v-if="getVersionDownloads(row.version)"
class="w-28 grid grid-flow-col auto-cols-max items-center justify-end gap-1 text-xs text-fg-muted tabular-nums shrink-0 relative z-10"
:aria-label="getDownloadsAriaLabel(getVersionDownloads(row.version)!)"
:aria-label="getDownloadsAriaLabel(getVersionDownloads(row.version)!, row.version)"
dir="ltr"
:title="getDownloadsAriaLabel(getVersionDownloads(row.version)!)"
:title="getDownloadsAriaLabel(getVersionDownloads(row.version)!, row.version)"
>
<span>{{ numberFormatter.format(getVersionDownloads(row.version)!) }}</span>
<span class="i-lucide:chart-line" aria-hidden="true"></span>
Expand Down Expand Up @@ -536,9 +546,13 @@ const flatItems = computed<FlatItem[]>(() => {
<span
v-if="groupDownloadsMap.has(item.groupKey)"
class="ms-auto w-28 grid grid-flow-col auto-cols-max items-center justify-end gap-1 text-xs text-fg-muted tabular-nums shrink-0"
:aria-label="getDownloadsAriaLabel(groupDownloadsMap.get(item.groupKey)!)"
:aria-label="
getDownloadsAriaLabel(groupDownloadsMap.get(item.groupKey)!, item.label)
"
dir="ltr"
:title="getDownloadsAriaLabel(groupDownloadsMap.get(item.groupKey)!)"
:title="
getDownloadsAriaLabel(groupDownloadsMap.get(item.groupKey)!, item.label)
"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
>
<span>{{
numberFormatter.format(groupDownloadsMap.get(item.groupKey)!)
Expand Down Expand Up @@ -627,8 +641,12 @@ const flatItems = computed<FlatItem[]>(() => {
<span
v-if="getVersionDownloads(item.version)"
class="w-28 grid grid-flow-col auto-cols-max items-center justify-end gap-1 text-xs text-fg-muted tabular-nums shrink-0 relative z-10"
:aria-label="getDownloadsAriaLabel(getVersionDownloads(item.version)!)"
:title="getDownloadsAriaLabel(getVersionDownloads(item.version)!)"
:aria-label="
getDownloadsAriaLabel(getVersionDownloads(item.version)!, item.version)
"
:title="
getDownloadsAriaLabel(getVersionDownloads(item.version)!, item.version)
"
dir="ltr"
>
<span>{{
Expand Down Expand Up @@ -676,9 +694,13 @@ const flatItems = computed<FlatItem[]>(() => {
<span
v-if="groupDownloadsMap.has(item.groupKey)"
class="ms-auto w-28 grid grid-flow-col auto-cols-max items-center justify-end gap-1 text-xs text-fg-muted tabular-nums shrink-0"
:aria-label="getDownloadsAriaLabel(groupDownloadsMap.get(item.groupKey)!)"
:aria-label="
getDownloadsAriaLabel(groupDownloadsMap.get(item.groupKey)!, item.label)
"
dir="ltr"
:title="getDownloadsAriaLabel(groupDownloadsMap.get(item.groupKey)!)"
:title="
getDownloadsAriaLabel(groupDownloadsMap.get(item.groupKey)!, item.label)
"
>
<span>{{ numberFormatter.format(groupDownloadsMap.get(item.groupKey)!) }}</span>
<span class="i-lucide:chart-line" aria-hidden="true"></span>
Expand Down
17 changes: 16 additions & 1 deletion i18n/locales/cs-CZ.json
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@
"size": "Velikost instalace se zvýšila o {percent} (větší o {size})",
"deps": "{count} další závislostí"
},
"size_decrease": {},
"replacement": {
"title": "Možná tuto závislost nepotřebujete.",
"native": "Tento balíček lze nahradit {replacement}, dostupné od Node {nodeVersion}.",
Expand Down Expand Up @@ -557,6 +558,11 @@
"current_tags": "Aktuální značky",
"no_match_filter": "Žádné verze neodpovídají {filter}"
},
"timeline": {
"chart": {
"copy_alt": {}
}
},
"dependencies": {
"title": "Závislosti ({count})",
"list_label": "Závislosti balíčku",
Expand Down Expand Up @@ -759,6 +765,9 @@
"tarball": "Stáhnout Tarball jako .tar.gz"
}
},
"leaderboard": {
"likes": {}
},
"connector": {
"modal": {
"title": "Lokální konektor",
Expand Down Expand Up @@ -1236,6 +1245,9 @@
"packages_selected": "Vybrané balíčky: {count}/{max}.",
"add_hint": "Přidejte alespoň 2 balíčky ke srovnání."
},
"scatter_chart": {
"copy_alt": {}
},
"no_dependency": {
"label": "(Žádná závislost)",
"typeahead_title": "Co by udělal James?",
Expand Down Expand Up @@ -1314,7 +1326,10 @@
"vulnerabilities": {
"label": "Zranitelnosti",
"description": "Známé bezpečnostní zranitelnosti"
}
},
"githubStars": {},
"githubIssues": {},
"createdAt": {}
},
"values": {
"any": "Jakékoliv",
Expand Down
14 changes: 13 additions & 1 deletion i18n/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@
"size": "Installationsgröße um {percent} gestiegen ({size} größer)",
"deps": "{count} zusätzliche Abhängigkeiten"
},
"size_decrease": {},
"replacement": {
"title": "Du brauchst diese Abhängigkeit vielleicht nicht.",
"native": "Dies kann durch {replacement} ersetzt werden, verfügbar seit Node {nodeVersion}.",
Expand Down Expand Up @@ -556,6 +557,11 @@
"current_tags": "Aktuelle Tags",
"no_match_filter": "Keine Versionen entsprechen {filter}"
},
"timeline": {
"chart": {
"copy_alt": {}
}
},
"dependencies": {
"title": "Abhängigkeit ({count}) | Abhängigkeiten ({count})",
"list_label": "Paketabhängigkeiten",
Expand Down Expand Up @@ -758,6 +764,9 @@
"tarball": "Tarball als .tar.gz herunterladen"
}
},
"leaderboard": {
"likes": {}
},
"connector": {
"modal": {
"title": "Lokaler Connector",
Expand Down Expand Up @@ -1316,7 +1325,10 @@
"vulnerabilities": {
"label": "Sicherheitslücken",
"description": "Bekannte Sicherheitsrisiken"
}
},
"githubStars": {},
"githubIssues": {},
"createdAt": {}
},
"values": {
"any": "Beliebig",
Expand Down
33 changes: 17 additions & 16 deletions i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
},
"built_at": "built {0}",
"alt_logo": "npmx logo",
"tagline": "a fast, modern browser for the npm registry",
"non_affiliation_disclaimer": "not affiliated with npm, Inc.",
"tagline": "A fast, modern browser for the npm registry",
"non_affiliation_disclaimer": "Not affiliated with npm, Inc.",
"trademark_disclaimer": "npm is a registered trademark of npm, Inc. This site is not affiliated with npm, Inc.",
"footer": {
"about": "about",
Expand Down Expand Up @@ -50,15 +50,15 @@
},
"search": {
"label": "Search npm packages",
"placeholder": "search packages...",
"placeholder": "Search packages...",
"button": "search",
"searching": "Searching...",
"found_packages": "No packages found | Found 1 package | Found {count} packages",
"found_packages_sorted": "No results found | Sorting top {count} result | Sorting top {count} results",
"updating": "(updating...)",
"no_results": "No packages found for \"{query}\"",
"rate_limited": "Hit npm rate limit, try again in a moment",
"title": "search",
"title": "Search",
"title_search": "search: {search}",
"title_packages": "search packages",
"meta_description": "Search results for '{search}'",
Expand All @@ -84,14 +84,14 @@
"instant_search_advisory": "{label} {state} — {action}"
},
"command_palette": {
"title": "command palette",
"title": "Command palette",
"quick_actions": "jump to...",
"subtitle": "navigate across npmx and switch settings quickly",
"subtitle_languages": "choose a language or help improve translations",
"instructions": "Type to filter commands. Use the arrow keys to move through results and Enter to run a command.",
"input_label": "Command palette search",
"results_label": "Command results",
"placeholder": "type a command...",
"placeholder": "Type a command...",
"back": "Back",
"empty": "No matching commands",
"empty_search_hint": "Press Enter to search for \"{query}\".",
Expand Down Expand Up @@ -205,7 +205,7 @@
},
"blog": {
"title": "Blog",
"heading": "blog",
"heading": "Blog",
"meta_description": "Insights and updates from the npmx community",
"author": {
"view_profile": "View {name}'s profile on Bluesky"
Expand All @@ -230,8 +230,8 @@
}
},
"settings": {
"title": "settings",
"tagline": "customize your npmx experience",
"title": "Settings",
"tagline": "Customize your npmx experience",
"meta_description": "Customize your npmx.dev experience with theme, language, and display preferences.",
"sections": {
"appearance": "Appearance",
Expand Down Expand Up @@ -716,6 +716,7 @@
},
"downloads": {
"title": "Weekly Downloads",
"version_distribution_title": "weekly downloads for version {version}",
"community_distribution": "View community adoption distribution",
"subtitle": "Across all versions",
"sparkline_nav_hint": "Use ← →"
Expand Down Expand Up @@ -836,7 +837,7 @@
"copied": "Copied",
"paste_token": "Then paste the token below to connect:",
"token_label": "Token",
"token_placeholder": "paste token here...",
"token_placeholder": "Paste token here...",
"advanced": "Advanced options",
"port_label": "Port",
"warning": "WARNING",
Expand All @@ -852,7 +853,7 @@
"clear_all": "clear all",
"refresh": "Refresh operations",
"empty": "No operations queued",
"empty_hint": "Add operations from package or org pages",
"empty_hint": "Add operations from package or organization pages",
"active_label": "Active operations",
"otp_required": "OTP required",
"otp_prompt": "Enter OTP to continue",
Expand Down Expand Up @@ -953,7 +954,7 @@
"page": {
"packages_title": "Packages",
"no_packages": "No public packages found for",
"no_packages_hint": "This user may not exist or has no public packages.",
"no_packages_hint": "This user may not exist, or has no public packages.",
"failed_to_load": "Failed to load user packages",
"no_match": "No packages match \"{query}\"",
"filter_placeholder": "Filter {count} package... | Filter {count} packages..."
Expand Down Expand Up @@ -1151,7 +1152,7 @@
},
"about": {
"title": "About",
"heading": "about",
"heading": "About",
"meta_description": "npmx is a fast, modern browser for the npm registry. A great UX/DX for exploring npm packages.",
"what_we_are": {
"title": "What we are",
Expand Down Expand Up @@ -1502,7 +1503,7 @@
}
},
"privacy_policy": {
"title": "privacy policy",
"title": "Privacy policy",
"last_updated": "Last updated: {date}",
"welcome": "Welcome to {app}. We are committed to protecting your privacy. This policy explains what data we collect, how we use it, and your rights regarding your information.",
"cookies": {
Expand Down Expand Up @@ -1582,7 +1583,7 @@
}
},
"a11y": {
"title": "accessibility",
"title": "Accessibility",
"footer_title": "a11y",
"welcome": "We want {app} to be usable by as many people as possible.",
"approach": {
Expand Down Expand Up @@ -1612,7 +1613,7 @@
}
},
"translation_status": {
"title": "translation status",
"title": "Translation status",
"generated_at": "Generation date: {date}",
"welcome": "If you're interested in helping us to translate {npmx} into one of the languages listed below, you've come to the right place! This auto-updating page always lists all the content that could use your help right now.",
"p1": "We use {lang} as the default language, with a total of {count}. If you'd like to help add translations, locate the language in {bylang} and expand the details.",
Expand Down
34 changes: 33 additions & 1 deletion i18n/locales/id-ID.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,23 @@
"instant_search_turn_off": "nonaktifkan",
"instant_search_advisory": "{label} {state} — {action}"
},
"command_palette": {
"state": {},
"groups": {},
"actions": {},
"connections": {},
"navigation": {},
"links": {},
"package_links": {},
"theme": {},
"package": {},
"package_actions": {},
"code": {},
"diff": {},
"version": {},
"status": {},
"announcements": {}
},
"nav": {
"main_navigation": "Utama",
"popular_packages": "Paket populer",
Expand Down Expand Up @@ -265,6 +282,7 @@
"size": "Ukuran instalasi meningkat sebesar {percent} ({size} lebih besar)",
"deps": "{count} lebih banyak dependensi"
},
"size_decrease": {},
"replacement": {
"title": "Mungkin Anda tidak butuh dependensi ini.",
"native": "Paket ini dapat diganti dengan {replacement}, tersedia sejak Node {nodeVersion}.",
Expand Down Expand Up @@ -442,6 +460,11 @@
"current_tags": "Tag Saat Ini",
"no_match_filter": "Tidak ada versi yang cocok dengan {filter}"
},
"timeline": {
"chart": {
"copy_alt": {}
}
},
"dependencies": {
"title": "Dependensi ({count})",
"list_label": "Dependensi paket",
Expand Down Expand Up @@ -644,6 +667,9 @@
"tarball": "Unduh Tarball sebagai .tar.gz"
}
},
"leaderboard": {
"likes": {}
},
"connector": {
"modal": {
"title": "Konektor Lokal",
Expand Down Expand Up @@ -1117,6 +1143,9 @@
"packages_selected": "{count}/{max} paket dipilih.",
"add_hint": "Tambah setidaknya 2 paket untuk dibandingkan."
},
"scatter_chart": {
"copy_alt": {}
},
"no_dependency": {
"label": "(Tanpa Ketergantungan)",
"typeahead_title": "Apa yang Akan Anda Lakukan?",
Expand Down Expand Up @@ -1195,7 +1224,10 @@
"vulnerabilities": {
"label": "Kerentanan",
"description": "Kerentanan keamanan yang diketahui"
}
},
"githubStars": {},
"githubIssues": {},
"createdAt": {}
},
"values": {
"any": "Apa saja",
Expand Down
Loading
Loading