From dc6d3f118a3309d6a3409b4ea857f0495737106d Mon Sep 17 00:00:00 2001 From: Yiffy Dev Date: Wed, 30 Oct 2024 19:41:37 +0500 Subject: [PATCH 1/6] fix awfull typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7d90fc0..775a6dc 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ Also, just about everything is pub-available in this crate - Sabry is ready for Feel free to check out examples: -|[crate of styles](./examples//define-styles/)|[style usage](./examples/use-styles/)|[leptox-axum with sabry](./examples/leptos-axum)| +|[crate of styles](./examples//define-styles/)|[style usage](./examples/use-styles/)|[leptos-axum with sabry](./examples/leptos-axum)| |-|-|-| ### Create a crate full of arbitrary SASS From e4c27f7caed11e3582018200bf5943a8c556581d Mon Sep 17 00:00:00 2001 From: Yiffy Dev Date: Thu, 31 Oct 2024 06:06:00 +0500 Subject: [PATCH 2/6] wow, nice badges --- LICENSE | 21 +++++++++++++++++++++ README.md | 24 ++++++++++++++---------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/LICENSE b/LICENSE index e69de29..c63862d 100644 --- a/LICENSE +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Svyatoslav Pushkarev + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 775a6dc..ea37bb7 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ > > the latest-trashy state is in the "window" branch +[![Crates.io](https://img.shields.io/crates/v/sabry.svg)](https://crates.io/crates/sabry) +[![Docs.rs](https://img.shields.io/docsrs/sabry/latest.svg)](https://docs.rs/sabry) +[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/yiffyrusdev/sabry/blob/master/LICENSE) + At first, I'll show how this crate "tastes". With SABRY, its in your power to: @@ -65,7 +69,7 @@ tgk_brandstyle = {version = "0.0.1", features = ["utils"]} `@use` your style-crates in sass code *naturally* ```rust,ignore -styly!(breadcumb { +styly!(breadbadge { @use 'tokens'; .scope {@include tokens.badge(primary);} }) @@ -176,11 +180,11 @@ sabry = {version = "0.0.1"} ``` And create a style scope wherever you want: ```rust,ignore -// breadcumblist.rs +// breadbadgelist.rs use sabry::styly; styly!(const styles { - .cumbs { + .badges { display: flex; &__list { display: flex; @@ -192,8 +196,8 @@ styly!(const styles { }); fn render() -> HtmlElement { - div().class(styles::cumbs).chain( - ul().class(styles::_list(styles::cumbs)) + div().class(styles::badges).chain( + ul().class(styles::_list(styles::badges)) ).chain( span().id(styles::thewolf) ) @@ -201,7 +205,7 @@ fn render() -> HtmlElement { ``` > That `const` usage is covered in the [following](#constant-styly-scopes) section. In this example we dont invoke sabry build-magic, so, to be as close to real life as possible, I used a const. -Every selector, if that does make sense, now available for you as a member of `styles` scope. In this example - `styles::cumbs`, `styles::thewolf` and `styles::_list()`. More about scoping and member names you can read [here](#styly-scopes). +Every selector, if that does make sense, now available for you as a member of `styles` scope. In this example - `styles::badges`, `styles::thewolf` and `styles::_list()`. More about scoping and member names you can read [here](#styly-scopes). ### Use styles earlier created in another crate @@ -238,12 +242,12 @@ fn main(){ Now lets get back to the code and use the mixin defined in another crate: ```rust,ignore -// breadcumblist.rs +// breadbadgelist.rs use sabry::styly; styly!(styles { @use "mixins"; - .cumbs { + .badges { display: flex; &__list { display: flex; @@ -255,8 +259,8 @@ styly!(styles { }); fn render() -> HtmlElement { - div().class(styles::cumbs).chain( - ul().class(styles::_list(styles::cumbs)) + div().class(styles::badges).chain( + ul().class(styles::_list(styles::badges)) ).chain( span().id(styles::thewolf) ) From f1c6d39893a19033188c586f45557358a26e08cc Mon Sep 17 00:00:00 2001 From: Yiffy Dev Date: Thu, 31 Oct 2024 08:07:24 +0500 Subject: [PATCH 3/6] more comprehensive error messages on file load --- sabry_procmacro_impl/src/impls/mod.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/sabry_procmacro_impl/src/impls/mod.rs b/sabry_procmacro_impl/src/impls/mod.rs index c2420e2..a6876d8 100644 --- a/sabry_procmacro_impl/src/impls/mod.rs +++ b/sabry_procmacro_impl/src/impls/mod.rs @@ -1,4 +1,4 @@ -use std::{fmt::Debug, fs}; +use std::{fmt::Debug, fs, path::PathBuf, str::FromStr}; use proc_macro2::{Span, TokenStream}; use quote::{quote, ToTokens, TokenStreamExt}; @@ -36,9 +36,28 @@ impl Parse for ArbitraryStyleBlock { let (code, span) = if let Ok(path_tok) = input.parse::() { let path = path_tok.value(); - let iofile = match fs::read(&path) { + let path = match PathBuf::from_str(&path) { + Ok(p) => p, + Err(_) => { + return Err(syn::Error::new( + path_tok.span(), + format!("Could not read {} as a path: Infallible", path), + )) + } + }; + let fullpath = match path.canonicalize() { + Ok(cp) => cp, + Err(e) => { + return Err(syn::Error::new( + path_tok.span(), + format!("Could not use path {path:?}: {:?}", e.kind()), + )) + } + }; + + let iofile = match fs::read(&fullpath) { Ok(bf) => bf, - Err(_) => return Err(syn::Error::new(path_tok.span(), format!("Could not read file '{path}'. Perhaps its relative? Thats not currently supported :("))) + Err(_) => return Err(syn::Error::new(path_tok.span(), format!("Could not read file at {fullpath:?}"))) }; let code = String::from_utf8_lossy(&iofile).to_string(); From c188c47f3955894cf08d0378b54f5966a6bf8bf1 Mon Sep 17 00:00:00 2001 From: Yiffy Dev Date: Thu, 31 Oct 2024 08:07:43 +0500 Subject: [PATCH 4/6] example with files --- examples/define-styles/Cargo.lock | 50 +++------------------------ examples/define-styles/src/lib.rs | 2 ++ examples/define-styles/src/style.scss | 5 +++ 3 files changed, 12 insertions(+), 45 deletions(-) create mode 100644 examples/define-styles/src/style.scss diff --git a/examples/define-styles/Cargo.lock b/examples/define-styles/Cargo.lock index 963559d..ce5f0bc 100644 --- a/examples/define-styles/Cargo.lock +++ b/examples/define-styles/Cargo.lock @@ -994,28 +994,15 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "sabry" -version = "0.0.1" +version = "0.0.1-alpha.1" dependencies = [ - "sabry_build", "sabry_intrnl", "sabry_procmacro", ] -[[package]] -name = "sabry_build" -version = "0.0.0" -dependencies = [ - "proc-macro2", - "sabry_intrnl", - "sabry_procmacro_impl", - "syn 2.0.85", - "thiserror", - "walkdir", -] - [[package]] name = "sabry_intrnl" -version = "0.0.0" +version = "0.0.1-alpha.1" dependencies = [ "base64", "blake3", @@ -1023,6 +1010,7 @@ dependencies = [ "grass", "lightningcss", "proc-macro2", + "quote", "raffia", "regex", "serde", @@ -1033,14 +1021,14 @@ dependencies = [ [[package]] name = "sabry_procmacro" -version = "0.0.0" +version = "0.0.1-alpha.1" dependencies = [ "sabry_procmacro_impl", ] [[package]] name = "sabry_procmacro_impl" -version = "0.0.0" +version = "0.0.1-alpha.1" dependencies = [ "proc-macro2", "quote", @@ -1050,15 +1038,6 @@ dependencies = [ "syn 2.0.85", ] -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - [[package]] name = "scopeguard" version = "1.2.0" @@ -1290,16 +1269,6 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65dd7eed29412da847b0f78bcec0ac98588165988a8cfe41d4ea1d429f8ccfff" -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1361,15 +1330,6 @@ version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys", -] - [[package]] name = "windows-sys" version = "0.59.0" diff --git a/examples/define-styles/src/lib.rs b/examples/define-styles/src/lib.rs index bdf62c3..d53f80c 100644 --- a/examples/define-styles/src/lib.rs +++ b/examples/define-styles/src/lib.rs @@ -1,5 +1,7 @@ use sabry::sassy; +sassy!(style "src/style.scss"); + sassy!(utils { @mixin flex($direction, $align, $justify, $gap: .5rem) { display: flex; diff --git a/examples/define-styles/src/style.scss b/examples/define-styles/src/style.scss new file mode 100644 index 0000000..d60a314 --- /dev/null +++ b/examples/define-styles/src/style.scss @@ -0,0 +1,5 @@ +@use "theme" as *; + +.codeblock { + background: $thm-surface-primary; +} From 5e1f16a4d71c31c8229f28856f09a55007c3de77 Mon Sep 17 00:00:00 2001 From: Yiffy Dev Date: Thu, 31 Oct 2024 08:55:00 +0500 Subject: [PATCH 5/6] introduce lepty-scoping, which is more effective and more nice - especially with leptos --- .github/workflows/cbt.yml | 3 +- Cargo.lock | 1 + Cargo.toml | 3 + README.md | 69 +++++++++++++++++++++ examples/leptos-axum/Cargo.toml | 9 +-- examples/leptos-axum/src/routes/home.rs | 26 +++----- examples/leptos-axum/src/routes/home.scss | 11 ++++ sabry_intrnl/Cargo.toml | 2 + sabry_intrnl/src/scoper/mod.rs | 73 +++++++++++++++++++---- 9 files changed, 162 insertions(+), 35 deletions(-) diff --git a/.github/workflows/cbt.yml b/.github/workflows/cbt.yml index aed0fdd..b8773f0 100644 --- a/.github/workflows/cbt.yml +++ b/.github/workflows/cbt.yml @@ -6,7 +6,7 @@ on: pull_request: branches: ["window"] -env: +env: CARGO_TERM_COLOR: always jobs: @@ -22,4 +22,5 @@ jobs: - uses: actions/checkout@v4 - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} - run: cargo build --verbose + - run: cargo test --verbose --all - run: cargo test --verbose --all --all-features diff --git a/Cargo.lock b/Cargo.lock index 91a3997..bd98667 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1012,6 +1012,7 @@ version = "0.0.1-alpha.1" dependencies = [ "base64", "blake3", + "cfg-if", "const_format", "grass", "lightningcss", diff --git a/Cargo.toml b/Cargo.toml index d244cf6..1cc9c1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,6 +43,9 @@ sabry_intrnl = {workspace = true} [features] default = ["procmacro"] +lepty-scoping = [ + "sabry_intrnl/lepty-scoping" +] procmacro = [ "dep:sabry_procmacro" ] diff --git a/README.md b/README.md index ea37bb7..34f0d86 100644 --- a/README.md +++ b/README.md @@ -268,6 +268,73 @@ fn render() -> HtmlElement { ``` So the `mixins!` macro we just passed to the `usey!` macro inside of `buildy` function call is now accessible with simple and natural `@use "mixins"` SASS rule! +### Leptos specials + +With [leptos](https://github.com/leptos-rs/leptos) framework you can do the trick to apply some class to most of HtmlElements for the entire component/island: + +```rust,ignore +#[component] +fn component() -> impl IntoView { + view! {class="cls1", /* <- here */ +

"Head"

+

"text"

+ } +} +``` +... and have "cls1" on both `h1` and `p` auto-assigned. Isn't this cool? + +So, if you're on leptos, and don't mind to take this approach, I'd highly recommend turning the *lepty-scoping* feature on: + +```toml +# Cargo.toml + +[dependencies] +sabry = {version = "0.0.1", features = ["lepty-scoping"]} + +[build-dependencies] +sabry = {version = "0.0.1", features = ["build", "lepty-scoping"]} +``` + +```rust,ignore +styly!(scope { + @use "tokens"; + h1 { + @include tokens.sectionhead(); + img { + @include tokens.sectionimg(); + } + } + .breadcumbs { + @include tokens.badgelist(); + &__item { + @include tokens.badge(secondary); + } + } +}); + +#[component] +fn component() -> impl IntoView { + view! {class=SCOPE, +

