diff --git a/.changeset/ten-plants-carry.md b/.changeset/ten-plants-carry.md new file mode 100644 index 0000000000..91ae5889cf --- /dev/null +++ b/.changeset/ten-plants-carry.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: don't redeclare `$$slots` diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/VariableDeclaration.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/VariableDeclaration.js index 1f2bd3e2b1..b76455b5c1 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/VariableDeclaration.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/VariableDeclaration.js @@ -1,6 +1,7 @@ /** @import { VariableDeclaration, VariableDeclarator, Expression, CallExpression, Pattern, Identifier } from 'estree' */ /** @import { Binding } from '#compiler' */ /** @import { Context } from '../types.js' */ +/** @import { ComponentAnalysis } from '../../../types.js' */ /** @import { Scope } from '../../../scope.js' */ import { build_fallback, extract_paths } from '../../../../utils/ast.js'; import * as b from '#compiler/builders'; @@ -50,20 +51,26 @@ export function VariableDeclaration(node, context) { } } }); + + // if `$$slots` is declared separately, deconflict + const slots_name = /** @type {ComponentAnalysis} */ (context.state.analysis).uses_slots + ? b.id('$$slots_') + : b.id('$$slots'); + if (id.type === 'ObjectPattern' && has_rest) { // If a rest pattern is used within an object pattern, we need to ensure we don't expose $$slots or $$events id.properties.splice( id.properties.length - 1, 0, // @ts-ignore - b.prop('init', b.id('$$slots'), b.id('$$slots')), + b.prop('init', b.id('$$slots'), slots_name), b.prop('init', b.id('$$events'), b.id('$$events')) ); } else if (id.type === 'Identifier') { // If $props is referenced as an identifier, we need to ensure we don't expose $$slots or $$events as properties // on the identifier reference id = b.object_pattern([ - b.prop('init', b.id('$$slots'), b.id('$$slots')), + b.prop('init', b.id('$$slots'), slots_name), b.prop('init', b.id('$$events'), b.id('$$events')), b.rest(b.id(id.name)) ]); diff --git a/packages/svelte/tests/runtime-runes/samples/props-and-slots/Child.svelte b/packages/svelte/tests/runtime-runes/samples/props-and-slots/Child.svelte new file mode 100644 index 0000000000..a2e7d6d8a4 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/props-and-slots/Child.svelte @@ -0,0 +1,9 @@ + + +

{Object.keys(props)}

+ +{#if $$slots.foo} +

foo exists

+{/if} diff --git a/packages/svelte/tests/runtime-runes/samples/props-and-slots/_config.js b/packages/svelte/tests/runtime-runes/samples/props-and-slots/_config.js new file mode 100644 index 0000000000..3f6fb4143c --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/props-and-slots/_config.js @@ -0,0 +1,8 @@ +import { test } from '../../test'; + +export default test({ + html: ` +

a

+

foo exists

+ ` +}); diff --git a/packages/svelte/tests/runtime-runes/samples/props-and-slots/main.svelte b/packages/svelte/tests/runtime-runes/samples/props-and-slots/main.svelte new file mode 100644 index 0000000000..3535da7132 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/props-and-slots/main.svelte @@ -0,0 +1,7 @@ + + + +
foo
+