Skip to content

Commit

Permalink
Allow Svelte 5 render slots as snippets (#9285)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluwy committed Dec 7, 2023
1 parent dfbc707 commit 1aa7fe8
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/big-shirts-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/svelte': patch
---

When using Svelte 5, slots can now be rendered as snippets
7 changes: 6 additions & 1 deletion packages/integrations/svelte/client-v5.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { mount } from 'svelte';
import { add_snippet_symbol } from 'svelte/internal';

// Allow a slot to be rendered as a snippet (dev validation only)
const tagSlotAsSnippet = import.meta.env.DEV ? add_snippet_symbol : (s) => s;

export default (element) => {
return async (Component, props, slotted) => {
Expand Down Expand Up @@ -32,12 +36,13 @@ function createSlotDefinition(key, children) {
/**
* @param {Comment} $$anchor A comment node for slots in Svelte 5
*/
return ($$anchor, _$$slotProps) => {
const fn = ($$anchor, _$$slotProps) => {
const parent = $$anchor.parentNode;
const el = document.createElement('div');
el.innerHTML = `<astro-slot${
key === 'default' ? '' : ` name="${key}"`
}>${children}</astro-slot>`;
parent.insertBefore(el.children[0], $$anchor);
};
return tagSlotAsSnippet(fn);
}
8 changes: 6 additions & 2 deletions packages/integrations/svelte/server-v5.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { render } from 'svelte/server';
import { add_snippet_symbol } from 'svelte/internal';

// Allow a slot to be rendered as a snippet (dev validation only)
const tagSlotAsSnippet = import.meta.env.DEV ? add_snippet_symbol : (s) => s;

function check(Component) {
// Svelte 5 generated components always accept these two props
Expand All @@ -18,10 +22,10 @@ async function renderToStaticMarkup(Component, props, slotted, metadata) {
let $$slots = undefined;
for (const [key, value] of Object.entries(slotted)) {
if (key === 'default') {
children = () => `<${tagName}>${value}</${tagName}>`;
children = tagSlotAsSnippet(() => `<${tagName}>${value}</${tagName}>`);
} else {
$$slots ??= {};
$$slots[key] = () => `<${tagName} name="${key}">${value}</${tagName}>`;
$$slots[key] = tagSlotAsSnippet(() => `<${tagName} name="${key}">${value}</${tagName}>`);
}
}

Expand Down

0 comments on commit 1aa7fe8

Please sign in to comment.