+ "Head" + +

+
    +
  • + "Home page" +
  • +
+ } +} +``` + +That will perform *much* better: + +- All scope members - like `scope::breadcumbs` - wont contain repeating scope hash, just the original class/id selector +- You will not encounter [the catch](#scoping) with nested tagname selectors + +Also, this isn't really exclusive leptos-supporting feature. It just changes scoping behavour. + ## Configuration Sabry configuration lives in `[package.metadata.sabry]` table of the manifest file. @@ -535,6 +602,8 @@ Different selector types are scoped differently: > > Also if there are nested tagname selectors - sabry won't take this into account and you'll > have to wrap them with `SCOPE` class as well +> +> **However** If you are able to apply some class to all html elements you have - like `view!{class=CLASS...}` with Leptos - you could use *lepty-scoping* feature flag for sabry and get rid of this catch! See more [here](#leptos-specials). As for **SASS parent selectors**: they are currently handled in different way. Instead of walking up the syntax tree sabry just creates function member for the scope and leave the rest to grass: diff --git a/examples/leptos-axum/Cargo.toml b/examples/leptos-axum/Cargo.toml index 1b30dbb..39e1e43 100644 --- a/examples/leptos-axum/Cargo.toml +++ b/examples/leptos-axum/Cargo.toml @@ -23,11 +23,11 @@ tracing = { version = "0.1", optional = true } http = "1" # sabry with sass -sabry = {path = "../../"} +sabry = {path = "../../", features = ["lepty-scoping"]} [build-dependencies] # sabry for build with sass -sabry = {path = "../../", features = ["build"]} +sabry = {path = "../../", features = ["build", "lepty-scoping"]} # lets depend on our styles define-styles = {path = "../define-styles"} @@ -51,11 +51,12 @@ css.minify = true css.bundle = "target/.sabry/target/bundle.css" [package.metadata.leptos] +# Sabry-specific quality of life config +style-file = "target/.sabry/target/bundle.css" + output-name = "leptos-axum" site-root = "target/site" site-pkg-dir = "pkg" -# Sabry-generated bundle for leptos -style-file = "target/.sabry/target/bundle.css" assets-dir = "public" site-addr = "127.0.0.1:3000" reload-port = 3001 diff --git a/examples/leptos-axum/src/routes/home.rs b/examples/leptos-axum/src/routes/home.rs index 0e06caf..1c006db 100644 --- a/examples/leptos-axum/src/routes/home.rs +++ b/examples/leptos-axum/src/routes/home.rs @@ -1,18 +1,7 @@ use leptos::prelude::*; use sabry::styly; -styly!(s "src/routes/home.scss"); - -styly!(s2 { - @use "theme"; - .card { - @include theme.surface(secondary); - } - .pocwarn { - @include theme.surface(secondary); - text-transform: uppercase; - } -}); +styly!(style "src/routes/home.scss"); /// Renders the home page of your application. #[component] @@ -21,13 +10,14 @@ pub fn Route() -> impl IntoView { let count = RwSignal::new(0); let on_click = move |_| *count.write() += 1; - view! { -
+ view! {class = STYLE, +

"Welcome to Leptos!"

- - "DISCLAIMER:" -

"This isn't a design example! Its just proof of sabry's capabilities."

-

"Plz dont make websites/apps which look like this page :D"

+ + + "DISCLAIMER:" +

"This isn't a design example! Its just proof of sabry's capabilities."

+

"Plz dont make websites/apps which look like this page :D"

} } diff --git a/examples/leptos-axum/src/routes/home.scss b/examples/leptos-axum/src/routes/home.scss index 67e7ec1..d9ef063 100644 --- a/examples/leptos-axum/src/routes/home.scss +++ b/examples/leptos-axum/src/routes/home.scss @@ -4,9 +4,20 @@ .btn { @include tokens.clickable(accent); + &-dark { + @include tokens.clickable(secondary, 0.8, 1.1); + } } .table { @include utils.flex(column, center, center); @include theme.surface(primary); } + +.card { + @include theme.surface(secondary); +} +.pocwarn { + @include theme.surface(secondary); + text-transform: uppercase; +} diff --git a/sabry_intrnl/Cargo.toml b/sabry_intrnl/Cargo.toml index 19d7f51..41c5cbc 100644 --- a/sabry_intrnl/Cargo.toml +++ b/sabry_intrnl/Cargo.toml @@ -23,5 +23,7 @@ const_format = {version = "^0.2"} thiserror = {version = "^1.0"} serde = {version = "^1.0", features = ["derive"]} toml = {version = "^0.8"} +cfg-if = {version = "^1.0"} [features] +lepty-scoping = [] diff --git a/sabry_intrnl/src/scoper/mod.rs b/sabry_intrnl/src/scoper/mod.rs index 658e8f0..0d82a7d 100644 --- a/sabry_intrnl/src/scoper/mod.rs +++ b/sabry_intrnl/src/scoper/mod.rs @@ -1,3 +1,4 @@ +use cfg_if::cfg_if; use hash::ScopeHash; use raffia::Spanned; use regex::Regex; @@ -187,10 +188,22 @@ impl HashedSelector { // As we dont want to use two HTML props for a single ID, // ID scoping is done with id modification ScopedSelector::Id(a) => { - format!("{}-{}", hash.as_str(), a.ident) + cfg_if! { + if #[cfg(feature = "lepty-scoping")] { + format!("{}.{}", a.ident, hash.as_str()) + } else { + format!("{}-{}", hash.as_str(), a.ident) + } + } } ScopedSelector::Tag(a) => { - format!(".{} {}", hash.as_str(), a.ident) + cfg_if! { + if #[cfg(feature = "lepty-scoping")] { + format!("{}.{}", a.ident, hash.as_str()) + } else { + format!(".{} {}", hash.as_str(), a.ident) + } + } } } } @@ -205,10 +218,26 @@ impl HashedSelector { pub fn make_hashed_html(value: &ScopedSelector, hash: &ScopeHash) -> Option { match value { // Class scoping is done with class composition - ScopedSelector::Class(a) => Some(format!("{} {}", hash.as_str(), a.ident)), + ScopedSelector::Class(a) => { + cfg_if! { + if #[cfg(feature = "lepty-scoping")] { + Some(a.ident.to_string()) + } else { + Some(format!("{} {}", hash.as_str(), a.ident)) + } + } + }, // As we dont want to use two HTML props for a single ID, // ID scoping is done with id modification - ScopedSelector::Id(a) => Some(format!("{}-{}", hash.as_str(), a.ident)), + ScopedSelector::Id(a) => { + cfg_if! { + if #[cfg(feature = "lepty-scoping")] { + Some(a.ident.to_string()) + } else { + Some(format!("{}-{}", hash.as_str(), a.ident)) + } + } + }, ScopedSelector::Tag(_) => None, } } @@ -330,6 +359,7 @@ pub fn apply_basic_rusty_member_gen_rules(source: &str) -> String { mod test { use std::collections::HashSet; + use cfg_if::cfg_if; use syn::Ident; use crate::{ @@ -345,14 +375,33 @@ mod test { ".cls1{color:red; &-dark{color: black;} #id1 {color:green;} div {color:blue;}} .cls3#id2{color: black;}"; let hash = ScopeHash::test_init("F2kf8nMs".into()); - let expect_code = ".F2kf8nMs.cls1{color:red; &-dark{color: black;} #F2kf8nMs-id1 {color:green;} .F2kf8nMs div {color:blue;}} .F2kf8nMs.cls3#F2kf8nMs-id2{color: black;}"; - let expect_selector_htmls = HashSet::from([ - "F2kf8nMs cls1".to_string(), - "F2kf8nMs-id1".to_string(), - "F2kf8nMs cls3".to_string(), - "F2kf8nMs-id2".to_string(), - "".to_string(), // comes from `div` which has no html hashed code, still want to check presense - ]); + cfg_if! { + if #[cfg(feature = "lepty-scoping")]{ + let expect_code = ".F2kf8nMs.cls1{color:red; &-dark{color: black;} #id1.F2kf8nMs {color:green;} div.F2kf8nMs {color:blue;}} .F2kf8nMs.cls3#id2.F2kf8nMs{color: black;}"; + } else { + let expect_code = ".F2kf8nMs.cls1{color:red; &-dark{color: black;} #F2kf8nMs-id1 {color:green;} .F2kf8nMs div {color:blue;}} .F2kf8nMs.cls3#F2kf8nMs-id2{color: black;}"; + } + } + + cfg_if! { + if #[cfg(feature = "lepty-scoping")] { + let expect_selector_htmls = HashSet::from([ + "cls1".to_string(), + "id1".to_string(), + "cls3".to_string(), + "id2".to_string(), + "".to_string(), // comes from `div` which has no html hashed code, still want to check presense + ]); + } else { + let expect_selector_htmls = HashSet::from([ + "F2kf8nMs cls1".to_string(), + "F2kf8nMs-id1".to_string(), + "F2kf8nMs cls3".to_string(), + "F2kf8nMs-id2".to_string(), + "".to_string(), // comes from `div` which has no html hashed code, still want to check presense + ]); + } + } let scope = ArbitraryScope::from_source( raffia::Syntax::Scss, From 13ac29a2337c7cb6a73c34002feeab5339ce1707 Mon Sep 17 00:00:00 2001 From: Yiffy Dev Date: Thu, 31 Oct 2024 09:15:42 +0500 Subject: [PATCH 6/6] use lepty-scoping in examples --- README.md | 2 ++ examples/leptos-axum/src/routes/home.rs | 44 +++++++++++++++++++++-- examples/leptos-axum/src/routes/home.scss | 23 ------------ 3 files changed, 44 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 34f0d86..6ab6e0b 100644 --- a/README.md +++ b/README.md @@ -209,6 +209,8 @@ Every selector, if that does make sense, now available for you as a member of `s ### Use styles earlier created in another crate +> **Tip** | If you use [leptos](https://github.com/leptos-rs/leptos) - check [this](#leptos-specials) section as well + The combination of previous two, with some additional work to do and some extra sugar to enjoy. Sabry is needed as both dependency and build-dependency. diff --git a/examples/leptos-axum/src/routes/home.rs b/examples/leptos-axum/src/routes/home.rs index 1c006db..b79682d 100644 --- a/examples/leptos-axum/src/routes/home.rs +++ b/examples/leptos-axum/src/routes/home.rs @@ -1,7 +1,41 @@ use leptos::prelude::*; use sabry::styly; -styly!(style "src/routes/home.scss"); +styly!(style { + @use "tokens"; + @use "utils"; + @use "theme"; + + h2 { + margin-bottom: 1rem; + @include theme.surface(primary); + @include theme.txt(primary); + span { + @include theme.txt(accent); + } + } + + .btn { + @include tokens.clickable(accent); + &-dark { + @include tokens.clickable(secondary, 0.8, 1.1); + } + } + + .table { + @include utils.flex(column, center, center); + @include theme.surface(primary); + } + + .card { + @include theme.surface(secondary); + } + .pocwarn { + @include theme.surface(secondary); + text-transform: uppercase; + } + +}); /// Renders the home page of your application. #[component] @@ -12,7 +46,13 @@ pub fn Route() -> impl IntoView { view! {class = STYLE,
-

"Welcome to Leptos!"

+

"Welcome to Leptos"

+

+ "This head is styled with lepty-scopes feature" +
+ "And this child too!" +

+ "DISCLAIMER:" diff --git a/examples/leptos-axum/src/routes/home.scss b/examples/leptos-axum/src/routes/home.scss index d9ef063..e69de29 100644 --- a/examples/leptos-axum/src/routes/home.scss +++ b/examples/leptos-axum/src/routes/home.scss @@ -1,23 +0,0 @@ -@use "tokens"; -@use "utils"; -@use "theme"; - -.btn { - @include tokens.clickable(accent); - &-dark { - @include tokens.clickable(secondary, 0.8, 1.1); - } -} - -.table { - @include utils.flex(column, center, center); - @include theme.surface(primary); -} - -.card { - @include theme.surface(secondary); -} -.pocwarn { - @include theme.surface(secondary); - text-transform: uppercase; -}