@let-value/translate-react 1.0.11 → 1.0.13

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/dist/index.cjs CHANGED
@@ -124,8 +124,7 @@ function Message({ context, children }) {
124
124
  }
125
125
  const tokens = values.map((_, i) => `\u0000${i}\u0000`);
126
126
  const built = (0, __let_value_translate.message)(strings, ...tokens);
127
- const translated = context ? translator.context(context).message(built) : translator.message(built);
128
- const parts = translated.split(/\u0000(\d+)\u0000/);
127
+ const parts = (context ? translator.context(context).message(built) : translator.message(built)).split(/\u0000(\d+)\u0000/);
129
128
  const result = [];
130
129
  for (let i = 0; i < parts.length; i += 2) {
131
130
  result.push(parts[i]);
@@ -149,8 +148,7 @@ function Plural({ number, forms, context }) {
149
148
  });
150
149
  const messages = built.map((b) => b.message);
151
150
  const input = (0, __let_value_translate.plural)(...messages, number);
152
- const translated = context ? translator.context(context).plural(input) : translator.plural(input);
153
- const parts = translated.split(/\u0000(\d+)-(\d+)\u0000/);
151
+ const parts = (context ? translator.context(context).plural(input) : translator.plural(input)).split(/\u0000(\d+)-(\d+)\u0000/);
154
152
  const result = [];
155
153
  for (let i = 0; i < parts.length;) {
156
154
  result.push(parts[i]);
package/dist/index.d.cts CHANGED
@@ -1,5 +1,6 @@
1
+ import * as _let_value_translate0 from "@let-value/translate";
1
2
  import { Locale, LocaleTranslator, Translator } from "@let-value/translate";
2
- import * as react1 from "react";
3
+ import * as react0 from "react";
3
4
  import { ReactNode } from "react";
4
5
  import { GetTextTranslations } from "gettext-parser";
5
6
  export * from "@let-value/translate";
@@ -12,7 +13,7 @@ interface LocaleProviderProps {
12
13
  declare function LocaleProvider({
13
14
  locale,
14
15
  children
15
- }: LocaleProviderProps): react1.FunctionComponentElement<react1.ProviderProps<Locale | undefined>>;
16
+ }: LocaleProviderProps): react0.FunctionComponentElement<react0.ProviderProps<_let_value_translate0.Configuration | undefined>>;
16
17
  //#endregion
17
18
  //#region src/components/Message.d.ts
18
19
  interface MessageProps {
@@ -22,7 +23,7 @@ interface MessageProps {
22
23
  declare function Message({
23
24
  context,
24
25
  children
25
- }: MessageProps): string | react1.FunctionComponentElement<react1.FragmentProps>;
26
+ }: MessageProps): string | react0.FunctionComponentElement<react0.FragmentProps>;
26
27
  //#endregion
27
28
  //#region src/components/Plural.d.ts
28
29
  interface PluralProps {
@@ -34,7 +35,7 @@ declare function Plural({
34
35
  number,
35
36
  forms,
36
37
  context
37
- }: PluralProps): react1.FunctionComponentElement<react1.FragmentProps>;
38
+ }: PluralProps): react0.FunctionComponentElement<react0.FragmentProps>;
38
39
  //#endregion
39
40
  //#region src/components/TranslationsProvider.d.ts
40
41
  type TranslationLoader = () => Promise<GetTextTranslations>;
@@ -46,7 +47,7 @@ interface TranslationsProviderProps {
46
47
  declare function TranslationsProvider({
47
48
  translations,
48
49
  children
49
- }: TranslationsProviderProps): react1.FunctionComponentElement<react1.ProviderProps<Translator<Partial<Record<Locale, (GetTextTranslations | {
50
+ }: TranslationsProviderProps): react0.FunctionComponentElement<react0.ProviderProps<Translator<Partial<Record<_let_value_translate0.Configuration, (GetTextTranslations | {
50
51
  default: GetTextTranslations;
51
52
  }) | Promise<GetTextTranslations | {
52
53
  default: GetTextTranslations;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/components/LocaleProvider.ts","../src/components/Message.ts","../src/components/Plural.ts","../src/components/TranslationsProvider.ts","../src/hooks/useLocale.ts","../src/hooks/useTranslations.ts"],"sourcesContent":[],"mappings":";;;;;;;UAIiB,mBAAA;UACL;aACG;;iBAGC,cAAA;;;GAAqC,sBAAmB,MAAA,CAAA,yBAAA,MAAA,CAAA,cAAA;;;UCHvD,YAAA;;YAEH;;iBAGE,OAAA;;;GAA+B,wBAAY,MAAA,CAAA,yBAAA,MAAA,CAAA,aAAA;;;UCL1C,WAAA;;kBAEG;;;iBAIJ,MAAA;;;;GAAmC,cAAW,MAAA,CAAA,yBAAA,MAAA,CAAA,aAAA;;;KCNzD,iBAAA,SAA0B,QAAQ;KAClC,gBAAA,GAAmB,sBAAsB;UAE7B,yBAAA;iBACE,QAAQ,OAAO,QAAQ;EHNzB,QAAA,CAAA,EGOF,SHPE;;AACL,iBGSI,oBAAA,CHTJ;EAAA,YAAA;EAAA;AAAA,CAAA,EGS0D,yBHT1D,CAAA,EGSmF,MAAA,CAAA,wBHTnF,CGSmF,MAAA,CAAA,aHTnF,CGSmF,UHTnF,CGSmF,OHTnF,CGSmF,MHTnF,CGSmF,MHTnF,EAAA,CGSmF,mBHTnF,GAAA;SACG,qBAAA;;EAGC,OAAA,qBAAc;CAAA,CAAA,GAAA,CAAA,GAAA,UAAA,oBAAA,GAAA;SAAG,qBAAA;SAAQ,SAAA,CAAA,CAAA;;;iBILzB,SAAA,CAAA,GAAa;;;iBC0Bb,eAAA,UAAyB,SAAS"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/components/LocaleProvider.ts","../src/components/Message.ts","../src/components/Plural.ts","../src/components/TranslationsProvider.ts","../src/hooks/useLocale.ts","../src/hooks/useTranslations.ts"],"sourcesContent":[],"mappings":";;;;;;;;UAIiB,mBAAA;UACL;aACG;;iBAGC,cAAA;;;GAAqC,sBAAmB,MAAA,CAAA,yBAAA,MAAA,CAAA,cAAA,qBAAA,CAAA,aAAA;;;UCHvD,YAAA;;YAEH;;iBAGE,OAAA;;;GAA+B,wBAAY,MAAA,CAAA,yBAAA,MAAA,CAAA,aAAA;;;UCL1C,WAAA;;kBAEG;;;iBAIJ,MAAA;;;;GAAmC,cAAW,MAAA,CAAA,yBAAA,MAAA,CAAA,aAAA;;;KCNzD,iBAAA,SAA0B,QAAQ;KAClC,gBAAA,GAAmB,sBAAsB;UAE7B,yBAAA;iBACE,QAAQ,OAAO,QAAQ;aAC3B;AHPf;AAAoC,iBGUpB,oBAAA,CHVoB;EAAA,YAAA;EAAA;AAAA,CAAA,EGUkC,yBHVlC,CAAA,EGU2D,MAAA,CAAA,wBHV3D,CGU2D,MAAA,CAAA,aHV3D,CGU2D,UHV3D,CGU2D,OHV3D,CGU2D,MHV3D,CGU2D,qBAAA,CAAA,aAAA,EHV3D,CGU2D,mBHV3D,GAAA;SACxB,qBAAA;YACG,oBAAA,GAAA;EAAS,OAAA,qBAAA;AAGxB,CAAA,CAAA,GAAgB,CAAA,GAAA,UAAA,oBAAc,GAAA;EAAA,OAAA,qBAAA;SAAG,SAAA,CAAA,CAAA;;;iBILjB,SAAA,CAAA,GAAa;;;iBC0Bb,eAAA,UAAyB,SAAS"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
+ import * as _let_value_translate0 from "@let-value/translate";
1
2
  import { Locale, LocaleTranslator, Translator } from "@let-value/translate";
2
- import * as react1 from "react";
3
+ import * as react0 from "react";
3
4
  import { ReactNode } from "react";
4
5
  import { GetTextTranslations } from "gettext-parser";
5
6
  export * from "@let-value/translate";
@@ -12,7 +13,7 @@ interface LocaleProviderProps {
12
13
  declare function LocaleProvider({
13
14
  locale,
14
15
  children
15
- }: LocaleProviderProps): react1.FunctionComponentElement<react1.ProviderProps<Locale | undefined>>;
16
+ }: LocaleProviderProps): react0.FunctionComponentElement<react0.ProviderProps<_let_value_translate0.Configuration | undefined>>;
16
17
  //#endregion
