Skip to content

Commit

Permalink
fix: return a single node when applicable (#2016)
Browse files Browse the repository at this point in the history
  • Loading branch information
bengry authored Sep 2, 2024
1 parent b9e89c1 commit 68d8358
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 11 deletions.
24 changes: 24 additions & 0 deletions packages/react/src/Trans.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,30 @@ describe("Trans component", () => {
expect(translation).toEqual(`Read <a href="/docs">the docs</a>`)
})

it("should render nested elements with `asChild` pattern", () => {
const ComponentThatExpectsSingleElementChild: React.FC<{
asChild: boolean
children?: React.ReactElement
}> = (props) => {
if (props.asChild && React.isValidElement(props.children)) {
return props.children
}

return <div />
}

const translation = html(
<Trans
id="please <0><1>sign in again</1></0>"
components={{
0: <ComponentThatExpectsSingleElementChild asChild />,
1: <a href="/login" />,
}}
/>
)
expect(translation).toEqual(`please <a href="/login">sign in again</a>`)
})

it("should render translation inside custom component", () => {
const Component = (props: PropsWithChildren) => (
<p className="lead">{props.children}</p>
Expand Down
22 changes: 13 additions & 9 deletions packages/react/src/format.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react"
import { render } from "@testing-library/react"
import * as React from "react"
import { formatElements } from "./format"
// eslint-disable-next-line import/no-extraneous-dependencies
import { mockConsole } from "@lingui/jest-mocks"
Expand Down Expand Up @@ -138,13 +138,17 @@ describe("formatElements", function () {
const elements = formatElements("<div><0/><0/></div>", {
div: <div />,
0: <span>hi</span>,
}) as Array<React.ReactElement>

expect(elements).toHaveLength(1)
const childElements = elements[0]!.props.children
const childKeys = childElements
.map((el: React.ReactElement) => el?.key)
.filter(Boolean)
expect(cleanPrefix(childKeys[0])).toBeLessThan(cleanPrefix(childKeys[1]))
})

expect(React.isValidElement(elements)).toBe(true)

const childElements = (
elements as React.ReactElement<{ children: React.ReactElement[] }>
).props.children
const childKeys = childElements.map((el) => el?.key).filter(Boolean)

expect(cleanPrefix(childKeys[0] as string)).toBeLessThan(
cleanPrefix(childKeys[1] as string)
)
})
})
4 changes: 2 additions & 2 deletions packages/react/src/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const voidElementTags = {
function formatElements(
value: string,
elements: { [key: string]: React.ReactElement } = {}
): string | Array<React.ReactElement | string> {
): string | React.ReactElement | Array<React.ReactElement | string> {
const uniqueId = makeCounter(0, "$lingui$")
const parts = value.replace(nlRe, "").split(tagRe)

Expand Down Expand Up @@ -87,7 +87,7 @@ function formatElements(
if (after) tree.push(after)
}

return tree
return tree.length === 1 ? tree[0]! : tree
}

/*
Expand Down

0 comments on commit 68d8358

Please sign in to comment.