@vaadin/hilla-react-i18n 24.4.0-alpha8 → 24.4.0-alpha9

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/backend.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { Translations } from './types.js';
2
+ export interface I18nBackend {
3
+ loadTranslations(language: string): Promise<Translations>;
4
+ }
5
+ export declare class DefaultBackend implements I18nBackend {
6
+ loadTranslations(language: string): Promise<Translations>;
7
+ }
8
+ //# sourceMappingURL=backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["src/backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,WAAW;IAC1B,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC3D;AAED,qBAAa,cAAe,YAAW,WAAW;IAC1C,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAShE"}
package/backend.js ADDED
@@ -0,0 +1,15 @@
1
+ class DefaultBackend {
2
+ async loadTranslations(language) {
3
+ const url = `./?v-r=i18n&langtag=${language}`;
4
+ return fetch(url).then(async (response) => {
5
+ if (response.status === 200) {
6
+ return response.json();
7
+ }
8
+ return Promise.reject(new Error(`Failed to load translations for language: ${language}`));
9
+ });
10
+ }
11
+ }
12
+ export {
13
+ DefaultBackend
14
+ };
15
+ //# sourceMappingURL=backend.js.map
package/backend.js.map ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["src/backend.ts"],
4
+ "sourcesContent": ["import type { Translations } from './types.js';\n\nexport interface I18nBackend {\n loadTranslations(language: string): Promise<Translations>;\n}\n\nexport class DefaultBackend implements I18nBackend {\n async loadTranslations(language: string): Promise<Translations> {\n const url = `./?v-r=i18n&langtag=${language}`;\n return fetch(url).then(async (response) => {\n if (response.status === 200) {\n return response.json();\n }\n return Promise.reject(new Error(`Failed to load translations for language: ${language}`));\n });\n }\n}\n"],
5
+ "mappings": "AAMO,MAAM,eAAsC;AAAA,EACjD,MAAM,iBAAiB,UAAyC;AAC9D,UAAM,MAAM,uBAAuB,QAAQ;AAC3C,WAAO,MAAM,GAAG,EAAE,KAAK,OAAO,aAAa;AACzC,UAAI,SAAS,WAAW,KAAK;AAC3B,eAAO,SAAS,KAAK;AAAA,MACvB;AACA,aAAO,QAAQ,OAAO,IAAI,MAAM,6CAA6C,QAAQ,EAAE,CAAC;AAAA,IAC1F,CAAC;AAAA,EACH;AACF;",
6
+ "names": []
7
+ }
package/index.d.ts CHANGED
@@ -1,4 +1,14 @@
1
+ import { type Signal } from '@vaadin/hilla-react-signals';
2
+ import type { I18nOptions } from './types.js';
1
3
  export declare class I18n {
4
+ #private;
5
+ get language(): Signal<string | undefined>;
6
+ configure(options?: I18nOptions): Promise<void>;
7
+ setLanguage(newLanguage: string): Promise<void>;
8
+ private updateLanguage;
9
+ private loadTranslations;
2
10
  translate(key: string): string;
3
11
  }
12
+ export declare const i18n: I18n;
13
+ export declare function translate(key: string): string;
4
14
  //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA,qBAAa,IAAI;IAEf,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAG/B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAGzE,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,YAAY,CAAC;AAgB5D,qBAAa,IAAI;;IAMf,IAAI,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAEzC;IAEK,SAAS,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/C,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAIvC,cAAc;YAmBd,gBAAgB;IAU9B,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAG/B;AAED,eAAO,MAAM,IAAI,MAAa,CAAC;AAE/B,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7C"}
