anylang-dev 0.1.0 → 0.1.1
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 +51 -15
- package/package.json +1 -1
- package/src/pipeline.js +49 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ It works in JSX and TSX when the text is wrapped in a JavaScript expression:
|
|
|
11
11
|
|
|
12
12
|
```tsx
|
|
13
13
|
export function Hero() {
|
|
14
|
-
const $tr =
|
|
14
|
+
const $tr = useTr();
|
|
15
15
|
|
|
16
16
|
return (
|
|
17
17
|
<section>
|
|
@@ -32,22 +32,18 @@ By default, `anylang` scans `.js`, `.jsx`, `.ts`, `.tsx`, `.vue`, and `.html` fi
|
|
|
32
32
|
`anylang` does not require a built-in selector. Build any selector UI you want and pass the selected locale to `setLanguage`.
|
|
33
33
|
|
|
34
34
|
```tsx
|
|
35
|
-
const
|
|
36
|
-
const $tr = useAnyLang(language);
|
|
37
|
-
|
|
38
|
-
function handleLanguageChange(nextLanguage: LanguageCode) {
|
|
39
|
-
setLanguage(nextLanguage);
|
|
40
|
-
setSelectedLanguage(nextLanguage);
|
|
41
|
-
}
|
|
35
|
+
const { language, languages, setLanguage } = useLanguage();
|
|
42
36
|
|
|
43
37
|
return (
|
|
44
38
|
<select
|
|
45
39
|
value={language}
|
|
46
|
-
onChange={(event) =>
|
|
40
|
+
onChange={(event) => setLanguage(event.target.value as LanguageCode)}
|
|
47
41
|
>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
{languages.map((language) => (
|
|
43
|
+
<option key={language.code} value={language.code}>
|
|
44
|
+
{language.nativeLabel}
|
|
45
|
+
</option>
|
|
46
|
+
))}
|
|
51
47
|
</select>
|
|
52
48
|
);
|
|
53
49
|
```
|
|
@@ -221,11 +217,51 @@ Import the generated runtime file in your app:
|
|
|
221
217
|
|
|
222
218
|
```tsx
|
|
223
219
|
import {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
220
|
+
AnyLangProvider,
|
|
221
|
+
useLanguage,
|
|
222
|
+
useTr,
|
|
227
223
|
type LanguageCode
|
|
228
224
|
} from "./anylang.generated";
|
|
229
225
|
```
|
|
230
226
|
|
|
231
227
|
You do not manually import `en.json`, `hi.json`, `ja.json`, etc. The generated file does that for you based on `sourceLocale` and `targetLocales`.
|
|
228
|
+
|
|
229
|
+
Wrap your app once:
|
|
230
|
+
|
|
231
|
+
```tsx
|
|
232
|
+
root.render(
|
|
233
|
+
<AnyLangProvider>
|
|
234
|
+
<App />
|
|
235
|
+
</AnyLangProvider>
|
|
236
|
+
);
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Then use translations in any component:
|
|
240
|
+
|
|
241
|
+
```tsx
|
|
242
|
+
function Hero() {
|
|
243
|
+
const $tr = useTr();
|
|
244
|
+
return <h1>{$tr("hero.title", "Translate your website with anylang")}</h1>;
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
And build any selector with `useLanguage`:
|
|
249
|
+
|
|
250
|
+
```tsx
|
|
251
|
+
function LanguageSelector() {
|
|
252
|
+
const { language, languages, setLanguage } = useLanguage();
|
|
253
|
+
|
|
254
|
+
return (
|
|
255
|
+
<select
|
|
256
|
+
value={language}
|
|
257
|
+
onChange={(event) => setLanguage(event.target.value as LanguageCode)}
|
|
258
|
+
>
|
|
259
|
+
{languages.map((language) => (
|
|
260
|
+
<option key={language.code} value={language.code}>
|
|
261
|
+
{language.nativeLabel}
|
|
262
|
+
</option>
|
|
263
|
+
))}
|
|
264
|
+
</select>
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
```
|
package/package.json
CHANGED
package/src/pipeline.js
CHANGED
|
@@ -159,7 +159,7 @@ function generatedRuntimeSource({ importFrom, localeImports, sourceLocale }) {
|
|
|
159
159
|
.join(",\n");
|
|
160
160
|
|
|
161
161
|
return `/* This file is generated by anylang. Do not edit by hand. */
|
|
162
|
-
import { useCallback } from 'react'
|
|
162
|
+
import { createContext, createElement, useCallback, useContext, useMemo, useState, type ReactNode } from 'react'
|
|
163
163
|
import { $tr as translate, configureAnyLang, setAnyLangLocale } from '${importFrom}'
|
|
164
164
|
${imports}
|
|
165
165
|
|
|
@@ -185,6 +185,54 @@ export function useAnyLang(locale: LanguageCode) {
|
|
|
185
185
|
export function setLanguage(locale: LanguageCode) {
|
|
186
186
|
setAnyLangLocale(locale)
|
|
187
187
|
}
|
|
188
|
+
|
|
189
|
+
type AnyLangContextValue = {
|
|
190
|
+
language: LanguageCode
|
|
191
|
+
languages: typeof languages
|
|
192
|
+
setLanguage: (locale: LanguageCode) => void
|
|
193
|
+
$tr: (key: string, source?: string) => string
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const AnyLangContext = createContext<AnyLangContextValue | null>(null)
|
|
197
|
+
|
|
198
|
+
export function AnyLangProvider({
|
|
199
|
+
children,
|
|
200
|
+
defaultLanguage = '${sourceLocale}' as LanguageCode,
|
|
201
|
+
}: {
|
|
202
|
+
children: ReactNode
|
|
203
|
+
defaultLanguage?: LanguageCode
|
|
204
|
+
}) {
|
|
205
|
+
const [language, setSelectedLanguage] = useState<LanguageCode>(defaultLanguage)
|
|
206
|
+
const $tr = useAnyLang(language)
|
|
207
|
+
|
|
208
|
+
const value = useMemo(() => ({
|
|
209
|
+
language,
|
|
210
|
+
languages,
|
|
211
|
+
setLanguage(nextLanguage: LanguageCode) {
|
|
212
|
+
setAnyLangLocale(nextLanguage)
|
|
213
|
+
setSelectedLanguage(nextLanguage)
|
|
214
|
+
},
|
|
215
|
+
$tr,
|
|
216
|
+
}), [language, $tr])
|
|
217
|
+
|
|
218
|
+
return createElement(AnyLangContext.Provider, { value }, children)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export function useLanguage() {
|
|
222
|
+
const context = useContext(AnyLangContext)
|
|
223
|
+
if (!context) throw new Error('useLanguage must be used inside AnyLangProvider')
|
|
224
|
+
return {
|
|
225
|
+
language: context.language,
|
|
226
|
+
languages: context.languages,
|
|
227
|
+
setLanguage: context.setLanguage,
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export function useTr() {
|
|
232
|
+
const context = useContext(AnyLangContext)
|
|
233
|
+
if (!context) throw new Error('useTr must be used inside AnyLangProvider')
|
|
234
|
+
return context.$tr
|
|
235
|
+
}
|
|
188
236
|
`;
|
|
189
237
|
}
|
|
190
238
|
|