Is your feature request related to a problem? Please describe.
I am looking at Svelte and wondering if it would work for a project where we would have to build admin interface for a lot of data to display and manage while maintaining a large degree of reusability of visual elements. I don't see it working in Svelte3, so I am entering it here in hopes that it might drive some future decisions.
Describe the solution you'd like
I'd like to be able to create a library of UI elements that would have standard baseline behavior but provide extensibility to fit all practical cases. For example, a table could provide ability to reorder columns or switch them on and off or resize them. Such behavior could be encapsulated in a custom component. At the same time the page component containing the table should be able to generate content for slots as necessary to meed business goals. I made a "make believe" version of the code at https://svelte.dev/repl/a6e3c2e49b2e43dd87a50430071463f6?version=3.9.1.
Describe alternatives you've considered
I don't see any alternatives
How important is this feature to you?
I think it is essential for admin interfaces and dashboards.
Additional context
This is a paradigm we used on the server side in a classic MVC app we built before.
EDIT:
Oh... see I thought the comments were a general "there's no component libraries out there."
My prior remark about Svelte Material UI still stands, though.
See: https://sveltematerialui.com/#/demo/data-table
There's also talk on another issue about making something like $$slots available to grab slot contents in the same way that $$props lets you grab property data. Having that would open up more possibilities of creatively using slotted content.
I don't really know what this issue is actually asking for, could you clarify what you would like to achieve so we can have a better idea of how it might work?
My apologies for mumbling. It is probably a combination of $$slots and ability to pass context to the slot renderer. The first part is to be able to test if the parent defined a slot named by a certain pattern (like "name-heading" and "name-view") while iterating over a dynamic field list where "name" is one of the fields. The second part is to allow parent define slots that render content based on child's own context. For example, when a table component iterates over the rows, the slot will need to know the current row each time it is called. This may be not in line with how Svelte does things, please feel free to point me to a better way to implement these scenarios.
Actually, I just found how slots can pass values to parents through props. That makes sense. So, the only part I am missing is the dynamic slot naming like in the example below.
<!-- App.svelte -->
<script> let fields = ["name","breed"]; </script>
<FancyTable {fields} {items}>
<div slot="name-view" let:item={item}>{item.text}</div>
<div slot="breed-view" let:item={item}>{item.otherText}</div>
<p slot="footer">Copyright (c) 2019 Svelte Industries</p>
</FancyTable>
<!-- FancyTable.svelte -->
<ul>
{#each items as item}
{#each fields as field}
<li class="fancy">
<slot name="{field}-view" item={item}></slot>
</li>
{/each}
{/each}
</ul>
<slot name="footer"></slot>
I have that component in Vue and I can't create it in Svelte, because doesn't have dynamic slots
<template>
<section>
<ul class="tabs">
<li
class="tab-header"
v-for="(tab, idx) in tabs"
:key="`tab-${idx}`"
@click="tabSelected = idx"
>
<slot :name="`header-${idx}`">{tab}</slot>
</li>
</ul>
<div class="tab-content">
<div
v-for="(tab, idx) in tabs"
:key="`content-${idx}`"
class="tab-internal"
>
<slot v-if="idx === tabSelected" :name="`tab-${idx}`">
Implement tab-{{ idx }}
</slot>
</div>
</div>
</section>
</template>
<script>
export default {
props: {
tabs: Array
},
data: () => ({
tabSelected: 0
})
};
</script>
I think a great example of this is a simple Tabs component. For each tab I want to dynamically open a named slot.
<script>
export let tabs; // array of strings.
export let currentTab = tabs[0];
</script>
<div class="tabs">
<ul>
{#each tabs as tab}
<li class:is-active={tab === currentTab}>
<a on:click={() => (currentTab = tab)}>{tab}</a>
</li>
{/each}
</ul>
</div>
{#each tabs as tab}
<slot name={tab} /> <!-- DOESN'T WORK-->
{/each}
It's interesting that dynamically named slots still works if you target web components.
E.g.
{#each [1,2,3,4,5] as i}
<div class="slide">
<slot name={i}></slot>
</div>
{/each}
Svelte compiles that normally, and produces a working web component with 5 slots.
For me it would be just sufficient to suppress that error message.
Edit If you only target web-components, then there is a workaround:
{#each [1,2,3,4,5] as i}
<div class="slide">
{@html `<slot name="${i}"></slot>`}
</div>
{/each}
I think this is a question of usage rather than a limitation in Svelte.
For the scenario above, there is no reason to use slots. You can have an array of components, and then a loop, which has <svelte:component this={yourComponent} /> inside it.
Closing due to age, but also because I think this is a case of using the right tool for the job.
Most helpful comment
Actually, I just found how slots can pass values to parents through props. That makes sense. So, the only part I am missing is the dynamic slot naming like in the example below.