@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 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.5-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
-
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
  <!-- ╚═════════════════════════════════════════════════════════════════╝ -->