@lingui/react 4.3.0 → 4.4.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/dist/index.cjs +46 -24
- package/dist/index.d.ts +8 -6
- package/dist/index.mjs +48 -26
- package/package.json +5 -3
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const React = require('react');
|
|
4
|
+
const shim = require('use-sync-external-store/shim');
|
|
4
5
|
|
|
5
6
|
const LinguiContext = React.createContext(null);
|
|
6
7
|
function useLingui() {
|
|
@@ -17,33 +18,44 @@ const I18nProvider = ({
|
|
|
17
18
|
defaultComponent,
|
|
18
19
|
children
|
|
19
20
|
}) => {
|
|
20
|
-
const latestKnownLocale = React.useRef(i18n.locale);
|
|
21
21
|
const makeContext = React.useCallback(
|
|
22
22
|
() => ({
|
|
23
23
|
i18n,
|
|
24
|
-
defaultComponent
|
|
24
|
+
defaultComponent,
|
|
25
|
+
_: i18n.t.bind(i18n)
|
|
25
26
|
}),
|
|
26
27
|
[i18n, defaultComponent]
|
|
27
28
|
);
|
|
28
|
-
const
|
|
29
|
-
React.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
29
|
+
const context = React.useRef(makeContext());
|
|
30
|
+
const subscribe = React.useCallback(
|
|
31
|
+
(onStoreChange) => {
|
|
32
|
+
const renderWithFreshContext = () => {
|
|
33
|
+
context.current = makeContext();
|
|
34
|
+
onStoreChange();
|
|
35
|
+
};
|
|
36
|
+
const propsChanged = context.current.i18n !== i18n || context.current.defaultComponent !== defaultComponent;
|
|
37
|
+
if (propsChanged) {
|
|
38
|
+
renderWithFreshContext();
|
|
39
|
+
}
|
|
40
|
+
return i18n.on("change", renderWithFreshContext);
|
|
41
|
+
},
|
|
42
|
+
[makeContext, i18n, defaultComponent]
|
|
43
|
+
);
|
|
44
|
+
const getSnapshot = React.useCallback(() => {
|
|
45
|
+
return context.current;
|
|
46
|
+
}, []);
|
|
47
|
+
const contextObject = shim.useSyncExternalStore(
|
|
48
|
+
subscribe,
|
|
49
|
+
getSnapshot,
|
|
50
|
+
getSnapshot
|
|
51
|
+
);
|
|
52
|
+
if (!contextObject.i18n.locale) {
|
|
41
53
|
process.env.NODE_ENV === "development" && console.log(
|
|
42
54
|
"I18nProvider rendered `null`. A call to `i18n.activate` needs to happen in order for translations to be activated and for the I18nProvider to render.This is not an error but an informational message logged only in development."
|
|
43
55
|
);
|
|
44
56
|
return null;
|
|
45
57
|
}
|
|
46
|
-
return /* @__PURE__ */ React.createElement(LinguiContext.Provider, { value:
|
|
58
|
+
return /* @__PURE__ */ React.createElement(LinguiContext.Provider, { value: contextObject }, children);
|
|
47
59
|
};
|
|
48
60
|
|
|
49
61
|
const tagRe = /<([a-zA-Z0-9]+)>(.*?)<\/\1>|<([a-zA-Z0-9]+)\/>/;
|
|
@@ -76,7 +88,7 @@ function formatElements(value, elements = {}) {
|
|
|
76
88
|
if (before)
|
|
77
89
|
tree.push(before);
|
|
78
90
|
for (const [index, children, after] of getElements(parts)) {
|
|
79
|
-
let element = elements[index];
|
|
91
|
+
let element = typeof index !== "undefined" ? elements[index] : void 0;
|
|
80
92
|
if (!element || voidElementTags[element.type] && children) {
|
|
81
93
|
if (!element) {
|
|
82
94
|
console.error(
|
|
@@ -110,21 +122,26 @@ function getElements(parts) {
|
|
|
110
122
|
if (!parts.length)
|
|
111
123
|
return [];
|
|
112
124
|
const [paired, children, unpaired, after] = parts.slice(0, 4);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
);
|
|
125
|
+
const triple = [paired || unpaired, children || "", after];
|
|
126
|
+
return [triple].concat(getElements(parts.slice(4, parts.length)));
|
|
116
127
|
}
|
|
117
128
|
const makeCounter = (count = 0, prefix = "") => () => `${prefix}_${count++}`;
|
|
118
129
|
|
|
119
|
-
function
|
|
120
|
-
const {
|
|
121
|
-
|
|
130
|
+
function TransNoContext(props) {
|
|
131
|
+
const {
|
|
132
|
+
render,
|
|
133
|
+
component,
|
|
134
|
+
id,
|
|
135
|
+
message,
|
|
136
|
+
formats,
|
|
137
|
+
lingui: { i18n, defaultComponent }
|
|
138
|
+
} = props;
|
|
122
139
|
const values = { ...props.values };
|
|
123
140
|
const components = { ...props.components };
|
|
124
141
|
if (values) {
|
|
125
142
|
Object.keys(values).forEach((key) => {
|
|
126
143
|
const value = values[key];
|
|
127
|
-
const valueIsReactEl = React.isValidElement(value) || Array.isArray(value) && value.every(
|
|
144
|
+
const valueIsReactEl = React.isValidElement(value) || Array.isArray(value) && value.every(React.isValidElement);
|
|
128
145
|
if (!valueIsReactEl)
|
|
129
146
|
return;
|
|
130
147
|
const index = Object.keys(components).length;
|
|
@@ -170,6 +187,11 @@ const RenderFragment = ({ children }) => {
|
|
|
170
187
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
|
|
171
188
|
};
|
|
172
189
|
|
|
190
|
+
function Trans(props) {
|
|
191
|
+
const lingui = useLingui();
|
|
192
|
+
return React.createElement(TransNoContext, { ...props, lingui });
|
|
193
|
+
}
|
|
194
|
+
|
|
173
195
|
exports.I18nProvider = I18nProvider;
|
|
174
196
|
exports.LinguiContext = LinguiContext;
|
|
175
197
|
exports.Trans = Trans;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { ComponentType, FunctionComponent } from 'react';
|
|
2
|
-
import { I18n } from '@lingui/core';
|
|
2
|
+
import { MessageOptions, I18n } from '@lingui/core';
|
|
3
3
|
|
|
4
4
|
type TransRenderProps = {
|
|
5
5
|
id: string;
|
|
@@ -10,7 +10,7 @@ type TransRenderProps = {
|
|
|
10
10
|
};
|
|
11
11
|
type TransRenderCallbackOrComponent = {
|
|
12
12
|
component?: undefined;
|
|
13
|
-
render?: (props: TransRenderProps) => React.ReactElement<any, any> | null;
|
|
13
|
+
render?: ((props: TransRenderProps) => React.ReactElement<any, any>) | null;
|
|
14
14
|
} | {
|
|
15
15
|
component?: React.ComponentType<TransRenderProps> | null;
|
|
16
16
|
render?: undefined;
|
|
@@ -22,21 +22,23 @@ type TransProps = {
|
|
|
22
22
|
components?: {
|
|
23
23
|
[key: string]: React.ElementType | any;
|
|
24
24
|
};
|
|
25
|
-
formats?:
|
|
25
|
+
formats?: MessageOptions["formats"];
|
|
26
26
|
comment?: string;
|
|
27
27
|
children?: React.ReactNode;
|
|
28
28
|
} & TransRenderCallbackOrComponent;
|
|
29
|
-
declare function Trans(props: TransProps): React.ReactElement<any, any> | null;
|
|
30
29
|
|
|
31
30
|
type I18nContext = {
|
|
32
31
|
i18n: I18n;
|
|
32
|
+
_: I18n["_"];
|
|
33
33
|
defaultComponent?: ComponentType<TransRenderProps>;
|
|
34
34
|
};
|
|
35
|
-
type I18nProviderProps = I18nContext & {
|
|
35
|
+
type I18nProviderProps = Omit<I18nContext, "_"> & {
|
|
36
36
|
children?: React.ReactNode;
|
|
37
37
|
};
|
|
38
|
-
declare const LinguiContext: React.Context<I18nContext>;
|
|
38
|
+
declare const LinguiContext: React.Context<I18nContext | null>;
|
|
39
39
|
declare function useLingui(): I18nContext;
|
|
40
40
|
declare const I18nProvider: FunctionComponent<I18nProviderProps>;
|
|
41
41
|
|
|
42
|
+
declare function Trans(props: TransProps): React.ReactElement<any, any> | null;
|
|
43
|
+
|
|
42
44
|
export { I18nContext, I18nProvider, I18nProviderProps, LinguiContext, Trans, TransProps, TransRenderCallbackOrComponent, TransRenderProps, useLingui };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useCallback, useRef } from 'react';
|
|
2
|
+
import { useSyncExternalStore } from 'use-sync-external-store/shim';
|
|
2
3
|
|
|
3
4
|
const LinguiContext = React.createContext(null);
|
|
4
5
|
function useLingui() {
|
|
@@ -15,33 +16,44 @@ const I18nProvider = ({
|
|
|
15
16
|
defaultComponent,
|
|
16
17
|
children
|
|
17
18
|
}) => {
|
|
18
|
-
const
|
|
19
|
-
const makeContext = React.useCallback(
|
|
19
|
+
const makeContext = useCallback(
|
|
20
20
|
() => ({
|
|
21
21
|
i18n,
|
|
22
|
-
defaultComponent
|
|
22
|
+
defaultComponent,
|
|
23
|
+
_: i18n.t.bind(i18n)
|
|
23
24
|
}),
|
|
24
25
|
[i18n, defaultComponent]
|
|
25
26
|
);
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
const context = useRef(makeContext());
|
|
28
|
+
const subscribe = useCallback(
|
|
29
|
+
(onStoreChange) => {
|
|
30
|
+
const renderWithFreshContext = () => {
|
|
31
|
+
context.current = makeContext();
|
|
32
|
+
onStoreChange();
|
|
33
|
+
};
|
|
34
|
+
const propsChanged = context.current.i18n !== i18n || context.current.defaultComponent !== defaultComponent;
|
|
35
|
+
if (propsChanged) {
|
|
36
|
+
renderWithFreshContext();
|
|
37
|
+
}
|
|
38
|
+
return i18n.on("change", renderWithFreshContext);
|
|
39
|
+
},
|
|
40
|
+
[makeContext, i18n, defaultComponent]
|
|
41
|
+
);
|
|
42
|
+
const getSnapshot = useCallback(() => {
|
|
43
|
+
return context.current;
|
|
44
|
+
}, []);
|
|
45
|
+
const contextObject = useSyncExternalStore(
|
|
46
|
+
subscribe,
|
|
47
|
+
getSnapshot,
|
|
48
|
+
getSnapshot
|
|
49
|
+
);
|
|
50
|
+
if (!contextObject.i18n.locale) {
|
|
39
51
|
process.env.NODE_ENV === "development" && console.log(
|
|
40
52
|
"I18nProvider rendered `null`. A call to `i18n.activate` needs to happen in order for translations to be activated and for the I18nProvider to render.This is not an error but an informational message logged only in development."
|
|
41
53
|
);
|
|
42
54
|
return null;
|
|
43
55
|
}
|
|
44
|
-
return /* @__PURE__ */ React.createElement(LinguiContext.Provider, { value:
|
|
56
|
+
return /* @__PURE__ */ React.createElement(LinguiContext.Provider, { value: contextObject }, children);
|
|
45
57
|
};
|
|
46
58
|
|
|
47
59
|
const tagRe = /<([a-zA-Z0-9]+)>(.*?)<\/\1>|<([a-zA-Z0-9]+)\/>/;
|
|
@@ -74,7 +86,7 @@ function formatElements(value, elements = {}) {
|
|
|
74
86
|
if (before)
|
|
75
87
|
tree.push(before);
|
|
76
88
|
for (const [index, children, after] of getElements(parts)) {
|
|
77
|
-
let element = elements[index];
|
|
89
|
+
let element = typeof index !== "undefined" ? elements[index] : void 0;
|
|
78
90
|
if (!element || voidElementTags[element.type] && children) {
|
|
79
91
|
if (!element) {
|
|
80
92
|
console.error(
|
|
@@ -108,21 +120,26 @@ function getElements(parts) {
|
|
|
108
120
|
if (!parts.length)
|
|
109
121
|
return [];
|
|
110
122
|
const [paired, children, unpaired, after] = parts.slice(0, 4);
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
);
|
|
123
|
+
const triple = [paired || unpaired, children || "", after];
|
|
124
|
+
return [triple].concat(getElements(parts.slice(4, parts.length)));
|
|
114
125
|
}
|
|
115
126
|
const makeCounter = (count = 0, prefix = "") => () => `${prefix}_${count++}`;
|
|
116
127
|
|
|
117
|
-
function
|
|
118
|
-
const {
|
|
119
|
-
|
|
128
|
+
function TransNoContext(props) {
|
|
129
|
+
const {
|
|
130
|
+
render,
|
|
131
|
+
component,
|
|
132
|
+
id,
|
|
133
|
+
message,
|
|
134
|
+
formats,
|
|
135
|
+
lingui: { i18n, defaultComponent }
|
|
136
|
+
} = props;
|
|
120
137
|
const values = { ...props.values };
|
|
121
138
|
const components = { ...props.components };
|
|
122
139
|
if (values) {
|
|
123
140
|
Object.keys(values).forEach((key) => {
|
|
124
141
|
const value = values[key];
|
|
125
|
-
const valueIsReactEl = React.isValidElement(value) || Array.isArray(value) && value.every(
|
|
142
|
+
const valueIsReactEl = React.isValidElement(value) || Array.isArray(value) && value.every(React.isValidElement);
|
|
126
143
|
if (!valueIsReactEl)
|
|
127
144
|
return;
|
|
128
145
|
const index = Object.keys(components).length;
|
|
@@ -168,4 +185,9 @@ const RenderFragment = ({ children }) => {
|
|
|
168
185
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
|
|
169
186
|
};
|
|
170
187
|
|
|
188
|
+
function Trans(props) {
|
|
189
|
+
const lingui = useLingui();
|
|
190
|
+
return React.createElement(TransNoContext, { ...props, lingui });
|
|
191
|
+
}
|
|
192
|
+
|
|
171
193
|
export { I18nProvider, LinguiContext, Trans, useLingui };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingui/react",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.1",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"description": "React components for translations",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -63,17 +63,19 @@
|
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"@babel/runtime": "^7.20.13",
|
|
66
|
-
"@lingui/core": "4.
|
|
66
|
+
"@lingui/core": "4.4.1",
|
|
67
|
+
"use-sync-external-store": "^1.2.0"
|
|
67
68
|
},
|
|
68
69
|
"devDependencies": {
|
|
69
70
|
"@lingui/jest-mocks": "*",
|
|
70
71
|
"@testing-library/react": "^14.0.0",
|
|
71
72
|
"@types/react": "^18.2.13",
|
|
73
|
+
"@types/use-sync-external-store": "^0.0.3",
|
|
72
74
|
"eslint-plugin-react": "^7.32.2",
|
|
73
75
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
74
76
|
"react": "^18.2.0",
|
|
75
77
|
"react-dom": "^18.2.0",
|
|
76
78
|
"unbuild": "^1.1.2"
|
|
77
79
|
},
|
|
78
|
-
"gitHead": "
|
|
80
|
+
"gitHead": "e7103c9f06a493e5871086e121f037309b0b742c"
|
|
79
81
|
}
|