Support rendering @motionone/solid
components (#5233)
This commit is contained in:
parent
c6b149bc0a
commit
7f8987085c
6 changed files with 47 additions and 3 deletions
5
.changeset/four-donuts-reply.md
Normal file
5
.changeset/four-donuts-reply.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Support rendering `@motionone/solid` components
|
|
@ -57,7 +57,7 @@ export function isAstroComponent(obj: any): obj is AstroComponent {
|
|||
}
|
||||
|
||||
export function isAstroComponentFactory(obj: any): obj is AstroComponentFactory {
|
||||
return obj == null ? false : !!obj.isAstroComponentFactory;
|
||||
return obj == null ? false : obj.isAstroComponentFactory === true;
|
||||
}
|
||||
|
||||
export async function* renderAstroComponent(
|
||||
|
|
|
@ -56,7 +56,7 @@ export async function renderComponent(
|
|||
_props: Record<string | number, any>,
|
||||
slots: any = {}
|
||||
): Promise<ComponentIterable> {
|
||||
Component = await Component;
|
||||
Component = (await Component) ?? Component;
|
||||
|
||||
switch (getComponentType(Component)) {
|
||||
case 'fragment': {
|
||||
|
@ -133,7 +133,14 @@ Did you mean to add ${formatList(probableRendererNames.map((r) => '`' + r + '`')
|
|||
// If this component ran through `__astro_tag_component__`, we already know
|
||||
// which renderer to match to and can skip the usual `check` calls.
|
||||
// This will help us throw most relevant error message for modules with runtime errors
|
||||
if (Component && (Component as any)[Renderer]) {
|
||||
let isTagged = false;
|
||||
try {
|
||||
isTagged = Component && (Component as any)[Renderer];
|
||||
} catch {
|
||||
// Accessing `Component[Renderer]` may throw if `Component` is a Proxy that doesn't
|
||||
// return the actual read-only value. In this case, ignore.
|
||||
}
|
||||
if (isTagged) {
|
||||
const rendererName = (Component as any)[Renderer];
|
||||
renderer = renderers.find(({ name }) => name === rendererName);
|
||||
}
|
||||
|
|
16
packages/astro/test/fixtures/solid-component/src/components/ProxyComponent.jsx
vendored
Normal file
16
packages/astro/test/fixtures/solid-component/src/components/ProxyComponent.jsx
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { Dynamic } from 'solid-js/web'
|
||||
|
||||
const BaseComponent = ({ tag } = {}) => {
|
||||
return <Dynamic id="proxy-component" component={tag || 'div'}>Hello world</Dynamic>;
|
||||
}
|
||||
|
||||
// Motion uses a Proxy to support syntax like `<Motion.div />` and `<Motion.button />` etc
|
||||
// https://cdn.jsdelivr.net/npm/@motionone/solid@10.14.2/dist/source/motion.jsx
|
||||
const ProxyComponent = new Proxy(BaseComponent, {
|
||||
get: (_, tag) => (props) => {
|
||||
delete props.tag
|
||||
return <BaseComponent {...props} tag={tag} />;
|
||||
}
|
||||
})
|
||||
|
||||
export default ProxyComponent;
|
|
@ -2,6 +2,7 @@
|
|||
import Hello from '../components/Hello.jsx';
|
||||
import WithNewlines from '../components/WithNewlines.jsx';
|
||||
import { Router } from "@solidjs/router";
|
||||
import ProxyComponent from '../components/ProxyComponent.jsx';
|
||||
---
|
||||
<html>
|
||||
<head><title>Solid</title></head>
|
||||
|
@ -10,6 +11,7 @@ import { Router } from "@solidjs/router";
|
|||
<Hello client:load />
|
||||
<WithNewlines client:load />
|
||||
<Router />
|
||||
<ProxyComponent client:load />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -22,6 +22,9 @@ describe('Solid component', () => {
|
|||
|
||||
// test 1: Works
|
||||
expect($('.hello')).to.have.lengthOf(1);
|
||||
|
||||
// test 2: Support rendering proxy components
|
||||
expect($('#proxy-component').text()).to.be.equal('Hello world');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -38,6 +41,17 @@ describe('Solid component', () => {
|
|||
await devServer.stop();
|
||||
});
|
||||
|
||||
it('Can load a component', async () => {
|
||||
const html = await fixture.fetch('/').then((res) => res.text());
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: Works
|
||||
expect($('.hello')).to.have.lengthOf(1);
|
||||
|
||||
// test 2: Support rendering proxy components
|
||||
expect($('#proxy-component').text()).to.be.equal('Hello world');
|
||||
});
|
||||
|
||||
it('scripts proxy correctly', async () => {
|
||||
const html = await fixture.fetch('/').then((res) => res.text());
|
||||
const $ = cheerio.load(html);
|
||||
|
|
Loading…
Reference in a new issue