[ci] format
This commit is contained in:
parent
16a3fdf931
commit
fb31ce55d9
5 changed files with 52 additions and 51 deletions
|
@ -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,
|
||||||
})
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -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, {
|
||||||
|
|
|
@ -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: {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue