summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Bjorn Lu <bjornlu.dev@gmail.com> 2022-10-28 22:42:37 +0800
committerGravatar GitHub <noreply@github.com> 2022-10-28 10:42:37 -0400
commit7f8987085c9c5bdcd39b9a6700303e9b9f76b9f2 (patch)
treec0e8604569107db595db7c9022de480559371e2b
parentc6b149bc0a223e404333240a66e42ea933d9b7a4 (diff)
downloadastro-7f8987085c9c5bdcd39b9a6700303e9b9f76b9f2.tar.gz
astro-7f8987085c9c5bdcd39b9a6700303e9b9f76b9f2.tar.zst
astro-7f8987085c9c5bdcd39b9a6700303e9b9f76b9f2.zip
Support rendering `@motionone/solid` components (#5233)
-rw-r--r--.changeset/four-donuts-reply.md5
-rw-r--r--packages/astro/src/runtime/server/render/astro.ts2
-rw-r--r--packages/astro/src/runtime/server/render/component.ts11
-rw-r--r--packages/astro/test/fixtures/solid-component/src/components/ProxyComponent.jsx16
-rw-r--r--packages/astro/test/fixtures/solid-component/src/pages/index.astro2
-rw-r--r--packages/astro/test/solid-component.test.js14
6 files changed, 47 insertions, 3 deletions
diff --git a/.changeset/four-donuts-reply.md b/.changeset/four-donuts-reply.md
new file mode 100644
index 000000000..5c15ad630
--- /dev/null
+++ b/.changeset/four-donuts-reply.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Support rendering `@motionone/solid` components
diff --git a/packages/astro/src/runtime/server/render/astro.ts b/packages/astro/src/runtime/server/render/astro.ts
index cd1c04885..d6da03007 100644
--- a/packages/astro/src/runtime/server/render/astro.ts
+++ b/packages/astro/src/runtime/server/render/astro.ts
@@ -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(
diff --git a/packages/astro/src/runtime/server/render/component.ts b/packages/astro/src/runtime/server/render/component.ts
index 0b6c90ebe..54dfb372f 100644
--- a/packages/astro/src/runtime/server/render/component.ts
+++ b/packages/astro/src/runtime/server/render/component.ts
@@ -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);
}
diff --git a/packages/astro/test/fixtures/solid-component/src/components/ProxyComponent.jsx b/packages/astro/test/fixtures/solid-component/src/components/ProxyComponent.jsx
new file mode 100644
index 000000000..9132c9a6c
--- /dev/null
+++ b/packages/astro/test/fixtures/solid-component/src/components/ProxyComponent.jsx
@@ -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;
diff --git a/packages/astro/test/fixtures/solid-component/src/pages/index.astro b/packages/astro/test/fixtures/solid-component/src/pages/index.astro
index 06c48e18a..a484a6b8d 100644
--- a/packages/astro/test/fixtures/solid-component/src/pages/index.astro
+++ b/packages/astro/test/fixtures/solid-component/src/pages/index.astro
@@ -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>
diff --git a/packages/astro/test/solid-component.test.js b/packages/astro/test/solid-component.test.js
index 0a05118eb..ed3af45e8 100644
--- a/packages/astro/test/solid-component.test.js
+++ b/packages/astro/test/solid-component.test.js
@@ -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);