| Crates.io | rustyle-css |
| lib.rs | rustyle-css |
| version | 0.3.0 |
| created_at | 2025-12-04 09:40:26.736213+00 |
| updated_at | 2025-12-04 09:40:26.736213+00 |
| description | Transformative Pure Rust CSS-in-RS solution for Leptos 0.8.14 with design tokens, components, modern CSS features, and exceptional developer experience |
| homepage | https://github.com/usvx/rustyle |
| repository | https://github.com/usvx/rustyle |
| max_upload_size | |
| id | 1966253 |
| size | 389,057 |
The Ultimate CSS-in-Rust Solution for Leptos 0.8.14
Rustyle 0.3.0 is the undisputed #1 CSS-in-Rust solution, delivering best-in-class features, unmatched developer experience, seamless Leptos integration, and zero-compromise performance.
lightningcss for CSS parsing:has(), :is(), :where() supportstyle_signal! macro - Full reactive styling with embedded Rust expressions, automatic signal dependency extractionAdd Rustyle to your Cargo.toml:
[dependencies]
rustyle-css = "0.3.0"
leptos = "0.8.14"
[features]
# Enable dev tools for development
dev = ["rustyle-css/dev"]
use leptos::*;
use rustyle_css::style;
#[component]
fn Button(cx: Scope) -> impl IntoView {
let class = style! {
.button {
background-color: #007bff;
color: white;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
&:hover {
background-color: #0056b3;
}
}
};
view! { cx,
<button class=class>"Click Me"</button>
}
}
use rustyle_css::{DesignTokens, ButtonStyle, Variant, Size};
let tokens = DesignTokens::default();
let button = ButtonStyle::new(Variant::Primary, Size::Medium);
let css = button.to_css();
use rustyle_css::{ButtonStyle, SelectStyle, BadgeStyle, AlertStyle, ProgressStyle, SpinnerStyle, Variant, Size, State};
// Button with variant and state
let button = ButtonStyle::new(Variant::Primary, Size::Large)
.state(State::Hover);
// Select dropdown
let select = SelectStyle::new(Variant::Primary, Size::Medium)
.state(State::Focus);
// Badge
let badge = BadgeStyle::new(Variant::Success, Size::Small);
// Alert
let alert = AlertStyle::new(Variant::Info, Size::Medium);
// Progress bar
let progress = ProgressStyle::new(Variant::Primary, Size::Medium);
// Loading spinner
let spinner = SpinnerStyle::new(Variant::Primary, Size::Large);
use leptos::*;
use rustyle_css::rustyle_macros::style_signal;
#[component]
fn Counter(cx: Scope) -> impl IntoView {
let (count, set_count) = create_signal(cx, 0);
// Style with embedded Rust expressions - updates automatically
let class = style_signal! {
.counter {
padding: 10px;
font-size: #{(count() * 2 + 16)}px;
color: #{if count() > 10 { "red" } else { "blue" }};
}
};
view! { cx,
<div class=class>
<button on:click=move |_| set_count.update(|c| *c += 1)>
"Count: " {count}
</button>
</div>
}
}
use rustyle_css::rustyle_macros::css_module;
// Load CSS module from file at compile time
let module = css_module!("styles/button.css");
let button_class = module.get("button");
style! - Scoped Styleslet class = style! {
.my-class {
color: red;
font-size: 16px;
}
};
style_with_vars! - Styles with CSS Variableslet theme = style_with_vars! {
--primary-color: blue;
--spacing: 10px;
.component {
color: var(--primary-color);
padding: var(--spacing);
}
};
global_style! - Global Stylesglobal_style! {
* {
box-sizing: border-box;
}
}
view_transition! - View Transitionsview_transition! {
.page {
view-transition-name: main-content;
}
}
scope_style! - @scope Rulesscope_style! {
@scope (.card) {
.title { color: blue; }
}
}
use rustyle_css::DesignTokens;
let tokens = DesignTokens::default();
// Or create custom tokens
let custom_tokens = DesignTokens::custom(
color_tokens,
spacing_tokens,
typography_tokens,
shadow_tokens,
border_tokens,
animation_tokens,
);
use rustyle_css::{ButtonStyle, CardStyle, InputStyle, Variant, Size, State};
// Button with variant and size
let button = ButtonStyle::new(Variant::Primary, Size::Medium);
// Card with elevation
let card = CardStyle::new(Size::Large).elevation("xl");
// Input with validation state
let input = InputStyle::new(Size::Medium)
.validation(ValidationState::Valid);
use rustyle_css::{Theme, ThemeManager, apply_theme, register_system_theme};
// Apply a theme
let theme = Theme::light();
apply_theme(&theme);
// Multi-theme support
let mut manager = ThemeManager::new(Theme::light());
manager.add_theme(Theme::dark());
manager.switch_to("dark");
// System theme detection
register_system_theme();
use rustyle_css::{register_focus_styles, register_reduced_motion, FocusStyle};
// Register focus styles
let focus_style = FocusStyle::new();
register_focus_styles(&focus_style);
// Register reduced motion support
register_reduced_motion();
use rustyle_css::{CssAssertions, CssLinter, ContrastLinter};
// CSS assertions
assert!(CssAssertions::assert_contains_property(css, "color"));
// Linting
let results = CssLinter::lint(css);
for result in results {
println!("{:?}: {}", result.severity, result.message);
}
See the examples/ directory for complete examples:
basic.rs - Basic styling exampletheming.rs - CSS variables and themingreactive.rs - Reactive component stylingssr_csr.rs - SSR/CSR compatibilitycomplete_app.rs - Complete application examplecontainer_queries.rs - Container queriestype_safe.rs - Type-safe utilitiesanimations.rs - Animations and keyframesresponsive.rs - Responsive designdesign_tokens.rs - Design tokens usagecomponents.rs - Component styles (Button, Card, Input)theming_advanced.rs - Advanced theming with multi-theme supportaccessibility.rs - Accessibility features demonstrationRustyle 0.2 maintains backward compatibility with 0.1.0 for basic usage. However, we recommend migrating to the new APIs:
DesignTokens for centralized design systemButtonStyle, CardStyle, etc.) instead of manual CSSThemeManager for multi-theme supportdev feature for development toolsLicensed under the Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
Contributions are welcome! Please feel free to submit a Pull Request.