diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts index 8f44594c0031..04dab9bd64f2 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts @@ -3516,6 +3516,22 @@ function lowerJsxElement( text = exprPath.node.value; } else { text = trimJsxText(exprPath.node.value); + /* + * If the decoded value trimmed to null, the text may still contain + * meaningful content that Babel decoded from HTML entity references + * (e.g. ` ` → space). In that case, trimming the decoded value + * discards the intentional whitespace. Preserve it by trimming the + * raw source instead so that the entity reference is retained in the + * output JSX and decoded correctly by the standard JSX transform. + */ + if (text === null) { + const rawValue = ( + exprPath.node.extra as {raw?: string} | undefined + )?.raw; + if (rawValue != null) { + text = trimJsxText(rawValue); + } + } } if (text === null) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-html-entity-preserved.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-html-entity-preserved.expect.md new file mode 100644 index 000000000000..c85df4b726d8 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-html-entity-preserved.expect.md @@ -0,0 +1,43 @@ + +## Input + +```javascript +// Ensure HTML entity references in JSX text (e.g. ) are preserved after +// compilation and not stripped as whitespace-only nodes. +function MyApp() { + return ( +
+ + hello world +
+ ); +} + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; // Ensure HTML entity references in JSX text (e.g. ) are preserved after +// compilation and not stripped as whitespace-only nodes. +function MyApp() { + const $ = _c(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = ( +
+ {" "} + hello world +
+ ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; +} + +``` + +### Eval output +(kind: exception) Fixture not implemented \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-html-entity-preserved.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-html-entity-preserved.js new file mode 100644 index 000000000000..ba4f7d05ebe4 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-html-entity-preserved.js @@ -0,0 +1,10 @@ +// Ensure HTML entity references in JSX text (e.g. ) are preserved after +// compilation and not stripped as whitespace-only nodes. +function MyApp() { + return ( +
+ + hello world +
+ ); +}