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

Content inside of declarative shadow dom is not rendered #2802

Open
slalomzacharyd opened this issue Aug 9, 2024 · 5 comments
Open

Content inside of declarative shadow dom is not rendered #2802

slalomzacharyd opened this issue Aug 9, 2024 · 5 comments

Comments

@slalomzacharyd
Copy link

slalomzacharyd commented Aug 9, 2024

Describe the bug
I am attempting to use a shadow dom tag in leptos and nothing is rendered for the content. This same html works in a normal html file.

Leptos Dependencies

[package]
name = "leptos-tutorial"
version = "0.1.0"
edition = "2021"

[dependencies]
leptos = { version = "0.6.13", features = ["csr", "nightly"] }

To Reproduce
Steps to reproduce the behavior:

  1. Use shadow dom in leptos
use leptos::*;


fn main() {
    mount_to_body(|| {
        view! {
            <p>
                <my-component>
                    <template shadowrootmode="open">
                        <style>"* { color: blue; }"</style>
                        <p>"Hello, world!"</p>
                    </template>
                </my-component>
            </p>
        }
    });
}
  1. Open it in the browser
  2. Notice nothing is rendered
Screenshot 2024-08-09 at 16 07 55

Expected behavior
Shadow dom in declarative shadow dom should render. It is valid html.

For reference, for the given html,

<html>
  <body>
   <p>
     <my-component>
        <template shadowrootmode="open">
           <style>* { color: blue; }</style>
           <p>Hello, world!</p>
        </template>
     </my-component>
   </p>
  </body>
</html>

It should render this:

Screenshot 2024-08-09 at 16 11 09
@slalomzacharyd
Copy link
Author

slalomzacharyd commented Aug 9, 2024

Additional note: The above styling code works when not inside of declarative shadow dom, so it does seem to be specific to the tag.

use leptos::*;


fn main() {
    mount_to_body(|| {
        view! {
            <p>
                    <style>"* { color: blue; }"</style>
                    <p>"Hello, world!"</p>
            </p>
        }
    });
}

@gbj
Copy link
Collaborator

gbj commented Aug 9, 2024

I don't think declarative shadow DOM works in client-side rendering, does it? i.e., if I do this

let tpl = document.createElement("template"); 
tpl.setAttribute("shadowrootmode", "open"); 

then tpl.shadowRoot is undefined. Declarative shadow DOM only works while parsing an HTML text:

let working = document.createElement("p");
working.setHTMLUnsafe(`<my-component>
        <template shadowrootmode="open">
           <style>* { color: blue; }</style>
           <p>Hello, world!</p>
        </template>
     </my-component>`);

This framework works primarily by building up a tree of DOM nodes using ordinary DOM operations (as in the first example), not by parsing from HTML (as in the second example). I would not expect this example to work in this or any other front-end framework that doesn't build in specific support for declarative shadow DOM by special-casing <template>.

(Note also that the "working" version has limited browser support.)

Leptos Dependencies

No extra dependencies.

This section is intended for you to show which version of Leptos you are using, i.e., what your Leptos dependency is.

@slalomzacharyd
Copy link
Author

Sorry for the delay, we had a holiday in Japan yesterday. For the context of my feature request description, it's black boxing the implementation from the point of view of a user. Please don't take it as a request for a specific implementation.

From the SSR Side:
Declarative shadow dom is really for the SSR. If leptos can convert the internal dom tree to html tags it should just work.

From the CSR Side:
For the client rendering it would have to recognize it is shadow dom and traverse inside it to the children. It's usually not too complicated to implement, but it does require a different logic branch. (I've implemented it for React because the npm libraries that implement it usually are usually garbage.)

I can possibly assist in implementing this if there is interest. Obviously it would add some complexity which needs to be weighed for its value.

Thank you for the information on the dependencies section, I'll add the toml file.

@gbj
Copy link
Collaborator

gbj commented Aug 14, 2024

Sounds good. This is a once-in-two-years request, so I'll leave it open as a feature request and feel free to make a PR.

@slalomzacharyd
Copy link
Author

Thank you! It may take me a month or so as I have to get used to the code base and I am ramping up on rust coming from a typescript/C background.

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