7 个不稳定版本 (3 个破坏性更新)

0.4.1 2022年6月4日
0.4.0 2022年6月4日
0.3.2 2022年4月1日
0.3.1 2022年3月27日
0.1.0 2022年3月5日

#scoped-css 中排名 6

Download history 25/week @ 2024-04-10 24/week @ 2024-04-17 29/week @ 2024-04-24 26/week @ 2024-05-01 13/week @ 2024-05-08 16/week @ 2024-05-15 18/week @ 2024-05-22 29/week @ 2024-05-29 20/week @ 2024-06-05 20/week @ 2024-06-12 26/week @ 2024-06-19 22/week @ 2024-06-26 1/week @ 2024-07-03 18/week @ 2024-07-10 22/week @ 2024-07-17 17/week @ 2024-07-24

每月下载量 58
用于 yew-scroll-area

MIT/Apache 许可

105KB
2K SLoC

yew-style-in-rs

功能

  • dry-run:不将 CSS 文件写入磁盘。没有此功能,此包将在目标磁盘上创建和写入 CSS 文件。此功能对文档构建很有用。

如果您想将使用 yew-style-in-rs 的组件发布到 crates.io,您可能需要在 Cargo.toml 中写入以下内容,因为 crates.io 文档构建环境无法写入文件系统

[features]
default = []
dry-run = ["yew-style-in-rs/dry-run"]

[package.metadata.docs.rs]
cargo-args = ["--features=dry-run"]

用法

style!

style! 宏生成作用域 CSS。 style! 宏可以包含 css!dyn css!keyframes!dyn keyframes! 声明。

css! 声明

css! 声明在编译时生成作用域 CSS。

use yew::prelude::*;
use yew_style_in_rs::*;

