Skip to content

Commit c1f5529

Browse files
committed
docs(ui): use storybook-i18n addon for locale switching
1 parent 5d8fcf5 commit c1f5529

File tree

6 files changed

+72
-30
lines changed

6 files changed

+72
-30
lines changed

.storybook/main.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import type { StorybookConfig } from '@storybook-vue/nuxt'
22

33
const config = {
44
stories: ['../app/**/*.stories.@(js|ts)'],
5-
addons: ['@storybook/addon-a11y', '@storybook/addon-docs', '@storybook/addon-themes'],
5+
addons: [
6+
'@storybook/addon-a11y',
7+
'@storybook/addon-docs',
8+
'@storybook/addon-themes',
9+
'storybook-i18n',
10+
],
611
framework: '@storybook-vue/nuxt',
712
staticDirs: ['./.public'],
813
features: {

.storybook/preview.ts

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Preview } from '@storybook-vue/nuxt'
22
import { withThemeByDataAttribute } from '@storybook/addon-themes'
3+
import { addons } from 'storybook/preview-api'
34
import { currentLocales } from '../config/i18n'
45
import { fn } from 'storybook/test'
56
import { ACCENT_COLORS } from '../shared/utils/constants'
@@ -17,6 +18,14 @@ globalThis['__NUXT_COLOR_MODE__'] ??= {
1718
// @ts-expect-error - dynamic global name
1819
globalThis.defineOgImageComponent = fn()
1920

21+
// Subscribe to locale changes from storybook-i18n addon (once, outside decorator)
22+
let currentI18nInstance: any = null
23+
addons.getChannel().on('LOCALE_CHANGED', (newLocale: string) => {
24+
if (currentI18nInstance) {
25+
currentI18nInstance.setLocale(newLocale)
26+
}
27+
})
28+
2029
const preview: Preview = {
2130
parameters: {
2231
controls: {
@@ -26,24 +35,18 @@ const preview: Preview = {
2635
},
2736
},
2837
},
38+
initialGlobals: {
39+
locale: 'en-US',
40+
locales: currentLocales.reduce(
41+
(acc, locale) => {
42+
acc[locale.code] = locale.name
43+
return acc
44+
},
45+
{} as Record<string, string>,
46+
),
47+
},
2948
// Provides toolbars to switch things like theming and language
3049
globalTypes: {
31-
locale: {
32-
name: 'Locale',
33-
description: 'UI language',
34-
defaultValue: 'en-US',
35-
toolbar: {
36-
icon: 'globe',
37-
dynamicTitle: true,
38-
items: [
39-
// English is at the top so it's easier to reset to it
40-
{ value: 'en-US', title: 'English (US)' },
41-
...currentLocales
42-
.filter(locale => locale.code !== 'en-US')
43-
.map(locale => ({ value: locale.code, title: locale.name })),
44-
],
45-
},
46-
},
4750
accentColor: {
4851
name: 'Accent Color',
4952
description: 'Accent color',
@@ -70,9 +73,9 @@ const preview: Preview = {
7073
attributeName: 'data-theme',
7174
}),
7275
(story, context) => {
73-
const { locale, accentColor } = context.globals as {
74-
locale: string
76+
const { accentColor, locale } = context.globals as {
7577
accentColor?: string
78+
locale?: string
7679
}
7780

7881
// Set accent color from globals
@@ -84,14 +87,12 @@ const preview: Preview = {
8487

8588
return {
8689
template: '<story />',
87-
// Set locale from globals
8890
created() {
89-
if (this.$i18n) {
90-
this.$i18n.setLocale(locale)
91-
}
92-
},
93-
updated() {
94-
if (this.$i18n) {
91+
// Store i18n instance for LOCALE_CHANGED events
92+
currentI18nInstance = this.$i18n
93+
94+
// Set initial locale when component is created
95+
if (locale && this.$i18n) {
9596
this.$i18n.setLocale(locale)
9697
}
9798
},

app/components/Link/Link.stories.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@ const meta = {
55
component: LinkBase,
66
args: {
77
to: '/',
8-
default: 'Click me',
98
},
109
} satisfies Meta<typeof LinkBase>
1110

1211
export default meta
1312
type Story = StoryObj<typeof meta>
1413

15-
export const Default: Story = {}
14+
export const Default: Story = {
15+
args: {
16+
default: 'Click me',
17+
},
18+
}
1619

1720
export const ExternalLink: Story = {
1821
args: {
@@ -75,16 +78,28 @@ export const WithIconButton: Story = {
7578
args: {
7679
variant: 'button-primary',
7780
classicon: 'i-lucide:copy',
78-
default: 'Copy',
7981
},
82+
render: args => ({
83+
components: { LinkBase },
84+
setup() {
85+
return { args }
86+
},
87+
template: `<LinkBase v-bind="args">{{ $t("package.readme.copy_as_markdown") }}</LinkBase>`,
88+
}),
8089
}
8190

8291
export const WithKeyboardShortcut: Story = {
8392
args: {
8493
variant: 'button-secondary',
8594
ariaKeyshortcuts: 's',
86-
default: 'Search',
8795
},
96+
render: args => ({
97+
components: { LinkBase },
98+
setup() {
99+
return { args }
100+
},
101+
template: `<LinkBase v-bind="args">{{ $t("search.button") }}</LinkBase>`,
102+
}),
88103
}
89104

90105
export const BlockLink: Story = {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138
"markdown-it-anchor": "9.2.0",
139139
"schema-dts": "1.1.5",
140140
"storybook": "catalog:storybook",
141+
"storybook-i18n": "catalog:storybook",
141142
"typescript": "5.9.3",
142143
"unplugin-vue-markdown": "30.0.0",
143144
"vitest": "npm:@voidzero-dev/vite-plus-test@0.1.12",

pnpm-lock.yaml

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,4 @@ catalogs:
4747
'@storybook/addon-docs': '^10.2.7'
4848
'@storybook/addon-themes': '^10.2.7'
4949
'storybook': '^10.2.7'
50+
'storybook-i18n': '^10.1.1'

0 commit comments

Comments
 (0)