Some checks failed
cargo basic build-test / Sabry - latest (push) Has been cancelled
cargo basic build-test / Sabry - latset - examples (push) Has been cancelled
cargo basic build-test / Sabry - latset - examples-1 (push) Has been cancelled
cargo basic build-test / Sabry - latset - examples-2 (push) Has been cancelled
666 lines
21 KiB
Markdown
666 lines
21 KiB
Markdown
> **Repository moved**
|
|
>
|
|
> On GithHub this repository is now a [push-mirror](https://git.spushk.work/rustyworks/sabry)
|
|
>
|
|
> Crate is still kinda maintained
|
|
|
|
# 🧙🏻 SABRY - Syntactically Awesome, But RustY
|
|
|
|
**Y**et another **R**usty **B**oilerplate-free **A**gnostic **S**tyling crate, which brings your SASS/SCSS style into Rust. Written by a fox this time.
|
|
|
|
\* sabry isn't "syntactically awesome", it refers to SASS abbr expansion.
|
|
|
|
> **Project status** - early, my team uses it now and again in production, and the most of features/fixes do come on demand. I'm pretty happy with ergonomics and taste of the crate, and I'll do my best to keep DX the way it is between minor versions - but there's no guarantee on backwards-compatibility and no refunds if something breaks.
|
|
>
|
|
> "master" branch is what's currently on crates.io
|
|
>
|
|
|
|
[](https://crates.io/crates/sabry)
|
|
[](https://docs.rs/sabry)
|
|
[](https://github.com/yiffyrusdev/sabry/blob/master/LICENSE)
|
|
|
|
At first, I'll show how this crate "tastes". With SABRY, its in your power to:
|
|
|
|
<hr/>
|
|
|
|
Write arbitrary SASS/SCSS code and ship it *as a crate* however you please: with modules, with feature flags, etc. Say "bye" to manual copying, cli-tools and consts.
|
|
|
|
```rust
|
|
sabry::scssy!(tokens {"@mixin colored{color: red;}"});
|
|
```
|
|
|
|
<hr/>
|
|
|
|
Code your SASS in separate files to get proper syntax highlighting, or do sass-in-the-rust to keep things in one place
|
|
|
|
```rust
|
|
sabry::styly!(component {".btn {color: green;}"});
|
|
sabry::styly!(extras "tests/assets/mixin-module.scss");
|
|
```
|
|
|
|
<hr/>
|
|
|
|
Depend on styles with cargo, at build time, which brings all the rusty sweeties in: versions, updates, cratesio, local registries, workspaces, etc.
|
|
|
|
```toml
|
|
[build-dependencies.your_styles]
|
|
registry = "your_registry_isnt_that_cool"
|
|
version = "^0.1"
|
|
features = ["darkmode", "mobile"]
|
|
```
|
|
|
|
<hr/>
|
|
|
|
`@use` your style-crates in sass code *naturally*
|
|
|
|
```rust
|
|
sabry::styly!(breadbadge {"
|
|
@use 'tokens';
|
|
.scope {@include tokens.badge(primary);}
|
|
"});
|
|
```
|
|
|
|
<hr/>
|
|
|
|
Keep things as private and modular as you wish
|
|
|
|
```rust
|
|
sabry::styly!(pub cats "tests/assets/mixin-module.scss");
|
|
sabry::styly!(dogs {".howl {border: none;}"});
|
|
```
|
|
```html
|
|
/// something like render function
|
|
{
|
|
<div class={concatcp!("meow ", CATS)}>
|
|
<ul class={concatcp!("howl ", DOGS)}></ul>
|
|
</div>
|
|
}
|
|
```
|
|
```html
|
|
/// or even better with leptos
|
|
view!{class=CATS
|
|
<div class="meow">
|
|
{move || view!{class=DOGS,
|
|
<ul class="howl"></ul>
|
|
}}
|
|
</div>
|
|
}
|
|
```
|
|
|
|
<hr/>
|
|
|
|
Compile all the sweet SASS/SCSS into the optimized CSS bundle, ship it in CSS shunks or even include the compiled style into the binary
|
|
|
|
```rust
|
|
sabry::styly!(cssbundle {".c1 {color: white;}"});
|
|
```
|
|
|
|
```rust,ignore
|
|
// requires `const-scoping` feature
|
|
sabry::styly!(const binary {".c2 {color: black;}"});
|
|
```
|
|
|
|
<hr/>
|
|
|
|
Sabry will gladly:
|
|
|
|
- scope and hash your styles, so they won't conflict, with amazing [raffia](https://crates.io/crates/raffia) parser
|
|
- compile SASS/SCSS into CSS with [grass](https://crates.io/crates/grass)
|
|
- optimize produced CSS with [lightningcss](https://crates.io/crates/lightningcss)
|
|
- prepare ready CSS bundle and put it wherever you wish
|
|
- include CSS into the build artifact - if you really want it
|
|
|
|
Also, just about everything is pub-available in this crate (with *internals* feature flag) - Sabry is ready for experiments.
|
|
|
|
## Usage
|
|
|
|
Feel free to check out examples:
|
|
|
|
|[crate of styles](./examples/define-styles)|[style usage](./examples/use-styles)|[leptos-axum with sabry](./examples/leptos-axum)|[leptos components](./examples/leptos-components)|
|
|
|-|-|-|-|
|
|
|
|
### Create a crate full of arbitrary SASS
|
|
|
|
The only need is the dependency
|
|
|
|
```toml
|
|
#Cargo.toml
|
|
|
|
[dependencies]
|
|
sabry = {version = "0.0.7"}
|
|
```
|
|
And a proc-macro
|
|
```rust
|
|
// lib.rs
|
|
use sabry::scssy;
|
|
|
|
scssy!(mixins "tests/assets/mixin-module.scss");
|
|
scssy!(styles {"
|
|
$primary-color: black;
|
|
@mixin colored($col: primary) {
|
|
@if $col == primary {
|
|
color: $primary-color;
|
|
} @else {
|
|
color: $col;
|
|
}
|
|
}
|
|
"});
|
|
```
|
|
*\* Unlike most of other crates that do sass-in-the-rust, sabry currently does not allow unquoted sass/scss. You still have to write it in a string-quotes. Unquoted sass/scss is reserved for the future, where, hopefully, I'll find more exciting usage for it. In the meantime it does look like Zed, for example, still highlights your code (:*
|
|
|
|
Now you can build and see two ready for export macros: `mixins!` and `styles!`.
|
|
These are usefull on their own, as invocation of `mixins!()` or `styles!()` - both shall give you the code literal.
|
|
|
|
However there's more sweet use case for them, which is covered below.
|
|
|
|
### Write scoped styles
|
|
|
|
Depend on sabry
|
|
```toml
|
|
# Cargo.toml
|
|
|
|
[dependencies]
|
|
sabry = {version = "0.0.7"}
|
|
```
|
|
And create a style scope wherever you want:
|
|
```rust
|
|
// breadbadgelist.rs
|
|
use sabry::styly;
|
|
|
|
styly!(styles {"
|
|
.badges {
|
|
display: flex;
|
|
&__list {
|
|
display: flex;
|
|
}
|
|
}
|
|
#wolf {
|
|
color: white;
|
|
}
|
|
"});
|
|
```
|
|
|
|
```html
|
|
<ul class={concatcp!("badges ", STYLES)}>
|
|
<li class={STYLES} id="wolf">
|
|
"HOOOOWL!"
|
|
</li>
|
|
</ul>
|
|
```
|
|
|
|
### Use styles earlier created in another crate
|
|
|
|
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.
|
|
To be able to compile all styles sabry also needs the *build* feature flag:
|
|
```toml
|
|
# Cargo.toml
|
|
|
|
[dependencies]
|
|
sabry = {version = "0.0.7"}
|
|
|
|
[build-dependencies]
|
|
sabry = {version = "0.0.7", features = ["build"]}
|
|
```
|
|
> If you do use some non-default feature flags make sure to keep them in sync between sabry-dependency and sabry-build-dependency.
|
|
|
|
Then you have to tell sabry when code should be compiled. We'll do this in *build.rs* file.
|
|
```rust,ignore
|
|
// build.rs
|
|
fn main(){
|
|
sabry::buildy(
|
|
sabry::usey!(
|
|
mixins!(),
|
|
styles!()
|
|
)
|
|
).expect("Failed to build sabry styles");
|
|
}
|
|
```
|
|
`buildy` is the entry function of sabry build-time process. The handy `usey!` macro will do just proper handling of our style-macros for it.
|
|
|
|
Now lets get back to the code and use the mixin defined in another crate:
|
|
```rust
|
|
// breadbadgelist.rs
|
|
use sabry::styly;
|
|
|
|
styly!(styles {"
|
|
// 'mixins' is available beacuse we did call mixins!() macro in the example below
|
|
@use 'mixins';
|
|
.badges {
|
|
display: flex;
|
|
&__list {
|
|
display: flex;
|
|
}
|
|
}
|
|
#wolf {
|
|
@include mixins.colored(white);
|
|
}
|
|
"});
|
|
```
|
|
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!
|
|
|
|
### Create crate of styled components
|
|
|
|
This is currently an alpha-testing-early-concept feature which comes
|
|
with some things to avoid.
|
|
|
|
While the process depends much on the framework you prefer, there are
|
|
some limitations and essential recommendations:
|
|
|
|
- Sabry will scope (hash) your styles at build time, which means
|
|
higher collision probability between the component crate and the main application, which *can not* be currently
|
|
detected by sabry.
|
|
- You have to write style scopes for components with `const` styly macro flavour: `styly!(const whatever {""})`
|
|
- And then you have to solve the task of injecting those generated CSS for your component manually.
|
|
- If you want to write styles in separate SASS/SCSS files, you need the nightly rust and the 'nightly' feature flag set
|
|
for sabry, so you can use styles from relative paths `styly!(const comp "./style.scss")`
|
|
- Which will give you an error from rust-analyzer wether file exists or not. However, if the path is correct, it will build fine.
|
|
|
|
<details>
|
|
<summary>I'd suggest something like this</summary>
|
|
|
|
```rust,ignore
|
|
// lib.rs
|
|
pub mod utils;
|
|
pub mod form;
|
|
|
|
pub const fn css() -> &'static str {
|
|
concatcp!(utils::css(), form::css())
|
|
}
|
|
```
|
|
|
|
```rust,ignore
|
|
// utils.rs
|
|
use sabry::styly;
|
|
|
|
// required `const-scoping` feature
|
|
styly!(pub const scope:scss {"
|
|
.whatever {
|
|
&__code {}
|
|
&[you-please] {}
|
|
}
|
|
"});
|
|
|
|
// requires `const-scoping` feature
|
|
styly!(pub const another:scss {"
|
|
.whatever {
|
|
&__code {}
|
|
&[you-please] {}
|
|
}
|
|
"});
|
|
|
|
pub const fn css() -> &'static str {
|
|
concatcp!(SCOPE, ANOTHER)
|
|
}
|
|
```
|
|
|
|
```rust,ignore
|
|
// form.rs
|
|
use sabry::styly;
|
|
|
|
// requires `const-scoping` feature
|
|
styly!(pub const scope:scss {"
|
|
.whatever {
|
|
&__code {}
|
|
&[you-please] {}
|
|
}
|
|
"});
|
|
|
|
// requires `const-scoping` feature
|
|
styly!(pub const another:scss {"
|
|
.whatever {
|
|
&__code {}
|
|
&[you-please] {}
|
|
}
|
|
"});
|
|
|
|
pub const fn css() -> &'static str {
|
|
concatcp!(SCOPE, ANOTHER)
|
|
}
|
|
```
|
|
So I'd say - do the const function back-propogation and let the consumer decide how to include the CSS of the component crate.
|
|
|
|
</details>
|
|
|
|
## Configuration
|
|
|
|
Sabry configuration lives in `[package.metadata.sabry]` table of the manifest file.
|
|
|
|
All configurations are optional, but with default configuration sabry won't produce any CSS files.
|
|
|
|
Full example, close to defaults:
|
|
```toml
|
|
# Cargo.toml
|
|
|
|
[package.metadata.sabry]
|
|
css.bundle = "target/static/style.css"
|
|
css.prelude = ["assets/prelude.css"]
|
|
css.scopes = "target/statis/scopes/"
|
|
css.minify = true
|
|
|
|
sass.intermediate_dir = "target/.sabry/sass"
|
|
sass.module_name_collision = "merge"
|
|
sass.modules = ["assets/sass/mod1.scss"]
|
|
sass.prelude = ["assets/sass/prelude.scss"]
|
|
sass.scanroot = "src"
|
|
|
|
hash.size = 6
|
|
hash.collision = "error"
|
|
hash.use_scope_name = true
|
|
hash.use_code_size = true
|
|
hash.use_item_names = false
|
|
hash.use_code_text = false
|
|
|
|
[package.metadata.sabry.lightningcss.targets]
|
|
chrome = "120"
|
|
safari = "13.2"
|
|
ie = "6"
|
|
```
|
|
|
|
### `sabry.css`
|
|
|
|
**bundle** *(no default)* - file path ro write CSS bundle into, relative to crate root
|
|
|
|
**prelude** *(no default)* - collection of CSS files, relative to the crate root, which content will be inserted before the compiled style into the *bundle* file if any. Does not affect generated CSS scopes if any.
|
|
|
|
**scopes** *(no default)* - dir path to put separate CSS for every scope into, relative to crate root
|
|
|
|
**minify** *(default true)* - print compressed CSS output and do the lightningcss thing
|
|
|
|
### `sabry.sass`
|
|
|
|
**intermediate_dir** *(default "target/.sabry/sass")* - file to put SASS/SCSS modules into so they are available with `@use` in code
|
|
|
|
**scanroot** *(default "src")* - root directory to start scanning "rs" files from. Used in build function
|
|
|
|
**modules** *(no default)* - collection of SASS/SCSS files, relative to the crate root, which should be available as modules as well
|
|
|
|
**prelude** *(no default)* - collection of SASS/SCSS files, relative to the crate root, which content will be compiled into CSS and then inserted into the CSS *bundle* if any. Does not affect generated CSS scopes if any.
|
|
|
|
**module_name_collision** *(default "merge")* - how to handle similary named modules.
|
|
|
|
*merge* - merge content
|
|
|
|
*error* - break building process with an error
|
|
|
|
### `sabry.hash`
|
|
|
|
**size** *(default 6)* - size of hash in bytes. Feel free to increase/decrease.
|
|
|
|
**use_scope_name** *(default true)* - wether to use scope identifier to calculate hash
|
|
|
|
**use_code_size** *(default true)* - wether to use scope code size to calculate hash
|
|
|
|
**use_item_names** *(default false)* - wether to use all scoped item idents to calculate hash
|
|
|
|
**use_code_text** *(default false)* - wether to use the scope code text to calculate hash
|
|
|
|
**collision** *(default "ignore")* - how to handle similarity of generated hashes
|
|
|
|
*ignore* - dont do anything
|
|
|
|
*error* - break building process with an error
|
|
|
|
### `sabry.lightningcss.targets`
|
|
|
|
Does require `css.minify` to be *true*.
|
|
|
|
Empty by default.
|
|
|
|
Available keys: chrome, firefox, edge, safari, saf_ios, samsung, android, ie
|
|
|
|
Value - minimal browser version to support in "M.m.p" format, where:
|
|
|
|
- *M* - major
|
|
- *m* - minor
|
|
- *p* - patch
|
|
|
|
For example `{ie = "9", saf_ios = "13.2"}` will try to generate CSS supported on both IE 9 and Safari-on-ios 13.2
|
|
|
|
## Detailed guide
|
|
|
|
### Style definition with `scssy!`
|
|
|
|
The `scssy!` macro is available with *procmacro* feature which is enabled by default.
|
|
|
|
It does accept the following syntax: `$name(:$syntax)? ({ $code })|($filename)`, where
|
|
|
|
- *$name* is any identifier valid for `macro_rules!`
|
|
- *$syntax* is either `sass` or `scss`
|
|
- *$code* is valid arbitrary style code in specified syntax
|
|
- *$filename* is a string literal which contains path to the file relative to package root
|
|
|
|
Examples:
|
|
```rust
|
|
use sabry::scssy;
|
|
|
|
scssy!(module1 {"$primary-color: red;"});
|
|
scssy!(module2 "tests/assets/mixin-module.scss");
|
|
scssy!(module3:sass "tests/assets/mixin-module.sass");
|
|
// works, but there are catches.
|
|
scssy!(module4:sass {"
|
|
@mixin colored($col: primary)
|
|
@if $col == primary
|
|
color: white
|
|
@else
|
|
color: red
|
|
"});
|
|
```
|
|
|
|
You may omit the syntax specifier - sabry uses SCSS as the default one.
|
|
|
|
The given code to `scssy!` is not checked to be valid code in given syntax (wip).
|
|
|
|
> SASS support inside of rust files is experimental. If you do want to use SASS tabbed syntax - consider to use files path instead of sass-in-rust option.
|
|
|
|
> With *nightly* feature flag if using the relative path like `scssy!(module "./module.scss")` you'll get false-positive error even if file exists. Also you won't get autocompletion and rust-analyzer will complain on `module!` macro. WIP.
|
|
|
|
### Scoping with `styly!`
|
|
|
|
The `styly!` macro is available with *procmacro* feature flag which is enabled by default.
|
|
|
|
It does accept the following syntax: `pub? const? $ident(:$syntax)? ({ $code })|($filename)`, where
|
|
|
|
- *pub* is explained [here](#public-styly-scopes)
|
|
- *const* is explained [here](#constant-styly-scopes)
|
|
- *$ident* is any identifier valid for `mod`
|
|
- *$syntax* is either `sass` or `scss`
|
|
- *$code* is arbitrary style code valid with given syntax
|
|
- *$filename* is a string literal which contains path to the file relative to package root
|
|
|
|
Examples
|
|
```rust
|
|
use sabry::styly;
|
|
|
|
styly!(private_fox {".fur {color: red; &-dark {color: black;}}"});
|
|
styly!(pub public_fox {".fur {color: red; &-dark {color: black;}}"});
|
|
```
|
|
```rust,ignore
|
|
// requires `const-scoping` feature
|
|
styly!(pub const pub_compiletime_fox:sass {"
|
|
.fur
|
|
color: red
|
|
&-dark
|
|
color: black
|
|
"});
|
|
```
|
|
|
|
Every of those calls will produce the styling scope as a module. Differences are explained right below.
|
|
|
|
In general the scope does look like this:
|
|
```rust,ignore
|
|
const FOX: &str = "J9k_s9";
|
|
mod fox {
|
|
#[deprecated(since = "0.0.6", note = "will remove")]
|
|
pub const fur: &str = "fur J9k_s9";
|
|
}
|
|
```
|
|
|
|
#### Styly scopes
|
|
|
|
Styly macro itself does not generate the scope. It is done in the `sabry_intrnl::scoper`. However, as a result, you will have the following:
|
|
|
|
- `const` with the UPPER_CASE name of the scope, which contains its hash
|
|
|
|
You can read more about scoping and hashing in the [scoping](#scoping) section.
|
|
|
|
#### Public styly scopes
|
|
|
|
By default generated `mod` is private. You can make both mod and wrapper style constant public by adding the `pub` to macro call:
|
|
|
|
```rust
|
|
sabry::styly!(pub whatever "tests/assets/mixin-module.scss");
|
|
```
|
|
|
|
#### Constant styly scopes
|
|
|
|
As you've seen above, scope doe not contain any style code by itself. That's the use case i advise mostly.
|
|
|
|
However you could still compile styles into the artifact by simply adding the `const` to the macro call:
|
|
|
|
```rust,ignore
|
|
// Requires `const-scoping` feature
|
|
sabry::styly!(const scope "tests/assets/mixin-module.scss");
|
|
```
|
|
Which results in following:
|
|
```rust,ignore
|
|
const SCOPE: &str = /* scope hash */;
|
|
const SCOPE_CSS: &str = /* compiled from src/assets/scope.scss */;
|
|
```
|
|
|
|
> **There is a catch** | with the `const` modifier macro must compile CSS at compile-time. That results in several game changers:
|
|
>
|
|
> *First*. You could avoid the "build magic". Sabry will just compile given styles with procmacro at compile time.
|
|
>
|
|
> *Second*. If you `@use` something inside of constant-flavored scope, you can only success if sabry *did the build magic before compilation of that macro call*. So you still can compile the styles into the artifact and enjoy mixins from other crates, but, in general, you are going to receive some false-positives from editor.
|
|
>
|
|
> Worth of notice: sabry will still include const-flavored styles into the CSS bundle during build time.
|
|
|
|
> With *nightly* feature flag if using the relative path like `styly!(const scope "./sctyle.scss")` you'll get false-positive error even if file exists. Also you won't get autocompletion and rust-analyzer will complain on `SCOPE_CSS`, `scope::whatever` etc. WIP.
|
|
|
|
### Building with `buildy` and `usey!`
|
|
|
|
The `buildy` function is available with *build* feature which needs to be enabled explicitly.
|
|
|
|
This function accepts an iterator of pairs: (file_name, code) in form of `(String, String)` type. File name should have an extension, so grass can infere syntax during CSS compilation.
|
|
|
|
Each of those pairs is processed as a file which sabry needs to write into
|
|
the configured `intermediate_dir` and then passed into the CSS compiler.
|
|
|
|
You could, for example, define the module "mixin_a":
|
|
```rust,ignore
|
|
buildy(vec![("mixin_a".to_string(), "@mixin a(){}".to_string())]);
|
|
```
|
|
|
|
However there's a usey macro, which handles this for you:
|
|
```rust,ignore
|
|
buildy(
|
|
usey!(mixins!(), utils!())
|
|
);
|
|
```
|
|
|
|
The `usey!` macro accepts the following syntax:
|
|
`#($macro,)*`, where
|
|
|
|
- *$macro* is a macro which handles two expansions:
|
|
- `() => { $code }`
|
|
- `(syntax) => { $syntax }`
|
|
|
|
Where for the *$macro*:
|
|
|
|
- *$code* is a source code of style as a string literal
|
|
- *$name* is a name of module without extension as a string literal
|
|
- *$syntax* is either "sass" or "scss"
|
|
|
|
`usey!` macro will put the module full name from macro call identifier and the `syntax` expansion, so you could
|
|
resolve potential naming conflicts:
|
|
|
|
```rust,ignore
|
|
use tgk_brandstyle::theme;
|
|
use basestyle::theme as base_theme;
|
|
|
|
sabry::buildy(
|
|
sabry::usey!(
|
|
theme!(),
|
|
base_theme!()
|
|
)
|
|
)?;
|
|
```
|
|
|
|
Exactly this kind of macros is produced by [`scssy!`](#style-definition-with-scssy).
|
|
|
|
### Scoping
|
|
|
|
Sabry handles scoping by restriction of existing selectors
|
|
with the hash. Hash is calculated for the entire scope by the [`styly!`](#scoping-with-styly) macro.
|
|
|
|
Currently the following types of selectors are scoped:
|
|
|
|
- class
|
|
- id
|
|
- tagname
|
|
- SASS parent selectors (see below, there is a catch)
|
|
|
|
Sabry does not make difference between top-level and nested selectors,
|
|
also selector complexity isn't taken into account: sabry simply walks through all compound selectors
|
|
and apply scoping for supported ones.
|
|
|
|
Different selector types are scoped differently:
|
|
|
|
- class selectors are restricted with scope hash: `.class` -> `.HASH.class`
|
|
- id selector are mutated with scope hash: `#id` -> `.HASH#id`
|
|
- tagname selectors are changed into indirect descendance: `div` -> `div.HASH`
|
|
|
|
#### Scope member naming rules
|
|
|
|
Not any valid CSS selector is a valid rust identifier. In general this section should not be needed, as you should receive autocompletion from the editor. *However* it doesn't seem to work properly. Check the [wip](#wip) section out.
|
|
|
|
## Notable feature flags
|
|
|
|
**build** - turns on the `sabry::buildy` function, along with the entire `sabry_build` crate where it lives
|
|
|
|
**internals** - exposes majority of internal stuff for you to experiment or build own workflow
|
|
|
|
**lepty-scoping** - overhauls the scope generation logic, best suitable for the leptos. Check out the [section](#leptos-specials) and an [example](https://github.com/yiffyrusdev/sabry/tree/master/examples/leptos-axum)
|
|
|
|
**const-scoping** - unlocks `styly!(const scope...` compile-time SASS->CSS generation, which seems to break WASM builds without special treatment (https://docs.rs/getrandom/latest/getrandom/#webassembly-support). Idk why, but it started to happen just recently
|
|
|
|
**nightly** - allows relative path selection with `scssy!` and `styly!` macros. However rust-analyzer will raise false-positives for reachable files as well.
|
|
|
|
## WIP
|
|
|
|
*(sorted by my own priority)*, "dones" are excluded
|
|
|
|
- [ ] Why does `const scope` break WASM build? Everything was fine untill recent. This feature isn't top-priority, I dont personally use it, but still curious
|
|
- [x] Somehow achieve the autocompletion for scopes. The problem is explained in details [here](https://github.com/yiffyrusdev/sabry/issues/2)
|
|
- [x] some weird unrelated stuff I can see in autocompletion (still investigating btw)
|
|
- [ ] Support for direct CSS syntax
|
|
- [ ] Currently the crate causes "dependency inheritance" infection. We cant get rid of it, however should be doable to at least get rid of flag inheritance
|
|
- [ ] Experience with cargo-leptos is fine, and we do use it, however its a bit "raughy". Need to do something about it:
|
|
- [ ] We have to save file twice with cargo leptos for changed styles to take effect
|
|
- [ ] Seems like turning on the "hashing" with leptos requires a hard-restart of cargo-leptos
|
|
|
|
## Contributions
|
|
|
|
Any contributions are always welcome!
|
|
|
|
If you find this crate usefull, wanna stick with it in some project, but do miss some
|
|
features - feel free to submit a PR.
|
|
|
|
> If you'd like to fork for the PR - please, use the "window" branch, not the "master".
|
|
|
|
If you encounter any bugs/problems or have use case where things dont work as they should
|
|
for the latest version - please, open an issue!
|
|
|
|
If you'd like to lend a paw - feel free to check the [WIP](#wip) section out, or to search for "TODO" comments.
|
|
|
|
## MSRV
|
|
|
|
Sabry passes its own tests on 1.88 nightly/stable.
|
|
|
|
Examples are on 1.88.
|
|
|
|
## License
|
|
|
|
MIT.
|