-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for slotted components #1037
Comments
Is there any progress on this one? What's the status? :) |
Agree with the proposal, it could be a usefull feature! |
This comment has been minimized.
This comment has been minimized.
Just closed #2080 in favor of this one, and a brief summary of the conversation there is:
@pngwn raised a concern about syntax 2, which is that it would be an entirely different way of specifying slots, which I hear, and which I'm not sure what to do about. |
If this is getting implemented, I think I'll love to see both implemented. I can see a lot of use cases where I would like to encapsulate the component with additional wrappers and in another scenarios I would like to just use the component. Now i work around this using empty div but then at times it breaks the structure because of the div element and I'll have to add more class utilities to make it work. This will be a great addition for Svelte. |
I think this is very important feature to implement. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I run into this on almost every project and end up doing this as a workaround: This allows me to style that extra div in the component that contains the slots but it would be super nice to have |
The second proposed syntax is very useful for clarity. In vue, I often end up using quite a lot to separate actual props from the rest. Just an opinion of course. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Hi, first time contributing to this project but I'm using Svelte (I love it!) for my own project and I bump up often against the limitation of not being able to pass arbitrary fragments to named slots without a wrapper element. So I've come to this thread a few times now. The two syntaxes that seem to be preferred are namespaced-component syntax ( The discussion around those syntaxes has been folded into this discussion about adding a To me the component syntax seems ideal.
Block syntax has a few drawbacks
Workaround using
|
The original syntax allows for multiple DOM nodes to be used while still keeping with standards: <Foo slot='bar'/>
<div slot='bar'>content</div>
<Bar slot='bar'/> |
As of yet this will not work inside blocks like |
What is the state of this issue? Is there a workaround yet? |
An alternative I've found is passing component references as props: <script>
import Container from './Container.svelte';
import Child from './Child.svelte';
<script>
<Container child={Child} childProps={{message: 'Hellow'}}/> And then on <script>
export let child, childProps;
<script>
<svelte:component this={child} {...childProps}/> It won't work in all use cases, but it's better than the div soup. |
This is (still) one area where the VDOM approaches are so much better. The extra div soup is two fold:
A lot of classical components will hit both problems at once (e.g: a Dropdown that needs to measure its content to position itself properly and where the content is to be defined on the call site) So we either have div soup (and lack of fun at reading it) or just make our components non configurable and copy paste all their code for each usage variation. The above workaround is not acceptable, especially when using TypeScript; two props for a single thing is awkward and there's no way to prove the passed props type match the component's props at this point. |
This is not an issue related to using a virtual DOM. Plenty of non VDOM libraries have solved this. Imba and Solid come to mind. |
Absolutely, but it comes easily and naturally with the VDOM approach whereas it's a special case that must be coded here. |
React didn't support rendering arrays without a wrapper for most of its existence
https://github.com/facebook/react/blob/master/CHANGELOG.md#1600-september-26-2017 Edit:
emphasis mine |
Sorry I'm new here, but is there a problem with just using another slot instead of a wrapper node workaround? |
Interesting 👀 . That feature ( I'm yet to find caveats to slotting components that way, other than it's inconvenient, as opposed to |
Just need a way to get at the slotted dom node from within a component now! |
What do you mean "get at the slotted dom node"? |
From a component's script that has a , provide an easy way to read the element that was slotted in without any unnecessary wrapper. |
I'm not sure I understand the point of what you're trying to do. Components inherently have no root node so there isn't just one "node slotted" that you could possibly reference. If for some reason you did need access to a top level dom node for your component you'd have to wrap the component yourself and then use something like Forgive me if I'm misunderstanding you here. |
Just access the slotted node, whether it's the default one or a named one. Right now, we can only know if a slot was provided (I think the API is a Record<slotName, boolean> but we can't access the DOM references. |
I don't think this is intended to work 😅 |
Grabbing the DOM references would be challenging. E.g. the following may or may not have elements and may have multiple nodes when it does depending on the contents of <Component>
{#if somevalue}
<div>my slotted info</div>
<AnotherComponent/>
{/if}
</Component> If We have <Component let:value give:node={myNode}>
{#if value}
<div bind:instance={myNode}>my slotted info</div>
<AnotherComponent/>
{/if}
</Component> You couldn't use It seems like a lot of added API in the framework would be needed to meet the desire to access slot contents. |
I also want to add to @jacwright 's comment to say that if you're trying to access DOM elements like this, it's hightly likely that you're using Svelte in a way which isn't a good fit for it, and your mental model of how a Svelte application works is incorrect. Svelte is a reactive UI language. It allows you to easily create things which react to state changes automatically. In Svelte, you manipulate a model of data, and Svelte handles the required DOM manipulation to reflect that state. If you edit the DOM, you are doing Svelte's job. If you want to modify a DOM element, you should do so by updating the state. You can do this for slotted content by declaring a context at the topmost level of your subtree, and changing elements within that context. Your slotted content can then read that content and react to changes which happen there. Often when an API appears "missing" from Svelte, it's actually instead absent, and often for a very good reason. |
While the previous comment was spot on, your point is a harder sell. Getting a DOM ref is pretty standard and svelte has an API for it (bind:this). I'm only saying it should ideally be available for slotted elements as well. |
It's there because it's possible at compile time since the presence of it is guaranteed. Since slotted content is not guaranteed, it would be a runtime concern. |
No, it's not any more guaranteed than a slot's content. https://svelte.dev/repl/07012a40613f49709479088be103681a?version=3.30.1 Let's not pretend it's missing for good practices reasons. Convoluted api? sure, maybe! |
I'm not really enjoying your tone. An |
You can do this already, kinda |
Nor do I like yours (you started insinuating that if I need this feature it's because I don't use svelte properly which is very ridiculous) but I will leave it at that; it's fine if you don't get it as far as I'm concerned. Please stop replying to me.
Ohh, didn't know I think the best we have right now is go from a div-soup to a well-named-elements-soup :D (https://github.com/sveltejs/svelte-virtual-list/blob/master/VirtualList.svelte#L165) |
@AlexGalays That's very clever @PatrickG. Nice one. I was a bit confused when first looking at it to understand what was going on, but I think that will be a handy tool in the toolbox. |
It would be nice if instead of only html elements, we could put components in named slots as well. Like this:
<MyComponent slot="title">Title here</MyComponent>
The text was updated successfully, but these errors were encountered: