diff --git a/packages/react/src/Trans.test.tsx b/packages/react/src/Trans.test.tsx index ab0dbd11f..a7830a737 100644 --- a/packages/react/src/Trans.test.tsx +++ b/packages/react/src/Trans.test.tsx @@ -138,6 +138,38 @@ describe("Trans component", () => { }) }) + it("should follow jsx semantics regarding booleans", () => { + expect( + html( + {0} bar"} + values={{ + 0: false && "lol", + }} + components={{ + 0: , + }} + /> + ) + ).toEqual("foo bar") + + expect( + html( + {0} bar"} + values={{ + 0: "lol", + }} + components={{ + 0: , + }} + /> + ) + ).toEqual("foo lol bar") + }) + it("should render default string", () => { expect(text()).toEqual("unknown") @@ -271,6 +303,28 @@ describe("Trans component", () => { expect(translation).toEqual("1,00 €") }) + it("should render plural", () => { + const render = (count: number) => + html( + A lot of them}}" + } + values={{ + count, + }} + components={{ + 0: , + }} + /> + ) + + expect(render(0)).toEqual("Zero items") + expect(render(1)).toEqual("1 item") + expect(render(2)).toEqual(`2 A lot of them`) + }) + describe("rendering", () => { it("should render a text node with no wrapper element", () => { const txt = html() diff --git a/packages/react/src/TransNoContext.tsx b/packages/react/src/TransNoContext.tsx index ea39f6cab..863849158 100644 --- a/packages/react/src/TransNoContext.tsx +++ b/packages/react/src/TransNoContext.tsx @@ -58,28 +58,31 @@ export function TransNoContext( if (values) { /* - Related discussion: https://github.com/lingui/js-lingui/issues/183 + Replace values placeholders with and add values to `components`. + This makes them processed as JSX children and follow JSX semantics. + + Related discussion: https://github.com/lingui/js-lingui/issues/1904 - Values *might* contain React elements with static content. - They're replaced with placeholders and added to `components`. + Another use-case is when React components directly passed as values: Example: - Translation: Hello {name} + Translation: 'Hello {name}' Values: { name: Jane } It'll become "Hello <0 />" with components=[Jane] - */ + Related discussion: https://github.com/lingui/js-lingui/issues/183 + */ Object.keys(values).forEach((key) => { - const value = values[key] - const valueIsReactEl = - React.isValidElement(value) || - (Array.isArray(value) && value.every(React.isValidElement)) - if (!valueIsReactEl) return - const index = Object.keys(components).length - components[index] = value + // simple scalars should be processed as values to be able to apply formatting + if (typeof values[key] === "string" || typeof values[key] === "number") { + return + } + + // react components, arrays, falsy values, all should be processed as JSX children + components[index] = <>{values[key]} values[key] = `<${index}/>` }) }