Skip to content

Commit 757b0d1

Browse files
committed
Merge branch 'main' into feat/changelog-1
2 parents 2076078 + 791ce70 commit 757b0d1

File tree

35 files changed

+1777
-74
lines changed

35 files changed

+1777
-74
lines changed

.github/ISSUE_TEMPLATE/bug-report.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
name: "\U0001F41E Bug report"
22
description: Create a report to help us improve npmx
3+
type: bug
4+
labels: ['pending triage']
35
body:
46
- type: markdown
57
attributes:

.github/ISSUE_TEMPLATE/feature-request.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
name: '🚀 Feature request'
22
description: Suggest a feature that will improve npmx
3+
type: feature
34
labels: ['pending triage']
45
body:
56
- type: markdown

.storybook/handlers.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,102 @@ export const contributorsHandler = http.get('/api/contributors', () => {
5757
},
5858
])
5959
})
60+
61+
export const pdsUsersHandler = http.get('/api/atproto/pds-users', () => {
62+
return HttpResponse.json([
63+
{
64+
did: 'did:plc:mock0001',
65+
handle: 'patak.dog',
66+
displayName: 'Patak Dog',
67+
avatar:
68+
'https://cdn.bsky.app/img/avatar/plain/did:plc:zjfptjaegvgc7r2axkkyyzqn/bafkreihrcqhp575f6dph4uztbeyxfrmfnbv7x2gvovrgu4idgdsdw7wety',
69+
},
70+
{
71+
did: 'did:plc:mock0002',
72+
handle: 'patakllama.mockpmx.social',
73+
displayName: 'Patak Llama',
74+
avatar: 'https://api.dicebear.com/9.x/initials/svg?seed=llama',
75+
},
76+
{
77+
did: 'did:plc:mock0003',
78+
handle: 'patak.horse',
79+
displayName: 'Patak Horse',
80+
avatar:
81+
'https://cdn.bsky.app/img/avatar/plain/did:plc:vqh7id7sddkrfkhgt7tstlpd/bafkreifodkgqszgpt2qnoyljnbafokr6eujqwztj2kxo473adv5b57hjse',
82+
},
83+
{
84+
did: 'did:plc:mock0004',
85+
handle: 'patakcatapiller.mockpmx.social',
86+
},
87+
{
88+
did: 'did:plc:mock0005',
89+
handle: 'patakgoat.mockpmx.social',
90+
displayName: 'Patak Goat',
91+
},
92+
])
93+
})
94+
95+
export const i18nStatusHandler = http.get('/lunaria/status.json', () => {
96+
return HttpResponse.json({
97+
generatedAt: '2026-01-22T10:07:07.000Z',
98+
sourceLocale: {
99+
lang: 'en',
100+
label: 'English',
101+
totalKeys: 500,
102+
},
103+
locales: [
104+
{
105+
lang: 'en-GB',
106+
label: 'English (UK)',
107+
dir: 'ltr',
108+
totalKeys: 500,
109+
completedKeys: 423,
110+
percentComplete: 84,
111+
missingKeys: [
112+
'settings.background_themes.label',
113+
'settings.enable_graph_pulse_loop',
114+
'settings.enable_graph_pulse_loop_description',
115+
'settings.data_source.algolia_description',
116+
'settings.data_source.npm_description',
117+
'i18n.contribute_hint',
118+
'i18n.copy_keys',
119+
],
120+
githubEditUrl: 'https://github.com/npmx-dev/npmx.dev/edit/main/i18n/locales/en-GB.json',
121+
githubHistoryUrl:
122+
'https://github.com/npmx-dev/npmx.dev/commits/main/i18n/locales/en-GB.json',
123+
},
124+
{
125+
lang: 'fr-FR',
126+
label: 'Français',
127+
dir: 'ltr',
128+
totalKeys: 500,
129+
completedKeys: 423,
130+
percentComplete: 84,
131+
missingKeys: [
132+
'settings.background_themes.label',
133+
'settings.enable_graph_pulse_loop',
134+
'settings.enable_graph_pulse_loop_description',
135+
'settings.data_source.algolia_description',
136+
'settings.data_source.npm_description',
137+
'i18n.contribute_hint',
138+
'i18n.copy_keys',
139+
],
140+
githubEditUrl: 'https://github.com/npmx-dev/npmx.dev/edit/main/i18n/locales/fr-FR.json',
141+
githubHistoryUrl:
142+
'https://github.com/npmx-dev/npmx.dev/commits/main/i18n/locales/fr-FR.json',
143+
},
144+
{
145+
lang: 'de-DE',
146+
label: 'Deutsch',
147+
dir: 'ltr',
148+
totalKeys: 500,
149+
completedKeys: 500,
150+
percentComplete: 100,
151+
missingKeys: [],
152+
githubEditUrl: 'https://github.com/npmx-dev/npmx.dev/edit/main/i18n/locales/de-DE.json',
153+
githubHistoryUrl:
154+
'https://github.com/npmx-dev/npmx.dev/commits/main/i18n/locales/de-DE.json',
155+
},
156+
],
157+
})
158+
})

