feat: dynamic $$slots

pull/8304/head
tanhauhau 4 years ago
parent 571dd6e26d
commit 8edc682a3a

@ -220,7 +220,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, {
@ -721,7 +722,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] === '$') {

@ -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}

@ -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;
}
};

@ -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>

@ -0,0 +1,3 @@
<div>
<slot>default fallback</slot>
</div>

@ -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>
`);
}
};

@ -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>
Loading…
Cancel
Save