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,
|
SSRResult,
|
||||||
} from '../../@types/astro';
|
} from '../../@types/astro';
|
||||||
import { renderSlot } from '../../runtime/server/index.js';
|
import { renderSlot } from '../../runtime/server/index.js';
|
||||||
|
import { renderJSX } from '../../runtime/server/jsx.js';
|
||||||
import { AstroCookies } from '../cookies/index.js';
|
import { AstroCookies } from '../cookies/index.js';
|
||||||
import { LogOptions, warn } from '../logger/core.js';
|
import { LogOptions, warn } from '../logger/core.js';
|
||||||
import { isScriptRequest } from './script.js';
|
import { isScriptRequest } from './script.js';
|
||||||
|
@ -94,8 +95,6 @@ class Slots {
|
||||||
if (!this.has(name)) return undefined;
|
if (!this.has(name)) return undefined;
|
||||||
if (!cacheable) {
|
if (!cacheable) {
|
||||||
const component = await this.#slots[name]();
|
const component = await this.#slots[name]();
|
||||||
const expression = getFunctionExpression(component);
|
|
||||||
|
|
||||||
if (!Array.isArray(args)) {
|
if (!Array.isArray(args)) {
|
||||||
warn(
|
warn(
|
||||||
this.#loggingOpts,
|
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"]])`
|
`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 {
|
} else {
|
||||||
|
// Astro
|
||||||
|
const expression = getFunctionExpression(component);
|
||||||
if (expression) {
|
if (expression) {
|
||||||
const slot = expression(...args);
|
const slot = expression(...args);
|
||||||
return await renderSlot(this.#result, slot).then((res) =>
|
return await renderSlot(this.#result, slot).then((res) =>
|
||||||
res != null ? String(res) : 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) =>
|
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;
|
return vnode;
|
||||||
case typeof vnode === 'string':
|
case typeof vnode === 'string':
|
||||||
return markHTMLString(escapeHTML(vnode));
|
return markHTMLString(escapeHTML(vnode));
|
||||||
|
case typeof vnode === 'function':
|
||||||
|
return vnode;
|
||||||
case !vnode && vnode !== 0:
|
case !vnode && vnode !== 0:
|
||||||
return '';
|
return '';
|
||||||
case Array.isArray(vnode):
|
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');
|
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…
Add table
Reference in a new issue