Skip to content

Commit 0b67bd6

Browse files
committed
Partial fix for a component not properly retrieving let: bindings when it fills a named slot
1 parent d23805a commit 0b67bd6

File tree

7 files changed

+80
-0
lines changed

7 files changed

+80
-0
lines changed

.changeset/swift-feet-juggle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte": patch
3+
---
4+
5+
Fix let: bindings on components filling a named slot

packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,7 @@ function serialize_inline_component(node, component_name, context) {
776776
}
777777
}
778778

779+
let is_named_parent_slot = false;
779780
for (const attribute of node.attributes) {
780781
if (attribute.type === 'LetDirective') {
781782
default_lets.push(
@@ -811,6 +812,10 @@ function serialize_inline_component(node, component_name, context) {
811812
continue;
812813
}
813814

815+
if (attribute.name === 'slot') {
816+
is_named_parent_slot = true;
817+
}
818+
814819
const [, value] = serialize_attribute_value(attribute.value, context);
815820

816821
if (attribute.metadata.dynamic) {
@@ -863,6 +868,12 @@ function serialize_inline_component(node, component_name, context) {
863868
}
864869
}
865870

871+
if (is_named_parent_slot) {
872+
// This component is filling a named slot in its parent component, so get the relevant
873+
// attributes from the parent slot.
874+
context.state.init.push(...default_lets);
875+
}
876+
866877
if (Object.keys(events).length > 0) {
867878
const events_expression = b.object(
868879
Object.keys(events).map((name) =>

packages/svelte/src/compiler/phases/3-transform/server/transform-server.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,7 @@ function serialize_inline_component(node, component_name, context) {
826826
}
827827
}
828828

829+
let is_named_parent_slot = false;
829830
for (const attribute of node.attributes) {
830831
if (attribute.type === 'LetDirective') {
831832
default_lets.push(
@@ -840,6 +841,10 @@ function serialize_inline_component(node, component_name, context) {
840841
continue;
841842
}
842843

844+
if (attribute.name === 'slot') {
845+
is_named_parent_slot = true;
846+
}
847+
843848
const value = serialize_attribute_value(attribute.value, context, false, true);
844849
push_prop(b.prop('init', b.key(attribute.name), value));
845850
} else if (attribute.type === 'BindDirective') {
@@ -862,6 +867,12 @@ function serialize_inline_component(node, component_name, context) {
862867
}
863868
}
864869

870+
if (is_named_parent_slot) {
871+
// This component is filling a named slot in its parent component, so get the relevant
872+
// attributes from the parent slot.
873+
context.state.init.push(...default_lets);
874+
}
875+
865876
/** @type {import('estree').Statement[]} */
866877
const snippet_declarations = [];
867878

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script>
2+
export let things;
3+
</script>
4+
5+
<div>
6+
{#each things as thing}
7+
<slot name="foo" {thing}/>
8+
{/each}
9+
</div>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<script>
2+
export let thing;
3+
</script>
4+
<span>{thing}</span>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
get props() {
5+
return { things: [1, 2, 3] };
6+
},
7+
8+
html: `
9+
<div>
10+
<span>1</span>
11+
<span>2</span>
12+
<span>3</span>
13+
</div>`,
14+
15+
test({ assert, component, target }) {
16+
component.things = [1, 2, 3, 4];
17+
assert.htmlEqual(
18+
target.innerHTML,
19+
`
20+
<div>
21+
<span>1</span>
22+
<span>2</span>
23+
<span>3</span>
24+
<span>4</span>
25+
</div>
26+
`
27+
);
28+
}
29+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script>
2+
import Nested from './Nested.svelte';
3+
import SlotInner from './SlotInner.svelte';
4+
5+
export let things;
6+
</script>
7+
8+
<Nested {things}>
9+
<!-- <SlotInner slot="foo" let:thing {thing} /> -->
10+
<div slot="foo" let:thing>{thing}</div>
11+
</Nested>

0 commit comments

Comments
 (0)