package/index.js CHANGED
@@ -1,10 +1,64 @@
1
+ import { batch, signal } from "@vaadin/hilla-react-signals";
2
+ import { DefaultBackend } from "./backend.js";
3
+ import { getLanguageSettings, updateLanguageSettings } from "./settings.js";
4
+ function determineInitialLanguage(options) {
5
+ if (options?.language) {
6
+ return options.language;
7
+ }
8
+ const settings = getLanguageSettings();
9
+ if (settings?.language) {
10
+ return settings.language;
11
+ }
12
+ return navigator.language;
13
+ }
1
14
  class I18n {
2
- // eslint-disable-next-line @typescript-eslint/class-methods-use-this
15
+ #backend = new DefaultBackend();
16
+ #language = signal(void 0);
17
+ #translations = signal({});
18
+ get language() {
19
+ return this.#language;
20
+ }
21
+ async configure(options) {
22
+ const initialLanguage = determineInitialLanguage(options);
23
+ await this.updateLanguage(initialLanguage);
24
+ }
25
+ async setLanguage(newLanguage) {
26
+ await this.updateLanguage(newLanguage, true);
27
+ }
28
+ async updateLanguage(newLanguage, updateSettings = false) {
29
+ if (this.#language.value === newLanguage) {
30
+ return;
31
+ }
32
+ const newTranslations = await this.loadTranslations(newLanguage);
33
+ batch(() => {
34
+ this.#translations.value = newTranslations;
35
+ this.#language.value = newLanguage;
36
+ if (updateSettings) {
37
+ updateLanguageSettings({
38
+ language: newLanguage
39
+ });
40
+ }
41
+ });
42
+ }
43
+ async loadTranslations(newLanguage) {
44
+ try {
45
+ return await this.#backend.loadTranslations(newLanguage);
46
+ } catch (e) {
47
+ console.error(`Failed to load translations for language: ${newLanguage}`, e);
48
+ return {};
49
+ }
50
+ }
3
51
  translate(key) {
4
- return key;
52
+ return this.#translations.value[key] || key;
5
53
  }
6
54
  }
55
+ const i18n = new I18n();
56
+ function translate(key) {
57
+ return i18n.translate(key);
58
+ }
7
59
  export {
8
- I18n
60
+ I18n,
61
+ i18n,
62
+ translate
9
63
  };
10
64
  //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["src/index.ts"],
