Skip to content
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

Slot Attributes #15

Closed
wants to merge 2 commits into from
Closed

Slot Attributes #15

wants to merge 2 commits into from

Conversation

lukeed
Copy link
Member

@lukeed lukeed commented Jan 1, 2020

@RedHatter
Copy link

Would sveltejs/svelte#2106 solve this? Something like

<div class="card">
  {#if $$slots.header}
    <div class="card-header">
      <slot name="header"/>
    </div>
  {/if}

  {#if $$slots.default}
    <div class="card-body">
      <slot />
    </div>
  {/if}

  {#if $$slots.footer}
    <div class="card-footer">
      <slot name="footer"/>
    </div>
  {/if}
</div>

@lukeed
Copy link
Member Author

lukeed commented Jan 3, 2020

Being able to detect slot existence would, yes, but IIRC there was hesitation around this – I think due to implementation hurdles? Can't really remember the details

@Conduitry
Copy link
Member

I don't think there are implementation hurdles - this is already sort of available as $$props.$$slots but there's no official public API for it currently. This is also discussed in sveltejs/svelte#2106

@lukeed
Copy link
Member Author

lukeed commented Jan 4, 2020

Thanks, missed the part where $$props.$$slots is already available.

So then here's what I have so far: https://svelte.dev/repl/69ca92e3995540a4a0a1865e6fc6b957?version=3.16.7

Then this RFC basically serves as a consolidation for the above while also adding ability to add additional props/attributes to each slot (sveltejs/svelte#2106 (comment))


In the process, we'd hopefully be able to remove the whitespace-only trigger for <slot (default) /> (shown in REPL) but that may be a separate task.

@Zizico2
Copy link

Zizico2 commented Sep 1, 2021

Sorry if I misread the RFC but there is stuff I'm sceptical about.

What happens when a slot doesn't have a unique child?

Will all top level children get assigned the attributes? Could we wrap the contents of the slot in a <div style="display: contents"></div> and apply the attributes to that?

I wrote an RFC (Declarative Actions) where I mentioned adding a <target /> component that behaves like your <slot /> extension, except it would only allow one child (as it was meant for actions, which can only be applied to one element at a time).

What happens when the attributes specified in the <slot /> aren't compatible with the elements inside it? Should Svelte not compile (seems too harsh xd)? Should there just be a warning? Should Svelte just clean up the invalid HTML for you and not tell you about it? What if the child is a Svelte Component and not an HTML Element? Svelte Components aren't compatible with most HTML attributes, would it apply the attributes to the component's top element?

One solution could be to (I'm gonna use <target /> insted of <slot /> as I feel it is different enough to warrant a new Element) have extra attributes on <target /> to allow you to specify allowed children.

Something like:

<!-- Card.svelte -->
<div class="card">
	<target allow="div" />
</div>

Would only allow a single div as a child. If you used this component and gave it a button it would not compile.

And something like:

<!-- Card.svelte -->
<div class="card">
	<target allow="div"  type="text"/>
</div>

Wouldn't compile right off the bat since a div shouldn't be assigned the attribute type.

You could even do:

<!-- Card.svelte -->
<div class="card">
	<target allow="div, button, form" />
</div>

This would allow one of those Elements as the root element and Svelte would be smart enough to allow the interception of their attributes list.

If you want to allow all don't include the allow attribute. If you want to allow all except some there could be a deny attribute.

As in:

<!-- Card.svelte -->
<div class="card">
	<target deny="svg" />
</div>

And, again, Svelte would be smart enough too allow you to use the right attributes.

You could even allow/deny specific Svelte Components (which could be useful for design systems) or only allow or only deny all Svelte Components:

Ex 1:

<!-- Card.svelte -->
<div class="card">
	<target deny="SvelteComponent" />
</div>

This would deny any Svelte Component and would mean roughly the same as:

<!-- Card.svelte -->
<div class="card">
	<target allow="HTMLElement" />
</div>

Ex 2:

<!-- Card.svelte -->
<div class="card">
	<target allow="SomeRandomCustomSvelteComponent, SomeOtherRandomCustomSvelteCompoonent" />
</div>

This would only allow those 2 Svelte Components as children and, once more, Svelte could be able (this doesn't seem as black and white as HTMLElements since 2 Components having props with the same name doesn't mean they have the same semantics) to allow the props in common.

I can see this being written off as too convoluted but I think it's a decent way to go about the problem.

Other questions:

How would directives, specifically style directives work?

How would style properties work?

How would actions work?

How would Svelte scope styles since the slot's content would need access the class selectors in its parent, or any selector for that matter?

@iacore
Copy link

iacore commented Jan 5, 2022

Slot variables is now available in Svelte, which is more general a solution than this proposal.
Demo: https://svelte.dev/repl/7853ade2c8fa43dcbe4cb128cf272a79?version=3.44.3

@lukaszpolowczyk
Copy link

@lukeed It looks like your RFC has something in common with mine - #68

Please check my RFC, and tell me if it covers 100% of your RFC?

@dummdidumm
Copy link
Member

Snippets will replace slots (they are still around but deprecated) in Svelte 5 and have the capabilities that are wanted. The $$slots.x feature that was introduced a while ago also solves many of the presented cases. Therefore closing this RFC - thank you.

@dummdidumm dummdidumm closed this Nov 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants