Skip to content

Commit

Permalink
feat: dynamic $$slots
Browse files Browse the repository at this point in the history
  • Loading branch information
tanhauhau committed Feb 23, 2023
1 parent 279a2ed commit 347774a
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/compiler/compile/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@ export default class Component {
this.add_var(node, {
name,
injected: true,
referenced: true
referenced: true,
reassigned: name === '$$slots'
});
} else if (name[0] === '$') {
this.add_var(node, {
Expand Down Expand Up @@ -720,7 +721,8 @@ export default class Component {
} else if (is_reserved_keyword(name)) {
this.add_var(node, {
name,
injected: true
injected: true,
reassigned: name === '$$slots'
});
} else if (name[0] === '$') {
if (name === '$' || name[1] === '$') {
Expand Down
28 changes: 28 additions & 0 deletions test/runtime/samples/$$slot-dynamic/A.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<script>
$: data = toString($$slots);
$: stringified = toString($$slots);
export function getData() {
return data;
}
function toString(data) {
const result = {};
const sortedKeys = Object.keys(data).sort();
sortedKeys.forEach(key => result[key] = data[key]);
return JSON.stringify(result);
}
</script>

<slot></slot>
<slot name="a"></slot>

$$slots: {toString($$slots)} {stringified}

{#if $$slots.b}
<div>
<slot name="b"></slot>
</div>
{:else}
Slot b is not available
{/if}
23 changes: 23 additions & 0 deletions test/runtime/samples/$$slot-dynamic/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export default {
html: `
<span>bye</span><span>default</span>
<span>hello a</span>
$$slots: {"a":true,"default":true} {"a":true,"default":true}
Slot b is not available
`,

async test({ assert, component, target }) {
assert.equal(component.getData(), '{"a":true,"default":true}');

component.show_b = true;
assert.htmlEqual(target.innerHTML, `
<span>bye</span><span>default</span>
<span>hello a</span>
$$slots: {"a":true,"b":true,"default":true} {"a":true,"b":true,"default":true}
<div><span>hello b</span></div>
`);
assert.equal(component.getData(), '{"a":true,"b":true,"default":true}');

component.show_default = false;
}
};
30 changes: 30 additions & 0 deletions test/runtime/samples/$$slot-dynamic/main.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script>
import A from "./A.svelte";
let a;
export let show_default = true;
export let show_a = true;
export let show_b = false;
export function getData() {
return a.getData();
}
</script>

<A bind:this={a}>
{#if show_a}
<svelte:fragment slot="a">
<span>hello a</span>
</svelte:fragment>
{/if}
{#if show_default}
<svelte:fragment slot="default">
<span>bye</span>
<span>default</span>
</svelte:fragment>
{/if}
{#if show_b}
<svelte:fragment slot="b">
<span>hello b</span>
</svelte:fragment>
{/if}
</A>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div>
<slot>default fallback</slot>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export default {
html: `
<div></div>
<div>default fallback</div>
`,
test({ assert, component, target }) {
component.condition = true;
assert.htmlEqual(target.innerHTML, `
<div>hello #1</div>
<div>hello #2</div>
`);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script>
import Foo from "./Foo.svelte";
export let condition = false;
</script>

<Foo>
{#if condition}
hello #1
{/if}
</Foo>

<Foo>
{#if condition}
<svelte:fragment slot="default">hello #2</svelte:fragment>
{/if}
</Foo>

0 comments on commit 347774a

Please sign in to comment.