Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .storybook/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,68 @@ export const pdsUsersHandler = http.get('/api/atproto/pds-users', () => {
},
])
})

export const i18nStatusHandler = http.get('/lunaria/status.json', () => {
return HttpResponse.json({
generatedAt: '2026-01-22T10:07:07.000Z',
sourceLocale: {
lang: 'en',
label: 'English',
totalKeys: 500,
},
locales: [
{
lang: 'en-GB',
label: 'English (UK)',
dir: 'ltr',
totalKeys: 500,
completedKeys: 423,
percentComplete: 84,
missingKeys: [
'settings.background_themes.label',
'settings.enable_graph_pulse_loop',
'settings.enable_graph_pulse_loop_description',
'settings.data_source.algolia_description',
'settings.data_source.npm_description',
'i18n.contribute_hint',
'i18n.copy_keys',
],
githubEditUrl: 'https://github.com/npmx-dev/npmx.dev/edit/main/i18n/locales/en-GB.json',
githubHistoryUrl:
'https://github.com/npmx-dev/npmx.dev/commits/main/i18n/locales/en-GB.json',
},
{
lang: 'fr-FR',
label: 'Français',
dir: 'ltr',
totalKeys: 500,
completedKeys: 423,
percentComplete: 84,
missingKeys: [
'settings.background_themes.label',
'settings.enable_graph_pulse_loop',
'settings.enable_graph_pulse_loop_description',
'settings.data_source.algolia_description',
'settings.data_source.npm_description',
'i18n.contribute_hint',
'i18n.copy_keys',
],
githubEditUrl: 'https://github.com/npmx-dev/npmx.dev/edit/main/i18n/locales/fr-FR.json',
githubHistoryUrl:
'https://github.com/npmx-dev/npmx.dev/commits/main/i18n/locales/fr-FR.json',
},
{
lang: 'de-DE',
label: 'Deutsch',
dir: 'ltr',
totalKeys: 500,
completedKeys: 500,
percentComplete: 100,
missingKeys: [],
githubEditUrl: 'https://github.com/npmx-dev/npmx.dev/edit/main/i18n/locales/de-DE.json',
githubHistoryUrl:
'https://github.com/npmx-dev/npmx.dev/commits/main/i18n/locales/de-DE.json',
},
],
})
})
16 changes: 16 additions & 0 deletions .storybook/preview-head.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,19 @@
background-color: var(--bg, oklch(0.171 0 0)) !important;
}
</style>
<script>
// related: https://github.com/npmx-dev/npmx.dev/blob/1431d24be555bca5e1ae6264434d49ca15173c43/test/nuxt/setup.ts#L12-L26
// Stub Nuxt specific globals
// @nuxtjs/color-mode's plugin.client.js reads window[globalName] at module
// evaluation time — before any Storybook setup() callback runs — so the
// global must exist in the HTML head, not in preview.ts.
window.__NUXT_COLOR_MODE__ ??= {
preference: 'system',
value: 'dark',
getColorScheme: function () {
return 'dark'
},
addColorScheme: function () {},
removeColorScheme: function () {},
}
</script>
10 changes: 0 additions & 10 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,6 @@ import npmxDark from './theme'

initialize()

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

Expand Down
55 changes: 55 additions & 0 deletions app/pages/settings.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import Settings from './settings.vue'
import type { Meta, StoryObj } from '@storybook-vue/nuxt'
import { userEvent, expect } from 'storybook/test'
import { pageDecorator } from '../../.storybook/decorators'
import { i18nStatusHandler } from '../../.storybook/handlers'

const meta = {
component: Settings,
globals: {
locale: 'en-US',
},
beforeEach: () => localStorage.removeItem('npmx-settings'),
parameters: {
layout: 'fullscreen',
msw: {
handlers: [i18nStatusHandler],
},
},
decorators: [pageDecorator],
} satisfies Meta<typeof Settings>

export default meta
type Story = StoryObj<typeof meta>

/** English locale (default). The Language section shows a GitHub link to help translate the site. */
export const Default: Story = {}

export const NpmRegistryDataSource: Story = {
play: async ({ canvas, step }) => {
await step('Select npm registry as the data source', async () => {
const select = await canvas.findByRole('combobox', { name: /data source/i })
await userEvent.selectOptions(select, 'npm')
await expect(select).toHaveValue('npm')
})
},
}

/** Non-English locale with incomplete translations. The Language section shows `SettingsTranslationHelper` with a progress bar and list of missing translation keys. `/lunaria/status.json` is intercepted by MSW to provide mock translation status data. */
export const NonEnglishTranslationHelper: Story = {
globals: {
locale: 'fr-FR',
},
}

/** Non-English locale without translations API response. The Language section shows a GitHub link to help translate the site. */
export const WithoutTranslationHelper: Story = {
globals: {
locale: 'fr-FR',
},
parameters: {
msw: {
handlers: [],
},
},
}
3 changes: 2 additions & 1 deletion nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export default defineNuxtConfig({
'@vite-pwa/nuxt',
'@vueuse/nuxt',
'@nuxtjs/i18n',
...(isStorybook ? [] : ['@nuxt/fonts', '@nuxtjs/color-mode']),
'@nuxtjs/color-mode',
...(isStorybook ? [] : ['@nuxt/fonts']),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also have to load those in the preview-head file at the moment. So we have them, just not from @nuxt/fonts.

Would be great to not have any special carve outs for storybook in the nuxt config eventually.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

100%

],

$test: {
Expand Down
Loading