From 83f00ebbd6e3400bf059690d132b31afa177c85a Mon Sep 17 00:00:00 2001
From: Simon H <5968653+dummdidumm@users.noreply.github.com>
Date: Thu, 30 Jan 2025 19:14:46 +0100
Subject: [PATCH] fix: don't error on slot prop inside block inside other
component (#15148)
`slot` is treated as a regular prop if it is not used directly inside another component, but we were running validations on such regular props that should only be run on real slots.
Fixes #15125
---
.changeset/good-rocks-talk.md | 5 +++
.../2-analyze/visitors/shared/attribute.js | 44 ++++++++++---------
.../slot-attribute-component/input.svelte | 6 +++
3 files changed, 34 insertions(+), 21 deletions(-)
create mode 100644 .changeset/good-rocks-talk.md
diff --git a/.changeset/good-rocks-talk.md b/.changeset/good-rocks-talk.md
new file mode 100644
index 0000000000..59af86c686
--- /dev/null
+++ b/.changeset/good-rocks-talk.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: don't error on slot prop inside block inside other component
diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/shared/attribute.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/shared/attribute.js
index 198e464ac7..19bd7b6e54 100644
--- a/packages/svelte/src/compiler/phases/2-analyze/visitors/shared/attribute.js
+++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/shared/attribute.js
@@ -80,40 +80,42 @@ export function validate_slot_attribute(context, attribute, is_component = false
}
if (owner) {
- if (!is_text_attribute(attribute)) {
- e.slot_attribute_invalid(attribute);
- }
-
if (
owner.type === 'Component' ||
owner.type === 'SvelteComponent' ||
owner.type === 'SvelteSelf'
) {
if (owner !== parent) {
- e.slot_attribute_invalid_placement(attribute);
- }
+ if (!is_component) {
+ e.slot_attribute_invalid_placement(attribute);
+ }
+ } else {
+ if (!is_text_attribute(attribute)) {
+ e.slot_attribute_invalid(attribute);
+ }
- const name = attribute.value[0].data;
+ const name = attribute.value[0].data;
- if (context.state.component_slots.has(name)) {
- e.slot_attribute_duplicate(attribute, name, owner.name);
- }
-
- context.state.component_slots.add(name);
+ if (context.state.component_slots.has(name)) {
+ e.slot_attribute_duplicate(attribute, name, owner.name);
+ }
- if (name === 'default') {
- for (const node of owner.fragment.nodes) {
- if (node.type === 'Text' && regex_only_whitespaces.test(node.data)) {
- continue;
- }
+ context.state.component_slots.add(name);
- if (node.type === 'RegularElement' || node.type === 'SvelteFragment') {
- if (node.attributes.some((a) => a.type === 'Attribute' && a.name === 'slot')) {
+ if (name === 'default') {
+ for (const node of owner.fragment.nodes) {
+ if (node.type === 'Text' && regex_only_whitespaces.test(node.data)) {
continue;
}
- }
- e.slot_default_duplicate(node);
+ if (node.type === 'RegularElement' || node.type === 'SvelteFragment') {
+ if (node.attributes.some((a) => a.type === 'Attribute' && a.name === 'slot')) {
+ continue;
+ }
+ }
+
+ e.slot_default_duplicate(node);
+ }
}
}
}
diff --git a/packages/svelte/tests/validator/samples/slot-attribute-component/input.svelte b/packages/svelte/tests/validator/samples/slot-attribute-component/input.svelte
index 5acb14e409..5d559e614e 100644
--- a/packages/svelte/tests/validator/samples/slot-attribute-component/input.svelte
+++ b/packages/svelte/tests/validator/samples/slot-attribute-component/input.svelte
@@ -1,2 +1,8 @@
valid
valid
+
+ {#if true}
+ valid
+ valid
+ {/if}
+
\ No newline at end of file