Fix unmount Svelte slots (#6250)
This commit is contained in:
parent
4b89c2b553
commit
5c7c7e463d
6 changed files with 49 additions and 1 deletions
5
.changeset/curvy-snakes-turn.md
Normal file
5
.changeset/curvy-snakes-turn.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@astrojs/svelte': patch
|
||||
---
|
||||
|
||||
Fix unmounting slots passed to Svelte components
|
|
@ -0,0 +1,12 @@
|
|||
<script>
|
||||
let isNavOpen = false;
|
||||
const toggleNav = () => (isNavOpen = !isNavOpen);
|
||||
</script>
|
||||
|
||||
<button id="toggle" on:click={toggleNav}>
|
||||
{#if isNavOpen}
|
||||
<slot name="open" />
|
||||
{:else}
|
||||
<slot name="close" />
|
||||
{/if}
|
||||
</button>
|
1
packages/astro/e2e/fixtures/svelte-component/src/env.d.ts
vendored
Normal file
1
packages/astro/e2e/fixtures/svelte-component/src/env.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/// <reference types="astro/client" />
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
import Counter from '../components/Counter.svelte';
|
||||
import SvelteComponent from '../components/SvelteComponent.svelte';
|
||||
import ToggleSlots from '../components/ToggleSlots.svelte';
|
||||
|
||||
const someProps = {
|
||||
count: 0,
|
||||
|
@ -33,5 +34,14 @@ const someProps = {
|
|||
</Counter>
|
||||
|
||||
<SvelteComponent id="client-only" client:only="svelte" />
|
||||
|
||||
<ToggleSlots client:load>
|
||||
<div slot="open">
|
||||
open
|
||||
</div>
|
||||
<div slot="close">
|
||||
close
|
||||
</div>
|
||||
</ToggleSlots>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { expect } from '@playwright/test';
|
||||
import { prepareTestFactory } from './shared-component-tests.js';
|
||||
|
||||
const { test, createTests } = prepareTestFactory({ root: './fixtures/svelte-component/' });
|
||||
|
@ -23,3 +24,14 @@ test.describe('Svelte components in MDX files', () => {
|
|||
pageSourceFilePath: './src/pages/mdx.mdx',
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Svelte components lifecycle', () => {
|
||||
test('slot should unmount properly', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const toggle = page.locator('#toggle');
|
||||
expect((await toggle.textContent()).trim()).toBe('close');
|
||||
await toggle.click()
|
||||
expect((await toggle.textContent()).trim()).toBe('open');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -23,10 +23,12 @@ export default (target) => {
|
|||
};
|
||||
|
||||
function createSlotDefinition(key, children) {
|
||||
let parent;
|
||||
return [
|
||||
() => ({
|
||||
// mount
|
||||
m(target) {
|
||||
parent = target;
|
||||
target.insertAdjacentHTML(
|
||||
'beforeend',
|
||||
`<astro-slot${key === 'default' ? '' : ` name="${key}"`}>${children}</astro-slot>`
|
||||
|
@ -37,7 +39,13 @@ function createSlotDefinition(key, children) {
|
|||
// hydrate
|
||||
l: noop,
|
||||
// destroy
|
||||
d: noop,
|
||||
d() {
|
||||
if (!parent) return;
|
||||
const slot = parent.querySelector(
|
||||
`astro-slot${key === 'default' ? ':not([name])' : `[name="${key}"]`}`
|
||||
);
|
||||
if (slot) slot.remove();
|
||||
},
|
||||
}),
|
||||
noop,
|
||||
noop,
|
||||
|
|
Loading…
Reference in a new issue