@wsxjs/wsx-i18next 0.0.18 → 0.0.19

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.
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @i18n 装饰器 - 自动为组件注入翻译功能
3
+ */
4
+ /**
5
+ * @i18n 装饰器 - 自动为组件注入翻译功能
6
+ *
7
+ * 使用方式:
8
+ * ```tsx
9
+ * @i18n('common')
10
+ * export class MyComponent extends WebComponent {
11
+ * render() {
12
+ * return <div>{this.t('welcome')}</div>;
13
+ * }
14
+ * }
15
+ * ```
16
+ *
17
+ * @param namespace 命名空间,默认为 'common'
18
+ * @returns 类装饰器
19
+ */
20
+ export declare function i18nDecorator(namespace?: string): <T extends {
21
+ new (...args: any[]): any;
22
+ }>(constructor: T) => T;
23
+ //# sourceMappingURL=decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorator.d.ts","sourceRoot":"","sources":["../src/decorator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,SAAS,GAAE,MAAiB,IAErC,CAAC,SAAS;IAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAA;CAAE,EAAE,aAAa,CAAC,KAkG7C,CAAC,CAE/B"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * useTranslation 函数(API 与 react-i18next 兼容)
3
+ */
4
+ import type { UseTranslationResponse } from "./types";
5
+ /**
6
+ * useTranslation - API 与 react-i18next 兼容的翻译函数
7
+ *
8
+ * **重要说明**:
9
+ * - 这不是 React hook,而是 WSXJS 的普通函数
10
+ * - API 设计参考 react-i18next,但实现方式完全不同
11
+ * - 在 WSXJS 中,需要配合 @state 或 @i18n 装饰器实现响应式
12
+ * - 不会自动响应语言变化,需要手动订阅 languageChanged 事件
13
+ *
14
+ * @param namespace 命名空间,默认为 'common'
15
+ * @returns 翻译对象
16
+ */
17
+ export declare function useTranslation(namespace?: string): UseTranslationResponse;
18
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEtD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,SAAS,GAAE,MAAiB,GAAG,sBAAsB,CAanF"}
package/dist/i18n.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * i18next 配置和初始化
3
+ */
4
+ import i18next from "i18next";
5
+ import type { I18nConfig } from "./types";
6
+ /**
7
+ * 初始化 i18next
8
+ * @param config 配置选项
9
+ * @returns i18n 实例
10
+ */
11
+ export declare function initI18n(config?: I18nConfig): typeof i18next;
12
+ export declare const i18n: typeof i18next;
13
+ //# sourceMappingURL=i18n.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,OAAO,MAAM,SAAS,CAAC;AAG9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,GAAE,UAAe,GAAG,OAAO,OAAO,CAmBhE;AAGD,eAAO,MAAM,IAAI,EAAE,OAAO,OAAiB,CAAC"}
@@ -1,9 +1,10 @@
1
- // src/i18n.ts
2
- import i18n from "i18next";
3
- import LanguageDetector from "i18next-browser-languagedetector";
4
- import Backend from "i18next-http-backend";
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const i18next = require("i18next");
4
+ const LanguageDetector = require("i18next-browser-languagedetector");
5
+ const Backend = require("i18next-http-backend");
5
6
  function initI18n(config = {}) {
6
- i18n.use(Backend).use(LanguageDetector).init({
7
+ i18next.use(Backend).use(LanguageDetector).init({
7
8
  fallbackLng: "en",
8
9
  debug: false,
9
10
  interpolation: {
@@ -16,10 +17,9 @@ function initI18n(config = {}) {
16
17
  defaultNS: "common",
17
18
  ...config
18
19
  });
19
- return i18n;
20
+ return i18next;
20
21
  }
21
-
22
- // src/decorator.ts
22
+ const i18n = i18next;
23
23
  function i18nDecorator(namespace = "common") {
24
24
  return function(constructor) {
25
25
  class I18nEnhanced extends constructor {
@@ -38,7 +38,8 @@ function i18nDecorator(namespace = "common") {
38
38
  }
39
39
  // 生命周期:组件连接时订阅语言变化
40
40
  onConnected() {
41
- super.onConnected?.();
41
+ var _a;
42
+ (_a = super.onConnected) == null ? void 0 : _a.call(this);
42
43
  const handler = () => {
43
44
  if (this.rerender) {
44
45
  this.rerender();
@@ -58,6 +59,7 @@ function i18nDecorator(namespace = "common") {
58
59
  }
59
60
  // 生命周期:组件断开时取消订阅
60
61
  onDisconnected() {
62
+ var _a;
61
63
  if (this._i18nUnsubscribe && typeof this._i18nUnsubscribe === "function") {
62
64
  try {
63
65
  this._i18nUnsubscribe();
@@ -77,7 +79,7 @@ function i18nDecorator(namespace = "common") {
77
79
  if (this._languageChangedHandler) {
78
80
  delete this._languageChangedHandler;
79
81
  }
80
- super.onDisconnected?.();
82
+ (_a = super.onDisconnected) == null ? void 0 : _a.call(this);
81
83
  }
82
84
  }
83
85
  Object.setPrototypeOf(I18nEnhanced, constructor);
@@ -88,8 +90,6 @@ function i18nDecorator(namespace = "common") {
88
90
  return I18nEnhanced;
89
91
  };
90
92
  }
91
-
92
- // src/hooks.ts
93
93
  function useTranslation(namespace = "common") {
94
94
  const t = (key, options) => {
95
95
  return i18n.t(key, { ns: namespace, ...options });
@@ -101,8 +101,6 @@ function useTranslation(namespace = "common") {
101
101
  ready: i18n.isInitialized
102
102
  };
103
103
  }
104
-
105
- // src/mixin.ts
106
104
  function withI18n(Base, defaultNamespace = "common") {
107
105
  return class extends Base {
108
106
  t(key, namespace, options) {
@@ -120,11 +118,10 @@ function withI18n(Base, defaultNamespace = "common") {
120
118
  }
121
119
  };
122
120
  }
123
- export {
124
- i18nDecorator as i18n,
125
- i18nDecorator,
126
- i18n as i18nInstance,
127
- initI18n,
128
- useTranslation,
129
- withI18n
130
- };
121
+ exports.i18n = i18nDecorator;
122
+ exports.i18nDecorator = i18nDecorator;
123
+ exports.i18nInstance = i18n;
124
+ exports.initI18n = initI18n;
125
+ exports.useTranslation = useTranslation;
126
+ exports.withI18n = withI18n;
127
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/i18n.ts","../src/decorator.ts","../src/hooks.ts","../src/mixin.ts"],"sourcesContent":["/**\n * i18next 配置和初始化\n */\n\nimport i18next from \"i18next\";\nimport LanguageDetector from \"i18next-browser-languagedetector\";\nimport Backend from \"i18next-http-backend\";\nimport type { I18nConfig } from \"./types\";\n\n/**\n * 初始化 i18next\n * @param config 配置选项\n * @returns i18n 实例\n */\nexport function initI18n(config: I18nConfig = {}): typeof i18next {\n i18next\n .use(Backend)\n .use(LanguageDetector)\n .init({\n fallbackLng: \"en\",\n debug: false,\n interpolation: {\n escapeValue: false,\n },\n backend: {\n loadPath: \"/locales/{{lng}}/{{ns}}.json\",\n },\n ns: [\"common\", \"home\", \"docs\", \"examples\"],\n defaultNS: \"common\",\n ...config,\n });\n\n return i18next;\n}\n\n// 导出 i18n 实例(直接导出常量)\nexport const i18n: typeof i18next = i18next;\n","/**\n * @i18n 装饰器 - 自动为组件注入翻译功能\n */\n\nimport { i18n } from \"./i18n\";\n\n/**\n * @i18n 装饰器 - 自动为组件注入翻译功能\n *\n * 使用方式:\n * ```tsx\n * @i18n('common')\n * export class MyComponent extends WebComponent {\n * render() {\n * return <div>{this.t('welcome')}</div>;\n * }\n * }\n * ```\n *\n * @param namespace 命名空间,默认为 'common'\n * @returns 类装饰器\n */\nexport function i18nDecorator(namespace: string = \"common\") {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return function <T extends { new (...args: any[]): any }>(constructor: T) {\n class I18nEnhanced extends constructor {\n // 使用 public 而不是 private,因为导出的匿名类类型限制\n public _i18nNamespace!: string;\n public _i18nUnsubscribe?: () => void;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(...args: any[]) {\n super(...args);\n // 初始化命名空间\n this._i18nNamespace = namespace;\n }\n\n // 注入 t 方法\n public t(key: string, options?: object): string {\n return i18n.t(key, { ns: this._i18nNamespace, ...options });\n }\n\n // 注入 i18n 实例\n public get i18n() {\n return i18n;\n }\n\n // 生命周期:组件连接时订阅语言变化\n public onConnected(): void {\n // 先调用父类的 onConnected(如果存在)\n super.onConnected?.();\n\n // 创建回调函数并保存引用,以便后续取消订阅\n const handler = (() => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((this as any).rerender) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this as any).rerender();\n }\n }) as () => void;\n\n // 保存回调引用以便取消订阅\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this as any)._languageChangedHandler = handler;\n\n // 订阅语言变化事件\n const unsubscribe = i18n.on(\"languageChanged\", handler);\n\n // 如果返回的是函数,直接使用;否则使用 off 方法\n if (typeof unsubscribe === \"function\") {\n this._i18nUnsubscribe = unsubscribe;\n } else {\n // 如果 i18n.on 返回的不是函数,创建一个取消订阅函数\n // 使用 off 方法(如果可用)或空函数\n this._i18nUnsubscribe = () => {\n if (typeof i18n.off === \"function\") {\n i18n.off(\"languageChanged\", handler);\n }\n };\n }\n }\n\n // 生命周期:组件断开时取消订阅\n public onDisconnected(): void {\n // 取消 i18n 订阅\n if (this._i18nUnsubscribe && typeof this._i18nUnsubscribe === \"function\") {\n try {\n this._i18nUnsubscribe();\n } catch {\n // 如果 unsubscribe 调用失败,尝试使用 off 方法(如果可用)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const handler = (this as any)._languageChangedHandler;\n if (handler && typeof i18n.off === \"function\") {\n i18n.off(\"languageChanged\", handler);\n }\n }\n this._i18nUnsubscribe = undefined;\n } else {\n // 如果 unsubscribe 不是函数,尝试使用 off 方法(如果可用)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const handler = (this as any)._languageChangedHandler;\n if (handler && typeof i18n.off === \"function\") {\n i18n.off(\"languageChanged\", handler);\n }\n }\n // 清理回调引用\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((this as any)._languageChangedHandler) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n delete (this as any)._languageChangedHandler;\n }\n\n // 调用父类的 onDisconnected(如果存在)\n super.onDisconnected?.();\n }\n }\n // 复制静态属性和方法\n Object.setPrototypeOf(I18nEnhanced, constructor);\n Object.defineProperty(I18nEnhanced, \"name\", {\n value: constructor.name,\n writable: false,\n });\n return I18nEnhanced as T;\n };\n}\n","/**\n * useTranslation 函数(API 与 react-i18next 兼容)\n */\n\nimport { i18n } from \"./i18n\";\nimport type { UseTranslationResponse } from \"./types\";\n\n/**\n * useTranslation - API 与 react-i18next 兼容的翻译函数\n *\n * **重要说明**:\n * - 这不是 React hook,而是 WSXJS 的普通函数\n * - API 设计参考 react-i18next,但实现方式完全不同\n * - 在 WSXJS 中,需要配合 @state 或 @i18n 装饰器实现响应式\n * - 不会自动响应语言变化,需要手动订阅 languageChanged 事件\n *\n * @param namespace 命名空间,默认为 'common'\n * @returns 翻译对象\n */\nexport function useTranslation(namespace: string = \"common\"): UseTranslationResponse {\n // 创建一个包装函数,保持 API 兼容性\n const t = (key: string, options?: object): string => {\n // 每次调用 t() 时,i18n.t() 会使用当前的 i18n.language\n // 所以只要组件重渲染,就会得到新的翻译\n return i18n.t(key, { ns: namespace, ...options });\n };\n return {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n t: t as any,\n i18n,\n ready: i18n.isInitialized,\n };\n}\n","/**\n * Mixin API - 为基类添加 i18n 支持\n */\n\nimport { i18n } from \"./i18n\";\nimport type { WebComponent, LightComponent } from \"@wsxjs/wsx-core\";\n\n/**\n * 为任何继承自 WebComponent 或 LightComponent 的类添加 i18n 支持\n *\n * 使用方式:\n * ```tsx\n * export class MyComponent extends withI18n(WebComponent, 'common') {\n * render() {\n * return <div>{this.t('welcome')}</div>;\n * }\n * }\n *\n * export class MyLightComponent extends withI18n(LightComponent, 'common') {\n * render() {\n * return <div>{this.t('welcome')}</div>;\n * }\n * }\n * ```\n *\n * @param Base 基类(WebComponent 或 LightComponent)\n * @param defaultNamespace 默认命名空间\n * @returns 增强后的类\n */\nexport function withI18n<T extends typeof WebComponent | typeof LightComponent>(\n Base: T,\n defaultNamespace: string = \"common\"\n): T {\n return class extends Base {\n protected t(key: string, namespace?: string, options?: object): string {\n return i18n.t(key, { ns: namespace || defaultNamespace, ...options });\n }\n\n protected get i18n() {\n return i18n;\n }\n\n protected onConnected(): void {\n // 订阅语言变化事件,自动触发重渲染\n i18n.on(\"languageChanged\", () => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((this as any).rerender) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this as any).rerender();\n }\n });\n }\n } as T;\n}\n"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,114 +1,13 @@
1
- import i18n$1, { TFunction, i18n } from 'i18next';
2
- export { default as i18nInstance } from 'i18next';
3
- import { WebComponent, LightComponent } from '@wsxjs/wsx-core';
4
-
5
1
  /**
6
- * TypeScript 类型定义
7
- */
8
-
9
- /**
10
- * i18n 配置接口
11
- */
12
- interface I18nConfig {
13
- fallbackLng?: string;
14
- debug?: boolean;
15
- resources?: Record<string, Record<string, object>>;
16
- backend?: {
17
- loadPath?: string;
18
- };
19
- ns?: string[];
20
- defaultNS?: string;
21
- interpolation?: {
22
- escapeValue?: boolean;
23
- };
24
- }
25
- /**
26
- * useTranslation 返回类型
27
- */
28
- interface UseTranslationResponse {
29
- t: TFunction;
30
- i18n: i18n;
31
- ready: boolean;
32
- }
33
-
34
- /**
35
- * i18next 配置和初始化
36
- */
37
-
38
- /**
39
- * 初始化 i18next
40
- * @param config 配置选项
41
- * @returns i18n 实例
42
- */
43
- declare function initI18n(config?: I18nConfig): typeof i18n$1;
44
-
45
- /**
46
- * @i18n 装饰器 - 自动为组件注入翻译功能
47
- */
48
- /**
49
- * @i18n 装饰器 - 自动为组件注入翻译功能
50
- *
51
- * 使用方式:
52
- * ```tsx
53
- * @i18n('common')
54
- * export class MyComponent extends WebComponent {
55
- * render() {
56
- * return <div>{this.t('welcome')}</div>;
57
- * }
58
- * }
59
- * ```
60
- *
61
- * @param namespace 命名空间,默认为 'common'
62
- * @returns 类装饰器
63
- */
64
- declare function i18nDecorator(namespace?: string): <T extends {
65
- new (...args: any[]): any;
66
- }>(constructor: T) => T;
67
-
68
- /**
69
- * useTranslation 函数(API 与 react-i18next 兼容)
70
- */
71
-
72
- /**
73
- * useTranslation - API 与 react-i18next 兼容的翻译函数
74
- *
75
- * **重要说明**:
76
- * - 这不是 React hook,而是 WSXJS 的普通函数
77
- * - API 设计参考 react-i18next,但实现方式完全不同
78
- * - 在 WSXJS 中,需要配合 @state 或 @i18n 装饰器实现响应式
79
- * - 不会自动响应语言变化,需要手动订阅 languageChanged 事件
80
- *
81
- * @param namespace 命名空间,默认为 'common'
82
- * @returns 翻译对象
83
- */
84
- declare function useTranslation(namespace?: string): UseTranslationResponse;
85
-
86
- /**
87
- * Mixin API - 为基类添加 i18n 支持
88
- */
89
-
90
- /**
91
- * 为任何继承自 WebComponent 或 LightComponent 的类添加 i18n 支持
92
- *
93
- * 使用方式:
94
- * ```tsx
95
- * export class MyComponent extends withI18n(WebComponent, 'common') {
96
- * render() {
97
- * return <div>{this.t('welcome')}</div>;
98
- * }
99
- * }
100
- *
101
- * export class MyLightComponent extends withI18n(LightComponent, 'common') {
102
- * render() {
103
- * return <div>{this.t('welcome')}</div>;
104
- * }
105
- * }
106
- * ```
2
+ * @wsxjs/wsx-i18next - i18next integration for WSXJS components
107
3
  *
108
- * @param Base 基类(WebComponent LightComponent)
109
- * @param defaultNamespace 默认命名空间
110
- * @returns 增强后的类
4
+ * WSXJS 组件提供 i18next 国际化支持
111
5
  */
112
- declare function withI18n<T extends typeof WebComponent | typeof LightComponent>(Base: T, defaultNamespace?: string): T;
113
-
114
- export { type I18nConfig, type UseTranslationResponse, i18nDecorator as i18n, i18nDecorator, initI18n, useTranslation, withI18n };
6
+ import { i18n as i18nInstance, initI18n } from "./i18n";
7
+ export { i18nInstance, initI18n };
8
+ import { i18nDecorator } from "./decorator";
9
+ export { i18nDecorator as i18n, i18nDecorator };
10
+ export { useTranslation } from "./hooks";
11
+ export { withI18n } from "./mixin";
12
+ export type { I18nConfig, UseTranslationResponse } from "./types";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;AAGlC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,IAAI,IAAI,EAAE,aAAa,EAAE,CAAC;AAGhD,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGnC,YAAY,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,50 +1,8 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
33
- i18n: () => i18nDecorator,
34
- i18nDecorator: () => i18nDecorator,
35
- i18nInstance: () => import_i18next.default,
36
- initI18n: () => initI18n,
37
- useTranslation: () => useTranslation,
38
- withI18n: () => withI18n
39
- });
40
- module.exports = __toCommonJS(index_exports);
41
-
42
- // src/i18n.ts
43
- var import_i18next = __toESM(require("i18next"));
44
- var import_i18next_browser_languagedetector = __toESM(require("i18next-browser-languagedetector"));
45
- var import_i18next_http_backend = __toESM(require("i18next-http-backend"));
1
+ import i18next from "i18next";
2
+ import LanguageDetector from "i18next-browser-languagedetector";
3
+ import Backend from "i18next-http-backend";
46
4
  function initI18n(config = {}) {
47
- import_i18next.default.use(import_i18next_http_backend.default).use(import_i18next_browser_languagedetector.default).init({
5
+ i18next.use(Backend).use(LanguageDetector).init({
48
6
  fallbackLng: "en",
49
7
  debug: false,
50
8
  interpolation: {
@@ -57,10 +15,9 @@ function initI18n(config = {}) {
57
15
  defaultNS: "common",
58
16
  ...config
59
17
  });
60
- return import_i18next.default;
18
+ return i18next;
61
19
  }
62
-
63
- // src/decorator.ts
20
+ const i18n = i18next;
64
21
  function i18nDecorator(namespace = "common") {
65
22
  return function(constructor) {
66
23
  class I18nEnhanced extends constructor {
@@ -71,54 +28,56 @@ function i18nDecorator(namespace = "common") {
71
28
  }
72
29
  // 注入 t 方法
73
30
  t(key, options) {
74
- return import_i18next.default.t(key, { ns: this._i18nNamespace, ...options });
31
+ return i18n.t(key, { ns: this._i18nNamespace, ...options });
75
32
  }
76
33
  // 注入 i18n 实例
77
34
  get i18n() {
78
- return import_i18next.default;
35
+ return i18n;
79
36
  }
80
37
  // 生命周期:组件连接时订阅语言变化
81
38
  onConnected() {
82
- super.onConnected?.();
39
+ var _a;
40
+ (_a = super.onConnected) == null ? void 0 : _a.call(this);
83
41
  const handler = () => {
84
42
  if (this.rerender) {
85
43
  this.rerender();
86
44
  }
87
45
  };
88
46
  this._languageChangedHandler = handler;
89
- const unsubscribe = import_i18next.default.on("languageChanged", handler);
47
+ const unsubscribe = i18n.on("languageChanged", handler);
90
48
  if (typeof unsubscribe === "function") {
91
49
  this._i18nUnsubscribe = unsubscribe;
92
50
  } else {
93
51
  this._i18nUnsubscribe = () => {
94
- if (typeof import_i18next.default.off === "function") {
95
- import_i18next.default.off("languageChanged", handler);
52
+ if (typeof i18n.off === "function") {
53
+ i18n.off("languageChanged", handler);
96
54
  }
97
55
  };
98
56
  }
99
57
  }
100
58
  // 生命周期:组件断开时取消订阅
101
59
  onDisconnected() {
60
+ var _a;
102
61
  if (this._i18nUnsubscribe && typeof this._i18nUnsubscribe === "function") {
103
62
  try {
104
63
  this._i18nUnsubscribe();
105
64
  } catch {
106
65
  const handler = this._languageChangedHandler;
107
- if (handler && typeof import_i18next.default.off === "function") {
108
- import_i18next.default.off("languageChanged", handler);
66
+ if (handler && typeof i18n.off === "function") {
67
+ i18n.off("languageChanged", handler);
109
68
  }
110
69
  }
111
70
  this._i18nUnsubscribe = void 0;
112
71
  } else {
113
72
  const handler = this._languageChangedHandler;
114
- if (handler && typeof import_i18next.default.off === "function") {
115
- import_i18next.default.off("languageChanged", handler);
73
+ if (handler && typeof i18n.off === "function") {
74
+ i18n.off("languageChanged", handler);
116
75
  }
117
76
  }
118
77
  if (this._languageChangedHandler) {
119
78
  delete this._languageChangedHandler;
120
79
  }
121
- super.onDisconnected?.();
80
+ (_a = super.onDisconnected) == null ? void 0 : _a.call(this);
122
81
  }
123
82
  }
124
83
  Object.setPrototypeOf(I18nEnhanced, constructor);
@@ -129,31 +88,27 @@ function i18nDecorator(namespace = "common") {
129
88
  return I18nEnhanced;
130
89
  };
131
90
  }
132
-
133
- // src/hooks.ts
134
91
  function useTranslation(namespace = "common") {
135
92
  const t = (key, options) => {
136
- return import_i18next.default.t(key, { ns: namespace, ...options });
93
+ return i18n.t(key, { ns: namespace, ...options });
137
94
  };
138
95
  return {
139
96
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
140
97
  t,
141
- i18n: import_i18next.default,
142
- ready: import_i18next.default.isInitialized
98
+ i18n,
99
+ ready: i18n.isInitialized
143
100
  };
144
101
  }
145
-
146
- // src/mixin.ts
147
102
  function withI18n(Base, defaultNamespace = "common") {
148
103
  return class extends Base {
149
104
  t(key, namespace, options) {
150
- return import_i18next.default.t(key, { ns: namespace || defaultNamespace, ...options });
105
+ return i18n.t(key, { ns: namespace || defaultNamespace, ...options });
151
106
  }
152
107
  get i18n() {
153
- return import_i18next.default;
108
+ return i18n;
154
109
  }
155
110
  onConnected() {
156
- import_i18next.default.on("languageChanged", () => {
111
+ i18n.on("languageChanged", () => {
157
112
  if (this.rerender) {
158
113
  this.rerender();
159
114
  }
@@ -161,12 +116,12 @@ function withI18n(Base, defaultNamespace = "common") {
161
116
  }
162
117
  };
163
118
  }
164
- // Annotate the CommonJS export names for ESM import in node:
165
- 0 && (module.exports = {
166
- i18n,
119
+ export {
120
+ i18nDecorator as i18n,
167
121
  i18nDecorator,
168
- i18nInstance,
122
+ i18n as i18nInstance,
169
123
  initI18n,
170
124
  useTranslation,
171
125
  withI18n
172
- });
126
+ };
127
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/i18n.ts","../src/decorator.ts","../src/hooks.ts","../src/mixin.ts"],"sourcesContent":["/**\n * i18next 配置和初始化\n */\n\nimport i18next from \"i18next\";\nimport LanguageDetector from \"i18next-browser-languagedetector\";\nimport Backend from \"i18next-http-backend\";\nimport type { I18nConfig } from \"./types\";\n\n/**\n * 初始化 i18next\n * @param config 配置选项\n * @returns i18n 实例\n */\nexport function initI18n(config: I18nConfig = {}): typeof i18next {\n i18next\n .use(Backend)\n .use(LanguageDetector)\n .init({\n fallbackLng: \"en\",\n debug: false,\n interpolation: {\n escapeValue: false,\n },\n backend: {\n loadPath: \"/locales/{{lng}}/{{ns}}.json\",\n },\n ns: [\"common\", \"home\", \"docs\", \"examples\"],\n defaultNS: \"common\",\n ...config,\n });\n\n return i18next;\n}\n\n// 导出 i18n 实例(直接导出常量)\nexport const i18n: typeof i18next = i18next;\n","/**\n * @i18n 装饰器 - 自动为组件注入翻译功能\n */\n\nimport { i18n } from \"./i18n\";\n\n/**\n * @i18n 装饰器 - 自动为组件注入翻译功能\n *\n * 使用方式:\n * ```tsx\n * @i18n('common')\n * export class MyComponent extends WebComponent {\n * render() {\n * return <div>{this.t('welcome')}</div>;\n * }\n * }\n * ```\n *\n * @param namespace 命名空间,默认为 'common'\n * @returns 类装饰器\n */\nexport function i18nDecorator(namespace: string = \"common\") {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return function <T extends { new (...args: any[]): any }>(constructor: T) {\n class I18nEnhanced extends constructor {\n // 使用 public 而不是 private,因为导出的匿名类类型限制\n public _i18nNamespace!: string;\n public _i18nUnsubscribe?: () => void;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(...args: any[]) {\n super(...args);\n // 初始化命名空间\n this._i18nNamespace = namespace;\n }\n\n // 注入 t 方法\n public t(key: string, options?: object): string {\n return i18n.t(key, { ns: this._i18nNamespace, ...options });\n }\n\n // 注入 i18n 实例\n public get i18n() {\n return i18n;\n }\n\n // 生命周期:组件连接时订阅语言变化\n public onConnected(): void {\n // 先调用父类的 onConnected(如果存在)\n super.onConnected?.();\n\n // 创建回调函数并保存引用,以便后续取消订阅\n const handler = (() => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((this as any).rerender) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this as any).rerender();\n }\n }) as () => void;\n\n // 保存回调引用以便取消订阅\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this as any)._languageChangedHandler = handler;\n\n // 订阅语言变化事件\n const unsubscribe = i18n.on(\"languageChanged\", handler);\n\n // 如果返回的是函数,直接使用;否则使用 off 方法\n if (typeof unsubscribe === \"function\") {\n this._i18nUnsubscribe = unsubscribe;\n } else {\n // 如果 i18n.on 返回的不是函数,创建一个取消订阅函数\n // 使用 off 方法(如果可用)或空函数\n this._i18nUnsubscribe = () => {\n if (typeof i18n.off === \"function\") {\n i18n.off(\"languageChanged\", handler);\n }\n };\n }\n }\n\n // 生命周期:组件断开时取消订阅\n public onDisconnected(): void {\n // 取消 i18n 订阅\n if (this._i18nUnsubscribe && typeof this._i18nUnsubscribe === \"function\") {\n try {\n this._i18nUnsubscribe();\n } catch {\n // 如果 unsubscribe 调用失败,尝试使用 off 方法(如果可用)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const handler = (this as any)._languageChangedHandler;\n if (handler && typeof i18n.off === \"function\") {\n i18n.off(\"languageChanged\", handler);\n }\n }\n this._i18nUnsubscribe = undefined;\n } else {\n // 如果 unsubscribe 不是函数,尝试使用 off 方法(如果可用)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const handler = (this as any)._languageChangedHandler;\n if (handler && typeof i18n.off === \"function\") {\n i18n.off(\"languageChanged\", handler);\n }\n }\n // 清理回调引用\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((this as any)._languageChangedHandler) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n delete (this as any)._languageChangedHandler;\n }\n\n // 调用父类的 onDisconnected(如果存在)\n super.onDisconnected?.();\n }\n }\n // 复制静态属性和方法\n Object.setPrototypeOf(I18nEnhanced, constructor);\n Object.defineProperty(I18nEnhanced, \"name\", {\n value: constructor.name,\n writable: false,\n });\n return I18nEnhanced as T;\n };\n}\n","/**\n * useTranslation 函数(API 与 react-i18next 兼容)\n */\n\nimport { i18n } from \"./i18n\";\nimport type { UseTranslationResponse } from \"./types\";\n\n/**\n * useTranslation - API 与 react-i18next 兼容的翻译函数\n *\n * **重要说明**:\n * - 这不是 React hook,而是 WSXJS 的普通函数\n * - API 设计参考 react-i18next,但实现方式完全不同\n * - 在 WSXJS 中,需要配合 @state 或 @i18n 装饰器实现响应式\n * - 不会自动响应语言变化,需要手动订阅 languageChanged 事件\n *\n * @param namespace 命名空间,默认为 'common'\n * @returns 翻译对象\n */\nexport function useTranslation(namespace: string = \"common\"): UseTranslationResponse {\n // 创建一个包装函数,保持 API 兼容性\n const t = (key: string, options?: object): string => {\n // 每次调用 t() 时,i18n.t() 会使用当前的 i18n.language\n // 所以只要组件重渲染,就会得到新的翻译\n return i18n.t(key, { ns: namespace, ...options });\n };\n return {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n t: t as any,\n i18n,\n ready: i18n.isInitialized,\n };\n}\n","/**\n * Mixin API - 为基类添加 i18n 支持\n */\n\nimport { i18n } from \"./i18n\";\nimport type { WebComponent, LightComponent } from \"@wsxjs/wsx-core\";\n\n/**\n * 为任何继承自 WebComponent 或 LightComponent 的类添加 i18n 支持\n *\n * 使用方式:\n * ```tsx\n * export class MyComponent extends withI18n(WebComponent, 'common') {\n * render() {\n * return <div>{this.t('welcome')}</div>;\n * }\n * }\n *\n * export class MyLightComponent extends withI18n(LightComponent, 'common') {\n * render() {\n * return <div>{this.t('welcome')}</div>;\n * }\n * }\n * ```\n *\n * @param Base 基类(WebComponent 或 LightComponent)\n * @param defaultNamespace 默认命名空间\n * @returns 增强后的类\n */\nexport function withI18n<T extends typeof WebComponent | typeof LightComponent>(\n Base: T,\n defaultNamespace: string = \"common\"\n): T {\n return class extends Base {\n protected t(key: string, namespace?: string, options?: object): string {\n return i18n.t(key, { ns: namespace || defaultNamespace, ...options });\n }\n\n protected get i18n() {\n return i18n;\n }\n\n protected onConnected(): void {\n // 订阅语言变化事件,自动触发重渲染\n i18n.on(\"languageChanged\", () => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((this as any).rerender) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this as any).rerender();\n }\n });\n }\n } as T;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Mixin API - 为基类添加 i18n 支持
3
+ */
4
+ import type { WebComponent, LightComponent } from "@wsxjs/wsx-core";
5
+ /**
6
+ * 为任何继承自 WebComponent 或 LightComponent 的类添加 i18n 支持
7
+ *
8
+ * 使用方式:
9
+ * ```tsx
10
+ * export class MyComponent extends withI18n(WebComponent, 'common') {
11
+ * render() {
12
+ * return <div>{this.t('welcome')}</div>;
13
+ * }
14
+ * }
15
+ *
16
+ * export class MyLightComponent extends withI18n(LightComponent, 'common') {
17
+ * render() {
18
+ * return <div>{this.t('welcome')}</div>;
19
+ * }
20
+ * }
21
+ * ```
22
+ *
23
+ * @param Base 基类(WebComponent 或 LightComponent)
24
+ * @param defaultNamespace 默认命名空间
25
+ * @returns 增强后的类
26
+ */
27
+ export declare function withI18n<T extends typeof WebComponent | typeof LightComponent>(Base: T, defaultNamespace?: string): T;
28
+ //# sourceMappingURL=mixin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mixin.d.ts","sourceRoot":"","sources":["../src/mixin.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEpE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,OAAO,YAAY,GAAG,OAAO,cAAc,EAC1E,IAAI,EAAE,CAAC,EACP,gBAAgB,GAAE,MAAiB,GACpC,CAAC,CAqBH"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * TypeScript 类型定义
3
+ */
4
+ import type { TFunction, i18n as I18nType } from "i18next";
5
+ /**
6
+ * i18n 配置接口
7
+ */
8
+ export interface I18nConfig {
9
+ fallbackLng?: string;
10
+ debug?: boolean;
11
+ resources?: Record<string, Record<string, object>>;
12
+ backend?: {
13
+ loadPath?: string;
14
+ };
15
+ ns?: string[];
16
+ defaultNS?: string;
17
+ interpolation?: {
18
+ escapeValue?: boolean;
19
+ };
20
+ }
21
+ /**
22
+ * useTranslation 返回类型
23
+ */
24
+ export interface UseTranslationResponse {
25
+ t: TFunction;
26
+ i18n: I18nType;
27
+ ready: boolean;
28
+ }
29
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,OAAO,CAAC,EAAE;QACN,QAAQ,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE;QACZ,WAAW,CAAC,EAAE,OAAO,CAAC;KACzB,CAAC;CACL;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACnC,CAAC,EAAE,SAAS,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;CAClB"}
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@wsxjs/wsx-i18next",
3
- "version": "0.0.18",
3
+ "version": "0.0.19",
4
4
  "description": "i18next integration for WSXJS components",
5
- "main": "./dist/index.js",
6
- "module": "./dist/index.mjs",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
7
8
  "types": "./dist/index.d.ts",
8
9
  "exports": {
9
10
  ".": {
10
11
  "types": "./dist/index.d.ts",
11
- "import": "./dist/index.mjs",
12
- "require": "./dist/index.js"
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
13
14
  }
14
15
  },
15
16
  "repository": {
@@ -37,15 +38,15 @@
37
38
  "i18next": "^23.0.0",
38
39
  "i18next-browser-languagedetector": "^7.0.0",
39
40
  "i18next-http-backend": "^2.0.0",
40
- "@wsxjs/wsx-core": "0.0.18"
41
+ "@wsxjs/wsx-core": "0.0.19"
41
42
  },
42
43
  "devDependencies": {
43
44
  "@types/jest": "^29.0.0",
44
45
  "@types/node": "^20.0.0",
45
46
  "jest": "^29.0.0",
46
47
  "ts-jest": "^29.0.0",
47
- "tsup": "^8.0.0",
48
- "typescript": "^5.0.0"
48
+ "typescript": "^5.0.0",
49
+ "vite": "^5.0.0"
49
50
  },
50
51
  "peerDependencies": {
51
52
  "i18next": "^23.0.0"
@@ -54,8 +55,8 @@
54
55
  "access": "public"
55
56
  },
56
57
  "scripts": {
57
- "build": "tsup src/index.ts --format cjs,esm --dts --tsconfig tsconfig.json",
58
- "dev": "tsup src/index.ts --format cjs,esm --dts --watch --tsconfig tsconfig.json",
58
+ "build": "vite build && tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist src/index.ts --moduleResolution node --esModuleInterop --downlevelIteration",
59
+ "dev": "vite build --watch",
59
60
  "test": "jest",
60
61
  "test:watch": "jest --watch",
61
62
  "test:coverage": "jest --coverage",
package/src/i18n.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @wsxjs/wsx-i18next 类型声明
3
+ *
4
+ * 为使用 @i18n 装饰器的组件扩展类型定义
5
+ * 这个文件会被包含在包的 dist 目录中,供其他项目使用
6
+ */
7
+
8
+ declare module "@wsxjs/wsx-core" {
9
+ interface WebComponent {
10
+ /**
11
+ * 翻译函数,由 @i18n 装饰器注入
12
+ * @param key 翻译键
13
+ * @param options 翻译选项(插值变量等)
14
+ * @returns 翻译后的字符串
15
+ */
16
+ t(key: string, options?: object): string;
17
+
18
+ /**
19
+ * i18n 实例,由 @i18n 装饰器注入
20
+ */
21
+ readonly i18n: import("i18next").i18n;
22
+ }
23
+
24
+ interface LightComponent {
25
+ /**
26
+ * 翻译函数,由 @i18n 装饰器注入
27
+ * @param key 翻译键
28
+ * @param options 翻译选项(插值变量等)
29
+ * @returns 翻译后的字符串
30
+ */
31
+ t(key: string, options?: object): string;
32
+
33
+ /**
34
+ * i18n 实例,由 @i18n 装饰器注入
35
+ */
36
+ readonly i18n: import("i18next").i18n;
37
+ }
38
+ }
39
+
40
+ export {};
package/src/i18n.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * i18next 配置和初始化
3
3
  */
4
4
 
5
- import i18n from "i18next";
5
+ import i18next from "i18next";
6
6
  import LanguageDetector from "i18next-browser-languagedetector";
7
7
  import Backend from "i18next-http-backend";
8
8
  import type { I18nConfig } from "./types";
@@ -12,8 +12,9 @@ import type { I18nConfig } from "./types";
12
12
  * @param config 配置选项
13
13
  * @returns i18n 实例
14
14
  */
15
- export function initI18n(config: I18nConfig = {}): typeof i18n {
16
- i18n.use(Backend)
15
+ export function initI18n(config: I18nConfig = {}): typeof i18next {
16
+ i18next
17
+ .use(Backend)
17
18
  .use(LanguageDetector)
18
19
  .init({
19
20
  fallbackLng: "en",
@@ -29,7 +30,8 @@ export function initI18n(config: I18nConfig = {}): typeof i18n {
29
30
  ...config,
30
31
  });
31
32
 
32
- return i18n;
33
+ return i18next;
33
34
  }
34
35
 
35
- export { i18n };
36
+ // 导出 i18n 实例(直接导出常量)
37
+ export const i18n: typeof i18next = i18next;
package/dist/index.d.mts DELETED
@@ -1,114 +0,0 @@
1
- import i18n$1, { TFunction, i18n } from 'i18next';
2
- export { default as i18nInstance } from 'i18next';
3
- import { WebComponent, LightComponent } from '@wsxjs/wsx-core';
4
-
5
- /**
6
- * TypeScript 类型定义
7
- */
8
-
9
- /**
10
- * i18n 配置接口
11
- */
12
- interface I18nConfig {
13
- fallbackLng?: string;
14
- debug?: boolean;
15
- resources?: Record<string, Record<string, object>>;
16
- backend?: {
17
- loadPath?: string;
18
- };
19
- ns?: string[];
20
- defaultNS?: string;
21
- interpolation?: {
22
- escapeValue?: boolean;
23
- };
24
- }
25
- /**
26
- * useTranslation 返回类型
27
- */
28
- interface UseTranslationResponse {
29
- t: TFunction;
30
- i18n: i18n;
31
- ready: boolean;
32
- }
33
-
34
- /**
35
- * i18next 配置和初始化
36
- */
37
-
38
- /**
39
- * 初始化 i18next
40
- * @param config 配置选项
41
- * @returns i18n 实例
42
- */
43
- declare function initI18n(config?: I18nConfig): typeof i18n$1;
44
-
45
- /**
46
- * @i18n 装饰器 - 自动为组件注入翻译功能
47
- */
48
- /**
49
- * @i18n 装饰器 - 自动为组件注入翻译功能
50
- *
51
- * 使用方式:
52
- * ```tsx
53
- * @i18n('common')
54
- * export class MyComponent extends WebComponent {
55
- * render() {
56
- * return <div>{this.t('welcome')}</div>;
57
- * }
58
- * }
59
- * ```
60
- *
61
- * @param namespace 命名空间,默认为 'common'
62
- * @returns 类装饰器
63
- */
64
- declare function i18nDecorator(namespace?: string): <T extends {
65
- new (...args: any[]): any;
66
- }>(constructor: T) => T;
67
-
68
- /**
69
- * useTranslation 函数(API 与 react-i18next 兼容)
70
- */
71
-
72
- /**
73
- * useTranslation - API 与 react-i18next 兼容的翻译函数
74
- *
75
- * **重要说明**:
76
- * - 这不是 React hook,而是 WSXJS 的普通函数
77
- * - API 设计参考 react-i18next,但实现方式完全不同
78
- * - 在 WSXJS 中,需要配合 @state 或 @i18n 装饰器实现响应式
79
- * - 不会自动响应语言变化,需要手动订阅 languageChanged 事件
80
- *
81
- * @param namespace 命名空间,默认为 'common'
82
- * @returns 翻译对象
83
- */
84
- declare function useTranslation(namespace?: string): UseTranslationResponse;
85
-
86
- /**
87
- * Mixin API - 为基类添加 i18n 支持
88
- */
89
-
90
- /**
91
- * 为任何继承自 WebComponent 或 LightComponent 的类添加 i18n 支持
92
- *
93
- * 使用方式:
94
- * ```tsx
95
- * export class MyComponent extends withI18n(WebComponent, 'common') {
96
- * render() {
97
- * return <div>{this.t('welcome')}</div>;
98
- * }
99
- * }
100
- *
101
- * export class MyLightComponent extends withI18n(LightComponent, 'common') {
102
- * render() {
103
- * return <div>{this.t('welcome')}</div>;
104
- * }
105
- * }
106
- * ```
107
- *
108
- * @param Base 基类(WebComponent 或 LightComponent)
109
- * @param defaultNamespace 默认命名空间
110
- * @returns 增强后的类
111
- */
112
- declare function withI18n<T extends typeof WebComponent | typeof LightComponent>(Base: T, defaultNamespace?: string): T;
113
-
114
- export { type I18nConfig, type UseTranslationResponse, i18nDecorator as i18n, i18nDecorator, initI18n, useTranslation, withI18n };