mew_css/variable.rs
1//! # CSS Variables Module
2//!
3//! This module provides support for CSS custom properties (CSS variables) in the Mew CSS library.
4//! CSS variables allow you to define reusable values that can be referenced throughout your styles.
5//!
6//! ## Usage
7//!
8//! There are two main ways to use CSS variables:
9//!
10//! 1. **Defining variables** - Use the `set_var` method on `Style` to define a variable
11//! 2. **Using variables** - Use the `var` function to create a reference to a variable
12//!
13//! ## Example
14//!
15//! ```rust
16//! use mew_css::{style, var};
17//! use mew_css::values::Color;
18//!
19//! // Define CSS variables
20//! let root_style = style()
21//!     .set_var("primary-color", "#3366ff")
22//!     .set_var("spacing", "1rem")
23//!     .apply();
24//!
25//! // Use CSS variables
26//! let button_style = style()
27//!     .color(var("primary-color").into())
28//!     .padding(var("spacing").into())
29//!     .apply();
30//! ```
31
32use std::fmt;
33
34/// Represents a reference to a CSS custom property (CSS variable).
35///
36/// The `CssVar` struct allows you to reference CSS variables in your styles.
37/// When displayed, it formats the variable name as `var(--name)`, which is
38/// the correct syntax for using CSS variables in property values.
39///
40/// CSS variables provide a way to store values that can be reused throughout
41/// a document. They help maintain consistency and make it easier to update
42/// styles globally.
43///
44/// # Examples
45///
46/// ```rust
47/// use mew_css::variable::{CssVar, var};
48/// use mew_css::style;
49/// use mew_css::values::Color;
50///
51/// // Create a CSS variable reference
52/// let primary_color = CssVar::new("primary-color");
53///
54/// // Use it in a style
55/// let css = style()
56///     .color(Color::Var(primary_color))
57///     .apply();
58///
59/// assert_eq!(css, "color: var(--primary-color);");
60///
61/// // The shorter way using the `var` function and `into()`
62/// let css = style()
63///     .color(var("primary-color").into())
64///     .apply();
65///
66/// assert_eq!(css, "color: var(--primary-color);");
67/// ```
68#[derive(Debug, Clone, PartialEq)]
69pub struct CssVar(String);
70
71impl CssVar {
72    /// Creates a new CSS variable reference.
73    ///
74    /// This method creates a reference to a CSS variable that can be used in
75    /// property values. The variable name can be provided with or without the
76    /// `--` prefix; if it's missing, it will be added automatically.
77    ///
78    /// # Arguments
79    ///
80    /// * `name` - The variable name (with or without the `--` prefix)
81    ///
82    /// # Returns
83    ///
84    /// A new `CssVar` instance
85    ///
86    /// # Examples
87    ///
88    /// ```rust
89    /// use mew_css::variable::CssVar;
90    ///
91    /// // These are equivalent
92    /// let var1 = CssVar::new("primary-color");
93    /// let var2 = CssVar::new("--primary-color");
94    /// ```
95    pub fn new(name: &str) -> Self {
96        let trimmed = name.trim();
97        let name = if trimmed.starts_with("--") {
98            trimmed.to_string()
99        } else {
100            format!("--{}", trimmed)
101        };
102        Self(name)
103    }
104}
105
106impl fmt::Display for CssVar {
107    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108        write!(f, "var({})", self.0)
109    }
110}
111
112/// Creates a new CSS variable reference.
113///
114/// This is a convenience function that creates a new `CssVar` instance.
115/// It's a shorter alternative to calling `CssVar::new()`.
116///
117/// # Arguments
118///
119/// * `name` - The variable name (with or without the `--` prefix)
120///
121/// # Returns
122///
123/// A new `CssVar` instance
124///
125/// # Examples
126///
127/// ```rust
128/// use mew_css::variable::var;
129/// use mew_css::style;
130/// use mew_css::values::Color;
131///
132/// // Create a CSS variable reference
133/// let primary_color = var("primary-color");
134///
135/// // Use it in a style
136/// let css = style()
137///     .color(primary_color.into())
138///     .apply();
139///
140/// assert_eq!(css, "color: var(--primary-color);");
141/// ```
142pub fn var(name: &str) -> CssVar {
143    CssVar::new(name)
144}