kotori 3.0.4 → 3.1.0
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 +11 -6
- package/dist/index.cjs +7 -5
- package/dist/index.d.cts +4 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.mjs +7 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
Strongly-typed, modular i18n for React. Variables are inferred directly from your strings — no codegen, no JSON, no schema files.
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
|
-
const { dict } = kotori({
|
|
8
|
+
const { dict, t } = kotori({
|
|
9
9
|
primaryLanguageTag: 'en',
|
|
10
10
|
secondaryLanguageTags: ['zh', 'ja', 'ms'],
|
|
11
11
|
})
|
|
@@ -26,16 +26,16 @@ const intro = dict({
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
// ✅ Works
|
|
29
|
-
t(
|
|
29
|
+
t(intro, { name: 'John', time: '12:25' })
|
|
30
30
|
|
|
31
31
|
// ❌ TypeScript error: missing { name }
|
|
32
|
-
t(
|
|
32
|
+
t(intro, { time: '12:25' })
|
|
33
33
|
|
|
34
34
|
// ❌ TypeScript error: unknown key 'nama'
|
|
35
|
-
t(
|
|
35
|
+
t(intro, { nama: 'John', time: '12:25' })
|
|
36
36
|
|
|
37
37
|
// ❌ TypeScript error: invalid format for 'time'
|
|
38
|
-
t(
|
|
38
|
+
t(intro, { name: 'John', time: '12-00' })
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
- No codegen
|
|
@@ -180,7 +180,7 @@ export const { useT, dict, setLanguage } = kotori({
|
|
|
180
180
|
| `primaryLanguageTag` | `BCP47LanguageTag` | The source language. Drives variable inference. |
|
|
181
181
|
| `secondaryLanguageTags` | `BCP47LanguageTag[]` | Additional supported languages. |
|
|
182
182
|
|
|
183
|
-
Returns `{ dict, useT, setLanguage }`.
|
|
183
|
+
Returns `{ dict, useT, setLanguage, t }`.
|
|
184
184
|
|
|
185
185
|
### `dict(translations)<argsType?>`
|
|
186
186
|
|
|
@@ -203,6 +203,10 @@ const time = dict({ en: '{{hour}}:{{minute}}' })<{
|
|
|
203
203
|
|
|
204
204
|
Updates the current language and rerenders all active `useT` consumers across all pages. Available directly on the `kotori` instance — useful for calling outside of React (route guards, axios interceptors, etc.).
|
|
205
205
|
|
|
206
|
+
### `t(dict, args?)`
|
|
207
|
+
|
|
208
|
+
Returns the translated string for the current language. `args` is required if the string has variables, omitted if it doesn't. Available directly on the `kotori` instance for non-React usage, but typically accessed via the `useT` hook.
|
|
209
|
+
|
|
206
210
|
### `useT()`
|
|
207
211
|
|
|
208
212
|
React hook. Returns `{ t, language, setLanguage }`.
|
|
@@ -224,6 +228,7 @@ kotori uses [BCP 47](https://www.iana.org/assignments/language-subtag-registry/l
|
|
|
224
228
|
- Pluralization support
|
|
225
229
|
- Gender support
|
|
226
230
|
- Value formatting (date, number, currency)
|
|
231
|
+
- Support for non-React frameworks (Vue, Svelte, Angular, etc.)
|
|
227
232
|
|
|
228
233
|
## Trivial
|
|
229
234
|
|
package/dist/index.cjs
CHANGED
|
@@ -20,17 +20,19 @@ const kotori = (props) => {
|
|
|
20
20
|
listeners.delete(listener);
|
|
21
21
|
};
|
|
22
22
|
};
|
|
23
|
+
const t = (dict, ...args) => {
|
|
24
|
+
let locale = dict().translation[language] || "unable_to_load_translations";
|
|
25
|
+
for (const objKey in args[0]) locale = locale.replace(new RegExp(`\\{\\{\\s*${objKey}\\s*\\}\\}`, "g"), () => String(args[0]?.[objKey]));
|
|
26
|
+
return locale;
|
|
27
|
+
};
|
|
23
28
|
let snapshot = {
|
|
24
29
|
language,
|
|
25
30
|
setLanguage,
|
|
26
|
-
t
|
|
27
|
-
let locale = dict().translation[language] || "unable_to_load_translations";
|
|
28
|
-
for (const objKey in args[0]) locale = locale.replace(new RegExp(`\\{\\{\\s*${objKey}\\s*\\}\\}`, "g"), () => String(args[0]?.[objKey]));
|
|
29
|
-
return locale;
|
|
30
|
-
}
|
|
31
|
+
t
|
|
31
32
|
};
|
|
32
33
|
return {
|
|
33
34
|
setLanguage,
|
|
35
|
+
t,
|
|
34
36
|
dict: (translation) => () => ({ translation }),
|
|
35
37
|
useT: () => (0, react.useSyncExternalStore)(subscribe, () => snapshot, () => snapshot)
|
|
36
38
|
};
|
package/dist/index.d.cts
CHANGED
|
@@ -13,6 +13,10 @@ declare const kotori: <const PrimaryTag extends AllTags, const SecondaryTags ext
|
|
|
13
13
|
secondaryLanguageTags: SecondaryTags[];
|
|
14
14
|
}) => {
|
|
15
15
|
setLanguage: (tag: PrimaryTag | SecondaryTags) => void;
|
|
16
|
+
t: <DictCallback extends () => Readonly<{
|
|
17
|
+
translation: Record<PrimaryTag | SecondaryTags, string>;
|
|
18
|
+
[_args]?: Record<string, string | number>;
|
|
19
|
+
}>>(dict: DictCallback, ...args: keyof NonNullable<ReturnType<DictCallback>[typeof _args]> extends never ? [] : [NonNullable<ReturnType<DictCallback>[typeof _args]>]) => string;
|
|
16
20
|
dict: <const PrimaryString extends string, const SecondaryObject extends { [Key in SecondaryTags]: ExtractVariables<PrimaryString> extends infer PrimaryVariables ? ExtractVariables<SecondaryObject[Key] & string> extends infer SecondaryVariables ? PrimaryVariables[] extends SecondaryVariables[] ? SecondaryVariables[] extends PrimaryVariables[] ? SecondaryObject[Key] : "variables not match!" : "variables not match!!" : never : never }>(translation: { [Key in PrimaryTag]: PrimaryString } & SecondaryObject) => <const ArgsType extends Record<ExtractVariables<PrimaryString>, string | number> = Record<ExtractVariables<PrimaryString>, string | number>>() => Readonly<{
|
|
17
21
|
translation: typeof translation;
|
|
18
22
|
[_args]?: ArgsType;
|
package/dist/index.d.mts
CHANGED
|
@@ -13,6 +13,10 @@ declare const kotori: <const PrimaryTag extends AllTags, const SecondaryTags ext
|
|
|
13
13
|
secondaryLanguageTags: SecondaryTags[];
|
|
14
14
|
}) => {
|
|
15
15
|
setLanguage: (tag: PrimaryTag | SecondaryTags) => void;
|
|
16
|
+
t: <DictCallback extends () => Readonly<{
|
|
17
|
+
translation: Record<PrimaryTag | SecondaryTags, string>;
|
|
18
|
+
[_args]?: Record<string, string | number>;
|
|
19
|
+
}>>(dict: DictCallback, ...args: keyof NonNullable<ReturnType<DictCallback>[typeof _args]> extends never ? [] : [NonNullable<ReturnType<DictCallback>[typeof _args]>]) => string;
|
|
16
20
|
dict: <const PrimaryString extends string, const SecondaryObject extends { [Key in SecondaryTags]: ExtractVariables<PrimaryString> extends infer PrimaryVariables ? ExtractVariables<SecondaryObject[Key] & string> extends infer SecondaryVariables ? PrimaryVariables[] extends SecondaryVariables[] ? SecondaryVariables[] extends PrimaryVariables[] ? SecondaryObject[Key] : "variables not match!" : "variables not match!!" : never : never }>(translation: { [Key in PrimaryTag]: PrimaryString } & SecondaryObject) => <const ArgsType extends Record<ExtractVariables<PrimaryString>, string | number> = Record<ExtractVariables<PrimaryString>, string | number>>() => Readonly<{
|
|
17
21
|
translation: typeof translation;
|
|
18
22
|
[_args]?: ArgsType;
|
package/dist/index.mjs
CHANGED
|
@@ -19,17 +19,19 @@ const kotori = (props) => {
|
|
|
19
19
|
listeners.delete(listener);
|
|
20
20
|
};
|
|
21
21
|
};
|
|
22
|
+
const t = (dict, ...args) => {
|
|
23
|
+
let locale = dict().translation[language] || "unable_to_load_translations";
|
|
24
|
+
for (const objKey in args[0]) locale = locale.replace(new RegExp(`\\{\\{\\s*${objKey}\\s*\\}\\}`, "g"), () => String(args[0]?.[objKey]));
|
|
25
|
+
return locale;
|
|
26
|
+
};
|
|
22
27
|
let snapshot = {
|
|
23
28
|
language,
|
|
24
29
|
setLanguage,
|
|
25
|
-
t
|
|
26
|
-
let locale = dict().translation[language] || "unable_to_load_translations";
|
|
27
|
-
for (const objKey in args[0]) locale = locale.replace(new RegExp(`\\{\\{\\s*${objKey}\\s*\\}\\}`, "g"), () => String(args[0]?.[objKey]));
|
|
28
|
-
return locale;
|
|
29
|
-
}
|
|
30
|
+
t
|
|
30
31
|
};
|
|
31
32
|
return {
|
|
32
33
|
setLanguage,
|
|
34
|
+
t,
|
|
33
35
|
dict: (translation) => () => ({ translation }),
|
|
34
36
|
useT: () => useSyncExternalStore(subscribe, () => snapshot, () => snapshot)
|
|
35
37
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kotori",
|
|
3
3
|
"description": "Strongly-typed and composable internationalization library for React",
|
|
4
|
-
"version": "3.0
|
|
4
|
+
"version": "3.1.0",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"setup": "rm -rf node_modules && npm i && git init && husky",
|
|
7
7
|
"prepublishOnly": "npm i && npx tsc && npm run build",
|