Repository: lingui/js-lingui
Pull request #1243 (2022-05-13 16:45:49)

docs: Replace Spectrum and Gitter with Discord

vercel[bot]: **The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Updated |
| :--- | :----- | :------ | :------ |
| **js-lingui** | 🔄 Building ([Inspect](https://vercel.com/lingui-js/js-lingui/4ELAtEUwQ1UyGc8RNtLt4VRGcXEu)) |  | May 13, 2022 at 4:45PM (UTC) |


codecov[bot]: # [Codecov](https://codecov.io/gh/lingui/js-lingui/pull/1243?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lingui) Report
> Merging [#1243](https://codecov.io/gh/lingui/js-lingui/pull/1243?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lingui) (26be240) into [main](https://codecov.io/gh/lingui/js-lingui/commit/d846e5088a84ab194858a06c38ac4fce0c387746?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lingui) (d846e50) will **not change** coverage.
> The diff coverage is `n/a`.

```diff
@@           Coverage Diff           @@
##             main    #1243   +/-   ##
=======================================
  Coverage   81.69%   81.69%           
=======================================
  Files          56       56           
  Lines        1770     1770           
  Branches      491      491           
=======================================
  Hits         1446     1446           
  Misses        194      194           
  Partials      130      130           
```



------

[Continue to review full report at Codecov](https://codecov.io/gh/lingui/js-lingui/pull/1243?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lingui).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lingui)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/lingui/js-lingui/pull/1243?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lingui). Last update [d846e50...26be240](https://codecov.io/gh/lingui/js-lingui/pull/1243?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lingui). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lingui).

Bertg: For some reason the checks on the commit, and on the PR are not the same.
Not sure what happened there. But everything is green.

Patch:
diff --git a/README.md b/README.md
index 6a83179c..65175e79 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@
 [![PRs Welcome][Badge-PRWelcome]][PRWelcome]
 [![Backers on Open Collective][Badge-ocbackers]][ocbackers-local]
 [![Sponsors on Open Collective][Badge-ocsponsors]][ocsponsors-local]
-[![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)][Spectrum]
+[![Join the community on Discord]][Discord]
 
 [**Documentation**][Documentation] · [**Documentation 2.x**](https://js-lingui-git-stable-2x.lingui-js.vercel.app/) · [**Quickstart**](#quickstart) · [**Example**](#example) · [**Support**](#support) · [**Contribute**](#contribute) · [**Licence**](#licence)
 </div>
@@ -45,7 +45,7 @@ Lingui is an easy yet powerful internationalization framework for global project
   React components are additional [3.1 kBs gzipped][BundleReact]. That's less than Redux
   for a full-featured intl library.
 
-- **Active community** - Join us on [Spectrum][Spectrum] to discuss the latest development.
+- **Active community** - Join us on [Discord][Discord] to discuss the latest development.
   At the moment, Lingui is the most active intl project on GitHub.
 
 - **Compatible with react-intl** - Low-level React API is very similar to react-intl
@@ -98,7 +98,7 @@ For more example see the [React tutorial][TutorialReact].
 
 If you are having issues, please let us know.
 
-- Join us at [Gitter](https://gitter.im/lingui/js-lingui) to get almost instant feedback.
+- Join us on [Discord](https://discord.gg/gFWwAYnMtA) to chat with the community.
 - Ask question on [StackOverflow](https://stackoverflow.com/questions/ask?tags=jsLingui)
   and mark it with [Lingui](https://stackoverflow.com/questions/tagged/jslingui) tag.
 - If something doesn't work as documented, documentation is missing or if you just want
@@ -182,4 +182,4 @@ The project is licensed under the [MIT][License] license.
 [ocsponsors-local]: #sponsors
 [BundleReact]: https://bundlephobia.com/result?p=@lingui/react
 [BundleCore]: https://bundlephobia.com/result?p=@lingui/core
-[Spectrum]: https://spectrum.chat/linguijs
+[Discord]: https://discord.gg/gFWwAYnMtA
diff --git a/docs/index.rst b/docs/index.rst
index 8bfbb465..7934f0b2 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -56,7 +56,7 @@ Lightweight and optimized
    That's less than Redux for a full-featured intl library.
 
 Active community
-   Join us on `Gitter`_ to discuss the latest development.
+   Join us on `Discord`_ to discuss the latest development.
    At the moment, Lingui is the most active intl project on GitHub.
 
 Compatible with react-intl
@@ -149,4 +149,4 @@ Indices
 * :ref:`genindex`
 * :ref:`search`
 
-.. _Gitter: https://gitter.im/lingui/js-lingui
+.. _Discord: https://discord.gg/gFWwAYnMtA
diff --git a/docs/misc/react-intl.rst b/docs/misc/react-intl.rst
index 35f7fd84..ee991d8f 100644
--- a/docs/misc/react-intl.rst
+++ b/docs/misc/react-intl.rst
@@ -283,7 +283,7 @@ Discussion
 ==========
 
 Do you have any comments or questions? Please join the discussion at
-`gitter <https://gitter.im/lingui/js-lingui>`_ or raise an
+`Discord <https://discord.gg/gFWwAYnMtA>`_ or raise an
 `issue <https://github.com/lingui/js-lingui/issues/new>`_. All feedback is welcome!
 
 .. _react-intl: https://github.com/yahoo/react-intl
diff --git a/docs/misc/showroom.rst b/docs/misc/showroom.rst
index 2386d23a..61af941b 100644
--- a/docs/misc/showroom.rst
+++ b/docs/misc/showroom.rst
@@ -20,3 +20,4 @@ Feel free to `send a PR <https://github.com/lingui/js-lingui/issues/new>`__ to l
 - `mapflow.ai <https://mapflow.ai>`__
 - `Ascendero.com <https://ascendero.com/>`__
 - `InterMenu.com <https://intermenu.com>`__
+- `Fider <https://fider.io/>`__ (`source <https://github.com/getfider/fider>`__)
diff --git a/docs/ref/react.rst b/docs/ref/react.rst
index 01170fe4..3d4978c5 100644
--- a/docs/ref/react.rst
+++ b/docs/ref/react.rst
@@ -171,6 +171,32 @@ I18nProvider
 components. :ref:`Rendering of translations <rendering-translations>` is explained
 at the beginning of this document.
 
+.. code-block:: jsx
+
+   import React from 'react';
+   import { I18nProvider } from '@lingui/react';
+   import { i18n } from '@lingui/core';
+   import { messages as messagesEn } from './locales/en/messages.js';
+
+   i18n.load({
+      en: messagesEn,
+   });
+   i18n.activate('en');
+
+   const DefaultI18n = ({ isTranslated, children }) => (
+      <span style={{ color: isTranslated ? undefined : 'red' }}>
+         {children}
+      </span>
+   )
+
+   const App = () => {
+      return (
+         <I18nProvider i18n={i18n} defaultComponent={DefaultI18n}>
+            // rest of the app
+         </I18nProvider>
+      );
+   }
+
 ``forceRenderOnLocaleChange`` is true by default and it ensures that:
 
   - Children of ``I18nProvider`` aren't rendered before locales are loaded.
diff --git a/docs/tutorials/react-native.rst b/docs/tutorials/react-native.rst
index d24310a7..598d5843 100644
--- a/docs/tutorials/react-native.rst
+++ b/docs/tutorials/react-native.rst
@@ -70,6 +70,17 @@ Introducing internationalization
 
 Not surprisingly, this part isn't too different from the :ref:`React tutorial <react-tutorial-label>`.
 
+⚠️ make sure to update ``metro.config.js`` resolvers with ``mjs`` extension to avoid `this problem <https://github.com/eemeli/make-plural/issues/15>`_:
+
+.. code-block:: jsx
+
+  resolver: {
+   sourceExts: ['js', 'ts', 'tsx', 'mjs'],
+  },
+
+
+
+
 Let's use the :jsxmacro:`Trans` macro first. Don't forget that we need to wrap our root
 component with the :component:`I18nProvider` so we can set the active language
 and load catalogs:
diff --git a/packages/react/src/I18nProvider.tsx b/packages/react/src/I18nProvider.tsx
index 17a42b2c..be2b4ee9 100644
--- a/packages/react/src/I18nProvider.tsx
+++ b/packages/react/src/I18nProvider.tsx
@@ -1,9 +1,10 @@
-import React, { FunctionComponent, ComponentType, ReactNode } from "react"
+import React, { ComponentType, FunctionComponent } from "react"
 import { I18n } from "@lingui/core"
+import { TransRenderProps } from "./Trans"
 
 export type I18nContext = {
   i18n: I18n
-  defaultComponent?: ComponentType<{ children?: ReactNode }>
+  defaultComponent?: ComponentType<TransRenderProps>
 }
 
 export type withI18nProps = {
diff --git a/packages/react/src/Trans.tsx b/packages/react/src/Trans.tsx
index af379d15..339d0950 100644
--- a/packages/react/src/Trans.tsx
+++ b/packages/react/src/Trans.tsx
@@ -8,6 +8,7 @@ export type TransRenderProps = {
   translation?: React.ReactNode
   children?: React.ReactNode
   message?: string | null
+  isTranslated?: boolean
 }
 
 export type TransProps = {
@@ -72,6 +73,13 @@ export function Trans(props: TransProps): React.ReactElement<any, any> | null {
   const FallbackComponent = (defaultComponent ||
     React.Fragment) as React.ComponentType<any>
 
+  const i18nProps = {
+    id,
+    message,
+    translation,
+    isTranslated: id !== translation && message !== translation,
+  }
+
   // Validation of `render` and `component` props
   if (render && component) {
     console.error(
@@ -87,22 +95,24 @@ export function Trans(props: TransProps): React.ReactElement<any, any> | null {
     console.error(
       `Invalid value supplied to prop \`component\`. It must be a React component, provided ${component}`
     )
-    return <FallbackComponent>{translation}</FallbackComponent>
+    return <FallbackComponent {...i18nProps}>{translation}</FallbackComponent>
   }
 
   // Rendering using a render prop
   if (typeof render === "function") {
     // Component: render={(props) => <a title={props.translation}>x</a>}
-    return render({
-      id,
-      translation,
-      message,
-    })
+    return render(i18nProps)
   }
 
   // `component` prop has a higher precedence over `defaultComponent`
   const Component = (component || FallbackComponent) as React.ComponentType<any>
-  return <Component>{translation}</Component>
+  const DefaultComponent = defaultComponent
+
+  return DefaultComponent && !component ? (
+    <DefaultComponent {...i18nProps}>{translation}</DefaultComponent>
+  ) : (
+    <Component>{translation}</Component>
+  )
 }
 
 Trans.defaultProps = {


Test patch:
diff --git a/packages/react/src/Trans.test.tsx b/packages/react/src/Trans.test.tsx
index e0d47212..0b89b813 100644
--- a/packages/react/src/Trans.test.tsx
+++ b/packages/react/src/Trans.test.tsx
@@ -172,6 +172,7 @@ describe("Trans component", function () {
         id: "ID",
         message: "Default",
         translation: "Translation",
+        isTranslated: true,
       })
     })
 
@@ -241,4 +242,54 @@ describe("Trans component", function () {
       expect(element).toEqual(`<div>value</div>`)
     })
   })
+
+  describe("I18nProvider defaulComponent accepts render-like props", function () {
+    const DefaultComponent: React.FunctionComponent = (props: {
+      children?: React.ReactNode
+      id: string
+      translation: string
+      message: string
+      isTranslated: boolean
+    }) => (
+      <>
+        <div data-testid="children">{props.children}</div>
+        {props.id && <div data-testid="id">{props.id}</div>}
+        {props.message && <div data-testid="message">{props.message}</div>}
+        {props.translation && (
+          <div data-testid="translation">{props.translation}</div>
+        )}
+
+        <div data-testid="is-translated">{String(props.isTranslated)}</div>
+      </>
+    )
+
+    it("should render defaultComponent with Trans props", function () {
+      const markup = render(
+        <I18nProvider i18n={i18n} defaultComponent={DefaultComponent}>
+          <Trans id="ID" message="Some message" />
+        </I18nProvider>
+      )
+
+      expect(markup.queryByTestId("id").innerHTML).toEqual("ID")
+      expect(markup.queryByTestId("message").innerHTML).toEqual("Some message")
+      expect(markup.queryByTestId("translation").innerHTML).toEqual(
+        "Translation"
+      )
+      expect(markup.queryByTestId("is-translated").innerHTML).toEqual("true")
+    })
+
+    it("should pass isTranslated: false if no translation", function () {
+      const markup = render(
+        <I18nProvider i18n={i18n} defaultComponent={DefaultComponent}>
+          <Trans id="NO_ID" message="Some message" />
+        </I18nProvider>
+      )
+
+      expect(markup.queryByTestId("id").innerHTML).toEqual("NO_ID")
+      expect(markup.queryByTestId("translation").innerHTML).toEqual(
+        "Some message"
+      )
+      expect(markup.queryByTestId("is-translated").innerHTML).toEqual("false")
+    })
+  })
 })