#[function_component(MyComponent)]
pub fn my_component() -> Html {
    style! {
        // You can use CSS Nesting
        let css = css! {r#"
            border: solid green 1px;
            width: 100%;
            height: 150px;
            text-align: center;
            box-sizing: border-box;

            & > p {
                background: white;
            }
        "#};
    }
    html! {
        <div class={classes!(css)}>
            <p>{"compile time static css"}</p>
        </div>
    }
}

上述代码在构建目录中生成以下 style.css

.AbCdEfGh {
  border: solid green 1px;
  width: 100%;
  height: 150px;
  text-align: center;
  box-sizing: border-box;
}

.AbCdEfGh > p {
  background: white;
}

AbCdEfGh 是一个随机的 8 位字母。注意,可以使用 CSS 嵌套。

css! 声明可以指定要生成的 CSS 文件名。

use yew::prelude::*;
use yew_style_in_rs::*;

#[function_component(MyComponent)]
pub fn my_component() -> Html {
    style! {
        // You can pass filename
        let important_css = css!(filename = "important") {r#"
            background: red;
            color: #000033;
        "#};
        // You can use CSS Nesting
        let css = css! {r#"
            border: solid green 1px;
            width: 100%;
            height: 150px;
            text-align: center;
            box-sizing: border-box;

            & > p {
                background: white;
            }
        "#};
    }
    html! {
        <div class={classes!(important_css, css)}>
            <p>{"compile time static css"}</p>
        </div>
    }
}

上述代码生成 style.cssimportant.css

您可以在 HTML 文件中按如下方式同步加载 important.css 和异步加载 style.css

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8"/>
    <title>yew-style-in-rs</title>

    <!-- important style -->
    <link rel="stylesheet" href="./important.css"/>

    <!-- async load style -->
    <link rel="stylesheet" href="./style.css" media="print" onload="this.media='all'">
  </head>
</html>

由于编译时生成 CSS,因此 css! 声明只能为静态。如果想在运行时更改样式,请使用以下 dyn css! 声明。

dyn css! 声明

dyn css! 声明在运行时生成作用域 CSS。

use yew::prelude::*;
use yew_style_in_rs::*;

#[function_component(MyComponent)]
pub fn my_component() -> Html {
    let background_state = use_state(|| "pink");
    let background = *background_state;
    let box_shadow_state = use_state(|| "#ffffff");
    let box_shadow = *box_shadow_state;

    let onclick = Callback::from({
        let background_state = background_state.clone();
        move |_| {
            if *background_state == "pink" {
                background_state.set("cyan");
                box_shadow_state.set("#101010");
            } else {
                background_state.set("pink");
                box_shadow_state.set("#ffffff");
            }
        }
    });

    style! {
        let dynamic_css = dyn css! {r#"
            background: ${background};

            & > p {
                box-shadow: 0 0 10px ${box_shadow};
            }
        "#};
    }
    html! {
        <div class={classes!(css, dynamic_css)} {onclick}>
            <p>{"Click Me"}</p>
            <p>{"dynamic css"}</p>
        </div>
    }
}

上述代码生成以下样式 HTML 元素并将其插入到 HTML 的头部。

<style data-style="dynamic-AbCdEfGh">
  .dynamic-AbCdEfGh {
    background: pink;
  }

  .dynamic-AbCdEfGh > p {
    box-shadow: 0 0 10px #ffffff;
  }
</style>

AbCdEfGh 是一个随机的 8 位字母。注意,可以使用 CSS 嵌套。

您可以在一个 style! 宏中同时使用 css! 声明和 dyn css! 声明。

use yew::prelude::*;
use yew_style_in_rs::*;

#[function_component(MyComponent)]
pub fn my_component() -> Html {
    let background_state = use_state(|| "pink");
    let background = *background_state;
    let box_shadow_state = use_state(|| "#ffffff");
    let box_shadow = *box_shadow_state;

    let onclick = Callback::from({
        let background_state = background_state.clone();
        move |_| {
            if *background_state == "pink" {
                background_state.set("cyan");
                box_shadow_state.set("#101010");
            } else {
                background_state.set("pink");
                box_shadow_state.set("#ffffff");
            }
        }
    });

    style! {
        let css = css!{r#"
            border: solid 1px black;
            width: 100%;
            height: 150px;
            text-align: center;
            box-sizing: border-box;

            &:hover {
                border: solid 10px black;
            }
        "#};
        let dynamic_css = dyn css! {r#"
            background: ${background};

            & > p {
                box-shadow: 0 0 10px ${box_shadow};
            }
        "#};
    }
    html! {
        <div class={classes!(css, dynamic_css)} {onclick}>
            <p>{"Click Me"}</p>
            <p>{"dynamic css"}</p>
        </div>
    }
}

可以使用 ${{}} 进行各种位置的插值。

# use yew::prelude::*;
# use yew_style_in_rs::*;
#
#[function_component(MyComponent)]
pub fn my_component() -> Html {
    let property_name = "background";
    let property_value = "black";
    let selector = "p";
    let declaration = "& > div { background: white; }";
    style! {
        let dynamic_css = dyn css! {r#"
            ${property_name}: ${property_value};
            & > ${selector} {
                box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
            }
            ${declaration}
        "#};
    }
    html! {
        <div class={dynamic_css}>
            <p>{"dynamic css"}</p>
            <div>{"Hi"}</div>
        </div>
    }
}

keyframes! 声明

keyframes! 声明在编译时生成作用域化的 @keyframes。在编译时,style.css 将在构建目录中生成。

# use yew::prelude::*;
# use yew_style_in_rs::*;
#
#[function_component(MyComponent)]
pub fn my_component() -> Html {
    style! {
        let css = css! {r#"
            animation: ##anim## 1s;
        "#};
        keyframes!{r#"
            @keyframes anim {
                from { transform: translateX(0px); }
                to { transform: translateX(100px); }
            }
        "#}
    }
    html! {
        <div class={classes!(css)}>
            <p>{"compile time css animation"}</p>
        </div>
    }
}

通过编写 ##<ANIMATION NAME>## 来使用声明的动画,例如 ##anim##。为了创建作用域,编译时 anim 将被重命名为 anim-AbCdEfGh

您可以为样式表传递文件名。

# use yew::prelude::*;
# use yew_style_in_rs::*;
#
#[function_component(MyComponent)]
pub fn my_component() -> Html {
    style! {
        let css = css! {r#"
            animation: ##anim## 1s;
        "#};
        keyframes!(filename = "important") {r#"
            @keyframes anim {
                from { transform: translateX(0px); }
                to { transform: translateX(100px); }
            }
        "#}
    }
    html! {
        <div class={classes!(css)}>
            <p>{"compile time css animation"}</p>
        </div>
    }
}

上面的代码生成 important.css

dyn keyframes! 声明

dyn keyframes! 声明在运行时生成作用域化的 CSS。将生成 style HTML 元素并将其插入到 HTML 的头部。

# use yew::prelude::*;
# use yew_style_in_rs::*;
#[function_component(MyComponentD)]
pub fn my_component_d() -> Html {
    let from_x_ref = use_mut_ref(|| 20);
    let to_x_ref = use_mut_ref(|| 20);
    let disabled_button = use_mut_ref(|| false);
    let animate_class = use_state(|| None);

    let onclick = Callback::from({
        let to_x_ref = to_x_ref.clone();
        let disabled_button = disabled_button.clone();
        let animate_class = animate_class.clone();
        move |_| {
            *to_x_ref.borrow_mut() += 20;
            if *to_x_ref.borrow() >= 100 {
                *to_x_ref.borrow_mut() = 0;
            }
            *disabled_button.borrow_mut() = true;
            animate_class.set(Some("animate"));
        }
    });
    let onanimationend = Callback::from({
        let from_x_ref = from_x_ref.clone();
        let disabled_button = disabled_button.clone();
        let animate_class = animate_class.clone();
        move |_| {
            *from_x_ref.borrow_mut() += 20;
            if *from_x_ref.borrow() >= 100 {
                *from_x_ref.borrow_mut() = 0;
            }
            *disabled_button.borrow_mut() = false;
            animate_class.set(None);
        }
    });

    let from_x = *from_x_ref.borrow();
    let to_x = *to_x_ref.borrow();
    let disabled = *disabled_button.borrow();

    style! {
        let css = css! {r#"
            border-top: solid 20px;
            border-bottom: solid 20px;
            width: 100%;
            height: 150px;
            text-align: center;
            box-sizing: border-box;

            & > div {
                width: 50px;
                height: 50px;
                background: black;
            }
        "#};
        let dyn_css = dyn css!{r#"
            & > div {
                transform: translateX(${from_x}vw);
            }
            & > div.animate {
                animation: ##translate## 1s;
            }
        "#};
        dyn keyframes!{r#"
            @keyframes translate {
                to {
                    transform: translateX(${to_x}vw);
                }
            }
        "#}
    }
    html! {
        <div class={classes!(css, dyn_css)}>
            <div class={*animate_class} {onanimationend}/>
            <button {onclick} {disabled}>{"Click Me!"}</button>
        </div>
    }
}

通过编写 ##<ANIMATION NAME>## 来使用声明的动画,例如 ##translate##。为了创建作用域,编译时 translate 将被重命名为 translate-dynamic-AbCdEfGh

dyn keyframes! 中声明的关键帧只能在 dyn css! 声明中使用。在 css! 声明中不能使用在 dyn keyframes! 中声明的关键帧。

依赖项

~14MB
~258K SLoC