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

Svelte 5: Slot not render content for customElements #12892

Closed
GELight opened this issue Aug 17, 2024 · 11 comments · Fixed by #12929
Closed

Svelte 5: Slot not render content for customElements #12892

GELight opened this issue Aug 17, 2024 · 11 comments · Fixed by #12929
Milestone

Comments

@GELight
Copy link

GELight commented Aug 17, 2024

Describe the bug

First of all ... sorry for my bad english.

This is a Release Canditate ... therefore I hope my report is not to early for Svelte 5.

My background and goal:

I have build a lib(bundle) with many custom elements based on Svelte 3 and in some cases also based on Svelte 4. So I naturally watched the development of Svelte 5 with excitement. In order to make the best decision as to whether it makes sense to upgrade all my components to Svelte 4 and then migrate to Svelte 5, I decided to get to know all the features of Svelte 5 first. In this case I try to migrate a first little button component of my existing lib (components bundle).

The problem:

In my migration test I tried to migrate all exactly by the current svelte 5 docs:
https://svelte-5-preview.vercel.app/docs/old-vs-new
In my test there will no content (Text: Button Text in Slot) rendered which I have placed inside my button element:

<cow-ps-button exclude-validation>Button Text in Slot</cow-ps-button>

Reproduction

Github Test Repo

I have created a example repo where I can show my problem.
https://github.com/GELight/svelte-5-test


Using

Here I use my test customElement cow-ps-button in the index.html:
https://github.com/GELight/svelte-5-test/blob/main/projects/test/index.html

Example:

<cow-ps-button exclude-validation>Button Text in Slot</cow-ps-button>

Note in passing for the showed exclude-validation attribute: I hope that kebab-case attributes now possible in Svelte 5.x. And I hope my implementation here is also correct.


Svelte Component (customElement)

... and this is my svelte component implementation:
https://github.com/GELight/svelte-5-test/blob/main/projects/test/src/components/Button/Button.svelte


Result in DOM (Developer Tools):

This is the result in the DOM:

image

Unfortunately ... No errors occurred.

Logs

No errors occurred.
No logs printed.

System Info

System:
    OS: Linux 6.1 Debian GNU/Linux 12 (bookworm) 12 (bookworm)
    CPU: (32) x64 AMD Ryzen 9 7950X3D 16-Core Processor
    Memory: 6.35 GB / 30.48 GB
    Container: Yes
    Shell: 5.2.15 - /bin/bash
  Binaries:
    Node: 21.7.1 - /usr/bin/node
    npm: 10.5.0 - /usr/bin/npm
  Browsers:
    Brave Browser: 126.1.67.123
    Chrome: 126.0.6478.126
  npmPackages:
    svelte: 5.0.0-next.210 => 5.0.0-next.210

Severity

blocking an upgrade

@7nik
Copy link

7nik commented Aug 17, 2024

AFAIK, in the case of custom elements, you should keep <slot/> - its semantic was changed to represent whatever was passed inside the custom element / Shadow DOM.

@GELight
Copy link
Author

GELight commented Aug 18, 2024

Wow ... -.- ... Why is such information not on this page?
https://svelte-5-preview.vercel.app/docs/old-vs-new

And why 2 ways for the same thing?

In my case two ways are really NOT GOOD because I need to be able to use my components both independently and in combination with other CustomElements. I cannot use both techniques inside the same component. I thought the "slot" element is deprecated or removed generally in Svelte 5 ?

But ok ... what is the solution for my case?
How have I implement my component slots (default or named) when I have to use a component directly in a native root DOM as well as inside another CustomElement (component)?

For me, both paths are mutually exclusive!

@7nik
Copy link

7nik commented Aug 18, 2024

I see a few bugs: custom elements don't receive the inlined snippets, the compiler throws an error when a custom element uses both slots and snippets, slot isn't rendered if children was and even slot's fallback isn't rendred. Though, the last two can be an exptected behaviour.

You probably could use such an approach to render slot or snippet or fallback.
However, the custom element's content always seems to be passed into the slot unless an explicit snippet is used.

@GELight
Copy link
Author

GELight commented Aug 19, 2024

Hi 7nik,
Thank you for your feedback and answer. That's exactly what I meant. As you already wrote, the compiler throws an error if you use @render and slot together in a component. And that's exactly what I meant ... “@render” and ‘slot’ are mutually exclusive. And this is a very big problem for several reasons.

  1. i can't use template snippets in my CustomElement because i can only use them with @render ... because i'm forced to use SLOT to render my slot content.
  2. i can't reuse my CustomElement as usual in the native root DOM of a page AND ALSO in another CustomElement (without import).

I just want to use my CustomElements the way CustomElements are meant to be used. I just don't want to build them natively but with the help of Svelte.

Let me show you in an abstract picture what I have been able to develop for years in Svelte 2, Svelte 3 and also in Svelte 4 without any problems:

image


Or am I just not understanding the problem?
Maybe I really could need a sample code as I have described in my picture.

Ok ... so once again, what I've been building with Svelte for years. I have a bundle of CustomElements, which I developed in Svelte 3. This bundle is provided in a html page per the script-Tag. I do not import any of my CustomElements in my Svelte files of my CustomElements. I just use them the way you would use 3rd party custom elements.
In my example in the image, I have my own implemented dialog custom element. I use this element both in the body of any page and in other custom elements of my own. And within my components, I use other of my components (without importing them separately). As before, I would like to be able to fill the default slot or named slots with content. And within a template of a component, I would of course still like to use the convenience of the new snippets.


Important question for slots for me:
I thought I read it somewhere but are slots deprecated in the future of Svelte or not?

@GELight
Copy link
Author

GELight commented Aug 19, 2024

Ok ... I think I begin to understand your REPL examples.
I will test your examples in my own test project. 👍

@dummdidumm dummdidumm added this to the 5.0 milestone Aug 19, 2024
@dummdidumm
Copy link
Member

Giving this the 5.0 milestone because we gotta figure out how to deal with this (whether or not this is the desired behavior etc, or what we need to change, and what we need to document)

@7nik
Copy link

7nik commented Aug 19, 2024

@GELight, seems for <my-elem>some content</my-elem> without any snippets, <slot/> is the best choice. If you need snippets, for now, pass them explicitly

<my-elem snip={mySnip}>slot content</my-elem>
{#snippet mySnip())}
  snippet content
{/snippet}

and you can render them indirectly, as in my examples.

@GELight

This comment was marked as resolved.

@7nik

This comment was marked as resolved.

@dummdidumm
Copy link
Member

The examples given in #12892 (comment) are not errors, they are deliberate - custom elements are not components, and as such you can't pass content through inlined snippets, nor should you use them at all; you should use the slot synax instead.

What we need to do is to adjust the documentation slightly to point out that you should continue using slots inside custom element components, and remove the error of mixing snippets and slots within them.

dummdidumm added a commit that referenced this issue Aug 20, 2024
We need to allow mixing those within custom element components because in a future version of Svelte where we remove the Svelte-version of slots, we'll preserve slots as-is, and people should use those within their components. At the same time they should be able to make use of snippets for reusable blocks of code.

Also document that you should continue using slots within custom elements.

closes #12892
@7nik
Copy link

7nik commented Aug 20, 2024

you can't pass content through inlined snippets

Should then the compiler emit an error in this case?

Also, shouldn't there be an error or warning in case of using snippet+slot or multiple slots in a custom element?

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 a pull request may close this issue.

3 participants