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

fix(rendering): remove render instructions from slot expressions (#10747)

This commit is contained in:
Arsh 2024-04-11 08:07:21 +05:30 committed by GitHub
parent 12e34e3cf5
commit 994337c99f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 45 additions and 4 deletions

View file

@ -0,0 +1,5 @@
---
"astro": patch
---
Fixes an issue where functions could not be used as named slots.

View file

@ -3,7 +3,7 @@ import type { Pipeline } from '../base-pipeline.js';
export { Pipeline } from '../base-pipeline.js'; export { Pipeline } from '../base-pipeline.js';
export { getParams, getProps } from './params-and-props.js'; export { getParams, getProps } from './params-and-props.js';
export { loadRenderer } from './renderer.js'; export { loadRenderer } from './renderer.js';
export { Slots } from './result.js'; export { Slots } from './slots.js';
export interface SSROptions { export interface SSROptions {
/** The pipeline instance */ /** The pipeline instance */

View file

@ -2,13 +2,15 @@ import type { SSRResult } from '../../@types/astro.js';
import { type ComponentSlots, renderSlotToString } from '../../runtime/server/index.js'; import { type ComponentSlots, renderSlotToString } from '../../runtime/server/index.js';
import { renderJSX } from '../../runtime/server/jsx.js'; import { renderJSX } from '../../runtime/server/jsx.js';
import { chunkToString } from '../../runtime/server/render/index.js'; import { chunkToString } from '../../runtime/server/render/index.js';
import { isRenderInstruction } from '../../runtime/server/render/instruction.js';
import { AstroError, AstroErrorData } from '../errors/index.js'; import { AstroError, AstroErrorData } from '../errors/index.js';
import type { Logger } from '../logger/core.js'; import type { Logger } from '../logger/core.js';
function getFunctionExpression(slot: any) { function getFunctionExpression(slot: any) {
if (!slot) return; if (!slot) return;
if (slot.expressions?.length !== 1) return; const expressions = slot?.expressions?.filter((e: unknown) => isRenderInstruction(e) === false);
return slot.expressions[0] as (...args: any[]) => any; if (expressions?.length !== 1) return
return expressions[0] as (...args: any[]) => any;
} }
export class Slots { export class Slots {

View file

@ -11,7 +11,7 @@ const renderTemplateResultSym = Symbol.for('astro.renderTemplateResult');
export class RenderTemplateResult { export class RenderTemplateResult {
public [renderTemplateResultSym] = true; public [renderTemplateResultSym] = true;
private htmlParts: TemplateStringsArray; private htmlParts: TemplateStringsArray;
private expressions: any[]; public expressions: any[];
private error: Error | undefined; private error: Error | undefined;
constructor(htmlParts: TemplateStringsArray, expressions: unknown[]) { constructor(htmlParts: TemplateStringsArray, expressions: unknown[]) {
this.htmlParts = htmlParts; this.htmlParts = htmlParts;

View file

@ -170,4 +170,15 @@ describe('Slots', () => {
assert.notEqual(third.children[0].data, first.children[0].data); assert.notEqual(third.children[0].data, first.children[0].data);
} }
}); });
it("Arguments can be passed to named slots with Astro.slots.render()", async () => {
const html = await fixture.readFile('/slotted-named-functions/index.html');
const $ = cheerio.load(html);
const befor = $("div#before");
const [ beforeDiv ] = befor.children("div")
assert.deepEqual(beforeDiv.firstChild.data, "Test Content BEFORE")
const after = $("div#after");
const [ afterDiv ] = after.children("div");
assert.deepEqual(afterDiv.firstChild.data, "Test Content AFTER")
});
}); });

View file

@ -0,0 +1,12 @@
---
const content = 'Test Content';
const beforeConent = await Astro.slots.render("before", [{content}])
const afterConent = await Astro.slots.render("after", [{content}])
---
<div id="before">
{beforeConent}
</div>
<div id="after">
{afterConent}
</div>

View file

@ -0,0 +1,11 @@
---
import Field from '../components/FunctionsToAPI.astro'
---
<Field>
<div slot="before">
{({content}) => <div>{content} BEFORE</div>}
</div>
<div slot="after">
{({content}) => <div>{content} AFTER</div>}
</div>
</Field>