13 个稳定版本

2.1.6 2021 年 3 月 8 日
2.1.5 2021 年 3 月 5 日
2.1.4 2021 年 2 月 28 日
1.0.2 2021 年 2 月 16 日

#4 in #class-name

27 每月下载量

MIT 许可证

26KB
573

Classnames

Current Crates.io Version

一个用于生成 BEM 风格类名的 Rust 库。

如果你不知道 BEM,它是一组 CSS 名称的命名约定。你可以在这里找到关于其命名约定的指南。

使用 Classnames

主要有两件事情需要导入 ...

  • ::classnames::classname - 一个用于创建类名的函数。
  • ::classnames::Class - 所有类名都实现的 trait。当你想将类名传递到需要使用它们的地方时,请使用此。

Classnames 的工作方式是,在内部它用不同的 Class 类型包裹每个 Class。添加 "__child" 和 "--attr" 类,等等。

这是为了避免在内部构建大量字符串,以提高效率。

使用 Classnames 的核心...

  1. 你调用 classname 来创建一个基本类名。
  2. 然后你可以调用 .el 来生成一个子类名。
  3. 你还可以调用 .attr 来添加任何 BEM 属性。
  4. 然后你可以将类名组合在一起,以便在组件中打印多个不同的类名。
  5. 最后,将上述所有内容组合在一起;基本类、子名称、属性和添加的类。所有这些都支持转换为 String,或使用 ::std::fmt::Display 打印。这就是如何获取格式化后的类名。

以下是将上述内容再次用代码表示 ...

use ::classnames::Class;
use ::classnames::classname;

fn example() {
  // 1. Prints "banner"
  let base_class = classname("banner");
  println!("{}", base_class);

  // 2. Prints "banner__header"
  let header = base_class.el("header");
  println!("{}", header);

  // 3. Prints "banner__header banner__header--bold"
  let bold_header = base_class.el("header").attr("bold");
  println!("{}", bold_header);

  // 4. Prints "banner pricing-banner"
  let pricing_banner = base_class + classname("pricing-banner");
  println!("{}", pricing_banner);

  // 5. Prints out HTML with the classes included.
  format!(r#"
      <div class="{base_class}">
        <h1 class="{header_class}">Pricing Information</h1>

        <p>Example copy</p>
      </div>
  "#, base_class = pricing_banner, header_class = bold_header);
}

将类名传递给其他函数

所有内部 Classname 类型都实现了 ::classnames::Class。可以使用此类型传递,你也可以将其包装在 Option 中以方便使用。

例如 ...

  use ::classnames::Class;
  use ::classnames::classname;

  #[component]
  pub fn Card<C: Class, Children: Render>(
    class: Option<C>,
    children: Children,
  ) -> impl Render {
    let base_class = classname("card");

    rsx! {
      <div
        class={base_class + class}
      >
        {children}
      </div>
    }
  }

使用 RSX 的示例

Classnames 旨在与用于渲染 HTML 的其他内容一起使用。例如与 render crate 一起使用。

这是一个HTML到假设的TextInput组件的示例,该组件可以可选地禁用。

  use ::classnames::Class;
  use ::render::{rsx, Render, component};

  #[component]
  pub fn TextInput(
    is_disabled: bool,
    error: &'static str,
  ) -> impl Render {
    let base_class = classname("text-input");

    rsx! {
      <div
        class={base_class}
      >
        <input class={base_class.el("input").maybe_attr("disabled", is_disabled)} type={"text"} />

        <div class={base_class.el("error")}>
          {error}
        </div>

        <img src={"/input-icon.svg"} class={base_class.el("icon").attr("large")} />
      </div>
    }
  }

运行render( true, &"发生了一些错误" )将生成类似HTML...

  <div
    class="text-input"
  >
    <input class="text-input__input text-input__input--disabled" type={"text"} />

    <div class="text-input__error">
      {"Some error has occured"}
    </div>

    <img src={"/input-icon.svg"} class="text-input__icon text-input__icon--large" />
  </div>

依赖项

~74KB