react-i18next 14.1.2 → 15.0.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/CHANGELOG.md +16 -0
- package/README.md +0 -2
- package/dist/amd/react-i18next.js +134 -176
- package/dist/amd/react-i18next.min.js +1 -1
- package/dist/commonjs/Trans.js +2 -2
- package/dist/commonjs/TransWithoutContext.js +53 -55
- package/dist/commonjs/Translation.js +6 -5
- package/dist/commonjs/context.js +17 -25
- package/dist/commonjs/defaults.js +6 -7
- package/dist/commonjs/i18nInstance.js +6 -7
- package/dist/commonjs/useSSR.js +5 -4
- package/dist/commonjs/useTranslation.js +17 -20
- package/dist/commonjs/utils.js +28 -45
- package/dist/commonjs/withSSR.js +19 -20
- package/dist/commonjs/withTranslation.js +4 -3
- package/dist/es/I18nextProvider.js +5 -6
- package/dist/es/Trans.js +18 -19
- package/dist/es/TransWithoutContext.js +68 -72
- package/dist/es/Translation.js +6 -7
- package/dist/es/context.js +13 -22
- package/dist/es/defaults.js +3 -6
- package/dist/es/i18nInstance.js +3 -5
- package/dist/es/package.json +1 -1
- package/dist/es/useSSR.js +3 -4
- package/dist/es/useTranslation.js +16 -21
- package/dist/es/utils.js +19 -46
- package/dist/es/withSSR.js +16 -19
- package/dist/es/withTranslation.js +28 -32
- package/dist/umd/react-i18next.js +134 -176
- package/dist/umd/react-i18next.min.js +1 -1
- package/icu.macro.d.ts +5 -5
- package/index.d.ts +2 -2
- package/package.json +23 -30
- package/react-i18next.js +134 -176
- package/react-i18next.min.js +1 -1
- package/src/Trans.js +2 -3
- package/src/TransWithoutContext.js +56 -62
- package/src/Translation.js +2 -3
- package/src/context.js +13 -36
- package/src/defaults.js +3 -5
- package/src/i18nInstance.js +3 -5
- package/src/useSSR.js +3 -3
- package/src/useTranslation.js +25 -24
- package/src/utils.js +26 -76
- package/src/withSSR.js +2 -3
- package/src/withTranslation.js +2 -3
- package/vitest.workspace.typescript.mts +11 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
### 15.0.0
|
|
2
|
+
|
|
3
|
+
- use optional chaining, nullish coalescing and nullish coalescing assignment [1774](https://github.com/i18next/react-i18next/pull/1774)
|
|
4
|
+
- Build config and optimizations [1769](https://github.com/i18next/react-i18next/pull/1769)
|
|
5
|
+
- some dependency updates [1768](https://github.com/i18next/react-i18next/pull/1768)
|
|
6
|
+
- use modern hasLoadedNamespace code (now requires at least i18next > v19.4.5 (introduced in june 2020))
|
|
7
|
+
|
|
8
|
+
### 14.1.3
|
|
9
|
+
|
|
10
|
+
- create a isObject helper function [1766](https://github.com/i18next/react-i18next/pull/1766)
|
|
11
|
+
- optimize nodesToString [1765](https://github.com/i18next/react-i18next/pull/1765)
|
|
12
|
+
- Simplifies hasValidReactChildren [1764](https://github.com/i18next/react-i18next/pull/1764)
|
|
13
|
+
- create a isString helper to avoid code duplication [1763](https://github.com/i18next/react-i18next/pull/1763)
|
|
14
|
+
- use arrow functions where possible [1762](https://github.com/i18next/react-i18next/pull/1762)
|
|
15
|
+
- use the commented out async code [1761](https://github.com/i18next/react-i18next/pull/1761)
|
|
16
|
+
|
|
1
17
|
### 14.1.2
|
|
2
18
|
|
|
3
19
|
- bring back internal interpolationOverride handling for Trans component (if there are childrens), fixes [1754](https://github.com/i18next/react-i18next/issues/1754)
|
package/README.md
CHANGED
|
@@ -60,8 +60,6 @@ The general i18next documentation is published on [www.i18next.com](https://www.
|
|
|
60
60
|
...
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
Head over to the **interactive playground** at [codesandbox](https://codesandbox.io/s/1zxox032q).
|
|
64
|
-
|
|
65
63
|
### 📖 What others say
|
|
66
64
|
|
|
67
65
|
- [How to properly internationalize a React application using i18next](https://locize.com/blog/react-i18next/) by Adriano Raiano
|
|
@@ -114,24 +114,24 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
114
114
|
}
|
|
115
115
|
};
|
|
116
116
|
|
|
117
|
-
function
|
|
118
|
-
if (console
|
|
117
|
+
const warn = function () {
|
|
118
|
+
if (console?.warn) {
|
|
119
119
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
120
120
|
args[_key] = arguments[_key];
|
|
121
121
|
}
|
|
122
|
-
if (
|
|
122
|
+
if (isString(args[0])) args[0] = `react-i18next:: ${args[0]}`;
|
|
123
123
|
console.warn(...args);
|
|
124
124
|
}
|
|
125
|
-
}
|
|
125
|
+
};
|
|
126
126
|
const alreadyWarned = {};
|
|
127
|
-
function
|
|
127
|
+
const warnOnce = function () {
|
|
128
128
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
129
129
|
args[_key2] = arguments[_key2];
|
|
130
130
|
}
|
|
131
|
-
if (
|
|
132
|
-
if (
|
|
131
|
+
if (isString(args[0]) && alreadyWarned[args[0]]) return;
|
|
132
|
+
if (isString(args[0])) alreadyWarned[args[0]] = new Date();
|
|
133
133
|
warn(...args);
|
|
134
|
-
}
|
|
134
|
+
};
|
|
135
135
|
const loadedClb = (i18n, cb) => () => {
|
|
136
136
|
if (i18n.isInitialized) {
|
|
137
137
|
cb();
|
|
@@ -145,52 +145,32 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
145
145
|
i18n.on('initialized', initialized);
|
|
146
146
|
}
|
|
147
147
|
};
|
|
148
|
-
|
|
148
|
+
const loadNamespaces = (i18n, ns, cb) => {
|
|
149
149
|
i18n.loadNamespaces(ns, loadedClb(i18n, cb));
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (
|
|
150
|
+
};
|
|
151
|
+
const loadLanguages = (i18n, lng, ns, cb) => {
|
|
152
|
+
if (isString(ns)) ns = [ns];
|
|
153
153
|
ns.forEach(n => {
|
|
154
154
|
if (i18n.options.ns.indexOf(n) < 0) i18n.options.ns.push(n);
|
|
155
155
|
});
|
|
156
156
|
i18n.loadLanguages(lng, loadedClb(i18n, cb));
|
|
157
|
-
}
|
|
158
|
-
function
|
|
159
|
-
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
160
|
-
const lng = i18n.languages[0];
|
|
161
|
-
const fallbackLng = i18n.options ? i18n.options.fallbackLng : false;
|
|
162
|
-
const lastLng = i18n.languages[i18n.languages.length - 1];
|
|
163
|
-
if (lng.toLowerCase() === 'cimode') return true;
|
|
164
|
-
const loadNotPending = (l, n) => {
|
|
165
|
-
const loadState = i18n.services.backendConnector.state[`${l}|${n}`];
|
|
166
|
-
return loadState === -1 || loadState === 2;
|
|
167
|
-
};
|
|
168
|
-
if (options.bindI18n && options.bindI18n.indexOf('languageChanging') > -1 && i18n.services.backendConnector.backend && i18n.isLanguageChangingTo && !loadNotPending(i18n.isLanguageChangingTo, ns)) return false;
|
|
169
|
-
if (i18n.hasResourceBundle(lng, ns)) return true;
|
|
170
|
-
if (!i18n.services.backendConnector.backend || i18n.options.resources && !i18n.options.partialBundledLanguages) return true;
|
|
171
|
-
if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns))) return true;
|
|
172
|
-
return false;
|
|
173
|
-
}
|
|
174
|
-
function hasLoadedNamespace(ns, i18n) {
|
|
157
|
+
};
|
|
158
|
+
const hasLoadedNamespace = function (ns, i18n) {
|
|
175
159
|
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
176
160
|
if (!i18n.languages || !i18n.languages.length) {
|
|
177
161
|
warnOnce('i18n.languages were undefined or empty', i18n.languages);
|
|
178
162
|
return true;
|
|
179
163
|
}
|
|
180
|
-
const isNewerI18next = i18n.options.ignoreJSONStructure !== undefined;
|
|
181
|
-
if (!isNewerI18next) {
|
|
182
|
-
return oldI18nextHasLoadedNamespace(ns, i18n, options);
|
|
183
|
-
}
|
|
184
164
|
return i18n.hasLoadedNamespace(ns, {
|
|
185
165
|
lng: options.lng,
|
|
186
166
|
precheck: (i18nInstance, loadNotPending) => {
|
|
187
|
-
if (options.bindI18n
|
|
167
|
+
if (options.bindI18n?.indexOf('languageChanging') > -1 && i18nInstance.services.backendConnector.backend && i18nInstance.isLanguageChangingTo && !loadNotPending(i18nInstance.isLanguageChangingTo, ns)) return false;
|
|
188
168
|
}
|
|
189
169
|
});
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
170
|
+
};
|
|
171
|
+
const getDisplayName = Component => Component.displayName || Component.name || (isString(Component) && Component.length > 0 ? Component : 'Unknown');
|
|
172
|
+
const isString = obj => typeof obj === 'string';
|
|
173
|
+
const isObject = obj => typeof obj === 'object' && obj !== null;
|
|
194
174
|
|
|
195
175
|
const matchHtmlEntity = /&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34|nbsp|#160|copy|#169|reg|#174|hellip|#8230|#x2F|#47);/g;
|
|
196
176
|
const htmlEntities = {
|
|
@@ -228,77 +208,70 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
228
208
|
useSuspense: true,
|
|
229
209
|
unescape
|
|
230
210
|
};
|
|
231
|
-
function
|
|
211
|
+
const setDefaults = function () {
|
|
232
212
|
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
233
213
|
defaultOptions = {
|
|
234
214
|
...defaultOptions,
|
|
235
215
|
...options
|
|
236
216
|
};
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
return defaultOptions;
|
|
240
|
-
}
|
|
217
|
+
};
|
|
218
|
+
const getDefaults = () => defaultOptions;
|
|
241
219
|
|
|
242
220
|
let i18nInstance;
|
|
243
|
-
|
|
221
|
+
const setI18n = instance => {
|
|
244
222
|
i18nInstance = instance;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
return i18nInstance;
|
|
248
|
-
}
|
|
223
|
+
};
|
|
224
|
+
const getI18n = () => i18nInstance;
|
|
249
225
|
|
|
250
|
-
|
|
226
|
+
const hasChildren = (node, checkLength) => {
|
|
251
227
|
if (!node) return false;
|
|
252
|
-
const base = node.props
|
|
228
|
+
const base = node.props?.children ?? node.children;
|
|
253
229
|
if (checkLength) return base.length > 0;
|
|
254
230
|
return !!base;
|
|
255
|
-
}
|
|
256
|
-
|
|
231
|
+
};
|
|
232
|
+
const getChildren = node => {
|
|
257
233
|
if (!node) return [];
|
|
258
|
-
const children = node.props
|
|
259
|
-
return node.props
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
function getAsArray(data) {
|
|
266
|
-
return Array.isArray(data) ? data : [data];
|
|
267
|
-
}
|
|
268
|
-
function mergeProps(source, target) {
|
|
234
|
+
const children = node.props?.children ?? node.children;
|
|
235
|
+
return node.props?.i18nIsDynamicList ? getAsArray(children) : children;
|
|
236
|
+
};
|
|
237
|
+
const hasValidReactChildren = children => Array.isArray(children) && children.every(react.isValidElement);
|
|
238
|
+
const getAsArray = data => Array.isArray(data) ? data : [data];
|
|
239
|
+
const mergeProps = (source, target) => {
|
|
269
240
|
const newTarget = {
|
|
270
241
|
...target
|
|
271
242
|
};
|
|
272
243
|
newTarget.props = Object.assign(source.props, target.props);
|
|
273
244
|
return newTarget;
|
|
274
|
-
}
|
|
275
|
-
|
|
245
|
+
};
|
|
246
|
+
const nodesToString = (children, i18nOptions) => {
|
|
276
247
|
if (!children) return '';
|
|
277
248
|
let stringNode = '';
|
|
278
249
|
const childrenArray = getAsArray(children);
|
|
279
|
-
const keepArray = i18nOptions
|
|
250
|
+
const keepArray = i18nOptions?.transSupportBasicHtmlNodes ? i18nOptions.transKeepBasicHtmlNodesFor ?? [] : [];
|
|
280
251
|
childrenArray.forEach((child, childIndex) => {
|
|
281
|
-
if (
|
|
252
|
+
if (isString(child)) {
|
|
282
253
|
stringNode += `${child}`;
|
|
283
254
|
} else if (react.isValidElement(child)) {
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
255
|
+
const {
|
|
256
|
+
props,
|
|
257
|
+
type
|
|
258
|
+
} = child;
|
|
259
|
+
const childPropsCount = Object.keys(props).length;
|
|
260
|
+
const shouldKeepChild = keepArray.indexOf(type) > -1;
|
|
261
|
+
const childChildren = props.children;
|
|
262
|
+
if (!childChildren && shouldKeepChild && !childPropsCount) {
|
|
263
|
+
stringNode += `<${type}/>`;
|
|
264
|
+
} else if (!childChildren && (!shouldKeepChild || childPropsCount) || props.i18nIsDynamicList) {
|
|
292
265
|
stringNode += `<${childIndex}></${childIndex}>`;
|
|
293
|
-
} else if (shouldKeepChild && childPropsCount === 1 &&
|
|
294
|
-
stringNode += `<${
|
|
266
|
+
} else if (shouldKeepChild && childPropsCount === 1 && isString(childChildren)) {
|
|
267
|
+
stringNode += `<${type}>${childChildren}</${type}>`;
|
|
295
268
|
} else {
|
|
296
269
|
const content = nodesToString(childChildren, i18nOptions);
|
|
297
270
|
stringNode += `<${childIndex}>${content}</${childIndex}>`;
|
|
298
271
|
}
|
|
299
272
|
} else if (child === null) {
|
|
300
273
|
warn(`Trans: the passed in value is invalid - seems you passed in a null child.`);
|
|
301
|
-
} else if (
|
|
274
|
+
} else if (isObject(child)) {
|
|
302
275
|
const {
|
|
303
276
|
format,
|
|
304
277
|
...clone
|
|
@@ -315,32 +288,32 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
315
288
|
}
|
|
316
289
|
});
|
|
317
290
|
return stringNode;
|
|
318
|
-
}
|
|
319
|
-
|
|
291
|
+
};
|
|
292
|
+
const renderNodes = (children, targetString, i18n, i18nOptions, combinedTOpts, shouldUnescape) => {
|
|
320
293
|
if (targetString === '') return [];
|
|
321
294
|
const keepArray = i18nOptions.transKeepBasicHtmlNodesFor || [];
|
|
322
295
|
const emptyChildrenButNeedsHandling = targetString && new RegExp(keepArray.map(keep => `<${keep}`).join('|')).test(targetString);
|
|
323
296
|
if (!children && !emptyChildrenButNeedsHandling && !shouldUnescape) return [targetString];
|
|
324
297
|
const data = {};
|
|
325
|
-
|
|
298
|
+
const getData = childs => {
|
|
326
299
|
const childrenArray = getAsArray(childs);
|
|
327
300
|
childrenArray.forEach(child => {
|
|
328
|
-
if (
|
|
329
|
-
if (hasChildren(child)) getData(getChildren(child));else if (
|
|
301
|
+
if (isString(child)) return;
|
|
302
|
+
if (hasChildren(child)) getData(getChildren(child));else if (isObject(child) && !react.isValidElement(child)) Object.assign(data, child);
|
|
330
303
|
});
|
|
331
|
-
}
|
|
304
|
+
};
|
|
332
305
|
getData(children);
|
|
333
306
|
const ast = c.parse(`<0>${targetString}</0>`);
|
|
334
307
|
const opts = {
|
|
335
308
|
...data,
|
|
336
309
|
...combinedTOpts
|
|
337
310
|
};
|
|
338
|
-
|
|
311
|
+
const renderInner = (child, node, rootReactNode) => {
|
|
339
312
|
const childs = getChildren(child);
|
|
340
313
|
const mappedChildren = mapAST(childs, node.children, rootReactNode);
|
|
341
|
-
return hasValidReactChildren(childs) && mappedChildren.length === 0 || child.props
|
|
342
|
-
}
|
|
343
|
-
|
|
314
|
+
return hasValidReactChildren(childs) && mappedChildren.length === 0 || child.props?.i18nIsDynamicList ? childs : mappedChildren;
|
|
315
|
+
};
|
|
316
|
+
const pushTranslatedJSX = (child, inner, mem, i, isVoid) => {
|
|
344
317
|
if (child.dummy) {
|
|
345
318
|
child.children = inner;
|
|
346
319
|
mem.push(react.cloneElement(child, {
|
|
@@ -359,12 +332,12 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
359
332
|
}, isVoid ? null : inner);
|
|
360
333
|
}));
|
|
361
334
|
}
|
|
362
|
-
}
|
|
363
|
-
|
|
335
|
+
};
|
|
336
|
+
const mapAST = (reactNode, astNode, rootReactNode) => {
|
|
364
337
|
const reactNodes = getAsArray(reactNode);
|
|
365
338
|
const astNodes = getAsArray(astNode);
|
|
366
339
|
return astNodes.reduce((mem, node, i) => {
|
|
367
|
-
const translationContent = node.children
|
|
340
|
+
const translationContent = node.children?.[0]?.content && i18n.services.interpolator.interpolate(node.children[0].content, opts, i18n.language);
|
|
368
341
|
if (node.type === 'tag') {
|
|
369
342
|
let tmp = reactNodes[parseInt(node.name, 10)];
|
|
370
343
|
if (rootReactNode.length === 1 && !tmp) tmp = rootReactNode[0][node.name];
|
|
@@ -374,9 +347,9 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
374
347
|
}, tmp) : tmp;
|
|
375
348
|
const isElement = react.isValidElement(child);
|
|
376
349
|
const isValidTranslationWithChildren = isElement && hasChildren(node, true) && !node.voidElement;
|
|
377
|
-
const isEmptyTransWithHTML = emptyChildrenButNeedsHandling &&
|
|
378
|
-
const isKnownComponent =
|
|
379
|
-
if (
|
|
350
|
+
const isEmptyTransWithHTML = emptyChildrenButNeedsHandling && isObject(child) && child.dummy && !isElement;
|
|
351
|
+
const isKnownComponent = isObject(children) && Object.hasOwnProperty.call(children, node.name);
|
|
352
|
+
if (isString(child)) {
|
|
380
353
|
const value = i18n.services.interpolator.interpolate(child, opts, i18n.language);
|
|
381
354
|
mem.push(value);
|
|
382
355
|
} else if (hasChildren(child) || isValidTranslationWithChildren) {
|
|
@@ -406,7 +379,7 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
406
379
|
const inner = mapAST(reactNodes, node.children, rootReactNode);
|
|
407
380
|
mem.push(`<${node.name}>${inner}</${node.name}>`);
|
|
408
381
|
}
|
|
409
|
-
} else if (
|
|
382
|
+
} else if (isObject(child) && !isElement) {
|
|
410
383
|
const content = node.children[0] ? translationContent : null;
|
|
411
384
|
if (content) mem.push(content);
|
|
412
385
|
} else {
|
|
@@ -425,13 +398,13 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
425
398
|
}
|
|
426
399
|
return mem;
|
|
427
400
|
}, []);
|
|
428
|
-
}
|
|
401
|
+
};
|
|
429
402
|
const result = mapAST([{
|
|
430
403
|
dummy: true,
|
|
431
404
|
children: children || []
|
|
432
405
|
}], ast, getAsArray(children || []));
|
|
433
406
|
return getChildren(result[0]);
|
|
434
|
-
}
|
|
407
|
+
};
|
|
435
408
|
function Trans$1(_ref) {
|
|
436
409
|
let {
|
|
437
410
|
children,
|
|
@@ -457,17 +430,17 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
457
430
|
const t = tFromProps || i18n.t.bind(i18n) || (k => k);
|
|
458
431
|
const reactI18nextOptions = {
|
|
459
432
|
...getDefaults(),
|
|
460
|
-
...
|
|
433
|
+
...i18n.options?.react
|
|
461
434
|
};
|
|
462
|
-
let namespaces = ns || t.ns || i18n.options
|
|
463
|
-
namespaces =
|
|
435
|
+
let namespaces = ns || t.ns || i18n.options?.defaultNS;
|
|
436
|
+
namespaces = isString(namespaces) ? [namespaces] : namespaces || ['translation'];
|
|
464
437
|
const nodeAsString = nodesToString(children, reactI18nextOptions);
|
|
465
438
|
const defaultValue = defaults || nodeAsString || reactI18nextOptions.transEmptyNodeValue || i18nKey;
|
|
466
439
|
const {
|
|
467
440
|
hashTransKey
|
|
468
441
|
} = reactI18nextOptions;
|
|
469
442
|
const key = i18nKey || (hashTransKey ? hashTransKey(nodeAsString || defaultValue) : nodeAsString || defaultValue);
|
|
470
|
-
if (i18n.options
|
|
443
|
+
if (i18n.options?.interpolation?.defaultVariables) {
|
|
471
444
|
values = values && Object.keys(values).length > 0 ? {
|
|
472
445
|
...values,
|
|
473
446
|
...i18n.options.interpolation.defaultVariables
|
|
@@ -503,7 +476,7 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
503
476
|
});
|
|
504
477
|
}
|
|
505
478
|
const content = renderNodes(components || children, translation, i18n, reactI18nextOptions, combinedTOpts, shouldUnescape);
|
|
506
|
-
const useAsParent = parent
|
|
479
|
+
const useAsParent = parent ?? reactI18nextOptions.defaultTransParent;
|
|
507
480
|
return useAsParent ? react.createElement(useAsParent, additionalProps, content) : content;
|
|
508
481
|
}
|
|
509
482
|
|
|
@@ -522,31 +495,22 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
522
495
|
}
|
|
523
496
|
addUsedNamespaces(namespaces) {
|
|
524
497
|
namespaces.forEach(ns => {
|
|
525
|
-
|
|
498
|
+
this.usedNamespaces[ns] ??= true;
|
|
526
499
|
});
|
|
527
500
|
}
|
|
528
|
-
getUsedNamespaces()
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
return
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
...i18nInitialProps
|
|
540
|
-
});
|
|
541
|
-
});
|
|
542
|
-
} else {
|
|
543
|
-
resolve(i18nInitialProps);
|
|
544
|
-
}
|
|
545
|
-
});
|
|
546
|
-
}
|
|
547
|
-
function getInitialProps() {
|
|
501
|
+
getUsedNamespaces = () => Object.keys(this.usedNamespaces);
|
|
502
|
+
}
|
|
503
|
+
const composeInitialProps = ForComponent => async ctx => {
|
|
504
|
+
const componentsInitialProps = (await ForComponent.getInitialProps?.(ctx)) ?? {};
|
|
505
|
+
const i18nInitialProps = getInitialProps();
|
|
506
|
+
return {
|
|
507
|
+
...componentsInitialProps,
|
|
508
|
+
...i18nInitialProps
|
|
509
|
+
};
|
|
510
|
+
};
|
|
511
|
+
const getInitialProps = () => {
|
|
548
512
|
const i18n = getI18n();
|
|
549
|
-
const namespaces = i18n.reportNamespaces
|
|
513
|
+
const namespaces = i18n.reportNamespaces?.getUsedNamespaces() ?? [];
|
|
550
514
|
const ret = {};
|
|
551
515
|
const initialI18nStore = {};
|
|
552
516
|
i18n.languages.forEach(l => {
|
|
@@ -558,7 +522,7 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
558
522
|
ret.initialI18nStore = initialI18nStore;
|
|
559
523
|
ret.initialLanguage = i18n.language;
|
|
560
524
|
return ret;
|
|
561
|
-
}
|
|
525
|
+
};
|
|
562
526
|
|
|
563
527
|
function Trans(_ref) {
|
|
564
528
|
let {
|
|
@@ -582,7 +546,7 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
582
546
|
defaultNS: defaultNSFromContext
|
|
583
547
|
} = react.useContext(I18nContext) || {};
|
|
584
548
|
const i18n = i18nFromProps || i18nFromContext || getI18n();
|
|
585
|
-
const t = tFromProps || i18n
|
|
549
|
+
const t = tFromProps || i18n?.t.bind(i18n);
|
|
586
550
|
return Trans$1({
|
|
587
551
|
children,
|
|
588
552
|
count,
|
|
@@ -593,7 +557,7 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
593
557
|
values,
|
|
594
558
|
defaults,
|
|
595
559
|
components,
|
|
596
|
-
ns: ns || t
|
|
560
|
+
ns: ns || t?.ns || defaultNSFromContext || i18n?.options?.defaultNS,
|
|
597
561
|
i18n,
|
|
598
562
|
t: tFromProps,
|
|
599
563
|
shouldUnescape,
|
|
@@ -604,17 +568,13 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
604
568
|
const usePrevious = (value, ignore) => {
|
|
605
569
|
const ref = react.useRef();
|
|
606
570
|
react.useEffect(() => {
|
|
607
|
-
ref.current =
|
|
571
|
+
ref.current = value;
|
|
608
572
|
}, [value, ignore]);
|
|
609
573
|
return ref.current;
|
|
610
574
|
};
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
function useMemoizedT(i18n, language, namespace, keyPrefix) {
|
|
615
|
-
return react.useCallback(alwaysNewT(i18n, language, namespace, keyPrefix), [i18n, language, namespace, keyPrefix]);
|
|
616
|
-
}
|
|
617
|
-
function useTranslation(ns) {
|
|
575
|
+
const alwaysNewT = (i18n, language, namespace, keyPrefix) => i18n.getFixedT(language, namespace, keyPrefix);
|
|
576
|
+
const useMemoizedT = (i18n, language, namespace, keyPrefix) => react.useCallback(alwaysNewT(i18n, language, namespace, keyPrefix), [i18n, language, namespace, keyPrefix]);
|
|
577
|
+
const useTranslation = function (ns) {
|
|
618
578
|
let props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
619
579
|
const {
|
|
620
580
|
i18n: i18nFromProps
|
|
@@ -628,8 +588,8 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
628
588
|
if (!i18n) {
|
|
629
589
|
warnOnce('You will need to pass in an i18next instance by using initReactI18next');
|
|
630
590
|
const notReadyT = (k, optsOrDefaultValue) => {
|
|
631
|
-
if (
|
|
632
|
-
if (optsOrDefaultValue &&
|
|
591
|
+
if (isString(optsOrDefaultValue)) return optsOrDefaultValue;
|
|
592
|
+
if (isObject(optsOrDefaultValue) && isString(optsOrDefaultValue.defaultValue)) return optsOrDefaultValue.defaultValue;
|
|
633
593
|
return Array.isArray(k) ? k[k.length - 1] : k;
|
|
634
594
|
};
|
|
635
595
|
const retNotReady = [notReadyT, {}, false];
|
|
@@ -638,7 +598,7 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
638
598
|
retNotReady.ready = false;
|
|
639
599
|
return retNotReady;
|
|
640
600
|
}
|
|
641
|
-
if (i18n.options.react
|
|
601
|
+
if (i18n.options.react?.wait) warnOnce('It seems you are still using the old wait option, you may migrate to the new useSuspense behaviour.');
|
|
642
602
|
const i18nOptions = {
|
|
643
603
|
...getDefaults(),
|
|
644
604
|
...i18n.options.react,
|
|
@@ -648,9 +608,9 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
648
608
|
useSuspense,
|
|
649
609
|
keyPrefix
|
|
650
610
|
} = i18nOptions;
|
|
651
|
-
let namespaces = ns || defaultNSFromContext || i18n.options
|
|
652
|
-
namespaces =
|
|
653
|
-
|
|
611
|
+
let namespaces = ns || defaultNSFromContext || i18n.options?.defaultNS;
|
|
612
|
+
namespaces = isString(namespaces) ? [namespaces] : namespaces || ['translation'];
|
|
613
|
+
i18n.reportNamespaces.addUsedNamespaces?.(namespaces);
|
|
654
614
|
const ready = (i18n.isInitialized || i18n.initializedStoreOnce) && namespaces.every(n => hasLoadedNamespace(n, i18n, i18nOptions));
|
|
655
615
|
const memoGetT = useMemoizedT(i18n, props.lng || null, i18nOptions.nsMode === 'fallback' ? namespaces : namespaces[0], keyPrefix);
|
|
656
616
|
const getT = () => memoGetT;
|
|
@@ -680,14 +640,14 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
680
640
|
if (ready && previousJoinedNS && previousJoinedNS !== joinedNS && isMounted.current) {
|
|
681
641
|
setT(getNewT);
|
|
682
642
|
}
|
|
683
|
-
|
|
643
|
+
const boundReset = () => {
|
|
684
644
|
if (isMounted.current) setT(getNewT);
|
|
685
|
-
}
|
|
686
|
-
if (bindI18n
|
|
687
|
-
if (bindI18nStore
|
|
645
|
+
};
|
|
646
|
+
if (bindI18n) i18n?.on(bindI18n, boundReset);
|
|
647
|
+
if (bindI18nStore) i18n?.store.on(bindI18nStore, boundReset);
|
|
688
648
|
return () => {
|
|
689
649
|
isMounted.current = false;
|
|
690
|
-
if (
|
|
650
|
+
if (i18n) bindI18n?.split(' ').forEach(e => i18n.off(e, boundReset));
|
|
691
651
|
if (bindI18nStore && i18n) bindI18nStore.split(' ').forEach(e => i18n.store.off(e, boundReset));
|
|
692
652
|
};
|
|
693
653
|
}, [i18n, joinedNS]);
|
|
@@ -709,9 +669,9 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
709
669
|
loadNamespaces(i18n, namespaces, () => resolve());
|
|
710
670
|
}
|
|
711
671
|
});
|
|
712
|
-
}
|
|
672
|
+
};
|
|
713
673
|
|
|
714
|
-
function
|
|
674
|
+
const withTranslation = function (ns) {
|
|
715
675
|
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
716
676
|
return function Extend(WrappedComponent) {
|
|
717
677
|
function I18nextWithTranslation(_ref) {
|
|
@@ -743,20 +703,20 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
743
703
|
}));
|
|
744
704
|
return options.withRef ? react.forwardRef(forwardRef) : I18nextWithTranslation;
|
|
745
705
|
};
|
|
746
|
-
}
|
|
706
|
+
};
|
|
747
707
|
|
|
748
|
-
|
|
749
|
-
|
|
708
|
+
const Translation = _ref => {
|
|
709
|
+
let {
|
|
750
710
|
ns,
|
|
751
711
|
children,
|
|
752
712
|
...options
|
|
753
|
-
} =
|
|
713
|
+
} = _ref;
|
|
754
714
|
const [t, i18n, ready] = useTranslation(ns, options);
|
|
755
715
|
return children(t, {
|
|
756
716
|
i18n,
|
|
757
717
|
lng: i18n.language
|
|
758
718
|
}, ready);
|
|
759
|
-
}
|
|
719
|
+
};
|
|
760
720
|
|
|
761
721
|
function I18nextProvider(_ref) {
|
|
762
722
|
let {
|
|
@@ -773,7 +733,7 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
773
733
|
}, children);
|
|
774
734
|
}
|
|
775
735
|
|
|
776
|
-
function
|
|
736
|
+
const useSSR = function (initialI18nStore, initialLanguage) {
|
|
777
737
|
let props = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
778
738
|
const {
|
|
779
739
|
i18n: i18nFromProps
|
|
@@ -782,7 +742,7 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
782
742
|
i18n: i18nFromContext
|
|
783
743
|
} = react.useContext(I18nContext) || {};
|
|
784
744
|
const i18n = i18nFromProps || i18nFromContext || getI18n();
|
|
785
|
-
if (i18n.options
|
|
745
|
+
if (i18n.options?.isClone) return;
|
|
786
746
|
if (initialI18nStore && !i18n.initializedStoreOnce) {
|
|
787
747
|
i18n.services.resourceStore.data = initialI18nStore;
|
|
788
748
|
i18n.options.ns = Object.values(initialI18nStore).reduce((mem, lngResources) => {
|
|
@@ -798,27 +758,25 @@ define(['exports', 'react'], (function (exports, react) { 'use strict';
|
|
|
798
758
|
i18n.changeLanguage(initialLanguage);
|
|
799
759
|
i18n.initializedLanguageOnce = true;
|
|
800
760
|
}
|
|
801
|
-
}
|
|
761
|
+
};
|
|
802
762
|
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
};
|
|
821
|
-
}
|
|
763
|
+
const withSSR = () => function Extend(WrappedComponent) {
|
|
764
|
+
function I18nextWithSSR(_ref) {
|
|
765
|
+
let {
|
|
766
|
+
initialI18nStore,
|
|
767
|
+
initialLanguage,
|
|
768
|
+
...rest
|
|
769
|
+
} = _ref;
|
|
770
|
+
useSSR(initialI18nStore, initialLanguage);
|
|
771
|
+
return react.createElement(WrappedComponent, {
|
|
772
|
+
...rest
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
I18nextWithSSR.getInitialProps = composeInitialProps(WrappedComponent);
|
|
776
|
+
I18nextWithSSR.displayName = `withI18nextSSR(${getDisplayName(WrappedComponent)})`;
|
|
777
|
+
I18nextWithSSR.WrappedComponent = WrappedComponent;
|
|
778
|
+
return I18nextWithSSR;
|
|
779
|
+
};
|
|
822
780
|
|
|
823
781
|
const date = () => '';
|
|
824
782
|
const time = () => '';
|