@minejs/i18n 0.0.5 → 0.0.6
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/README.md +340 -340
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +84 -73
- package/dist/index.d.ts +84 -73
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,341 +1,341 @@
|
|
|
1
|
-
<!-- ╔══════════════════════════════ BEG ══════════════════════════════╗ -->
|
|
2
|
-
|
|
3
|
-
<br>
|
|
4
|
-
<div align="center">
|
|
5
|
-
<p>
|
|
6
|
-
<img src="./assets/img/logo.png" alt="logo" style="" height="60" />
|
|
7
|
-
</p>
|
|
8
|
-
</div>
|
|
9
|
-
|
|
10
|
-
<div align="center">
|
|
11
|
-
<img src="https://img.shields.io/badge/v-0.0.
|
|
12
|
-
<a href="https://img.shields.io/github/stars/minejs-org"><img src="https://img.shields.io/badge/🔥-@minejs-black"/></a>
|
|
13
|
-
<br>
|
|
14
|
-
<img src="https://img.shields.io/badge/coverage-94.40%25-brightgreen" alt="Test Coverage" />
|
|
15
|
-
<img src="https://img.shields.io/github/issues/minejs-org/i18n?style=flat" alt="Github Repo Issues" />
|
|
16
|
-
<img src="https://img.shields.io/github/stars/minejs-org/i18n?style=social" alt="GitHub Repo stars" />
|
|
17
|
-
</div>
|
|
18
|
-
<br>
|
|
19
|
-
|
|
20
|
-
<!-- ╚═════════════════════════════════════════════════════════════════╝ -->
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<!-- ╔══════════════════════════════ DOC ══════════════════════════════╗ -->
|
|
25
|
-
|
|
26
|
-
- ## Overview 👀
|
|
27
|
-
|
|
28
|
-
- #### Why ?
|
|
29
|
-
> To unify the translation system and languages on the server and client, faster, cleaner, more maintainable.
|
|
30
|
-
|
|
31
|
-
- #### When ?
|
|
32
|
-
> When you need to add a translation to your server or client.
|
|
33
|
-
|
|
34
|
-
> When you use [@cruxjs/app](https://github.com/cruxjs-org/app).
|
|
35
|
-
|
|
36
|
-
<br>
|
|
37
|
-
<br>
|
|
38
|
-
|
|
39
|
-
- ## Quick Start 🔥
|
|
40
|
-
|
|
41
|
-
> install [`hmm`](https://github.com/minejs-org/hmm) first.
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
# in your terminal
|
|
45
|
-
hmm i @minejs/i18n
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
|
|
49
|
-
|
|
50
|
-
- #### Setup
|
|
51
|
-
|
|
52
|
-
- ##### JSON
|
|
53
|
-
|
|
54
|
-
> Save the translation **keys and their values** in `.json` files.
|
|
55
|
-
|
|
56
|
-
```jsonc
|
|
57
|
-
// ./src/shared/dist/u18n/en.json
|
|
58
|
-
{
|
|
59
|
-
"key": "value"
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
```jsonc
|
|
64
|
-
// ./src/shared/dist/u18n/ar.json
|
|
65
|
-
{
|
|
66
|
-
"key": "قيـمة"
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
- ##### I18n
|
|
71
|
-
|
|
72
|
-
> ***🌟 If you are using [`@cruxjs/app`](https://github.com/cruxjs-org/app) you can skip this step. 🌟***
|
|
73
|
-
|
|
74
|
-
> Then in your project ***(works with any environment: `server`, `browser`, ..)***
|
|
75
|
-
>
|
|
76
|
-
> Call the `setupI18n(..)` function **only once** in your application's lifecycle :
|
|
77
|
-
|
|
78
|
-
```ts
|
|
79
|
-
import { setupI18n } from `@minejs/i18n`;
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
await this.setupI18n({
|
|
84
|
-
defaultLanguage : 'en',
|
|
85
|
-
supportedLanguages : ['en', 'ar'],
|
|
86
|
-
basePath : '/static/dist/i18n', // for client side (or your custom public url)
|
|
87
|
-
: './src/shared/dist/i18n', // for server side (or your custom local path)
|
|
88
|
-
});
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
|
|
92
|
-
<br>
|
|
93
|
-
|
|
94
|
-
- #### Usage
|
|
95
|
-
|
|
96
|
-
> Now you can call the `t(..)` function anywhere in your project :
|
|
97
|
-
|
|
98
|
-
```tsx
|
|
99
|
-
import { t } from `@minejs/i18n`;
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
```ts
|
|
103
|
-
t('key', { params }, fallback) // just it !
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
|
|
107
|
-
|
|
108
|
-
- #### Language Switching
|
|
109
|
-
|
|
110
|
-
```typescript
|
|
111
|
-
import { setLanguage, onChange } from '@minejs/i18n';
|
|
112
|
-
|
|
113
|
-
// Listen to changes
|
|
114
|
-
onChange((lang) => {
|
|
115
|
-
console.log('Language changed to:', lang);
|
|
116
|
-
document.documentElement.lang = lang;
|
|
117
|
-
document.dir = isRTL() ? 'rtl' : 'ltr';
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
// Change language
|
|
121
|
-
await setLanguage('ar');
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
- #### Parameterized Translations
|
|
125
|
-
|
|
126
|
-
```json
|
|
127
|
-
{
|
|
128
|
-
"greeting": "Hello {name}, you have {count} messages"
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
```typescript
|
|
133
|
-
t('greeting', { name: 'John', count: '5' })
|
|
134
|
-
// "Hello John, you have 5 messages"
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
- #### HTML Tag Parsing
|
|
138
|
-
|
|
139
|
-
```json
|
|
140
|
-
{
|
|
141
|
-
"terms": "I agree to the <link>Terms of Service</link>"
|
|
142
|
-
}
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
const tokens = tParse('terms');
|
|
147
|
-
// [
|
|
148
|
-
// { type: 'text', content: 'I agree to the ' },
|
|
149
|
-
// { type: 'tag', tag: 'link', content: 'Terms of Service' }
|
|
150
|
-
// ]
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
- #### Page Titles (with RTL support)
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
156
|
-
import { genPageTitle } from '@minejs/i18n';
|
|
157
|
-
|
|
158
|
-
// en: "Settings - MyApp"
|
|
159
|
-
// ar: "MyApp - الإعدادات"
|
|
160
|
-
const title = genPageTitle('settings');
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
<br>
|
|
164
|
-
<br>
|
|
165
|
-
|
|
166
|
-
- ## Documentation 📑
|
|
167
|
-
|
|
168
|
-
- ### API
|
|
169
|
-
|
|
170
|
-
- #### Types
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
type LanguageCode = string;
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
```typescript
|
|
177
|
-
interface I18nConfig {
|
|
178
|
-
defaultLanguage? : LanguageCode;
|
|
179
|
-
supportedLanguages? : LanguageCode[];
|
|
180
|
-
fallbackLanguage? : LanguageCode;
|
|
181
|
-
onLanguageChange? : (lang: LanguageCode) => void;
|
|
182
|
-
storage? : I18nStorage;
|
|
183
|
-
basePath? : string;
|
|
184
|
-
fileExtension? : string;
|
|
185
|
-
}
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
```typescript
|
|
189
|
-
interface TranslationToken {
|
|
190
|
-
type : 'text' | 'tag';
|
|
191
|
-
tag? : string;
|
|
192
|
-
content : string;
|
|
193
|
-
}
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
|
|
197
|
-
|
|
198
|
-
- #### Functions
|
|
199
|
-
|
|
200
|
-
- #### `setupI18n(config)`
|
|
201
|
-
|
|
202
|
-
> Initialize i18n with auto-detection
|
|
203
|
-
|
|
204
|
-
```typescript
|
|
205
|
-
await setupI18n({
|
|
206
|
-
defaultLanguage : 'en',
|
|
207
|
-
supportedLanguages : ['en', 'ar', 'fr'],
|
|
208
|
-
basePath : '/i18n/', // URL (browser) or path (server)
|
|
209
|
-
fileExtension : 'json' // optional
|
|
210
|
-
});
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
- #### `t(key, params?)`
|
|
214
|
-
|
|
215
|
-
> Translate with parameter replacement
|
|
216
|
-
|
|
217
|
-
```typescript
|
|
218
|
-
t('greeting', { name: 'John' }) // "Hello John"
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
- #### `tLang(key, lang, params?)`
|
|
222
|
-
|
|
223
|
-
> Translate with specific language
|
|
224
|
-
|
|
225
|
-
```typescript
|
|
226
|
-
tLang('greeting', 'ar', { name: 'أحمد' })
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
- #### `tParse(key, params?)`
|
|
230
|
-
|
|
231
|
-
> Parse translation with HTML tags
|
|
232
|
-
|
|
233
|
-
```typescript
|
|
234
|
-
tParse('message') // Returns TokenArray
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
- #### `setLanguage(lang)`
|
|
238
|
-
|
|
239
|
-
> Change current language
|
|
240
|
-
|
|
241
|
-
```typescript
|
|
242
|
-
await setLanguage('ar')
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
- #### `getLanguage()`
|
|
246
|
-
|
|
247
|
-
> Get current language code
|
|
248
|
-
|
|
249
|
-
```typescript
|
|
250
|
-
const lang = getLanguage() // 'en'
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
- #### `getSupportedLanguages()`
|
|
254
|
-
|
|
255
|
-
> Get all supported languages
|
|
256
|
-
|
|
257
|
-
```typescript
|
|
258
|
-
const langs = getSupportedLanguages() // ['en', 'ar', 'fr']
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
- #### `isRTL()`
|
|
262
|
-
|
|
263
|
-
> Check if current language is RTL
|
|
264
|
-
|
|
265
|
-
```typescript
|
|
266
|
-
if (isRTL()) { /* Handle RTL layout */ }
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
- #### `onChange(callback)`
|
|
270
|
-
|
|
271
|
-
> Subscribe to language changes
|
|
272
|
-
|
|
273
|
-
```typescript
|
|
274
|
-
const unsubscribe = onChange((lang) => console.log('Changed to:', lang))
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
- #### `genPageTitle(key, prefix?)`
|
|
278
|
-
|
|
279
|
-
> Generate page title with app name
|
|
280
|
-
|
|
281
|
-
```typescript
|
|
282
|
-
genPageTitle('home') // "Home - MyApp" or "MyApp - الرئيسية"
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
- #### `plural(count, singleKey, pluralKey)`
|
|
286
|
-
|
|
287
|
-
> Handle pluralization
|
|
288
|
-
|
|
289
|
-
```typescript
|
|
290
|
-
plural(5, 'item.single', 'item.plural') // "5 items"
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
- #### `hasKey(key)`
|
|
294
|
-
|
|
295
|
-
> Check if translation exists
|
|
296
|
-
|
|
297
|
-
```typescript
|
|
298
|
-
if (hasKey('settings.theme')) { /* ... */ }
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
- #### `loadLanguage(lang, translations)`
|
|
302
|
-
|
|
303
|
-
> Load translations for a language
|
|
304
|
-
|
|
305
|
-
```typescript
|
|
306
|
-
loadLanguage('en', { greeting: 'Hello' })
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
- #### `loadTranslations(translations)`
|
|
310
|
-
|
|
311
|
-
> Load multiple languages at once
|
|
312
|
-
|
|
313
|
-
```typescript
|
|
314
|
-
loadTranslations({
|
|
315
|
-
en: { greeting: 'Hello' },
|
|
316
|
-
ar: { greeting: 'مرحبا' }
|
|
317
|
-
})
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
|
|
321
|
-
|
|
322
|
-
- #### Related
|
|
323
|
-
|
|
324
|
-
- ##### [@cruxjs/app](https://github.com/cruxjs-org/app)
|
|
325
|
-
|
|
326
|
-
<!-- ╚═════════════════════════════════════════════════════════════════╝ -->
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
<!-- ╔══════════════════════════════ END ══════════════════════════════╗ -->
|
|
331
|
-
|
|
332
|
-
<br>
|
|
333
|
-
<br>
|
|
334
|
-
|
|
335
|
-
---
|
|
336
|
-
|
|
337
|
-
<div align="center">
|
|
338
|
-
<a href="https://github.com/maysara-elshewehy"><img src="https://img.shields.io/badge/by-Maysara-black"/></a>
|
|
339
|
-
</div>
|
|
340
|
-
|
|
1
|
+
<!-- ╔══════════════════════════════ BEG ══════════════════════════════╗ -->
|
|
2
|
+
|
|
3
|
+
<br>
|
|
4
|
+
<div align="center">
|
|
5
|
+
<p>
|
|
6
|
+
<img src="./assets/img/logo.png" alt="logo" style="" height="60" />
|
|
7
|
+
</p>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div align="center">
|
|
11
|
+
<img src="https://img.shields.io/badge/v-0.0.6-black"/>
|
|
12
|
+
<a href="https://img.shields.io/github/stars/minejs-org"><img src="https://img.shields.io/badge/🔥-@minejs-black"/></a>
|
|
13
|
+
<br>
|
|
14
|
+
<img src="https://img.shields.io/badge/coverage-94.40%25-brightgreen" alt="Test Coverage" />
|
|
15
|
+
<img src="https://img.shields.io/github/issues/minejs-org/i18n?style=flat" alt="Github Repo Issues" />
|
|
16
|
+
<img src="https://img.shields.io/github/stars/minejs-org/i18n?style=social" alt="GitHub Repo stars" />
|
|
17
|
+
</div>
|
|
18
|
+
<br>
|
|
19
|
+
|
|
20
|
+
<!-- ╚═════════════════════════════════════════════════════════════════╝ -->
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
<!-- ╔══════════════════════════════ DOC ══════════════════════════════╗ -->
|
|
25
|
+
|
|
26
|
+
- ## Overview 👀
|
|
27
|
+
|
|
28
|
+
- #### Why ?
|
|
29
|
+
> To unify the translation system and languages on the server and client, faster, cleaner, more maintainable.
|
|
30
|
+
|
|
31
|
+
- #### When ?
|
|
32
|
+
> When you need to add a translation to your server or client.
|
|
33
|
+
|
|
34
|
+
> When you use [@cruxjs/app](https://github.com/cruxjs-org/app).
|
|
35
|
+
|
|
36
|
+
<br>
|
|
37
|
+
<br>
|
|
38
|
+
|
|
39
|
+
- ## Quick Start 🔥
|
|
40
|
+
|
|
41
|
+
> install [`hmm`](https://github.com/minejs-org/hmm) first.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# in your terminal
|
|
45
|
+
hmm i @minejs/i18n
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
|
|
49
|
+
|
|
50
|
+
- #### Setup
|
|
51
|
+
|
|
52
|
+
- ##### JSON
|
|
53
|
+
|
|
54
|
+
> Save the translation **keys and their values** in `.json` files.
|
|
55
|
+
|
|
56
|
+
```jsonc
|
|
57
|
+
// ./src/shared/dist/u18n/en.json
|
|
58
|
+
{
|
|
59
|
+
"key": "value"
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```jsonc
|
|
64
|
+
// ./src/shared/dist/u18n/ar.json
|
|
65
|
+
{
|
|
66
|
+
"key": "قيـمة"
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
- ##### I18n
|
|
71
|
+
|
|
72
|
+
> ***🌟 If you are using [`@cruxjs/app`](https://github.com/cruxjs-org/app) you can skip this step. 🌟***
|
|
73
|
+
|
|
74
|
+
> Then in your project ***(works with any environment: `server`, `browser`, ..)***
|
|
75
|
+
>
|
|
76
|
+
> Call the `setupI18n(..)` function **only once** in your application's lifecycle :
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { setupI18n } from `@minejs/i18n`;
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
await this.setupI18n({
|
|
84
|
+
defaultLanguage : 'en',
|
|
85
|
+
supportedLanguages : ['en', 'ar'],
|
|
86
|
+
basePath : '/static/dist/i18n', // for client side (or your custom public url)
|
|
87
|
+
: './src/shared/dist/i18n', // for server side (or your custom local path)
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
|
|
92
|
+
<br>
|
|
93
|
+
|
|
94
|
+
- #### Usage
|
|
95
|
+
|
|
96
|
+
> Now you can call the `t(..)` function anywhere in your project :
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
import { t } from `@minejs/i18n`;
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
t('key', { params }, fallback) // just it !
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
|
|
107
|
+
|
|
108
|
+
- #### Language Switching
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { setLanguage, onChange } from '@minejs/i18n';
|
|
112
|
+
|
|
113
|
+
// Listen to changes
|
|
114
|
+
onChange((lang) => {
|
|
115
|
+
console.log('Language changed to:', lang);
|
|
116
|
+
document.documentElement.lang = lang;
|
|
117
|
+
document.dir = isRTL() ? 'rtl' : 'ltr';
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Change language
|
|
121
|
+
await setLanguage('ar');
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
- #### Parameterized Translations
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"greeting": "Hello {name}, you have {count} messages"
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
t('greeting', { name: 'John', count: '5' })
|
|
134
|
+
// "Hello John, you have 5 messages"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
- #### HTML Tag Parsing
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"terms": "I agree to the <link>Terms of Service</link>"
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
const tokens = tParse('terms');
|
|
147
|
+
// [
|
|
148
|
+
// { type: 'text', content: 'I agree to the ' },
|
|
149
|
+
// { type: 'tag', tag: 'link', content: 'Terms of Service' }
|
|
150
|
+
// ]
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
- #### Page Titles (with RTL support)
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import { genPageTitle } from '@minejs/i18n';
|
|
157
|
+
|
|
158
|
+
// en: "Settings - MyApp"
|
|
159
|
+
// ar: "MyApp - الإعدادات"
|
|
160
|
+
const title = genPageTitle('settings');
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
<br>
|
|
164
|
+
<br>
|
|
165
|
+
|
|
166
|
+
- ## Documentation 📑
|
|
167
|
+
|
|
168
|
+
- ### API
|
|
169
|
+
|
|
170
|
+
- #### Types
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
type LanguageCode = string;
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
interface I18nConfig {
|
|
178
|
+
defaultLanguage? : LanguageCode;
|
|
179
|
+
supportedLanguages? : LanguageCode[];
|
|
180
|
+
fallbackLanguage? : LanguageCode;
|
|
181
|
+
onLanguageChange? : (lang: LanguageCode) => void;
|
|
182
|
+
storage? : I18nStorage;
|
|
183
|
+
basePath? : string;
|
|
184
|
+
fileExtension? : string;
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
interface TranslationToken {
|
|
190
|
+
type : 'text' | 'tag';
|
|
191
|
+
tag? : string;
|
|
192
|
+
content : string;
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
|
|
197
|
+
|
|
198
|
+
- #### Functions
|
|
199
|
+
|
|
200
|
+
- #### `setupI18n(config)`
|
|
201
|
+
|
|
202
|
+
> Initialize i18n with auto-detection
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
await setupI18n({
|
|
206
|
+
defaultLanguage : 'en',
|
|
207
|
+
supportedLanguages : ['en', 'ar', 'fr'],
|
|
208
|
+
basePath : '/i18n/', // URL (browser) or path (server)
|
|
209
|
+
fileExtension : 'json' // optional
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
- #### `t(key, params?)`
|
|
214
|
+
|
|
215
|
+
> Translate with parameter replacement
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
t('greeting', { name: 'John' }) // "Hello John"
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
- #### `tLang(key, lang, params?)`
|
|
222
|
+
|
|
223
|
+
> Translate with specific language
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
tLang('greeting', 'ar', { name: 'أحمد' })
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
- #### `tParse(key, params?)`
|
|
230
|
+
|
|
231
|
+
> Parse translation with HTML tags
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
tParse('message') // Returns TokenArray
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
- #### `setLanguage(lang)`
|
|
238
|
+
|
|
239
|
+
> Change current language
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
await setLanguage('ar')
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
- #### `getLanguage()`
|
|
246
|
+
|
|
247
|
+
> Get current language code
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
const lang = getLanguage() // 'en'
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
- #### `getSupportedLanguages()`
|
|
254
|
+
|
|
255
|
+
> Get all supported languages
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
const langs = getSupportedLanguages() // ['en', 'ar', 'fr']
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
- #### `isRTL()`
|
|
262
|
+
|
|
263
|
+
> Check if current language is RTL
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
if (isRTL()) { /* Handle RTL layout */ }
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
- #### `onChange(callback)`
|
|
270
|
+
|
|
271
|
+
> Subscribe to language changes
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
const unsubscribe = onChange((lang) => console.log('Changed to:', lang))
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
- #### `genPageTitle(key, prefix?)`
|
|
278
|
+
|
|
279
|
+
> Generate page title with app name
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
genPageTitle('home') // "Home - MyApp" or "MyApp - الرئيسية"
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
- #### `plural(count, singleKey, pluralKey)`
|
|
286
|
+
|
|
287
|
+
> Handle pluralization
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
plural(5, 'item.single', 'item.plural') // "5 items"
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
- #### `hasKey(key)`
|
|
294
|
+
|
|
295
|
+
> Check if translation exists
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
if (hasKey('settings.theme')) { /* ... */ }
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
- #### `loadLanguage(lang, translations)`
|
|
302
|
+
|
|
303
|
+
> Load translations for a language
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
loadLanguage('en', { greeting: 'Hello' })
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
- #### `loadTranslations(translations)`
|
|
310
|
+
|
|
311
|
+
> Load multiple languages at once
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
loadTranslations({
|
|
315
|
+
en: { greeting: 'Hello' },
|
|
316
|
+
ar: { greeting: 'مرحبا' }
|
|
317
|
+
})
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
|
|
321
|
+
|
|
322
|
+
- #### Related
|
|
323
|
+
|
|
324
|
+
- ##### [@cruxjs/app](https://github.com/cruxjs-org/app)
|
|
325
|
+
|
|
326
|
+
<!-- ╚═════════════════════════════════════════════════════════════════╝ -->
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
<!-- ╔══════════════════════════════ END ══════════════════════════════╗ -->
|
|
331
|
+
|
|
332
|
+
<br>
|
|
333
|
+
<br>
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
<div align="center">
|
|
338
|
+
<a href="https://github.com/maysara-elshewehy"><img src="https://img.shields.io/badge/by-Maysara-black"/></a>
|
|
339
|
+
</div>
|
|
340
|
+
|
|
341
341
|
<!-- ╚═════════════════════════════════════════════════════════════════╝ -->
|