Pauan / rust-dominator

Zero-cost ultra-high-performance declarative DOM library using FRP signals for Rust!
MIT License
998 stars 63 forks source link

generate web components #35

Closed dakom closed 4 years ago

dakom commented 4 years ago

Sortof the inverse of https://github.com/Pauan/rust-dominator/issues/23

Would be great if dominator could be used to create web components. On one very rough foot, I think the only thing missing really is css encapsulation and rendering as shadow dom?

Haven't looked into it too much... just an idea :)

dakom commented 4 years ago

Is there a way to have encapsulated CSS without going full-blown web components?

Pauan commented 4 years ago

The real problem is the inability to create proper ES6 classes in wasm-bindgen, so that would need to be fixed first.

Is there a way to have encapsulated CSS without going full-blown web components?

True encapsulation can only be done with shadow DOM (which can be used with or without web components), or <iframe>s.

Dominator provides fake encapsulation with its class! macro (which creates a unique classname), which is very close to true encapsulation but not 100% perfect.

dakom commented 4 years ago

Interesting... so could shadowDOM be done, without registering web components - in order to get native CSS encapsulation (and not needing the macro) - or does this also require classes from wasm-bindgen?

Pauan commented 4 years ago

so could shadowDOM be done, without registering web components

Sure, no problem:

Dom::with_state(None, |state| {
    html!("div", {
        .before_inserted(|element| {
            let shadow = element.attach_shadow(&ShadowInitRoot::new(ShadowRootMode::Closed)).unwrap();

            *state = apply_methods!(DomBuilder::new(shadow), {
                .children(&mut [
                    // Put shadow DOM children in here...
                ])
            }).into_dom();
        })
    })
})

Naturally this could be made a lot easier with a new method.

Pauan commented 4 years ago

I just published version 0.5.10 which includes a new shadow_root macro, which can be used like this:

use dominator::{html, shadow_root, ShadowRootMode};

html!("div", {
    .shadow_root!(ShadowRootMode::Closed => {
        .children(&mut [
            // Put shadow DOM children in here...
        ])
    })
})
dakom commented 4 years ago

whoa, cool! From my perspective you can rename this issue to be about shadowDOM and close it :)

I may have other questions about class! and if that's a better fit for my use case...