Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix a bug when Fragment is as a slot #6832

Merged
merged 14 commits into from May 23, 2023
5 changes: 5 additions & 0 deletions .changeset/good-parrots-work.md
@@ -0,0 +1,5 @@
---
'astro': minor
JerryWu1234 marked this conversation as resolved.
Show resolved Hide resolved
---

fix a bug when Fragment is as a slot
9 changes: 6 additions & 3 deletions packages/astro/src/core/render/result.ts
Expand Up @@ -18,6 +18,7 @@ import { renderJSX } from '../../runtime/server/jsx.js';
import { AstroCookies } from '../cookies/index.js';
import { AstroError, AstroErrorData } from '../errors/index.js';
import { warn, type LogOptions } from '../logger/core.js';
import { isHTMLString } from '../../runtime/server/escape.js';

const clientAddressSymbol = Symbol.for('astro.clientAddress');
const responseSentSymbol = Symbol.for('astro.responseSent');
Expand Down Expand Up @@ -108,9 +109,11 @@ class Slots {
// Astro
const expression = getFunctionExpression(component);
if (expression) {
const slot = () => expression(...args);
return await renderSlotToString(result, slot).then((res) =>
res != null ? String(res) : res
const slot = async () => isHTMLString(await expression) ? expression : expression(...args)
return await renderSlotToString(result, slot).then((res) =>{
return res != null ? String(res) : res
}

);
}
// JSX
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/runtime/server/render/slot.ts
Expand Up @@ -7,7 +7,7 @@ import { renderChild } from './any.js';

type RenderTemplateResult = ReturnType<typeof renderTemplate>;
export type ComponentSlots = Record<string, ComponentSlotValue>;
export type ComponentSlotValue = (result: SSRResult) => RenderTemplateResult;
export type ComponentSlotValue = (result: SSRResult) => RenderTemplateResult | Promise<RenderTemplateResult>;

const slotString = Symbol.for('astro:slot-string');

Expand Down
2 changes: 2 additions & 0 deletions packages/astro/test/fixtures/set-html/components/Slot.astro
@@ -0,0 +1,2 @@

<Fragment set:html={Astro.slots.render('name', ['arg'])} />
22 changes: 22 additions & 0 deletions packages/astro/test/fixtures/set-html/src/pages/children.astro
@@ -0,0 +1,22 @@
---
import Slot from '../../components/Slot.astro';
---

<html>
<body>
<h3>Bug: Astro.slots.render() with arguments does not work with &lt;Fragment&gt; slot</h3>
<p>Comment out working example and uncomment non working exmaples</p>
<hr>

<Slot>
<Fragment slot="name">
Test
</Fragment>
</Slot>
<Slot>
<!-- <Fragment slot="name">
{arg => <p>{arg}</p>}
</Fragment> -->
</Slot>
</body>
</html>
11 changes: 11 additions & 0 deletions packages/astro/test/set-html.test.js
Expand Up @@ -35,6 +35,12 @@ describe('set:html', () => {
expect($('#fetched-html')).to.have.a.lengthOf(1);
expect($('#fetched-html').text()).to.equal('works');
});
it('test Fragment when Fragment is as a slot', async () => {
let res = await fixture.fetch('/children');
expect(res.status).to.equal(200);
let html = await res.text();
expect(html).include('Test');
})
});

describe('Build', () => {
Expand Down Expand Up @@ -77,5 +83,10 @@ describe('set:html', () => {
const $ = cheerio.load(html);
expect($('#readable-inner')).to.have.a.lengthOf(1);
});

it('test Fragment when Fragment is as a slot', async () => {
let res = await fixture.readFile('/children/index.html');
expect(res).include('Test');
})
});
});
11 changes: 6 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.