4
- "sourcesContent": ["export class I18n {\n // eslint-disable-next-line @typescript-eslint/class-methods-use-this\n translate(key: string): string {\n return key;\n }\n}\n"],
5
- "mappings": "AAAO,MAAM,KAAK;AAAA;AAAA,EAEhB,UAAU,KAAqB;AAC7B,WAAO;AAAA,EACT;AACF;",
4
+ "sourcesContent": ["import { batch, signal, type Signal } from '@vaadin/hilla-react-signals';\nimport { DefaultBackend, type I18nBackend } from './backend.js';\nimport { getLanguageSettings, updateLanguageSettings } from './settings.js';\nimport type { I18nOptions, Translations } from './types.js';\n\nfunction determineInitialLanguage(options?: I18nOptions): string {\n // Use explicitly configured language if defined\n if (options?.language) {\n return options.language;\n }\n // Use last used language as fallback\n const settings = getLanguageSettings();\n if (settings?.language) {\n return settings.language;\n }\n // Otherwise use browser language\n return navigator.language;\n}\n\nexport class I18n {\n readonly #backend: I18nBackend = new DefaultBackend();\n\n readonly #language: Signal<string | undefined> = signal(undefined);\n readonly #translations: Signal<Translations> = signal({});\n\n get language(): Signal<string | undefined> {\n return this.#language;\n }\n\n async configure(options?: I18nOptions): Promise<void> {\n const initialLanguage = determineInitialLanguage(options);\n await this.updateLanguage(initialLanguage);\n }\n\n async setLanguage(newLanguage: string): Promise<void> {\n await this.updateLanguage(newLanguage, true);\n }\n\n private async updateLanguage(newLanguage: string, updateSettings = false) {\n if (this.#language.value === newLanguage) {\n return;\n }\n\n const newTranslations = await this.loadTranslations(newLanguage);\n // Update all signals together to avoid triggering side effects multiple times\n batch(() => {\n this.#translations.value = newTranslations;\n this.#language.value = newLanguage;\n\n if (updateSettings) {\n updateLanguageSettings({\n language: newLanguage,\n });\n }\n });\n }\n\n private async loadTranslations(newLanguage: string) {\n try {\n return await this.#backend.loadTranslations(newLanguage);\n } catch (e) {\n // TODO proper error handling, maybe allow developer to hook into this\n console.error(`Failed to load translations for language: ${newLanguage}`, e);\n return {};\n }\n }\n\n translate(key: string): string {\n return this.#translations.value[key] || key;\n }\n}\n\nexport const i18n = new I18n();\n\nexport function translate(key: string): string {\n return i18n.translate(key);\n}\n"],
5
+ "mappings": "AAAA,SAAS,OAAO,cAA2B;AAC3C,SAAS,sBAAwC;AACjD,SAAS,qBAAqB,8BAA8B;AAG5D,SAAS,yBAAyB,SAA+B;AAE/D,MAAI,SAAS,UAAU;AACrB,WAAO,QAAQ;AAAA,EACjB;AAEA,QAAM,WAAW,oBAAoB;AACrC,MAAI,UAAU,UAAU;AACtB,WAAO,SAAS;AAAA,EAClB;AAEA,SAAO,UAAU;AACnB;AAEO,MAAM,KAAK;AAAA,EACP,WAAwB,IAAI,eAAe;AAAA,EAE3C,YAAwC,OAAO,MAAS;AAAA,EACxD,gBAAsC,OAAO,CAAC,CAAC;AAAA,EAExD,IAAI,WAAuC;AACzC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,UAAU,SAAsC;AACpD,UAAM,kBAAkB,yBAAyB,OAAO;AACxD,UAAM,KAAK,eAAe,eAAe;AAAA,EAC3C;AAAA,EAEA,MAAM,YAAY,aAAoC;AACpD,UAAM,KAAK,eAAe,aAAa,IAAI;AAAA,EAC7C;AAAA,EAEA,MAAc,eAAe,aAAqB,iBAAiB,OAAO;AACxE,QAAI,KAAK,UAAU,UAAU,aAAa;AACxC;AAAA,IACF;AAEA,UAAM,kBAAkB,MAAM,KAAK,iBAAiB,WAAW;AAE/D,UAAM,MAAM;AACV,WAAK,cAAc,QAAQ;AAC3B,WAAK,UAAU,QAAQ;AAEvB,UAAI,gBAAgB;AAClB,+BAAuB;AAAA,UACrB,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,iBAAiB,aAAqB;AAClD,QAAI;AACF,aAAO,MAAM,KAAK,SAAS,iBAAiB,WAAW;AAAA,IACzD,SAAS,GAAG;AAEV,cAAQ,MAAM,6CAA6C,WAAW,IAAI,CAAC;AAC3E,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,UAAU,KAAqB;AAC7B,WAAO,KAAK,cAAc,MAAM,GAAG,KAAK;AAAA,EAC1C;AACF;AAEO,MAAM,OAAO,IAAI,KAAK;AAEtB,SAAS,UAAU,KAAqB;AAC7C,SAAO,KAAK,UAAU,GAAG;AAC3B;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/hilla-react-i18n",
3
- "version": "24.4.0-alpha8",
3
+ "version": "24.4.0-alpha9",
4
4
  "description": "Hilla I18n utils for React",
5
5
  "main": "index.js",
6
6
  "module": "index.js",
@@ -45,6 +45,10 @@
45
45
  "publishConfig": {
46
46
  "access": "public"
47
47
  },
48
+ "dependencies": {
49
+ "@vaadin/hilla-frontend": "24.4.0-alpha9",
50
+ "@vaadin/hilla-react-signals": "24.4.0-alpha9"
51
+ },
48
52
  "peerDependencies": {
49
53
  "react": "^18"
50
54
  },
@@ -62,6 +66,7 @@
62
66
  "@types/validator": "^13.11.2",
63
67
  "chai-as-promised": "^7.1.1",
64
68
  "chai-dom": "^1.11.0",
69
+ "fetch-mock": "^9.11.0",
65
70
  "sinon": "^16.0.0",
66
71
  "sinon-chai": "^3.7.0",
67
72
  "typescript": "5.3.2"