.storybook/preview-head.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,19 @@
6161
background-color: var(--bg, oklch(0.171 0 0)) !important;
6262
}
6363
</style>
64+
<script>
65+
// related: https://github.com/npmx-dev/npmx.dev/blob/1431d24be555bca5e1ae6264434d49ca15173c43/test/nuxt/setup.ts#L12-L26
66+
// Stub Nuxt specific globals
67+
// @nuxtjs/color-mode's plugin.client.js reads window[globalName] at module
68+
// evaluation time — before any Storybook setup() callback runs — so the
69+
// global must exist in the HTML head, not in preview.ts.
70+
window.__NUXT_COLOR_MODE__ ??= {
71+
preference: 'system',
72+
value: 'dark',
73+
getColorScheme: function () {
74+
return 'dark'
75+
},
76+
addColorScheme: function () {},
77+
removeColorScheme: function () {},
78+
}
79+
</script>

.storybook/preview.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,6 @@ import npmxDark from './theme'
1010

1111
initialize()
1212

13-
// related: https://github.com/npmx-dev/npmx.dev/blob/1431d24be555bca5e1ae6264434d49ca15173c43/test/nuxt/setup.ts#L12-L26
14-
// Stub Nuxt specific globals
15-
// @ts-expect-error - dynamic global name
16-
globalThis['__NUXT_COLOR_MODE__'] ??= {
17-
preference: 'system',
18-
value: 'dark',
19-
getColorScheme: fn(() => 'dark'),
20-
addColorScheme: fn(),
21-
removeColorScheme: fn(),
22-
}
2313
// @ts-expect-error - dynamic global name
2414
globalThis.defineOgImageComponent = fn()
2515

app/components/AppFooter.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ const closeModal = () => modalRef.value?.close?.()
120120
<kbd class="kbd">f</kbd>
121121
<span>{{ $t('shortcuts.open_diff') }}</span>
122122
</li>
123+
<li class="flex gap-2 items-center">
124+
<kbd class="kbd">t</kbd>
125+
<span>{{ $t('shortcuts.open_timeline') }}</span>
126+
</li>
123127
<li class="flex gap-2 items-center">
124128
<kbd class="kbd">c</kbd>
125129
<span>{{ $t('shortcuts.compare_from_package') }}</span>

