summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/three-timers-arrive.md5
-rw-r--r--packages/integrations/react/package.json6
-rw-r--r--packages/integrations/react/test/parsed-react-children.test.js15
-rw-r--r--packages/integrations/react/vnode-children.js16
-rw-r--r--pnpm-lock.yaml3
5 files changed, 33 insertions, 12 deletions
diff --git a/.changeset/three-timers-arrive.md b/.changeset/three-timers-arrive.md
new file mode 100644
index 000000000..619e7d815
--- /dev/null
+++ b/.changeset/three-timers-arrive.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/react': patch
+---
+
+Fixes an issue where slotting self-closing elements (img, br, hr) into react components with `experimentalReactChildren` enabled led to an error.
diff --git a/packages/integrations/react/package.json b/packages/integrations/react/package.json
index 49d357a94..100ac3baa 100644
--- a/packages/integrations/react/package.json
+++ b/packages/integrations/react/package.json
@@ -42,7 +42,8 @@
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
- "dev": "astro-scripts dev \"src/**/*.ts\""
+ "dev": "astro-scripts dev \"src/**/*.ts\"",
+ "test": "mocha --exit --timeout 20000"
},
"dependencies": {
"@vitejs/plugin-react": "^4.0.4",
@@ -57,7 +58,8 @@
"cheerio": "1.0.0-rc.12",
"react": "^18.1.0",
"react-dom": "^18.1.0",
- "vite": "^4.4.9"
+ "vite": "^4.4.9",
+ "mocha": "^10.2.0"
},
"peerDependencies": {
"@types/react": "^17.0.50 || ^18.0.21",
diff --git a/packages/integrations/react/test/parsed-react-children.test.js b/packages/integrations/react/test/parsed-react-children.test.js
new file mode 100644
index 000000000..876897c95
--- /dev/null
+++ b/packages/integrations/react/test/parsed-react-children.test.js
@@ -0,0 +1,15 @@
+import { expect } from 'chai';
+import convert from "../vnode-children.js";
+
+describe('experimental react children', () => {
+ it('has undefined as children for direct children', () => {
+ const [ imgVNode ] = convert('<img src="abc"></img>');
+ expect(imgVNode.props).to.deep.include({ children: undefined });
+ })
+
+ it('has undefined as children for nested children', () => {
+ const [ divVNode ] = convert('<div><img src="xyz"></img></div>');
+ const [ imgVNode ] = divVNode.props.children;
+ expect(imgVNode.props).to.deep.include({ children: undefined });
+ })
+})
diff --git a/packages/integrations/react/vnode-children.js b/packages/integrations/react/vnode-children.js
index cc8ec3510..5fd421e67 100644
--- a/packages/integrations/react/vnode-children.js
+++ b/packages/integrations/react/vnode-children.js
@@ -8,17 +8,10 @@ export default function convert(children) {
let key = 0;
function createReactElementFromNode(node) {
- const childVnodes = Array.isArray(node.children)
+ const childVnodes = Array.isArray(node.children) && node.children.length
? node.children
- .map((child) => {
- if (child.type === ELEMENT_NODE) {
- return createReactElementFromNode(child);
- } else if (child.type === TEXT_NODE) {
- // 0-length text gets omitted in JSX
- return child.value.trim() ? child.value : undefined;
- }
- })
- .filter((n) => !!n)
+ .map((child) => createReactElementFromNode(child))
+ .filter(Boolean)
: undefined;
if (node.type === DOCUMENT_NODE) {
@@ -26,6 +19,9 @@ export default function convert(children) {
} else if (node.type === ELEMENT_NODE) {
const { class: className, ...props } = node.attributes;
return createElement(node.name, { ...props, className, key: `${id}-${key++}` }, childVnodes);
+ } else if (node.type === TEXT_NODE) {
+ // 0-length text gets omitted in JSX
+ return node.value.trim() ? node.value : undefined;
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 14c70baad..33a41186b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -4473,6 +4473,9 @@ importers:
cheerio:
specifier: 1.0.0-rc.12
version: 1.0.0-rc.12
+ mocha:
+ specifier: ^10.2.0
+ version: 10.2.0
react:
specifier: ^18.1.0
version: 18.2.0