classnames-rs
A Rust macro library for dynamically building CSS class names, inspired by the JavaScript classnames library.
Features
- โจ String literals support - Basic class name strings
- ๐ Conditional rendering - Dynamic class names based on conditions
- ๐ฏ Option type support - Handle optional class names gracefully
- ๐ Ternary expressions - Inline conditional logic
- ๐ ๏ธ Helper macros - Additional utilities like
choose!
,when!
,maybe!
- ๐งน Automatic whitespace normalization - Clean output formatting
Installation
Add this to your Cargo.toml
:
[]
= "0.1.0"
Quick Start
use classnames;
// Basic usage
let classes = classnames!;
assert_eq!;
// Conditional classes
let is_active = true;
let classes = classnames!;
assert_eq!;
Usage Examples
All examples below are tested and verified. You can run cargo test
to verify them yourself.
Basic Usage
use classnames;
let result = classnames!;
assert_eq!;
Conditional Class Names
use classnames;
let is_active = true;
let is_small = false;
let result = classnames!;
assert_eq!;
Option Type Support
use classnames;
let optional_class: = Some;
let none_class: = None;
let result = classnames!;
assert_eq!;
Ternary Expressions
use classnames;
let count = 5;
let result = classnames!;
assert_eq!;
Helper Macros
choose!
Macro
use ;
let is_dark = true;
let result = classnames!;
assert_eq!;
when!
Macro
use ;
let is_loading = true;
let result = classnames!;
assert_eq!;
maybe!
Macro
use ;
let optional: = Some;
let result = classnames!;
assert_eq!;
Complex Example
use ;
let is_primary = true;
let size: = Some;
let is_disabled = false;
let count = 3;
let result = classnames!;
assert_eq!;
Supported Expression Types
Expression Type | Syntax | Example |
---|---|---|
String literals | "class-name" |
"btn" |
Conditional tuples | (condition, "class") |
(is_active, "active") |
Ternary tuples | (condition, "true-class", "false-class") |
(is_dark, "dark", "light") |
Option types | some_option |
Some("highlight") |
If expressions | if condition { "true" } else { "false" } |
if loading { "spinner" } else { "" } |
Block expressions | { /* returns Option<T> or &str */ } |
{ get_dynamic_class() } |
API Reference
Core Macros
classnames!(...)
- Main macro for building class nameschoose!(condition, true_val, false_val)
- Conditional selectionwhen!(condition, value)
- Conditional inclusionmaybe!(option)
- Handle Option typespretty_classname!(input)
- Normalize whitespace
Real-world Example
use ;
// Usage
let button = ButtonProps ;
assert_eq!;
Testing Examples
All examples in this README are tested to ensure they work as documented. Run the following to verify:
# Run all tests
# Run only documentation tests
# Run specific test module
Performance
Important Note: This library has runtime overhead for conditional evaluations. The macro generates code that performs condition checks at runtime.
For zero runtime overhead, consider using classnames-const-rs which provides compile-time class name resolution for static use cases.
Performance Characteristics:
- โ Macro expansion: Zero overhead (compile-time)
- โ ๏ธ Conditional logic: Runtime evaluation overhead
- โ String operations: Minimal allocation overhead
- โ Memory usage: Efficient string building
Choose the right tool for your use case:
- Use
classnames-rs
for dynamic, runtime-dependent class names - Use
classnames-const-rs
for static, compile-time class names
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Inspired by the JavaScript classnames library
- Built with โค๏ธ for the Rust community