@intlayer/docs 8.4.5 → 8.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blog/en/next-i18next_vs_next-intl_vs_intlayer.md +1 -3
- package/blog/en-GB/next-i18next_vs_next-intl_vs_intlayer.md +1 -3
- package/blog/es/next-i18next_vs_next-intl_vs_intlayer.md +1 -3
- package/blog/id/next-i18next_vs_next-intl_vs_intlayer.md +1 -3
- package/blog/it/next-i18next_vs_next-intl_vs_intlayer.md +1 -3
- package/blog/ja/next-i18next_vs_next-intl_vs_intlayer.md +1 -3
- package/blog/ko/next-i18next_vs_next-intl_vs_intlayer.md +1 -3
- package/blog/uk/next-i18next_vs_next-intl_vs_intlayer.md +1 -3
- package/blog/vi/next-i18next_vs_next-intl_vs_intlayer.md +1 -3
- package/blog/zh/next-i18next_vs_next-intl_vs_intlayer.md +1 -3
- package/dist/cjs/generated/docs.entry.cjs +20 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +20 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/intlayer_with_storybook.md +521 -0
- package/docs/bn/intlayer_with_hono.md +428 -0
- package/docs/de/intlayer_with_storybook.md +521 -0
- package/docs/en/configuration.md +160 -508
- package/docs/en/intlayer_with_storybook.md +521 -0
- package/docs/en-GB/intlayer_with_storybook.md +521 -0
- package/docs/es/configuration.md +387 -754
- package/docs/es/intlayer_with_storybook.md +521 -0
- package/docs/fr/configuration.md +384 -757
- package/docs/fr/intlayer_with_storybook.md +521 -0
- package/docs/hi/intlayer_with_storybook.md +521 -0
- package/docs/id/intlayer_with_storybook.md +521 -0
- package/docs/it/intlayer_with_storybook.md +521 -0
- package/docs/ja/intlayer_with_storybook.md +521 -0
- package/docs/ko/intlayer_with_storybook.md +521 -0
- package/docs/pl/intlayer_with_storybook.md +521 -0
- package/docs/pt/intlayer_with_storybook.md +521 -0
- package/docs/ru/intlayer_with_storybook.md +521 -0
- package/docs/tr/intlayer_with_storybook.md +521 -0
- package/docs/uk/intlayer_with_storybook.md +521 -0
- package/docs/ur/intlayer_with_hono.md +428 -0
- package/docs/vi/intlayer_with_storybook.md +521 -0
- package/docs/zh/intlayer_with_storybook.md +521 -0
- package/package.json +6 -6
- package/src/generated/docs.entry.ts +20 -0
- package/docs/ar/configuration.md +0 -1124
- package/docs/de/configuration.md +0 -1296
- package/docs/en-GB/configuration.md +0 -1123
- package/docs/hi/configuration.md +0 -1118
- package/docs/id/configuration.md +0 -1235
- package/docs/it/configuration.md +0 -1301
- package/docs/ja/configuration.md +0 -1121
- package/docs/ko/configuration.md +0 -1121
- package/docs/pl/configuration.md +0 -1226
- package/docs/pt/configuration.md +0 -1293
- package/docs/ru/configuration.md +0 -1112
- package/docs/tr/configuration.md +0 -1114
- package/docs/uk/configuration.md +0 -1241
- package/docs/vi/configuration.md +0 -1263
- package/docs/zh/configuration.md +0 -1115
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-03-20
|
|
3
|
+
updatedAt: 2026-03-20
|
|
4
|
+
title: Как настроить Intlayer с помощью Storybook
|
|
5
|
+
description: Узнайте, как сделать вашу дизайн-систему многоязычной с помощью Intlayer и Storybook — компилируйте декларации контента, добавьте переключатель языков и просматривайте компоненты на любом языке.
|
|
6
|
+
keywords:
|
|
7
|
+
- Интернационализация
|
|
8
|
+
- Документация
|
|
9
|
+
- Intlayer
|
|
10
|
+
- Storybook
|
|
11
|
+
- React
|
|
12
|
+
- i18n
|
|
13
|
+
- TypeScript
|
|
14
|
+
- Vite
|
|
15
|
+
- Webpack
|
|
16
|
+
slugs:
|
|
17
|
+
- doc
|
|
18
|
+
- storybook
|
|
19
|
+
history:
|
|
20
|
+
- version: 8.4.5
|
|
21
|
+
date: 2026-03-20
|
|
22
|
+
changes: Init doc
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Intlayer со Storybook
|
|
26
|
+
|
|
27
|
+
## Содержание
|
|
28
|
+
|
|
29
|
+
<TOC/>
|
|
30
|
+
|
|
31
|
+
## Что такое Intlayer?
|
|
32
|
+
|
|
33
|
+
**Intlayer** — это инновационная библиотека интернационализации (i18n) с открытым исходным кодом, разработанная для упрощения многоязычной поддержки в современных веб-приложениях. Она работает на **уровне компонентов** — каждый компонент владеет своими декларациями контента, что позволяет хранить переводы рядом с кодом, который их использует.
|
|
34
|
+
|
|
35
|
+
С Intlayer вы можете:
|
|
36
|
+
|
|
37
|
+
- **Управлять переводами декларативно** с помощью файлов контента для каждого компонента.
|
|
38
|
+
- **Получать полную поддержку TypeScript** через автоматически создаваемые типы и автодополнение в IDE.
|
|
39
|
+
- **Переключать языки во время выполнения** без перезагрузки страницы.
|
|
40
|
+
- **Переводить автоматически** благодаря встроенной интеграции с ИИ.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Зачем использовать Intlayer со Storybook?
|
|
45
|
+
|
|
46
|
+
Storybook — это отраслевой стандарт для разработки и документирования компонентов пользовательского интерфейса в изоляции. Совмещение его с Intlayer позволяет:
|
|
47
|
+
|
|
48
|
+
- **Предварительно просматривать каждый язык** прямо в Storybook с помощью переключателя в панели инструментов.
|
|
49
|
+
- **Обнаруживать недостающие переводы** до того, как они попадут в продакшн.
|
|
50
|
+
- **Документировать многоязычные компоненты** с использованием реального, типизированного контента вместо жестко закодированных строк.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Пошаговая настройка
|
|
55
|
+
|
|
56
|
+
<Tabs>
|
|
57
|
+
<Tab value="Vite Setup">
|
|
58
|
+
|
|
59
|
+
### Шаг 1: Установка зависимостей
|
|
60
|
+
|
|
61
|
+
```bash packageManager="npm"
|
|
62
|
+
npm install intlayer react-intlayer
|
|
63
|
+
npm install vite-intlayer --save-dev
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```bash packageManager="pnpm"
|
|
67
|
+
pnpm add intlayer react-intlayer
|
|
68
|
+
pnpm add vite-intlayer --save-dev
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```bash packageManager="yarn"
|
|
72
|
+
yarn add intlayer react-intlayer
|
|
73
|
+
yarn add vite-intlayer --save-dev
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```bash packageManager="bun"
|
|
77
|
+
bun add intlayer react-intlayer
|
|
78
|
+
bun add vite-intlayer --dev
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
| Пакет | Роль |
|
|
82
|
+
| ---------------- | ----------------------------------------------------------------- |
|
|
83
|
+
| `intlayer` | Ядро — конфигурация, компиляция контента, CLI |
|
|
84
|
+
| `react-intlayer` | Привязки React — `IntlayerProvider`, хук `useIntlayer` |
|
|
85
|
+
| `vite-intlayer` | Плагин Vite — отслеживает и компилирует файлы деклараций контента |
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### Шаг 2: Создание конфигурации Intlayer
|
|
90
|
+
|
|
91
|
+
Создайте `intlayer.config.ts` в корне вашего проекта (или внутри вашего пакета дизайн-системы):
|
|
92
|
+
|
|
93
|
+
```typescript fileName="intlayer.config.ts" codeFormat="typescript"
|
|
94
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
95
|
+
|
|
96
|
+
const config: IntlayerConfig = {
|
|
97
|
+
internationalization: {
|
|
98
|
+
locales: [
|
|
99
|
+
Locales.ENGLISH,
|
|
100
|
+
Locales.FRENCH,
|
|
101
|
+
Locales.SPANISH,
|
|
102
|
+
// добавьте другие языки по мере необходимости
|
|
103
|
+
],
|
|
104
|
+
defaultLocale: Locales.ENGLISH,
|
|
105
|
+
},
|
|
106
|
+
content: {
|
|
107
|
+
contentDir: ["./src"], // где хранятся ваши файлы *.content.ts
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export default config;
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
> Полный список опций см. в [справочнике по конфигурации](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/configuration.md).
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
### Шаг 3: Добавление плагина Vite в Storybook
|
|
119
|
+
|
|
120
|
+
Хук `viteFinal` в Storybook позволяет расширить внутреннюю конфигурацию Vite. Импортируйте и добавьте туда плагин `intlayer()`:
|
|
121
|
+
|
|
122
|
+
```typescript fileName=".storybook/main.ts" codeFormat="typescript"
|
|
123
|
+
import type { StorybookConfig } from "@storybook/react-vite";
|
|
124
|
+
import { defineConfig, mergeConfig } from "vite";
|
|
125
|
+
import { intlayer } from "vite-intlayer";
|
|
126
|
+
|
|
127
|
+
const config: StorybookConfig = {
|
|
128
|
+
stories: ["../src/**/*.stories.@(js|jsx|ts|tsx)"],
|
|
129
|
+
addons: [
|
|
130
|
+
"@storybook/addon-essentials",
|
|
131
|
+
// …другие аддоны
|
|
132
|
+
],
|
|
133
|
+
framework: {
|
|
134
|
+
name: "@storybook/react-vite",
|
|
135
|
+
options: {},
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
async viteFinal(baseConfig, { configType }) {
|
|
139
|
+
const env = {
|
|
140
|
+
command: configType === "DEVELOPMENT" ? "serve" : "build",
|
|
141
|
+
mode: configType === "DEVELOPMENT" ? "development" : "production",
|
|
142
|
+
} as const;
|
|
143
|
+
|
|
144
|
+
const viteConfig = defineConfig(() => ({
|
|
145
|
+
plugins: [intlayer()],
|
|
146
|
+
}));
|
|
147
|
+
|
|
148
|
+
return mergeConfig(baseConfig, viteConfig(env));
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
export default config;
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Плагин `intlayer()` отслеживает ваши файлы `*.content.ts` и автоматически перестраивает словари при любых изменениях во время разработки в Storybook.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
### Шаг 4: Добавление декоратора `IntlayerProvider` и переключателя языков
|
|
160
|
+
|
|
161
|
+
Файл `preview` в Storybook — подходящее место для обертывания каждой истории в `IntlayerProvider` и добавления переключателя языков в панель инструментов:
|
|
162
|
+
|
|
163
|
+
```tsx fileName=".storybook/preview.tsx" codeFormat="typescript"
|
|
164
|
+
import type { Preview, StoryContext } from "@storybook/react";
|
|
165
|
+
import { IntlayerProvider } from "react-intlayer";
|
|
166
|
+
|
|
167
|
+
const preview: Preview = {
|
|
168
|
+
// Оборачиваем каждую историю в IntlayerProvider
|
|
169
|
+
decorators: [
|
|
170
|
+
(Story, context: StoryContext) => {
|
|
171
|
+
const locale = context.globals.locale ?? "en";
|
|
172
|
+
return (
|
|
173
|
+
<IntlayerProvider locale={locale}>
|
|
174
|
+
<Story />
|
|
175
|
+
</IntlayerProvider>
|
|
176
|
+
);
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
|
|
180
|
+
// Добавляем переключатель языков в панель инструментов Storybook
|
|
181
|
+
globalTypes: {
|
|
182
|
+
locale: {
|
|
183
|
+
description: "Активный язык",
|
|
184
|
+
defaultValue: "en",
|
|
185
|
+
toolbar: {
|
|
186
|
+
title: "Язык",
|
|
187
|
+
icon: "globe",
|
|
188
|
+
items: [
|
|
189
|
+
{ value: "en", title: "English" },
|
|
190
|
+
{ value: "fr", title: "Français" },
|
|
191
|
+
{ value: "es", title: "Español" },
|
|
192
|
+
],
|
|
193
|
+
dynamicTitle: true,
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
parameters: {
|
|
199
|
+
controls: {
|
|
200
|
+
matchers: {
|
|
201
|
+
color: /(background|color)$/i,
|
|
202
|
+
date: /Date$/i,
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
export default preview;
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
> Значения `locale` должны соответствовать языкам, объявленным в вашем `intlayer.config.ts`.
|
|
212
|
+
|
|
213
|
+
</Tab>
|
|
214
|
+
<Tab value="Webpack Setup">
|
|
215
|
+
|
|
216
|
+
### Шаг 1: Установка зависимостей
|
|
217
|
+
|
|
218
|
+
```bash packageManager="npm"
|
|
219
|
+
npm install intlayer react-intlayer
|
|
220
|
+
npm install @intlayer/webpack --save-dev
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
```bash packageManager="pnpm"
|
|
224
|
+
pnpm add intlayer react-intlayer
|
|
225
|
+
pnpm add @intlayer/webpack --save-dev
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
```bash packageManager="yarn"
|
|
229
|
+
yarn add intlayer react-intlayer
|
|
230
|
+
yarn add @intlayer/webpack --save-dev
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
```bash packageManager="bun"
|
|
234
|
+
bun add intlayer react-intlayer
|
|
235
|
+
bun add @intlayer/webpack --dev
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
### Шаг 2: Создание конфигурации Intlayer
|
|
241
|
+
|
|
242
|
+
Создайте `intlayer.config.ts` в корне вашего проекта:
|
|
243
|
+
|
|
244
|
+
```typescript fileName="intlayer.config.ts" codeFormat="typescript"
|
|
245
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
246
|
+
|
|
247
|
+
const config: IntlayerConfig = {
|
|
248
|
+
internationalization: {
|
|
249
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
250
|
+
defaultLocale: Locales.ENGLISH,
|
|
251
|
+
},
|
|
252
|
+
content: {
|
|
253
|
+
contentDir: ["./src"],
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
export default config;
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
### Шаг 3: Настройка Webpack в Storybook
|
|
263
|
+
|
|
264
|
+
Для настроек Storybook на базе Webpack (например, `@storybook/react-webpack5`) расширьте конфигурацию webpack через `webpackFinal`, чтобы добавить алиасы и загрузчик Intlayer:
|
|
265
|
+
|
|
266
|
+
```typescript fileName=".storybook/main.ts" codeFormat="typescript"
|
|
267
|
+
import type { StorybookConfig } from "@storybook/react-webpack5";
|
|
268
|
+
import { IntlayerWebpackPlugin } from "@intlayer/webpack";
|
|
269
|
+
|
|
270
|
+
const config: StorybookConfig = {
|
|
271
|
+
stories: ["../src/**/*.stories.@(js|jsx|ts|tsx)"],
|
|
272
|
+
addons: ["@storybook/addon-essentials"],
|
|
273
|
+
framework: {
|
|
274
|
+
name: "@storybook/react-webpack5",
|
|
275
|
+
options: {},
|
|
276
|
+
},
|
|
277
|
+
|
|
278
|
+
webpackFinal: async (baseConfig) => {
|
|
279
|
+
baseConfig.plugins = [
|
|
280
|
+
...(baseConfig.plugins ?? []),
|
|
281
|
+
new IntlayerWebpackPlugin(),
|
|
282
|
+
];
|
|
283
|
+
return baseConfig;
|
|
284
|
+
},
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
export default config;
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
### Шаг 4: Добавление декоратора `IntlayerProvider` и переключателя языков
|
|
293
|
+
|
|
294
|
+
Аналогично настройке Vite — добавьте декоратор и глобальный тип языка в `.storybook/preview.tsx`:
|
|
295
|
+
|
|
296
|
+
```tsx fileName=".storybook/preview.tsx" codeFormat="typescript"
|
|
297
|
+
import type { Preview, StoryContext } from "@storybook/react";
|
|
298
|
+
import { IntlayerProvider } from "react-intlayer";
|
|
299
|
+
|
|
300
|
+
const preview: Preview = {
|
|
301
|
+
decorators: [
|
|
302
|
+
(Story, context: StoryContext) => {
|
|
303
|
+
const locale = context.globals.locale ?? "en";
|
|
304
|
+
return (
|
|
305
|
+
<IntlayerProvider locale={locale}>
|
|
306
|
+
<Story />
|
|
307
|
+
</IntlayerProvider>
|
|
308
|
+
);
|
|
309
|
+
},
|
|
310
|
+
],
|
|
311
|
+
|
|
312
|
+
globalTypes: {
|
|
313
|
+
locale: {
|
|
314
|
+
description: "Активный язык",
|
|
315
|
+
defaultValue: "en",
|
|
316
|
+
toolbar: {
|
|
317
|
+
title: "Язык",
|
|
318
|
+
icon: "globe",
|
|
319
|
+
items: [
|
|
320
|
+
{ value: "en", title: "English" },
|
|
321
|
+
{ value: "fr", title: "Français" },
|
|
322
|
+
{ value: "es", title: "Español" },
|
|
323
|
+
],
|
|
324
|
+
dynamicTitle: true,
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
export default preview;
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
</Tab>
|
|
334
|
+
</Tabs>
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## Объявление контента
|
|
339
|
+
|
|
340
|
+
Создайте файл `*.content.ts` рядом с каждым компонентом. Intlayer автоматически подхватит его во время компиляции.
|
|
341
|
+
|
|
342
|
+
```typescript fileName="src/components/CopyButton/CopyButton.content.ts" codeFormat="typescript"
|
|
343
|
+
import { type Dictionary, t } from "intlayer";
|
|
344
|
+
|
|
345
|
+
const copyButtonContent = {
|
|
346
|
+
key: "copy-button",
|
|
347
|
+
content: {
|
|
348
|
+
label: t({
|
|
349
|
+
en: "Copy content",
|
|
350
|
+
fr: "Copier le contenu",
|
|
351
|
+
es: "Copiar contenido",
|
|
352
|
+
}),
|
|
353
|
+
},
|
|
354
|
+
} satisfies Dictionary;
|
|
355
|
+
|
|
356
|
+
export default copyButtonContent;
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
```javascript fileName="src/components/CopyButton/CopyButton.content.mjs" codeFormat="esm"
|
|
360
|
+
import { t } from "intlayer";
|
|
361
|
+
|
|
362
|
+
/** @type {import('intlayer').Dictionary} */
|
|
363
|
+
const copyButtonContent = {
|
|
364
|
+
key: "copy-button",
|
|
365
|
+
content: {
|
|
366
|
+
label: t({
|
|
367
|
+
en: "Copy content",
|
|
368
|
+
fr: "Copier le contenu",
|
|
369
|
+
es: "Copiar contenido",
|
|
370
|
+
}),
|
|
371
|
+
},
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
export default copyButtonContent;
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
```javascript fileName="src/components/CopyButton/CopyButton.content.cjs" codeFormat="commonjs"
|
|
378
|
+
const { t } = require("intlayer");
|
|
379
|
+
|
|
380
|
+
/** @type {import('intlayer').Dictionary} */
|
|
381
|
+
const copyButtonContent = {
|
|
382
|
+
key: "copy-button",
|
|
383
|
+
content: {
|
|
384
|
+
label: t({
|
|
385
|
+
en: "Copy content",
|
|
386
|
+
fr: "Copier le contenu",
|
|
387
|
+
es: "Copiar contenido",
|
|
388
|
+
}),
|
|
389
|
+
},
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
module.exports = copyButtonContent;
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
> Более подробную информацию о форматах объявлений контента и функциях см. в [документации по объявлению контента](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/dictionary/content_file.md).
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
## Использование `useIntlayer` в компоненте
|
|
400
|
+
|
|
401
|
+
```tsx fileName="src/components/CopyButton/index.tsx" codeFormat="typescript"
|
|
402
|
+
"use client";
|
|
403
|
+
|
|
404
|
+
import { type FC } from "react";
|
|
405
|
+
import { useIntlayer } from "react-intlayer";
|
|
406
|
+
|
|
407
|
+
type CopyButtonProps = {
|
|
408
|
+
content: string;
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
export const CopyButton: FC<CopyButtonProps> = ({ content }) => {
|
|
412
|
+
const { label } = useIntlayer("copy-button");
|
|
413
|
+
|
|
414
|
+
return (
|
|
415
|
+
<button
|
|
416
|
+
onClick={() => navigator.clipboard.writeText(content)}
|
|
417
|
+
aria-label={label.value}
|
|
418
|
+
title={label.value}
|
|
419
|
+
>
|
|
420
|
+
Копировать
|
|
421
|
+
</button>
|
|
422
|
+
);
|
|
423
|
+
};
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
`useIntlayer` возвращает скомпилированный словарь для текущего языка, предоставленного ближайшим `IntlayerProvider`. Переключение языка в панели инструментов Storybook автоматически перерисовывает историю с обновленными переводами.
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## Написание историй для интернационализированных компонентов
|
|
431
|
+
|
|
432
|
+
С настроенным декоратором `IntlayerProvider` ваши истории работают так же, как и раньше. Панель инструментов управляет активным языком для всего холста:
|
|
433
|
+
|
|
434
|
+
```tsx fileName="src/components/CopyButton/CopyButton.stories.tsx" codeFormat="typescript"
|
|
435
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
436
|
+
import { CopyButton } from ".";
|
|
437
|
+
|
|
438
|
+
const meta: Meta<typeof CopyButton> = {
|
|
439
|
+
title: "Components/CopyButton",
|
|
440
|
+
component: CopyButton,
|
|
441
|
+
tags: ["autodocs"],
|
|
442
|
+
argTypes: {
|
|
443
|
+
content: { control: "text" },
|
|
444
|
+
},
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
export default meta;
|
|
448
|
+
type Story = StoryObj<typeof CopyButton>;
|
|
449
|
+
|
|
450
|
+
/** История по умолчанию — переключите язык в панели инструментов, чтобы просмотреть переводы. */
|
|
451
|
+
export const Default: Story = {
|
|
452
|
+
args: {
|
|
453
|
+
content: "npm install intlayer react-intlayer",
|
|
454
|
+
},
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
/** Отрисовывает кнопку внутри блока кода — распространенный случай использования. */
|
|
458
|
+
export const InsideCodeBlock: Story = {
|
|
459
|
+
render: (args) => (
|
|
460
|
+
<div style={{ position: "relative", display: "inline-block" }}>
|
|
461
|
+
<pre style={{ background: "#1e1e1e", color: "#fff", padding: "1rem" }}>
|
|
462
|
+
<code>{args.content}</code>
|
|
463
|
+
</pre>
|
|
464
|
+
<CopyButton
|
|
465
|
+
content={args.content}
|
|
466
|
+
style={{ position: "absolute", top: 8, right: 8 }}
|
|
467
|
+
/>
|
|
468
|
+
</div>
|
|
469
|
+
),
|
|
470
|
+
args: {
|
|
471
|
+
content: "npx intlayer init",
|
|
472
|
+
},
|
|
473
|
+
};
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
> Каждая история наследует глобальный параметр `locale` из панели инструментов, поэтому вы можете проверить каждый язык без изменения кода самой истории.
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
## Тестирование переводов в историях
|
|
481
|
+
|
|
482
|
+
Используйте функции `play` в Storybook, чтобы подтвердить правильность отображения переведенного текста для заданного языка:
|
|
483
|
+
|
|
484
|
+
```tsx fileName="src/components/CopyButton/CopyButton.stories.tsx" codeFormat="typescript"
|
|
485
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
486
|
+
import { expect, within } from "@storybook/test";
|
|
487
|
+
import { CopyButton } from ".";
|
|
488
|
+
|
|
489
|
+
const meta: Meta<typeof CopyButton> = {
|
|
490
|
+
title: "Components/CopyButton",
|
|
491
|
+
component: CopyButton,
|
|
492
|
+
tags: ["autodocs"],
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
export default meta;
|
|
496
|
+
type Story = StoryObj<typeof CopyButton>;
|
|
497
|
+
|
|
498
|
+
export const AccessibleLabel: Story = {
|
|
499
|
+
args: { content: "Hello World" },
|
|
500
|
+
play: async ({ canvasElement }) => {
|
|
501
|
+
const canvas = within(canvasElement);
|
|
502
|
+
const button = canvas.getByRole("button");
|
|
503
|
+
|
|
504
|
+
// Проверяем, что у кнопки есть непустое доступное имя
|
|
505
|
+
await expect(button).toHaveAccessibleName();
|
|
506
|
+
// Проверяем, что кнопка не отключена
|
|
507
|
+
await expect(button).not.toBeDisabled();
|
|
508
|
+
// Проверяем доступность клавиатуры
|
|
509
|
+
await expect(button).toHaveAttribute("tabindex", "0");
|
|
510
|
+
},
|
|
511
|
+
};
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
---
|
|
515
|
+
|
|
516
|
+
## Дополнительные ресурсы
|
|
517
|
+
|
|
518
|
+
- [Справочник по конфигурации Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/configuration.md)
|
|
519
|
+
- [Документация по объявлению контента](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/dictionary/content_file.md)
|
|
520
|
+
- [Документация CLI Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/cli/index.md)
|
|
521
|
+
- [Документация Storybook](https://storybook.js.org/docs)
|