rustyle_css/css/
color.rs

1//! Type-safe color definitions
2//!
3//! Provides comprehensive color types including scales, semantic colors, and manipulation utilities.
4//!
5//! # Examples
6//!
7//! ```rust
8//! use rustyle_css::Color;
9//!
10//! // Create colors in different formats
11//! let hex_color = Color::hex("#007bff");
12//! let rgb_color = Color::rgb(0, 123, 255);
13//! let rgba_color = Color::rgba(0, 123, 255, 0.5);
14//! let named_color = Color::named("blue");
15//! let var_color = Color::var("--primary-color");
16//!
17//! // Convert to CSS
18//! assert_eq!(hex_color.to_css(), "#007bff");
19//! assert_eq!(rgb_color.to_css(), "rgb(0, 123, 255)");
20//!
21//! // Manipulate colors
22//! let lighter = hex_color.lighten(0.2);
23//! let darker = hex_color.darken(0.2);
24//! ```
25
26use crate::tokens::color::{ColorScale as TokenColorScale, SemanticColors as TokenSemanticColors};
27
28/// Represents a CSS color with type-safe operations
29///
30/// Supports multiple color formats: hex, RGB, RGBA, named colors, and CSS variables.
31/// Provides color manipulation methods like lighten, darken, and opacity adjustment.
32///
33/// # Examples
34///
35/// ```rust
36/// use rustyle_css::Color;
37///
38/// let primary = Color::hex("#007bff");
39/// let with_opacity = primary.with_opacity(0.5);
40/// ```
41#[derive(Clone, Debug)]
42pub enum Color {
43    /// Hex color (e.g., #007bff or #007bff80 for alpha)
44    Hex(String),
45    /// RGB color (red, green, blue)
46    Rgb(u8, u8, u8),
47    /// RGBA color (red, green, blue, alpha 0.0-1.0)
48    Rgba(u8, u8, u8, f32),
49    /// Named color (e.g., "red", "blue", "transparent")
50    Named(String),
51    /// CSS variable (e.g., var(--primary-color))
52    Var(String),
53}
54
55impl Color {
56    /// Create a hex color
57    pub fn hex(hex: &str) -> Self {
58        Self::Hex(hex.to_string())
59    }
60
61    /// Create an RGB color
62    pub fn rgb(r: u8, g: u8, b: u8) -> Self {
63        Self::Rgb(r, g, b)
64    }
65
66    /// Create an RGBA color
67    pub fn rgba(r: u8, g: u8, b: u8, a: f32) -> Self {
68        Self::Rgba(r, g, b, a)
69    }
70
71    /// Create a named color
72    pub fn named(name: &str) -> Self {
73        Self::Named(name.to_string())
74    }
75
76    /// Create a CSS variable color
77    pub fn var(name: &str) -> Self {
78        Self::Var(name.to_string())
79    }
80
81    /// Convert to CSS string
82    pub fn to_css(&self) -> String {
83        match self {
84            Color::Hex(hex) => hex.clone(),
85            Color::Rgb(r, g, b) => format!("rgb({}, {}, {})", r, g, b),
86            Color::Rgba(r, g, b, a) => format!("rgba({}, {}, {}, {})", r, g, b, a),
87            Color::Named(name) => name.clone(),
88            Color::Var(name) => format!("var({})", name),
89        }
90    }
91
92    /// Lighten a color by a percentage (0.0 to 1.0)
93    /// Note: This is a simplified implementation. For full color manipulation,
94    /// consider using a color library or CSS filters.
95    pub fn lighten(&self, amount: f32) -> Self {
96        match self {
97            Color::Rgb(r, g, b) => {
98                let r = (*r as f32 + (255.0 - *r as f32) * amount.min(1.0).max(0.0)) as u8;
99                let g = (*g as f32 + (255.0 - *g as f32) * amount.min(1.0).max(0.0)) as u8;
100                let b = (*b as f32 + (255.0 - *b as f32) * amount.min(1.0).max(0.0)) as u8;
101                Color::Rgb(r, g, b)
102            }
103            _ => self.clone(), // For other types, return as-is
104        }
105    }
106
107    /// Darken a color by a percentage (0.0 to 1.0)
108    pub fn darken(&self, amount: f32) -> Self {
109        match self {
110            Color::Rgb(r, g, b) => {
111                let r = (*r as f32 * (1.0 - amount.min(1.0).max(0.0))) as u8;
112                let g = (*g as f32 * (1.0 - amount.min(1.0).max(0.0))) as u8;
113                let b = (*b as f32 * (1.0 - amount.min(1.0).max(0.0))) as u8;
114                Color::Rgb(r, g, b)
115            }
116            _ => self.clone(),
117        }
118    }
119
120    /// Set the opacity of a color
121    pub fn with_opacity(&self, opacity: f32) -> Self {
122        match self {
123            Color::Rgb(r, g, b) => Color::Rgba(*r, *g, *b, opacity.min(1.0).max(0.0)),
124            Color::Rgba(r, g, b, _) => Color::Rgba(*r, *g, *b, opacity.min(1.0).max(0.0)),
125            _ => self.clone(),
126        }
127    }
128}
129
130/// Color scale from 50 (lightest) to 950 (darkest)
131/// Re-exported from tokens for convenience
132pub type ColorScale = TokenColorScale;
133
134/// Semantic colors for UI states
135/// Re-exported from tokens for convenience
136pub type SemanticColors = TokenSemanticColors;