| Crates.io | clsx |
| lib.rs | clsx |
| version | 0.1.1 |
| created_at | 2025-01-18 14:21:59.284765+00 |
| updated_at | 2025-01-18 18:35:31.878167+00 |
| description | A flexible class name composition utility for Rust, inspired by clsx and tailwind-merge. |
| homepage | https://github.com/geoffreygarrett/clsx#readme |
| repository | https://github.com/geoffreygarrett/clsx |
| max_upload_size | |
| id | 1521670 |
| size | 24,271 |
A tiny utility for conditionally constructing space-separated class strings in Rust,
inspired by lukeed/clsx.
A single-pass, flexible, and highly efficient library for assembling “className” strings in Rust.
String.HashMap<String, bool>) to mimic JS object usage(bool, &str) or (bool, String) for conditional insertionClsxArgAdd clsx to your Cargo.toml:
[dependencies]
clsx = "0.1.0"
Then in your code:
use clsx::clsx;
use clsx::clsx;
fn main() {
// 1) Basic strings
let classes = clsx!("foo", "bar", "baz");
assert_eq!(classes, "foo bar baz");
// 2) Conditional tuples
let is_active = true;
let is_disabled = false;
let classes = clsx!(
"btn",
(is_active, "btn-active"),
(is_disabled, "btn-disabled")
);
// => "btn btn-active"
assert_eq!(classes, "btn btn-active");
// 3) HashMap usage
use std::collections::HashMap;
let mut map = HashMap::new();
map.insert("flex".to_string(), true);
map.insert("hidden".to_string(), false);
let classes = clsx!(map, "base");
assert_eq!(classes, "flex base");
// 4) Arrays & flattening
let classes = clsx!(
["hello", "world"],
(true, "testing"),
["nested", "classes"]
);
assert_eq!(classes, "hello world testing nested classes");
// 5) Options
let maybe_active: Option<&str> = Some("active");
let none_str: Option<&str> = None;
let classes = clsx!("btn", maybe_active, none_str, "p-4");
// => "btn active p-4"
assert_eq!(classes, "btn active p-4");
// 6) Numbers
let i = 10;
let f = 3.14;
let classes = clsx!("start", i, f, "end");
// => "start 10 3.14 end"
assert_eq!(classes, "start 10 3.14 end");
}
clsx!(...args) -> StringFlatten and conditionally assemble space-separated classes from any combination of arguments:
| Type(s) | Behavior |
|---|---|
&str, String |
Appends if non-empty |
| booleans | Ignored (no classes appended) |
| numeric types | Appended as string (10, 3.14, etc.) |
| arrays/slices/vectors | Flatten each item (recursively) |
| hash maps | (HashMap<String, bool>) – Only the keys whose value is true get appended |
| tuples | (bool, &str) or (bool, String) => appended only if the bool is true |
| option | Option<T> => appended if Some, ignored if None |
| closures | Called, and the result is appended if it’s non-empty or meets the above criteria |
Note: Any empty strings, false booleans, or “falsey” checks automatically discard the class from the output.
(bool, &str), you can inline if your_bool { "class" } else { "" }:
let show_extra = false;
let classes = clsx!("core", if show_extra { "extra" } else { "" }, "final");
// => "core final"
Option<T>:
let maybe = || -> Option<&'static str> { Some("maybe-yes") };
let never = || -> Option<&'static str> { None };
let output = clsx!("start", maybe, never, "end");
// => "start maybe-yes end"
We don’t provide cross-browser or JS benchmarks, but this crate is quite small and uses:
String capacity (approx. 8 * number_of_arguments bytes)std::fmt::Write for numeric conversions to avoid small temporary buffersFor detailed performance measurements, add your own Criterion or custom benchmarks.
All stable releases of Rust (>=1.60) are supported. If you find any compatibility issues, please file an issue.
Use clsx with Tailwind CSS by simply providing the Tailwind classes. For advanced
autocompletion, your IDE needs to recognize clsx!(...) usage. The standard JS/TS IntelliSense extension might not work
in Rust, but you may
try Tailwind Language Server
or a Rust-specific extension.
MIT © RustForWeb This library is a Rust port inspired by the original clsx by Luke Edwards.