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:
parent
aaf0635cc0
commit
98e0372cfd
4 changed files with 76 additions and 4 deletions
17
.changeset/thirty-dots-end.md
Normal file
17
.changeset/thirty-dots-end.md
Normal 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
|
||||
}
|
||||
});
|
||||
```
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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/);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue