[READ-ONLY] a fast, modern browser for the npm registry
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: `formatNumber` is now automatically using the locale now (#497)

authored by

jyc.dev and committed by
GitHub
27653f9c 96fd9c86

+18 -26
+9 -5
CONTRIBUTING.md
··· 369 369 370 370 The extension is included in our workspace recommendations, so VSCode should prompt you to install it. 371 371 372 - ### Formatting with locale 372 + ### Formatting numbers and dates 373 373 374 - When formatting numbers or dates that should respect the user's locale, pass the locale: 374 + Use vue-i18n's built-in formatters for locale-aware formatting: 375 375 376 - ```typescript 377 - const { locale } = useI18n() 378 - const formatted = formatNumber(12345, locale.value) // "12,345" in en-US 376 + ```vue 377 + <template> 378 + <p>{{ $n(12345) }}</p> 379 + <!-- "12,345" in en-US, "12 345" in fr-FR --> 380 + <p>{{ $d(new Date()) }}</p> 381 + <!-- locale-aware date --> 382 + </template> 379 383 ``` 380 384 381 385 ## Testing
+2 -2
app/components/PackageCard.vue
··· 123 123 <dt class="sr-only">{{ $t('package.card.weekly_downloads') }}</dt> 124 124 <dd class="flex items-center gap-1.5"> 125 125 <span class="i-carbon:chart-line w-3.5 h-3.5 inline-block" aria-hidden="true" /> 126 - <span class="font-mono">{{ formatNumber(result.downloads.weekly) }}/w</span> 126 + <span class="font-mono">{{ $n(result.downloads.weekly) }}/w</span> 127 127 </dd> 128 128 </div> 129 129 </dl> ··· 158 158 > 159 159 <span class="i-carbon:chart-line w-3.5 h-3.5 inline-block" aria-hidden="true" /> 160 160 <span class="font-mono text-xs"> 161 - {{ formatNumber(result.downloads.weekly) }} {{ $t('common.per_week') }} 161 + {{ $n(result.downloads.weekly) }} {{ $t('common.per_week') }} 162 162 </span> 163 163 </div> 164 164 </div>
+2 -3
app/pages/@[org].vue
··· 1 1 <script setup lang="ts"> 2 - import { formatNumber } from '#imports' 3 2 import type { FilterChip, SortOption } from '#shared/types/preferences' 4 3 import { debounce } from 'perfect-debounce' 5 4 ··· 157 156 <div> 158 157 <h1 class="font-mono text-2xl sm:text-3xl font-medium">@{{ orgName }}</h1> 159 158 <p v-if="status === 'success'" class="text-fg-muted text-sm mt-1"> 160 - {{ $t('org.public_packages', { count: formatNumber(packageCount) }, packageCount) }} 159 + {{ $t('org.public_packages', { count: $n(packageCount) }, packageCount) }} 161 160 </p> 162 161 </div> 163 162 ··· 181 180 > 182 181 <span class="i-carbon:chart-line w-3.5 h-3.5" aria-hidden="true" /> 183 182 <span class="font-mono" 184 - >{{ formatNumber(totalWeeklyDownloads) }} {{ $t('common.per_week') }}</span 183 + >{{ $n(totalWeeklyDownloads) }} {{ $t('common.per_week') }}</span 185 184 > 186 185 </p> 187 186 </div>
+1 -5
app/pages/[...package].vue
··· 258 258 return `${(bytes / (1024 * 1024)).toFixed(1)} MB` 259 259 } 260 260 261 - function formatNumber(num: number): string { 262 - return new Intl.NumberFormat('en-US').format(num) 263 - } 264 - 265 261 function getDependencyCount(version: PackumentVersion | null): number { 266 262 if (!version?.dependencies) return 0 267 263 return Object.keys(version.dependencies).length ··· 360 356 defineOgImageComponent('Package', { 361 357 name: () => pkg.value?.name ?? 'Package', 362 358 version: () => displayVersion.value?.version ?? '', 363 - downloads: () => (downloads.value ? formatNumber(downloads.value.downloads) : ''), 359 + downloads: () => (downloads.value ? $n(downloads.value.downloads) : ''), 364 360 license: () => pkg.value?.license ?? '', 365 361 primaryColor: '#60a5fa', 366 362 })
+1 -2
app/pages/search.vue
··· 1 1 <script setup lang="ts"> 2 - import { formatNumber } from '#imports' 3 2 import type { FilterChip, SortOption } from '#shared/types/preferences' 4 3 import { onKeyDown } from '@vueuse/core' 5 4 import { debounce } from 'perfect-debounce' ··· 783 782 {{ 784 783 $t( 785 784 'search.found_packages', 786 - { count: formatNumber(visibleResults.total) }, 785 + { count: $n(visibleResults.total) }, 787 786 visibleResults.total, 788 787 ) 789 788 }}
+2 -3
app/pages/~[username]/index.vue
··· 1 1 <script setup lang="ts"> 2 - import { formatNumber } from '#imports' 3 2 import { debounce } from 'perfect-debounce' 4 3 5 4 const route = useRoute('~username') ··· 192 191 <div> 193 192 <h1 class="font-mono text-2xl sm:text-3xl font-medium">~{{ username }}</h1> 194 193 <p v-if="results?.total" class="text-fg-muted text-sm mt-1"> 195 - {{ $t('org.public_packages', { count: formatNumber(results.total) }, results.total) }} 194 + {{ $t('org.public_packages', { count: $n(results.total) }, results.total) }} 196 195 </p> 197 196 </div> 198 197 ··· 216 215 > 217 216 <span class="i-carbon:chart-line w-3.5 h-3.5" aria-hidden="true" /> 218 217 <span class="font-mono" 219 - >{{ formatNumber(totalWeeklyDownloads) }} {{ $t('common.per_week') }}</span 218 + >{{ $n(totalWeeklyDownloads) }} {{ $t('common.per_week') }}</span 220 219 > 221 220 </p> 222 221 </div>
-6
app/utils/formatters.ts
··· 1 - /** @public */ 2 - export function formatNumber(num: number, _locale?: string): string { 3 - // TODO: Support different locales (needs care to ensure hydration works correctly) 4 - return new Intl.NumberFormat('en-US').format(num) 5 - } 6 - 7 1 /** @public */ 8 2 export function toIsoDateString(date: Date): string { 9 3 const year = date.getUTCFullYear()
+1
scripts/compare-translations.ts
··· 1 + /* eslint-disable no-console */ 1 2 import process from 'node:process' 2 3 import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs' 3 4 import { join } from 'node:path'