From 994337c99f84304df1147a14504659439a9a7326 Mon Sep 17 00:00:00 2001 From: Arsh <69170106+lilnasy@users.noreply.github.com> Date: Thu, 11 Apr 2024 08:07:21 +0530 Subject: [PATCH] fix(rendering): remove render instructions from slot expressions (#10747) --- .changeset/calm-mails-check.md | 5 +++++ packages/astro/src/core/render/index.ts | 2 +- .../astro/src/core/render/{result.ts => slots.ts} | 6 ++++-- .../runtime/server/render/astro/render-template.ts | 2 +- packages/astro/test/astro-slots.test.js | 11 +++++++++++ .../astro-slots/src/components/FunctionsToAPI.astro | 12 ++++++++++++ .../src/pages/slotted-named-functions.astro | 11 +++++++++++ 7 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 .changeset/calm-mails-check.md rename packages/astro/src/core/render/{result.ts => slots.ts} (90%) create mode 100644 packages/astro/test/fixtures/astro-slots/src/components/FunctionsToAPI.astro create mode 100644 packages/astro/test/fixtures/astro-slots/src/pages/slotted-named-functions.astro diff --git a/.changeset/calm-mails-check.md b/.changeset/calm-mails-check.md new file mode 100644 index 0000000000..7de709c1b0 --- /dev/null +++ b/.changeset/calm-mails-check.md @@ -0,0 +1,5 @@ +--- +"astro": patch +--- + +Fixes an issue where functions could not be used as named slots. diff --git a/packages/astro/src/core/render/index.ts b/packages/astro/src/core/render/index.ts index 35b5ce76ec..db14701b0f 100644 --- a/packages/astro/src/core/render/index.ts +++ b/packages/astro/src/core/render/index.ts @@ -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 */ diff --git a/packages/astro/src/core/render/result.ts b/packages/astro/src/core/render/slots.ts similarity index 90% rename from packages/astro/src/core/render/result.ts rename to packages/astro/src/core/render/slots.ts index e23e87adf7..f6d469b2a7 100644 --- a/packages/astro/src/core/render/result.ts +++ b/packages/astro/src/core/render/slots.ts @@ -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 { diff --git a/packages/astro/src/runtime/server/render/astro/render-template.ts b/packages/astro/src/runtime/server/render/astro/render-template.ts index f12344fe86..68df865181 100644 --- a/packages/astro/src/runtime/server/render/astro/render-template.ts +++ b/packages/astro/src/runtime/server/render/astro/render-template.ts @@ -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; diff --git a/packages/astro/test/astro-slots.test.js b/packages/astro/test/astro-slots.test.js index 5653e0421c..5078ead05e 100644 --- a/packages/astro/test/astro-slots.test.js +++ b/packages/astro/test/astro-slots.test.js @@ -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") + }); }); diff --git a/packages/astro/test/fixtures/astro-slots/src/components/FunctionsToAPI.astro b/packages/astro/test/fixtures/astro-slots/src/components/FunctionsToAPI.astro new file mode 100644 index 0000000000..93d50689fa --- /dev/null +++ b/packages/astro/test/fixtures/astro-slots/src/components/FunctionsToAPI.astro @@ -0,0 +1,12 @@ +--- +const content = 'Test Content'; +const beforeConent = await Astro.slots.render("before", [{content}]) +const afterConent = await Astro.slots.render("after", [{content}]) +--- +
+ {beforeConent} +
+
+ {afterConent} +
+ diff --git a/packages/astro/test/fixtures/astro-slots/src/pages/slotted-named-functions.astro b/packages/astro/test/fixtures/astro-slots/src/pages/slotted-named-functions.astro new file mode 100644 index 0000000000..7885af6946 --- /dev/null +++ b/packages/astro/test/fixtures/astro-slots/src/pages/slotted-named-functions.astro @@ -0,0 +1,11 @@ +--- +import Field from '../components/FunctionsToAPI.astro' +--- + +
+ {({content}) =>
{content} BEFORE
} +
+
+ {({content}) =>
{content} AFTER
} +
+
\ No newline at end of file