17
18
  //#region src/components/Message.d.ts
18
19
  interface MessageProps {
@@ -22,7 +23,7 @@ interface MessageProps {
22
23
  declare function Message({
23
24
  context,
24
25
  children
25
- }: MessageProps): string | react1.FunctionComponentElement<react1.FragmentProps>;
26
+ }: MessageProps): string | react0.FunctionComponentElement<react0.FragmentProps>;
26
27
  //#endregion
27
28
  //#region src/components/Plural.d.ts
28
29
  interface PluralProps {
@@ -34,7 +35,7 @@ declare function Plural({
34
35
  number,
35
36
  forms,
36
37
  context
37
- }: PluralProps): react1.FunctionComponentElement<react1.FragmentProps>;
38
+ }: PluralProps): react0.FunctionComponentElement<react0.FragmentProps>;
38
39
  //#endregion
39
40
  //#region src/components/TranslationsProvider.d.ts
40
41
  type TranslationLoader = () => Promise<GetTextTranslations>;
@@ -46,7 +47,7 @@ interface TranslationsProviderProps {
46
47
  declare function TranslationsProvider({
47
48
  translations,
48
49
  children
49
- }: TranslationsProviderProps): react1.FunctionComponentElement<react1.ProviderProps<Translator<Partial<Record<Locale, (GetTextTranslations | {
50
+ }: TranslationsProviderProps): react0.FunctionComponentElement<react0.ProviderProps<Translator<Partial<Record<_let_value_translate0.Configuration, (GetTextTranslations | {
50
51
  default: GetTextTranslations;
51
52
  }) | Promise<GetTextTranslations | {
52
53
  default: GetTextTranslations;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/components/LocaleProvider.ts","../src/components/Message.ts","../src/components/Plural.ts","../src/components/TranslationsProvider.ts","../src/hooks/useLocale.ts","../src/hooks/useTranslations.ts"],"sourcesContent":[],"mappings":";;;;;;;UAIiB,mBAAA;UACL;aACG;;iBAGC,cAAA;;;GAAqC,sBAAmB,MAAA,CAAA,yBAAA,MAAA,CAAA,cAAA;;;UCHvD,YAAA;;YAEH;;iBAGE,OAAA;;;GAA+B,wBAAY,MAAA,CAAA,yBAAA,MAAA,CAAA,aAAA;;;UCL1C,WAAA;;kBAEG;;;iBAIJ,MAAA;;;;GAAmC,cAAW,MAAA,CAAA,yBAAA,MAAA,CAAA,aAAA;;;KCNzD,iBAAA,SAA0B,QAAQ;KAClC,gBAAA,GAAmB,sBAAsB;UAE7B,yBAAA;iBACE,QAAQ,OAAO,QAAQ;EHNzB,QAAA,CAAA,EGOF,SHPE;;AACL,iBGSI,oBAAA,CHTJ;EAAA,YAAA;EAAA;AAAA,CAAA,EGS0D,yBHT1D,CAAA,EGSmF,MAAA,CAAA,wBHTnF,CGSmF,MAAA,CAAA,aHTnF,CGSmF,UHTnF,CGSmF,OHTnF,CGSmF,MHTnF,CGSmF,MHTnF,EAAA,CGSmF,mBHTnF,GAAA;SACG,qBAAA;;EAGC,OAAA,qBAAc;CAAA,CAAA,GAAA,CAAA,GAAA,UAAA,oBAAA,GAAA;SAAG,qBAAA;SAAQ,SAAA,CAAA,CAAA;;;iBILzB,SAAA,CAAA,GAAa;;;iBC0Bb,eAAA,UAAyB,SAAS"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/components/LocaleProvider.ts","../src/components/Message.ts","../src/components/Plural.ts","../src/components/TranslationsProvider.ts","../src/hooks/useLocale.ts","../src/hooks/useTranslations.ts"],"sourcesContent":[],"mappings":";;;;;;;;UAIiB,mBAAA;UACL;aACG;;iBAGC,cAAA;;;GAAqC,sBAAmB,MAAA,CAAA,yBAAA,MAAA,CAAA,cAAA,qBAAA,CAAA,aAAA;;;UCHvD,YAAA;;YAEH;;iBAGE,OAAA;;;GAA+B,wBAAY,MAAA,CAAA,yBAAA,MAAA,CAAA,aAAA;;;UCL1C,WAAA;;kBAEG;;;iBAIJ,MAAA;;;;GAAmC,cAAW,MAAA,CAAA,yBAAA,MAAA,CAAA,aAAA;;;KCNzD,iBAAA,SAA0B,QAAQ;KAClC,gBAAA,GAAmB,sBAAsB;UAE7B,yBAAA;iBACE,QAAQ,OAAO,QAAQ;aAC3B;AHPf;AAAoC,iBGUpB,oBAAA,CHVoB;EAAA,YAAA;EAAA;AAAA,CAAA,EGUkC,yBHVlC,CAAA,EGU2D,MAAA,CAAA,wBHV3D,CGU2D,MAAA,CAAA,aHV3D,CGU2D,UHV3D,CGU2D,OHV3D,CGU2D,MHV3D,CGU2D,qBAAA,CAAA,aAAA,EHV3D,CGU2D,mBHV3D,GAAA;SACxB,qBAAA;YACG,oBAAA,GAAA;EAAS,OAAA,qBAAA;AAGxB,CAAA,CAAA,GAAgB,CAAA,GAAA,UAAA,oBAAc,GAAA;EAAA,OAAA,qBAAA;SAAG,SAAA,CAAA,CAAA;;;iBILjB,SAAA,CAAA,GAAa;;;iBC0Bb,eAAA,UAAyB,SAAS"}
