1
1
import { Fragment , isValidElement , cloneElement , createElement , Children } from 'react' ;
2
2
import HTML from 'html-parse-stringify' ;
3
- import { isObject , isString , warn , warnOnce } from './utils.js' ;
3
+ import { ERR_CODES , isObject , isString , warn , warnOnce } from './utils.js' ;
4
4
import { getDefaults } from './defaults.js' ;
5
5
import { getI18n } from './i18nInstance.js' ;
6
6
@@ -45,7 +45,10 @@ export const nodesToString = (children, i18nOptions, i18n, i18nKey) => {
45
45
// actual e.g. lorem
46
46
// expected e.g. lorem
47
47
stringNode += `${ child } ` ;
48
- } else if ( isValidElement ( child ) ) {
48
+ return ;
49
+ }
50
+
51
+ if ( isValidElement ( child ) ) {
49
52
const { props, type } = child ;
50
53
const childPropsCount = Object . keys ( props ) . length ;
51
54
const shouldKeepChild = keepArray . indexOf ( type ) > - 1 ;
@@ -55,53 +58,77 @@ export const nodesToString = (children, i18nOptions, i18n, i18nKey) => {
55
58
// actual e.g. lorem <br/> ipsum
56
59
// expected e.g. lorem <br/> ipsum
57
60
stringNode += `<${ type } />` ;
58
- } else if (
59
- ( ! childChildren && ( ! shouldKeepChild || childPropsCount ) ) ||
60
- props . i18nIsDynamicList
61
- ) {
61
+ return ;
62
+ }
63
+
64
+ if ( ( ! childChildren && ( ! shouldKeepChild || childPropsCount ) ) || props . i18nIsDynamicList ) {
62
65
// actual e.g. lorem <hr className="test" /> ipsum
63
66
// expected e.g. lorem <0></0> ipsum
64
67
// or
65
68
// we got a dynamic list like
66
69
// e.g. <ul i18nIsDynamicList>{['a', 'b'].map(item => ( <li key={item}>{item}</li> ))}</ul>
67
70
// expected e.g. "<0></0>", not e.g. "<0><0>a</0><1>b</1></0>"
68
71
stringNode += `<${ childIndex } ></${ childIndex } >` ;
69
- } else if ( shouldKeepChild && childPropsCount === 1 && isString ( childChildren ) ) {
72
+ return ;
73
+ }
74
+
75
+ if ( shouldKeepChild && childPropsCount === 1 && isString ( childChildren ) ) {
70
76
// actual e.g. dolor <strong>bold</strong> amet
71
77
// expected e.g. dolor <strong>bold</strong> amet
72
78
stringNode += `<${ type } >${ childChildren } </${ type } >` ;
73
- } else {
74
- // regular case mapping the inner children
75
- const content = nodesToString ( childChildren , i18nOptions , i18n , i18nKey ) ;
76
- stringNode += `<${ childIndex } >${ content } </${ childIndex } >` ;
79
+ return ;
77
80
}
78
- } else if ( child === null ) {
79
- warn ( i18n , `Trans: the passed in value is invalid - seems you passed in a null child.` ) ;
80
- } else if ( isObject ( child ) ) {
81
+
82
+ // regular case mapping the inner children
83
+ const content = nodesToString ( childChildren , i18nOptions , i18n , i18nKey ) ;
84
+ stringNode += `<${ childIndex } >${ content } </${ childIndex } >` ;
85
+
86
+ return ;
87
+ }
88
+
89
+ if ( child === null ) {
90
+ warn ( i18n , `Trans: The passed in value is invalid - seems you passed in a null child.` , {
91
+ code : ERR_CODES . TRANS_NULL_VALUE ,
92
+ i18nKey,
93
+ } ) ;
94
+ return ;
95
+ }
96
+
97
+ if ( isObject ( child ) ) {
81
98
// e.g. lorem {{ value, format }} ipsum
82
99
const { format, ...clone } = child ;
83
100
const keys = Object . keys ( clone ) ;
84
101
85
102
if ( keys . length === 1 ) {
86
103
const value = format ? `${ keys [ 0 ] } , ${ format } ` : keys [ 0 ] ;
87
104
stringNode += `{{${ value } }}` ;
88
- } else {
89
- // not a valid interpolation object (can only contain one value plus format)
90
- warn (
91
- i18n ,
92
- `react-i18next: the passed in object contained more than one variable - the object should look like {{ value, format }} where format is optional.` ,
93
- child ,
94
- i18nKey ,
95
- ) ;
105
+ return ;
96
106
}
97
- } else {
107
+
108
+ // not a valid interpolation object (can only contain one value plus format)
98
109
warn (
99
110
i18n ,
100
- `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}}.` ,
101
- child ,
102
- i18nKey ,
111
+ `Trans: The passed in object contained more than one variable - the object should look like {{ value, format }} where format is optional.` ,
112
+ {
113
+ code : ERR_CODES . TRANS_INVALID_OBJ ,
114
+ i18nKey,
115
+ child,
116
+ } ,
103
117
) ;
118
+
119
+ return ;
104
120
}
121
+
122
+ // e.g. lorem {number} ipsum
123
+ warn (
124
+ i18n ,
125
+ `Trans: Passed in a variable like {number} - please pass in variables for interpolation as full objects like {{number}}.` ,
126
+ {
127
+ code : ERR_CODES . TRANS_INVALID_VAR ,
128
+ i18nKey,
129
+ child,
130
+ } ,
131
+ ) ;
105
132
} ) ;
106
133
107
134
return stringNode ;
@@ -336,7 +363,7 @@ const generateObjectComponents = (components, translation) => {
336
363
return componentMap ;
337
364
} ;
338
365
339
- const generateComponents = ( components , translation , i18n ) => {
366
+ const generateComponents = ( components , translation , i18n , i18nKey ) => {
340
367
if ( ! components ) return null ;
341
368
342
369
// components could be either an array or an object
@@ -351,7 +378,10 @@ const generateComponents = (components, translation, i18n) => {
351
378
352
379
// if components is not an array or an object, warn the user
353
380
// and return null
354
- warnOnce ( i18n , '<Trans /> component prop expects an object or an array' ) ;
381
+ warnOnce ( i18n , `<Trans /> "components" prop expects an object or an array` , {
382
+ i18nKey,
383
+ code : ERR_CODES . TRANS_INVALID_COMPONENTS ,
384
+ } ) ;
355
385
return null ;
356
386
} ;
357
387
@@ -374,7 +404,14 @@ export function Trans({
374
404
const i18n = i18nFromProps || getI18n ( ) ;
375
405
376
406
if ( ! i18n ) {
377
- warnOnce ( i18n , 'You will need to pass in an i18next instance by using i18nextReactModule' ) ;
407
+ warnOnce (
408
+ i18n ,
409
+ 'Trans: You will need to pass in an i18next instance by using i18nextReactModule' ,
410
+ {
411
+ i18nKey,
412
+ code : ERR_CODES . NO_I18NEXT_INSTANCE ,
413
+ } ,
414
+ ) ;
378
415
return children ;
379
416
}
380
417
@@ -417,7 +454,7 @@ export function Trans({
417
454
} ;
418
455
const translation = key ? t ( key , combinedTOpts ) : defaultValue ;
419
456
420
- const generatedComponents = generateComponents ( components , translation , i18n ) ;
457
+ const generatedComponents = generateComponents ( components , translation , i18n , i18nKey ) ;
421
458
422
459
const content = renderNodes (
423
460
generatedComponents || children ,
0 commit comments