Support Astro.slots.render for mdx (#4973)
* Support Astro.slots.render for mdx * Remove extra imports
This commit is contained in:
parent
5d58787f7a
commit
c733d4fb81
8 changed files with 69 additions and 2 deletions
5
.changeset/friendly-wolves-juggle.md
Normal file
5
.changeset/friendly-wolves-juggle.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Support Astro.slots.render for mdx
|
|
@ -11,6 +11,7 @@ import type {
|
|||
SSRResult,
|
||||
} from '../../@types/astro';
|
||||
import { renderSlot } from '../../runtime/server/index.js';
|
||||
import { renderJSX } from '../../runtime/server/jsx.js';
|
||||
import { AstroCookies } from '../cookies/index.js';
|
||||
import { LogOptions, warn } from '../logger/core.js';
|
||||
import { isScriptRequest } from './script.js';
|
||||
|
@ -94,8 +95,6 @@ class Slots {
|
|||
if (!this.has(name)) return undefined;
|
||||
if (!cacheable) {
|
||||
const component = await this.#slots[name]();
|
||||
const expression = getFunctionExpression(component);
|
||||
|
||||
if (!Array.isArray(args)) {
|
||||
warn(
|
||||
this.#loggingOpts,
|
||||
|
@ -103,12 +102,20 @@ class Slots {
|
|||
`Expected second parameter to be an array, received a ${typeof args}. If you're trying to pass an array as a single argument and getting unexpected results, make sure you're passing your array as a item of an array. Ex: Astro.slots.render('default', [["Hello", "World"]])`
|
||||
);
|
||||
} else {
|
||||
// Astro
|
||||
const expression = getFunctionExpression(component);
|
||||
if (expression) {
|
||||
const slot = expression(...args);
|
||||
return await renderSlot(this.#result, slot).then((res) =>
|
||||
res != null ? String(res) : res
|
||||
);
|
||||
}
|
||||
// JSX
|
||||
if (typeof component === 'function') {
|
||||
return await renderJSX(this.#result, component(...args)).then((res) =>
|
||||
res != null ? String(res) : res
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
const content = await renderSlot(this.#result, this.#slots[name]).then((res) =>
|
||||
|
|
|
@ -29,6 +29,8 @@ export async function renderJSX(result: SSRResult, vnode: any): Promise<any> {
|
|||
return vnode;
|
||||
case typeof vnode === 'string':
|
||||
return markHTMLString(escapeHTML(vnode));
|
||||
case typeof vnode === 'function':
|
||||
return vnode;
|
||||
case !vnode && vnode !== 0:
|
||||
return '';
|
||||
case Array.isArray(vnode):
|
||||
|
|
6
packages/astro/test/fixtures/slots-react/src/components/Render.astro
vendored
Normal file
6
packages/astro/test/fixtures/slots-react/src/components/Render.astro
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
const { id } = Astro.props;
|
||||
const content = await Astro.slots.render('default');
|
||||
---
|
||||
|
||||
<div id={id} set:html={content} />
|
5
packages/astro/test/fixtures/slots-react/src/components/RenderArgs.astro
vendored
Normal file
5
packages/astro/test/fixtures/slots-react/src/components/RenderArgs.astro
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
const { id, text } = Astro.props;
|
||||
---
|
||||
|
||||
<div id={id} set:html={Astro.slots.render('default', [text])} />
|
6
packages/astro/test/fixtures/slots-react/src/components/RenderFn.astro
vendored
Normal file
6
packages/astro/test/fixtures/slots-react/src/components/RenderFn.astro
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
const { id } = Astro.props;
|
||||
const content = await Astro.slots.render('default');
|
||||
---
|
||||
|
||||
<div id={id} set:html={content} />
|
9
packages/astro/test/fixtures/slots-react/src/pages/slottedapi-render.mdx
vendored
Normal file
9
packages/astro/test/fixtures/slots-react/src/pages/slottedapi-render.mdx
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
import Render from '../components/Render.astro';
|
||||
import RenderFn from '../components/RenderFn.astro';
|
||||
import RenderArgs from '../components/RenderArgs.astro';
|
||||
|
||||
# Slots: MDX
|
||||
|
||||
<Render id="render">render</Render>
|
||||
<RenderFn id="render-fn">{() => "render-fn"}</RenderFn>
|
||||
<RenderArgs id="render-args" text="render-args">{(text) => <span>{text}</span>}</RenderArgs>
|
|
@ -73,4 +73,31 @@ describe('Slots: React', () => {
|
|||
expect($('#dash-case').text().trim()).to.equal('Fallback / Dash Case');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Slots.render() API', async () => {
|
||||
it('Simple imperative slot render', async () => {
|
||||
const html = await fixture.readFile('/slottedapi-render/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('#render')).to.have.lengthOf(1);
|
||||
expect($('#render').text()).to.equal('render');
|
||||
});
|
||||
|
||||
it('Child function render without args', async () => {
|
||||
const html = await fixture.readFile('/slottedapi-render/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('#render-fn')).to.have.lengthOf(1);
|
||||
expect($('#render-fn').text()).to.equal('render-fn');
|
||||
});
|
||||
|
||||
it('Child function render with args', async () => {
|
||||
const html = await fixture.readFile('/slottedapi-render/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('#render-args')).to.have.lengthOf(1);
|
||||
expect($('#render-args span')).to.have.lengthOf(1);
|
||||
expect($('#render-args').text()).to.equal('render-args');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue