diff --git a/packages/integrations/react/README.md b/packages/integrations/react/README.md index 7504490e0d..8009972b30 100644 --- a/packages/integrations/react/README.md +++ b/packages/integrations/react/README.md @@ -80,9 +80,9 @@ import ReactComponent from './ReactComponent'; ``` -If you are using a library that *expects* more than one child element element to be passed, for example so that it can slot certain elements in different places, you might find this to be a blocker. +If you are using a library that _expects_ more than one child element element to be passed, for example so that it can slot certain elements in different places, you might find this to be a blocker. -You can set the experimental flag `experimentalReactChildren` to tell Astro to always pass children to React as React vnodes. There is some runtime cost to this, but it can help with compatibility. +You can set the experimental flag `experimentalReactChildren` to tell Astro to always pass children to React as React vnodes. There is some runtime cost to this, but it can help with compatibility. You can enable this option in the configuration for the React integration: @@ -96,8 +96,8 @@ export default defineConfig({ integrations: [ react({ experimentalReactChildren: true, - }) - ], + }), + ], }); ``` diff --git a/packages/integrations/react/server.js b/packages/integrations/react/server.js index 3f0d93e971..c2400accb6 100644 --- a/packages/integrations/react/server.js +++ b/packages/integrations/react/server.js @@ -87,7 +87,7 @@ async function renderToStaticMarkup(Component, props, { default: children, ...sl }; const newChildren = children ?? props.children; if (children && opts.experimentalReactChildren) { - const convert = await import('./vnode-children.js').then(mod => mod.default); + const convert = await import('./vnode-children.js').then((mod) => mod.default); newProps.children = convert(children); } else if (newChildren != null) { newProps.children = React.createElement(StaticHtml, { diff --git a/packages/integrations/react/src/index.ts b/packages/integrations/react/src/index.ts index 5560622823..d1cd7c4e63 100644 --- a/packages/integrations/react/src/index.ts +++ b/packages/integrations/react/src/index.ts @@ -39,23 +39,23 @@ function getRenderer() { function optionsPlugin(experimentalReactChildren: boolean): vite.Plugin { const virtualModule = 'astro:react:opts'; - const virtualModuleId = '\0' + virtualModule; - return { + const virtualModuleId = '\0' + virtualModule; + return { name: '@astrojs/react:opts', resolveId(id) { - if(id === virtualModule) { + if (id === virtualModule) { return virtualModuleId; } }, load(id) { - if(id === virtualModuleId) { + if (id === virtualModuleId) { return { code: `export default { experimentalReactChildren: ${JSON.stringify(experimentalReactChildren)} - }` + }`, }; } - } + }, }; } @@ -93,17 +93,17 @@ function getViteConfiguration(experimentalReactChildren: boolean) { 'use-immer', ], }, - plugins: [ - optionsPlugin(experimentalReactChildren) - ] + plugins: [optionsPlugin(experimentalReactChildren)], }; } export type ReactIntegrationOptions = { experimentalReactChildren: boolean; -} +}; -export default function ({ experimentalReactChildren }: ReactIntegrationOptions = { experimentalReactChildren: false }): AstroIntegration { +export default function ( + { experimentalReactChildren }: ReactIntegrationOptions = { experimentalReactChildren: false } +): AstroIntegration { return { name: '@astrojs/react', hooks: { diff --git a/packages/integrations/react/test/react-component.test.js b/packages/integrations/react/test/react-component.test.js index da7fa018a4..43df1d9e4f 100644 --- a/packages/integrations/react/test/react-component.test.js +++ b/packages/integrations/react/test/react-component.test.js @@ -51,7 +51,9 @@ describe('React Components', () => { // test 10: Should properly render children passed as props const islandsWithChildren = $('.with-children'); expect(islandsWithChildren).to.have.lengthOf(2); - expect($(islandsWithChildren[0]).html()).to.equal($(islandsWithChildren[1]).find('astro-slot').html()); + expect($(islandsWithChildren[0]).html()).to.equal( + $(islandsWithChildren[1]).find('astro-slot').html() + ); // test 11: Should generate unique React.useId per island const islandsWithId = $('.react-use-id'); @@ -103,8 +105,8 @@ describe('React Components', () => { it('Children are parsed as React components, can be manipulated', async () => { const html = await fixture.readFile('/children/index.html'); const $ = cheerioLoad(html); - expect($(".with-children-count").text()).to.equal('2'); - }) + expect($('.with-children-count').text()).to.equal('2'); + }); }); if (isWindows) return; diff --git a/packages/integrations/react/vnode-children.js b/packages/integrations/react/vnode-children.js index 0c9d5e08da..9c7abe6441 100644 --- a/packages/integrations/react/vnode-children.js +++ b/packages/integrations/react/vnode-children.js @@ -1,38 +1,37 @@ -import { parse, walkSync, DOCUMENT_NODE, ELEMENT_NODE, TEXT_NODE } from 'ultrahtml' +import { parse, walkSync, DOCUMENT_NODE, ELEMENT_NODE, TEXT_NODE } from 'ultrahtml'; import { createElement, Fragment } from 'react'; export default function convert(children) { - const nodeMap = new WeakMap(); - let doc = parse(children.toString().trim()); - let root = createElement(Fragment, { children: [] }); + const nodeMap = new WeakMap(); + let doc = parse(children.toString().trim()); + let root = createElement(Fragment, { children: [] }); - walkSync(doc, (node, parent, index) => { - let newNode = {}; - if (node.type === DOCUMENT_NODE) { - nodeMap.set(node, root); - } else if (node.type === ELEMENT_NODE) { - const { class: className, ...props } = node.attributes; - newNode = createElement(node.name, { ...props, className, children: [] }); - nodeMap.set(node, newNode); - if (parent) { - const newParent = nodeMap.get(parent); - newParent.props.children[index] = newNode; - - } - } else if (node.type === TEXT_NODE) { - newNode = node.value.trim(); - if (newNode.trim()) { - if (parent) { - const newParent = nodeMap.get(parent); - if (parent.children.length === 1) { - newParent.props.children[0] = newNode; - } else { - newParent.props.children[index] = newNode; - } - } - } - } - }); + walkSync(doc, (node, parent, index) => { + let newNode = {}; + if (node.type === DOCUMENT_NODE) { + nodeMap.set(node, root); + } else if (node.type === ELEMENT_NODE) { + const { class: className, ...props } = node.attributes; + newNode = createElement(node.name, { ...props, className, children: [] }); + nodeMap.set(node, newNode); + if (parent) { + const newParent = nodeMap.get(parent); + newParent.props.children[index] = newNode; + } + } else if (node.type === TEXT_NODE) { + newNode = node.value.trim(); + if (newNode.trim()) { + if (parent) { + const newParent = nodeMap.get(parent); + if (parent.children.length === 1) { + newParent.props.children[0] = newNode; + } else { + newParent.props.children[index] = newNode; + } + } + } + } + }); - return root.props.children; + return root.props.children; }