7 releases

0.1.10 Sep 21, 2024
0.1.9 Sep 14, 2024

#155 in WebAssembly

MIT license

46KB
1K SLoC

wasm-css

Ergonomic WASM-CSS framework

Description

Provides a simple API through Style and the style!, named_style!, add_effects! and global_style! macros to implement dynamic CSS styling in WASM environments.

Requirements

  • Rust

  • WASM Pack for testing: cargo install wasm-pack

Installation

cargo add wasm-css

Usage

You can create a Style via style!, named_style! and global_style! macros; as well as Style::new. Each style, unless given a class name or a global style target; will generate a UUID using the Crypto module, and use that as the <style> tags class name and id.

When a Style is created, or mutated; it will update the DOMs <style> node corresponding to its uuid. You can get the class name (which is also set as the style tags ID) through the Style::class method to apply it to elements. So, when applying mass changes, it is more efficient to use the *_many or append methods.

You can add effects or media queries, hover effects, key frames and so on through the add_effects! macro or the Style::insert_effect and Style::insert_effect_many methods.

Please see Full crate documentation can be found here at docs.rs for all available functionality.

Invalid CSS

In its current state, the parser will only detect and skip invalid CSS key names or ill-formatted CSS. Events are internally parsed for CSS formatting, but do not include any level of validation.

Errors

Errors can happen constructing and updating Style if:

  • No Head Object

  • No Window Object

  • No Document Object

  • No Crypto Object when trying to generate class names automatically

Example

use wasm_css::{add_effects, error::WasmCssError, global_style, named_style, style};

fn example() -> Result<(), WasmCssError> {
    let font_size = 20;

    // Constructing Styles
    let mut style = style!("font-size: {font_size}rem;")?;

    let global_style = global_style!(
        "html",
        "
            color: blue;
            background-color: blue;
        "
    )
    .unwrap();

    let named_style = named_style!(
        "my_class_name",
        "
            border: 1px solid black;
            border-radius: 10px;
        "
    )?;

    // Combining Styles
    style.append(&named_style)?;

    // Inserting CSS Lines
    style.insert("font-weight", "bold")?;

    // Removing CSS Lines
    style.remove_many(vec!["border-color", "background-color"])?;

    // Manipulating Effects
    add_effects!(
        &mut style,
        (
            "@media (max-width: {}px) {{ font-size: {}px; background-color: red; }}",
            400,
            12
        ),
        ("&:hover {{ font-size: 20rem; }}",)
    )?;

    style.remove_effect("@media (max-width: 400px)")?;

    // Obtain the styles ClassName/ClassID
    let class = style.class();

    Ok(())
}

Roadmap

Potential Improvements:

  • More validation (Currently only validates standard CSS key name)

  • More CSS Parsing/Generation optimization

  • Parse effects body content "prettily" like standard CSS

Contributing

Open to contributions, please just create a PR/issue or reach out to me to discuss what you would like to add/change.

Testing can be done by:

  • wasm-pack test --chrome

  • Go to the listed URI to run the test suite

License

MIT License

Copyright (c) 2024 Robert Lopez

See LICENSE.md

Dependencies

~7.5–10MB
~182K SLoC