Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support rendering @motionone/solid components #5233

Merged
merged 1 commit into from
Oct 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/four-donuts-reply.md
@@ -0,0 +1,5 @@
---
'astro': patch
---

Support rendering `@motionone/solid` components
2 changes: 1 addition & 1 deletion packages/astro/src/runtime/server/render/astro.ts
Expand Up @@ -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(
Expand Down
11 changes: 9 additions & 2 deletions packages/astro/src/runtime/server/render/component.ts
Expand Up @@ -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': {
Expand Down Expand Up @@ -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) {
Comment on lines +136 to +143
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error would be something like:

 error   'get' on proxy: property 'Symbol(astro:renderer)' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '@astrojs/solid-js' but got 'props => {
      delete props.tag;
      return __vite_ssr_import_1__.createComponent(BaseComponent, __vite_ssr_imp...<omitted>... }')

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be very cheeky to parse the error message to get it's actual value now that I think of it, but right now it works without doing so.

const rendererName = (Component as any)[Renderer];
renderer = renderers.find(({ name }) => name === rendererName);
}
Expand Down
@@ -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;
Expand Up @@ -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>
Expand All @@ -10,6 +11,7 @@ import { Router } from "@solidjs/router";
<Hello client:load />
<WithNewlines client:load />
<Router />
<ProxyComponent client:load />
</div>
</body>
</html>
14 changes: 14 additions & 0 deletions packages/astro/test/solid-component.test.js
Expand Up @@ -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');
});
});

Expand All @@ -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);
Expand Down