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 { 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 */
|
||||||
|
|
|
@ -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 {
|
|
@ -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;
|
||||||
|
|
|
@ -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")
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
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