diff --git a/.changeset/curvy-snakes-turn.md b/.changeset/curvy-snakes-turn.md new file mode 100644 index 000000000..07349e478 --- /dev/null +++ b/.changeset/curvy-snakes-turn.md @@ -0,0 +1,5 @@ +--- +'@astrojs/svelte': patch +--- + +Fix unmounting slots passed to Svelte components diff --git a/packages/astro/e2e/fixtures/svelte-component/src/components/ToggleSlots.svelte b/packages/astro/e2e/fixtures/svelte-component/src/components/ToggleSlots.svelte new file mode 100644 index 000000000..3a8595ff5 --- /dev/null +++ b/packages/astro/e2e/fixtures/svelte-component/src/components/ToggleSlots.svelte @@ -0,0 +1,12 @@ + + + diff --git a/packages/astro/e2e/fixtures/svelte-component/src/env.d.ts b/packages/astro/e2e/fixtures/svelte-component/src/env.d.ts new file mode 100644 index 000000000..8c34fb45e --- /dev/null +++ b/packages/astro/e2e/fixtures/svelte-component/src/env.d.ts @@ -0,0 +1 @@ +/// \ No newline at end of file diff --git a/packages/astro/e2e/fixtures/svelte-component/src/pages/index.astro b/packages/astro/e2e/fixtures/svelte-component/src/pages/index.astro index 9bd8f23bf..472b863f6 100644 --- a/packages/astro/e2e/fixtures/svelte-component/src/pages/index.astro +++ b/packages/astro/e2e/fixtures/svelte-component/src/pages/index.astro @@ -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 = { + + +
+ open +
+
+ close +
+
diff --git a/packages/astro/e2e/svelte-component.test.js b/packages/astro/e2e/svelte-component.test.js index d267aeafe..30ed2eeb4 100644 --- a/packages/astro/e2e/svelte-component.test.js +++ b/packages/astro/e2e/svelte-component.test.js @@ -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'); + }); +}); diff --git a/packages/integrations/svelte/client.js b/packages/integrations/svelte/client.js index 406500374..658ddb02f 100644 --- a/packages/integrations/svelte/client.js +++ b/packages/integrations/svelte/client.js @@ -23,10 +23,12 @@ export default (target) => { }; function createSlotDefinition(key, children) { + let parent; return [ () => ({ // mount m(target) { + parent = target; target.insertAdjacentHTML( 'beforeend', `${children}` @@ -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,