package/dist/index.js CHANGED
@@ -101,8 +101,7 @@ function Message({ context, children }) {
101
101
  }
102
102
  const tokens = values.map((_, i) => `\u0000${i}\u0000`);
103
103
  const built = message(strings, ...tokens);
104
- const translated = context ? translator.context(context).message(built) : translator.message(built);
105
- const parts = translated.split(/\u0000(\d+)\u0000/);
104
+ const parts = (context ? translator.context(context).message(built) : translator.message(built)).split(/\u0000(\d+)\u0000/);
106
105
  const result = [];
107
106
  for (let i = 0; i < parts.length; i += 2) {
108
107
  result.push(parts[i]);
@@ -126,8 +125,7 @@ function Plural({ number, forms, context }) {
126
125
  });
127
126
  const messages = built.map((b) => b.message);
128
127
  const input = plural(...messages, number);
129
- const translated = context ? translator.context(context).plural(input) : translator.plural(input);
130
- const parts = translated.split(/\u0000(\d+)-(\d+)\u0000/);
128
+ const parts = (context ? translator.context(context).plural(input) : translator.plural(input)).split(/\u0000(\d+)-(\d+)\u0000/);
131
129
  const result = [];
132
130
  for (let i = 0; i < parts.length;) {
133
131
  result.push(parts[i]);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["result: ReactNode[]","strings: string[]","values: ReactNode[]","result: ReactNode[]","result: ReactNode[]"],"sources":["../src/context.ts","../src/components/LocaleProvider.ts","../src/hooks/useTranslations.ts","../src/utils.ts","../src/components/Message.ts","../src/components/Plural.ts","../src/components/TranslationsProvider.ts","../src/hooks/useLocale.ts"],"sourcesContent":["import type { Locale, Translator } from \"@let-value/translate\";\nimport { createContext } from \"react\";\n\nexport const localeContext = createContext<Locale | undefined>(undefined);\nexport const translatorContext = createContext<Translator | undefined>(undefined);\n","import type { Locale } from \"@let-value/translate\";\nimport { createElement, type ReactNode } from \"react\";\nimport { localeContext } from \"../context.ts\";\n\nexport interface LocaleProviderProps {\n locale: Locale;\n children?: ReactNode;\n}\n\nexport function LocaleProvider({ locale, children }: LocaleProviderProps) {\n return createElement(localeContext.Provider, { value: locale }, children);\n}\n","import type { Locale, LocaleTranslator } from \"@let-value/translate\";\nimport { use } from \"react\";\n\nimport { localeContext, translatorContext } from \"../context.ts\";\n\n/** @deprecated replace with `use` from react */\n// biome-ignore lint/suspicious/noExplicitAny: we need to decorate the promise\nfunction getPromiseState(promise: any) {\n switch (promise.status) {\n case \"pending\":\n return { status: \"pending\" };\n case \"fulfilled\":\n return { status: \"fulfilled\", value: promise.value };\n case \"rejected\":\n return { status: \"rejected\", reason: promise.reason };\n default: {\n promise.status = \"pending\";\n promise.then((value: unknown) => {\n promise.status = \"fulfilled\";\n promise.value = value;\n });\n promise.catch((reason: unknown) => {\n promise.status = \"rejected\";\n promise.reason = reason;\n });\n return getPromiseState(promise);\n }\n }\n}\n\nexport function useTranslations(locale?: Locale): LocaleTranslator {\n const requestedLocale = locale ?? use(localeContext) ?? (\"unknown\" as never);\n const translator = use(translatorContext);\n if (!translator) {\n throw new Error(\"TranslationsProvider is missing\");\n }\n\n const resource = translator.fetchLocale(requestedLocale);\n if (!(resource instanceof Promise)) {\n return resource;\n }\n\n const state = getPromiseState(resource);\n if (state.status === \"pending\") {\n throw resource;\n }\n if (state.status === \"rejected\") {\n throw state.reason;\n }\n if (state.status === \"fulfilled\") {\n return state.value;\n }\n\n return use(resource);\n}\n","import { Children, Fragment, isValidElement, type PropsWithChildren, type ReactNode } from \"react\";\n\nexport function buildTemplateFromChildren(children: ReactNode): {\n strings: string[];\n values: ReactNode[];\n} {\n function flatten(nodes: ReactNode): ReactNode[] {\n const result: ReactNode[] = [];\n Children.forEach(nodes, (child) => {\n if (isValidElement(child) && child.type === Fragment) {\n result.push(...flatten((child.props as PropsWithChildren).children));\n } else {\n result.push(child);\n }\n });\n return result;\n }\n\n const array = flatten(children);\n const strings: string[] = [\"\"];\n const values: ReactNode[] = [];\n let expectValue = false;\n\n array.forEach((child) => {\n if (typeof child === \"string\") {\n if (expectValue) {\n values.push(child);\n strings.push(\"\");\n expectValue = false;\n } else {\n strings[strings.length - 1] += child;\n expectValue = true;\n }\n } else if (typeof child === \"number\" || child != null) {\n values.push(child as ReactNode);\n strings.push(\"\");\n expectValue = false;\n }\n });\n\n return { strings, values };\n}\n","import { message } from \"@let-value/translate\";\nimport { createElement, Fragment, type ReactNode } from \"react\";\n\nimport { useTranslations } from \"../hooks/useTranslations.ts\";\nimport { buildTemplateFromChildren } from \"../utils.ts\";\n\nexport interface MessageProps {\n context?: string;\n children: ReactNode;\n}\n\nexport function Message({ context, children }: MessageProps) {\n const translator = useTranslations();\n const { strings, values } = buildTemplateFromChildren(children);\n\n if (values.length === 0) {\n const input = strings.join(\"\");\n if (context) {\n return translator.context(context as \"\").message(input as never);\n }\n return translator.message(input as never);\n }\n\n const tokens = values.map((_, i) => `\\u0000${i}\\u0000`);\n const built = message(strings as unknown as TemplateStringsArray, ...tokens);\n const translated = context ? translator.context(context as \"\").message(built) : translator.message(built);\n\n // biome-ignore lint/suspicious/noControlCharactersInRegex: using null separators\n const parts = translated.split(/\\u0000(\\d+)\\u0000/);\n const result: ReactNode[] = [];\n for (let i = 0; i < parts.length; i += 2) {\n result.push(parts[i]);\n const idx = parts[i + 1];\n if (idx !== undefined) {\n result.push(values[Number(idx)]);\n }\n }\n\n return createElement(Fragment, null, ...result);\n}\n","import { message, plural } from \"@let-value/translate\";\nimport { createElement, Fragment, type ReactNode } from \"react\";\n\nimport { useTranslations } from \"../hooks/useTranslations.ts\";\nimport { buildTemplateFromChildren } from \"../utils.ts\";\n\nexport interface PluralProps {\n number: number;\n forms: readonly ReactNode[];\n context?: string;\n}\n\nexport function Plural({ number, forms, context }: PluralProps) {\n const translator = useTranslations();\n\n const built = forms.map((child, i) => {\n const { strings, values } = buildTemplateFromChildren(child);\n const tokens = values.map((_, j) => `\\u0000${i}-${j}\\u0000`);\n return { message: message(strings as unknown as TemplateStringsArray, ...tokens), values };\n });\n\n const messages = built.map((b) => b.message);\n const input = plural(...messages, number);\n\n const translated = context ? translator.context(context as \"\").plural(input) : translator.plural(input);\n\n // biome-ignore lint/suspicious/noControlCharactersInRegex: using null separators\n const parts = translated.split(/\\u0000(\\d+)-(\\d+)\\u0000/);\n const result: ReactNode[] = [];\n for (let i = 0; i < parts.length; ) {\n result.push(parts[i]);\n if (i + 2 < parts.length) {\n const formIndex = Number(parts[i + 1]);\n const valueIndex = Number(parts[i + 2]);\n result.push(built[formIndex].values[valueIndex]);\n }\n i += 3;\n }\n\n return createElement(Fragment, null, ...result);\n}\n","import type { Locale } from \"@let-value/translate\";\nimport { Translator } from \"@let-value/translate\";\nimport type { GetTextTranslations } from \"gettext-parser\";\nimport { createElement, type ReactNode, Suspense, use, useMemo } from \"react\";\nimport { translatorContext } from \"../context.ts\";\n\ntype TranslationLoader = () => Promise<GetTextTranslations>;\ntype TranslationEntry = GetTextTranslations | TranslationLoader;\n\nexport interface TranslationsProviderProps {\n translations?: Partial<Record<Locale, TranslationEntry>>;\n children?: ReactNode;\n}\n\nexport function TranslationsProvider({ translations = {}, children }: TranslationsProviderProps) {\n const parent = use(translatorContext);\n\n const translator = useMemo(() => {\n // Create a nested Translator that inherits from parent and merges entries\n return new Translator(translations, parent);\n }, [parent, translations]);\n\n return createElement(translatorContext.Provider, { value: translator }, createElement(Suspense, null, children));\n}\n","import type { Locale } from \"@let-value/translate\";\nimport { use } from \"react\";\nimport { localeContext } from \"../context.ts\";\n\nexport function useLocale(): Locale | undefined {\n return use(localeContext);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["result: ReactNode[]","strings: string[]","values: ReactNode[]","result: ReactNode[]","result: ReactNode[]"],"sources":["../src/context.ts","../src/components/LocaleProvider.ts","../src/hooks/useTranslations.ts","../src/utils.ts","../src/components/Message.ts","../src/components/Plural.ts","../src/components/TranslationsProvider.ts","../src/hooks/useLocale.ts"],"sourcesContent":["import type { Locale, Translator } from \"@let-value/translate\";\nimport { createContext } from \"react\";\n\nexport const localeContext = createContext<Locale | undefined>(undefined);\nexport const translatorContext = createContext<Translator | undefined>(undefined);\n","import type { Locale } from \"@let-value/translate\";\nimport { createElement, type ReactNode } from \"react\";\nimport { localeContext } from \"../context.ts\";\n\nexport interface LocaleProviderProps {\n locale: Locale;\n children?: ReactNode;\n}\n\nexport function LocaleProvider({ locale, children }: LocaleProviderProps) {\n return createElement(localeContext.Provider, { value: locale }, children);\n}\n","import type { Locale, LocaleTranslator } from \"@let-value/translate\";\nimport { use } from \"react\";\n\nimport { localeContext, translatorContext } from \"../context.ts\";\n\n/** @deprecated replace with `use` from react */\n// biome-ignore lint/suspicious/noExplicitAny: we need to decorate the promise\nfunction getPromiseState(promise: any) {\n switch (promise.status) {\n case \"pending\":\n return { status: \"pending\" };\n case \"fulfilled\":\n return { status: \"fulfilled\", value: promise.value };\n case \"rejected\":\n return { status: \"rejected\", reason: promise.reason };\n default: {\n promise.status = \"pending\";\n promise.then((value: unknown) => {\n promise.status = \"fulfilled\";\n promise.value = value;\n });\n promise.catch((reason: unknown) => {\n promise.status = \"rejected\";\n promise.reason = reason;\n });\n return getPromiseState(promise);\n }\n }\n}\n\nexport function useTranslations(locale?: Locale): LocaleTranslator {\n const requestedLocale = locale ?? use(localeContext) ?? (\"unknown\" as never);\n const translator = use(translatorContext);\n if (!translator) {\n throw new Error(\"TranslationsProvider is missing\");\n }\n\n const resource = translator.fetchLocale(requestedLocale);\n if (!(resource instanceof Promise)) {\n return resource;\n }\n\n const state = getPromiseState(resource);\n if (state.status === \"pending\") {\n throw resource;\n }\n if (state.status === \"rejected\") {\n throw state.reason;\n }\n if (state.status === \"fulfilled\") {\n return state.value;\n }\n\n return use(resource);\n}\n","import { Children, Fragment, isValidElement, type PropsWithChildren, type ReactNode } from \"react\";\n\nexport function buildTemplateFromChildren(children: ReactNode): {\n strings: string[];\n values: ReactNode[];\n} {\n function flatten(nodes: ReactNode): ReactNode[] {\n const result: ReactNode[] = [];\n Children.forEach(nodes, (child) => {\n if (isValidElement(child) && child.type === Fragment) {\n result.push(...flatten((child.props as PropsWithChildren).children));\n } else {\n result.push(child);\n }\n });\n return result;\n }\n\n const array = flatten(children);\n const strings: string[] = [\"\"];\n const values: ReactNode[] = [];\n let expectValue = false;\n\n array.forEach((child) => {\n if (typeof child === \"string\") {\n if (expectValue) {\n values.push(child);\n strings.push(\"\");\n expectValue = false;\n } else {\n strings[strings.length - 1] += child;\n expectValue = true;\n }\n } else if (typeof child === \"number\" || child != null) {\n values.push(child as ReactNode);\n strings.push(\"\");\n expectValue = false;\n }\n });\n\n return { strings, values };\n}\n","import { message } from \"@let-value/translate\";\nimport { createElement, Fragment, type ReactNode } from \"react\";\n\nimport { useTranslations } from \"../hooks/useTranslations.ts\";\nimport { buildTemplateFromChildren } from \"../utils.ts\";\n\nexport interface MessageProps {\n context?: string;\n children: ReactNode;\n}\n\nexport function Message({ context, children }: MessageProps) {\n const translator = useTranslations();\n const { strings, values } = buildTemplateFromChildren(children);\n\n if (values.length === 0) {\n const input = strings.join(\"\");\n if (context) {\n return translator.context(context as \"\").message(input as never);\n }\n return translator.message(input as never);\n }\n\n const tokens = values.map((_, i) => `\\u0000${i}\\u0000`);\n const built = message(strings as unknown as TemplateStringsArray, ...tokens);\n const translated = context ? translator.context(context as \"\").message(built) : translator.message(built);\n\n // biome-ignore lint/suspicious/noControlCharactersInRegex: using null separators\n const parts = translated.split(/\\u0000(\\d+)\\u0000/);\n const result: ReactNode[] = [];\n for (let i = 0; i < parts.length; i += 2) {\n result.push(parts[i]);\n const idx = parts[i + 1];\n if (idx !== undefined) {\n result.push(values[Number(idx)]);\n }\n }\n\n return createElement(Fragment, null, ...result);\n}\n","import { message, plural } from \"@let-value/translate\";\nimport { createElement, Fragment, type ReactNode } from \"react\";\n\nimport { useTranslations } from \"../hooks/useTranslations.ts\";\nimport { buildTemplateFromChildren } from \"../utils.ts\";\n\nexport interface PluralProps {\n number: number;\n forms: readonly ReactNode[];\n context?: string;\n}\n\nexport function Plural({ number, forms, context }: PluralProps) {\n const translator = useTranslations();\n\n const built = forms.map((child, i) => {\n const { strings, values } = buildTemplateFromChildren(child);\n const tokens = values.map((_, j) => `\\u0000${i}-${j}\\u0000`);\n return { message: message(strings as unknown as TemplateStringsArray, ...tokens), values };\n });\n\n const messages = built.map((b) => b.message);\n const input = plural(...messages, number);\n\n const translated = context ? translator.context(context as \"\").plural(input) : translator.plural(input);\n\n // biome-ignore lint/suspicious/noControlCharactersInRegex: using null separators\n const parts = translated.split(/\\u0000(\\d+)-(\\d+)\\u0000/);\n const result: ReactNode[] = [];\n for (let i = 0; i < parts.length; ) {\n result.push(parts[i]);\n if (i + 2 < parts.length) {\n const formIndex = Number(parts[i + 1]);\n const valueIndex = Number(parts[i + 2]);\n result.push(built[formIndex].values[valueIndex]);\n }\n i += 3;\n }\n\n return createElement(Fragment, null, ...result);\n}\n","import type { Locale } from \"@let-value/translate\";\nimport { Translator } from \"@let-value/translate\";\nimport type { GetTextTranslations } from \"gettext-parser\";\nimport { createElement, type ReactNode, Suspense, use, useMemo } from \"react\";\nimport { translatorContext } from \"../context.ts\";\n\ntype TranslationLoader = () => Promise<GetTextTranslations>;\ntype TranslationEntry = GetTextTranslations | TranslationLoader;\n\nexport interface TranslationsProviderProps {\n translations?: Partial<Record<Locale, TranslationEntry>>;\n children?: ReactNode;\n}\n\nexport function TranslationsProvider({ translations = {}, children }: TranslationsProviderProps) {\n const parent = use(translatorContext);\n\n const translator = useMemo(() => {\n // Create a nested Translator that inherits from parent and merges entries\n return new Translator(translations, parent);\n }, [parent, translations]);\n\n return createElement(translatorContext.Provider, { value: translator }, createElement(Suspense, null, children));\n}\n","import type { Locale } from \"@let-value/translate\";\nimport { use } from \"react\";\nimport { localeContext } from \"../context.ts\";\n\nexport function useLocale(): Locale | undefined {\n return use(localeContext);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@let-value/translate-react",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -24,17 +24,17 @@
24
24
  "test": "node --test"
25
25
  },
26
26
  "dependencies": {
27
- "@let-value/translate": "1.0.11",
27
+ "@let-value/translate": "1.0.13",
28
28
  "radash": "^12.1.1"
29
29
  },
30
30
  "devDependencies": {
31
- "@let-value/translate-e2e": "1.0.11",
31
+ "@let-value/translate-e2e": "1.0.13",
32
32
  "@types/gettext-parser": "8.0.0",
33
- "@types/react": "19.1.12",
33
+ "@types/react": "19.1.13",
34
34
  "@types/react-dom": "19.1.9",
35
35
  "react": "19.1.1",
36
36
  "react-dom": "19.1.1",
37
- "tsdown": "0.14.2",
37
+ "tsdown": "0.15.2",
38
38
  "typescript": "5.9.2"
39
39
  },
40
40
  "peerDependencies": {