app/components/Chart/SplitSparkline.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ const props = defineProps<{
3131
3232
const { locale } = useI18n()
3333
const colorMode = useColorMode()
34+
const numberFormatter = useNumberFormatter({
35+
maximumFractionDigits: 0,
36+
})
3437
const resolvedMode = shallowRef<'light' | 'dark'>('light')
3538
const rootEl = shallowRef<HTMLElement | null>(null)
3639
const palette = getPalette('')
@@ -153,6 +156,9 @@ const configs = computed(() => {
153156
fontSize: 24,
154157
bold: false,
155158
color: colors.value.fg,
159+
formatter: ({ value }) => {
160+
return numberFormatter.value.format(value)
161+
},
156162
datetimeFormatter: {
157163
enable: true,
158164
locale: locale.value,

app/components/Package/Header.vue

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const props = defineProps<{
1111
latestVersion?: SlimVersion | null
1212
provenanceData?: ProvenanceDetails | null
1313
provenanceStatus?: string | null
14-
page: 'main' | 'docs' | 'code' | 'diff' | 'changelog'
14+
page: 'main' | 'docs' | 'code' | 'diff' | 'changelog' | 'timeline'
1515
versionUrlPattern: string
1616
}>()
1717
@@ -177,13 +177,27 @@ const changelogLink = computed((): RouteLocationRaw | null => {
177177
return changelogRoute(props.pkg.name, props.resolvedVersion)
178178
})
179179
180+
const timelineLink = computed((): RouteLocationRaw | null => {
181+
if (props.pkg == null || props.resolvedVersion == null) return null
182+
const split = props.pkg.name.split('/')
183+
return {
184+
name: 'timeline',
185+
params: {
186+
org: split.length === 2 ? split[0] : undefined,
187+
packageName: split.length === 2 ? split[1]! : split[0]!,
188+
version: props.resolvedVersion,
189+
},
190+
}
191+
})
192+
180193
useShortcuts({
181194
'.': () => codeLink.value,
182195
'm': () => mainLink.value,
183196
'd': () => docsLink.value,
184197
'c': () => props.pkg && { name: 'compare' as const, query: { packages: props.pkg.name } },
185198
'f': () => diffLink.value,
186199
'-': () => changelogLink.value,
200+
't': () => timelineLink.value,
187201
})
188202
</script>
189203

@@ -355,6 +369,15 @@ useShortcuts({
355369
>
356370
{{ $t('package.links.changelog') }}
357371
</LinkBase>
372+
<LinkBase
373+
v-if="timelineLink"
374+
:to="timelineLink"
375+
aria-keyshortcuts="t"
376+
class="decoration-none border-b-2 p-1 hover:border-accent/50 focus-visible:[outline-offset:-2px]!"
377+
:class="page === 'timeline' ? 'border-accent text-accent!' : 'border-transparent'"
378+
>
379+
{{ $t('package.links.timeline') }}
380+
</LinkBase>
358381
</nav>
359382
</div>
360383
</div>

app/components/Package/TrendsChart.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1540,7 +1540,7 @@ const chartConfig = computed<VueUiXyConfig>(() => {
15401540
const rows = items
15411541
.map((d: Record<string, any>) => {
15421542
const label = String(d?.name ?? '').trim()
1543-
const raw = Number(d?.value ?? 0)
1543+
const raw = Math.round(Number(d?.value ?? 0))
15441544
const v = compactNumberFormatter.value.format(Number.isFinite(raw) ? raw : 0)
15451545
15461546
if (!hasMultipleItems) {

app/components/Package/WeeklyDownloadStats.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ function handleModalTransitioned() {
6060
}
6161
6262
const { fetchPackageDownloadEvolution } = useCharts()
63+
const numberFormatter = useNumberFormatter({
64+
maximumFractionDigits: 0,
65+
})
6366
6467
const { accentColors, selectedAccentColor } = useAccentColor()
6568
@@ -359,6 +362,9 @@ const config = computed<VueUiSparklineConfig>(() => {
359362
fontSize: 28,
360363
bold: false,
361364
color: colors.value.fg,
365+
formatter: ({ value }) => {
366+
return numberFormatter.value.format(value)
367+
},
362368
},
363369
line: {
364370
color: colors.value.borderHover,

0 commit comments

Comments
 (0)