Fix slot attribute inside expressions (#3837)
* fix: use slots inside expressions * test: add test for conditional named slots * test: fix incorrect test fixture * chore: update `@astrojs/compiler` * chore: add test coverage for `switch` Co-authored-by: Nate Moore <nate@astro.build>
This commit is contained in:
parent
c191098b97
commit
5afb807688
8 changed files with 89 additions and 5 deletions
5
.changeset/smooth-files-attend.md
Normal file
5
.changeset/smooth-files-attend.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix usage of slots inside expressions
|
|
@ -80,7 +80,7 @@
|
||||||
"test:e2e:match": "playwright test -g"
|
"test:e2e:match": "playwright test -g"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/compiler": "^0.17.1",
|
"@astrojs/compiler": "^0.18.0",
|
||||||
"@astrojs/language-server": "^0.13.4",
|
"@astrojs/language-server": "^0.13.4",
|
||||||
"@astrojs/markdown-remark": "^0.11.3",
|
"@astrojs/markdown-remark": "^0.11.3",
|
||||||
"@astrojs/prism": "0.4.1",
|
"@astrojs/prism": "0.4.1",
|
||||||
|
|
|
@ -142,6 +142,19 @@ export async function renderSlot(_result: any, slotted: string, fallback?: any):
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function mergeSlots(...slotted: unknown[]) {
|
||||||
|
const slots: Record<string, () => 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');
|
export const Fragment = Symbol('Astro.Fragment');
|
||||||
|
|
||||||
function guessRenderers(componentUrl?: string): string[] {
|
function guessRenderers(componentUrl?: string): string[] {
|
||||||
|
|
|
@ -114,4 +114,13 @@ describe('Expressions', () => {
|
||||||
|
|
||||||
expect($('#single-escape').html()).to.equal('Astro & Vite');
|
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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -30,6 +30,16 @@ describe('Slots', () => {
|
||||||
expect($('#default').text().trim()).to.equal('Default');
|
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 () => {
|
it('Slots render fallback content by default', async () => {
|
||||||
const html = await fixture.readFile('/fallback/index.html');
|
const html = await fixture.readFile('/fallback/index.html');
|
||||||
const $ = cheerio.load(html);
|
const $ = cheerio.load(html);
|
||||||
|
|
20
packages/astro/test/fixtures/astro-expr/src/pages/switch.astro
vendored
Normal file
20
packages/astro/test/fixtures/astro-expr/src/pages/switch.astro
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
let title = 'Switch';
|
||||||
|
let colors = ['red', 'yellow', 'blue'];
|
||||||
|
---
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{title}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{() => {
|
||||||
|
const color = colors[1];
|
||||||
|
switch (color) {
|
||||||
|
case 'red': return <div id="red">red</div>;
|
||||||
|
case 'yellow': return <div id="yellow">yellow</div>
|
||||||
|
case 'blue': return <div id="blue">blue</div>
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
</body>
|
||||||
|
</html>
|
27
packages/astro/test/fixtures/astro-slots/src/pages/conditional.astro
vendored
Normal file
27
packages/astro/test/fixtures/astro-slots/src/pages/conditional.astro
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
import Slotted from '../components/Slotted.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Head Stuff -->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<Slotted>
|
||||||
|
{true && <span slot="a">A</span>}
|
||||||
|
{true ? <span slot="b">B</span> : null}
|
||||||
|
{() => <span slot="c">C</span>}
|
||||||
|
{() => {
|
||||||
|
const value = 0.33;
|
||||||
|
if (value > 0.25) {
|
||||||
|
return <span>Default</span>
|
||||||
|
} else if (value > 0.5) {
|
||||||
|
return <span>Another</span>
|
||||||
|
} else if (value > 0.75) {
|
||||||
|
return <span>Other</span>
|
||||||
|
}
|
||||||
|
return <span>Yet Another</span>
|
||||||
|
}}
|
||||||
|
</Slotted>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -483,7 +483,7 @@ importers:
|
||||||
|
|
||||||
packages/astro:
|
packages/astro:
|
||||||
specifiers:
|
specifiers:
|
||||||
'@astrojs/compiler': ^0.17.1
|
'@astrojs/compiler': ^0.18.0
|
||||||
'@astrojs/language-server': ^0.13.4
|
'@astrojs/language-server': ^0.13.4
|
||||||
'@astrojs/markdown-remark': ^0.11.3
|
'@astrojs/markdown-remark': ^0.11.3
|
||||||
'@astrojs/prism': 0.4.1
|
'@astrojs/prism': 0.4.1
|
||||||
|
@ -567,7 +567,7 @@ importers:
|
||||||
yargs-parser: ^21.0.1
|
yargs-parser: ^21.0.1
|
||||||
zod: ^3.17.3
|
zod: ^3.17.3
|
||||||
dependencies:
|
dependencies:
|
||||||
'@astrojs/compiler': 0.17.1
|
'@astrojs/compiler': 0.18.0
|
||||||
'@astrojs/language-server': 0.13.4
|
'@astrojs/language-server': 0.13.4
|
||||||
'@astrojs/markdown-remark': link:../markdown/remark
|
'@astrojs/markdown-remark': link:../markdown/remark
|
||||||
'@astrojs/prism': link:../astro-prism
|
'@astrojs/prism': link:../astro-prism
|
||||||
|
@ -2636,8 +2636,8 @@ packages:
|
||||||
leven: 3.1.0
|
leven: 3.1.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@astrojs/compiler/0.17.1:
|
/@astrojs/compiler/0.18.0:
|
||||||
resolution: {integrity: sha512-TawCnNbN00PXVHrps7zk/WwlcxaJQ8gVjk+tel57UQtSt3PmTsarlmq/uX165xKgn2/3Vz5inTNJxoDnr2pZBQ==}
|
resolution: {integrity: sha512-iBX4Fm5FwAnDLJcnH6DII41lla6iLX3gSabZ884P5TuG+CxL3fEew9gZ6AhTUnpyNXuyuYb6+xWQPQdNA9KsXA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@astrojs/language-server/0.13.4:
|
/@astrojs/language-server/0.13.4:
|
||||||
|
|
Loading…
Reference in a new issue