@vocab/react 1.1.13 → 1.1.14-fix-messageformat-import-20250923014407

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,73 @@
1
+ import React, { ReactNode } from "react";
2
+ import { LanguageName, ParsedFormatFn, ParsedFormatFnByKey, TranslationFile } from "@vocab/core";
3
+
4
+ //#region src/components.d.ts
5
+ type Locale = string;
6
+ interface TranslationsContextValue {
7
+ /**
8
+ * The `language` passed in to your `VocabProvider`
9
+ */
10
+ language: LanguageName;
11
+ /**
12
+ * The `locale` passed in to your `VocabProvider`
13
+ *
14
+ * Please note that this value will be `undefined` if you have not passed a `locale` to your `VocabProvider`.
15
+ * If your languages are named with IETF language tags, you should just use `language` instead of
16
+ * this value, unless you specifically need to access your `locale` override.
17
+ */
18
+ locale?: Locale;
19
+ }
20
+ interface VocabProviderProps {
21
+ /**
22
+ * The language to load translations for. Must be one of the language names defined in your `vocab.config.js`.
23
+ */
24
+ language: TranslationsContextValue['language'];
25
+ /**
26
+ * A locale override. By default, Vocab will use the `language` as the locale when formatting messages if
27
+ * `locale` is not set. If your languages are named with IETF language tags, you probably don't need to
28
+ * set this value.
29
+ *
30
+ * You may want to override the locale for a specific language if the default formatting for that locale
31
+ * is not desired.
32
+ *
33
+ * @example
34
+ * // Override the locale for th-TH to use the Gregorian calendar instead of the default Buddhist calendar
35
+ * <VocabProvider language="th-TH" locale="th-TH-u-ca-gregory">
36
+ * </App>
37
+ * <VocabProvider />
38
+ */
39
+ locale?: TranslationsContextValue['locale'];
40
+ children: ReactNode;
41
+ }
42
+ /**
43
+ * Provides a translation context for your application
44
+ *
45
+ * @example
46
+ * import { VocabProvider } from '@vocab/react';
47
+ *
48
+ * <VocabProvider language="en">
49
+ * <App />
50
+ * <VocabProvider />
51
+ */
52
+ declare const VocabProvider: ({
53
+ children,
54
+ language,
55
+ locale
56
+ }: VocabProviderProps) => React.JSX.Element;
57
+ /**
58
+ * @returns The `language` and `locale` values passed in to your `VocabProvider`
59
+ */
60
+ declare const useLanguage: () => TranslationsContextValue;
61
+ type FormatXMLElementReactNodeFn = (parts: ReactNode[]) => ReactNode;
62
+ type MapToReactNodeFunction<Params extends Record<string, any>> = { [key in keyof Params]: Params[key] extends ParsedFormatFn ? FormatXMLElementReactNodeFn : Params[key] };
63
+ type TranslateFn<FormatFnByKey extends ParsedFormatFnByKey> = {
64
+ <TranslationKey extends keyof FormatFnByKey>(key: TranslationKey, params: MapToReactNodeFunction<Parameters<FormatFnByKey[TranslationKey]>[0]>): ReturnType<FormatFnByKey[TranslationKey]> extends string ? string : ReactNode | string | Array<ReactNode | string>;
65
+ <TranslationKey extends keyof FormatFnByKey>(key: Parameters<FormatFnByKey[TranslationKey]>[0] extends Record<string, any> ? never : TranslationKey): string;
66
+ };
67
+ declare function useTranslations<Language extends string, FormatFnByKey extends ParsedFormatFnByKey>(translations: TranslationFile<Language, FormatFnByKey>): {
68
+ ready: boolean;
69
+ t: TranslateFn<FormatFnByKey>;
70
+ };
71
+ //#endregion
72
+ export { VocabProvider, useLanguage, useTranslations };
73
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1,73 @@
1
+ import { LanguageName, ParsedFormatFn, ParsedFormatFnByKey, TranslationFile } from "@vocab/core";
2
+ import React, { ReactNode } from "react";
3
+
4
+ //#region src/components.d.ts
5
+ type Locale = string;
6
+ interface TranslationsContextValue {
7
+ /**
8
+ * The `language` passed in to your `VocabProvider`
9
+ */
10
+ language: LanguageName;
11
+ /**
12
+ * The `locale` passed in to your `VocabProvider`
13
+ *
14
+ * Please note that this value will be `undefined` if you have not passed a `locale` to your `VocabProvider`.
15
+ * If your languages are named with IETF language tags, you should just use `language` instead of
16
+ * this value, unless you specifically need to access your `locale` override.
17
+ */
18
+ locale?: Locale;
19
+ }
20
+ interface VocabProviderProps {
21
+ /**
22
+ * The language to load translations for. Must be one of the language names defined in your `vocab.config.js`.
23
+ */
24
+ language: TranslationsContextValue['language'];
25
+ /**
26
+ * A locale override. By default, Vocab will use the `language` as the locale when formatting messages if
27
+ * `locale` is not set. If your languages are named with IETF language tags, you probably don't need to
28
+ * set this value.
29
+ *
30
+ * You may want to override the locale for a specific language if the default formatting for that locale
31
+ * is not desired.
32
+ *
33
+ * @example
34
+ * // Override the locale for th-TH to use the Gregorian calendar instead of the default Buddhist calendar
35
+ * <VocabProvider language="th-TH" locale="th-TH-u-ca-gregory">
36
+ * </App>
37
+ * <VocabProvider />
38
+ */
39
+ locale?: TranslationsContextValue['locale'];
40
+ children: ReactNode;
41
+ }
42
+ /**
43
+ * Provides a translation context for your application
44
+ *
45
+ * @example
46
+ * import { VocabProvider } from '@vocab/react';
47
+ *
48
+ * <VocabProvider language="en">
49
+ * <App />
50
+ * <VocabProvider />
51
+ */
52
+ declare const VocabProvider: ({
53
+ children,
54
+ language,
55
+ locale
56
+ }: VocabProviderProps) => React.JSX.Element;
57
+ /**
58
+ * @returns The `language` and `locale` values passed in to your `VocabProvider`
59
+ */
60
+ declare const useLanguage: () => TranslationsContextValue;
61
+ type FormatXMLElementReactNodeFn = (parts: ReactNode[]) => ReactNode;
62
+ type MapToReactNodeFunction<Params extends Record<string, any>> = { [key in keyof Params]: Params[key] extends ParsedFormatFn ? FormatXMLElementReactNodeFn : Params[key] };
63
+ type TranslateFn<FormatFnByKey extends ParsedFormatFnByKey> = {
64
+ <TranslationKey extends keyof FormatFnByKey>(key: TranslationKey, params: MapToReactNodeFunction<Parameters<FormatFnByKey[TranslationKey]>[0]>): ReturnType<FormatFnByKey[TranslationKey]> extends string ? string : ReactNode | string | Array<ReactNode | string>;
65
+ <TranslationKey extends keyof FormatFnByKey>(key: Parameters<FormatFnByKey[TranslationKey]>[0] extends Record<string, any> ? never : TranslationKey): string;
66
+ };
67
+ declare function useTranslations<Language extends string, FormatFnByKey extends ParsedFormatFnByKey>(translations: TranslationFile<Language, FormatFnByKey>): {
68
+ ready: boolean;
69
+ t: TranslateFn<FormatFnByKey>;
70
+ };
71
+ //#endregion
72
+ export { VocabProvider, useLanguage, useTranslations };
73
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,92 @@
1
+ //#region rolldown:runtime
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 __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+ let react = require("react");
25
+ react = __toESM(react);
26
+
27
+ //#region src/components.tsx
28
+ const TranslationsContext = react.default.createContext(void 0);
29
+ /**
30
+ * Provides a translation context for your application
31
+ *
32
+ * @example
33
+ * import { VocabProvider } from '@vocab/react';
34
+ *
35
+ * <VocabProvider language="en">
36
+ * <App />
37
+ * <VocabProvider />
38
+ */
39
+ const VocabProvider = ({ children, language, locale }) => {
40
+ const value = (0, react.useMemo)(() => ({
41
+ language,
42
+ locale
43
+ }), [language, locale]);
44
+ return /* @__PURE__ */ react.default.createElement(TranslationsContext.Provider, { value }, children);
45
+ };
46
+ /**
47
+ * @returns The `language` and `locale` values passed in to your `VocabProvider`
48
+ */
49
+ const useLanguage = () => {
50
+ const context = (0, react.useContext)(TranslationsContext);
51
+ if (!context) throw new Error("Attempted to access translation without Vocab context set. Did you forget to render VocabProvider?");
52
+ if (!context.language) throw new Error("Attempted to access translation without language set. Did you forget to pass language to VocabProvider?");
53
+ return context;
54
+ };
55
+ const SERVER_RENDERING = typeof window === "undefined";
56
+ function useTranslations(translations) {
57
+ const { language, locale } = useLanguage();
58
+ const [, forceRender] = (0, react.useReducer)((s) => s + 1, 0);
59
+ const translationsObject = translations.getLoadedMessages(language, locale || language);
60
+ let ready = true;
61
+ if (!translationsObject) {
62
+ if (SERVER_RENDERING) throw new Error(`Translations not synchronously available on server render. Applying translations dynamically server-side is not supported.`);
63
+ translations.load(language).then(() => {
64
+ forceRender();
65
+ });
66
+ ready = false;
67
+ }
68
+ const t = (0, react.useCallback)((key, params) => {
69
+ if (!translationsObject) return " ";
70
+ const message = translationsObject?.[key];
71
+ if (!message) {
72
+ console.error(`Unable to find translation for key "${key}". Possible keys are ${Object.keys(translationsObject).map((v) => `"${v}"`).join(", ")}`);
73
+ return "";
74
+ }
75
+ const result = message.format(params);
76
+ if (Array.isArray(result)) for (let i = 0; i < result.length; i++) {
77
+ const item = result[i];
78
+ if (typeof item === "object" && item && !item.key && (0, react.isValidElement)(item)) result[i] = (0, react.cloneElement)(item, { key: `_vocab-${i}` });
79
+ }
80
+ return result;
81
+ }, [translationsObject]);
82
+ return {
83
+ ready,
84
+ t
85
+ };
86
+ }
87
+
88
+ //#endregion
89
+ exports.VocabProvider = VocabProvider;
90
+ exports.useLanguage = useLanguage;
91
+ exports.useTranslations = useTranslations;
92
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["React"],"sources":["../src/components.tsx"],"sourcesContent":["import type {\n TranslationFile,\n LanguageName,\n ParsedFormatFnByKey,\n ParsedFormatFn,\n} from '@vocab/core';\n\nimport React, {\n type ReactNode,\n useContext,\n useMemo,\n useReducer,\n isValidElement,\n cloneElement,\n useCallback,\n} from 'react';\n\ntype Locale = string;\n\ninterface TranslationsContextValue {\n /**\n * The `language` passed in to your `VocabProvider`\n */\n language: LanguageName;\n /**\n * The `locale` passed in to your `VocabProvider`\n *\n * Please note that this value will be `undefined` if you have not passed a `locale` to your `VocabProvider`.\n * If your languages are named with IETF language tags, you should just use `language` instead of\n * this value, unless you specifically need to access your `locale` override.\n */\n locale?: Locale;\n}\n\nconst TranslationsContext = React.createContext<\n TranslationsContextValue | undefined\n>(undefined);\n\n// Not extending TranslationsContextValue so we can tailor the docs for each prop to be better\n// suited to the provider, rather than for the useLanguage hook\ninterface VocabProviderProps {\n /**\n * The language to load translations for. Must be one of the language names defined in your `vocab.config.js`.\n */\n language: TranslationsContextValue['language'];\n /**\n * A locale override. By default, Vocab will use the `language` as the locale when formatting messages if\n * `locale` is not set. If your languages are named with IETF language tags, you probably don't need to\n * set this value.\n *\n * You may want to override the locale for a specific language if the default formatting for that locale\n * is not desired.\n *\n * @example\n * // Override the locale for th-TH to use the Gregorian calendar instead of the default Buddhist calendar\n * <VocabProvider language=\"th-TH\" locale=\"th-TH-u-ca-gregory\">\n * </App>\n * <VocabProvider />\n */\n locale?: TranslationsContextValue['locale'];\n children: ReactNode;\n}\n\n/**\n * Provides a translation context for your application\n *\n * @example\n * import { VocabProvider } from '@vocab/react';\n *\n * <VocabProvider language=\"en\">\n * <App />\n * <VocabProvider />\n */\nexport const VocabProvider = ({\n children,\n language,\n locale,\n}: VocabProviderProps) => {\n const value = useMemo(() => ({ language, locale }), [language, locale]);\n\n return (\n <TranslationsContext.Provider value={value}>\n {children}\n </TranslationsContext.Provider>\n );\n};\n\n/**\n * @returns The `language` and `locale` values passed in to your `VocabProvider`\n */\nexport const useLanguage = (): TranslationsContextValue => {\n const context = useContext(TranslationsContext);\n if (!context) {\n throw new Error(\n 'Attempted to access translation without Vocab context set. Did you forget to render VocabProvider?',\n );\n }\n if (!context.language) {\n throw new Error(\n 'Attempted to access translation without language set. Did you forget to pass language to VocabProvider?',\n );\n }\n\n return context;\n};\n\nconst SERVER_RENDERING = typeof window === 'undefined';\n\ntype FormatXMLElementReactNodeFn = (parts: ReactNode[]) => ReactNode;\n\ntype MapToReactNodeFunction<Params extends Record<string, any>> = {\n [key in keyof Params]: Params[key] extends ParsedFormatFn\n ? FormatXMLElementReactNodeFn\n : Params[key];\n};\n\ntype TranslateFn<FormatFnByKey extends ParsedFormatFnByKey> = {\n <TranslationKey extends keyof FormatFnByKey>(\n key: TranslationKey,\n params: MapToReactNodeFunction<\n Parameters<FormatFnByKey[TranslationKey]>[0]\n >,\n ): ReturnType<FormatFnByKey[TranslationKey]> extends string\n ? string\n : ReactNode | string | Array<ReactNode | string>;\n <TranslationKey extends keyof FormatFnByKey>(\n key: Parameters<FormatFnByKey[TranslationKey]>[0] extends Record<\n string,\n any\n >\n ? never\n : TranslationKey,\n ): string;\n};\n\nexport function useTranslations<\n Language extends string,\n FormatFnByKey extends ParsedFormatFnByKey,\n>(\n translations: TranslationFile<Language, FormatFnByKey>,\n): {\n ready: boolean;\n t: TranslateFn<FormatFnByKey>;\n} {\n const { language, locale } = useLanguage();\n const [, forceRender] = useReducer((s: number) => s + 1, 0);\n\n const translationsObject = translations.getLoadedMessages(\n language as any,\n locale || language,\n );\n\n let ready = true;\n\n if (!translationsObject) {\n if (SERVER_RENDERING) {\n throw new Error(\n `Translations not synchronously available on server render. Applying translations dynamically server-side is not supported.`,\n );\n }\n\n translations.load(language as any).then(() => {\n forceRender();\n });\n ready = false;\n }\n\n const t = useCallback(\n (key: string, params?: any) => {\n if (!translationsObject) {\n return ' ';\n }\n\n const message = translationsObject?.[key];\n\n if (!message) {\n // eslint-disable-next-line no-console\n console.error(\n `Unable to find translation for key \"${key}\". Possible keys are ${Object.keys(\n translationsObject,\n )\n .map((v) => `\"${v}\"`)\n .join(', ')}`,\n );\n return '';\n }\n\n const result = message.format(params);\n\n if (Array.isArray(result)) {\n for (let i = 0; i < result.length; i++) {\n const item = result[i];\n if (\n typeof item === 'object' &&\n item &&\n !item.key &&\n isValidElement(item)\n ) {\n result[i] = cloneElement(item, { key: `_vocab-${i}` });\n }\n }\n }\n\n return result;\n },\n [translationsObject],\n );\n\n return {\n ready,\n t,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,MAAM,sBAAsBA,cAAM,cAEhC,OAAU;;;;;;;;;;;AAqCZ,MAAa,iBAAiB,EAC5B,UACA,UACA,aACwB;CACxB,MAAM,kCAAuB;EAAE;EAAU;EAAQ,GAAG,CAAC,UAAU,OAAO,CAAC;AAEvE,QACE,4CAAC,oBAAoB,YAAgB,SAClC,SAC4B;;;;;AAOnC,MAAa,oBAA8C;CACzD,MAAM,gCAAqB,oBAAoB;AAC/C,KAAI,CAAC,QACH,OAAM,IAAI,MACR,qGACD;AAEH,KAAI,CAAC,QAAQ,SACX,OAAM,IAAI,MACR,0GACD;AAGH,QAAO;;AAGT,MAAM,mBAAmB,OAAO,WAAW;AA6B3C,SAAgB,gBAId,cAIA;CACA,MAAM,EAAE,UAAU,WAAW,aAAa;CAC1C,MAAM,GAAG,sCAA2B,MAAc,IAAI,GAAG,EAAE;CAE3D,MAAM,qBAAqB,aAAa,kBACtC,UACA,UAAU,SACX;CAED,IAAI,QAAQ;AAEZ,KAAI,CAAC,oBAAoB;AACvB,MAAI,iBACF,OAAM,IAAI,MACR,6HACD;AAGH,eAAa,KAAK,SAAgB,CAAC,WAAW;AAC5C,gBAAa;IACb;AACF,UAAQ;;CAGV,MAAM,4BACH,KAAa,WAAiB;AAC7B,MAAI,CAAC,mBACH,QAAO;EAGT,MAAM,UAAU,qBAAqB;AAErC,MAAI,CAAC,SAAS;AAEZ,WAAQ,MACN,uCAAuC,IAAI,uBAAuB,OAAO,KACvE,mBACD,CACE,KAAK,MAAM,IAAI,EAAE,GAAG,CACpB,KAAK,KAAK,GACd;AACD,UAAO;;EAGT,MAAM,SAAS,QAAQ,OAAO,OAAO;AAErC,MAAI,MAAM,QAAQ,OAAO,CACvB,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;GACtC,MAAM,OAAO,OAAO;AACpB,OACE,OAAO,SAAS,YAChB,QACA,CAAC,KAAK,iCACS,KAAK,CAEpB,QAAO,6BAAkB,MAAM,EAAE,KAAK,UAAU,KAAK,CAAC;;AAK5D,SAAO;IAET,CAAC,mBAAmB,CACrB;AAED,QAAO;EACL;EACA;EACD"}
package/dist/index.mjs ADDED
@@ -0,0 +1,66 @@
1
+ import React, { cloneElement, isValidElement, useCallback, useContext, useMemo, useReducer } from "react";
2
+
3
+ //#region src/components.tsx
4
+ const TranslationsContext = React.createContext(void 0);
5
+ /**
6
+ * Provides a translation context for your application
7
+ *
8
+ * @example
9
+ * import { VocabProvider } from '@vocab/react';
10
+ *
11
+ * <VocabProvider language="en">
12
+ * <App />
13
+ * <VocabProvider />
14
+ */
15
+ const VocabProvider = ({ children, language, locale }) => {
16
+ const value = useMemo(() => ({
17
+ language,
18
+ locale
19
+ }), [language, locale]);
20
+ return /* @__PURE__ */ React.createElement(TranslationsContext.Provider, { value }, children);
21
+ };
22
+ /**
23
+ * @returns The `language` and `locale` values passed in to your `VocabProvider`
24
+ */
25
+ const useLanguage = () => {
26
+ const context = useContext(TranslationsContext);
27
+ if (!context) throw new Error("Attempted to access translation without Vocab context set. Did you forget to render VocabProvider?");
28
+ if (!context.language) throw new Error("Attempted to access translation without language set. Did you forget to pass language to VocabProvider?");
29
+ return context;
30
+ };
31
+ const SERVER_RENDERING = typeof window === "undefined";
32
+ function useTranslations(translations) {
33
+ const { language, locale } = useLanguage();
34
+ const [, forceRender] = useReducer((s) => s + 1, 0);
35
+ const translationsObject = translations.getLoadedMessages(language, locale || language);
36
+ let ready = true;
37
+ if (!translationsObject) {
38
+ if (SERVER_RENDERING) throw new Error(`Translations not synchronously available on server render. Applying translations dynamically server-side is not supported.`);
39
+ translations.load(language).then(() => {
40
+ forceRender();
41
+ });
42
+ ready = false;
43
+ }
44
+ const t = useCallback((key, params) => {
45
+ if (!translationsObject) return " ";
46
+ const message = translationsObject?.[key];
47
+ if (!message) {
48
+ console.error(`Unable to find translation for key "${key}". Possible keys are ${Object.keys(translationsObject).map((v) => `"${v}"`).join(", ")}`);
49
+ return "";
50
+ }
51
+ const result = message.format(params);
52
+ if (Array.isArray(result)) for (let i = 0; i < result.length; i++) {
53
+ const item = result[i];
54
+ if (typeof item === "object" && item && !item.key && isValidElement(item)) result[i] = cloneElement(item, { key: `_vocab-${i}` });
55
+ }
56
+ return result;
57
+ }, [translationsObject]);
58
+ return {
59
+ ready,
60
+ t
61
+ };
62
+ }
63
+
64
+ //#endregion
65
+ export { VocabProvider, useLanguage, useTranslations };
66
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/components.tsx"],"sourcesContent":["import type {\n TranslationFile,\n LanguageName,\n ParsedFormatFnByKey,\n ParsedFormatFn,\n} from '@vocab/core';\n\nimport React, {\n type ReactNode,\n useContext,\n useMemo,\n useReducer,\n isValidElement,\n cloneElement,\n useCallback,\n} from 'react';\n\ntype Locale = string;\n\ninterface TranslationsContextValue {\n /**\n * The `language` passed in to your `VocabProvider`\n */\n language: LanguageName;\n /**\n * The `locale` passed in to your `VocabProvider`\n *\n * Please note that this value will be `undefined` if you have not passed a `locale` to your `VocabProvider`.\n * If your languages are named with IETF language tags, you should just use `language` instead of\n * this value, unless you specifically need to access your `locale` override.\n */\n locale?: Locale;\n}\n\nconst TranslationsContext = React.createContext<\n TranslationsContextValue | undefined\n>(undefined);\n\n// Not extending TranslationsContextValue so we can tailor the docs for each prop to be better\n// suited to the provider, rather than for the useLanguage hook\ninterface VocabProviderProps {\n /**\n * The language to load translations for. Must be one of the language names defined in your `vocab.config.js`.\n */\n language: TranslationsContextValue['language'];\n /**\n * A locale override. By default, Vocab will use the `language` as the locale when formatting messages if\n * `locale` is not set. If your languages are named with IETF language tags, you probably don't need to\n * set this value.\n *\n * You may want to override the locale for a specific language if the default formatting for that locale\n * is not desired.\n *\n * @example\n * // Override the locale for th-TH to use the Gregorian calendar instead of the default Buddhist calendar\n * <VocabProvider language=\"th-TH\" locale=\"th-TH-u-ca-gregory\">\n * </App>\n * <VocabProvider />\n */\n locale?: TranslationsContextValue['locale'];\n children: ReactNode;\n}\n\n/**\n * Provides a translation context for your application\n *\n * @example\n * import { VocabProvider } from '@vocab/react';\n *\n * <VocabProvider language=\"en\">\n * <App />\n * <VocabProvider />\n */\nexport const VocabProvider = ({\n children,\n language,\n locale,\n}: VocabProviderProps) => {\n const value = useMemo(() => ({ language, locale }), [language, locale]);\n\n return (\n <TranslationsContext.Provider value={value}>\n {children}\n </TranslationsContext.Provider>\n );\n};\n\n/**\n * @returns The `language` and `locale` values passed in to your `VocabProvider`\n */\nexport const useLanguage = (): TranslationsContextValue => {\n const context = useContext(TranslationsContext);\n if (!context) {\n throw new Error(\n 'Attempted to access translation without Vocab context set. Did you forget to render VocabProvider?',\n );\n }\n if (!context.language) {\n throw new Error(\n 'Attempted to access translation without language set. Did you forget to pass language to VocabProvider?',\n );\n }\n\n return context;\n};\n\nconst SERVER_RENDERING = typeof window === 'undefined';\n\ntype FormatXMLElementReactNodeFn = (parts: ReactNode[]) => ReactNode;\n\ntype MapToReactNodeFunction<Params extends Record<string, any>> = {\n [key in keyof Params]: Params[key] extends ParsedFormatFn\n ? FormatXMLElementReactNodeFn\n : Params[key];\n};\n\ntype TranslateFn<FormatFnByKey extends ParsedFormatFnByKey> = {\n <TranslationKey extends keyof FormatFnByKey>(\n key: TranslationKey,\n params: MapToReactNodeFunction<\n Parameters<FormatFnByKey[TranslationKey]>[0]\n >,\n ): ReturnType<FormatFnByKey[TranslationKey]> extends string\n ? string\n : ReactNode | string | Array<ReactNode | string>;\n <TranslationKey extends keyof FormatFnByKey>(\n key: Parameters<FormatFnByKey[TranslationKey]>[0] extends Record<\n string,\n any\n >\n ? never\n : TranslationKey,\n ): string;\n};\n\nexport function useTranslations<\n Language extends string,\n FormatFnByKey extends ParsedFormatFnByKey,\n>(\n translations: TranslationFile<Language, FormatFnByKey>,\n): {\n ready: boolean;\n t: TranslateFn<FormatFnByKey>;\n} {\n const { language, locale } = useLanguage();\n const [, forceRender] = useReducer((s: number) => s + 1, 0);\n\n const translationsObject = translations.getLoadedMessages(\n language as any,\n locale || language,\n );\n\n let ready = true;\n\n if (!translationsObject) {\n if (SERVER_RENDERING) {\n throw new Error(\n `Translations not synchronously available on server render. Applying translations dynamically server-side is not supported.`,\n );\n }\n\n translations.load(language as any).then(() => {\n forceRender();\n });\n ready = false;\n }\n\n const t = useCallback(\n (key: string, params?: any) => {\n if (!translationsObject) {\n return ' ';\n }\n\n const message = translationsObject?.[key];\n\n if (!message) {\n // eslint-disable-next-line no-console\n console.error(\n `Unable to find translation for key \"${key}\". Possible keys are ${Object.keys(\n translationsObject,\n )\n .map((v) => `\"${v}\"`)\n .join(', ')}`,\n );\n return '';\n }\n\n const result = message.format(params);\n\n if (Array.isArray(result)) {\n for (let i = 0; i < result.length; i++) {\n const item = result[i];\n if (\n typeof item === 'object' &&\n item &&\n !item.key &&\n isValidElement(item)\n ) {\n result[i] = cloneElement(item, { key: `_vocab-${i}` });\n }\n }\n }\n\n return result;\n },\n [translationsObject],\n );\n\n return {\n ready,\n t,\n };\n}\n"],"mappings":";;;AAkCA,MAAM,sBAAsB,MAAM,cAEhC,OAAU;;;;;;;;;;;AAqCZ,MAAa,iBAAiB,EAC5B,UACA,UACA,aACwB;CACxB,MAAM,QAAQ,eAAe;EAAE;EAAU;EAAQ,GAAG,CAAC,UAAU,OAAO,CAAC;AAEvE,QACE,oCAAC,oBAAoB,YAAgB,SAClC,SAC4B;;;;;AAOnC,MAAa,oBAA8C;CACzD,MAAM,UAAU,WAAW,oBAAoB;AAC/C,KAAI,CAAC,QACH,OAAM,IAAI,MACR,qGACD;AAEH,KAAI,CAAC,QAAQ,SACX,OAAM,IAAI,MACR,0GACD;AAGH,QAAO;;AAGT,MAAM,mBAAmB,OAAO,WAAW;AA6B3C,SAAgB,gBAId,cAIA;CACA,MAAM,EAAE,UAAU,WAAW,aAAa;CAC1C,MAAM,GAAG,eAAe,YAAY,MAAc,IAAI,GAAG,EAAE;CAE3D,MAAM,qBAAqB,aAAa,kBACtC,UACA,UAAU,SACX;CAED,IAAI,QAAQ;AAEZ,KAAI,CAAC,oBAAoB;AACvB,MAAI,iBACF,OAAM,IAAI,MACR,6HACD;AAGH,eAAa,KAAK,SAAgB,CAAC,WAAW;AAC5C,gBAAa;IACb;AACF,UAAQ;;CAGV,MAAM,IAAI,aACP,KAAa,WAAiB;AAC7B,MAAI,CAAC,mBACH,QAAO;EAGT,MAAM,UAAU,qBAAqB;AAErC,MAAI,CAAC,SAAS;AAEZ,WAAQ,MACN,uCAAuC,IAAI,uBAAuB,OAAO,KACvE,mBACD,CACE,KAAK,MAAM,IAAI,EAAE,GAAG,CACpB,KAAK,KAAK,GACd;AACD,UAAO;;EAGT,MAAM,SAAS,QAAQ,OAAO,OAAO;AAErC,MAAI,MAAM,QAAQ,OAAO,CACvB,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;GACtC,MAAM,OAAO,OAAO;AACpB,OACE,OAAO,SAAS,YAChB,QACA,CAAC,KAAK,OACN,eAAe,KAAK,CAEpB,QAAO,KAAK,aAAa,MAAM,EAAE,KAAK,UAAU,KAAK,CAAC;;AAK5D,SAAO;IAET,CAAC,mBAAmB,CACrB;AAED,QAAO;EACL;EACA;EACD"}
package/package.json CHANGED
@@ -1,13 +1,21 @@
1
1
  {
2
2
  "name": "@vocab/react",
3
- "version": "1.1.13",
3
+ "version": "1.1.14-fix-messageformat-import-20250923014407",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/seek-oss/vocab.git",
7
7
  "directory": "packages/react"
8
8
  },
9
- "main": "dist/vocab-react.cjs.js",
10
- "module": "dist/vocab-react.esm.js",
9
+ "main": "./dist/index.js",
10
+ "module": "./dist/index.mjs",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "import": "./dist/index.mjs",
15
+ "require": "./dist/index.js"
16
+ },
17
+ "./package.json": "./package.json"
18
+ },
11
19
  "author": "SEEK",
12
20
  "license": "MIT",
13
21
  "peerDependencies": {
@@ -18,10 +26,10 @@
18
26
  ],
19
27
  "dependencies": {
20
28
  "intl-messageformat": "^10.0.0",
21
- "@vocab/core": "^1.6.4"
29
+ "@vocab/core": "^1.6.5-fix-messageformat-import-20250923014407"
22
30
  },
23
31
  "devDependencies": {
24
- "@types/react": "^18.0.9",
25
- "react": "^18.1.0"
32
+ "@types/react": "^19.1.8",
33
+ "react": "^19.1.0"
26
34
  }
27
35
  }