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:
parent
12e34e3cf5
commit
994337c99f
7 changed files with 45 additions and 4 deletions
5
.changeset/calm-mails-check.md
Normal file
5
.changeset/calm-mails-check.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"astro": patch
|
||||
---
|
||||
|
||||
Fixes an issue where functions could not be used as named slots.
|
|
@ -3,7 +3,7 @@ import type { Pipeline } from '../base-pipeline.js';
|
|||
export { Pipeline } from '../base-pipeline.js';
|
||||
export { getParams, getProps } from './params-and-props.js';
|
||||
export { loadRenderer } from './renderer.js';
|
||||
export { Slots } from './result.js';
|
||||
export { Slots } from './slots.js';
|
||||
|
||||
export interface SSROptions {
|
||||
/** The pipeline instance */
|
||||
|
|
|
@ -2,13 +2,15 @@ import type { SSRResult } from '../../@types/astro.js';
|
|||
import { type ComponentSlots, renderSlotToString } from '../../runtime/server/index.js';
|
||||
import { renderJSX } from '../../runtime/server/jsx.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 type { Logger } from '../logger/core.js';
|
||||
|
||||
function getFunctionExpression(slot: any) {
|
||||
if (!slot) return;
|
||||
if (slot.expressions?.length !== 1) return;
|
||||
return slot.expressions[0] as (...args: any[]) => any;
|
||||
const expressions = slot?.expressions?.filter((e: unknown) => isRenderInstruction(e) === false);
|
||||
if (expressions?.length !== 1) return
|
||||
return expressions[0] as (...args: any[]) => any;
|
||||
}
|
||||
|
||||
export class Slots {
|
|
@ -11,7 +11,7 @@ const renderTemplateResultSym = Symbol.for('astro.renderTemplateResult');
|
|||
export class RenderTemplateResult {
|
||||
public [renderTemplateResultSym] = true;
|
||||
private htmlParts: TemplateStringsArray;
|
||||
private expressions: any[];
|
||||
public expressions: any[];
|
||||
private error: Error | undefined;
|
||||
constructor(htmlParts: TemplateStringsArray, expressions: unknown[]) {
|
||||
this.htmlParts = htmlParts;
|
||||
|
|
|
@ -170,4 +170,15 @@ describe('Slots', () => {
|
|||
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")
|
||||
});
|
||||
});
|
||||
|
|
12
packages/astro/test/fixtures/astro-slots/src/components/FunctionsToAPI.astro
vendored
Normal file
12
packages/astro/test/fixtures/astro-slots/src/components/FunctionsToAPI.astro
vendored
Normal 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>
|
||||
|
11
packages/astro/test/fixtures/astro-slots/src/pages/slotted-named-functions.astro
vendored
Normal file
11
packages/astro/test/fixtures/astro-slots/src/pages/slotted-named-functions.astro
vendored
Normal 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>
|
Loading…
Reference in a new issue