@lingui/react 4.4.2 → 4.6.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/dist/index.cjs CHANGED
@@ -1,10 +1,15 @@
1
1
  'use strict';
2
2
 
3
3
  const React = require('react');
4
+ const server = require('./server.cjs');
4
5
 
5
- const LinguiContext = React.createContext(null);
6
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
7
+
8
+ const React__default = /*#__PURE__*/_interopDefaultCompat(React);
9
+
10
+ const LinguiContext = React__default.createContext(null);
6
11
  function useLingui() {
7
- const context = React.useContext(LinguiContext);
12
+ const context = React__default.useContext(LinguiContext);
8
13
  if (process.env.NODE_ENV !== "production") {
9
14
  if (context == null) {
10
15
  throw new Error("useLingui hook was used without I18nProvider.");
@@ -17,8 +22,8 @@ const I18nProvider = ({
17
22
  defaultComponent,
18
23
  children
19
24
  }) => {
20
- const latestKnownLocale = React.useRef(i18n.locale);
21
- const makeContext = React.useCallback(
25
+ const latestKnownLocale = React__default.useRef(i18n.locale);
26
+ const makeContext = React__default.useCallback(
22
27
  () => ({
23
28
  i18n,
24
29
  defaultComponent,
@@ -26,8 +31,8 @@ const I18nProvider = ({
26
31
  }),
27
32
  [i18n, defaultComponent]
28
33
  );
29
- const [context, setContext] = React.useState(makeContext());
30
- React.useEffect(() => {
34
+ const [context, setContext] = React__default.useState(makeContext());
35
+ React__default.useEffect(() => {
31
36
  const updateContext = () => {
32
37
  latestKnownLocale.current = i18n.locale;
33
38
  setContext(makeContext());
@@ -44,141 +49,12 @@ const I18nProvider = ({
44
49
  );
45
50
  return null;
46
51
  }
47
- return /* @__PURE__ */ React.createElement(LinguiContext.Provider, { value: context }, children);
48
- };
49
-
50
- const tagRe = /<([a-zA-Z0-9]+)>(.*?)<\/\1>|<([a-zA-Z0-9]+)\/>/;
51
- const nlRe = /(?:\r\n|\r|\n)/g;
52
- const voidElementTags = {
53
- area: true,
54
- base: true,
55
- br: true,
56
- col: true,
57
- embed: true,
58
- hr: true,
59
- img: true,
60
- input: true,
61
- keygen: true,
62
- link: true,
63
- meta: true,
64
- param: true,
65
- source: true,
66
- track: true,
67
- wbr: true,
68
- menuitem: true
69
- };
70
- function formatElements(value, elements = {}) {
71
- const uniqueId = makeCounter(0, "$lingui$");
72
- const parts = value.replace(nlRe, "").split(tagRe);
73
- if (parts.length === 1)
74
- return value;
75
- const tree = [];
76
- const before = parts.shift();
77
- if (before)
78
- tree.push(before);
79
- for (const [index, children, after] of getElements(parts)) {
80
- let element = typeof index !== "undefined" ? elements[index] : void 0;
81
- if (!element || voidElementTags[element.type] && children) {
82
- if (!element) {
83
- console.error(
84
- `Can't use element at index '${index}' as it is not declared in the original translation`
85
- );
86
- } else {
87
- console.error(
88
- `${element.type} is a void element tag therefore it must have no children`
89
- );
90
- }
91
- element = React.createElement(React.Fragment);
92
- }
93
- if (Array.isArray(element)) {
94
- element = React.createElement(React.Fragment, {}, element);
95
- }
96
- tree.push(
97
- React.cloneElement(
98
- element,
99
- { key: uniqueId() },
100
- // format children for pair tags
101
- // unpaired tags might have children if it's a component passed as a variable
102
- children ? formatElements(children, elements) : element.props.children
103
- )
104
- );
105
- if (after)
106
- tree.push(after);
107
- }
108
- return tree;
109
- }
110
- function getElements(parts) {
111
- if (!parts.length)
112
- return [];
113
- const [paired, children, unpaired, after] = parts.slice(0, 4);
114
- const triple = [paired || unpaired, children || "", after];
115
- return [triple].concat(getElements(parts.slice(4, parts.length)));
116
- }
117
- const makeCounter = (count = 0, prefix = "") => () => `${prefix}_${count++}`;
118
-
119
- function TransNoContext(props) {
120
- const {
121
- render,
122
- component,
123
- id,
124
- message,
125
- formats,
126
- lingui: { i18n, defaultComponent }
127
- } = props;
128
- const values = { ...props.values };
129
- const components = { ...props.components };
130
- if (values) {
131
- Object.keys(values).forEach((key) => {
132
- const value = values[key];
133
- const valueIsReactEl = React.isValidElement(value) || Array.isArray(value) && value.every(React.isValidElement);
134
- if (!valueIsReactEl)
135
- return;
136
- const index = Object.keys(components).length;
137
- components[index] = value;
138
- values[key] = `<${index}/>`;
139
- });
140
- }
141
- const _translation = i18n && typeof i18n._ === "function" ? i18n._(id, values, { message, formats }) : id;
142
- const translation = _translation ? formatElements(_translation, components) : null;
143
- if (render === null || component === null) {
144
- return translation;
145
- }
146
- const FallbackComponent = defaultComponent || RenderFragment;
147
- const i18nProps = {
148
- id,
149
- message,
150
- translation,
151
- isTranslated: id !== translation && message !== translation,
152
- children: translation
153
- // for type-compatibility with `component` prop
154
- };
155
- if (render && component) {
156
- console.error(
157
- "You can't use both `component` and `render` prop at the same time. `component` is ignored."
158
- );
159
- } else if (render && typeof render !== "function") {
160
- console.error(
161
- `Invalid value supplied to prop \`render\`. It must be a function, provided ${render}`
162
- );
163
- } else if (component && typeof component !== "function") {
164
- console.error(
165
- `Invalid value supplied to prop \`component\`. It must be a React component, provided ${component}`
166
- );
167
- return React.createElement(FallbackComponent, i18nProps, translation);
168
- }
169
- if (typeof render === "function") {
170
- return render(i18nProps);
171
- }
172
- const Component = component || FallbackComponent;
173
- return React.createElement(Component, i18nProps, translation);
174
- }
175
- const RenderFragment = ({ children }) => {
176
- return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
52
+ return /* @__PURE__ */ React__default.createElement(LinguiContext.Provider, { value: context }, children);
177
53
  };
178
54
 
179
55
  function Trans(props) {
180
56
  const lingui = useLingui();
181
- return React.createElement(TransNoContext, { ...props, lingui });
57
+ return React__default.createElement(server.TransNoContext, { ...props, lingui });
182
58
  }
183
59
 
184
60
  exports.I18nProvider = I18nProvider;
@@ -0,0 +1,20 @@
1
+ import React, { ComponentType, FunctionComponent } from 'react';
2
+ import { I18n } from '@lingui/core';
3
+ import { TransRenderProps, TransProps } from './server.cjs';
4
+ export { TransRenderCallbackOrComponent } from './server.cjs';
5
+
6
+ type I18nContext = {
7
+ i18n: I18n;
8
+ _: I18n["_"];
9
+ defaultComponent?: ComponentType<TransRenderProps>;
10
+ };
11
+ type I18nProviderProps = Omit<I18nContext, "_"> & {
12
+ children?: React.ReactNode;
13
+ };
14
+ declare const LinguiContext: React.Context<I18nContext | null>;
15
+ declare function useLingui(): I18nContext;
16
+ declare const I18nProvider: FunctionComponent<I18nProviderProps>;
17
+
18
+ declare function Trans(props: TransProps): React.ReactElement<any, any> | null;
19
+
20
+ export { type I18nContext, I18nProvider, type I18nProviderProps, LinguiContext, Trans, TransProps, TransRenderProps, useLingui };
@@ -0,0 +1,20 @@
1
+ import React, { ComponentType, FunctionComponent } from 'react';
2
+ import { I18n } from '@lingui/core';
3
+ import { TransRenderProps, TransProps } from './server.mjs';
4
+ export { TransRenderCallbackOrComponent } from './server.mjs';
5
+
6
+ type I18nContext = {
7
+ i18n: I18n;
8
+ _: I18n["_"];
9
+ defaultComponent?: ComponentType<TransRenderProps>;
10
+ };
11
+ type I18nProviderProps = Omit<I18nContext, "_"> & {
12
+ children?: React.ReactNode;
13
+ };
14
+ declare const LinguiContext: React.Context<I18nContext | null>;
15
+ declare function useLingui(): I18nContext;
16
+ declare const I18nProvider: FunctionComponent<I18nProviderProps>;
17
+
18
+ declare function Trans(props: TransProps): React.ReactElement<any, any> | null;
19
+
20
+ export { type I18nContext, I18nProvider, type I18nProviderProps, LinguiContext, Trans, TransProps, TransRenderProps, useLingui };
package/dist/index.d.ts CHANGED
@@ -1,31 +1,7 @@
1
1
  import React, { ComponentType, FunctionComponent } from 'react';
2
- import { MessageOptions, I18n } from '@lingui/core';
3
-
4
- type TransRenderProps = {
5
- id: string;
6
- translation: React.ReactNode;
7
- children: React.ReactNode;
8
- message?: string | null;
9
- isTranslated: boolean;
10
- };
11
- type TransRenderCallbackOrComponent = {
12
- component?: undefined;
13
- render?: ((props: TransRenderProps) => React.ReactElement<any, any>) | null;
14
- } | {
15
- component?: React.ComponentType<TransRenderProps> | null;
16
- render?: undefined;
17
- };
18
- type TransProps = {
19
- id: string;
20
- message?: string;
21
- values?: Record<string, unknown>;
22
- components?: {
23
- [key: string]: React.ElementType | any;
24
- };
25
- formats?: MessageOptions["formats"];
26
- comment?: string;
27
- children?: React.ReactNode;
28
- } & TransRenderCallbackOrComponent;
2
+ import { I18n } from '@lingui/core';
3
+ import { TransRenderProps, TransProps } from './server.js';
4
+ export { TransRenderCallbackOrComponent } from './server.js';
29
5
 
30
6
  type I18nContext = {
31
7
  i18n: I18n;
@@ -41,4 +17,4 @@ declare const I18nProvider: FunctionComponent<I18nProviderProps>;
41
17
 
42
18
  declare function Trans(props: TransProps): React.ReactElement<any, any> | null;
43
19
 
44
- export { I18nContext, I18nProvider, I18nProviderProps, LinguiContext, Trans, TransProps, TransRenderCallbackOrComponent, TransRenderProps, useLingui };
20
+ export { type I18nContext, I18nProvider, type I18nProviderProps, LinguiContext, Trans, TransProps, TransRenderProps, useLingui };
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { TransNoContext } from './server.mjs';
2
3
 
3
4
  const LinguiContext = React.createContext(null);
4
5
  function useLingui() {
@@ -45,135 +46,6 @@ const I18nProvider = ({
45
46
  return /* @__PURE__ */ React.createElement(LinguiContext.Provider, { value: context }, children);
46
47
  };
47
48
 
48
- const tagRe = /<([a-zA-Z0-9]+)>(.*?)<\/\1>|<([a-zA-Z0-9]+)\/>/;
49
- const nlRe = /(?:\r\n|\r|\n)/g;
50
- const voidElementTags = {
51
- area: true,
52
- base: true,
53
- br: true,
54
- col: true,
55
- embed: true,
56
- hr: true,
57
- img: true,
58
- input: true,
59
- keygen: true,
60
- link: true,
61
- meta: true,
62
- param: true,
63
- source: true,
64
- track: true,
65
- wbr: true,
66
- menuitem: true
67
- };
68
- function formatElements(value, elements = {}) {
69
- const uniqueId = makeCounter(0, "$lingui$");
70
- const parts = value.replace(nlRe, "").split(tagRe);
71
- if (parts.length === 1)
72
- return value;
73
- const tree = [];
74
- const before = parts.shift();
75
- if (before)
76
- tree.push(before);
77
- for (const [index, children, after] of getElements(parts)) {
78
- let element = typeof index !== "undefined" ? elements[index] : void 0;
79
- if (!element || voidElementTags[element.type] && children) {
80
- if (!element) {
81
- console.error(
82
- `Can't use element at index '${index}' as it is not declared in the original translation`
83
- );
84
- } else {
85
- console.error(
86
- `${element.type} is a void element tag therefore it must have no children`
87
- );
88
- }
89
- element = React.createElement(React.Fragment);
90
- }
91
- if (Array.isArray(element)) {
92
- element = React.createElement(React.Fragment, {}, element);
93
- }
94
- tree.push(
95
- React.cloneElement(
96
- element,
97
- { key: uniqueId() },
98
- // format children for pair tags
99
- // unpaired tags might have children if it's a component passed as a variable
100
- children ? formatElements(children, elements) : element.props.children
101
- )
102
- );
103
- if (after)
104
- tree.push(after);
105
- }
106
- return tree;
107
- }
108
- function getElements(parts) {
109
- if (!parts.length)
110
- return [];
111
- const [paired, children, unpaired, after] = parts.slice(0, 4);
112
- const triple = [paired || unpaired, children || "", after];
113
- return [triple].concat(getElements(parts.slice(4, parts.length)));
114
- }
115
- const makeCounter = (count = 0, prefix = "") => () => `${prefix}_${count++}`;
116
-
117
- function TransNoContext(props) {
118
- const {
119
- render,
120
- component,
121
- id,
122
- message,
123
- formats,
124
- lingui: { i18n, defaultComponent }
125
- } = props;
126
- const values = { ...props.values };
127
- const components = { ...props.components };
128
- if (values) {
129
- Object.keys(values).forEach((key) => {
130
- const value = values[key];
131
- const valueIsReactEl = React.isValidElement(value) || Array.isArray(value) && value.every(React.isValidElement);
132
- if (!valueIsReactEl)
133
- return;
134
- const index = Object.keys(components).length;
135
- components[index] = value;
136
- values[key] = `<${index}/>`;
137
- });
138
- }
139
- const _translation = i18n && typeof i18n._ === "function" ? i18n._(id, values, { message, formats }) : id;
140
- const translation = _translation ? formatElements(_translation, components) : null;
141
- if (render === null || component === null) {
142
- return translation;
143
- }
144
- const FallbackComponent = defaultComponent || RenderFragment;
145
- const i18nProps = {
146
- id,
147
- message,
148
- translation,
149
- isTranslated: id !== translation && message !== translation,
150
- children: translation
151
- // for type-compatibility with `component` prop
152
- };
153
- if (render && component) {
154
- console.error(
155
- "You can't use both `component` and `render` prop at the same time. `component` is ignored."
156
- );
157
- } else if (render && typeof render !== "function") {
158
- console.error(
159
- `Invalid value supplied to prop \`render\`. It must be a function, provided ${render}`
160
- );
161
- } else if (component && typeof component !== "function") {
162
- console.error(
163
- `Invalid value supplied to prop \`component\`. It must be a React component, provided ${component}`
164
- );
165
- return React.createElement(FallbackComponent, i18nProps, translation);
166
- }
167
- if (typeof render === "function") {
168
- return render(i18nProps);
169
- }
170
- const Component = component || FallbackComponent;
171
- return React.createElement(Component, i18nProps, translation);
172
- }
173
- const RenderFragment = ({ children }) => {
174
- return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
175
- };
176
-
177
49
  function Trans(props) {
178
50
  const lingui = useLingui();
179
51
  return React.createElement(TransNoContext, { ...props, lingui });
@@ -0,0 +1,139 @@
1
+ 'use strict';
2
+
3
+ const React = require('react');
4
+
5
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
6
+
7
+ const React__default = /*#__PURE__*/_interopDefaultCompat(React);
8
+
9
+ const tagRe = /<([a-zA-Z0-9]+)>(.*?)<\/\1>|<([a-zA-Z0-9]+)\/>/;
10
+ const nlRe = /(?:\r\n|\r|\n)/g;
11
+ const voidElementTags = {
12
+ area: true,
13
+ base: true,
14
+ br: true,
15
+ col: true,
16
+ embed: true,
17
+ hr: true,
18
+ img: true,
19
+ input: true,
20
+ keygen: true,
21
+ link: true,
22
+ meta: true,
23
+ param: true,
24
+ source: true,
25
+ track: true,
26
+ wbr: true,
27
+ menuitem: true
28
+ };
29
+ function formatElements(value, elements = {}) {
30
+ const uniqueId = makeCounter(0, "$lingui$");
31
+ const parts = value.replace(nlRe, "").split(tagRe);
32
+ if (parts.length === 1)
33
+ return value;
34
+ const tree = [];
35
+ const before = parts.shift();
36
+ if (before)
37
+ tree.push(before);
38
+ for (const [index, children, after] of getElements(parts)) {
39
+ let element = typeof index !== "undefined" ? elements[index] : void 0;
40
+ if (!element || voidElementTags[element.type] && children) {
41
+ if (!element) {
42
+ console.error(
43
+ `Can't use element at index '${index}' as it is not declared in the original translation`
44
+ );
45
+ } else {
46
+ console.error(
47
+ `${element.type} is a void element tag therefore it must have no children`
48
+ );
49
+ }
50
+ element = React__default.createElement(React__default.Fragment);
51
+ }
52
+ if (Array.isArray(element)) {
53
+ element = React__default.createElement(React__default.Fragment, {}, element);
54
+ }
55
+ tree.push(
56
+ React__default.cloneElement(
57
+ element,
58
+ { key: uniqueId() },
59
+ // format children for pair tags
60
+ // unpaired tags might have children if it's a component passed as a variable
61
+ children ? formatElements(children, elements) : element.props.children
62
+ )
63
+ );
64
+ if (after)
65
+ tree.push(after);
66
+ }
67
+ return tree;
68
+ }
69
+ function getElements(parts) {
70
+ if (!parts.length)
71
+ return [];
72
+ const [paired, children, unpaired, after] = parts.slice(0, 4);
73
+ const triple = [paired || unpaired, children || "", after];
74
+ return [triple].concat(getElements(parts.slice(4, parts.length)));
75
+ }
76
+ const makeCounter = (count = 0, prefix = "") => () => `${prefix}_${count++}`;
77
+
78
+ function TransNoContext(props) {
79
+ const {
80
+ render,
81
+ component,
82
+ id,
83
+ message,
84
+ formats,
85
+ lingui: { i18n, defaultComponent }
86
+ } = props;
87
+ const values = { ...props.values };
88
+ const components = { ...props.components };
89
+ if (values) {
90
+ Object.keys(values).forEach((key) => {
91
+ const value = values[key];
92
+ const valueIsReactEl = React__default.isValidElement(value) || Array.isArray(value) && value.every(React__default.isValidElement);
93
+ if (!valueIsReactEl)
94
+ return;
95
+ const index = Object.keys(components).length;
96
+ components[index] = value;
97
+ values[key] = `<${index}/>`;
98
+ });
99
+ }
100
+ const _translation = i18n && typeof i18n._ === "function" ? i18n._(id, values, { message, formats }) : id;
101
+ const translation = _translation ? formatElements(_translation, components) : null;
102
+ if (render === null || component === null) {
103
+ return translation;
104
+ }
105
+ const FallbackComponent = defaultComponent || RenderFragment;
106
+ const i18nProps = {
107
+ id,
108
+ message,
109
+ translation,
110
+ // TODO vonovak - remove isTranslated prop in v5 release
111
+ isTranslated: id !== translation && message !== translation,
112
+ children: translation
113
+ // for type-compatibility with `component` prop
114
+ };
115
+ if (render && component) {
116
+ console.error(
117
+ "You can't use both `component` and `render` prop at the same time. `component` is ignored."
118
+ );
119
+ } else if (render && typeof render !== "function") {
120
+ console.error(
121
+ `Invalid value supplied to prop \`render\`. It must be a function, provided ${render}`
122
+ );
123
+ } else if (component && typeof component !== "function") {
124
+ console.error(
125
+ `Invalid value supplied to prop \`component\`. It must be a React component, provided ${component}`
126
+ );
127
+ return React__default.createElement(FallbackComponent, i18nProps, translation);
128
+ }
129
+ if (typeof render === "function") {
130
+ return render(i18nProps);
131
+ }
132
+ const Component = component || FallbackComponent;
133
+ return React__default.createElement(Component, i18nProps, translation);
134
+ }
135
+ const RenderFragment = ({ children }) => {
136
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, children);
137
+ };
138
+
139
+ exports.TransNoContext = TransNoContext;
@@ -0,0 +1,45 @@
1
+ import React, { ComponentType } from 'react';
2
+ import { MessageOptions, I18n } from '@lingui/core';
3
+
4
+ type TransRenderProps = {
5
+ id: string;
6
+ translation: React.ReactNode;
7
+ children: React.ReactNode;
8
+ message?: string | null;
9
+ /**
10
+ * @deprecated isTranslated prop is undocumented and buggy. It'll be removed in v5 release.
11
+ * */
12
+ isTranslated: boolean;
13
+ };
14
+ type TransRenderCallbackOrComponent = {
15
+ component?: undefined;
16
+ render?: ((props: TransRenderProps) => React.ReactElement<any, any>) | null;
17
+ } | {
18
+ component?: React.ComponentType<TransRenderProps> | null;
19
+ render?: undefined;
20
+ };
21
+ type TransProps = {
22
+ id: string;
23
+ message?: string;
24
+ values?: Record<string, unknown>;
25
+ components?: {
26
+ [key: string]: React.ElementType | any;
27
+ };
28
+ formats?: MessageOptions["formats"];
29
+ comment?: string;
30
+ children?: React.ReactNode;
31
+ } & TransRenderCallbackOrComponent;
32
+ /**
33
+ * Version of `<Trans>` component without using a Provider/Context React feature.
34
+ * Primarily made for support React Server Components (RSC)
35
+ *
36
+ * @experimental the api of this component is not stabilized yet.
37
+ */
38
+ declare function TransNoContext(props: TransProps & {
39
+ lingui: {
40
+ i18n: I18n;
41
+ defaultComponent?: ComponentType<TransRenderProps>;
42
+ };
43
+ }): React.ReactElement<any, any> | null;
44
+
45
+ export { TransNoContext, type TransProps, type TransRenderCallbackOrComponent, type TransRenderProps };
@@ -0,0 +1,45 @@
1
+ import React, { ComponentType } from 'react';
2
+ import { MessageOptions, I18n } from '@lingui/core';
3
+
4
+ type TransRenderProps = {
5
+ id: string;
6
+ translation: React.ReactNode;
7
+ children: React.ReactNode;
8
+ message?: string | null;
9
+ /**
10
+ * @deprecated isTranslated prop is undocumented and buggy. It'll be removed in v5 release.
11
+ * */
12
+ isTranslated: boolean;
13
+ };
14
+ type TransRenderCallbackOrComponent = {
15
+ component?: undefined;
16
+ render?: ((props: TransRenderProps) => React.ReactElement<any, any>) | null;
17
+ } | {
18
+ component?: React.ComponentType<TransRenderProps> | null;
19
+ render?: undefined;
20
+ };
21
+ type TransProps = {
22
+ id: string;
23
+ message?: string;
24
+ values?: Record<string, unknown>;
25
+ components?: {
26
+ [key: string]: React.ElementType | any;
27
+ };
28
+ formats?: MessageOptions["formats"];
29
+ comment?: string;
30
+ children?: React.ReactNode;
31
+ } & TransRenderCallbackOrComponent;
32
+ /**
33
+ * Version of `<Trans>` component without using a Provider/Context React feature.
34
+ * Primarily made for support React Server Components (RSC)
35
+ *
36
+ * @experimental the api of this component is not stabilized yet.
37
+ */
38
+ declare function TransNoContext(props: TransProps & {
39
+ lingui: {
40
+ i18n: I18n;
41
+ defaultComponent?: ComponentType<TransRenderProps>;
42
+ };
43
+ }): React.ReactElement<any, any> | null;
44
+
45
+ export { TransNoContext, type TransProps, type TransRenderCallbackOrComponent, type TransRenderProps };
@@ -0,0 +1,45 @@
1
+ import React, { ComponentType } from 'react';
2
+ import { MessageOptions, I18n } from '@lingui/core';
3
+
4
+ type TransRenderProps = {
5
+ id: string;
6
+ translation: React.ReactNode;
7
+ children: React.ReactNode;
8
+ message?: string | null;
9
+ /**
10
+ * @deprecated isTranslated prop is undocumented and buggy. It'll be removed in v5 release.
11
+ * */
12
+ isTranslated: boolean;
13
+ };
14
+ type TransRenderCallbackOrComponent = {
15
+ component?: undefined;
16
+ render?: ((props: TransRenderProps) => React.ReactElement<any, any>) | null;
17
+ } | {
18
+ component?: React.ComponentType<TransRenderProps> | null;
19
+ render?: undefined;
20
+ };
21
+ type TransProps = {
22
+ id: string;
23
+ message?: string;
24
+ values?: Record<string, unknown>;
25
+ components?: {
26
+ [key: string]: React.ElementType | any;
27
+ };
28
+ formats?: MessageOptions["formats"];
29
+ comment?: string;
30
+ children?: React.ReactNode;
31
+ } & TransRenderCallbackOrComponent;
32
+ /**
33
+ * Version of `<Trans>` component without using a Provider/Context React feature.
34
+ * Primarily made for support React Server Components (RSC)
35
+ *
36
+ * @experimental the api of this component is not stabilized yet.
37
+ */
38
+ declare function TransNoContext(props: TransProps & {
39
+ lingui: {
40
+ i18n: I18n;
41
+ defaultComponent?: ComponentType<TransRenderProps>;
42
+ };
43
+ }): React.ReactElement<any, any> | null;
44
+
45
+ export { TransNoContext, type TransProps, type TransRenderCallbackOrComponent, type TransRenderProps };
@@ -0,0 +1,133 @@
1
+ import React from 'react';
2
+
3
+ const tagRe = /<([a-zA-Z0-9]+)>(.*?)<\/\1>|<([a-zA-Z0-9]+)\/>/;
4
+ const nlRe = /(?:\r\n|\r|\n)/g;
5
+ const voidElementTags = {
6
+ area: true,
7
+ base: true,
8
+ br: true,
9
+ col: true,
10
+ embed: true,
11
+ hr: true,
12
+ img: true,
13
+ input: true,
14
+ keygen: true,
15
+ link: true,
16
+ meta: true,
17
+ param: true,
18
+ source: true,
19
+ track: true,
20
+ wbr: true,
21
+ menuitem: true
22
+ };
23
+ function formatElements(value, elements = {}) {
24
+ const uniqueId = makeCounter(0, "$lingui$");
25
+ const parts = value.replace(nlRe, "").split(tagRe);
26
+ if (parts.length === 1)
27
+ return value;
28
+ const tree = [];
29
+ const before = parts.shift();
30
+ if (before)
31
+ tree.push(before);
32
+ for (const [index, children, after] of getElements(parts)) {
33
+ let element = typeof index !== "undefined" ? elements[index] : void 0;
34
+ if (!element || voidElementTags[element.type] && children) {
35
+ if (!element) {
36
+ console.error(
37
+ `Can't use element at index '${index}' as it is not declared in the original translation`
38
+ );
39
+ } else {
40
+ console.error(
41
+ `${element.type} is a void element tag therefore it must have no children`
42
+ );
43
+ }
44
+ element = React.createElement(React.Fragment);
45
+ }
46
+ if (Array.isArray(element)) {
47
+ element = React.createElement(React.Fragment, {}, element);
48
+ }
49
+ tree.push(
50
+ React.cloneElement(
51
+ element,
52
+ { key: uniqueId() },
53
+ // format children for pair tags
54
+ // unpaired tags might have children if it's a component passed as a variable
55
+ children ? formatElements(children, elements) : element.props.children
56
+ )
57
+ );
58
+ if (after)
59
+ tree.push(after);
60
+ }
61
+ return tree;
62
+ }
63
+ function getElements(parts) {
64
+ if (!parts.length)
65
+ return [];
66
+ const [paired, children, unpaired, after] = parts.slice(0, 4);
67
+ const triple = [paired || unpaired, children || "", after];
68
+ return [triple].concat(getElements(parts.slice(4, parts.length)));
69
+ }
70
+ const makeCounter = (count = 0, prefix = "") => () => `${prefix}_${count++}`;
71
+
72
+ function TransNoContext(props) {
73
+ const {
74
+ render,
75
+ component,
76
+ id,
77
+ message,
78
+ formats,
79
+ lingui: { i18n, defaultComponent }
80
+ } = props;
81
+ const values = { ...props.values };
82
+ const components = { ...props.components };
83
+ if (values) {
84
+ Object.keys(values).forEach((key) => {
85
+ const value = values[key];
86
+ const valueIsReactEl = React.isValidElement(value) || Array.isArray(value) && value.every(React.isValidElement);
87
+ if (!valueIsReactEl)
88
+ return;
89
+ const index = Object.keys(components).length;
90
+ components[index] = value;
91
+ values[key] = `<${index}/>`;
92
+ });
93
+ }
94
+ const _translation = i18n && typeof i18n._ === "function" ? i18n._(id, values, { message, formats }) : id;
95
+ const translation = _translation ? formatElements(_translation, components) : null;
96
+ if (render === null || component === null) {
97
+ return translation;
98
+ }
99
+ const FallbackComponent = defaultComponent || RenderFragment;
100
+ const i18nProps = {
101
+ id,
102
+ message,
103
+ translation,
104
+ // TODO vonovak - remove isTranslated prop in v5 release
105
+ isTranslated: id !== translation && message !== translation,
106
+ children: translation
107
+ // for type-compatibility with `component` prop
108
+ };
109
+ if (render && component) {
110
+ console.error(
111
+ "You can't use both `component` and `render` prop at the same time. `component` is ignored."
112
+ );
113
+ } else if (render && typeof render !== "function") {
114
+ console.error(
115
+ `Invalid value supplied to prop \`render\`. It must be a function, provided ${render}`
116
+ );
117
+ } else if (component && typeof component !== "function") {
118
+ console.error(
119
+ `Invalid value supplied to prop \`component\`. It must be a React component, provided ${component}`
120
+ );
121
+ return React.createElement(FallbackComponent, i18nProps, translation);
122
+ }
123
+ if (typeof render === "function") {
124
+ return render(i18nProps);
125
+ }
126
+ const Component = component || FallbackComponent;
127
+ return React.createElement(Component, i18nProps, translation);
128
+ }
129
+ const RenderFragment = ({ children }) => {
130
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
131
+ };
132
+
133
+ export { TransNoContext };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingui/react",
3
- "version": "4.4.2",
3
+ "version": "4.6.0",
4
4
  "sideEffects": false,
5
5
  "description": "React components for translations",
6
6
  "main": "./dist/index.cjs",
@@ -43,14 +43,24 @@
43
43
  "exports": {
44
44
  ".": {
45
45
  "require": {
46
- "types": "./dist/index.d.ts",
46
+ "types": "./dist/index.d.cts",
47
47
  "default": "./dist/index.cjs"
48
48
  },
49
49
  "import": {
50
- "types": "./dist/index.d.ts",
50
+ "types": "./dist/index.d.mts",
51
51
  "default": "./dist/index.mjs"
52
52
  }
53
53
  },
54
+ "./server": {
55
+ "require": {
56
+ "types": "./dist/server.d.ts",
57
+ "default": "./dist/server.cjs"
58
+ },
59
+ "import": {
60
+ "types": "./dist/server.d.ts",
61
+ "default": "./dist/server.mjs"
62
+ }
63
+ },
54
64
  "./package.json": "./package.json"
55
65
  },
56
66
  "files": [
@@ -63,7 +73,7 @@
63
73
  },
64
74
  "dependencies": {
65
75
  "@babel/runtime": "^7.20.13",
66
- "@lingui/core": "4.4.2"
76
+ "@lingui/core": "4.6.0"
67
77
  },
68
78
  "devDependencies": {
69
79
  "@lingui/jest-mocks": "*",
@@ -73,7 +83,7 @@
73
83
  "eslint-plugin-react-hooks": "^4.6.0",
74
84
  "react": "^18.2.0",
75
85
  "react-dom": "^18.2.0",
76
- "unbuild": "^1.1.2"
86
+ "unbuild": "2.0.0"
77
87
  },
78
- "gitHead": "316a004ec82721fcceb8f3c4a5aeb4a48d367927"
88
+ "gitHead": "2afa0efb2d0cd1d47adc76e1eec9f5e57e34ae18"
79
89
  }