Skip to content

Commit 347774a

Browse files
committed
feat: dynamic $$slots
1 parent 279a2ed commit 347774a

File tree

7 files changed

+117
-2
lines changed

7 files changed

+117
-2
lines changed

src/compiler/compile/Component.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ export default class Component {
219219
this.add_var(node, {
220220
name,
221221
injected: true,
222-
referenced: true
222+
referenced: true,
223+
reassigned: name === '$$slots'
223224
});
224225
} else if (name[0] === '$') {
225226
this.add_var(node, {
@@ -720,7 +721,8 @@ export default class Component {
720721
} else if (is_reserved_keyword(name)) {
721722
this.add_var(node, {
722723
name,
723-
injected: true
724+
injected: true,
725+
reassigned: name === '$$slots'
724726
});
725727
} else if (name[0] === '$') {
726728
if (name === '$' || name[1] === '$') {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<script>
2+
$: data = toString($$slots);
3+
$: stringified = toString($$slots);
4+
5+
export function getData() {
6+
return data;
7+
}
8+
9+
function toString(data) {
10+
const result = {};
11+
const sortedKeys = Object.keys(data).sort();
12+
sortedKeys.forEach(key => result[key] = data[key]);
13+
return JSON.stringify(result);
14+
}
15+
</script>
16+
17+
<slot></slot>
18+
<slot name="a"></slot>
19+
20+
$$slots: {toString($$slots)} {stringified}
21+
22+
{#if $$slots.b}
23+
<div>
24+
<slot name="b"></slot>
25+
</div>
26+
{:else}
27+
Slot b is not available
28+
{/if}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
export default {
2+
html: `
3+
<span>bye</span><span>default</span>
4+
<span>hello a</span>
5+
$$slots: {"a":true,"default":true} {"a":true,"default":true}
6+
Slot b is not available
7+
`,
8+
9+
async test({ assert, component, target }) {
10+
assert.equal(component.getData(), '{"a":true,"default":true}');
11+
12+
component.show_b = true;
13+
assert.htmlEqual(target.innerHTML, `
14+
<span>bye</span><span>default</span>
15+
<span>hello a</span>
16+
$$slots: {"a":true,"b":true,"default":true} {"a":true,"b":true,"default":true}
17+
<div><span>hello b</span></div>
18+
`);
19+
assert.equal(component.getData(), '{"a":true,"b":true,"default":true}');
20+
21+
component.show_default = false;
22+
}
23+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<script>
2+
import A from "./A.svelte";
3+
let a;
4+
export let show_default = true;
5+
export let show_a = true;
6+
export let show_b = false;
7+
8+
export function getData() {
9+
return a.getData();
10+
}
11+
</script>
12+
13+
<A bind:this={a}>
14+
{#if show_a}
15+
<svelte:fragment slot="a">
16+
<span>hello a</span>
17+
</svelte:fragment>
18+
{/if}
19+
{#if show_default}
20+
<svelte:fragment slot="default">
21+
<span>bye</span>
22+
<span>default</span>
23+
</svelte:fragment>
24+
{/if}
25+
{#if show_b}
26+
<svelte:fragment slot="b">
27+
<span>hello b</span>
28+
</svelte:fragment>
29+
{/if}
30+
</A>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div>
2+
<slot>default fallback</slot>
3+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export default {
2+
html: `
3+
<div></div>
4+
<div>default fallback</div>
5+
`,
6+
test({ assert, component, target }) {
7+
component.condition = true;
8+
assert.htmlEqual(target.innerHTML, `
9+
<div>hello #1</div>
10+
<div>hello #2</div>
11+
`);
12+
}
13+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<script>
2+
import Foo from "./Foo.svelte";
3+
export let condition = false;
4+
</script>
5+
6+
<Foo>
7+
{#if condition}
8+
hello #1
9+
{/if}
10+
</Foo>
11+
12+
<Foo>
13+
{#if condition}
14+
<svelte:fragment slot="default">hello #2</svelte:fragment>
15+
{/if}
16+
</Foo>

0 commit comments

Comments
 (0)