@lingui/react 4.4.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 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,7 +18,6 @@ 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,
@@ -26,25 +26,36 @@ const I18nProvider = ({
26
26
  }),
27
27
  [i18n, defaultComponent]
28
28
  );
29
- const [context, setContext] = React.useState(makeContext());
30
- React.useEffect(() => {
31
- const updateContext = () => {
32
- latestKnownLocale.current = i18n.locale;
33
- setContext(makeContext());
34
- };
35
- const unsubscribe = i18n.on("change", updateContext);
36
- if (latestKnownLocale.current !== i18n.locale) {
37
- updateContext();
38
- }
39
- return unsubscribe;
40
- }, [i18n, makeContext]);
41
- if (!latestKnownLocale.current) {
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) {
42
53
  process.env.NODE_ENV === "development" && console.log(
43
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."
44
55
  );
45
56
  return null;
46
57
  }
47
- return /* @__PURE__ */ React.createElement(LinguiContext.Provider, { value: context }, children);
58
+ return /* @__PURE__ */ React.createElement(LinguiContext.Provider, { value: contextObject }, children);
48
59
  };
49
60
 
50
61
  const tagRe = /<([a-zA-Z0-9]+)>(.*?)<\/\1>|<([a-zA-Z0-9]+)\/>/;
@@ -116,10 +127,6 @@ function getElements(parts) {
116
127
  }
117
128
  const makeCounter = (count = 0, prefix = "") => () => `${prefix}_${count++}`;
118
129
 
119
- function Trans(props) {
120
- const lingui = useLingui();
121
- return React.createElement(TransNoContext, { ...props, lingui });
122
- }
123
130
  function TransNoContext(props) {
124
131
  const {
125
132
  render,
@@ -180,8 +187,12 @@ const RenderFragment = ({ children }) => {
180
187
  return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
181
188
  };
182
189
 
190
+ function Trans(props) {
191
+ const lingui = useLingui();
192
+ return React.createElement(TransNoContext, { ...props, lingui });
193
+ }
194
+
183
195
  exports.I18nProvider = I18nProvider;
184
196
  exports.LinguiContext = LinguiContext;
185
197
  exports.Trans = Trans;
186
- exports.TransNoContext = TransNoContext;
187
198
  exports.useLingui = useLingui;
package/dist/index.d.ts CHANGED
@@ -26,19 +26,6 @@ type TransProps = {
26
26
  comment?: string;
27
27
  children?: React.ReactNode;
28
28
  } & TransRenderCallbackOrComponent;
29
- declare function Trans(props: TransProps): React.ReactElement<any, any> | null;
30
- /**
31
- * Version of `<Trans>` component without using a Provider/Context React feature.
32
- * Primarily made for support React Server Components (RSC)
33
- *
34
- * @experimental the api of this component is not stabilized yet.
35
- */
36
- declare function TransNoContext(props: TransProps & {
37
- lingui: {
38
- i18n: I18n;
39
- defaultComponent?: ComponentType<TransRenderProps>;
40
- };
41
- }): React.ReactElement<any, any> | null;
42
29
 
43
30
  type I18nContext = {
44
31
  i18n: I18n;
@@ -52,4 +39,6 @@ declare const LinguiContext: React.Context<I18nContext | null>;
52
39
  declare function useLingui(): I18nContext;
53
40
  declare const I18nProvider: FunctionComponent<I18nProviderProps>;
54
41
 
55
- export { I18nContext, I18nProvider, I18nProviderProps, LinguiContext, Trans, TransNoContext, TransProps, TransRenderCallbackOrComponent, TransRenderProps, useLingui };
42
+ declare function Trans(props: TransProps): React.ReactElement<any, any> | null;
43
+
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,8 +16,7 @@ const I18nProvider = ({
15
16
  defaultComponent,
16
17
  children
17
18
  }) => {
18
- const latestKnownLocale = React.useRef(i18n.locale);
19
- const makeContext = React.useCallback(
19
+ const makeContext = useCallback(
20
20
  () => ({
21
21
  i18n,
22
22
  defaultComponent,
@@ -24,25 +24,36 @@ const I18nProvider = ({
24
24
  }),
25
25
  [i18n, defaultComponent]
26
26
  );
27
- const [context, setContext] = React.useState(makeContext());
28
- React.useEffect(() => {
29
- const updateContext = () => {
30
- latestKnownLocale.current = i18n.locale;
31
- setContext(makeContext());
32
- };
33
- const unsubscribe = i18n.on("change", updateContext);
34
- if (latestKnownLocale.current !== i18n.locale) {
35
- updateContext();
36
- }
37
- return unsubscribe;
38
- }, [i18n, makeContext]);
39
- if (!latestKnownLocale.current) {
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) {
40
51
  process.env.NODE_ENV === "development" && console.log(
41
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."
42
53
  );
43
54
  return null;
44
55
  }
45
- return /* @__PURE__ */ React.createElement(LinguiContext.Provider, { value: context }, children);
56
+ return /* @__PURE__ */ React.createElement(LinguiContext.Provider, { value: contextObject }, children);
46
57
  };
47
58
 
48
59
  const tagRe = /<([a-zA-Z0-9]+)>(.*?)<\/\1>|<([a-zA-Z0-9]+)\/>/;
@@ -114,10 +125,6 @@ function getElements(parts) {
114
125
  }
115
126
  const makeCounter = (count = 0, prefix = "") => () => `${prefix}_${count++}`;
116
127
 
117
- function Trans(props) {
118
- const lingui = useLingui();
119
- return React.createElement(TransNoContext, { ...props, lingui });
120
- }
121
128
  function TransNoContext(props) {
122
129
  const {
123
130
  render,
@@ -178,4 +185,9 @@ const RenderFragment = ({ children }) => {
178
185
  return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
179
186
  };
180
187
 
181
- export { I18nProvider, LinguiContext, Trans, TransNoContext, useLingui };
188
+ function Trans(props) {
189
+ const lingui = useLingui();
190
+ return React.createElement(TransNoContext, { ...props, lingui });
191
+ }
192
+
193
+ export { I18nProvider, LinguiContext, Trans, useLingui };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingui/react",
3
- "version": "4.4.0",
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.4.0"
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": "c36c0340ced1c4b76d5e1c340785932122449ac9"
80
+ "gitHead": "e7103c9f06a493e5871086e121f037309b0b742c"
79
81
  }