0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-16 21:46:22 -05:00

feat: pass props to container (#11138)

This commit is contained in:
Emanuele Stoppa 2024-05-24 14:41:56 +01:00 committed by GitHub
parent aaf0635cc0
commit 98e0372cfd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 76 additions and 4 deletions

View file

@ -0,0 +1,17 @@
---
"astro": patch
---
You can now pass `props` when rendering a component using the Container APIs:
```js
import { experimental_AstroContainer as AstroContainer } from "astro/contaienr";
import Card from "../src/components/Card.astro";
const container = await AstroContainer.create();
const result = await container.renderToString(Card, {
props: {
someState: true
}
});
```

View file

@ -3,7 +3,7 @@ import type {
AstroRenderer,
AstroUserConfig,
ComponentInstance,
MiddlewareHandler,
MiddlewareHandler, Props,
RouteData,
RouteType,
SSRLoadedRenderer,
@ -70,6 +70,15 @@ export type ContainerRenderOptions = {
* ```
*/
routeType?: RouteType;
/**
* Allows to pass `Astro.props` to an Astro component:
*
* ```js
* container.renderToString(Endpoint, { props: { "lorem": "ipsum" } });
* ```
*/
props?: Props
};
function createManifest(
@ -369,6 +378,9 @@ export class experimental_AstroContainer {
if (options.params) {
renderContext.params = options.params;
}
if (options.props) {
renderContext.props = options.props;
}
return renderContext.render(componentInstance, slots);
}

View file

@ -3,7 +3,7 @@ import type {
AstroGlobal,
AstroGlobalPartial,
ComponentInstance,
MiddlewareHandler,
MiddlewareHandler, Props,
RewritePayload,
RouteData,
SSRResult,
@ -47,7 +47,8 @@ export class RenderContext {
public status: number,
protected cookies = new AstroCookies(request),
public params = getParams(routeData, pathname),
protected url = new URL(request.url)
protected url = new URL(request.url),
public props: Props = {}
) {}
/**
@ -97,7 +98,7 @@ export class RenderContext {
): Promise<Response> {
const { cookies, middleware, pathname, pipeline } = this;
const { logger, routeCache, serverLike, streaming } = pipeline;
const props = await getProps({
const props = Object.keys(this.props).length > 0 ? this.props : await getProps({
mod: componentInstance,
routeData: this.routeData,
routeCache,

View file

@ -139,4 +139,46 @@ describe('Container', () => {
assert.match(result, /Custom name/);
assert.match(result, /Bar name/);
});
it('Renders props', async () => {
const Page = createComponent(
(result, props, _slots) => {
return render`${renderComponent(
result,
'BaseLayout',
BaseLayout,
{},
{
default: () => render`
${maybeRenderHead(result)}
${props.isOpen ? "Is open" : "Is closed"}
`,
head: () => render`
${renderComponent(
result,
'Fragment',
Fragment,
{ slot: 'head' },
{
default: () => render`<meta charset="utf-8">`,
}
)}
`,
}
)}`;
},
'Component2.astro',
undefined
);
const container = await experimental_AstroContainer.create();
const result = await container.renderToString(Page, {
props: {
isOpen: true
},
});
assert.match(result, /Is open/);
});
});