fix a bug when Fragment is as a slot (#6832)

* fix a bug when Fragment is as a slot

* update yaml

* fix ts errpr

* fix astro name of md

---------

Co-authored-by: wuls <linsheng.wu@beantechs.com>
This commit is contained in:
wulinsheng123 2023-05-24 03:40:21 +08:00 committed by GitHub
parent 57e65d247f
commit 904131aec3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 47 additions and 4 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
fix a bug when Fragment is as a slot

View file

@ -18,6 +18,7 @@ import { renderJSX } from '../../runtime/server/jsx.js';
import { AstroCookies } from '../cookies/index.js'; import { AstroCookies } from '../cookies/index.js';
import { AstroError, AstroErrorData } from '../errors/index.js'; import { AstroError, AstroErrorData } from '../errors/index.js';
import { warn, type LogOptions } from '../logger/core.js'; import { warn, type LogOptions } from '../logger/core.js';
import { isHTMLString } from '../../runtime/server/escape.js';
const clientAddressSymbol = Symbol.for('astro.clientAddress'); const clientAddressSymbol = Symbol.for('astro.clientAddress');
const responseSentSymbol = Symbol.for('astro.responseSent'); const responseSentSymbol = Symbol.for('astro.responseSent');
@ -110,9 +111,11 @@ class Slots {
// Astro // Astro
const expression = getFunctionExpression(component); const expression = getFunctionExpression(component);
if (expression) { if (expression) {
const slot = () => expression(...args); const slot = async () => isHTMLString(await expression) ? expression : expression(...args)
return await renderSlotToString(result, slot).then((res) => return await renderSlotToString(result, slot).then((res) =>{
res != null ? String(res) : res return res != null ? String(res) : res
}
); );
} }
// JSX // JSX

View file

@ -7,7 +7,7 @@ import { renderChild } from './any.js';
type RenderTemplateResult = ReturnType<typeof renderTemplate>; type RenderTemplateResult = ReturnType<typeof renderTemplate>;
export type ComponentSlots = Record<string, ComponentSlotValue>; 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'); const slotString = Symbol.for('astro:slot-string');

View file

@ -0,0 +1,2 @@
<Fragment set:html={Astro.slots.render('name', ['arg'])} />

View file

@ -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>

View file

@ -35,6 +35,12 @@ describe('set:html', () => {
expect($('#fetched-html')).to.have.a.lengthOf(1); expect($('#fetched-html')).to.have.a.lengthOf(1);
expect($('#fetched-html').text()).to.equal('works'); 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', () => { describe('Build', () => {
@ -77,5 +83,10 @@ describe('set:html', () => {
const $ = cheerio.load(html); const $ = cheerio.load(html);
expect($('#readable-inner')).to.have.a.lengthOf(1); 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');
})
}); });
}); });