futursolo / stylist-rs

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

CSS values and units #80

Closed simbleau closed 2 years ago

simbleau commented 2 years ago

I think there's a lot of ergonomics that could be gained through support of units and values.

The goals of stylist aren't entirely explained, so I'm not sure if you would be opposed to ergonomic values and unit types in stylist, such that someone could do more intricate styling.

Example of a unit:

use std::{fmt::Display, ops::Mul};

pub enum FontSize {
    Em(f32),
}

impl Mul for FontSize {
    type Output = Self;

    fn mul(self, rhs: Self) -> Self {
        match self {
            FontSize::Em(lhs) => match rhs {
                FontSize::Em(rhs) => FontSize::Em(lhs * rhs),
            },
        }
    }
}

impl Mul<i32> for FontSize {
    type Output = Self;

    fn mul(self, rhs: i32) -> Self {
        match self {
            FontSize::Em(lhs) => FontSize::Em(lhs * rhs as f32),
        }
    }
}

... (Div/Mul/Add/Sub) x (f32, i32, u32, etc..)

impl Display for FontSize {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "{}",
            match self {
                FontSize::Em(val) => format!("{}em", val),
            },
        )
    }
}

This would allow someone to, with stylist, do the following:

#[derive(Properties, PartialEq)]
pub struct Props {
    pub scale: u32, 
}

#[function_component(SizedButton)]
pub fn sized_button(props: &Props) -> Html {
    let style = css!(
        r#"
            & {
                text-size: ${fs}
            }
        "#,
        fs = Em(1.0) * &props.scale
    );

    html! {
        <button class={style}>{ "CLICK ME!" }</button>
    }
}

The benefits of having support for rgb, rgba, em, etc.. built in would be a massive gain in ergonomics for dynamic sizing, especially media queries.

What are your thoughts?

This is meant to be an open discussion, and I would take over the implementation. I can either make this another crate or we can put this in stylist.