Skip to content

Commit 8b9b2c2

Browse files
tanhauhauConduitry
authored andcommitted
fix allow let scoped to root element (#4266)
1 parent bfff7a9 commit 8b9b2c2

File tree

5 files changed

+63
-16
lines changed

5 files changed

+63
-16
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Svelte changelog
22

3+
## Unreleased
4+
5+
* Allow access to `let:` variables in sibling attributes on slot root ([#4173](https://github.com/sveltejs/svelte/issues/4173))
6+
37
## 3.17.1
48

59
* Only attach SSR mode markers to a component's `<head>` elements when compiling with `hydratable: true` ([#4258](https://github.com/sveltejs/svelte/issues/4258))

src/compiler/compile/nodes/Element.ts

+15-16
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ export default class Element extends Node {
151151
}
152152
}
153153

154+
const has_let = info.attributes.some(node => node.type === 'Let');
155+
if (has_let) {
156+
scope = scope.child();
157+
}
158+
154159
// Binding relies on Attribute, defer its evaluation
155160
const order = ['Binding']; // everything else is -1
156161
info.attributes.sort((a, b) => order.indexOf(a.type) - order.indexOf(b.type));
@@ -181,9 +186,16 @@ export default class Element extends Node {
181186
this.handlers.push(new EventHandler(component, this, scope, node));
182187
break;
183188

184-
case 'Let':
185-
this.lets.push(new Let(component, this, scope, node));
189+
case 'Let': {
190+
const l = new Let(component, this, scope, node);
191+
this.lets.push(l);
192+
const dependencies = new Set([l.name.name]);
193+
194+
l.names.forEach(name => {
195+
scope.add(name, dependencies, this);
196+
});
186197
break;
198+
}
187199

188200
case 'Transition':
189201
{
@@ -202,20 +214,7 @@ export default class Element extends Node {
202214
}
203215
});
204216

205-
if (this.lets.length > 0) {
206-
this.scope = scope.child();
207-
208-
this.lets.forEach(l => {
209-
const dependencies = new Set([l.name.name]);
210-
211-
l.names.forEach(name => {
212-
this.scope.add(name, dependencies, this);
213-
});
214-
});
215-
} else {
216-
this.scope = scope;
217-
}
218-
217+
this.scope = scope;
219218
this.children = map_children(component, this, this.scope, info.children);
220219

221220
this.validate();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
export let x;
3+
</script>
4+
5+
<slot name="foo" reflected={x}/>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
export default {
2+
html: `
3+
<span slot="foo" class="1">1</span>
4+
0
5+
`,
6+
async test({ assert, target, component, window }) {
7+
component.x = 2;
8+
9+
assert.htmlEqual(target.innerHTML, `
10+
<span slot="foo" class="2">2</span>
11+
0
12+
`);
13+
14+
const span = target.querySelector('span');
15+
await span.dispatchEvent(new window.MouseEvent('click'));
16+
17+
assert.htmlEqual(target.innerHTML, `
18+
<span slot="foo" class="2">2</span>
19+
2
20+
`);
21+
}
22+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script>
2+
import A from './A.svelte';
3+
export let x = 1;
4+
let y = 0;
5+
</script>
6+
7+
<A {x}>
8+
<span
9+
on:click={() => y = reflected}
10+
slot="foo"
11+
let:reflected
12+
class={reflected}
13+
>
14+
{reflected}
15+
</span>
16+
</A>
17+
{ y }

0 commit comments

Comments
 (0)