futursolo / stylist-rs

A CSS-in-Rust styling solution for WebAssembly Applications
https://crates.io/crates/stylist
MIT License
373 stars 22 forks source link

Global requires 'static & doesn't support Classes #78

Closed simbleau closed 2 years ago

simbleau commented 2 years ago

https://github.com/futursolo/stylist-rs/blob/d47e21f24eb3ce14ae71c02a4d5b0fb2edc76862/packages/stylist/src/yew/global.rs#L52

Is it really necessary this is static? Or can we allow <Global css={}> to take Classes as input?

My main concern is trying to apply a theme with a little more modularity than the example.

My use case:

fn global_css() -> StyleSource<'static> {
    css!(
        r#"
            :root {
                --fs: 1rem;
                --fw: 400;
                --fh: 700
            }
        "#,
    )
}

#[function_component(App)]
fn app() -> Html {
    let theme = use_theme();
    let theme_css: StyleSource<'static> = css!(
        r#"
        :root {
            background-color: ${bg};
            color: ${fg};
        }
        "#,
        bg = theme.bg1.to_css(),
        fg = theme.fg1.to_css(),
    );
    let root_classes = classes!(global_css(), theme_css);

    html! {
        <>
        <Global css={ root_classes } />
        ...
        </>
    }
}
simbleau commented 2 years ago

Also I'll note in my example, I would have preferred to use global_style!() and use & instead of :root, but I couldn't get it to work.

simbleau commented 2 years ago

Ok, I feel a little silly. Apparently this works:

<Global css={ global::get_style() } />
<Global css={ theme_css } />

Whichs begs, wouldn't this make sense to be permissible?

<Global css={ classes!(global::get_style(), theme_css) } />
WorldSEnder commented 2 years ago

Is it really necessary this is static? Or can we allow to take Classes as input?

No, and this lifetime parameter has been removed on master already

Ok, I feel a little silly. Apparently this works:

<Global css={ global::get_style() } />
<Global css={ theme_css } />

Whichs begs, wouldn't this make sense to be permissible?

<Global css={ classes!(global::get_style(), theme_css) } />

classes! != StyleSource. Think of StyleSource like a potential class that doesn't have a classname yet. The missing utility is one that combines multiple style sources into one, much like classes! converts multiple yew::Classes together.

The conversion that often takes place, converting a StyleSource into Classes is the magic sauce that checks for such a stylesheet to exist, otherwise generates a new classname and mounts a <style> element in the document. The combinator for StyleSource could either merge multiple sheets (such that only one classname is ultimately generated) or keep them in a list (such that potentially multiple class names are generated, but deduplication could be a bit better).

<Global css={ global::get_style() } />
<Global css={ theme_css } />

You already found the easy workaround in this case ;)

simbleau commented 2 years ago

Awesome. Perhaps justification for a sources! macro in the future.