@ttoss/react-i18n 1.25.5 → 1.25.7

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/esm/index.js CHANGED
@@ -10,6 +10,7 @@ import { Fragment, jsx } from "react/jsx-runtime";
10
10
  var DEFAULT_LOCALE = "en";
11
11
  var I18nConfigContext = /*#__PURE__*/React.createContext({
12
12
  defaultLocale: DEFAULT_LOCALE,
13
+ messages: {},
13
14
  setLocale: () => {
14
15
  return null;
15
16
  }
@@ -21,25 +22,31 @@ var I18nProvider = ({
21
22
  ...intlConfig
22
23
  }) => {
23
24
  const [locale, setLocale] = React.useState(initialLocale || DEFAULT_LOCALE);
24
- const [messages, setMessages] = React.useState();
25
+ const [messagesAndLocale, setMessagesAndLocale] = React.useState({
26
+ locale: DEFAULT_LOCALE
27
+ });
25
28
  React.useEffect(() => {
26
- if (loadLocaleData) {
27
- loadLocaleData(locale).then(message => {
28
- return setMessages(message);
29
+ if (loadLocaleData && locale) {
30
+ Promise.resolve(loadLocaleData(locale)).then(messages => {
31
+ setMessagesAndLocale({
32
+ messages,
33
+ locale
34
+ });
29
35
  });
30
36
  }
31
37
  }, [loadLocaleData, locale]);
32
38
  return /* @__PURE__ */jsx(I18nConfigContext.Provider, {
33
39
  value: {
34
- defaultLocale: DEFAULT_LOCALE,
35
40
  locale,
41
+ defaultLocale: DEFAULT_LOCALE,
42
+ messages: messagesAndLocale.messages,
36
43
  setLocale,
37
44
  ...intlConfig
38
45
  },
39
46
  children: /* @__PURE__ */jsx(IntlProvider, {
40
47
  defaultLocale: DEFAULT_LOCALE,
41
- locale,
42
- messages,
48
+ locale: messagesAndLocale.locale,
49
+ messages: messagesAndLocale.messages,
43
50
  ...intlConfig,
44
51
  children: /* @__PURE__ */jsx(Fragment, {
45
52
  children
package/dist/index.d.mts CHANGED
@@ -1,10 +1,11 @@
1
1
  import * as react_intl from 'react-intl';
2
+ import { MessageFormatElement } from 'react-intl';
2
3
  export { FormattedMessage, IntlShape, MessageDescriptor, defineMessage, defineMessages } from 'react-intl';
3
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
5
  import * as React from 'react';
5
6
 
6
- type MessagesType = any;
7
- type LoadLocaleData = (locale: string) => Promise<MessagesType>;
7
+ type Messages = Record<string, string> | Record<string, MessageFormatElement[]>;
8
+ type LoadLocaleData = (locale: string) => Promise<Messages> | Messages;
8
9
  type I18nProviderProps = {
9
10
  locale?: string;
10
11
  loadLocaleData?: LoadLocaleData;
@@ -24,6 +25,7 @@ declare const useI18n: () => {
24
25
  children?: React.ReactNode;
25
26
  onError?: ((err: Error) => void) | undefined;
26
27
  defaultLocale: string;
28
+ messages?: Messages | undefined;
27
29
  setLocale: (language: string) => void;
28
30
  };
29
31
 
package/dist/index.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import * as react_intl from 'react-intl';
2
+ import { MessageFormatElement } from 'react-intl';
2
3
  export { FormattedMessage, IntlShape, MessageDescriptor, defineMessage, defineMessages } from 'react-intl';
3
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
5
  import * as React from 'react';
5
6
 
6
- type MessagesType = any;
7
- type LoadLocaleData = (locale: string) => Promise<MessagesType>;
7
+ type Messages = Record<string, string> | Record<string, MessageFormatElement[]>;
8
+ type LoadLocaleData = (locale: string) => Promise<Messages> | Messages;
8
9
  type I18nProviderProps = {
9
10
  locale?: string;
10
11
  loadLocaleData?: LoadLocaleData;
@@ -24,6 +25,7 @@ declare const useI18n: () => {
24
25
  children?: React.ReactNode;
25
26
  onError?: ((err: Error) => void) | undefined;
26
27
  defaultLocale: string;
28
+ messages?: Messages | undefined;
27
29
  setLocale: (language: string) => void;
28
30
  };
29
31
 
package/dist/index.js CHANGED
@@ -55,6 +55,7 @@ var import_jsx_runtime = require("react/jsx-runtime");
55
55
  var DEFAULT_LOCALE = "en";
56
56
  var I18nConfigContext = React.createContext({
57
57
  defaultLocale: DEFAULT_LOCALE,
58
+ messages: {},
58
59
  setLocale: () => {
59
60
  return null;
60
61
  }
@@ -66,25 +67,31 @@ var I18nProvider = ({
66
67
  ...intlConfig
67
68
  }) => {
68
69
  const [locale, setLocale] = React.useState(initialLocale || DEFAULT_LOCALE);
69
- const [messages, setMessages] = React.useState();
70
+ const [messagesAndLocale, setMessagesAndLocale] = React.useState({
71
+ locale: DEFAULT_LOCALE
72
+ });
70
73
  React.useEffect(() => {
71
- if (loadLocaleData) {
72
- loadLocaleData(locale).then(message => {
73
- return setMessages(message);
74
+ if (loadLocaleData && locale) {
75
+ Promise.resolve(loadLocaleData(locale)).then(messages => {
76
+ setMessagesAndLocale({
77
+ messages,
78
+ locale
79
+ });
74
80
  });
75
81
  }
76
82
  }, [loadLocaleData, locale]);
77
83
  return /* @__PURE__ */(0, import_jsx_runtime.jsx)(I18nConfigContext.Provider, {
78
84
  value: {
79
- defaultLocale: DEFAULT_LOCALE,
80
85
  locale,
86
+ defaultLocale: DEFAULT_LOCALE,
87
+ messages: messagesAndLocale.messages,
81
88
  setLocale,
82
89
  ...intlConfig
83
90
  },
84
91
  children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_react_intl.IntlProvider, {
85
92
  defaultLocale: DEFAULT_LOCALE,
86
- locale,
87
- messages,
93
+ locale: messagesAndLocale.locale,
94
+ messages: messagesAndLocale.messages,
88
95
  ...intlConfig,
89
96
  children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, {
90
97
  children
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/react-i18n",
3
- "version": "1.25.5",
3
+ "version": "1.25.7",
4
4
  "author": "ttoss",
5
5
  "contributors": [
6
6
  "Pedro Arantes <arantespp@gmail.com> (https://arantespp.com)",
@@ -32,7 +32,7 @@
32
32
  "tsup": "^8.0.1",
33
33
  "@ttoss/config": "^1.31.3",
34
34
  "@ttoss/i18n-cli": "^0.7.4",
35
- "@ttoss/test-utils": "^2.0.2"
35
+ "@ttoss/test-utils": "^2.0.3"
36
36
  },
37
37
  "keywords": [
38
38
  "React",
@@ -1,10 +1,11 @@
1
1
  import * as React from 'react';
2
- import { IntlProvider } from 'react-intl';
2
+ import { IntlProvider, MessageFormatElement } from 'react-intl';
3
3
 
4
- export type MessagesType = any;
4
+ export type Messages =
5
+ | Record<string, string>
6
+ | Record<string, MessageFormatElement[]>;
5
7
 
6
- // eslint-disable-next-line no-unused-vars
7
- export type LoadLocaleData = (locale: string) => Promise<MessagesType>;
8
+ export type LoadLocaleData = (locale: string) => Promise<Messages> | Messages;
8
9
 
9
10
  export type I18nProviderProps = {
10
11
  locale?: string;
@@ -23,12 +24,13 @@ export type I18nConfigContextProps = Omit<
23
24
  'LoadLocaleData'
24
25
  > & {
25
26
  defaultLocale: string;
26
- // eslint-disable-next-line no-unused-vars
27
+ messages?: Messages;
27
28
  setLocale: (language: string) => void;
28
29
  };
29
30
 
30
31
  export const I18nConfigContext = React.createContext<I18nConfigContextProps>({
31
32
  defaultLocale: DEFAULT_LOCALE,
33
+ messages: {},
32
34
  setLocale: () => {
33
35
  return null;
34
36
  },
@@ -40,14 +42,37 @@ export const I18nProvider = ({
40
42
  loadLocaleData,
41
43
  ...intlConfig
42
44
  }: I18nProviderProps) => {
43
- const [locale, setLocale] = React.useState(initialLocale || DEFAULT_LOCALE);
45
+ /**
46
+ * This is state is a internal state of the I18nProvider. Users modify it
47
+ * through the `setLocale` function or by changing the `locale` prop. It
48
+ * triggers the useEffect below to load the locale data.
49
+ */
50
+ const [locale, setLocale] = React.useState<string>(
51
+ initialLocale || DEFAULT_LOCALE
52
+ );
44
53
 
45
- const [messages, setMessages] = React.useState<MessagesType>();
54
+ /**
55
+ * This state exists because of the `loadLocaleData` async characteristic.
56
+ * It is used to store the locale and the loaded messages because `messages`
57
+ * can be undefined while they are being loaded. This way, we need to sync
58
+ * the `messages` with a `locale` before passing to the IntlProvider.
59
+ * If we pass `locale` defined and `messages` undefined, the IntlProvider
60
+ * will display a MISSING TRANSLATION error on console.
61
+ */
62
+ const [messagesAndLocale, setMessagesAndLocale] = React.useState<{
63
+ messages?: Messages;
64
+ locale: string;
65
+ }>({
66
+ locale: DEFAULT_LOCALE,
67
+ });
46
68
 
47
69
  React.useEffect(() => {
48
- if (loadLocaleData) {
49
- loadLocaleData(locale).then((message) => {
50
- return setMessages(message);
70
+ if (loadLocaleData && locale) {
71
+ /**
72
+ * https://stackoverflow.com/a/27760489/8786986
73
+ */
74
+ Promise.resolve(loadLocaleData(locale)).then((messages) => {
75
+ setMessagesAndLocale({ messages, locale });
51
76
  });
52
77
  }
53
78
  }, [loadLocaleData, locale]);
@@ -55,16 +80,17 @@ export const I18nProvider = ({
55
80
  return (
56
81
  <I18nConfigContext.Provider
57
82
  value={{
58
- defaultLocale: DEFAULT_LOCALE,
59
83
  locale,
84
+ defaultLocale: DEFAULT_LOCALE,
85
+ messages: messagesAndLocale.messages,
60
86
  setLocale,
61
87
  ...intlConfig,
62
88
  }}
63
89
  >
64
90
  <IntlProvider
65
91
  defaultLocale={DEFAULT_LOCALE}
66
- locale={locale}
67
- messages={messages}
92
+ locale={messagesAndLocale.locale}
93
+ messages={messagesAndLocale.messages}
68
94
  {...intlConfig}
69
95
  >
70
96
  <>{children}</>