leptos-rs / leptos

Build fast web applications with Rust.
https://leptos.dev
MIT License
15.3k stars 599 forks source link

Scoped CSS for Component #246

Closed ekanna closed 1 year ago

ekanna commented 1 year ago

Hi I am just creating this issue to keep track on scoped css for component. Ideally it should be like Svelete component style tag. For reference implementation in rust , we can look at https://saru-tora.github.io/anansi/

abishekatp commented 1 year ago

I would like to work on this issue.

gbj commented 1 year ago

I think this is great. It shouldn't need any tight integration at the framework level, but let's keep the issue open to track it, and please let me know if there is anything I can provide from the framework end to make it easier.

@abishekatp Thanks for offering to work on this! Do you want to take the lead? I'd recommend taking a look at stylist, which has examples geared toward Yew but should be possible easy to integrate with Leptos, or at least just useful to look at. But maybe you have other ieas.

abishekatp commented 1 year ago

Yeah I will look into both options and start working on it.

akesson commented 1 year ago

@abishekatp If you need any cargo-leptos integration or changes then feel free to contact me. I'm quite busy so I can only promise to reply to questions and help with PR reviews.

abishekatp commented 1 year ago

Yeah okay sure.

gbj commented 1 year ago

351 will add support for this by adding a class = ..., field to the view macro which will allow that class to every element, so that you can do

let class = style! { ... };
view! { cx, class = class,
  <div><p><span>"Text"</span></p></div>
}

This will add whatever class is returned by style! to the <div>, the <p>, and the <span>.

ekanna commented 1 year ago

Thank you @abishekatp and @gbj . Everyone can give you your feedback on this style macro. https://github.com/abishekatp/stylers

ekanna commented 1 year ago

Example component

#[component]
fn Hello(cx: Scope, name: &'static str) -> impl IntoView {

    let styler_class = style! {"Hello",
        div.one{
            color: red;
        }
        div #two{
            color: blue;
        }
        div {
            border: 1px solid black;
            margin: 25px 50px 75px 100px;
            background-color: lightblue;
        }
        h2 {
            color: purple;
        }
    }

    view! {cx, class = styler_class,
        <div class="one">
            <h1 id="two">"Hello"</h1>
            <h2>"World"</h2>
            <h2>{name}</h2>
            <h3>"Hello Kanna"</h3>
        </div>
    }
}
ekanna commented 1 year ago

I am closing this issue. Any issues relating to scoped css, one can raise at https://github.com/abishekatp/stylers

d4h0 commented 1 year ago

It shouldn't need any tight integration at the framework level, but let's keep the issue open to track it, and please let me know if there is anything I can provide from the framework end to make it easier.

@gbj: Is there a way (planned) for stylers (and similar crates) to integrate with the new amazing hot-reload feature of cargo leptos?

(For people who don't know about it: --hot-reload is a new option of cargo leptos watch that tries to update the web application without re-compiling it, resulting in changes being faster applied than you will take to switch to your browser, which results in amazing DX)

I'd love to use Scoped CSS, but losing hot-reload support isn't really an option for me (always having to wait for 3-10 seconds after changing the color of a button or similar is killing me... ;)).

abishekatp commented 1 year ago

Yeah If we can hot reload for css changes that will be awsome. I think it could be possible to do that for style! ad style_str! macros.

gbj commented 1 year ago

@gbj: Is there a way (planned) for stylers (and similar crates) to integrate with the new amazing hot-reload feature of cargo leptos?

What the hot-reloading does at the moment is 1) track all view macro invocations in your app, using syn to parse all the files searching for view invocations and syn-rsx to parse them 2) when you change a file, diffs its old view macros against new view macros, and extracts any changes to static HTML content (adding or removing nodes, changing static class names or attribute values) 3) sends those static changes directly to the browser

Note that this is doing more work (parsing all the Rust files twice, parsing view macros twice) but because it's skipping the Rust compilation step for some updates it feels much faster.

I can't remember exactly how stylers is working right now, but if I recall correctly it builds a CSS file during the proc macro phase of compilation?

It would certainly be possible to build a CLI tool to do live updates to the CSS similar to what I'm doing, which is to run a file watcher that uses syn to parse the style! and style_str! macros, and updates the CSS files directly, outside the Rust compilation loop. This would be a good place for cargo-leptos to have something like a plugin system, which it doesn't currently.