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 slot content in custom elements when shadow root is disabled/false #8963

Open
patricknelson opened this issue Jul 13, 2023 · 0 comments

Comments

@patricknelson
Copy link

Describe the problem

Since slots are already supported when compiling to custom elements (via shadow DOM) and Svelte can now natively utilize the light DOM (thanks to #8457), one might naturally also want slot support when in the light DOM. This is not currently possible, but would be awesome if Svelte had a way of natively supporting slot content when not using a shadow root.

For example, given ExampleElement.svelte:

<svelte:options
	customElement={{
		tag: 'example-element',
		shadow: 'none',
	}}
/>

<h1>My Heading</h1>
<slot/>

And index.html containing:

<example-element>
	<p>Hello world!</p>
</example-element>

The final rendered version in the light DOM might look something like this:

<example-element>
	<h1>My Heading</h1>
	<p>Hello world!</p>
</example-element>

Note: This is a reopening/variant of #8686 where this was originally reported as a bug.

Describe the proposed solution

Taking inspiration from experimentation already done in svelte-retag, I'd propose two approaches, each of which are necessary depending on how the compiled component is shipped (e.g. esm or umd/iife)

  1. Module + UMD/IIFE: Parse out elements with named slot="..." attributes and populate into Svelte component slots. Use remaining content as "default" content for the default slot.
  2. UMD/IFFE only: Do the above, but also watch for changes using MutationObserver since the custom HTMLElement will connect early while the parser appends new nodes (i.e. slot content) as it moves across the DOM. Practically, this can be accomplished by temporarily (or permanently) isolating rendered component HTML to prevent recursion. svelte-retag accomplishes this by tucking that HTML into a no-op custom element called <svelte-retag> where we can be certain that rendered HTML lives in a separate hierarchy that will not be confused with newly appended child nodes as the parser progresses.

One might also want to ensure they account for changes to slot content beyond document.readyState === 'complete' (svelte-retag doesn't yet do this so I haven't tried it yet). But this is just one possible approach.

Alternatives considered

This concept is already readily demonstrated here in Svelte using light DOM custom elements via svelte-retag.

Importance

would make my life easier

patricknelson referenced this issue in typhonjs-typedoc/typedoc-theme-dmt Jul 13, 2023
@patricknelson patricknelson changed the title Allow slot content in custom elements when shadow root is disabled Allow slot content in custom elements when shadow root is disabled/false Oct 9, 2023
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

2 participants