@vocab/react 1.1.1 → 1.1.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @vocab/react
2
2
 
3
+ ## 1.1.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [`e5a066c`](https://github.com/seek-oss/vocab/commit/e5a066c8a7539a62a9c1c4d813aa87461ba43cdc) [#96](https://github.com/seek-oss/vocab/pull/96) Thanks [@askoufis](https://github.com/askoufis)! - Update `intl-messageformat` dependencies
8
+
9
+ - Updated dependencies [[`e5a066c`](https://github.com/seek-oss/vocab/commit/e5a066c8a7539a62a9c1c4d813aa87461ba43cdc)]:
10
+ - @vocab/types@1.1.1
11
+
12
+ ## 1.1.2
13
+
14
+ ### Patch Changes
15
+
16
+ - [`240d6ad`](https://github.com/seek-oss/vocab/commit/240d6ad7e0cf43fed92655a2f95fb463bd7b6644) [#85](https://github.com/seek-oss/vocab/pull/85) Thanks [@askoufis](https://github.com/askoufis)! - The `t` function returned from `useTranslations` is now memoized. `t` should now only change after the initial loading of translations, and when the language changes, making it more useful inside a hook's dependency array.
17
+
3
18
  ## 1.1.1
4
19
 
5
20
  ### Patch Changes
package/README.md CHANGED
@@ -432,6 +432,7 @@ Vocab can be used to synchronize your translations with translations from a remo
432
432
 
433
433
  ```bash
434
434
  $ vocab push --branch my-branch
435
+ $ vocab push --branch my-branch --delete-unused-keys
435
436
  $ vocab pull --branch my-branch
436
437
  ```
437
438
 
@@ -43,6 +43,7 @@ function useTranslations(translations) {
43
43
  } = useLanguage();
44
44
  const [, forceRender] = React.useReducer(s => s + 1, 0);
45
45
  const translationsObject = translations.getLoadedMessages(language, locale || language);
46
+ let ready = true;
46
47
 
47
48
  if (!translationsObject) {
48
49
  if (SERVER_RENDERING) {
@@ -52,20 +53,23 @@ function useTranslations(translations) {
52
53
  translations.load(language).then(() => {
53
54
  forceRender();
54
55
  });
55
- return {
56
- t: () => ' ',
57
- ready: false
58
- };
56
+ ready = false;
59
57
  }
60
58
 
61
- const t = (key, params) => {
62
- if (!(translationsObject !== null && translationsObject !== void 0 && translationsObject[key])) {
59
+ const t = React.useCallback((key, params) => {
60
+ if (!translationsObject) {
61
+ return ' ';
62
+ }
63
+
64
+ const message = translationsObject === null || translationsObject === void 0 ? void 0 : translationsObject[key];
65
+
66
+ if (!message) {
63
67
  // eslint-disable-next-line no-console
64
68
  console.error(`Unable to find translation for key "${key}". Possible keys are ${Object.keys(translationsObject).map(v => `"${v}"`).join(', ')}`);
65
69
  return '';
66
70
  }
67
71
 
68
- const result = translationsObject[key].format(params);
72
+ const result = message.format(params);
69
73
 
70
74
  if (Array.isArray(result)) {
71
75
  for (let i = 0; i < result.length; i++) {
@@ -80,10 +84,9 @@ function useTranslations(translations) {
80
84
  }
81
85
 
82
86
  return result;
83
- };
84
-
87
+ }, [translationsObject]);
85
88
  return {
86
- ready: true,
89
+ ready,
87
90
  t
88
91
  };
89
92
  }
@@ -43,6 +43,7 @@ function useTranslations(translations) {
43
43
  } = useLanguage();
44
44
  const [, forceRender] = React.useReducer(s => s + 1, 0);
45
45
  const translationsObject = translations.getLoadedMessages(language, locale || language);
46
+ let ready = true;
46
47
 
47
48
  if (!translationsObject) {
48
49
  if (SERVER_RENDERING) {
@@ -52,20 +53,23 @@ function useTranslations(translations) {
52
53
  translations.load(language).then(() => {
53
54
  forceRender();
54
55
  });
55
- return {
56
- t: () => ' ',
57
- ready: false
58
- };
56
+ ready = false;
59
57
  }
60
58
 
61
- const t = (key, params) => {
62
- if (!(translationsObject !== null && translationsObject !== void 0 && translationsObject[key])) {
59
+ const t = React.useCallback((key, params) => {
60
+ if (!translationsObject) {
61
+ return ' ';
62
+ }
63
+
64
+ const message = translationsObject === null || translationsObject === void 0 ? void 0 : translationsObject[key];
65
+
66
+ if (!message) {
63
67
  // eslint-disable-next-line no-console
64
68
  console.error(`Unable to find translation for key "${key}". Possible keys are ${Object.keys(translationsObject).map(v => `"${v}"`).join(', ')}`);
65
69
  return '';
66
70
  }
67
71
 
68
- const result = translationsObject[key].format(params);
72
+ const result = message.format(params);
69
73
 
70
74
  if (Array.isArray(result)) {
71
75
  for (let i = 0; i < result.length; i++) {
@@ -80,10 +84,9 @@ function useTranslations(translations) {
80
84
  }
81
85
 
82
86
  return result;
83
- };
84
-
87
+ }, [translationsObject]);
85
88
  return {
86
- ready: true,
89
+ ready,
87
90
  t
88
91
  };
89
92
  }
@@ -1,4 +1,4 @@
1
- import React, { useMemo, useContext, useReducer, isValidElement, cloneElement } from 'react';
1
+ import React, { useMemo, useContext, useReducer, useCallback, isValidElement, cloneElement } from 'react';
2
2
 
3
3
  const TranslationsContext = /*#__PURE__*/React.createContext(undefined);
4
4
  const VocabProvider = ({
@@ -35,6 +35,7 @@ function useTranslations(translations) {
35
35
  } = useLanguage();
36
36
  const [, forceRender] = useReducer(s => s + 1, 0);
37
37
  const translationsObject = translations.getLoadedMessages(language, locale || language);
38
+ let ready = true;
38
39
 
39
40
  if (!translationsObject) {
40
41
  if (SERVER_RENDERING) {
@@ -44,20 +45,23 @@ function useTranslations(translations) {
44
45
  translations.load(language).then(() => {
45
46
  forceRender();
46
47
  });
47
- return {
48
- t: () => ' ',
49
- ready: false
50
- };
48
+ ready = false;
51
49
  }
52
50
 
53
- const t = (key, params) => {
54
- if (!(translationsObject !== null && translationsObject !== void 0 && translationsObject[key])) {
51
+ const t = useCallback((key, params) => {
52
+ if (!translationsObject) {
53
+ return ' ';
54
+ }
55
+
56
+ const message = translationsObject === null || translationsObject === void 0 ? void 0 : translationsObject[key];
57
+
58
+ if (!message) {
55
59
  // eslint-disable-next-line no-console
56
60
  console.error(`Unable to find translation for key "${key}". Possible keys are ${Object.keys(translationsObject).map(v => `"${v}"`).join(', ')}`);
57
61
  return '';
58
62
  }
59
63
 
60
- const result = translationsObject[key].format(params);
64
+ const result = message.format(params);
61
65
 
62
66
  if (Array.isArray(result)) {
63
67
  for (let i = 0; i < result.length; i++) {
@@ -72,10 +76,9 @@ function useTranslations(translations) {
72
76
  }
73
77
 
74
78
  return result;
75
- };
76
-
79
+ }, [translationsObject]);
77
80
  return {
78
- ready: true,
81
+ ready,
79
82
  t
80
83
  };
81
84
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vocab/react",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "main": "dist/vocab-react.cjs.js",
5
5
  "module": "dist/vocab-react.esm.js",
6
6
  "author": "SEEK",
@@ -9,8 +9,8 @@
9
9
  "react": ">=16.3.0"
10
10
  },
11
11
  "dependencies": {
12
- "@vocab/types": "^1.0.1",
13
- "intl-messageformat": "^9.9.0"
12
+ "@vocab/types": "^1.1.1",
13
+ "intl-messageformat": "^10.0.0"
14
14
  },
15
15
  "devDependencies": {
16
16
  "@types/react": "^18.0.9",
package/src/index.tsx CHANGED
@@ -11,6 +11,7 @@ import React, {
11
11
  useReducer,
12
12
  isValidElement,
13
13
  cloneElement,
14
+ useCallback,
14
15
  } from 'react';
15
16
 
16
17
  type Locale = string;
@@ -103,55 +104,64 @@ export function useTranslations<
103
104
  locale || language,
104
105
  );
105
106
 
107
+ let ready = true;
108
+
106
109
  if (!translationsObject) {
107
110
  if (SERVER_RENDERING) {
108
111
  throw new Error(
109
112
  `Translations not synchronously available on server render. Applying translations dynamically server-side is not supported.`,
110
113
  );
111
114
  }
115
+
112
116
  translations.load(language as any).then(() => {
113
117
  forceRender();
114
118
  });
115
- return {
116
- t: (() => ' ') as TranslateFn<ParsedFormatFnByKey>,
117
- ready: false,
118
- };
119
+ ready = false;
119
120
  }
120
121
 
121
- const t = (key: string, params?: any) => {
122
- if (!translationsObject?.[key]) {
123
- // eslint-disable-next-line no-console
124
- console.error(
125
- `Unable to find translation for key "${key}". Possible keys are ${Object.keys(
126
- translationsObject,
127
- )
128
- .map((v) => `"${v}"`)
129
- .join(', ')}`,
130
- );
131
- return '';
132
- }
122
+ const t = useCallback(
123
+ (key: string, params?: any) => {
124
+ if (!translationsObject) {
125
+ return ' ';
126
+ }
133
127
 
134
- const result = translationsObject[key].format(params);
135
-
136
- if (Array.isArray(result)) {
137
- for (let i = 0; i < result.length; i++) {
138
- const item = result[i];
139
- if (
140
- typeof item === 'object' &&
141
- item &&
142
- !item.key &&
143
- isValidElement(item)
144
- ) {
145
- result[i] = cloneElement(item, { key: `_vocab-${i}` });
128
+ const message = translationsObject?.[key];
129
+
130
+ if (!message) {
131
+ // eslint-disable-next-line no-console
132
+ console.error(
133
+ `Unable to find translation for key "${key}". Possible keys are ${Object.keys(
134
+ translationsObject,
135
+ )
136
+ .map((v) => `"${v}"`)
137
+ .join(', ')}`,
138
+ );
139
+ return '';
140
+ }
141
+
142
+ const result = message.format(params);
143
+
144
+ if (Array.isArray(result)) {
145
+ for (let i = 0; i < result.length; i++) {
146
+ const item = result[i];
147
+ if (
148
+ typeof item === 'object' &&
149
+ item &&
150
+ !item.key &&
151
+ isValidElement(item)
152
+ ) {
153
+ result[i] = cloneElement(item, { key: `_vocab-${i}` });
154
+ }
146
155
  }
147
156
  }
148
- }
149
157
 
150
- return result;
151
- };
158
+ return result;
159
+ },
160
+ [translationsObject],
161
+ );
152
162
 
153
163
  return {
154
- ready: true,
164
+ ready,
155
165
  t,
156
166
  };
157
167
  }