rustyle-css

Crates.iorustyle-css
lib.rsrustyle-css
version0.3.0
created_at2025-12-04 09:40:26.736213+00
updated_at2025-12-04 09:40:26.736213+00
descriptionTransformative Pure Rust CSS-in-RS solution for Leptos 0.8.14 with design tokens, components, modern CSS features, and exceptional developer experience
homepagehttps://github.com/usvx/rustyle
repositoryhttps://github.com/usvx/rustyle
max_upload_size
id1966253
size389,057
(usvx)

documentation

README

Rustyle 0.3.0

Crates.io Documentation

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.

Features

Core Features

  • Compile-time CSS processing - Zero runtime overhead for static styles
  • Automatic scoped styles - Unique class names prevent style conflicts
  • Full SSR/CSR support - Works seamlessly in both server-side and client-side rendering
  • Type-safe class names - Compile-time validation of CSS syntax
  • CSS nesting support - Write nested CSS like modern preprocessors
  • Pure Rust implementation - Uses lightningcss for CSS parsing

Design System & Tokens

  • Comprehensive design token system - Colors, spacing, typography, shadows, borders, animations
  • Type-safe color scales - 50-950 color scales with semantic colors
  • Component system - Pre-built Button, Card, and Input components with variants
  • Multi-theme support - Light/dark themes with smooth transitions
  • System theme detection - Automatic dark/light mode support

Modern CSS Features (2025)

  • View Transitions API - Smooth page transitions
  • Advanced selectors - :has(), :is(), :where() support
  • @scope and @starting-style - Modern CSS scoping and entry animations
  • CSS Grid Subgrid - Full grid system with subgrid support
  • Container queries - Type-safe container query builders

Performance & Optimization

  • Complete Critical CSS extraction - Real HTML/DOM parsing, selector matching, and route-based splitting
  • Complete Tree Shaking - Unused CSS removal with component-level analysis
  • Advanced minification - Dead code elimination using lightningcss
  • Optimized Style Registry - Thread-safe DashMap for concurrent access
  • CSS optimization - Automatic vendor prefixing and browser targeting

Reactive Styling

  • Complete style_signal! macro - Full reactive styling with embedded Rust expressions, automatic signal dependency extraction
  • Full Leptos signal integration - Reactive styles that update with signals
  • Zero-overhead when signals don't change - Optimized reactive updates
  • Animation state management - State-driven animations
  • Dynamic style builders - Runtime style generation when needed

Developer Experience

  • Intelligent Error System - Enhanced error messages with exact source locations, visual code snippets, multiple ranked suggestions, and quick-fix actions
  • Enhanced Hot Module Replacement - Incremental updates, state preservation, and change notifications
  • Advanced Debugging Tools - Style inspector with real-time visualization, component style tree, and performance profiling
  • Comprehensive CSS Linting - 50+ accessibility, performance, and best practice rules with auto-fix capabilities
  • Complete CSS Modules - Full file system support, build-time compilation, and type-safe class accessors
  • Testing utilities - CSS validation and style testing helpers

Accessibility

  • Focus management - Automatic focus-visible styles
  • Reduced motion support - Respects user preferences
  • Color contrast checking - WCAG AA/AAA validation

Advanced Features

  • Style composition - Mixins and style inheritance
  • Runtime style generation - Type-safe dynamic style builders

Installation

Add 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"]

Quick Start

Basic Usage

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>
    }
}

Using Design Tokens

use rustyle_css::{DesignTokens, ButtonStyle, Variant, Size};

let tokens = DesignTokens::default();
let button = ButtonStyle::new(Variant::Primary, Size::Medium);
let css = button.to_css();

Using Components

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);

Reactive Styling

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>
    }
}

CSS Modules

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");

API Reference

Macros

style! - Scoped Styles

let class = style! {
    .my-class {
        color: red;
        font-size: 16px;
    }
};

style_with_vars! - Styles with CSS Variables

let theme = style_with_vars! {
    --primary-color: blue;
    --spacing: 10px;
    
    .component {
        color: var(--primary-color);
        padding: var(--spacing);
    }
};

global_style! - Global Styles

global_style! {
    * {
        box-sizing: border-box;
    }
}

view_transition! - View Transitions

view_transition! {
    .page {
        view-transition-name: main-content;
    }
}

scope_style! - @scope Rules

scope_style! {
    @scope (.card) {
        .title { color: blue; }
    }
}

Design Tokens

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,
);

Components

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);

Theming

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();

Accessibility

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();

Testing & Linting

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);
}

Examples

See the examples/ directory for complete examples:

  • basic.rs - Basic styling example
  • theming.rs - CSS variables and theming
  • reactive.rs - Reactive component styling
  • ssr_csr.rs - SSR/CSR compatibility
  • complete_app.rs - Complete application example
  • container_queries.rs - Container queries
  • type_safe.rs - Type-safe utilities
  • animations.rs - Animations and keyframes
  • responsive.rs - Responsive design
  • design_tokens.rs - Design tokens usage
  • components.rs - Component styles (Button, Card, Input)
  • theming_advanced.rs - Advanced theming with multi-theme support
  • accessibility.rs - Accessibility features demonstration

Migration from 0.1.0

Rustyle 0.2 maintains backward compatibility with 0.1.0 for basic usage. However, we recommend migrating to the new APIs:

  • Use DesignTokens for centralized design system
  • Use component styles (ButtonStyle, CardStyle, etc.) instead of manual CSS
  • Use ThemeManager for multi-theme support
  • Enable dev feature for development tools

Requirements

  • Rust 1.85.0 or later (for edition 2024)
  • Leptos 0.8.14

License

Licensed under the Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Repository

https://github.com/usvx/rustyle

Commit count: 0

cargo fmt