@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: Jak skonfigurować Intlayer z Storybook
|
|
5
|
+
description: Dowiedz się, jak uczynić swój system projektowania wielojęzycznym, używając Intlayer z Storybook — kompiluj deklaracje treści, dodaj przełącznik języka i przeglądaj komponenty w dowolnym języku.
|
|
6
|
+
keywords:
|
|
7
|
+
- Internacjonalizacja
|
|
8
|
+
- Dokumentacja
|
|
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 z Storybook
|
|
26
|
+
|
|
27
|
+
## Spis treści
|
|
28
|
+
|
|
29
|
+
<TOC/>
|
|
30
|
+
|
|
31
|
+
## Czym jest Intlayer?
|
|
32
|
+
|
|
33
|
+
**Intlayer** to innowacyjna biblioteka internacjonalizacji (i18n) typu open-source, zaprojektowana w celu uproszczenia obsługi wielojęzyczności w nowoczesnych aplikacjach internetowych. Działa na **poziomie komponentów** — każdy komponent posiada własne deklaracje treści — co pozwala na przechowywanie tłumaczeń w tym samym miejscu, co kod, który ich używa.
|
|
34
|
+
|
|
35
|
+
Dzięki Intlayer możesz:
|
|
36
|
+
|
|
37
|
+
- **Zarządzać tłumaczeniami deklaratywnie** za pomocą plików treści dla poszczególnych komponentów.
|
|
38
|
+
- **Korzystać z pełnego wsparcia TypeScript** dzięki automatycznie generowanym typom i autouzupełnianiu w środowisku IDE.
|
|
39
|
+
- **Przełączać języki w czasie rzeczywistym** bez konieczności przeładowywania strony.
|
|
40
|
+
- **Automatycznie tłumaczyć treści** dzięki wbudowanym integracjom z dostawcami AI.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Dlaczego warto używać Intlayer z Storybook?
|
|
45
|
+
|
|
46
|
+
Storybook to standardowe narzędzie branżowe do tworzenia i dokumentowania komponentów interfejsu użytkownika w izolacji. Połączenie go z Intlayer pozwala na:
|
|
47
|
+
|
|
48
|
+
- **Podgląd każdego języka** bezpośrednio w środowisku Storybook za pomocą przełącznika na pasku narzędzi.
|
|
49
|
+
- **Wykrywanie brakujących tłumaczeń** przed ich wdrożeniem do produkcji.
|
|
50
|
+
- **Dokumentowanie komponentów wielojęzycznych** przy użyciu rzeczywistych, bezpiecznych pod kątem typów treści zamiast zakodowanych na sztywno ciągów znaków.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Konfiguracja krok po kroku
|
|
55
|
+
|
|
56
|
+
<Tabs>
|
|
57
|
+
<Tab value="Vite Setup">
|
|
58
|
+
|
|
59
|
+
### Krok 1: Instalacja zależności
|
|
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
|
+
| Pakiet | Rola |
|
|
82
|
+
| ---------------- | ------------------------------------------------------------- |
|
|
83
|
+
| `intlayer` | Rdzeń — konfiguracja, kompilacja treści, interfejs CLI |
|
|
84
|
+
| `react-intlayer` | Powiązania React — `IntlayerProvider`, hook `useIntlayer` |
|
|
85
|
+
| `vite-intlayer` | Wtyczka Vite — monitoruje i kompiluje pliki deklaracji treści |
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### Krok 2: Tworzenie konfiguracji Intlayer
|
|
90
|
+
|
|
91
|
+
Utwórz plik `intlayer.config.ts` w katalogu głównym projektu (lub wewnątrz pakietu systemu projektowania):
|
|
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
|
+
// dodaj więcej języków w razie potrzeby
|
|
103
|
+
],
|
|
104
|
+
defaultLocale: Locales.ENGLISH,
|
|
105
|
+
},
|
|
106
|
+
content: {
|
|
107
|
+
contentDir: ["./src"], // miejsce przechowywania plików *.content.ts
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export default config;
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
> Pełną listę opcji znajdziesz w [dokumentacji konfiguracji](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/configuration.md).
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
### Krok 3: Dodawanie wtyczki Vite do Storybook
|
|
119
|
+
|
|
120
|
+
Hook `viteFinal` w Storybook pozwala na rozszerzenie wewnętrznej konfiguracji Vite. Zaimportuj i dodaj wtyczkę `intlayer()` w tym miejscu:
|
|
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
|
+
// …pozostałe wtyczki
|
|
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
|
+
Wtyczka `intlayer()` monitoruje pliki `*.content.ts` i automatycznie przebudowuje słowniki przy każdej zmianie podczas pracy w Storybook.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
### Krok 4: Dodawanie dekoratora `IntlayerProvider` i przełącznika języków
|
|
160
|
+
|
|
161
|
+
Plik `preview` w Storybook to odpowiednie miejsce, aby opakować każdą historię w `IntlayerProvider` i udostępnić przełącznik języków na pasku narzędzi:
|
|
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
|
+
// Opakuj każdą historię w 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
|
+
// Udostępnij przełącznik języków na pasku narzędzi Storybook
|
|
181
|
+
globalTypes: {
|
|
182
|
+
locale: {
|
|
183
|
+
description: "Aktywny język",
|
|
184
|
+
defaultValue: "en",
|
|
185
|
+
toolbar: {
|
|
186
|
+
title: "Język",
|
|
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
|
+
> Wartości `locale` muszą odpowiadać językom zadeklarowanym w `intlayer.config.ts`.
|
|
212
|
+
|
|
213
|
+
</Tab>
|
|
214
|
+
<Tab value="Webpack Setup">
|
|
215
|
+
|
|
216
|
+
### Krok 1: Instalacja zależności
|
|
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
|
+
### Krok 2: Tworzenie konfiguracji Intlayer
|
|
241
|
+
|
|
242
|
+
Utwórz plik `intlayer.config.ts` w katalogu głównym projektu:
|
|
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
|
+
### Krok 3: Konfiguracja Webpack dla Storybook
|
|
263
|
+
|
|
264
|
+
W przypadku konfiguracji Storybook opartych na Webpack (np. `@storybook/react-webpack5`), rozszerz konfigurację za pomocą `webpackFinal`, aby dodać aliasy i loader 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
|
+
### Krok 4: Dodawanie dekoratora `IntlayerProvider` i przełącznika języków
|
|
293
|
+
|
|
294
|
+
Podobnie jak w przypadku konfiguracji Vite — dodaj dekorator i globalny typ języka w `.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: "Aktywny język",
|
|
315
|
+
defaultValue: "en",
|
|
316
|
+
toolbar: {
|
|
317
|
+
title: "Język",
|
|
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
|
+
## Deklarowanie treści
|
|
339
|
+
|
|
340
|
+
Utwórz plik `*.content.ts` obok każdego komponentu. Intlayer automatycznie wykryje go podczas kompilacji.
|
|
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
|
+
> Więcej informacji na temat formatów deklaracji i dostępnych funkcji znajdziesz w [dokumentacji deklaracji treści](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dictionary/content_file.md).
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
## Używanie `useIntlayer` w komponencie
|
|
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
|
+
Kopiuj
|
|
421
|
+
</button>
|
|
422
|
+
);
|
|
423
|
+
};
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
`useIntlayer` zwraca skompilowany słownik dla bieżącego języka, dostarczanego przez najbliższy komponent `IntlayerProvider`. Przełączenie języka na pasku narzędzi Storybook automatycznie odświeży historię z zaktualizowanymi tłumaczeniami.
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## Pisanie historii dla komponentów zinternacjonalizowanych
|
|
431
|
+
|
|
432
|
+
Dzięki zastosowaniu dekoratora `IntlayerProvider` Twoje historie działają dokładnie tak, jak wcześniej. Pasek narzędzi kontroluje aktywny język dla całego obszaru roboczego:
|
|
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
|
+
/** Domyślna historia — przełącz język na pasku narzędzi, aby zobaczyć tłumaczenia. */
|
|
451
|
+
export const Default: Story = {
|
|
452
|
+
args: {
|
|
453
|
+
content: "npm install intlayer react-intlayer",
|
|
454
|
+
},
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
/** Renderuje przycisk wewnątrz bloku kodu, co jest częstym przypadkiem użycia w rzeczywistych projektach. */
|
|
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
|
+
> Każda historia dziedziczy parametr globalny `locale` z paska narzędzi, więc możesz zweryfikować każdy język bez modyfikacji kodu historii.
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
## Testowanie tłumaczeń w historiach
|
|
481
|
+
|
|
482
|
+
Użyj funkcji `play` w Storybook, aby upewnić się, że renderowany jest poprawny przetłumaczony tekst dla danego języka:
|
|
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
|
+
// Sprawdź, czy przycisk posiada niepustą nazwę dostępności (accessible name)
|
|
505
|
+
await expect(button).toHaveAccessibleName();
|
|
506
|
+
// Sprawdź, czy przycisk nie jest wyłączony
|
|
507
|
+
await expect(button).not.toBeDisabled();
|
|
508
|
+
// Sprawdź dostępność klawiatury
|
|
509
|
+
await expect(button).toHaveAttribute("tabindex", "0");
|
|
510
|
+
},
|
|
511
|
+
};
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
---
|
|
515
|
+
|
|
516
|
+
## Dodatkowe zasoby
|
|
517
|
+
|
|
518
|
+
- [Dokumentacja konfiguracji Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/configuration.md)
|
|
519
|
+
- [Dokumentacja deklaracji treści](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dictionary/content_file.md)
|
|
520
|
+
- [Dokumentacja CLI Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/cli/index.md)
|
|
521
|
+
- [Dokumentacja Storybook](https://storybook.js.org/docs)
|