[ci] format

This commit is contained in:
matthewp 2023-08-16 17:44:01 +00:00 committed by astrobot-houston
parent 16a3fdf931
commit fb31ce55d9
5 changed files with 52 additions and 51 deletions

View file

@ -80,9 +80,9 @@ import ReactComponent from './ReactComponent';
</ReactComponent> </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: You can enable this option in the configuration for the React integration:
@ -96,8 +96,8 @@ export default defineConfig({
integrations: [ integrations: [
react({ react({
experimentalReactChildren: true, experimentalReactChildren: true,
}) }),
], ],
}); });
``` ```

View file

@ -87,7 +87,7 @@ async function renderToStaticMarkup(Component, props, { default: children, ...sl
}; };
const newChildren = children ?? props.children; const newChildren = children ?? props.children;
if (children && opts.experimentalReactChildren) { 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); newProps.children = convert(children);
} else if (newChildren != null) { } else if (newChildren != null) {
newProps.children = React.createElement(StaticHtml, { newProps.children = React.createElement(StaticHtml, {

View file

@ -39,23 +39,23 @@ function getRenderer() {
function optionsPlugin(experimentalReactChildren: boolean): vite.Plugin { function optionsPlugin(experimentalReactChildren: boolean): vite.Plugin {
const virtualModule = 'astro:react:opts'; const virtualModule = 'astro:react:opts';
const virtualModuleId = '\0' + virtualModule; const virtualModuleId = '\0' + virtualModule;
return { return {
name: '@astrojs/react:opts', name: '@astrojs/react:opts',
resolveId(id) { resolveId(id) {
if(id === virtualModule) { if (id === virtualModule) {
return virtualModuleId; return virtualModuleId;
} }
}, },
load(id) { load(id) {
if(id === virtualModuleId) { if (id === virtualModuleId) {
return { return {
code: `export default { code: `export default {
experimentalReactChildren: ${JSON.stringify(experimentalReactChildren)} experimentalReactChildren: ${JSON.stringify(experimentalReactChildren)}
}` }`,
}; };
} }
} },
}; };
} }
@ -93,17 +93,17 @@ function getViteConfiguration(experimentalReactChildren: boolean) {
'use-immer', 'use-immer',
], ],
}, },
plugins: [ plugins: [optionsPlugin(experimentalReactChildren)],
optionsPlugin(experimentalReactChildren)
]
}; };
} }
export type ReactIntegrationOptions = { export type ReactIntegrationOptions = {
experimentalReactChildren: boolean; experimentalReactChildren: boolean;
} };
export default function ({ experimentalReactChildren }: ReactIntegrationOptions = { experimentalReactChildren: false }): AstroIntegration { export default function (
{ experimentalReactChildren }: ReactIntegrationOptions = { experimentalReactChildren: false }
): AstroIntegration {
return { return {
name: '@astrojs/react', name: '@astrojs/react',
hooks: { hooks: {

View file

@ -51,7 +51,9 @@ describe('React Components', () => {
// test 10: Should properly render children passed as props // test 10: Should properly render children passed as props
const islandsWithChildren = $('.with-children'); const islandsWithChildren = $('.with-children');
expect(islandsWithChildren).to.have.lengthOf(2); 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 // test 11: Should generate unique React.useId per island
const islandsWithId = $('.react-use-id'); const islandsWithId = $('.react-use-id');
@ -103,8 +105,8 @@ describe('React Components', () => {
it('Children are parsed as React components, can be manipulated', async () => { it('Children are parsed as React components, can be manipulated', async () => {
const html = await fixture.readFile('/children/index.html'); const html = await fixture.readFile('/children/index.html');
const $ = cheerioLoad(html); const $ = cheerioLoad(html);
expect($(".with-children-count").text()).to.equal('2'); expect($('.with-children-count').text()).to.equal('2');
}) });
}); });
if (isWindows) return; if (isWindows) return;

View file

@ -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'; import { createElement, Fragment } from 'react';
export default function convert(children) { export default function convert(children) {
const nodeMap = new WeakMap(); const nodeMap = new WeakMap();
let doc = parse(children.toString().trim()); let doc = parse(children.toString().trim());
let root = createElement(Fragment, { children: [] }); let root = createElement(Fragment, { children: [] });
walkSync(doc, (node, parent, index) => { walkSync(doc, (node, parent, index) => {
let newNode = {}; let newNode = {};
if (node.type === DOCUMENT_NODE) { if (node.type === DOCUMENT_NODE) {
nodeMap.set(node, root); nodeMap.set(node, root);
} else if (node.type === ELEMENT_NODE) { } else if (node.type === ELEMENT_NODE) {
const { class: className, ...props } = node.attributes; const { class: className, ...props } = node.attributes;
newNode = createElement(node.name, { ...props, className, children: [] }); newNode = createElement(node.name, { ...props, className, children: [] });
nodeMap.set(node, newNode); nodeMap.set(node, newNode);
if (parent) { if (parent) {
const newParent = nodeMap.get(parent); const newParent = nodeMap.get(parent);
newParent.props.children[index] = newNode; newParent.props.children[index] = newNode;
}
} } else if (node.type === TEXT_NODE) {
} else if (node.type === TEXT_NODE) { newNode = node.value.trim();
newNode = node.value.trim(); if (newNode.trim()) {
if (newNode.trim()) { if (parent) {
if (parent) { const newParent = nodeMap.get(parent);
const newParent = nodeMap.get(parent); if (parent.children.length === 1) {
if (parent.children.length === 1) { newParent.props.children[0] = newNode;
newParent.props.children[0] = newNode; } else {
} else { newParent.props.children[index] = newNode;
newParent.props.children[index] = newNode; }
} }
} }
} }
} });
});
return root.props.children; return root.props.children;
} }