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

Allow slots to be packaged in components #5979

Closed
subhog opened this issue Feb 10, 2021 · 7 comments
Closed

Allow slots to be packaged in components #5979

subhog opened this issue Feb 10, 2021 · 7 comments

Comments

@subhog
Copy link

subhog commented Feb 10, 2021

The problem

Is your feature request related to a problem? Please describe.

When creating a layout (i.e. in Sapper) it's often useful to define multiple areas of content injection. Svelte solves this issue with named slots, but the current implementation does not allow to multiple slots to be packaged in a single child component.

For instance, creating a named slot in Sapper _layout file and then using said slot in a Sapper page leads to the error:

Element with a slot='...' attribute must be a child of a component or a descendant of a custom element

Example

The minimal repl: https://svelte.dev/repl/f0d8d2d093094565bc36d62837d275da?version=3.32.2
To reproduce the issue, uncomment the top slot in Content.svelte.

Expected behavior: the contents of the "top" slot should be rendered in the slot.

Actual behavior: compilation error.

Solution

Describe the solution you'd like

Allow any component to use any named slot (could be in top level children only). Pass the content of such slots to the nearest ancestor component that defined appropriate slot.

Workarounds

Describe alternatives you've considered

The alternative I'm aware of is not to use _layout files in Sapper, but to define layout component in a separate file and reuse it in every page. This invalidates all the benefits of the layout system.

How important is this feature to you?

Not being able to define multiple regions in a _layout file limits its usability to simple applications. I'd really like to keep using layout files as my projects grow.

@Ennoriel
Copy link
Contributor

Hi!

It is really confusing to me using both layout and _layout in your REPL example and in the issue. I don't know if you mean a different thing or not.

From what I understand, if you want to use different layouts directly from your App component (or _Layout component), you'll need to have a map like object to determine which layout should be used with each route. It doesn't feel much better than using your workaround.

Also, if you have an undefined number of named slots used by some components but not all, it is probably going to be a pain to maintain and I am not sure it would be well optimized by the SRR.

@subhog
Copy link
Author

subhog commented Feb 11, 2021

Apologies. _layout is the special filename Sapper is using for layout components. In the REPL there is no Sapper, hence I just named the components by what they are (Layout and Content).

Sapper automatically applies _layout files to all the app pages placed in the same and descending folders as the _layout file. See the docs at https://sapper.svelte.dev/docs#Layouts, I don't think my explanation skills could match the official documentation 😄 The point is, using different layouts for different parts of the application works well in Sapper.

The problem is that within a single layout component, I would like to have multiple slots to render the content into. For example, my layout defines a menu area and a content area. The page component defines the content, but I'd also like it to put controls specific to this page in the slot in the menu area of the layout. Exactly as the REPL is attempting to.

I hope this clears the confusion a bit.

Also of note: I mention Sapper because it's the framework of choice for Svelte web apps, so I think the implications for the framework are wide an important for the context. However, I did check that the error is generated at the Svelte level, as illustrated by my REPL.

@paulovieira
Copy link

Sapper is going to be retired in a matter of months (hopefully). Maybe this problem anymore when SvelteKit arrives?

Anyway: I'm not sure if I understood fully the issue, but would it help to use named slots in a <MainComponent>? (instead of using slots in _layout.svelte directly). That is, use <MainComponent> in _layout.

@Ennoriel
Copy link
Contributor

Ennoriel commented Feb 13, 2021

In our app, we designed the pages using slots only for the main content, allowing us not to use named slots. If I understand well, in your application you use many and many different navs/menus that you'd like to use named slots? Otherwise, I would suggest to do as we did:

// UserTemplate.svelte
<MyUserNav />
<MyUserLeftMenu />
<slot />
// AdminTemplate.svelte
<MyAdminNav />
// no left menu (for example)
<slot />

And we do not have so many template components!

@dikaio
Copy link

dikaio commented Feb 17, 2021

@Ennoriel I like that approach.

@stale
Copy link

stale bot commented Jun 26, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale-bot label Jun 26, 2021
@stale stale bot removed the stale-bot label Jun 26, 2021
@stale stale bot removed the stale-bot label Jun 27, 2021
@dummdidumm
Copy link
Member

dummdidumm commented Jul 12, 2021

This is something that would need to be solved in Sapper/Kit, not Svelte core. Sapper is deprecated, and there exists an issue for that in SvelteKit. Therefore closing as duplicate of sveltejs/kit#627

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants