react-i18next 16.0.1 → 16.1.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/amd/react-i18next.js +486 -32
  3. package/dist/amd/react-i18next.min.js +1 -1
  4. package/dist/commonjs/IcuTrans.js +35 -0
  5. package/dist/commonjs/IcuTransUtils/TranslationParserError.js +18 -0
  6. package/dist/commonjs/IcuTransUtils/htmlEntityDecoder.js +218 -0
  7. package/dist/commonjs/IcuTransUtils/index.js +49 -0
  8. package/dist/commonjs/IcuTransUtils/renderTranslation.js +114 -0
  9. package/dist/commonjs/IcuTransUtils/tokenizer.js +58 -0
  10. package/dist/commonjs/IcuTransWithoutContext.js +56 -0
  11. package/dist/commonjs/index.js +14 -0
  12. package/dist/es/IcuTrans.js +29 -0
  13. package/dist/es/IcuTransUtils/TranslationParserError.js +11 -0
  14. package/dist/es/IcuTransUtils/htmlEntityDecoder.js +211 -0
  15. package/dist/es/IcuTransUtils/index.js +4 -0
  16. package/dist/es/IcuTransUtils/renderTranslation.js +106 -0
  17. package/dist/es/IcuTransUtils/tokenizer.js +51 -0
  18. package/dist/es/IcuTransWithoutContext.js +49 -0
  19. package/dist/es/index.js +2 -0
  20. package/dist/es/package.json +1 -1
  21. package/dist/umd/react-i18next.js +486 -32
  22. package/dist/umd/react-i18next.min.js +1 -1
  23. package/icu.macro.js +170 -48
  24. package/index.d.ts +107 -0
  25. package/package.json +6 -3
  26. package/react-i18next.js +486 -32
  27. package/react-i18next.min.js +1 -1
  28. package/src/IcuTrans.js +103 -0
  29. package/src/IcuTransUtils/TranslationParserError.js +24 -0
  30. package/src/IcuTransUtils/htmlEntityDecoder.js +264 -0
  31. package/src/IcuTransUtils/index.js +4 -0
  32. package/src/IcuTransUtils/renderTranslation.js +215 -0
  33. package/src/IcuTransUtils/tokenizer.js +78 -0
  34. package/src/IcuTransWithoutContext.js +146 -0
  35. package/src/index.js +2 -0
package/react-i18next.js CHANGED
@@ -2,7 +2,7 @@
2
2
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
3
3
  typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ReactI18next = {}, global.React));
5
- })(this, (function (exports, react) { 'use strict';
5
+ })(this, (function (exports, React) { 'use strict';
6
6
 
7
7
  const isString$1 = obj => typeof obj === 'string';
8
8
  const defer = () => {
@@ -2426,7 +2426,7 @@
2426
2426
  const children = node.props?.children ?? node.children;
2427
2427
  return node.props?.i18nIsDynamicList ? getAsArray(children) : children;
2428
2428
  };
2429
- const hasValidReactChildren = children => Array.isArray(children) && children.every(react.isValidElement);
2429
+ const hasValidReactChildren = children => Array.isArray(children) && children.every(React.isValidElement);
2430
2430
  const getAsArray = data => Array.isArray(data) ? data : [data];
2431
2431
  const mergeProps = (source, target) => {
2432
2432
  const newTarget = {
@@ -2445,7 +2445,7 @@
2445
2445
  stringNode += `${child}`;
2446
2446
  return;
2447
2447
  }
2448
- if (react.isValidElement(child)) {
2448
+ if (React.isValidElement(child)) {
2449
2449
  const {
2450
2450
  props,
2451
2451
  type
@@ -2509,7 +2509,7 @@
2509
2509
  const childrenArray = getAsArray(childs);
2510
2510
  childrenArray.forEach(child => {
2511
2511
  if (isString(child)) return;
2512
- if (hasChildren(child)) getData(getChildren(child));else if (isObject(child) && !react.isValidElement(child)) Object.assign(data, child);
2512
+ if (hasChildren(child)) getData(getChildren(child));else if (isObject(child) && !React.isValidElement(child)) Object.assign(data, child);
2513
2513
  });
2514
2514
  };
2515
2515
  getData(children);
@@ -2526,16 +2526,16 @@
2526
2526
  const pushTranslatedJSX = (child, inner, mem, i, isVoid) => {
2527
2527
  if (child.dummy) {
2528
2528
  child.children = inner;
2529
- mem.push(react.cloneElement(child, {
2529
+ mem.push(React.cloneElement(child, {
2530
2530
  key: i
2531
2531
  }, isVoid ? undefined : inner));
2532
2532
  } else {
2533
- mem.push(...react.Children.map([child], c => {
2533
+ mem.push(...React.Children.map([child], c => {
2534
2534
  const props = {
2535
2535
  ...c.props
2536
2536
  };
2537
2537
  delete props.i18nIsDynamicList;
2538
- return react.createElement(c.type, {
2538
+ return React.createElement(c.type, {
2539
2539
  ...props,
2540
2540
  key: i,
2541
2541
  ref: c.props.ref ?? c.ref
@@ -2556,7 +2556,7 @@
2556
2556
  const child = Object.keys(node.attrs).length !== 0 ? mergeProps({
2557
2557
  props: node.attrs
2558
2558
  }, tmp) : tmp;
2559
- const isElement = react.isValidElement(child);
2559
+ const isElement = React.isValidElement(child);
2560
2560
  const isValidTranslationWithChildren = isElement && hasChildren(node, true) && !node.voidElement;
2561
2561
  const isEmptyTransWithHTML = emptyChildrenButNeedsHandling && isObject(child) && child.dummy && !isElement;
2562
2562
  const isKnownComponent = isObject(knownComponentsMap) && Object.hasOwnProperty.call(knownComponentsMap, node.name);
@@ -2575,12 +2575,12 @@
2575
2575
  pushTranslatedJSX(child, inner, mem, i, node.voidElement);
2576
2576
  } else if (i18nOptions.transSupportBasicHtmlNodes && keepArray.indexOf(node.name) > -1) {
2577
2577
  if (node.voidElement) {
2578
- mem.push(react.createElement(node.name, {
2578
+ mem.push(React.createElement(node.name, {
2579
2579
  key: `${node.name}-${i}`
2580
2580
  }));
2581
2581
  } else {
2582
2582
  const inner = mapAST(reactNodes, node.children, rootReactNode);
2583
- mem.push(react.createElement(node.name, {
2583
+ mem.push(React.createElement(node.name, {
2584
2584
  key: `${node.name}-${i}`
2585
2585
  }, inner));
2586
2586
  }
@@ -2600,7 +2600,7 @@
2600
2600
  const wrapTextNodes = i18nOptions.transWrapTextNodes;
2601
2601
  const content = shouldUnescape ? i18nOptions.unescape(i18n.services.interpolator.interpolate(node.content, opts, i18n.language)) : i18n.services.interpolator.interpolate(node.content, opts, i18n.language);
2602
2602
  if (wrapTextNodes) {
2603
- mem.push(react.createElement(wrapTextNodes, {
2603
+ mem.push(React.createElement(wrapTextNodes, {
2604
2604
  key: `${node.name}-${i}`
2605
2605
  }, content));
2606
2606
  } else {
@@ -2618,16 +2618,16 @@
2618
2618
  };
2619
2619
  const fixComponentProps = (component, index, translation) => {
2620
2620
  const componentKey = component.key || index;
2621
- const comp = react.cloneElement(component, {
2621
+ const comp = React.cloneElement(component, {
2622
2622
  key: componentKey
2623
2623
  });
2624
2624
  if (!comp.props || !comp.props.children || translation.indexOf(`${index}/>`) < 0 && translation.indexOf(`${index} />`) < 0) {
2625
2625
  return comp;
2626
2626
  }
2627
2627
  function Componentized() {
2628
- return react.createElement(react.Fragment, null, comp);
2628
+ return React.createElement(React.Fragment, null, comp);
2629
2629
  }
2630
- return react.createElement(Componentized, {
2630
+ return React.createElement(Componentized, {
2631
2631
  key: componentKey
2632
2632
  });
2633
2633
  };
@@ -2729,7 +2729,7 @@
2729
2729
  }
2730
2730
  const content = renderNodes(indexedChildren, componentsMap, translation, i18n, reactI18nextOptions, combinedTOpts, shouldUnescape);
2731
2731
  const useAsParent = parent ?? reactI18nextOptions.defaultTransParent;
2732
- return useAsParent ? react.createElement(useAsParent, additionalProps, content) : content;
2732
+ return useAsParent ? React.createElement(useAsParent, additionalProps, content) : content;
2733
2733
  }
2734
2734
 
2735
2735
  const initReactI18next = {
@@ -2740,7 +2740,7 @@
2740
2740
  }
2741
2741
  };
2742
2742
 
2743
- const I18nContext = react.createContext();
2743
+ const I18nContext = React.createContext();
2744
2744
  class ReportNamespaces {
2745
2745
  constructor() {
2746
2746
  this.usedNamespaces = {};
@@ -2797,7 +2797,7 @@
2797
2797
  const {
2798
2798
  i18n: i18nFromContext,
2799
2799
  defaultNS: defaultNSFromContext
2800
- } = react.useContext(I18nContext) || {};
2800
+ } = React.useContext(I18nContext) || {};
2801
2801
  const i18n = i18nFromProps || i18nFromContext || getI18n();
2802
2802
  const t = tFromProps || i18n?.t.bind(i18n);
2803
2803
  return Trans$1({
@@ -2818,15 +2818,467 @@
2818
2818
  });
2819
2819
  }
2820
2820
 
2821
+ class TranslationParserError extends Error {
2822
+ constructor(message, position, translationString) {
2823
+ super(message);
2824
+ this.name = 'TranslationParserError';
2825
+ this.position = position;
2826
+ this.translationString = translationString;
2827
+ if (Error.captureStackTrace) {
2828
+ Error.captureStackTrace(this, TranslationParserError);
2829
+ }
2830
+ }
2831
+ }
2832
+
2833
+ const commonEntities = {
2834
+ '&nbsp;': '\u00A0',
2835
+ '&amp;': '&',
2836
+ '&lt;': '<',
2837
+ '&gt;': '>',
2838
+ '&quot;': '"',
2839
+ '&apos;': "'",
2840
+ '&copy;': '©',
2841
+ '&reg;': '®',
2842
+ '&trade;': '™',
2843
+ '&hellip;': '…',
2844
+ '&ndash;': '–',
2845
+ '&mdash;': '—',
2846
+ '&lsquo;': '\u2018',
2847
+ '&rsquo;': '\u2019',
2848
+ '&sbquo;': '\u201A',
2849
+ '&ldquo;': '\u201C',
2850
+ '&rdquo;': '\u201D',
2851
+ '&bdquo;': '\u201E',
2852
+ '&dagger;': '†',
2853
+ '&Dagger;': '‡',
2854
+ '&bull;': '•',
2855
+ '&prime;': '′',
2856
+ '&Prime;': '″',
2857
+ '&lsaquo;': '‹',
2858
+ '&rsaquo;': '›',
2859
+ '&sect;': '§',
2860
+ '&para;': '¶',
2861
+ '&middot;': '·',
2862
+ '&ensp;': '\u2002',
2863
+ '&emsp;': '\u2003',
2864
+ '&thinsp;': '\u2009',
2865
+ '&euro;': '€',
2866
+ '&pound;': '£',
2867
+ '&yen;': '¥',
2868
+ '&cent;': '¢',
2869
+ '&curren;': '¤',
2870
+ '&times;': '×',
2871
+ '&divide;': '÷',
2872
+ '&minus;': '−',
2873
+ '&plusmn;': '±',
2874
+ '&ne;': '≠',
2875
+ '&le;': '≤',
2876
+ '&ge;': '≥',
2877
+ '&asymp;': '≈',
2878
+ '&equiv;': '≡',
2879
+ '&infin;': '∞',
2880
+ '&int;': '∫',
2881
+ '&sum;': '∑',
2882
+ '&prod;': '∏',
2883
+ '&radic;': '√',
2884
+ '&part;': '∂',
2885
+ '&permil;': '‰',
2886
+ '&deg;': '°',
2887
+ '&micro;': 'µ',
2888
+ '&larr;': '←',
2889
+ '&uarr;': '↑',
2890
+ '&rarr;': '→',
2891
+ '&darr;': '↓',
2892
+ '&harr;': '↔',
2893
+ '&crarr;': '↵',
2894
+ '&lArr;': '⇐',
2895
+ '&uArr;': '⇑',
2896
+ '&rArr;': '⇒',
2897
+ '&dArr;': '⇓',
2898
+ '&hArr;': '⇔',
2899
+ '&alpha;': 'α',
2900
+ '&beta;': 'β',
2901
+ '&gamma;': 'γ',
2902
+ '&delta;': 'δ',
2903
+ '&epsilon;': 'ε',
2904
+ '&zeta;': 'ζ',
2905
+ '&eta;': 'η',
2906
+ '&theta;': 'θ',
2907
+ '&iota;': 'ι',
2908
+ '&kappa;': 'κ',
2909
+ '&lambda;': 'λ',
2910
+ '&mu;': 'μ',
2911
+ '&nu;': 'ν',
2912
+ '&xi;': 'ξ',
2913
+ '&omicron;': 'ο',
2914
+ '&pi;': 'π',
2915
+ '&rho;': 'ρ',
2916
+ '&sigma;': 'σ',
2917
+ '&tau;': 'τ',
2918
+ '&upsilon;': 'υ',
2919
+ '&phi;': 'φ',
2920
+ '&chi;': 'χ',
2921
+ '&psi;': 'ψ',
2922
+ '&omega;': 'ω',
2923
+ '&Alpha;': 'Α',
2924
+ '&Beta;': 'Β',
2925
+ '&Gamma;': 'Γ',
2926
+ '&Delta;': 'Δ',
2927
+ '&Epsilon;': 'Ε',
2928
+ '&Zeta;': 'Ζ',
2929
+ '&Eta;': 'Η',
2930
+ '&Theta;': 'Θ',
2931
+ '&Iota;': 'Ι',
2932
+ '&Kappa;': 'Κ',
2933
+ '&Lambda;': 'Λ',
2934
+ '&Mu;': 'Μ',
2935
+ '&Nu;': 'Ν',
2936
+ '&Xi;': 'Ξ',
2937
+ '&Omicron;': 'Ο',
2938
+ '&Pi;': 'Π',
2939
+ '&Rho;': 'Ρ',
2940
+ '&Sigma;': 'Σ',
2941
+ '&Tau;': 'Τ',
2942
+ '&Upsilon;': 'Υ',
2943
+ '&Phi;': 'Φ',
2944
+ '&Chi;': 'Χ',
2945
+ '&Psi;': 'Ψ',
2946
+ '&Omega;': 'Ω',
2947
+ '&Agrave;': 'À',
2948
+ '&Aacute;': 'Á',
2949
+ '&Acirc;': 'Â',
2950
+ '&Atilde;': 'Ã',
2951
+ '&Auml;': 'Ä',
2952
+ '&Aring;': 'Å',
2953
+ '&AElig;': 'Æ',
2954
+ '&Ccedil;': 'Ç',
2955
+ '&Egrave;': 'È',
2956
+ '&Eacute;': 'É',
2957
+ '&Ecirc;': 'Ê',
2958
+ '&Euml;': 'Ë',
2959
+ '&Igrave;': 'Ì',
2960
+ '&Iacute;': 'Í',
2961
+ '&Icirc;': 'Î',
2962
+ '&Iuml;': 'Ï',
2963
+ '&ETH;': 'Ð',
2964
+ '&Ntilde;': 'Ñ',
2965
+ '&Ograve;': 'Ò',
2966
+ '&Oacute;': 'Ó',
2967
+ '&Ocirc;': 'Ô',
2968
+ '&Otilde;': 'Õ',
2969
+ '&Ouml;': 'Ö',
2970
+ '&Oslash;': 'Ø',
2971
+ '&Ugrave;': 'Ù',
2972
+ '&Uacute;': 'Ú',
2973
+ '&Ucirc;': 'Û',
2974
+ '&Uuml;': 'Ü',
2975
+ '&Yacute;': 'Ý',
2976
+ '&THORN;': 'Þ',
2977
+ '&szlig;': 'ß',
2978
+ '&agrave;': 'à',
2979
+ '&aacute;': 'á',
2980
+ '&acirc;': 'â',
2981
+ '&atilde;': 'ã',
2982
+ '&auml;': 'ä',
2983
+ '&aring;': 'å',
2984
+ '&aelig;': 'æ',
2985
+ '&ccedil;': 'ç',
2986
+ '&egrave;': 'è',
2987
+ '&eacute;': 'é',
2988
+ '&ecirc;': 'ê',
2989
+ '&euml;': 'ë',
2990
+ '&igrave;': 'ì',
2991
+ '&iacute;': 'í',
2992
+ '&icirc;': 'î',
2993
+ '&iuml;': 'ï',
2994
+ '&eth;': 'ð',
2995
+ '&ntilde;': 'ñ',
2996
+ '&ograve;': 'ò',
2997
+ '&oacute;': 'ó',
2998
+ '&ocirc;': 'ô',
2999
+ '&otilde;': 'õ',
3000
+ '&ouml;': 'ö',
3001
+ '&oslash;': 'ø',
3002
+ '&ugrave;': 'ù',
3003
+ '&uacute;': 'ú',
3004
+ '&ucirc;': 'û',
3005
+ '&uuml;': 'ü',
3006
+ '&yacute;': 'ý',
3007
+ '&thorn;': 'þ',
3008
+ '&yuml;': 'ÿ',
3009
+ '&iexcl;': '¡',
3010
+ '&iquest;': '¿',
3011
+ '&fnof;': 'ƒ',
3012
+ '&circ;': 'ˆ',
3013
+ '&tilde;': '˜',
3014
+ '&OElig;': 'Œ',
3015
+ '&oelig;': 'œ',
3016
+ '&Scaron;': 'Š',
3017
+ '&scaron;': 'š',
3018
+ '&Yuml;': 'Ÿ',
3019
+ '&ordf;': 'ª',
3020
+ '&ordm;': 'º',
3021
+ '&macr;': '¯',
3022
+ '&acute;': '´',
3023
+ '&cedil;': '¸',
3024
+ '&sup1;': '¹',
3025
+ '&sup2;': '²',
3026
+ '&sup3;': '³',
3027
+ '&frac14;': '¼',
3028
+ '&frac12;': '½',
3029
+ '&frac34;': '¾',
3030
+ '&spades;': '♠',
3031
+ '&clubs;': '♣',
3032
+ '&hearts;': '♥',
3033
+ '&diams;': '♦',
3034
+ '&loz;': '◊',
3035
+ '&oline;': '‾',
3036
+ '&frasl;': '⁄',
3037
+ '&weierp;': '℘',
3038
+ '&image;': 'ℑ',
3039
+ '&real;': 'ℜ',
3040
+ '&alefsym;': 'ℵ'
3041
+ };
3042
+ const entityPattern = new RegExp(Object.keys(commonEntities).map(entity => entity.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|'), 'g');
3043
+ const decodeHtmlEntities = text => text.replace(entityPattern, match => commonEntities[match]).replace(/&#(\d+);/g, (_, num) => String.fromCharCode(parseInt(num, 10))).replace(/&#x([0-9a-fA-F]+);/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
3044
+
3045
+ const tokenize = translation => {
3046
+ const tokens = [];
3047
+ let position = 0;
3048
+ let currentText = '';
3049
+ const flushText = () => {
3050
+ if (currentText) {
3051
+ tokens.push({
3052
+ type: 'Text',
3053
+ value: currentText,
3054
+ position: position - currentText.length
3055
+ });
3056
+ currentText = '';
3057
+ }
3058
+ };
3059
+ while (position < translation.length) {
3060
+ const char = translation[position];
3061
+ if (char === '<') {
3062
+ const tagMatch = translation.slice(position).match(/^<(\d+)>/);
3063
+ if (tagMatch) {
3064
+ flushText();
3065
+ tokens.push({
3066
+ type: 'TagOpen',
3067
+ value: tagMatch[0],
3068
+ position,
3069
+ tagNumber: parseInt(tagMatch[1], 10)
3070
+ });
3071
+ position += tagMatch[0].length;
3072
+ } else {
3073
+ const closeTagMatch = translation.slice(position).match(/^<\/(\d+)>/);
3074
+ if (closeTagMatch) {
3075
+ flushText();
3076
+ tokens.push({
3077
+ type: 'TagClose',
3078
+ value: closeTagMatch[0],
3079
+ position,
3080
+ tagNumber: parseInt(closeTagMatch[1], 10)
3081
+ });
3082
+ position += closeTagMatch[0].length;
3083
+ } else {
3084
+ currentText += char;
3085
+ position += 1;
3086
+ }
3087
+ }
3088
+ } else {
3089
+ currentText += char;
3090
+ position += 1;
3091
+ }
3092
+ }
3093
+ flushText();
3094
+ return tokens;
3095
+ };
3096
+
3097
+ const renderDeclarationNode = (declaration, children, childDeclarations) => {
3098
+ const {
3099
+ type,
3100
+ props = {}
3101
+ } = declaration;
3102
+ if (props.children && Array.isArray(props.children) && childDeclarations) {
3103
+ const {
3104
+ children: _childrenToRemove,
3105
+ ...propsWithoutChildren
3106
+ } = props;
3107
+ return React.createElement(type, propsWithoutChildren, ...children);
3108
+ }
3109
+ if (children.length === 0) {
3110
+ return React.createElement(type, props);
3111
+ }
3112
+ if (children.length === 1) {
3113
+ return React.createElement(type, props, children[0]);
3114
+ }
3115
+ return React.createElement(type, props, ...children);
3116
+ };
3117
+ const renderTranslation = (translation, declarations = []) => {
3118
+ if (!translation) {
3119
+ return [];
3120
+ }
3121
+ const tokens = tokenize(translation);
3122
+ const result = [];
3123
+ const stack = [];
3124
+ const literalTagNumbers = new Set();
3125
+ const getCurrentDeclarations = () => {
3126
+ if (stack.length === 0) {
3127
+ return declarations;
3128
+ }
3129
+ const parentFrame = stack[stack.length - 1];
3130
+ if (parentFrame.declaration.props?.children && Array.isArray(parentFrame.declaration.props.children)) {
3131
+ return parentFrame.declaration.props.children;
3132
+ }
3133
+ return parentFrame.declarations;
3134
+ };
3135
+ tokens.forEach(token => {
3136
+ switch (token.type) {
3137
+ case 'Text':
3138
+ {
3139
+ const decoded = decodeHtmlEntities(token.value);
3140
+ const targetArray = stack.length > 0 ? stack[stack.length - 1].children : result;
3141
+ targetArray.push(decoded);
3142
+ }
3143
+ break;
3144
+ case 'TagOpen':
3145
+ {
3146
+ const {
3147
+ tagNumber
3148
+ } = token;
3149
+ const currentDeclarations = getCurrentDeclarations();
3150
+ const declaration = currentDeclarations[tagNumber];
3151
+ if (!declaration) {
3152
+ literalTagNumbers.add(tagNumber);
3153
+ const literalText = `<${tagNumber}>`;
3154
+ const targetArray = stack.length > 0 ? stack[stack.length - 1].children : result;
3155
+ targetArray.push(literalText);
3156
+ break;
3157
+ }
3158
+ stack.push({
3159
+ tagNumber,
3160
+ children: [],
3161
+ position: token.position,
3162
+ declaration,
3163
+ declarations: currentDeclarations
3164
+ });
3165
+ }
3166
+ break;
3167
+ case 'TagClose':
3168
+ {
3169
+ const {
3170
+ tagNumber
3171
+ } = token;
3172
+ if (literalTagNumbers.has(tagNumber)) {
3173
+ const literalText = `</${tagNumber}>`;
3174
+ const literalTargetArray = stack.length > 0 ? stack[stack.length - 1].children : result;
3175
+ literalTargetArray.push(literalText);
3176
+ literalTagNumbers.delete(tagNumber);
3177
+ break;
3178
+ }
3179
+ if (stack.length === 0) {
3180
+ throw new TranslationParserError(`Unexpected closing tag </${tagNumber}> at position ${token.position}`, token.position, translation);
3181
+ }
3182
+ const frame = stack.pop();
3183
+ if (frame.tagNumber !== tagNumber) {
3184
+ throw new TranslationParserError(`Mismatched tags: expected </${frame.tagNumber}> but got </${tagNumber}> at position ${token.position}`, token.position, translation);
3185
+ }
3186
+ const element = renderDeclarationNode(frame.declaration, frame.children, frame.declarations);
3187
+ const elementTargetArray = stack.length > 0 ? stack[stack.length - 1].children : result;
3188
+ elementTargetArray.push(element);
3189
+ }
3190
+ break;
3191
+ }
3192
+ });
3193
+ if (stack.length > 0) {
3194
+ const unclosed = stack[stack.length - 1];
3195
+ throw new TranslationParserError(`Unclosed tag <${unclosed.tagNumber}> at position ${unclosed.position}`, unclosed.position, translation);
3196
+ }
3197
+ return result;
3198
+ };
3199
+
3200
+ function IcuTransWithoutContext({
3201
+ i18nKey,
3202
+ defaultTranslation,
3203
+ content,
3204
+ ns,
3205
+ values = {},
3206
+ i18n: i18nFromProps,
3207
+ t: tFromProps
3208
+ }) {
3209
+ const i18n = i18nFromProps || getI18n();
3210
+ if (!i18n) {
3211
+ warnOnce(i18n, 'NO_I18NEXT_INSTANCE', `IcuTrans: You need to pass in an i18next instance using i18nextReactModule`, {
3212
+ i18nKey
3213
+ });
3214
+ return React.createElement(React.Fragment, {}, defaultTranslation);
3215
+ }
3216
+ const t = tFromProps || i18n.t?.bind(i18n) || (k => k);
3217
+ let namespaces = ns || t.ns || i18n.options?.defaultNS;
3218
+ namespaces = isString(namespaces) ? [namespaces] : namespaces || ['translation'];
3219
+ let mergedValues = values;
3220
+ if (i18n.options?.interpolation?.defaultVariables) {
3221
+ mergedValues = values && Object.keys(values).length > 0 ? {
3222
+ ...values,
3223
+ ...i18n.options.interpolation.defaultVariables
3224
+ } : {
3225
+ ...i18n.options.interpolation.defaultVariables
3226
+ };
3227
+ }
3228
+ const translation = t(i18nKey, {
3229
+ defaultValue: defaultTranslation,
3230
+ ...mergedValues,
3231
+ ns: namespaces
3232
+ });
3233
+ try {
3234
+ const rendered = renderTranslation(translation, content);
3235
+ return React.createElement(React.Fragment, {}, ...rendered);
3236
+ } catch (error) {
3237
+ warn(i18n, 'ICU_TRANS_RENDER_ERROR', `IcuTrans component error for key "${i18nKey}": ${error.message}`, {
3238
+ i18nKey,
3239
+ error
3240
+ });
3241
+ return React.createElement(React.Fragment, {}, translation);
3242
+ }
3243
+ }
3244
+ IcuTransWithoutContext.displayName = 'IcuTransWithoutContext';
3245
+
3246
+ function IcuTrans({
3247
+ i18nKey,
3248
+ defaultTranslation,
3249
+ content,
3250
+ ns,
3251
+ values = {},
3252
+ i18n: i18nFromProps,
3253
+ t: tFromProps
3254
+ }) {
3255
+ const {
3256
+ i18n: i18nFromContext,
3257
+ defaultNS: defaultNSFromContext
3258
+ } = React.useContext(I18nContext) || {};
3259
+ const i18n = i18nFromProps || i18nFromContext || getI18n();
3260
+ const t = tFromProps || i18n?.t.bind(i18n);
3261
+ return IcuTransWithoutContext({
3262
+ i18nKey,
3263
+ defaultTranslation,
3264
+ content,
3265
+ ns: ns || t?.ns || defaultNSFromContext || i18n?.options?.defaultNS,
3266
+ values,
3267
+ i18n,
3268
+ t: tFromProps
3269
+ });
3270
+ }
3271
+ IcuTrans.displayName = 'IcuTrans';
3272
+
2821
3273
  const usePrevious = (value, ignore) => {
2822
- const ref = react.useRef();
2823
- react.useEffect(() => {
3274
+ const ref = React.useRef();
3275
+ React.useEffect(() => {
2824
3276
  ref.current = value;
2825
3277
  }, [value, ignore]);
2826
3278
  return ref.current;
2827
3279
  };
2828
3280
  const alwaysNewT = (i18n, language, namespace, keyPrefix) => i18n.getFixedT(language, namespace, keyPrefix);
2829
- const useMemoizedT = (i18n, language, namespace, keyPrefix) => react.useCallback(alwaysNewT(i18n, language, namespace, keyPrefix), [i18n, language, namespace, keyPrefix]);
3281
+ const useMemoizedT = (i18n, language, namespace, keyPrefix) => React.useCallback(alwaysNewT(i18n, language, namespace, keyPrefix), [i18n, language, namespace, keyPrefix]);
2830
3282
  const useTranslation = (ns, props = {}) => {
2831
3283
  const {
2832
3284
  i18n: i18nFromProps
@@ -2834,7 +3286,7 @@
2834
3286
  const {
2835
3287
  i18n: i18nFromContext,
2836
3288
  defaultNS: defaultNSFromContext
2837
- } = react.useContext(I18nContext) || {};
3289
+ } = React.useContext(I18nContext) || {};
2838
3290
  const i18n = i18nFromProps || i18nFromContext || getI18n();
2839
3291
  if (i18n && !i18n.reportNamespaces) i18n.reportNamespaces = new ReportNamespaces();
2840
3292
  if (!i18n) {
@@ -2867,12 +3319,12 @@
2867
3319
  const memoGetT = useMemoizedT(i18n, props.lng || null, i18nOptions.nsMode === 'fallback' ? namespaces : namespaces[0], keyPrefix);
2868
3320
  const getT = () => memoGetT;
2869
3321
  const getNewT = () => alwaysNewT(i18n, props.lng || null, i18nOptions.nsMode === 'fallback' ? namespaces : namespaces[0], keyPrefix);
2870
- const [t, setT] = react.useState(getT);
3322
+ const [t, setT] = React.useState(getT);
2871
3323
  let joinedNS = namespaces.join();
2872
3324
  if (props.lng) joinedNS = `${props.lng}${joinedNS}`;
2873
3325
  const previousJoinedNS = usePrevious(joinedNS);
2874
- const isMounted = react.useRef(true);
2875
- react.useEffect(() => {
3326
+ const isMounted = React.useRef(true);
3327
+ React.useEffect(() => {
2876
3328
  const {
2877
3329
  bindI18n,
2878
3330
  bindI18nStore
@@ -2903,7 +3355,7 @@
2903
3355
  if (bindI18nStore && i18n) bindI18nStore.split(' ').forEach(e => i18n.store.off(e, boundReset));
2904
3356
  };
2905
3357
  }, [i18n, joinedNS]);
2906
- react.useEffect(() => {
3358
+ React.useEffect(() => {
2907
3359
  if (isMounted.current && ready) {
2908
3360
  setT(getT);
2909
3361
  }
@@ -2943,14 +3395,14 @@
2943
3395
  } else if (!options.withRef && forwardedRef) {
2944
3396
  passDownProps.forwardedRef = forwardedRef;
2945
3397
  }
2946
- return react.createElement(WrappedComponent, passDownProps);
3398
+ return React.createElement(WrappedComponent, passDownProps);
2947
3399
  }
2948
3400
  I18nextWithTranslation.displayName = `withI18nextTranslation(${getDisplayName(WrappedComponent)})`;
2949
3401
  I18nextWithTranslation.WrappedComponent = WrappedComponent;
2950
- const forwardRef = (props, ref) => react.createElement(I18nextWithTranslation, Object.assign({}, props, {
3402
+ const forwardRef = (props, ref) => React.createElement(I18nextWithTranslation, Object.assign({}, props, {
2951
3403
  forwardedRef: ref
2952
3404
  }));
2953
- return options.withRef ? react.forwardRef(forwardRef) : I18nextWithTranslation;
3405
+ return options.withRef ? React.forwardRef(forwardRef) : I18nextWithTranslation;
2954
3406
  };
2955
3407
 
2956
3408
  const Translation = ({
@@ -2970,11 +3422,11 @@
2970
3422
  defaultNS,
2971
3423
  children
2972
3424
  }) {
2973
- const value = react.useMemo(() => ({
3425
+ const value = React.useMemo(() => ({
2974
3426
  i18n,
2975
3427
  defaultNS
2976
3428
  }), [i18n, defaultNS]);
2977
- return react.createElement(I18nContext.Provider, {
3429
+ return React.createElement(I18nContext.Provider, {
2978
3430
  value
2979
3431
  }, children);
2980
3432
  }
@@ -2985,7 +3437,7 @@
2985
3437
  } = props;
2986
3438
  const {
2987
3439
  i18n: i18nFromContext
2988
- } = react.useContext(I18nContext) || {};
3440
+ } = React.useContext(I18nContext) || {};
2989
3441
  const i18n = i18nFromProps || i18nFromContext || getI18n();
2990
3442
  if (i18n.options?.isClone) return;
2991
3443
  if (initialI18nStore && !i18n.initializedStoreOnce) {
@@ -3012,7 +3464,7 @@
3012
3464
  ...rest
3013
3465
  }) {
3014
3466
  useSSR(initialI18nStore, initialLanguage);
3015
- return react.createElement(WrappedComponent, {
3467
+ return React.createElement(WrappedComponent, {
3016
3468
  ...rest
3017
3469
  });
3018
3470
  }
@@ -3031,6 +3483,8 @@
3031
3483
 
3032
3484
  exports.I18nContext = I18nContext;
3033
3485
  exports.I18nextProvider = I18nextProvider;
3486
+ exports.IcuTrans = IcuTrans;
3487
+ exports.IcuTransWithoutContext = IcuTransWithoutContext;
3034
3488
  exports.Trans = Trans;
3035
3489
  exports.TransWithoutContext = Trans$1;
3036
3490
  exports.Translation = Translation;