@intlayer/lingui 8.12.5-canary.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 +330 -0
- package/dist/cjs/I18nClass.cjs +127 -0
- package/dist/cjs/I18nClass.cjs.map +1 -0
- package/dist/cjs/I18nProvider.cjs +64 -0
- package/dist/cjs/I18nProvider.cjs.map +1 -0
- package/dist/cjs/LinguiContext.cjs +23 -0
- package/dist/cjs/LinguiContext.cjs.map +1 -0
- package/dist/cjs/Trans.cjs +71 -0
- package/dist/cjs/Trans.cjs.map +1 -0
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +29 -0
- package/dist/cjs/eventEmitter.cjs +37 -0
- package/dist/cjs/eventEmitter.cjs.map +1 -0
- package/dist/cjs/formats.cjs +66 -0
- package/dist/cjs/formats.cjs.map +1 -0
- package/dist/cjs/index.cjs +19 -0
- package/dist/cjs/plugin/index.cjs +64 -0
- package/dist/cjs/plugin/index.cjs.map +1 -0
- package/dist/cjs/setupI18n.cjs +33 -0
- package/dist/cjs/setupI18n.cjs.map +1 -0
- package/dist/cjs/useLingui.cjs +40 -0
- package/dist/cjs/useLingui.cjs.map +1 -0
- package/dist/esm/I18nClass.mjs +126 -0
- package/dist/esm/I18nClass.mjs.map +1 -0
- package/dist/esm/I18nProvider.mjs +63 -0
- package/dist/esm/I18nProvider.mjs.map +1 -0
- package/dist/esm/LinguiContext.mjs +22 -0
- package/dist/esm/LinguiContext.mjs.map +1 -0
- package/dist/esm/Trans.mjs +70 -0
- package/dist/esm/Trans.mjs.map +1 -0
- package/dist/esm/eventEmitter.mjs +35 -0
- package/dist/esm/eventEmitter.mjs.map +1 -0
- package/dist/esm/formats.mjs +64 -0
- package/dist/esm/formats.mjs.map +1 -0
- package/dist/esm/index.mjs +11 -0
- package/dist/esm/plugin/index.mjs +60 -0
- package/dist/esm/plugin/index.mjs.map +1 -0
- package/dist/esm/setupI18n.mjs +31 -0
- package/dist/esm/setupI18n.mjs.map +1 -0
- package/dist/esm/useLingui.mjs +39 -0
- package/dist/esm/useLingui.mjs.map +1 -0
- package/dist/types/I18nClass.d.ts +92 -0
- package/dist/types/I18nClass.d.ts.map +1 -0
- package/dist/types/I18nProvider.d.ts +39 -0
- package/dist/types/I18nProvider.d.ts.map +1 -0
- package/dist/types/LinguiContext.d.ts +21 -0
- package/dist/types/LinguiContext.d.ts.map +1 -0
- package/dist/types/Trans.d.ts +38 -0
- package/dist/types/Trans.d.ts.map +1 -0
- package/dist/types/eventEmitter.d.ts +24 -0
- package/dist/types/eventEmitter.d.ts.map +1 -0
- package/dist/types/formats.d.ts +32 -0
- package/dist/types/formats.d.ts.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/plugin/index.d.ts +25 -0
- package/dist/types/plugin/index.d.ts.map +1 -0
- package/dist/types/setupI18n.d.ts +37 -0
- package/dist/types/setupI18n.d.ts.map +1 -0
- package/dist/types/useLingui.d.ts +21 -0
- package/dist/types/useLingui.d.ts.map +1 -0
- package/package.json +115 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/LinguiContext.tsx
|
|
4
|
+
/**
|
|
5
|
+
* Drop-in for `@lingui/react`'s `LinguiContext`.
|
|
6
|
+
*
|
|
7
|
+
* Provides the active `I18n` instance and the `_` translation function
|
|
8
|
+
* to all descendant components.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import { useContext } from 'react';
|
|
13
|
+
* import { LinguiContext } from '@lingui/react';
|
|
14
|
+
*
|
|
15
|
+
* const { i18n } = useContext(LinguiContext)!;
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
const LinguiContext = createContext(null);
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
export { LinguiContext };
|
|
22
|
+
//# sourceMappingURL=LinguiContext.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinguiContext.mjs","names":[],"sources":["../../src/LinguiContext.tsx"],"sourcesContent":["import type { I18nContext } from '@lingui/react';\nimport { createContext } from 'react';\n\n/**\n * Drop-in for `@lingui/react`'s `LinguiContext`.\n *\n * Provides the active `I18n` instance and the `_` translation function\n * to all descendant components.\n *\n * @example\n * ```tsx\n * import { useContext } from 'react';\n * import { LinguiContext } from '@lingui/react';\n *\n * const { i18n } = useContext(LinguiContext)!;\n * ```\n */\nexport const LinguiContext = createContext<I18nContext | null>(null);\n"],"mappings":";;;;;;;;;;;;;;;;;AAiBA,MAAa,gBAAgB,cAAkC,IAAI"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useLingui } from "./useLingui.mjs";
|
|
4
|
+
import { parseTaggedMessage } from "@intlayer/core/messageFormat";
|
|
5
|
+
import { Fragment } from "react";
|
|
6
|
+
import { Fragment as Fragment$1, jsx } from "react/jsx-runtime";
|
|
7
|
+
|
|
8
|
+
//#region src/Trans.tsx
|
|
9
|
+
/** Maps tagged tokens to React nodes using a components record (numbered or named). */
|
|
10
|
+
const renderTaggedTokens = (tokens, components) => tokens.map((token, tokenIndex) => {
|
|
11
|
+
if (typeof token === "string") return token;
|
|
12
|
+
const children = renderTaggedTokens(token.children, components);
|
|
13
|
+
const component = components[token.tag];
|
|
14
|
+
if (component === void 0) return /* @__PURE__ */ jsx(Fragment, { children }, tokenIndex);
|
|
15
|
+
if (typeof component === "function") return /* @__PURE__ */ jsx(Fragment, { children: component(/* @__PURE__ */ jsx(Fragment$1, { children })) }, tokenIndex);
|
|
16
|
+
if (typeof component === "object" && component !== null && "type" in component) {
|
|
17
|
+
const { type: TagComponent, props: tagProps } = component;
|
|
18
|
+
return /* @__PURE__ */ jsx(TagComponent, {
|
|
19
|
+
...tagProps,
|
|
20
|
+
children
|
|
21
|
+
}, tokenIndex);
|
|
22
|
+
}
|
|
23
|
+
return /* @__PURE__ */ jsx(Fragment, { children }, tokenIndex);
|
|
24
|
+
});
|
|
25
|
+
/**
|
|
26
|
+
* Drop-in for `@lingui/react`'s `<Trans>`.
|
|
27
|
+
*
|
|
28
|
+
* Looks up the message `id` in the `messages` intlayer dictionary and renders
|
|
29
|
+
* the result. When `components` is provided, named tags in the translated
|
|
30
|
+
* string are mapped to React elements (uses `parseTaggedMessage` from
|
|
31
|
+
* `@intlayer/core`).
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* // Simple message
|
|
36
|
+
* <Trans id="home.title" message="Welcome" />
|
|
37
|
+
*
|
|
38
|
+
* // Rich text with components
|
|
39
|
+
* <Trans
|
|
40
|
+
* id="legal.terms"
|
|
41
|
+
* message="I agree to the <link>terms</link>"
|
|
42
|
+
* components={{ link: <a href="/terms" /> }}
|
|
43
|
+
* />
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
const Trans = ({ id, message, values, components, formats: _formats, comment: _comment, render, component: WrapperComponent }) => {
|
|
47
|
+
const { i18n, defaultComponent: DefaultComponent } = useLingui();
|
|
48
|
+
const translation = i18n._(id, values ?? {}, { message });
|
|
49
|
+
const hasComponents = components && Object.keys(components).length > 0;
|
|
50
|
+
let content;
|
|
51
|
+
if (hasComponents) content = /* @__PURE__ */ jsx(Fragment$1, { children: renderTaggedTokens(parseTaggedMessage(translation), components) });
|
|
52
|
+
else content = translation;
|
|
53
|
+
const renderProps = {
|
|
54
|
+
id,
|
|
55
|
+
translation: content,
|
|
56
|
+
children: content,
|
|
57
|
+
message: message ?? null
|
|
58
|
+
};
|
|
59
|
+
if (typeof render === "function") return render(renderProps);
|
|
60
|
+
const Wrapper = WrapperComponent ?? DefaultComponent;
|
|
61
|
+
if (Wrapper) return /* @__PURE__ */ jsx(Wrapper, {
|
|
62
|
+
...renderProps,
|
|
63
|
+
children: content
|
|
64
|
+
});
|
|
65
|
+
return /* @__PURE__ */ jsx(Fragment$1, { children: content });
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
//#endregion
|
|
69
|
+
export { Trans };
|
|
70
|
+
//# sourceMappingURL=Trans.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Trans.mjs","names":[],"sources":["../../src/Trans.tsx"],"sourcesContent":["'use client';\n\nimport {\n parseTaggedMessage,\n type TaggedMessageToken,\n} from '@intlayer/core/messageFormat';\nimport type { MessageId } from '@lingui/core';\nimport type { TransProps, TransRenderProps } from '@lingui/react';\nimport {\n type ComponentType,\n Fragment,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { useLingui } from './useLingui';\n\ntype RichRenderer = (...args: unknown[]) => ReactNode;\n\n/** Maps tagged tokens to React nodes using a components record (numbered or named). */\nconst renderTaggedTokens = (\n tokens: TaggedMessageToken[],\n components: Record<\n string,\n ComponentType<Record<string, unknown>> | ReactElement | unknown\n >\n): ReactNode[] =>\n tokens.map((token, tokenIndex) => {\n if (typeof token === 'string') return token;\n const children = renderTaggedTokens(token.children, components);\n const component = components[token.tag];\n if (component === undefined) {\n return <Fragment key={tokenIndex}>{children}</Fragment>;\n }\n if (typeof component === 'function') {\n return (\n <Fragment key={tokenIndex}>\n {(component as RichRenderer)(<>{children}</>)}\n </Fragment>\n );\n }\n if (\n typeof component === 'object' &&\n component !== null &&\n 'type' in component\n ) {\n const { type: TagComponent, props: tagProps } = component as ReactElement;\n return (\n <TagComponent\n key={tokenIndex}\n {...(tagProps as Record<string, unknown>)}\n >\n {children}\n </TagComponent>\n );\n }\n return <Fragment key={tokenIndex}>{children}</Fragment>;\n });\n\n/**\n * Drop-in for `@lingui/react`'s `<Trans>`.\n *\n * Looks up the message `id` in the `messages` intlayer dictionary and renders\n * the result. When `components` is provided, named tags in the translated\n * string are mapped to React elements (uses `parseTaggedMessage` from\n * `@intlayer/core`).\n *\n * @example\n * ```tsx\n * // Simple message\n * <Trans id=\"home.title\" message=\"Welcome\" />\n *\n * // Rich text with components\n * <Trans\n * id=\"legal.terms\"\n * message=\"I agree to the <link>terms</link>\"\n * components={{ link: <a href=\"/terms\" /> }}\n * />\n * ```\n */\nexport const Trans = ({\n id,\n message,\n values,\n components,\n formats: _formats,\n comment: _comment,\n render,\n component: WrapperComponent,\n}: TransProps): ReactElement | null => {\n const { i18n, defaultComponent: DefaultComponent } = useLingui();\n\n const translation = i18n._(id as MessageId, values ?? {}, { message });\n const hasComponents = components && Object.keys(components).length > 0;\n\n let content: ReactNode;\n\n if (hasComponents) {\n const tokens = parseTaggedMessage(translation);\n const nodes = renderTaggedTokens(tokens, components);\n content = <>{nodes}</>;\n } else {\n content = translation;\n }\n\n const renderProps: TransRenderProps = {\n id: id as MessageId,\n translation: content,\n children: content,\n message: message ?? null,\n };\n\n if (typeof render === 'function') {\n return render(renderProps);\n }\n\n const Wrapper =\n WrapperComponent ??\n (DefaultComponent as ComponentType<TransRenderProps> | undefined);\n\n if (Wrapper) {\n return <Wrapper {...renderProps}>{content}</Wrapper>;\n }\n\n return <>{content}</>;\n};\n"],"mappings":";;;;;;;;;AAmBA,MAAM,sBACJ,QACA,eAKA,OAAO,KAAK,OAAO,eAAe;CAChC,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,MAAM,WAAW,mBAAmB,MAAM,UAAU,UAAU;CAC9D,MAAM,YAAY,WAAW,MAAM;CACnC,IAAI,cAAc,QAChB,OAAO,oBAAC,UAAD,EAA4B,SAAmB,GAAhC,UAAgC;CAExD,IAAI,OAAO,cAAc,YACvB,OACE,oBAAC,UAAD,YACI,UAA2B,kCAAG,SAAW,EAAC,EACpC,GAFK,UAEL;CAGd,IACE,OAAO,cAAc,YACrB,cAAc,QACd,UAAU,WACV;EACA,MAAM,EAAE,MAAM,cAAc,OAAO,aAAa;EAChD,OACE,oBAAC,cAAD;GAEE,GAAK;GAEJ;EACW,GAJP,UAIO;CAElB;CACA,OAAO,oBAAC,UAAD,EAA4B,SAAmB,GAAhC,UAAgC;AACxD,CAAC;;;;;;;;;;;;;;;;;;;;;;AAuBH,MAAa,SAAS,EACpB,IACA,SACA,QACA,YACA,SAAS,UACT,SAAS,UACT,QACA,WAAW,uBAC0B;CACrC,MAAM,EAAE,MAAM,kBAAkB,qBAAqB,UAAU;CAE/D,MAAM,cAAc,KAAK,EAAE,IAAiB,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC;CACrE,MAAM,gBAAgB,cAAc,OAAO,KAAK,UAAU,CAAC,CAAC,SAAS;CAErE,IAAI;CAEJ,IAAI,eAGF,UAAU,4CADI,mBADC,mBAAmB,WACI,GAAG,UACxB,EAAI;MAErB,UAAU;CAGZ,MAAM,cAAgC;EAChC;EACJ,aAAa;EACb,UAAU;EACV,SAAS,WAAW;CACtB;CAEA,IAAI,OAAO,WAAW,YACpB,OAAO,OAAO,WAAW;CAG3B,MAAM,UACJ,oBACC;CAEH,IAAI,SACF,OAAO,oBAAC,SAAD;EAAS,GAAI;YAAc;CAAiB;CAGrD,OAAO,4CAAG,QAAU;AACtB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/eventEmitter.ts
|
|
2
|
+
/**
|
|
3
|
+
* Minimal EventEmitter that mirrors `@lingui/core`'s EventEmitter API.
|
|
4
|
+
* Required because we cannot import from `@lingui/core` at runtime
|
|
5
|
+
* (we are its alias) — so we reimplement the base class here.
|
|
6
|
+
*/
|
|
7
|
+
var EventEmitter = class {
|
|
8
|
+
_events = /* @__PURE__ */ new Map();
|
|
9
|
+
/**
|
|
10
|
+
* Registers a listener for the given event and returns an unsubscribe function.
|
|
11
|
+
*/
|
|
12
|
+
on(event, listener) {
|
|
13
|
+
if (!this._events.has(event)) this._events.set(event, /* @__PURE__ */ new Set());
|
|
14
|
+
this._events.get(event).add(listener);
|
|
15
|
+
return () => this.removeListener(event, listener);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Removes a previously registered listener.
|
|
19
|
+
*/
|
|
20
|
+
removeListener(event, listener) {
|
|
21
|
+
this._events.get(event)?.delete(listener);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Emits an event, invoking all registered listeners.
|
|
25
|
+
*/
|
|
26
|
+
emit(event, ...args) {
|
|
27
|
+
this._events.get(event)?.forEach((listener) => {
|
|
28
|
+
listener(...args);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
//#endregion
|
|
34
|
+
export { EventEmitter };
|
|
35
|
+
//# sourceMappingURL=eventEmitter.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventEmitter.mjs","names":[],"sources":["../../src/eventEmitter.ts"],"sourcesContent":["/**\n * Minimal EventEmitter that mirrors `@lingui/core`'s EventEmitter API.\n * Required because we cannot import from `@lingui/core` at runtime\n * (we are its alias) — so we reimplement the base class here.\n */\nexport class EventEmitter<\n Events extends Record<string, (...args: unknown[]) => void>,\n> {\n private readonly _events: Map<\n keyof Events,\n Set<(...args: unknown[]) => void>\n > = new Map();\n\n /**\n * Registers a listener for the given event and returns an unsubscribe function.\n */\n on<E extends keyof Events>(event: E, listener: Events[E]): () => void {\n if (!this._events.has(event)) {\n this._events.set(event, new Set());\n }\n this._events.get(event)!.add(listener as (...args: unknown[]) => void);\n return () => this.removeListener(event, listener);\n }\n\n /**\n * Removes a previously registered listener.\n */\n removeListener<E extends keyof Events>(event: E, listener: Events[E]): void {\n this._events.get(event)?.delete(listener as (...args: unknown[]) => void);\n }\n\n /**\n * Emits an event, invoking all registered listeners.\n */\n emit<E extends keyof Events>(event: E, ...args: Parameters<Events[E]>): void {\n this._events.get(event)?.forEach((listener) => {\n listener(...(args as unknown[]));\n });\n }\n}\n"],"mappings":";;;;;;AAKA,IAAa,eAAb,MAEE;CACA,AAAiB,0BAGb,IAAI,IAAI;;;;CAKZ,GAA2B,OAAU,UAAiC;EACpE,IAAI,CAAC,KAAK,QAAQ,IAAI,KAAK,GACzB,KAAK,QAAQ,IAAI,uBAAO,IAAI,IAAI,CAAC;EAEnC,KAAK,QAAQ,IAAI,KAAK,CAAC,CAAE,IAAI,QAAwC;EACrE,aAAa,KAAK,eAAe,OAAO,QAAQ;CAClD;;;;CAKA,eAAuC,OAAU,UAA2B;EAC1E,KAAK,QAAQ,IAAI,KAAK,CAAC,EAAE,OAAO,QAAwC;CAC1E;;;;CAKA,KAA6B,OAAU,GAAG,MAAmC;EAC3E,KAAK,QAAQ,IAAI,KAAK,CAAC,EAAE,SAAS,aAAa;GAC7C,SAAS,GAAI,IAAkB;EACjC,CAAC;CACH;AACF"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
//#region src/formats.ts
|
|
2
|
+
const SIZE_FORMAT_MAP = {
|
|
3
|
+
short: {
|
|
4
|
+
dateStyle: "short",
|
|
5
|
+
timeStyle: "short"
|
|
6
|
+
},
|
|
7
|
+
default: {
|
|
8
|
+
dateStyle: "medium",
|
|
9
|
+
timeStyle: "medium"
|
|
10
|
+
},
|
|
11
|
+
long: {
|
|
12
|
+
dateStyle: "long",
|
|
13
|
+
timeStyle: "long"
|
|
14
|
+
},
|
|
15
|
+
full: {
|
|
16
|
+
dateStyle: "full",
|
|
17
|
+
timeStyle: "full"
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const toDateObject = (value) => typeof value === "string" ? new Date(value) : new Date(value);
|
|
21
|
+
const resolveLocales = (locales) => locales;
|
|
22
|
+
/**
|
|
23
|
+
* Formats a date value.
|
|
24
|
+
* @deprecated Use `Intl.DateTimeFormat` directly.
|
|
25
|
+
*/
|
|
26
|
+
const date = (locales, value, format) => {
|
|
27
|
+
const options = typeof format === "string" ? SIZE_FORMAT_MAP[format] ?? SIZE_FORMAT_MAP.default : format ?? {};
|
|
28
|
+
return new Intl.DateTimeFormat(resolveLocales(locales), options).format(toDateObject(value));
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Formats a time value.
|
|
32
|
+
* @deprecated Use `Intl.DateTimeFormat` directly.
|
|
33
|
+
*/
|
|
34
|
+
const time = (locales, value, format) => {
|
|
35
|
+
const options = typeof format === "string" ? SIZE_FORMAT_MAP[format] ?? SIZE_FORMAT_MAP.default : format ?? { timeStyle: "medium" };
|
|
36
|
+
return new Intl.DateTimeFormat(resolveLocales(locales), options).format(toDateObject(value));
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Formats a number value.
|
|
40
|
+
* @deprecated Use `Intl.NumberFormat` directly.
|
|
41
|
+
*/
|
|
42
|
+
const number = (locales, value, format) => new Intl.NumberFormat(resolveLocales(locales), format).format(value);
|
|
43
|
+
/**
|
|
44
|
+
* Selects the correct plural form from a set of plural rules.
|
|
45
|
+
* @deprecated Use `Intl.PluralRules` directly.
|
|
46
|
+
*/
|
|
47
|
+
const plural = (locales, ordinal, value, { offset = 0, ...rules }) => {
|
|
48
|
+
const count = value - offset;
|
|
49
|
+
const pluralRule = new Intl.PluralRules(resolveLocales(locales), { type: ordinal ? "ordinal" : "cardinal" }).select(count);
|
|
50
|
+
return rules[String(count)] ?? rules[pluralRule] ?? rules.other;
|
|
51
|
+
};
|
|
52
|
+
/** Default locale used when none is configured. */
|
|
53
|
+
const defaultLocale = "en";
|
|
54
|
+
const formats = {
|
|
55
|
+
date,
|
|
56
|
+
time,
|
|
57
|
+
number,
|
|
58
|
+
plural,
|
|
59
|
+
defaultLocale
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
//#endregion
|
|
63
|
+
export { formats };
|
|
64
|
+
//# sourceMappingURL=formats.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formats.mjs","names":[],"sources":["../../src/formats.ts"],"sourcesContent":["/**\n * Reimplementation of `@lingui/core`'s `formats` namespace.\n *\n * These static helpers are deliberately kept independent of any I18n instance\n * so that they can be used without a Provider.\n *\n * @deprecated Use `Intl.*` APIs directly — these helpers will be removed in\n * a future version of lingui.\n */\n\nexport type DateTimeFormatSize = 'short' | 'default' | 'long' | 'full';\nexport type DateTimeFormatValue = Parameters<Intl.DateTimeFormat['format']>[0];\nexport type NumberFormatValue = Parameters<Intl.NumberFormat['format']>[0];\n\nexport type PluralOptions = {\n [key: string]: string | undefined;\n} & {\n offset?: number;\n other: string;\n};\n\nconst SIZE_FORMAT_MAP: Record<DateTimeFormatSize, Intl.DateTimeFormatOptions> =\n {\n short: { dateStyle: 'short', timeStyle: 'short' },\n default: { dateStyle: 'medium', timeStyle: 'medium' },\n long: { dateStyle: 'long', timeStyle: 'long' },\n full: { dateStyle: 'full', timeStyle: 'full' },\n };\n\nconst toDateObject = (value: string | DateTimeFormatValue): Date =>\n typeof value === 'string' ? new Date(value) : new Date(value as number);\n\nconst resolveLocales = (locales: string | string[]): string | string[] =>\n locales;\n\n/**\n * Formats a date value.\n * @deprecated Use `Intl.DateTimeFormat` directly.\n */\nconst date = (\n locales: string | string[],\n value: string | DateTimeFormatValue,\n format?: Intl.DateTimeFormatOptions | DateTimeFormatSize\n): string => {\n const options: Intl.DateTimeFormatOptions =\n typeof format === 'string'\n ? (SIZE_FORMAT_MAP[format] ?? SIZE_FORMAT_MAP.default)\n : (format ?? {});\n return new Intl.DateTimeFormat(resolveLocales(locales), options).format(\n toDateObject(value)\n );\n};\n\n/**\n * Formats a time value.\n * @deprecated Use `Intl.DateTimeFormat` directly.\n */\nconst time = (\n locales: string | string[],\n value: string | DateTimeFormatValue,\n format?: Intl.DateTimeFormatOptions | DateTimeFormatSize\n): string => {\n const options: Intl.DateTimeFormatOptions =\n typeof format === 'string'\n ? (SIZE_FORMAT_MAP[format] ?? SIZE_FORMAT_MAP.default)\n : (format ?? { timeStyle: 'medium' });\n return new Intl.DateTimeFormat(resolveLocales(locales), options).format(\n toDateObject(value)\n );\n};\n\n/**\n * Formats a number value.\n * @deprecated Use `Intl.NumberFormat` directly.\n */\nconst number = (\n locales: string | string[],\n value: NumberFormatValue,\n format?: Intl.NumberFormatOptions\n): string =>\n new Intl.NumberFormat(resolveLocales(locales), format).format(value);\n\n/**\n * Selects the correct plural form from a set of plural rules.\n * @deprecated Use `Intl.PluralRules` directly.\n */\nconst plural = (\n locales: string | string[],\n ordinal: boolean,\n value: number,\n { offset = 0, ...rules }: PluralOptions\n): string => {\n const count = value - offset;\n const pluralRule = new Intl.PluralRules(resolveLocales(locales), {\n type: ordinal ? 'ordinal' : 'cardinal',\n }).select(count);\n return (\n (rules[String(count)] as string | undefined) ??\n (rules[pluralRule] as string | undefined) ??\n rules.other\n );\n};\n\n/** Default locale used when none is configured. */\nconst defaultLocale = 'en';\n\nexport const formats = {\n date,\n time,\n number,\n plural,\n defaultLocale,\n};\n"],"mappings":";AAqBA,MAAM,kBACJ;CACE,OAAO;EAAE,WAAW;EAAS,WAAW;CAAQ;CAChD,SAAS;EAAE,WAAW;EAAU,WAAW;CAAS;CACpD,MAAM;EAAE,WAAW;EAAQ,WAAW;CAAO;CAC7C,MAAM;EAAE,WAAW;EAAQ,WAAW;CAAO;AAC/C;AAEF,MAAM,gBAAgB,UACpB,OAAO,UAAU,WAAW,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAe;AAExE,MAAM,kBAAkB,YACtB;;;;;AAMF,MAAM,QACJ,SACA,OACA,WACW;CACX,MAAM,UACJ,OAAO,WAAW,WACb,gBAAgB,WAAW,gBAAgB,UAC3C,UAAU,CAAC;CAClB,OAAO,IAAI,KAAK,eAAe,eAAe,OAAO,GAAG,OAAO,CAAC,CAAC,OAC/D,aAAa,KAAK,CACpB;AACF;;;;;AAMA,MAAM,QACJ,SACA,OACA,WACW;CACX,MAAM,UACJ,OAAO,WAAW,WACb,gBAAgB,WAAW,gBAAgB,UAC3C,UAAU,EAAE,WAAW,SAAS;CACvC,OAAO,IAAI,KAAK,eAAe,eAAe,OAAO,GAAG,OAAO,CAAC,CAAC,OAC/D,aAAa,KAAK,CACpB;AACF;;;;;AAMA,MAAM,UACJ,SACA,OACA,WAEA,IAAI,KAAK,aAAa,eAAe,OAAO,GAAG,MAAM,CAAC,CAAC,OAAO,KAAK;;;;;AAMrE,MAAM,UACJ,SACA,SACA,OACA,EAAE,SAAS,GAAG,GAAG,YACN;CACX,MAAM,QAAQ,QAAQ;CACtB,MAAM,aAAa,IAAI,KAAK,YAAY,eAAe,OAAO,GAAG,EAC/D,MAAM,UAAU,YAAY,WAC9B,CAAC,CAAC,CAAC,OAAO,KAAK;CACf,OACG,MAAM,OAAO,KAAK,MAClB,MAAM,eACP,MAAM;AAEV;;AAGA,MAAM,gBAAgB;AAEtB,MAAa,UAAU;CACrB;CACA;CACA;CACA;CACA;AACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { I18nClass } from "./I18nClass.mjs";
|
|
4
|
+
import { LinguiContext } from "./LinguiContext.mjs";
|
|
5
|
+
import { useLingui } from "./useLingui.mjs";
|
|
6
|
+
import { formats } from "./formats.mjs";
|
|
7
|
+
import { I18nProvider } from "./I18nProvider.mjs";
|
|
8
|
+
import { Trans } from "./Trans.mjs";
|
|
9
|
+
import { i18n, setupI18n } from "./setupI18n.mjs";
|
|
10
|
+
|
|
11
|
+
export { I18nClass as I18n, I18nProvider, LinguiContext, Trans, formats, i18n, setupI18n, useLingui };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { runOnce } from "@intlayer/chokidar/utils";
|
|
3
|
+
import * as ANSIColors from "@intlayer/config/colors";
|
|
4
|
+
import { colorize, getAppLogger } from "@intlayer/config/logger";
|
|
5
|
+
import { getConfiguration } from "@intlayer/config/node";
|
|
6
|
+
import { intlayer } from "vite-intlayer";
|
|
7
|
+
|
|
8
|
+
//#region src/plugin/index.ts
|
|
9
|
+
/**
|
|
10
|
+
* Caller configurations for lingui.
|
|
11
|
+
*
|
|
12
|
+
* Lingui's `i18n._(id)` / `i18n.t` and `useLingui()`'s `_()` all resolve
|
|
13
|
+
* translations at runtime through the intlayer `messages` dictionary. Since the
|
|
14
|
+
* mapping is 1:1 (one catalog → one `messages` dict) there is no namespace
|
|
15
|
+
* splitting needed at the analyser level, so the caller list is empty for now.
|
|
16
|
+
*
|
|
17
|
+
* Future: once `namespace: { from: 'self' }` is supported in the babel/swc
|
|
18
|
+
* analyser, we can add callers for `useLingui()._(id)`.
|
|
19
|
+
*/
|
|
20
|
+
const LINGUI_COMPAT_CALLERS = [];
|
|
21
|
+
/**
|
|
22
|
+
* A Vite plugin for the lingui compat adapter.
|
|
23
|
+
*
|
|
24
|
+
* Wraps `vite-intlayer` and adds resolve aliases so that both
|
|
25
|
+
* `@lingui/core` **and** `@lingui/react` are redirected to
|
|
26
|
+
* `@intlayer/lingui` at bundle time.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* // vite.config.ts
|
|
31
|
+
* import { linguiVitePlugin } from '@intlayer/lingui/plugin';
|
|
32
|
+
*
|
|
33
|
+
* export default defineConfig({
|
|
34
|
+
* plugins: [linguiVitePlugin()],
|
|
35
|
+
* });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
const linguiVitePlugin = (options) => {
|
|
39
|
+
const intlayerConfig = getConfiguration();
|
|
40
|
+
const appLogger = getAppLogger(intlayerConfig);
|
|
41
|
+
runOnce(join(intlayerConfig.system.baseDir, ".intlayer", "cache", "intlayer-issues-invitation.lock"), () => {
|
|
42
|
+
appLogger([colorize("Please report any issues you met on GitHub:", ANSIColors.GREY), colorize("https://github.com/aymericzip/intlayer/issues", ANSIColors.GREY_LIGHT)]);
|
|
43
|
+
}, { cacheTimeoutMs: 1e3 * 60 * 60 });
|
|
44
|
+
const basePlugins = intlayer({
|
|
45
|
+
...options,
|
|
46
|
+
compatCallers: [...options?.compatCallers ?? [], ...LINGUI_COMPAT_CALLERS]
|
|
47
|
+
});
|
|
48
|
+
const compatPlugin = {
|
|
49
|
+
name: "vite-lingui-compat-plugin",
|
|
50
|
+
config: () => ({ resolve: { alias: {
|
|
51
|
+
"@lingui/core": "@intlayer/lingui",
|
|
52
|
+
"@lingui/react": "@intlayer/lingui"
|
|
53
|
+
} } })
|
|
54
|
+
};
|
|
55
|
+
return [...Array.isArray(basePlugins) ? basePlugins : [basePlugins], compatPlugin];
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
export { linguiVitePlugin as default, linguiVitePlugin };
|
|
60
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugin/index.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { runOnce } from '@intlayer/chokidar/utils';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport type { PluginOption } from 'vite';\nimport { type CompatCallerConfig, intlayer } from 'vite-intlayer';\n\n/**\n * Caller configurations for lingui.\n *\n * Lingui's `i18n._(id)` / `i18n.t` and `useLingui()`'s `_()` all resolve\n * translations at runtime through the intlayer `messages` dictionary. Since the\n * mapping is 1:1 (one catalog → one `messages` dict) there is no namespace\n * splitting needed at the analyser level, so the caller list is empty for now.\n *\n * Future: once `namespace: { from: 'self' }` is supported in the babel/swc\n * analyser, we can add callers for `useLingui()._(id)`.\n */\nconst LINGUI_COMPAT_CALLERS: CompatCallerConfig[] = [];\n\n/**\n * A Vite plugin for the lingui compat adapter.\n *\n * Wraps `vite-intlayer` and adds resolve aliases so that both\n * `@lingui/core` **and** `@lingui/react` are redirected to\n * `@intlayer/lingui` at bundle time.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { linguiVitePlugin } from '@intlayer/lingui/plugin';\n *\n * export default defineConfig({\n * plugins: [linguiVitePlugin()],\n * });\n * ```\n */\nexport const linguiVitePlugin = (\n options?: Parameters<typeof intlayer>[0]\n): PluginOption[] => {\n const intlayerConfig = getConfiguration();\n const appLogger = getAppLogger(intlayerConfig);\n\n runOnce(\n join(\n intlayerConfig.system.baseDir,\n '.intlayer',\n 'cache',\n 'intlayer-issues-invitation.lock'\n ),\n () => {\n appLogger([\n colorize(\n 'Please report any issues you met on GitHub:',\n ANSIColors.GREY\n ),\n colorize(\n 'https://github.com/aymericzip/intlayer/issues',\n ANSIColors.GREY_LIGHT\n ),\n ]);\n },\n {\n cacheTimeoutMs: 1000 * 60 * 60, // 1 hour\n }\n );\n\n const basePlugins = intlayer({\n ...options,\n compatCallers: [\n ...(options?.compatCallers ?? []),\n ...LINGUI_COMPAT_CALLERS,\n ],\n });\n\n const compatPlugin: PluginOption = {\n name: 'vite-lingui-compat-plugin',\n config: () => ({\n resolve: {\n alias: {\n '@lingui/core': '@intlayer/lingui',\n '@lingui/react': '@intlayer/lingui',\n },\n },\n }),\n };\n\n return [\n ...(Array.isArray(basePlugins) ? basePlugins : [basePlugins]),\n compatPlugin,\n ];\n};\n\nexport default linguiVitePlugin;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAmBA,MAAM,wBAA8C,CAAC;;;;;;;;;;;;;;;;;;AAmBrD,MAAa,oBACX,YACmB;CACnB,MAAM,iBAAiB,iBAAiB;CACxC,MAAM,YAAY,aAAa,cAAc;CAE7C,QACE,KACE,eAAe,OAAO,SACtB,aACA,SACA,iCACF,SACM;EACJ,UAAU,CACR,SACE,+CACA,WAAW,IACb,GACA,SACE,iDACA,WAAW,UACb,CACF,CAAC;CACH,GACA,EACE,gBAAgB,MAAO,KAAK,GAC9B,CACF;CAEA,MAAM,cAAc,SAAS;EAC3B,GAAG;EACH,eAAe,CACb,GAAI,SAAS,iBAAiB,CAAC,GAC/B,GAAG,qBACL;CACF,CAAC;CAED,MAAM,eAA6B;EACjC,MAAM;EACN,eAAe,EACb,SAAS,EACP,OAAO;GACL,gBAAgB;GAChB,iBAAiB;EACnB,EACF,EACF;CACF;CAEA,OAAO,CACL,GAAI,MAAM,QAAQ,WAAW,IAAI,cAAc,CAAC,WAAW,GAC3D,YACF;AACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { I18nClass } from "./I18nClass.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/setupI18n.ts
|
|
4
|
+
/**
|
|
5
|
+
* Drop-in for `@lingui/core`'s `setupI18n`.
|
|
6
|
+
*
|
|
7
|
+
* Creates a new intlayer-backed `I18n` instance. The `messages` and
|
|
8
|
+
* `missing` properties from `params` are accepted for API compatibility
|
|
9
|
+
* but are ignored — messages are served by intlayer's compiled dictionaries.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { setupI18n } from '@lingui/core';
|
|
14
|
+
*
|
|
15
|
+
* const i18n = setupI18n({ locale: 'en' });
|
|
16
|
+
* i18n.activate('fr');
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
const setupI18n = (params) => new I18nClass(params);
|
|
20
|
+
/**
|
|
21
|
+
* Global `i18n` singleton — drop-in for `@lingui/core`'s `i18n`.
|
|
22
|
+
*
|
|
23
|
+
* Call `i18n.activate(locale)` to set the active locale before rendering.
|
|
24
|
+
* In React apps, prefer using `useLingui()` inside components so that
|
|
25
|
+
* locale updates are handled reactively via `I18nProvider`.
|
|
26
|
+
*/
|
|
27
|
+
const i18n = setupI18n({ locale: "en" });
|
|
28
|
+
|
|
29
|
+
//#endregion
|
|
30
|
+
export { i18n, setupI18n };
|
|
31
|
+
//# sourceMappingURL=setupI18n.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupI18n.mjs","names":[],"sources":["../../src/setupI18n.ts"],"sourcesContent":["import type { AllMessages, I18n, Locale, Locales } from '@lingui/core';\nimport { I18nClass } from './I18nClass';\n\n/** Mirrors the unexported `I18nProps` type from `@lingui/core`. */\ntype I18nProps = {\n locale?: Locale;\n locales?: Locales;\n messages?: AllMessages;\n missing?: string | ((locale: string, id: string) => string);\n};\n\n/**\n * Drop-in for `@lingui/core`'s `setupI18n`.\n *\n * Creates a new intlayer-backed `I18n` instance. The `messages` and\n * `missing` properties from `params` are accepted for API compatibility\n * but are ignored — messages are served by intlayer's compiled dictionaries.\n *\n * @example\n * ```ts\n * import { setupI18n } from '@lingui/core';\n *\n * const i18n = setupI18n({ locale: 'en' });\n * i18n.activate('fr');\n * ```\n */\nexport const setupI18n = (params?: I18nProps): I18n =>\n new I18nClass(params) as unknown as I18n;\n\n/**\n * Global `i18n` singleton — drop-in for `@lingui/core`'s `i18n`.\n *\n * Call `i18n.activate(locale)` to set the active locale before rendering.\n * In React apps, prefer using `useLingui()` inside components so that\n * locale updates are handled reactively via `I18nProvider`.\n */\nexport const i18n: I18n = setupI18n({ locale: 'en' });\n"],"mappings":";;;;;;;;;;;;;;;;;;AA0BA,MAAa,aAAa,WACxB,IAAI,UAAU,MAAM;;;;;;;;AAStB,MAAa,OAAa,UAAU,EAAE,QAAQ,KAAK,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { I18nClass } from "./I18nClass.mjs";
|
|
4
|
+
import { LinguiContext } from "./LinguiContext.mjs";
|
|
5
|
+
import { useContext, useMemo } from "react";
|
|
6
|
+
import { useLocale } from "react-intlayer";
|
|
7
|
+
|
|
8
|
+
//#region src/useLingui.ts
|
|
9
|
+
/**
|
|
10
|
+
* Drop-in for `@lingui/react`'s `useLingui`.
|
|
11
|
+
*
|
|
12
|
+
* Returns `{ i18n, _, defaultComponent }` from the nearest `I18nProvider`.
|
|
13
|
+
* When used outside a provider, derives a locale-aware `i18n` instance from
|
|
14
|
+
* `react-intlayer`'s `useLocale()` so that Server Components and test contexts
|
|
15
|
+
* work without an explicit provider.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* const { _ } = useLingui();
|
|
20
|
+
* return <h1>{_({ id: 'home.title', message: 'Welcome' })}</h1>;
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
const useLingui = () => {
|
|
24
|
+
const context = useContext(LinguiContext);
|
|
25
|
+
const { locale } = useLocale();
|
|
26
|
+
const derivedI18n = useMemo(() => {
|
|
27
|
+
const instance = new I18nClass({ locale });
|
|
28
|
+
return {
|
|
29
|
+
i18n: instance,
|
|
30
|
+
_: instance._.bind(instance)
|
|
31
|
+
};
|
|
32
|
+
}, [locale]);
|
|
33
|
+
if (context) return context;
|
|
34
|
+
return derivedI18n;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
export { useLingui };
|
|
39
|
+
//# sourceMappingURL=useLingui.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLingui.mjs","names":[],"sources":["../../src/useLingui.ts"],"sourcesContent":["'use client';\n\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport type { I18nContext } from '@lingui/react';\nimport { useContext, useMemo } from 'react';\nimport { useLocale } from 'react-intlayer';\nimport { I18nClass } from './I18nClass';\nimport { LinguiContext } from './LinguiContext';\n\n/**\n * Drop-in for `@lingui/react`'s `useLingui`.\n *\n * Returns `{ i18n, _, defaultComponent }` from the nearest `I18nProvider`.\n * When used outside a provider, derives a locale-aware `i18n` instance from\n * `react-intlayer`'s `useLocale()` so that Server Components and test contexts\n * work without an explicit provider.\n *\n * @example\n * ```tsx\n * const { _ } = useLingui();\n * return <h1>{_({ id: 'home.title', message: 'Welcome' })}</h1>;\n * ```\n */\nexport const useLingui = (): I18nContext => {\n const context = useContext(LinguiContext);\n const { locale } = useLocale();\n\n const derivedI18n = useMemo(() => {\n const instance = new I18nClass({ locale: locale as string });\n return {\n i18n: instance as unknown as I18nContext['i18n'],\n _: instance._.bind(instance) as I18nContext['_'],\n };\n }, [locale]);\n\n if (context) {\n return context;\n }\n\n return derivedI18n as I18nContext;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,kBAA+B;CAC1C,MAAM,UAAU,WAAW,aAAa;CACxC,MAAM,EAAE,WAAW,UAAU;CAE7B,MAAM,cAAc,cAAc;EAChC,MAAM,WAAW,IAAI,UAAU,EAAU,OAAiB,CAAC;EAC3D,OAAO;GACL,MAAM;GACN,GAAG,SAAS,EAAE,KAAK,QAAQ;EAC7B;CACF,GAAG,CAAC,MAAM,CAAC;CAEX,IAAI,SACF,OAAO;CAGT,OAAO;AACT"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { EventEmitter } from "./eventEmitter.js";
|
|
2
|
+
import { AllMessages, Locale, Locales, MessageDescriptor, MessageId, MessageOptions, Messages } from "@lingui/core";
|
|
3
|
+
|
|
4
|
+
//#region src/I18nClass.d.ts
|
|
5
|
+
/** Mirrors the unexported `Values` type from `@lingui/core`. */
|
|
6
|
+
type Values = Record<string, unknown>;
|
|
7
|
+
/** Mirrors the unexported `MessageCompiler` type from `@lingui/core`. */
|
|
8
|
+
type MessageCompiler = (message: string) => unknown;
|
|
9
|
+
/** Mirrors the unexported `Events` type from `@lingui/core`. */
|
|
10
|
+
type LinguiEvents = {
|
|
11
|
+
change: () => void;
|
|
12
|
+
missing: (event: {
|
|
13
|
+
locale: Locale;
|
|
14
|
+
id: MessageId;
|
|
15
|
+
}) => void;
|
|
16
|
+
};
|
|
17
|
+
/** Mirrors the unexported `I18nProps` type from `@lingui/core`. */
|
|
18
|
+
type I18nProps = {
|
|
19
|
+
locale?: Locale;
|
|
20
|
+
locales?: Locales;
|
|
21
|
+
messages?: AllMessages;
|
|
22
|
+
missing?: string | ((locale: string, id: string) => string);
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Intlayer-backed implementation of `@lingui/core`'s `I18n` class.
|
|
26
|
+
*
|
|
27
|
+
* - Messages are read from the `messages` intlayer dictionary.
|
|
28
|
+
* - ICU MessageFormat syntax is resolved via `@intlayer/core/messageFormat`.
|
|
29
|
+
* - `load()` / `loadAndActivate()` / `setMessagesCompiler()` are no-ops —
|
|
30
|
+
* messages are served by intlayer's compiled dictionaries.
|
|
31
|
+
* - `activate(locale)` emits `'change'` so that React consumers re-render.
|
|
32
|
+
*/
|
|
33
|
+
declare class I18nClass extends EventEmitter<LinguiEvents> {
|
|
34
|
+
private _locale;
|
|
35
|
+
private _locales?;
|
|
36
|
+
constructor({
|
|
37
|
+
locale,
|
|
38
|
+
locales
|
|
39
|
+
}?: I18nProps);
|
|
40
|
+
get locale(): string;
|
|
41
|
+
get locales(): Locales | undefined;
|
|
42
|
+
get messages(): Messages;
|
|
43
|
+
/**
|
|
44
|
+
* No-op: intlayer handles message compilation at build time.
|
|
45
|
+
*/
|
|
46
|
+
setMessagesCompiler(_compiler: MessageCompiler): this;
|
|
47
|
+
/**
|
|
48
|
+
* No-op: messages are loaded automatically via intlayer dictionaries.
|
|
49
|
+
*/
|
|
50
|
+
load(_localeOrAll: Locale | AllMessages, _messages?: Messages): void;
|
|
51
|
+
/**
|
|
52
|
+
* Activates the given locale (emits `'change'`).
|
|
53
|
+
* The `messages` argument is ignored — intlayer handles the catalog.
|
|
54
|
+
*/
|
|
55
|
+
loadAndActivate({
|
|
56
|
+
locale,
|
|
57
|
+
locales
|
|
58
|
+
}: {
|
|
59
|
+
locale: Locale;
|
|
60
|
+
locales?: Locales;
|
|
61
|
+
messages: Messages;
|
|
62
|
+
}): void;
|
|
63
|
+
/**
|
|
64
|
+
* Sets the active locale and emits `'change'` to notify React consumers.
|
|
65
|
+
*/
|
|
66
|
+
activate(locale: Locale, locales?: Locales): void;
|
|
67
|
+
/**
|
|
68
|
+
* Translates a message descriptor or a plain ID.
|
|
69
|
+
*
|
|
70
|
+
* Resolution order:
|
|
71
|
+
* 1. `messages` intlayer dictionary (dotted path navigation)
|
|
72
|
+
* 2. `descriptor.message` or `options.message` (original source string)
|
|
73
|
+
* 3. The raw `id` as fallback
|
|
74
|
+
*/
|
|
75
|
+
_(descriptor: MessageDescriptor): string;
|
|
76
|
+
_(id: MessageId, values?: Values, options?: MessageOptions): string;
|
|
77
|
+
/**
|
|
78
|
+
* Alias for `_`. Provided for lingui API compatibility.
|
|
79
|
+
*/
|
|
80
|
+
t: (descriptorOrId: MessageDescriptor | MessageId, values?: Values, options?: MessageOptions) => string;
|
|
81
|
+
/**
|
|
82
|
+
* @deprecated Use `Intl.DateTimeFormat` directly.
|
|
83
|
+
*/
|
|
84
|
+
date(value?: string | Date | number, format?: Intl.DateTimeFormatOptions): string;
|
|
85
|
+
/**
|
|
86
|
+
* @deprecated Use `Intl.NumberFormat` directly.
|
|
87
|
+
*/
|
|
88
|
+
number(value: number | bigint, format?: Intl.NumberFormatOptions): string;
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
export { I18nClass };
|
|
92
|
+
//# sourceMappingURL=I18nClass.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"I18nClass.d.ts","names":[],"sources":["../../src/I18nClass.ts"],"mappings":";;;;;KAkBK,MAAA,GAAS,MAAM;AAH0B;AAAA,KAMzC,eAAA,IAAmB,OAAe;;KAGlC,YAAA;EACH,MAAA;EACA,OAAA,GAAU,KAAA;IAAS,MAAA,EAAQ,MAAA;IAAQ,EAAA,EAAI,SAAS;EAAA;AAAA;AALX;AAAA,KASlC,SAAA;EACH,MAAA,GAAS,MAAA;EACT,OAAA,GAAU,OAAA;EACV,QAAA,GAAW,WAAA;EACX,OAAA,cAAqB,MAAA,UAAgB,EAAA;AAAA;;;;;;AARa;AAAA;;;cA8DvC,SAAA,SAAkB,YAAA,CAAa,YAAA;EAAA,QAClC,OAAA;EAAA,QACA,QAAA;;IAEM,MAAA;IAAe;EAAA,IAAW,SAAA;EAAA,IAMpC,MAAA;EAAA,IAIA,OAAA,IAAW,OAAA;EAAA,IAIX,QAAA,IAAY,QAAA;EA1EhB;;;EAwFA,mBAAA,CAAoB,SAAA,EAAW,eAAA;EAtF/B;;;EAmGA,IAAA,CAAK,YAAA,EAAc,MAAA,GAAS,WAAA,EAAa,SAAA,GAAY,QAAA;EAnGN;AAsDjD;;;EA0DE,eAAA;IACE,MAAA;IACA;EAAA;IAEA,MAAA,EAAQ,MAAA;IACR,OAAA,GAAU,OAAA;IACV,QAAA,EAAU,QAAA;EAAA;EA9CI;;;EAsDhB,QAAA,CAAS,MAAA,EAAQ,MAAA,EAAQ,OAAA,GAAU,OAAA;EA3BkB;;;;;;;;EAyCrD,CAAA,CAAE,UAAA,EAAY,iBAAA;EACd,CAAA,CAAE,EAAA,EAAI,SAAA,EAAW,MAAA,GAAS,MAAA,EAAQ,OAAA,GAAU,cAAA;EAAlB;;;EAqC1B,CAAA,GACE,cAAA,EAAgB,iBAAA,GAAoB,SAAA,EACpC,MAAA,GAAS,MAAA,EACT,OAAA,GAAU,cAAA;EADD;;;EAOX,IAAA,CACE,KAAA,YAAiB,IAAA,WACjB,MAAA,GAAS,IAAA,CAAK,qBAAA;EAawB;;;EAAxC,MAAA,CAAO,KAAA,mBAAwB,MAAA,GAAS,IAAA,CAAK,mBAAA;AAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { I18nProviderProps } from "@lingui/react";
|
|
2
|
+
import { JSX } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/I18nProvider.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Drop-in for `@lingui/react`'s `I18nProvider`.
|
|
7
|
+
*
|
|
8
|
+
* Differences from the original:
|
|
9
|
+
* - Wraps children in an `IntlayerProvider` so that intlayer hooks receive the
|
|
10
|
+
* correct locale from the `i18n` instance.
|
|
11
|
+
* - Listens to the `i18n` `'change'` event to sync locale and context when
|
|
12
|
+
* `i18n.activate(locale)` is called at runtime.
|
|
13
|
+
* - The `defaultComponent` prop is forwarded but not used for rendering — it is
|
|
14
|
+
* stored in context for downstream `useLingui()` consumers.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* import { i18n } from '@lingui/core';
|
|
19
|
+
* import { I18nProvider } from '@lingui/react';
|
|
20
|
+
*
|
|
21
|
+
* i18n.activate('fr');
|
|
22
|
+
*
|
|
23
|
+
* export default function App() {
|
|
24
|
+
* return (
|
|
25
|
+
* <I18nProvider i18n={i18n}>
|
|
26
|
+
* <YourApp />
|
|
27
|
+
* </I18nProvider>
|
|
28
|
+
* );
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
declare const I18nProvider: ({
|
|
33
|
+
i18n,
|
|
34
|
+
defaultComponent,
|
|
35
|
+
children
|
|
36
|
+
}: I18nProviderProps) => JSX.Element | null;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { I18nProvider };
|
|
39
|
+
//# sourceMappingURL=I18nProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"I18nProvider.d.ts","names":[],"sources":["../../src/I18nProvider.tsx"],"mappings":";;;;;;AAoCA;;;;;;;;;;;;;;;;;;;;AAIkC;;;;;cAJrB,YAAA;EAAgB,IAAA;EAAA,gBAAA;EAAA;AAAA,GAI1B,iBAAA,KAAoB,GAAA,CAAI,OAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { I18nContext } from "@lingui/react";
|
|
2
|
+
|
|
3
|
+
//#region src/LinguiContext.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Drop-in for `@lingui/react`'s `LinguiContext`.
|
|
6
|
+
*
|
|
7
|
+
* Provides the active `I18n` instance and the `_` translation function
|
|
8
|
+
* to all descendant components.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import { useContext } from 'react';
|
|
13
|
+
* import { LinguiContext } from '@lingui/react';
|
|
14
|
+
*
|
|
15
|
+
* const { i18n } = useContext(LinguiContext)!;
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
declare const LinguiContext: import("react").Context<I18nContext>;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { LinguiContext };
|
|
21
|
+
//# sourceMappingURL=LinguiContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinguiContext.d.ts","names":[],"sources":["../../src/LinguiContext.tsx"],"mappings":";;;;;AAiBA;;;;AAA0B;;;;;;;;cAAb,aAAA,kBAAa,OAAA,CAAA,WAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { TransProps } from "@lingui/react";
|
|
2
|
+
import { ReactElement } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/Trans.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Drop-in for `@lingui/react`'s `<Trans>`.
|
|
7
|
+
*
|
|
8
|
+
* Looks up the message `id` in the `messages` intlayer dictionary and renders
|
|
9
|
+
* the result. When `components` is provided, named tags in the translated
|
|
10
|
+
* string are mapped to React elements (uses `parseTaggedMessage` from
|
|
11
|
+
* `@intlayer/core`).
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* // Simple message
|
|
16
|
+
* <Trans id="home.title" message="Welcome" />
|
|
17
|
+
*
|
|
18
|
+
* // Rich text with components
|
|
19
|
+
* <Trans
|
|
20
|
+
* id="legal.terms"
|
|
21
|
+
* message="I agree to the <link>terms</link>"
|
|
22
|
+
* components={{ link: <a href="/terms" /> }}
|
|
23
|
+
* />
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
declare const Trans: ({
|
|
27
|
+
id,
|
|
28
|
+
message,
|
|
29
|
+
values,
|
|
30
|
+
components,
|
|
31
|
+
formats: _formats,
|
|
32
|
+
comment: _comment,
|
|
33
|
+
render,
|
|
34
|
+
component: WrapperComponent
|
|
35
|
+
}: TransProps) => ReactElement | null;
|
|
36
|
+
//#endregion
|
|
37
|
+
export { Trans };
|
|
38
|
+
//# sourceMappingURL=Trans.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Trans.d.ts","names":[],"sources":["../../src/Trans.tsx"],"mappings":";;;;;;AA+EA;;;;;;;;;;;;;;;;;;;cAAa,KAAA;EAAS,EAAA;EAAA,OAAA;EAAA,MAAA;EAAA,UAAA;EAAA,OAAA,EAAA,QAAA;EAAA,OAAA,EAAA,QAAA;EAAA,MAAA;EAAA,SAAA,EAAA;AAAA,GASnB,UAAA,KAAa,YAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region src/eventEmitter.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Minimal EventEmitter that mirrors `@lingui/core`'s EventEmitter API.
|
|
4
|
+
* Required because we cannot import from `@lingui/core` at runtime
|
|
5
|
+
* (we are its alias) — so we reimplement the base class here.
|
|
6
|
+
*/
|
|
7
|
+
declare class EventEmitter<Events extends Record<string, (...args: unknown[]) => void>> {
|
|
8
|
+
private readonly _events;
|
|
9
|
+
/**
|
|
10
|
+
* Registers a listener for the given event and returns an unsubscribe function.
|
|
11
|
+
*/
|
|
12
|
+
on<E extends keyof Events>(event: E, listener: Events[E]): () => void;
|
|
13
|
+
/**
|
|
14
|
+
* Removes a previously registered listener.
|
|
15
|
+
*/
|
|
16
|
+
removeListener<E extends keyof Events>(event: E, listener: Events[E]): void;
|
|
17
|
+
/**
|
|
18
|
+
* Emits an event, invoking all registered listeners.
|
|
19
|
+
*/
|
|
20
|
+
emit<E extends keyof Events>(event: E, ...args: Parameters<Events[E]>): void;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { EventEmitter };
|
|
24
|
+
//# sourceMappingURL=eventEmitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventEmitter.d.ts","names":[],"sources":["../../src/eventEmitter.ts"],"mappings":";;AAKA;;;;cAAa,YAAA,gBACI,MAAA,aAAmB,IAAA;EAAA,iBAEjB,OAAA;EAQ8B;;;EAA/C,EAAA,iBAAmB,MAAA,EAAQ,KAAA,EAAO,CAAA,EAAG,QAAA,EAAU,MAAA,CAAO,CAAA;EAWK;;;EAA3D,cAAA,iBAA+B,MAAA,EAAQ,KAAA,EAAO,CAAA,EAAG,QAAA,EAAU,MAAA,CAAO,CAAA;EAOP;;;EAA3D,IAAA,iBAAqB,MAAA,EAAQ,KAAA,EAAO,CAAA,KAAM,IAAA,EAAM,UAAA,CAAW,MAAA,CAAO,CAAA;AAAA"}
|