package/settings.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export declare const VAADIN_LANGUAGE_SETTINGS_COOKIE_NAME = "vaadinLanguageSettings";
2
+ export interface LanguageSettings {
3
+ language?: string;
4
+ }
5
+ export declare function getLanguageSettings(): LanguageSettings | undefined;
6
+ export declare function updateLanguageSettings(updates: Partial<LanguageSettings>): void;
7
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["src/settings.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,oCAAoC,2BAA2B,CAAC;AAE7E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,mBAAmB,IAAI,gBAAgB,GAAG,SAAS,CAUlE;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAQ/E"}
package/settings.js ADDED
@@ -0,0 +1,27 @@
1
+ import CookieManager from "@vaadin/hilla-frontend/CookieManager.js";
2
+ const VAADIN_LANGUAGE_SETTINGS_COOKIE_NAME = "vaadinLanguageSettings";
3
+ function getLanguageSettings() {
4
+ const cookie = CookieManager.get(VAADIN_LANGUAGE_SETTINGS_COOKIE_NAME);
5
+ if (!cookie)
6
+ return void 0;
7
+ try {
8
+ return JSON.parse(cookie);
9
+ } catch (e) {
10
+ return void 0;
11
+ }
12
+ }
13
+ function updateLanguageSettings(updates) {
14
+ const settings = getLanguageSettings() ?? {};
15
+ const newSettings = {
16
+ ...settings,
17
+ ...updates
18
+ };
19
+ const json = JSON.stringify(newSettings);
20
+ CookieManager.set(VAADIN_LANGUAGE_SETTINGS_COOKIE_NAME, json);
21
+ }
22
+ export {
23
+ VAADIN_LANGUAGE_SETTINGS_COOKIE_NAME,
24
+ getLanguageSettings,
25
+ updateLanguageSettings
26
+ };
27
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["src/settings.ts"],
4
+ "sourcesContent": ["import CookieManager from '@vaadin/hilla-frontend/CookieManager.js';\n\nexport const VAADIN_LANGUAGE_SETTINGS_COOKIE_NAME = 'vaadinLanguageSettings';\n\nexport interface LanguageSettings {\n language?: string;\n}\n\nexport function getLanguageSettings(): LanguageSettings | undefined {\n const cookie = CookieManager.get(VAADIN_LANGUAGE_SETTINGS_COOKIE_NAME);\n if (!cookie) return undefined;\n\n try {\n return JSON.parse(cookie);\n } catch (e) {\n // Ignore\n return undefined;\n }\n}\n\nexport function updateLanguageSettings(updates: Partial<LanguageSettings>): void {\n const settings = getLanguageSettings() ?? {};\n const newSettings = {\n ...settings,\n ...updates,\n };\n const json = JSON.stringify(newSettings);\n CookieManager.set(VAADIN_LANGUAGE_SETTINGS_COOKIE_NAME, json);\n}\n"],
5
+ "mappings": "AAAA,OAAO,mBAAmB;AAEnB,MAAM,uCAAuC;AAM7C,SAAS,sBAAoD;AAClE,QAAM,SAAS,cAAc,IAAI,oCAAoC;AACrE,MAAI,CAAC;AAAQ,WAAO;AAEpB,MAAI;AACF,WAAO,KAAK,MAAM,MAAM;AAAA,EAC1B,SAAS,GAAG;AAEV,WAAO;AAAA,EACT;AACF;AAEO,SAAS,uBAAuB,SAA0C;AAC/E,QAAM,WAAW,oBAAoB,KAAK,CAAC;AAC3C,QAAM,cAAc;AAAA,IAClB,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AACA,QAAM,OAAO,KAAK,UAAU,WAAW;AACvC,gBAAc,IAAI,sCAAsC,IAAI;AAC9D;",
6
+ "names": []
7
+ }
package/types.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export type Translations = Record<string, string>;
2
+ export interface I18nOptions {
3
+ language?: string;
4
+ }
5
+ //# sourceMappingURL=types.d.ts.map
package/types.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAElD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
package/types.js ADDED
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.js.map
package/types.js.map ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }