diff --git a/.changeset/tidy-spies-beg.md b/.changeset/tidy-spies-beg.md new file mode 100644 index 0000000000..ca8049eaad --- /dev/null +++ b/.changeset/tidy-spies-beg.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: better children snippet / default slot interop diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js index ccf0e23dd2..e98c4f04f5 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js @@ -231,7 +231,9 @@ export function build_component(node, component_name, context, anchor = context. push_prop(b.prop('init', child.expression, child.expression)); // Interop: allows people to pass snippets when component still uses slots - serialized_slots.push(b.init(child.expression.name, b.true)); + serialized_slots.push( + b.init(child.expression.name === 'children' ? 'default' : child.expression.name, b.true) + ); continue; } @@ -273,7 +275,14 @@ export function build_component(node, component_name, context, anchor = context. ); if (slot_name === 'default' && !has_children_prop) { - if (lets.length === 0 && children.default.every((node) => node.type !== 'SvelteFragment')) { + if ( + lets.length === 0 && + children.default.every( + (node) => + node.type !== 'SvelteFragment' || + !node.attributes.some((attr) => attr.type === 'LetDirective') + ) + ) { // create `children` prop... push_prop( b.init( diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js index 7da60cad21..79df3cdd04 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js @@ -120,7 +120,9 @@ export function build_inline_component(node, expression, context) { push_prop(b.prop('init', child.expression, child.expression)); // Interop: allows people to pass snippets when component still uses slots - serialized_slots.push(b.init(child.expression.name, b.true)); + serialized_slots.push( + b.init(child.expression.name === 'children' ? 'default' : child.expression.name, b.true) + ); continue; } @@ -200,7 +202,11 @@ export function build_inline_component(node, expression, context) { if (slot_name === 'default' && !has_children_prop) { if ( lets.default.length === 0 && - children.default.every((node) => node.type !== 'SvelteFragment') + children.default.every( + (node) => + node.type !== 'SvelteFragment' || + !node.attributes.some((attr) => attr.type === 'LetDirective') + ) ) { // create `children` prop... push_prop(b.prop('init', b.id('children'), slot_fn)); diff --git a/packages/svelte/tests/runtime-runes/samples/slot-svelte-fragment-render-tag/_config.js b/packages/svelte/tests/runtime-runes/samples/slot-svelte-fragment-render-tag/_config.js new file mode 100644 index 0000000000..d1e605e850 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/slot-svelte-fragment-render-tag/_config.js @@ -0,0 +1,5 @@ +import { test } from '../../test'; + +export default test({ + html: `

bar

` +}); diff --git a/packages/svelte/tests/runtime-runes/samples/slot-svelte-fragment-render-tag/child.svelte b/packages/svelte/tests/runtime-runes/samples/slot-svelte-fragment-render-tag/child.svelte new file mode 100644 index 0000000000..bf79ef5d9e --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/slot-svelte-fragment-render-tag/child.svelte @@ -0,0 +1,5 @@ + + +{@render children()} diff --git a/packages/svelte/tests/runtime-runes/samples/slot-svelte-fragment-render-tag/main.svelte b/packages/svelte/tests/runtime-runes/samples/slot-svelte-fragment-render-tag/main.svelte new file mode 100644 index 0000000000..85fd85fb61 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/slot-svelte-fragment-render-tag/main.svelte @@ -0,0 +1,9 @@ + + + + +

bar

+
+
diff --git a/packages/svelte/tests/runtime-runes/samples/snippets-as-slots/_config.js b/packages/svelte/tests/runtime-runes/samples/snippets-as-slots/_config.js index 718ca9b50b..b2322bc108 100644 --- a/packages/svelte/tests/runtime-runes/samples/snippets-as-slots/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/snippets-as-slots/_config.js @@ -1,5 +1,5 @@ import { test } from '../../test'; export default test({ - html: `

Default

Named foo

` + html: `

Default foo

Named bar

` }); diff --git a/packages/svelte/tests/runtime-runes/samples/snippets-as-slots/child.svelte b/packages/svelte/tests/runtime-runes/samples/snippets-as-slots/child.svelte index 49ef446e25..01f02c3a8b 100644 --- a/packages/svelte/tests/runtime-runes/samples/snippets-as-slots/child.svelte +++ b/packages/svelte/tests/runtime-runes/samples/snippets-as-slots/child.svelte @@ -1,2 +1,2 @@ -

-

+

+

diff --git a/packages/svelte/tests/runtime-runes/samples/snippets-as-slots/main.svelte b/packages/svelte/tests/runtime-runes/samples/snippets-as-slots/main.svelte index 6f58a1a13f..f80c77b726 100644 --- a/packages/svelte/tests/runtime-runes/samples/snippets-as-slots/main.svelte +++ b/packages/svelte/tests/runtime-runes/samples/snippets-as-slots/main.svelte @@ -3,8 +3,10 @@ - Default - {#snippet named({ foo })} - Named {foo} + {#snippet children({ foo })} + Default {foo} + {/snippet} + {#snippet named({ bar })} + Named {bar} {/snippet}