-
-
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
A way to see if slot prop is present #2106
Comments
Maybe one way is to make internal gubbins Nonenumerable instead of remove them? |
There are a workaround.
|
If we decide to expose this, it's something that should have a proper API rather than relying on Do other frameworks expose that information? Any ideas how, if so? |
Vue does this: https://vuejs.org/v2/api/#vm-slots
|
WebComponents give access via the SlotElement let slots = this.shadowRoot.querySelectorAll('slot');
console.log(slots[0].assignedNodes()) |
Since |
Maybe {#if $$slots.description}
<div class="description">
<slot name="description"></slot>
</div>
{/if} |
Another possible way would be to allow binding slots to variables with In reference to the example in the previous comment, it would look like this: {#if slottedElement}
<div class="description">
<slot bind:this="slottedElement" name="description"></slot>
</div>
{/if}
<script>
let slottedElement
</script> It would remove the need for a separate API and be reactive without further efforts (if reactivity is something that applies to slots in any way, not sure about that). Also not sure though if it would add too large of an inconsistency since slots cannot have directives otherwise. |
I believe this feature already exists ... example https://github.com/kaisermann/svelte-loadable <script>
const SLOTS = $$props.$$slots
</script>
{#if SLOTS.success}
<slot name="success" {component} />
{:else}
<svelte:component this={component} />
{/if} |
Hm I'd tend to think that the presence of |
I really like this variant: <slot bind:this={slotEl}></slot> @Rich-Harris What do you think? Is it possible? |
Any updates regarding this request? It would be very useful to be able to iterate over I would like to be able to do the following:
|
This can also be useful when trying to replicate an API similar to the one of the
myTextarea.svelte file content:
Here I think that maybe instead of using the prefixed
Svelte will look for imports of |
This, or being able to pass props to slot components, would be super useful for a pixi.js wrapper I've been trying to build. Each child component needs to know what canvas to render to. As far as I can tell, the only way to do this is to pass the canvas to each child component, it's a little inconvenient.
Ideally, the syntax will look something like this
With
And all
|
@ryanking1809 You could achieve the above (assuming I understand it correctly) using the context API. Something like in the Mapbox example should work fine for this case. |
@pngwn oh perfect! Thanks! |
Yes very interesting. I used to solve this with contenteditable shown below.
The Nav.svelte:
And in NavPick.svelte:
|
Now with
|
Slot element doesn't support This works: <script>
let fallbackElement;
</script>
<slot>
<div bind:this={fallbackElement}/>
</slot>
{#if !fallbackElement}
HAS SLOT
{/if} |
Hi, I wanted to add my 2 cents on this one. I think that One big use case for this one is for example "portals" which I've been trying to build for a while using some hacks... A "portal" is a pattern of passing the data inside the slots to another component, to be rendered elsewhere. This pattern of using portals is very common when building mobile apps because if you take a look at native mobile apps, the headers of the apps change based on context. Here is an illustration of how it works conceptually: <script>
import Portal from './Portal.svelte';
function submitForm() {
}
</script>
<form>
stuff here...
<form>
<Portal to="header">
<button on:click={submitForm}>Save<button>
</Portal> It is currently impossible to something like this in Svelte(without some very hacky stuff like rendering twice and passing HTML elements instead of render functions etc) while it's completely possible in any other UI framework without any hacks. There are two things that are necessary in order to achieve such a thing:
It is a shame that it's not possible because it's an important feature for the app im building, and after leaving Vue for Svelte, now I have to switch back to Vue and rebuild an entire app just because of this missing feature... Edit: I just found out that I already commented on this previously, it just goes to show how long I'm waiting for this feature. |
Would be great if a component could not only access its own slot content but also manipulate how it is displayed in the template. For example: Panel.svelte:
The
Notice there is no |
Another use case for programmatic access to slot content is to enable specification of slot content for slots within a nested component. For example, suppose we have a
Now suppose we want to create a
In Vue, the above allows the following:
Via access to This is an especially important feature when the nested component comes from an external library, as the only alternative is to manually re-create the slot from the nested component, including any fallback content (which you would then need to keep in sync with any updates to the external library). |
Would be awesome if we can have this. It isn’t always guaranteed to be a single root element, in that case it could return an array of elements? |
The magic global |
Unfortunately, const fillCols = (children, cols) => {
children.forEach((child, i) => cols[i % cols.length].push(child))
} In Svelte, this seems to be non-trivial. |
@janosh
The You can see mine at https://github.com/wickning1/svelte-components/blob/master/src/CardLayout.svelte Moving DOM elements around made me anxious and I wanted to preserve natural tab order without resorting to setting |
@janosh Hm, React-way is really hacky... When we talking about lists, masonry, or any other table-style components, first of all, we talk about arrays and iteration through them. If you iterate over the children in the Masonry component, somewhere (in parent component I guess) you also iterate over the actual items. Over and over again, in all places you use this component, you perform almost the same iteration twice. Why we should do this? I believe the interface of this kind of components should look like this: <Masonry {items} {colsNum} let:item>
<SomeItemComponent>{item}</SomeItemComponent>
</Masonry> So, we just don't need to iterate through children and do the same work twice in all places we need it. We just delegate repetitive work to the component which should be responsible for that work. In
<script>
export let items = [];
export let colsNum = 3;
$: cols = items.reduce(...);
</script>
{#each cols as col}
{#each col as item}
<slot {item} />
{/each}
{/each}
|
@PaulMaly Interesting approach. What's the best way in Svelte to get the height of all children in order to distribute them across the columns in a way that balances their height? |
It seems being able to bind:this={slotEl} directly on a slot element is a popular request. I'll add my +1 as adding div wrappers just to get dom references gets old really fast (and is not free, performance wise) |
I like this idea. Though there may be some issues with the new <!-- Component.svelte -->
<script>
let this
</script>
<slot bind:this />
<!-- App.svelte -->
<Component>
<svelte:fragment>
<p>Just some content.</p>
<p>Just some more content.</p>
</svelte:fragment>
</Component> Which DOM element should we bind |
This turned into two feature requests which both are implemented now:
|
@dummdidumm Should that first link be https://svelte.dev/docs#template-syntax-slot-$$slots now? Also, am I understanding this correctly: the only way to check if a slot has content, is if that slot is named? |
Yes that first link should be that now. The default slot is present as |
@dummdidumm I apologize if I am not understanding correctly, but i thought that this issue was for a way to cleanly access the contents of a slot when provided. I'm still not seeing a way to do that, other than something kludgy like a hidden element: Repl
|
@TristanBrotherton <Div>{noText}</Div> -- will have $$slots.default = true
<Div /> -- will have $$slots.default = false |
how do you see the slot content? Cant get it with: import { get_current_component } from 'svelte/internal'
let component = get_current_component();
console.log(component); |
Both links in the docs have changed no, so the updated version of @dummdidumm's comment above is:
|
v3.0.0-beta.5
Before #2083 it was possible to check if slot prop is present
An option to see if a slot prop is preset would be nice to have.
The text was updated successfully, but these errors were encountered: