diff --git a/.changeset/smooth-files-attend.md b/.changeset/smooth-files-attend.md new file mode 100644 index 000000000..0348a11e8 --- /dev/null +++ b/.changeset/smooth-files-attend.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fix usage of slots inside expressions diff --git a/packages/astro/package.json b/packages/astro/package.json index 3903b2a84..93e54affd 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -80,7 +80,7 @@ "test:e2e:match": "playwright test -g" }, "dependencies": { - "@astrojs/compiler": "^0.17.1", + "@astrojs/compiler": "^0.18.0", "@astrojs/language-server": "^0.13.4", "@astrojs/markdown-remark": "^0.11.3", "@astrojs/prism": "0.4.1", diff --git a/packages/astro/src/runtime/server/index.ts b/packages/astro/src/runtime/server/index.ts index c796ba13b..230c043ed 100644 --- a/packages/astro/src/runtime/server/index.ts +++ b/packages/astro/src/runtime/server/index.ts @@ -142,6 +142,19 @@ export async function renderSlot(_result: any, slotted: string, fallback?: any): return fallback; } +export function mergeSlots(...slotted: unknown[]) { + const slots: Record any> = {}; + for (const slot of slotted) { + if (!slot) continue; + if (typeof slot === 'object') { + Object.assign(slots, slot); + } else if (typeof slot === 'function') { + Object.assign(slots, mergeSlots(slot())); + } + } + return slots; +} + export const Fragment = Symbol('Astro.Fragment'); function guessRenderers(componentUrl?: string): string[] { diff --git a/packages/astro/test/astro-expr.test.js b/packages/astro/test/astro-expr.test.js index c3c71450f..33a976d33 100644 --- a/packages/astro/test/astro-expr.test.js +++ b/packages/astro/test/astro-expr.test.js @@ -114,4 +114,13 @@ describe('Expressions', () => { expect($('#single-escape').html()).to.equal('Astro & Vite'); }); + + it('Handles switch statements', async () => { + const html = await fixture.readFile('/switch/index.html'); + const $ = cheerio.load(html); + + expect($('#red').length).to.equal(0); + expect($('#yellow').length).to.equal(1); + expect($('#blue').length).to.equal(0); + }); }); diff --git a/packages/astro/test/astro-slots.test.js b/packages/astro/test/astro-slots.test.js index 60d4e2560..b5ab05909 100644 --- a/packages/astro/test/astro-slots.test.js +++ b/packages/astro/test/astro-slots.test.js @@ -30,6 +30,16 @@ describe('Slots', () => { expect($('#default').text().trim()).to.equal('Default'); }); + it('Conditional named slots work', async () => { + const html = await fixture.readFile('/conditional/index.html'); + const $ = cheerio.load(html); + + expect($('#a').text().trim()).to.equal('A'); + expect($('#b').text().trim()).to.equal('B'); + expect($('#c').text().trim()).to.equal('C'); + expect($('#default').text().trim()).to.equal('Default'); + }); + it('Slots render fallback content by default', async () => { const html = await fixture.readFile('/fallback/index.html'); const $ = cheerio.load(html); diff --git a/packages/astro/test/fixtures/astro-expr/src/pages/switch.astro b/packages/astro/test/fixtures/astro-expr/src/pages/switch.astro new file mode 100644 index 000000000..ded58613e --- /dev/null +++ b/packages/astro/test/fixtures/astro-expr/src/pages/switch.astro @@ -0,0 +1,20 @@ +--- +let title = 'Switch'; +let colors = ['red', 'yellow', 'blue']; +--- + + + + {title} + + + {() => { + const color = colors[1]; + switch (color) { + case 'red': return
red
; + case 'yellow': return
yellow
+ case 'blue': return
blue
+ } + }} + + diff --git a/packages/astro/test/fixtures/astro-slots/src/pages/conditional.astro b/packages/astro/test/fixtures/astro-slots/src/pages/conditional.astro new file mode 100644 index 000000000..2cc6747b7 --- /dev/null +++ b/packages/astro/test/fixtures/astro-slots/src/pages/conditional.astro @@ -0,0 +1,27 @@ +--- +import Slotted from '../components/Slotted.astro'; +--- + + + + + + + + {true && A} + {true ? B : null} + {() => C} + {() => { + const value = 0.33; + if (value > 0.25) { + return Default + } else if (value > 0.5) { + return Another + } else if (value > 0.75) { + return Other + } + return Yet Another + }} + + + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9aa6f057a..f904c6db4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -483,7 +483,7 @@ importers: packages/astro: specifiers: - '@astrojs/compiler': ^0.17.1 + '@astrojs/compiler': ^0.18.0 '@astrojs/language-server': ^0.13.4 '@astrojs/markdown-remark': ^0.11.3 '@astrojs/prism': 0.4.1 @@ -567,7 +567,7 @@ importers: yargs-parser: ^21.0.1 zod: ^3.17.3 dependencies: - '@astrojs/compiler': 0.17.1 + '@astrojs/compiler': 0.18.0 '@astrojs/language-server': 0.13.4 '@astrojs/markdown-remark': link:../markdown/remark '@astrojs/prism': link:../astro-prism @@ -2636,8 +2636,8 @@ packages: leven: 3.1.0 dev: true - /@astrojs/compiler/0.17.1: - resolution: {integrity: sha512-TawCnNbN00PXVHrps7zk/WwlcxaJQ8gVjk+tel57UQtSt3PmTsarlmq/uX165xKgn2/3Vz5inTNJxoDnr2pZBQ==} + /@astrojs/compiler/0.18.0: + resolution: {integrity: sha512-iBX4Fm5FwAnDLJcnH6DII41lla6iLX3gSabZ884P5TuG+CxL3fEew9gZ6AhTUnpyNXuyuYb6+xWQPQdNA9KsXA==} dev: false /@astrojs/language-server/0.13.4: