Added more clarification around using Astro.slots.render
(#4456)
* Add an error message for when something that's not an array is passed to Astro.slots.render * Add changeset * Add more details
This commit is contained in:
parent
78334b9765
commit
47e71ae8f8
3 changed files with 39 additions and 7 deletions
5
.changeset/unlucky-otters-end.md
Normal file
5
.changeset/unlucky-otters-end.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Added an error message when the second argument of Astro.slots.render is not an array
|
|
@ -203,7 +203,7 @@ export interface AstroGlobal extends AstroGlobalPartial {
|
|||
*/
|
||||
has(slotName: string): boolean;
|
||||
/**
|
||||
* Asychronously renders this slot and returns HTML
|
||||
* Asynchronously renders this slot and returns a string
|
||||
*
|
||||
* Example usage:
|
||||
* ```astro
|
||||
|
@ -216,6 +216,21 @@ export interface AstroGlobal extends AstroGlobalPartial {
|
|||
* <Fragment set:html={html} />
|
||||
* ```
|
||||
*
|
||||
* A second parameters can be used to pass arguments to a slotted callback
|
||||
*
|
||||
* Example usage:
|
||||
* ```astro
|
||||
* ---
|
||||
* html = await Astro.slots.render('default', ["Hello", "World"])
|
||||
* ---
|
||||
* ```
|
||||
* Each item in the array will be passed as an argument that you can use like so:
|
||||
* ```astro
|
||||
* <Component>
|
||||
* {(hello, world) => <div>{hello}, {world}!</div>}
|
||||
* </Component>
|
||||
* ```
|
||||
*
|
||||
* [Astro reference](https://docs.astro.build/en/reference/api-reference/#astroslots)
|
||||
*/
|
||||
render(slotName: string, args?: any[]): Promise<string>;
|
||||
|
|
|
@ -55,10 +55,13 @@ class Slots {
|
|||
#cache = new Map<string, string>();
|
||||
#result: SSRResult;
|
||||
#slots: Record<string, any> | null;
|
||||
#loggingOpts: LogOptions;
|
||||
|
||||
constructor(result: SSRResult, slots: Record<string, any> | null) {
|
||||
constructor(result: SSRResult, slots: Record<string, any> | null, logging: LogOptions) {
|
||||
this.#result = result;
|
||||
this.#slots = slots;
|
||||
this.#loggingOpts = logging;
|
||||
|
||||
if (slots) {
|
||||
for (const key of Object.keys(slots)) {
|
||||
if ((this as any)[key] !== undefined) {
|
||||
|
@ -92,11 +95,20 @@ class Slots {
|
|||
if (!cacheable) {
|
||||
const component = await this.#slots[name]();
|
||||
const expression = getFunctionExpression(component);
|
||||
if (expression) {
|
||||
const slot = expression(...args);
|
||||
return await renderSlot(this.#result, slot).then((res) =>
|
||||
res != null ? String(res) : res
|
||||
|
||||
if (!Array.isArray(args)) {
|
||||
warn(
|
||||
this.#loggingOpts,
|
||||
'Astro.slots.render',
|
||||
`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 {
|
||||
if (expression) {
|
||||
const slot = expression(...args);
|
||||
return await renderSlot(this.#result, slot).then((res) =>
|
||||
res != null ? String(res) : res
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
const content = await renderSlot(this.#result, this.#slots[name]).then((res) =>
|
||||
|
@ -146,7 +158,7 @@ export function createResult(args: CreateResultArgs): SSRResult {
|
|||
props: Record<string, any>,
|
||||
slots: Record<string, any> | null
|
||||
) {
|
||||
const astroSlots = new Slots(result, slots);
|
||||
const astroSlots = new Slots(result, slots, args.logging);
|
||||
|
||||
const Astro = {
|
||||
__proto__: astroGlobal,
|
||||
|
|
Loading…
Reference in a new issue