react-i18next 14.1.3 → 15.0.1
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 +11 -0
- package/dist/amd/react-i18next.js +36 -54
- package/dist/amd/react-i18next.min.js +1 -1
- package/dist/commonjs/Trans.js +2 -2
- package/dist/commonjs/TransWithoutContext.js +10 -10
- package/dist/commonjs/Translation.js +6 -5
- package/dist/commonjs/context.js +6 -4
- package/dist/commonjs/useSSR.js +1 -1
- package/dist/commonjs/useTranslation.js +6 -6
- package/dist/commonjs/utils.js +9 -29
- package/dist/es/I18nextProvider.js +5 -6
- package/dist/es/Trans.js +18 -19
- package/dist/es/TransWithoutContext.js +26 -27
- package/dist/es/Translation.js +6 -7
- package/dist/es/context.js +6 -4
- package/dist/es/defaults.js +1 -2
- package/dist/es/package.json +1 -1
- package/dist/es/useSSR.js +2 -3
- package/dist/es/useTranslation.js +7 -8
- package/dist/es/utils.js +7 -34
- package/dist/es/withSSR.js +5 -6
- package/dist/es/withTranslation.js +27 -31
- package/dist/umd/react-i18next.js +36 -54
- 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 +36 -54
- package/react-i18next.min.js +1 -1
- package/src/Trans.js +2 -3
- package/src/TransWithoutContext.js +12 -15
- package/src/Translation.js +2 -3
- package/src/context.js +6 -6
- package/src/useSSR.js +1 -1
- package/src/useTranslation.js +6 -6
- package/src/utils.js +7 -60
- package/vitest.workspace.typescript.mts +11 -0
package/react-i18next.js
CHANGED
|
@@ -118,24 +118,24 @@
|
|
|
118
118
|
}
|
|
119
119
|
};
|
|
120
120
|
|
|
121
|
-
function
|
|
122
|
-
if (console
|
|
121
|
+
const warn = function () {
|
|
122
|
+
if (console?.warn) {
|
|
123
123
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
124
124
|
args[_key] = arguments[_key];
|
|
125
125
|
}
|
|
126
126
|
if (isString(args[0])) args[0] = `react-i18next:: ${args[0]}`;
|
|
127
127
|
console.warn(...args);
|
|
128
128
|
}
|
|
129
|
-
}
|
|
129
|
+
};
|
|
130
130
|
const alreadyWarned = {};
|
|
131
|
-
function
|
|
131
|
+
const warnOnce = function () {
|
|
132
132
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
133
133
|
args[_key2] = arguments[_key2];
|
|
134
134
|
}
|
|
135
135
|
if (isString(args[0]) && alreadyWarned[args[0]]) return;
|
|
136
136
|
if (isString(args[0])) alreadyWarned[args[0]] = new Date();
|
|
137
137
|
warn(...args);
|
|
138
|
-
}
|
|
138
|
+
};
|
|
139
139
|
const loadedClb = (i18n, cb) => () => {
|
|
140
140
|
if (i18n.isInitialized) {
|
|
141
141
|
cb();
|
|
@@ -159,36 +159,16 @@
|
|
|
159
159
|
});
|
|
160
160
|
i18n.loadLanguages(lng, loadedClb(i18n, cb));
|
|
161
161
|
};
|
|
162
|
-
const oldI18nextHasLoadedNamespace = function (ns, i18n) {
|
|
163
|
-
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
164
|
-
const lng = i18n.languages[0];
|
|
165
|
-
const fallbackLng = i18n.options ? i18n.options.fallbackLng : false;
|
|
166
|
-
const lastLng = i18n.languages[i18n.languages.length - 1];
|
|
167
|
-
if (lng.toLowerCase() === 'cimode') return true;
|
|
168
|
-
const loadNotPending = (l, n) => {
|
|
169
|
-
const loadState = i18n.services.backendConnector.state[`${l}|${n}`];
|
|
170
|
-
return loadState === -1 || loadState === 2;
|
|
171
|
-
};
|
|
172
|
-
if (options.bindI18n && options.bindI18n.indexOf('languageChanging') > -1 && i18n.services.backendConnector.backend && i18n.isLanguageChangingTo && !loadNotPending(i18n.isLanguageChangingTo, ns)) return false;
|
|
173
|
-
if (i18n.hasResourceBundle(lng, ns)) return true;
|
|
174
|
-
if (!i18n.services.backendConnector.backend || i18n.options.resources && !i18n.options.partialBundledLanguages) return true;
|
|
175
|
-
if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns))) return true;
|
|
176
|
-
return false;
|
|
177
|
-
};
|
|
178
162
|
const hasLoadedNamespace = function (ns, i18n) {
|
|
179
163
|
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
180
164
|
if (!i18n.languages || !i18n.languages.length) {
|
|
181
165
|
warnOnce('i18n.languages were undefined or empty', i18n.languages);
|
|
182
166
|
return true;
|
|
183
167
|
}
|
|
184
|
-
const isNewerI18next = i18n.options.ignoreJSONStructure !== undefined;
|
|
185
|
-
if (!isNewerI18next) {
|
|
186
|
-
return oldI18nextHasLoadedNamespace(ns, i18n, options);
|
|
187
|
-
}
|
|
188
168
|
return i18n.hasLoadedNamespace(ns, {
|
|
189
169
|
lng: options.lng,
|
|
190
170
|
precheck: (i18nInstance, loadNotPending) => {
|
|
191
|
-
if (options.bindI18n
|
|
171
|
+
if (options.bindI18n?.indexOf('languageChanging') > -1 && i18nInstance.services.backendConnector.backend && i18nInstance.isLanguageChangingTo && !loadNotPending(i18nInstance.isLanguageChangingTo, ns)) return false;
|
|
192
172
|
}
|
|
193
173
|
});
|
|
194
174
|
};
|
|
@@ -249,14 +229,14 @@
|
|
|
249
229
|
|
|
250
230
|
const hasChildren = (node, checkLength) => {
|
|
251
231
|
if (!node) return false;
|
|
252
|
-
const base = node.props
|
|
232
|
+
const base = node.props?.children ?? node.children;
|
|
253
233
|
if (checkLength) return base.length > 0;
|
|
254
234
|
return !!base;
|
|
255
235
|
};
|
|
256
236
|
const getChildren = node => {
|
|
257
237
|
if (!node) return [];
|
|
258
|
-
const children = node.props
|
|
259
|
-
return node.props
|
|
238
|
+
const children = node.props?.children ?? node.children;
|
|
239
|
+
return node.props?.i18nIsDynamicList ? getAsArray(children) : children;
|
|
260
240
|
};
|
|
261
241
|
const hasValidReactChildren = children => Array.isArray(children) && children.every(react.isValidElement);
|
|
262
242
|
const getAsArray = data => Array.isArray(data) ? data : [data];
|
|
@@ -271,7 +251,7 @@
|
|
|
271
251
|
if (!children) return '';
|
|
272
252
|
let stringNode = '';
|
|
273
253
|
const childrenArray = getAsArray(children);
|
|
274
|
-
const keepArray = i18nOptions
|
|
254
|
+
const keepArray = i18nOptions?.transSupportBasicHtmlNodes ? i18nOptions.transKeepBasicHtmlNodesFor ?? [] : [];
|
|
275
255
|
childrenArray.forEach((child, childIndex) => {
|
|
276
256
|
if (isString(child)) {
|
|
277
257
|
stringNode += `${child}`;
|
|
@@ -335,7 +315,7 @@
|
|
|
335
315
|
const renderInner = (child, node, rootReactNode) => {
|
|
336
316
|
const childs = getChildren(child);
|
|
337
317
|
const mappedChildren = mapAST(childs, node.children, rootReactNode);
|
|
338
|
-
return hasValidReactChildren(childs) && mappedChildren.length === 0 || child.props
|
|
318
|
+
return hasValidReactChildren(childs) && mappedChildren.length === 0 || child.props?.i18nIsDynamicList ? childs : mappedChildren;
|
|
339
319
|
};
|
|
340
320
|
const pushTranslatedJSX = (child, inner, mem, i, isVoid) => {
|
|
341
321
|
if (child.dummy) {
|
|
@@ -361,7 +341,7 @@
|
|
|
361
341
|
const reactNodes = getAsArray(reactNode);
|
|
362
342
|
const astNodes = getAsArray(astNode);
|
|
363
343
|
return astNodes.reduce((mem, node, i) => {
|
|
364
|
-
const translationContent = node.children
|
|
344
|
+
const translationContent = node.children?.[0]?.content && i18n.services.interpolator.interpolate(node.children[0].content, opts, i18n.language);
|
|
365
345
|
if (node.type === 'tag') {
|
|
366
346
|
let tmp = reactNodes[parseInt(node.name, 10)];
|
|
367
347
|
if (rootReactNode.length === 1 && !tmp) tmp = rootReactNode[0][node.name];
|
|
@@ -454,9 +434,9 @@
|
|
|
454
434
|
const t = tFromProps || i18n.t.bind(i18n) || (k => k);
|
|
455
435
|
const reactI18nextOptions = {
|
|
456
436
|
...getDefaults(),
|
|
457
|
-
...
|
|
437
|
+
...i18n.options?.react
|
|
458
438
|
};
|
|
459
|
-
let namespaces = ns || t.ns || i18n.options
|
|
439
|
+
let namespaces = ns || t.ns || i18n.options?.defaultNS;
|
|
460
440
|
namespaces = isString(namespaces) ? [namespaces] : namespaces || ['translation'];
|
|
461
441
|
const nodeAsString = nodesToString(children, reactI18nextOptions);
|
|
462
442
|
const defaultValue = defaults || nodeAsString || reactI18nextOptions.transEmptyNodeValue || i18nKey;
|
|
@@ -464,7 +444,7 @@
|
|
|
464
444
|
hashTransKey
|
|
465
445
|
} = reactI18nextOptions;
|
|
466
446
|
const key = i18nKey || (hashTransKey ? hashTransKey(nodeAsString || defaultValue) : nodeAsString || defaultValue);
|
|
467
|
-
if (i18n.options
|
|
447
|
+
if (i18n.options?.interpolation?.defaultVariables) {
|
|
468
448
|
values = values && Object.keys(values).length > 0 ? {
|
|
469
449
|
...values,
|
|
470
450
|
...i18n.options.interpolation.defaultVariables
|
|
@@ -500,7 +480,7 @@
|
|
|
500
480
|
});
|
|
501
481
|
}
|
|
502
482
|
const content = renderNodes(components || children, translation, i18n, reactI18nextOptions, combinedTOpts, shouldUnescape);
|
|
503
|
-
const useAsParent = parent
|
|
483
|
+
const useAsParent = parent ?? reactI18nextOptions.defaultTransParent;
|
|
504
484
|
return useAsParent ? react.createElement(useAsParent, additionalProps, content) : content;
|
|
505
485
|
}
|
|
506
486
|
|
|
@@ -519,13 +499,15 @@
|
|
|
519
499
|
}
|
|
520
500
|
addUsedNamespaces(namespaces) {
|
|
521
501
|
namespaces.forEach(ns => {
|
|
522
|
-
|
|
502
|
+
this.usedNamespaces[ns] ??= true;
|
|
523
503
|
});
|
|
524
504
|
}
|
|
525
|
-
getUsedNamespaces
|
|
505
|
+
getUsedNamespaces() {
|
|
506
|
+
return Object.keys(this.usedNamespaces);
|
|
507
|
+
}
|
|
526
508
|
}
|
|
527
509
|
const composeInitialProps = ForComponent => async ctx => {
|
|
528
|
-
const componentsInitialProps =
|
|
510
|
+
const componentsInitialProps = (await ForComponent.getInitialProps?.(ctx)) ?? {};
|
|
529
511
|
const i18nInitialProps = getInitialProps();
|
|
530
512
|
return {
|
|
531
513
|
...componentsInitialProps,
|
|
@@ -534,7 +516,7 @@
|
|
|
534
516
|
};
|
|
535
517
|
const getInitialProps = () => {
|
|
536
518
|
const i18n = getI18n();
|
|
537
|
-
const namespaces = i18n.reportNamespaces
|
|
519
|
+
const namespaces = i18n.reportNamespaces?.getUsedNamespaces() ?? [];
|
|
538
520
|
const ret = {};
|
|
539
521
|
const initialI18nStore = {};
|
|
540
522
|
i18n.languages.forEach(l => {
|
|
@@ -570,7 +552,7 @@
|
|
|
570
552
|
defaultNS: defaultNSFromContext
|
|
571
553
|
} = react.useContext(I18nContext) || {};
|
|
572
554
|
const i18n = i18nFromProps || i18nFromContext || getI18n();
|
|
573
|
-
const t = tFromProps || i18n
|
|
555
|
+
const t = tFromProps || i18n?.t.bind(i18n);
|
|
574
556
|
return Trans$1({
|
|
575
557
|
children,
|
|
576
558
|
count,
|
|
@@ -581,7 +563,7 @@
|
|
|
581
563
|
values,
|
|
582
564
|
defaults,
|
|
583
565
|
components,
|
|
584
|
-
ns: ns || t
|
|
566
|
+
ns: ns || t?.ns || defaultNSFromContext || i18n?.options?.defaultNS,
|
|
585
567
|
i18n,
|
|
586
568
|
t: tFromProps,
|
|
587
569
|
shouldUnescape,
|
|
@@ -592,7 +574,7 @@
|
|
|
592
574
|
const usePrevious = (value, ignore) => {
|
|
593
575
|
const ref = react.useRef();
|
|
594
576
|
react.useEffect(() => {
|
|
595
|
-
ref.current =
|
|
577
|
+
ref.current = value;
|
|
596
578
|
}, [value, ignore]);
|
|
597
579
|
return ref.current;
|
|
598
580
|
};
|
|
@@ -622,7 +604,7 @@
|
|
|
622
604
|
retNotReady.ready = false;
|
|
623
605
|
return retNotReady;
|
|
624
606
|
}
|
|
625
|
-
if (i18n.options.react
|
|
607
|
+
if (i18n.options.react?.wait) warnOnce('It seems you are still using the old wait option, you may migrate to the new useSuspense behaviour.');
|
|
626
608
|
const i18nOptions = {
|
|
627
609
|
...getDefaults(),
|
|
628
610
|
...i18n.options.react,
|
|
@@ -632,9 +614,9 @@
|
|
|
632
614
|
useSuspense,
|
|
633
615
|
keyPrefix
|
|
634
616
|
} = i18nOptions;
|
|
635
|
-
let namespaces = ns || defaultNSFromContext || i18n.options
|
|
617
|
+
let namespaces = ns || defaultNSFromContext || i18n.options?.defaultNS;
|
|
636
618
|
namespaces = isString(namespaces) ? [namespaces] : namespaces || ['translation'];
|
|
637
|
-
|
|
619
|
+
i18n.reportNamespaces.addUsedNamespaces?.(namespaces);
|
|
638
620
|
const ready = (i18n.isInitialized || i18n.initializedStoreOnce) && namespaces.every(n => hasLoadedNamespace(n, i18n, i18nOptions));
|
|
639
621
|
const memoGetT = useMemoizedT(i18n, props.lng || null, i18nOptions.nsMode === 'fallback' ? namespaces : namespaces[0], keyPrefix);
|
|
640
622
|
const getT = () => memoGetT;
|
|
@@ -667,11 +649,11 @@
|
|
|
667
649
|
const boundReset = () => {
|
|
668
650
|
if (isMounted.current) setT(getNewT);
|
|
669
651
|
};
|
|
670
|
-
if (bindI18n
|
|
671
|
-
if (bindI18nStore
|
|
652
|
+
if (bindI18n) i18n?.on(bindI18n, boundReset);
|
|
653
|
+
if (bindI18nStore) i18n?.store.on(bindI18nStore, boundReset);
|
|
672
654
|
return () => {
|
|
673
655
|
isMounted.current = false;
|
|
674
|
-
if (
|
|
656
|
+
if (i18n) bindI18n?.split(' ').forEach(e => i18n.off(e, boundReset));
|
|
675
657
|
if (bindI18nStore && i18n) bindI18nStore.split(' ').forEach(e => i18n.store.off(e, boundReset));
|
|
676
658
|
};
|
|
677
659
|
}, [i18n, joinedNS]);
|
|
@@ -729,18 +711,18 @@
|
|
|
729
711
|
};
|
|
730
712
|
};
|
|
731
713
|
|
|
732
|
-
|
|
733
|
-
|
|
714
|
+
const Translation = _ref => {
|
|
715
|
+
let {
|
|
734
716
|
ns,
|
|
735
717
|
children,
|
|
736
718
|
...options
|
|
737
|
-
} =
|
|
719
|
+
} = _ref;
|
|
738
720
|
const [t, i18n, ready] = useTranslation(ns, options);
|
|
739
721
|
return children(t, {
|
|
740
722
|
i18n,
|
|
741
723
|
lng: i18n.language
|
|
742
724
|
}, ready);
|
|
743
|
-
}
|
|
725
|
+
};
|
|
744
726
|
|
|
745
727
|
function I18nextProvider(_ref) {
|
|
746
728
|
let {
|
|
@@ -766,7 +748,7 @@
|
|
|
766
748
|
i18n: i18nFromContext
|
|
767
749
|
} = react.useContext(I18nContext) || {};
|
|
768
750
|
const i18n = i18nFromProps || i18nFromContext || getI18n();
|
|
769
|
-
if (i18n.options
|
|
751
|
+
if (i18n.options?.isClone) return;
|
|
770
752
|
if (initialI18nStore && !i18n.initializedStoreOnce) {
|
|
771
753
|
i18n.services.resourceStore.data = initialI18nStore;
|
|
772
754
|
i18n.options.ns = Object.values(initialI18nStore).reduce((mem, lngResources) => {
|
package/react-i18next.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).ReactI18next={},e.React)}(this,(function(e,n){"use strict";function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var s=t({area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0}),i=/\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?(".*?"|'.*?')/g;function a(e){var n={type:"tag",name:"",voidElement:!1,attrs:{},children:[]},t=e.match(/<\/?([^\s]+?)[/\s>]/);if(t&&(n.name=t[1],(s[t[1]]||"/"===e.charAt(e.length-2))&&(n.voidElement=!0),n.name.startsWith("!--"))){var a=e.indexOf("--\x3e");return{type:"comment",comment:-1!==a?e.slice(4,a):""}}for(var o=new RegExp(i),r=null;null!==(r=o.exec(e));)if(r[0].trim())if(r[1]){var l=r[1].trim(),c=[l,""];l.indexOf("=")>-1&&(c=l.split("=")),n.attrs[c[0]]=c[1],o.lastIndex--}else r[2]&&(n.attrs[r[2]]=r[3].trim().substring(1,r[3].length-1));return n}var o=/<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g,r=/^\s*$/,l=Object.create(null);var c=function(e,n){n||(n={}),n.components||(n.components=l);var t,s=[],i=[],c=-1,u=!1;if(0!==e.indexOf("<")){var p=e.indexOf("<");s.push({type:"text",content:-1===p?e:e.substring(0,p)})}return e.replace(o,(function(o,l){if(u){if(o!=="</"+t.name+">")return;u=!1}var p,d="/"!==o.charAt(1),f=o.startsWith("\x3c!--"),g=l+o.length,h=e.charAt(g);if(f){var m=a(o);return c<0?(s.push(m),s):((p=i[c]).children.push(m),s)}if(d&&(c++,"tag"===(t=a(o)).type&&n.components[t.name]&&(t.type="component",u=!0),t.voidElement||u||!h||"<"===h||t.children.push({type:"text",content:e.slice(g,e.indexOf("<",g))}),0===c&&s.push(t),(p=i[c-1])&&p.children.push(t),i[c]=t),(!d||t.voidElement)&&(c>-1&&(t.voidElement||t.name===o.slice(2,-1))&&(c--,t=-1===c?s:i[c]),!u&&"<"!==h&&h)){p=-1===c?s:i[c].children;var y=e.indexOf("<",g),b=e.slice(g,-1===y?void 0:y);r.test(b)&&(b=" "),(y>-1&&c+p.length>=0||" "!==b)&&p.push({type:"text",content:b})}})),s};function u(){if(console&&console.warn){for(var e=arguments.length,n=new Array(e),t=0;t<e;t++)n[t]=arguments[t];y(n[0])&&(n[0]=`react-i18next:: ${n[0]}`),console.warn(...n)}}const p={};function d(){for(var e=arguments.length,n=new Array(e),t=0;t<e;t++)n[t]=arguments[t];y(n[0])&&p[n[0]]||(y(n[0])&&(p[n[0]]=new Date),u(...n))}const f=(e,n)=>()=>{if(e.isInitialized)n();else{const t=()=>{setTimeout((()=>{e.off("initialized",t)}),0),n()};e.on("initialized",t)}},g=(e,n,t)=>{e.loadNamespaces(n,f(e,t))},h=(e,n,t,s)=>{y(t)&&(t=[t]),t.forEach((n=>{e.options.ns.indexOf(n)<0&&e.options.ns.push(n)})),e.loadLanguages(n,f(e,s))},m=e=>e.displayName||e.name||(y(e)&&e.length>0?e:"Unknown"),y=e=>"string"==typeof e,b=e=>"object"==typeof e&&null!==e,v=/&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34|nbsp|#160|copy|#169|reg|#174|hellip|#8230|#x2F|#47);/g,x={"&":"&","&":"&","<":"<","<":"<",">":">",">":">","'":"'","'":"'",""":'"',""":'"'," ":" "," ":" ","©":"©","©":"©","®":"®","®":"®","…":"…","…":"…","/":"/","/":"/"},E=e=>x[e];let N={bindI18n:"languageChanged",bindI18nStore:"",transEmptyNodeValue:"",transSupportBasicHtmlNodes:!0,transWrapTextNodes:"",transKeepBasicHtmlNodesFor:["br","strong","i","p"],useSuspense:!0,unescape:e=>e.replace(v,E)};const O=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};N={...N,...e}},$=()=>N;let k;const w=e=>{k=e},I=()=>k,S=(e,n)=>{if(!e)return!1;const t=e.props?e.props.children:e.children;return n?t.length>0:!!t},C=e=>{if(!e)return[];const n=e.props?e.props.children:e.children;return e.props&&e.props.i18nIsDynamicList?R(n):n},R=e=>Array.isArray(e)?e:[e],j=(e,t)=>{if(!e)return"";let s="";const i=R(e),a=t.transSupportBasicHtmlNodes&&t.transKeepBasicHtmlNodesFor?t.transKeepBasicHtmlNodesFor:[];return i.forEach(((e,i)=>{if(y(e))s+=`${e}`;else if(n.isValidElement(e)){const{props:n,type:o}=e,r=Object.keys(n).length,l=a.indexOf(o)>-1,c=n.children;if(c||!l||r)if(!c&&(!l||r)||n.i18nIsDynamicList)s+=`<${i}></${i}>`;else if(l&&1===r&&y(c))s+=`<${o}>${c}</${o}>`;else{const e=j(c,t);s+=`<${i}>${e}</${i}>`}else s+=`<${o}/>`}else if(null===e)u("Trans: the passed in value is invalid - seems you passed in a null child.");else if(b(e)){const{format:n,...t}=e,i=Object.keys(t);if(1===i.length){const e=n?`${i[0]}, ${n}`:i[0];s+=`{{${e}}}`}else u("react-i18next: the passed in object contained more than one variable - the object should look like {{ value, format }} where format is optional.",e)}else u("Trans: the passed in value is invalid - seems you passed in a variable like {number} - please pass in variables for interpolation as full objects like {{number}}.",e)})),s},T=(e,t,s,i,a,o)=>{if(""===t)return[];const r=i.transKeepBasicHtmlNodesFor||[],l=t&&new RegExp(r.map((e=>`<${e}`)).join("|")).test(t);if(!e&&!l&&!o)return[t];const u={},p=e=>{R(e).forEach((e=>{y(e)||(S(e)?p(C(e)):b(e)&&!n.isValidElement(e)&&Object.assign(u,e))}))};p(e);const d=c(`<0>${t}</0>`),f={...u,...a},g=(e,t,s)=>{const i=C(e),a=m(i,t.children,s);return(e=>Array.isArray(e)&&e.every(n.isValidElement))(i)&&0===a.length||e.props&&e.props.i18nIsDynamicList?i:a},h=(e,t,s,i,a)=>{e.dummy?(e.children=t,s.push(n.cloneElement(e,{key:i},a?void 0:t))):s.push(...n.Children.map([e],(e=>{const s={...e.props};return delete s.i18nIsDynamicList,n.createElement(e.type,{...s,key:i,ref:e.ref},a?null:t)})))},m=(t,a,c)=>{const u=R(t);return R(a).reduce(((t,a,p)=>{const d=a.children&&a.children[0]&&a.children[0].content&&s.services.interpolator.interpolate(a.children[0].content,f,s.language);if("tag"===a.type){let o=u[parseInt(a.name,10)];1!==c.length||o||(o=c[0][a.name]),o||(o={});const v=0!==Object.keys(a.attrs).length?((e,n)=>{const t={...n};return t.props=Object.assign(e.props,n.props),t})({props:a.attrs},o):o,x=n.isValidElement(v),E=x&&S(a,!0)&&!a.voidElement,N=l&&b(v)&&v.dummy&&!x,O=b(e)&&Object.hasOwnProperty.call(e,a.name);if(y(v)){const e=s.services.interpolator.interpolate(v,f,s.language);t.push(e)}else if(S(v)||E){const e=g(v,a,c);h(v,e,t,p)}else if(N){const e=m(u,a.children,c);h(v,e,t,p)}else if(Number.isNaN(parseFloat(a.name)))if(O){const e=g(v,a,c);h(v,e,t,p,a.voidElement)}else if(i.transSupportBasicHtmlNodes&&r.indexOf(a.name)>-1)if(a.voidElement)t.push(n.createElement(a.name,{key:`${a.name}-${p}`}));else{const e=m(u,a.children,c);t.push(n.createElement(a.name,{key:`${a.name}-${p}`},e))}else if(a.voidElement)t.push(`<${a.name} />`);else{const e=m(u,a.children,c);t.push(`<${a.name}>${e}</${a.name}>`)}else if(b(v)&&!x){const e=a.children[0]?d:null;e&&t.push(e)}else h(v,d,t,p,1!==a.children.length||!d)}else if("text"===a.type){const e=i.transWrapTextNodes,r=o?i.unescape(s.services.interpolator.interpolate(a.content,f,s.language)):s.services.interpolator.interpolate(a.content,f,s.language);e?t.push(n.createElement(e,{key:`${a.name}-${p}`},r)):t.push(r)}return t}),[])},v=m([{dummy:!0,children:e||[]}],d,R(e||[]));return C(v[0])};function L(e){let{children:t,count:s,parent:i,i18nKey:a,context:o,tOptions:r={},values:l,defaults:c,components:u,ns:p,i18n:f,t:g,shouldUnescape:h,...m}=e;const b=f||I();if(!b)return d("You will need to pass in an i18next instance by using i18nextReactModule"),t;const v=g||b.t.bind(b)||(e=>e),x={...$(),...b.options&&b.options.react};let E=p||v.ns||b.options&&b.options.defaultNS;E=y(E)?[E]:E||["translation"];const N=j(t,x),O=c||N||x.transEmptyNodeValue||a,{hashTransKey:k}=x,w=a||(k?k(N||O):N||O);b.options&&b.options.interpolation&&b.options.interpolation.defaultVariables&&(l=l&&Object.keys(l).length>0?{...l,...b.options.interpolation.defaultVariables}:{...b.options.interpolation.defaultVariables});const S=l||void 0!==s||!t?r.interpolation:{interpolation:{...r.interpolation,prefix:"#$?",suffix:"?$#"}},C={...r,context:o||r.context,count:s,...l,...S,defaultValue:O,ns:E},R=w?v(w,C):O;u&&Object.keys(u).forEach((e=>{const t=u[e];"function"==typeof t.type||!t.props||!t.props.children||R.indexOf(`${e}/>`)<0&&R.indexOf(`${e} />`)<0||(u[e]=n.createElement((function(){return n.createElement(n.Fragment,null,t)})))}));const L=T(u||t,R,b,x,C,h),P=void 0!==i?i:x.defaultTransParent;return P?n.createElement(P,m,L):L}const P={type:"3rdParty",init(e){O(e.options.react),w(e)}},A=n.createContext();class V{constructor(){this.usedNamespaces={}}addUsedNamespaces(e){e.forEach((e=>{this.usedNamespaces[e]||(this.usedNamespaces[e]=!0)}))}getUsedNamespaces=()=>Object.keys(this.usedNamespaces)}const z=e=>async n=>({...e.getInitialProps?await e.getInitialProps(n):{},...B()}),B=()=>{const e=I(),n=e.reportNamespaces?e.reportNamespaces.getUsedNamespaces():[],t={},s={};return e.languages.forEach((t=>{s[t]={},n.forEach((n=>{s[t][n]=e.getResourceBundle(t,n)||{}}))})),t.initialI18nStore=s,t.initialLanguage=e.language,t};const F=(e,n,t,s)=>e.getFixedT(n,t,s),U=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const{i18n:s}=t,{i18n:i,defaultNS:a}=n.useContext(A)||{},o=s||i||I();if(o&&!o.reportNamespaces&&(o.reportNamespaces=new V),!o){d("You will need to pass in an i18next instance by using initReactI18next");const e=(e,n)=>y(n)?n:b(n)&&y(n.defaultValue)?n.defaultValue:Array.isArray(e)?e[e.length-1]:e,n=[e,{},!1];return n.t=e,n.i18n={},n.ready=!1,n}o.options.react&&void 0!==o.options.react.wait&&d("It seems you are still using the old wait option, you may migrate to the new useSuspense behaviour.");const r={...$(),...o.options.react,...t},{useSuspense:l,keyPrefix:c}=r;let u=e||a||o.options&&o.options.defaultNS;u=y(u)?[u]:u||["translation"],o.reportNamespaces.addUsedNamespaces&&o.reportNamespaces.addUsedNamespaces(u);const p=(o.isInitialized||o.initializedStoreOnce)&&u.every((e=>function(e,n){let t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return n.languages&&n.languages.length?void 0!==n.options.ignoreJSONStructure?n.hasLoadedNamespace(e,{lng:t.lng,precheck:(n,s)=>{if(t.bindI18n&&t.bindI18n.indexOf("languageChanging")>-1&&n.services.backendConnector.backend&&n.isLanguageChangingTo&&!s(n.isLanguageChangingTo,e))return!1}}):function(e,n){let t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const s=n.languages[0],i=!!n.options&&n.options.fallbackLng,a=n.languages[n.languages.length-1];if("cimode"===s.toLowerCase())return!0;const o=(e,t)=>{const s=n.services.backendConnector.state[`${e}|${t}`];return-1===s||2===s};return!(t.bindI18n&&t.bindI18n.indexOf("languageChanging")>-1&&n.services.backendConnector.backend&&n.isLanguageChangingTo&&!o(n.isLanguageChangingTo,e)||!n.hasResourceBundle(s,e)&&n.services.backendConnector.backend&&(!n.options.resources||n.options.partialBundledLanguages)&&(!o(s,e)||i&&!o(a,e)))}(e,n,t):(d("i18n.languages were undefined or empty",n.languages),!0)}(e,o,r))),f=((e,t,s,i)=>n.useCallback(F(e,t,s,i),[e,t,s,i]))(o,t.lng||null,"fallback"===r.nsMode?u:u[0],c),m=()=>f,v=()=>F(o,t.lng||null,"fallback"===r.nsMode?u:u[0],c),[x,E]=n.useState(m);let N=u.join();t.lng&&(N=`${t.lng}${N}`);const O=((e,t)=>{const s=n.useRef();return n.useEffect((()=>{s.current=t?s.current:e}),[e,t]),s.current})(N),k=n.useRef(!0);n.useEffect((()=>{const{bindI18n:e,bindI18nStore:n}=r;k.current=!0,p||l||(t.lng?h(o,t.lng,u,(()=>{k.current&&E(v)})):g(o,u,(()=>{k.current&&E(v)}))),p&&O&&O!==N&&k.current&&E(v);const s=()=>{k.current&&E(v)};return e&&o&&o.on(e,s),n&&o&&o.store.on(n,s),()=>{k.current=!1,e&&o&&e.split(" ").forEach((e=>o.off(e,s))),n&&o&&n.split(" ").forEach((e=>o.store.off(e,s)))}}),[o,N]),n.useEffect((()=>{k.current&&p&&E(m)}),[o,c,p]);const w=[x,o,p];if(w.t=x,w.i18n=o,w.ready=p,p)return w;if(!p&&!l)return w;throw new Promise((e=>{t.lng?h(o,t.lng,u,(()=>e())):g(o,u,(()=>e()))}))};const K=function(e,t){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const{i18n:i}=s,{i18n:a}=n.useContext(A)||{},o=i||a||I();o.options&&o.options.isClone||(e&&!o.initializedStoreOnce&&(o.services.resourceStore.data=e,o.options.ns=Object.values(e).reduce(((e,n)=>(Object.keys(n).forEach((n=>{e.indexOf(n)<0&&e.push(n)})),e)),o.options.ns),o.initializedStoreOnce=!0,o.isInitialized=!0),t&&!o.initializedLanguageOnce&&(o.changeLanguage(t),o.initializedLanguageOnce=!0))};e.I18nContext=A,e.I18nextProvider=function(e){let{i18n:t,defaultNS:s,children:i}=e;const a=n.useMemo((()=>({i18n:t,defaultNS:s})),[t,s]);return n.createElement(A.Provider,{value:a},i)},e.Trans=function(e){let{children:t,count:s,parent:i,i18nKey:a,context:o,tOptions:r={},values:l,defaults:c,components:u,ns:p,i18n:d,t:f,shouldUnescape:g,...h}=e;const{i18n:m,defaultNS:y}=n.useContext(A)||{},b=d||m||I(),v=f||b&&b.t.bind(b);return L({children:t,count:s,parent:i,i18nKey:a,context:o,tOptions:r,values:l,defaults:c,components:u,ns:p||v&&v.ns||y||b&&b.options&&b.options.defaultNS,i18n:b,t:f,shouldUnescape:g,...h})},e.TransWithoutContext=L,e.Translation=function(e){const{ns:n,children:t,...s}=e,[i,a,o]=U(n,s);return t(i,{i18n:a,lng:a.language},o)},e.composeInitialProps=z,e.date=()=>"",e.getDefaults=$,e.getI18n=I,e.getInitialProps=B,e.initReactI18next=P,e.number=()=>"",e.plural=()=>"",e.select=()=>"",e.selectOrdinal=()=>"",e.setDefaults=O,e.setI18n=w,e.time=()=>"",e.useSSR=K,e.useTranslation=U,e.withSSR=()=>function(e){function t(t){let{initialI18nStore:s,initialLanguage:i,...a}=t;return K(s,i),n.createElement(e,{...a})}return t.getInitialProps=z(e),t.displayName=`withI18nextSSR(${m(e)})`,t.WrappedComponent=e,t},e.withTranslation=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return function(s){function i(i){let{forwardedRef:a,...o}=i;const[r,l,c]=U(e,{...o,keyPrefix:t.keyPrefix}),u={...o,t:r,i18n:l,tReady:c};return t.withRef&&a?u.ref=a:!t.withRef&&a&&(u.forwardedRef=a),n.createElement(s,u)}i.displayName=`withI18nextTranslation(${m(s)})`,i.WrappedComponent=s;return t.withRef?n.forwardRef(((e,t)=>n.createElement(i,Object.assign({},e,{forwardedRef:t})))):i}}}));
|
|
1
|
+
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).ReactI18next={},e.React)}(this,(function(e,n){"use strict";function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var s=t({area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0}),i=/\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?(".*?"|'.*?')/g;function a(e){var n={type:"tag",name:"",voidElement:!1,attrs:{},children:[]},t=e.match(/<\/?([^\s]+?)[/\s>]/);if(t&&(n.name=t[1],(s[t[1]]||"/"===e.charAt(e.length-2))&&(n.voidElement=!0),n.name.startsWith("!--"))){var a=e.indexOf("--\x3e");return{type:"comment",comment:-1!==a?e.slice(4,a):""}}for(var r=new RegExp(i),o=null;null!==(o=r.exec(e));)if(o[0].trim())if(o[1]){var l=o[1].trim(),c=[l,""];l.indexOf("=")>-1&&(c=l.split("=")),n.attrs[c[0]]=c[1],r.lastIndex--}else o[2]&&(n.attrs[o[2]]=o[3].trim().substring(1,o[3].length-1));return n}var r=/<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g,o=/^\s*$/,l=Object.create(null);var c=function(e,n){n||(n={}),n.components||(n.components=l);var t,s=[],i=[],c=-1,u=!1;if(0!==e.indexOf("<")){var p=e.indexOf("<");s.push({type:"text",content:-1===p?e:e.substring(0,p)})}return e.replace(r,(function(r,l){if(u){if(r!=="</"+t.name+">")return;u=!1}var p,d="/"!==r.charAt(1),f=r.startsWith("\x3c!--"),h=l+r.length,m=e.charAt(h);if(f){var g=a(r);return c<0?(s.push(g),s):((p=i[c]).children.push(g),s)}if(d&&(c++,"tag"===(t=a(r)).type&&n.components[t.name]&&(t.type="component",u=!0),t.voidElement||u||!m||"<"===m||t.children.push({type:"text",content:e.slice(h,e.indexOf("<",h))}),0===c&&s.push(t),(p=i[c-1])&&p.children.push(t),i[c]=t),(!d||t.voidElement)&&(c>-1&&(t.voidElement||t.name===r.slice(2,-1))&&(c--,t=-1===c?s:i[c]),!u&&"<"!==m&&m)){p=-1===c?s:i[c].children;var y=e.indexOf("<",h),x=e.slice(h,-1===y?void 0:y);o.test(x)&&(x=" "),(y>-1&&c+p.length>=0||" "!==x)&&p.push({type:"text",content:x})}})),s};const u=function(){if(console?.warn){for(var e=arguments.length,n=new Array(e),t=0;t<e;t++)n[t]=arguments[t];y(n[0])&&(n[0]=`react-i18next:: ${n[0]}`),console.warn(...n)}},p={},d=function(){for(var e=arguments.length,n=new Array(e),t=0;t<e;t++)n[t]=arguments[t];y(n[0])&&p[n[0]]||(y(n[0])&&(p[n[0]]=new Date),u(...n))},f=(e,n)=>()=>{if(e.isInitialized)n();else{const t=()=>{setTimeout((()=>{e.off("initialized",t)}),0),n()};e.on("initialized",t)}},h=(e,n,t)=>{e.loadNamespaces(n,f(e,t))},m=(e,n,t,s)=>{y(t)&&(t=[t]),t.forEach((n=>{e.options.ns.indexOf(n)<0&&e.options.ns.push(n)})),e.loadLanguages(n,f(e,s))},g=e=>e.displayName||e.name||(y(e)&&e.length>0?e:"Unknown"),y=e=>"string"==typeof e,x=e=>"object"==typeof e&&null!==e,b=/&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34|nbsp|#160|copy|#169|reg|#174|hellip|#8230|#x2F|#47);/g,v={"&":"&","&":"&","<":"<","<":"<",">":">",">":">","'":"'","'":"'",""":'"',""":'"'," ":" "," ":" ","©":"©","©":"©","®":"®","®":"®","…":"…","…":"…","/":"/","/":"/"},E=e=>v[e];let O={bindI18n:"languageChanged",bindI18nStore:"",transEmptyNodeValue:"",transSupportBasicHtmlNodes:!0,transWrapTextNodes:"",transKeepBasicHtmlNodesFor:["br","strong","i","p"],useSuspense:!0,unescape:e=>e.replace(b,E)};const N=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};O={...O,...e}},$=()=>O;let w;const I=e=>{w=e},k=()=>w,S=(e,n)=>{if(!e)return!1;const t=e.props?.children??e.children;return n?t.length>0:!!t},j=e=>{if(!e)return[];const n=e.props?.children??e.children;return e.props?.i18nIsDynamicList?R(n):n},R=e=>Array.isArray(e)?e:[e],T=(e,t)=>{if(!e)return"";let s="";const i=R(e),a=t?.transSupportBasicHtmlNodes?t.transKeepBasicHtmlNodesFor??[]:[];return i.forEach(((e,i)=>{if(y(e))s+=`${e}`;else if(n.isValidElement(e)){const{props:n,type:r}=e,o=Object.keys(n).length,l=a.indexOf(r)>-1,c=n.children;if(c||!l||o)if(!c&&(!l||o)||n.i18nIsDynamicList)s+=`<${i}></${i}>`;else if(l&&1===o&&y(c))s+=`<${r}>${c}</${r}>`;else{const e=T(c,t);s+=`<${i}>${e}</${i}>`}else s+=`<${r}/>`}else if(null===e)u("Trans: the passed in value is invalid - seems you passed in a null child.");else if(x(e)){const{format:n,...t}=e,i=Object.keys(t);if(1===i.length){const e=n?`${i[0]}, ${n}`:i[0];s+=`{{${e}}}`}else u("react-i18next: the passed in object contained more than one variable - the object should look like {{ value, format }} where format is optional.",e)}else u("Trans: the passed in value is invalid - seems you passed in a variable like {number} - please pass in variables for interpolation as full objects like {{number}}.",e)})),s},C=(e,t,s,i,a,r)=>{if(""===t)return[];const o=i.transKeepBasicHtmlNodesFor||[],l=t&&new RegExp(o.map((e=>`<${e}`)).join("|")).test(t);if(!e&&!l&&!r)return[t];const u={},p=e=>{R(e).forEach((e=>{y(e)||(S(e)?p(j(e)):x(e)&&!n.isValidElement(e)&&Object.assign(u,e))}))};p(e);const d=c(`<0>${t}</0>`),f={...u,...a},h=(e,t,s)=>{const i=j(e),a=g(i,t.children,s);return(e=>Array.isArray(e)&&e.every(n.isValidElement))(i)&&0===a.length||e.props?.i18nIsDynamicList?i:a},m=(e,t,s,i,a)=>{e.dummy?(e.children=t,s.push(n.cloneElement(e,{key:i},a?void 0:t))):s.push(...n.Children.map([e],(e=>{const s={...e.props};return delete s.i18nIsDynamicList,n.createElement(e.type,{...s,key:i,ref:e.ref},a?null:t)})))},g=(t,a,c)=>{const u=R(t);return R(a).reduce(((t,a,p)=>{const d=a.children?.[0]?.content&&s.services.interpolator.interpolate(a.children[0].content,f,s.language);if("tag"===a.type){let r=u[parseInt(a.name,10)];1!==c.length||r||(r=c[0][a.name]),r||(r={});const b=0!==Object.keys(a.attrs).length?((e,n)=>{const t={...n};return t.props=Object.assign(e.props,n.props),t})({props:a.attrs},r):r,v=n.isValidElement(b),E=v&&S(a,!0)&&!a.voidElement,O=l&&x(b)&&b.dummy&&!v,N=x(e)&&Object.hasOwnProperty.call(e,a.name);if(y(b)){const e=s.services.interpolator.interpolate(b,f,s.language);t.push(e)}else if(S(b)||E){const e=h(b,a,c);m(b,e,t,p)}else if(O){const e=g(u,a.children,c);m(b,e,t,p)}else if(Number.isNaN(parseFloat(a.name)))if(N){const e=h(b,a,c);m(b,e,t,p,a.voidElement)}else if(i.transSupportBasicHtmlNodes&&o.indexOf(a.name)>-1)if(a.voidElement)t.push(n.createElement(a.name,{key:`${a.name}-${p}`}));else{const e=g(u,a.children,c);t.push(n.createElement(a.name,{key:`${a.name}-${p}`},e))}else if(a.voidElement)t.push(`<${a.name} />`);else{const e=g(u,a.children,c);t.push(`<${a.name}>${e}</${a.name}>`)}else if(x(b)&&!v){const e=a.children[0]?d:null;e&&t.push(e)}else m(b,d,t,p,1!==a.children.length||!d)}else if("text"===a.type){const e=i.transWrapTextNodes,o=r?i.unescape(s.services.interpolator.interpolate(a.content,f,s.language)):s.services.interpolator.interpolate(a.content,f,s.language);e?t.push(n.createElement(e,{key:`${a.name}-${p}`},o)):t.push(o)}return t}),[])},b=g([{dummy:!0,children:e||[]}],d,R(e||[]));return j(b[0])};function P(e){let{children:t,count:s,parent:i,i18nKey:a,context:r,tOptions:o={},values:l,defaults:c,components:u,ns:p,i18n:f,t:h,shouldUnescape:m,...g}=e;const x=f||k();if(!x)return d("You will need to pass in an i18next instance by using i18nextReactModule"),t;const b=h||x.t.bind(x)||(e=>e),v={...$(),...x.options?.react};let E=p||b.ns||x.options?.defaultNS;E=y(E)?[E]:E||["translation"];const O=T(t,v),N=c||O||v.transEmptyNodeValue||a,{hashTransKey:w}=v,I=a||(w?w(O||N):O||N);x.options?.interpolation?.defaultVariables&&(l=l&&Object.keys(l).length>0?{...l,...x.options.interpolation.defaultVariables}:{...x.options.interpolation.defaultVariables});const S=l||void 0!==s||!t?o.interpolation:{interpolation:{...o.interpolation,prefix:"#$?",suffix:"?$#"}},j={...o,context:r||o.context,count:s,...l,...S,defaultValue:N,ns:E},R=I?b(I,j):N;u&&Object.keys(u).forEach((e=>{const t=u[e];"function"==typeof t.type||!t.props||!t.props.children||R.indexOf(`${e}/>`)<0&&R.indexOf(`${e} />`)<0||(u[e]=n.createElement((function(){return n.createElement(n.Fragment,null,t)})))}));const P=C(u||t,R,x,v,j,m),L=i??v.defaultTransParent;return L?n.createElement(L,g,P):P}const L={type:"3rdParty",init(e){N(e.options.react),I(e)}},A=n.createContext();class V{constructor(){this.usedNamespaces={}}addUsedNamespaces(e){e.forEach((e=>{this.usedNamespaces[e]??=!0}))}getUsedNamespaces(){return Object.keys(this.usedNamespaces)}}const z=e=>async n=>({...await(e.getInitialProps?.(n))??{},...F()}),F=()=>{const e=k(),n=e.reportNamespaces?.getUsedNamespaces()??[],t={},s={};return e.languages.forEach((t=>{s[t]={},n.forEach((n=>{s[t][n]=e.getResourceBundle(t,n)||{}}))})),t.initialI18nStore=s,t.initialLanguage=e.language,t};const U=(e,n,t,s)=>e.getFixedT(n,t,s),B=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const{i18n:s}=t,{i18n:i,defaultNS:a}=n.useContext(A)||{},r=s||i||k();if(r&&!r.reportNamespaces&&(r.reportNamespaces=new V),!r){d("You will need to pass in an i18next instance by using initReactI18next");const e=(e,n)=>y(n)?n:x(n)&&y(n.defaultValue)?n.defaultValue:Array.isArray(e)?e[e.length-1]:e,n=[e,{},!1];return n.t=e,n.i18n={},n.ready=!1,n}r.options.react?.wait&&d("It seems you are still using the old wait option, you may migrate to the new useSuspense behaviour.");const o={...$(),...r.options.react,...t},{useSuspense:l,keyPrefix:c}=o;let u=e||a||r.options?.defaultNS;u=y(u)?[u]:u||["translation"],r.reportNamespaces.addUsedNamespaces?.(u);const p=(r.isInitialized||r.initializedStoreOnce)&&u.every((e=>function(e,n){let t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return n.languages&&n.languages.length?n.hasLoadedNamespace(e,{lng:t.lng,precheck:(n,s)=>{if(t.bindI18n?.indexOf("languageChanging")>-1&&n.services.backendConnector.backend&&n.isLanguageChangingTo&&!s(n.isLanguageChangingTo,e))return!1}}):(d("i18n.languages were undefined or empty",n.languages),!0)}(e,r,o))),f=((e,t,s,i)=>n.useCallback(U(e,t,s,i),[e,t,s,i]))(r,t.lng||null,"fallback"===o.nsMode?u:u[0],c),g=()=>f,b=()=>U(r,t.lng||null,"fallback"===o.nsMode?u:u[0],c),[v,E]=n.useState(g);let O=u.join();t.lng&&(O=`${t.lng}${O}`);const N=((e,t)=>{const s=n.useRef();return n.useEffect((()=>{s.current=e}),[e,t]),s.current})(O),w=n.useRef(!0);n.useEffect((()=>{const{bindI18n:e,bindI18nStore:n}=o;w.current=!0,p||l||(t.lng?m(r,t.lng,u,(()=>{w.current&&E(b)})):h(r,u,(()=>{w.current&&E(b)}))),p&&N&&N!==O&&w.current&&E(b);const s=()=>{w.current&&E(b)};return e&&r?.on(e,s),n&&r?.store.on(n,s),()=>{w.current=!1,r&&e?.split(" ").forEach((e=>r.off(e,s))),n&&r&&n.split(" ").forEach((e=>r.store.off(e,s)))}}),[r,O]),n.useEffect((()=>{w.current&&p&&E(g)}),[r,c,p]);const I=[v,r,p];if(I.t=v,I.i18n=r,I.ready=p,p)return I;if(!p&&!l)return I;throw new Promise((e=>{t.lng?m(r,t.lng,u,(()=>e())):h(r,u,(()=>e()))}))};const D=function(e,t){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const{i18n:i}=s,{i18n:a}=n.useContext(A)||{},r=i||a||k();r.options?.isClone||(e&&!r.initializedStoreOnce&&(r.services.resourceStore.data=e,r.options.ns=Object.values(e).reduce(((e,n)=>(Object.keys(n).forEach((n=>{e.indexOf(n)<0&&e.push(n)})),e)),r.options.ns),r.initializedStoreOnce=!0,r.isInitialized=!0),t&&!r.initializedLanguageOnce&&(r.changeLanguage(t),r.initializedLanguageOnce=!0))};e.I18nContext=A,e.I18nextProvider=function(e){let{i18n:t,defaultNS:s,children:i}=e;const a=n.useMemo((()=>({i18n:t,defaultNS:s})),[t,s]);return n.createElement(A.Provider,{value:a},i)},e.Trans=function(e){let{children:t,count:s,parent:i,i18nKey:a,context:r,tOptions:o={},values:l,defaults:c,components:u,ns:p,i18n:d,t:f,shouldUnescape:h,...m}=e;const{i18n:g,defaultNS:y}=n.useContext(A)||{},x=d||g||k(),b=f||x?.t.bind(x);return P({children:t,count:s,parent:i,i18nKey:a,context:r,tOptions:o,values:l,defaults:c,components:u,ns:p||b?.ns||y||x?.options?.defaultNS,i18n:x,t:f,shouldUnescape:h,...m})},e.TransWithoutContext=P,e.Translation=e=>{let{ns:n,children:t,...s}=e;const[i,a,r]=B(n,s);return t(i,{i18n:a,lng:a.language},r)},e.composeInitialProps=z,e.date=()=>"",e.getDefaults=$,e.getI18n=k,e.getInitialProps=F,e.initReactI18next=L,e.number=()=>"",e.plural=()=>"",e.select=()=>"",e.selectOrdinal=()=>"",e.setDefaults=N,e.setI18n=I,e.time=()=>"",e.useSSR=D,e.useTranslation=B,e.withSSR=()=>function(e){function t(t){let{initialI18nStore:s,initialLanguage:i,...a}=t;return D(s,i),n.createElement(e,{...a})}return t.getInitialProps=z(e),t.displayName=`withI18nextSSR(${g(e)})`,t.WrappedComponent=e,t},e.withTranslation=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return function(s){function i(i){let{forwardedRef:a,...r}=i;const[o,l,c]=B(e,{...r,keyPrefix:t.keyPrefix}),u={...r,t:o,i18n:l,tReady:c};return t.withRef&&a?u.ref=a:!t.withRef&&a&&(u.forwardedRef=a),n.createElement(s,u)}i.displayName=`withI18nextTranslation(${g(s)})`,i.WrappedComponent=s;return t.withRef?n.forwardRef(((e,t)=>n.createElement(i,Object.assign({},e,{forwardedRef:t})))):i}}}));
|
package/src/Trans.js
CHANGED
|
@@ -23,7 +23,7 @@ export function Trans({
|
|
|
23
23
|
const { i18n: i18nFromContext, defaultNS: defaultNSFromContext } = useContext(I18nContext) || {};
|
|
24
24
|
const i18n = i18nFromProps || i18nFromContext || getI18n();
|
|
25
25
|
|
|
26
|
-
const t = tFromProps ||
|
|
26
|
+
const t = tFromProps || i18n?.t.bind(i18n);
|
|
27
27
|
|
|
28
28
|
return TransWithoutContext({
|
|
29
29
|
children,
|
|
@@ -36,8 +36,7 @@ export function Trans({
|
|
|
36
36
|
defaults,
|
|
37
37
|
components,
|
|
38
38
|
// prepare having a namespace
|
|
39
|
-
ns:
|
|
40
|
-
ns || (t && t.ns) || defaultNSFromContext || (i18n && i18n.options && i18n.options.defaultNS),
|
|
39
|
+
ns: ns || t?.ns || defaultNSFromContext || i18n?.options?.defaultNS,
|
|
41
40
|
i18n,
|
|
42
41
|
t: tFromProps,
|
|
43
42
|
shouldUnescape,
|
|
@@ -6,15 +6,15 @@ import { getI18n } from './i18nInstance.js';
|
|
|
6
6
|
|
|
7
7
|
const hasChildren = (node, checkLength) => {
|
|
8
8
|
if (!node) return false;
|
|
9
|
-
const base = node.props
|
|
9
|
+
const base = node.props?.children ?? node.children;
|
|
10
10
|
if (checkLength) return base.length > 0;
|
|
11
11
|
return !!base;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
const getChildren = (node) => {
|
|
15
15
|
if (!node) return [];
|
|
16
|
-
const children = node.props
|
|
17
|
-
return node.props
|
|
16
|
+
const children = node.props?.children ?? node.children;
|
|
17
|
+
return node.props?.i18nIsDynamicList ? getAsArray(children) : children;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
const hasValidReactChildren = (children) =>
|
|
@@ -35,10 +35,9 @@ export const nodesToString = (children, i18nOptions) => {
|
|
|
35
35
|
|
|
36
36
|
// do not use `React.Children.toArray`, will fail at object children
|
|
37
37
|
const childrenArray = getAsArray(children);
|
|
38
|
-
const keepArray =
|
|
39
|
-
i18nOptions.
|
|
40
|
-
|
|
41
|
-
: [];
|
|
38
|
+
const keepArray = i18nOptions?.transSupportBasicHtmlNodes
|
|
39
|
+
? (i18nOptions.transKeepBasicHtmlNodesFor ?? [])
|
|
40
|
+
: [];
|
|
42
41
|
|
|
43
42
|
// e.g. lorem <br/> ipsum {{ messageCount, format }} dolor <strong>bold</strong> amet
|
|
44
43
|
childrenArray.forEach((child, childIndex) => {
|
|
@@ -141,7 +140,7 @@ const renderNodes = (children, targetString, i18n, i18nOptions, combinedTOpts, s
|
|
|
141
140
|
// `mappedChildren` will always be empty if using the `i18nIsDynamicList` prop,
|
|
142
141
|
// but the children might not necessarily be react components
|
|
143
142
|
return (hasValidReactChildren(childs) && mappedChildren.length === 0) ||
|
|
144
|
-
|
|
143
|
+
child.props?.i18nIsDynamicList
|
|
145
144
|
? childs
|
|
146
145
|
: mappedChildren;
|
|
147
146
|
};
|
|
@@ -179,9 +178,7 @@ const renderNodes = (children, targetString, i18n, i18nOptions, combinedTOpts, s
|
|
|
179
178
|
|
|
180
179
|
return astNodes.reduce((mem, node, i) => {
|
|
181
180
|
const translationContent =
|
|
182
|
-
node.children &&
|
|
183
|
-
node.children[0] &&
|
|
184
|
-
node.children[0].content &&
|
|
181
|
+
node.children?.[0]?.content &&
|
|
185
182
|
i18n.services.interpolator.interpolate(node.children[0].content, opts, i18n.language);
|
|
186
183
|
|
|
187
184
|
if (node.type === 'tag') {
|
|
@@ -326,10 +323,10 @@ export function Trans({
|
|
|
326
323
|
|
|
327
324
|
const t = tFromProps || i18n.t.bind(i18n) || ((k) => k);
|
|
328
325
|
|
|
329
|
-
const reactI18nextOptions = { ...getDefaults(), ...
|
|
326
|
+
const reactI18nextOptions = { ...getDefaults(), ...i18n.options?.react };
|
|
330
327
|
|
|
331
328
|
// prepare having a namespace
|
|
332
|
-
let namespaces = ns || t.ns ||
|
|
329
|
+
let namespaces = ns || t.ns || i18n.options?.defaultNS;
|
|
333
330
|
namespaces = isString(namespaces) ? [namespaces] : namespaces || ['translation'];
|
|
334
331
|
|
|
335
332
|
const nodeAsString = nodesToString(children, reactI18nextOptions);
|
|
@@ -339,7 +336,7 @@ export function Trans({
|
|
|
339
336
|
const key =
|
|
340
337
|
i18nKey ||
|
|
341
338
|
(hashTransKey ? hashTransKey(nodeAsString || defaultValue) : nodeAsString || defaultValue);
|
|
342
|
-
if (i18n.options
|
|
339
|
+
if (i18n.options?.interpolation?.defaultVariables) {
|
|
343
340
|
// eslint-disable-next-line no-param-reassign
|
|
344
341
|
values =
|
|
345
342
|
values && Object.keys(values).length > 0
|
|
@@ -393,7 +390,7 @@ export function Trans({
|
|
|
393
390
|
|
|
394
391
|
// allows user to pass `null` to `parent`
|
|
395
392
|
// and override `defaultTransParent` if is present
|
|
396
|
-
const useAsParent = parent
|
|
393
|
+
const useAsParent = parent ?? reactI18nextOptions.defaultTransParent;
|
|
397
394
|
|
|
398
395
|
return useAsParent ? createElement(useAsParent, additionalProps, content) : content;
|
|
399
396
|
}
|
package/src/Translation.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { useTranslation } from './useTranslation.js';
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
const { ns, children, ...options } = props;
|
|
3
|
+
export const Translation = ({ ns, children, ...options }) => {
|
|
5
4
|
const [t, i18n, ready] = useTranslation(ns, options);
|
|
6
5
|
|
|
7
6
|
return children(
|
|
@@ -12,4 +11,4 @@ export function Translation(props) {
|
|
|
12
11
|
},
|
|
13
12
|
ready,
|
|
14
13
|
);
|
|
15
|
-
}
|
|
14
|
+
};
|
package/src/context.js
CHANGED
|
@@ -14,17 +14,17 @@ export class ReportNamespaces {
|
|
|
14
14
|
|
|
15
15
|
addUsedNamespaces(namespaces) {
|
|
16
16
|
namespaces.forEach((ns) => {
|
|
17
|
-
|
|
17
|
+
this.usedNamespaces[ns] ??= true;
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
getUsedNamespaces
|
|
21
|
+
getUsedNamespaces() {
|
|
22
|
+
return Object.keys(this.usedNamespaces);
|
|
23
|
+
}
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
export const composeInitialProps = (ForComponent) => async (ctx) => {
|
|
25
|
-
const componentsInitialProps = ForComponent.getInitialProps
|
|
26
|
-
? await ForComponent.getInitialProps(ctx)
|
|
27
|
-
: {};
|
|
27
|
+
const componentsInitialProps = (await ForComponent.getInitialProps?.(ctx)) ?? {};
|
|
28
28
|
|
|
29
29
|
const i18nInitialProps = getInitialProps();
|
|
30
30
|
|
|
@@ -36,7 +36,7 @@ export const composeInitialProps = (ForComponent) => async (ctx) => {
|
|
|
36
36
|
|
|
37
37
|
export const getInitialProps = () => {
|
|
38
38
|
const i18n = getI18n();
|
|
39
|
-
const namespaces = i18n.reportNamespaces
|
|
39
|
+
const namespaces = i18n.reportNamespaces?.getUsedNamespaces() ?? [];
|
|
40
40
|
|
|
41
41
|
const ret = {};
|
|
42
42
|
const initialI18nStore = {};
|
package/src/useSSR.js
CHANGED
|
@@ -8,7 +8,7 @@ export const useSSR = (initialI18nStore, initialLanguage, props = {}) => {
|
|
|
8
8
|
|
|
9
9
|
// opt out if is a cloned instance, eg. created by i18next-http-middleware on request
|
|
10
10
|
// -> do not set initial stuff on server side
|
|
11
|
-
if (i18n.options
|
|
11
|
+
if (i18n.options?.isClone) return;
|
|
12
12
|
|
|
13
13
|
// nextjs / SSR: getting data from next.js or other ssr stack
|
|
14
14
|
if (initialI18nStore && !i18n.initializedStoreOnce) {
|
package/src/useTranslation.js
CHANGED
|
@@ -49,7 +49,7 @@ export const useTranslation = (ns, props = {}) => {
|
|
|
49
49
|
return retNotReady;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
if (i18n.options.react
|
|
52
|
+
if (i18n.options.react?.wait)
|
|
53
53
|
warnOnce(
|
|
54
54
|
'It seems you are still using the old wait option, you may migrate to the new useSuspense behaviour.',
|
|
55
55
|
);
|
|
@@ -58,11 +58,11 @@ export const useTranslation = (ns, props = {}) => {
|
|
|
58
58
|
const { useSuspense, keyPrefix } = i18nOptions;
|
|
59
59
|
|
|
60
60
|
// prepare having a namespace
|
|
61
|
-
let namespaces = ns || defaultNSFromContext ||
|
|
61
|
+
let namespaces = ns || defaultNSFromContext || i18n.options?.defaultNS;
|
|
62
62
|
namespaces = isString(namespaces) ? [namespaces] : namespaces || ['translation'];
|
|
63
63
|
|
|
64
64
|
// report namespaces as used
|
|
65
|
-
|
|
65
|
+
i18n.reportNamespaces.addUsedNamespaces?.(namespaces);
|
|
66
66
|
|
|
67
67
|
// are we ready? yes if all namespaces in first language are loaded already (either with data or empty object on failed load)
|
|
68
68
|
const ready =
|
|
@@ -120,13 +120,13 @@ export const useTranslation = (ns, props = {}) => {
|
|
|
120
120
|
};
|
|
121
121
|
|
|
122
122
|
// bind events to trigger change, like languageChanged
|
|
123
|
-
if (bindI18n
|
|
124
|
-
if (bindI18nStore
|
|
123
|
+
if (bindI18n) i18n?.on(bindI18n, boundReset);
|
|
124
|
+
if (bindI18nStore) i18n?.store.on(bindI18nStore, boundReset);
|
|
125
125
|
|
|
126
126
|
// unbinding on unmount
|
|
127
127
|
return () => {
|
|
128
128
|
isMounted.current = false;
|
|
129
|
-
if (
|
|
129
|
+
if (i18n) bindI18n?.split(' ').forEach((e) => i18n.off(e, boundReset));
|
|
130
130
|
if (bindI18nStore && i18n)
|
|
131
131
|
bindI18nStore.split(' ').forEach((e) => i18n.store.off(e, boundReset));
|
|
132
132
|
};
|
package/src/utils.js
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
if (console && console.warn) {
|
|
1
|
+
export const warn = (...args) => {
|
|
2
|
+
if (console?.warn) {
|
|
4
3
|
if (isString(args[0])) args[0] = `react-i18next:: ${args[0]}`;
|
|
5
4
|
console.warn(...args);
|
|
6
5
|
}
|
|
7
|
-
}
|
|
6
|
+
};
|
|
8
7
|
|
|
9
8
|
const alreadyWarned = {};
|
|
10
|
-
|
|
11
|
-
export function warnOnce(...args) {
|
|
9
|
+
export const warnOnce = (...args) => {
|
|
12
10
|
if (isString(args[0]) && alreadyWarned[args[0]]) return;
|
|
13
11
|
if (isString(args[0])) alreadyWarned[args[0]] = new Date();
|
|
14
12
|
warn(...args);
|
|
15
|
-
}
|
|
13
|
+
};
|
|
16
14
|
|
|
17
15
|
// not needed right now
|
|
18
16
|
//
|
|
19
|
-
// export
|
|
17
|
+
// export const deprecated = (...args) => {
|
|
20
18
|
// if (process && process.env && (!process.env.NODE_ENV || process.env.NODE_ENV === 'development')) {
|
|
21
19
|
// if (isString(args[0])) args[0] = `deprecation warning -> ${args[0]}`;
|
|
22
20
|
// warnOnce(...args);
|
|
@@ -53,68 +51,17 @@ export const loadLanguages = (i18n, lng, ns, cb) => {
|
|
|
53
51
|
i18n.loadLanguages(lng, loadedClb(i18n, cb));
|
|
54
52
|
};
|
|
55
53
|
|
|
56
|
-
// WAIT A LITTLE FOR I18NEXT BEING UPDATED IN THE WILD, before removing this old i18next version support
|
|
57
|
-
const oldI18nextHasLoadedNamespace = (ns, i18n, options = {}) => {
|
|
58
|
-
const lng = i18n.languages[0];
|
|
59
|
-
const fallbackLng = i18n.options ? i18n.options.fallbackLng : false;
|
|
60
|
-
const lastLng = i18n.languages[i18n.languages.length - 1];
|
|
61
|
-
|
|
62
|
-
// we're in cimode so this shall pass
|
|
63
|
-
if (lng.toLowerCase() === 'cimode') return true;
|
|
64
|
-
|
|
65
|
-
const loadNotPending = (l, n) => {
|
|
66
|
-
const loadState = i18n.services.backendConnector.state[`${l}|${n}`];
|
|
67
|
-
return loadState === -1 || loadState === 2;
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// bound to trigger on event languageChanging
|
|
71
|
-
// so set ready to false while we are changing the language
|
|
72
|
-
// and namespace pending (depends on having a backend)
|
|
73
|
-
if (
|
|
74
|
-
options.bindI18n &&
|
|
75
|
-
options.bindI18n.indexOf('languageChanging') > -1 &&
|
|
76
|
-
i18n.services.backendConnector.backend &&
|
|
77
|
-
i18n.isLanguageChangingTo &&
|
|
78
|
-
!loadNotPending(i18n.isLanguageChangingTo, ns)
|
|
79
|
-
)
|
|
80
|
-
return false;
|
|
81
|
-
|
|
82
|
-
// loaded -> SUCCESS
|
|
83
|
-
if (i18n.hasResourceBundle(lng, ns)) return true;
|
|
84
|
-
|
|
85
|
-
// were not loading at all -> SEMI SUCCESS
|
|
86
|
-
if (
|
|
87
|
-
!i18n.services.backendConnector.backend ||
|
|
88
|
-
(i18n.options.resources && !i18n.options.partialBundledLanguages)
|
|
89
|
-
)
|
|
90
|
-
return true;
|
|
91
|
-
|
|
92
|
-
// failed loading ns - but at least fallback is not pending -> SEMI SUCCESS
|
|
93
|
-
if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns))) return true;
|
|
94
|
-
|
|
95
|
-
return false;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
54
|
export const hasLoadedNamespace = (ns, i18n, options = {}) => {
|
|
99
55
|
if (!i18n.languages || !i18n.languages.length) {
|
|
100
56
|
warnOnce('i18n.languages were undefined or empty', i18n.languages);
|
|
101
57
|
return true;
|
|
102
58
|
}
|
|
103
59
|
|
|
104
|
-
// ignoreJSONStructure was introduced in v20.0.0 (MARCH 2021)
|
|
105
|
-
const isNewerI18next = i18n.options.ignoreJSONStructure !== undefined;
|
|
106
|
-
if (!isNewerI18next) {
|
|
107
|
-
// WAIT A LITTLE FOR I18NEXT BEING UPDATED IN THE WILD, before removing this old i18next version support
|
|
108
|
-
return oldI18nextHasLoadedNamespace(ns, i18n, options);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// IN I18NEXT > v19.4.5 WE CAN (INTRODUCED JUNE 2020)
|
|
112
60
|
return i18n.hasLoadedNamespace(ns, {
|
|
113
61
|
lng: options.lng,
|
|
114
62
|
precheck: (i18nInstance, loadNotPending) => {
|
|
115
63
|
if (
|
|
116
|
-
options.bindI18n &&
|
|
117
|
-
options.bindI18n.indexOf('languageChanging') > -1 &&
|
|
64
|
+
options.bindI18n?.indexOf('languageChanging') > -1 &&
|
|
118
65
|
i18nInstance.services.backendConnector.backend &&
|
|
119
66
|
i18nInstance.isLanguageChangingTo &&
|
|
120
67
|
!loadNotPending(i18nInstance.isLanguageChangingTo, ns)
|
|
@@ -27,6 +27,17 @@ export default defineWorkspace(
|
|
|
27
27
|
test: {
|
|
28
28
|
dir: `./${dirPath}`,
|
|
29
29
|
name: workspaceName,
|
|
30
|
+
alias: {
|
|
31
|
+
/**
|
|
32
|
+
* From `vitest` >= 2 imports are resolved even if we are running only typecheck tests.
|
|
33
|
+
* This will result in:
|
|
34
|
+
* ```text
|
|
35
|
+
* Error: Failed to resolve entry for package "react-i18next". The package may have incorrect main/module/exports specified in its package.json.
|
|
36
|
+
* ```
|
|
37
|
+
* To avoid a useless build process before running these tests an empty alias to `react-i18next` is added.
|
|
38
|
+
*/
|
|
39
|
+
'react-i18next': '',
|
|
40
|
+
},
|
|
30
41
|
typecheck: {
|
|
31
42
|
enabled: true,
|
|
32
43
|
include: [`**/${dirPath}/*.test.{ts,tsx}`],
|