rustyle_css/tokens/
shadow.rs

1//! Shadow token system
2//!
3//! Provides an elevation system using box shadows.
4
5/// Shadow definition
6#[derive(Clone, Debug)]
7pub struct Shadow {
8    /// Shadow offset X
9    pub offset_x: String,
10    /// Shadow offset Y
11    pub offset_y: String,
12    /// Shadow blur radius
13    pub blur: String,
14    /// Shadow spread radius
15    pub spread: String,
16    /// Shadow color
17    pub color: String,
18}
19
20impl Shadow {
21    /// Create a new shadow
22    pub fn new(offset_x: &str, offset_y: &str, blur: &str, spread: &str, color: &str) -> Self {
23        Self {
24            offset_x: offset_x.to_string(),
25            offset_y: offset_y.to_string(),
26            blur: blur.to_string(),
27            spread: spread.to_string(),
28            color: color.to_string(),
29        }
30    }
31
32    /// Convert to CSS string
33    pub fn to_css(&self) -> String {
34        format!(
35            "{} {} {} {} {}",
36            self.offset_x, self.offset_y, self.blur, self.spread, self.color
37        )
38    }
39}
40
41/// Elevation levels using shadows
42#[derive(Clone, Debug)]
43pub struct ShadowTokens {
44    pub none: Shadow,
45    pub sm: Shadow,
46    pub md: Shadow,
47    pub lg: Shadow,
48    pub xl: Shadow,
49    pub xl2: Shadow,
50    pub inner: Shadow,
51}
52
53impl ShadowTokens {
54    /// Create new shadow tokens
55    pub fn new(
56        none: Shadow,
57        sm: Shadow,
58        md: Shadow,
59        lg: Shadow,
60        xl: Shadow,
61        xl2: Shadow,
62        inner: Shadow,
63    ) -> Self {
64        Self {
65            none,
66            sm,
67            md,
68            lg,
69            xl,
70            xl2,
71            inner,
72        }
73    }
74
75    /// Get shadow by name
76    pub fn get(&self, name: &str) -> &Shadow {
77        match name {
78            "none" => &self.none,
79            "sm" => &self.sm,
80            "md" => &self.md,
81            "lg" => &self.lg,
82            "xl" => &self.xl,
83            "2xl" | "xl2" => &self.xl2,
84            "inner" => &self.inner,
85            _ => &self.none,
86        }
87    }
88
89    /// Convert shadow tokens to CSS custom properties
90    pub fn to_css_vars(&self) -> String {
91        format!(
92            "  --shadow-none: {};\n  --shadow-sm: {};\n  --shadow-md: {};\n  --shadow-lg: {};\n  --shadow-xl: {};\n  --shadow-2xl: {};\n  --shadow-inner: {};\n",
93            self.none.to_css(),
94            self.sm.to_css(),
95            self.md.to_css(),
96            self.lg.to_css(),
97            self.xl.to_css(),
98            self.xl2.to_css(),
99            self.inner.to_css(),
100        )
101    }
102}
103
104impl Default for ShadowTokens {
105    fn default() -> Self {
106        Self {
107            none: Shadow::new("0", "0", "0", "0", "transparent"),
108            sm: Shadow::new("0", "1px", "2px", "0", "rgba(0, 0, 0, 0.05)"),
109            md: Shadow::new("0", "4px", "6px", "-1px", "rgba(0, 0, 0, 0.1)"),
110            lg: Shadow::new("0", "10px", "15px", "-3px", "rgba(0, 0, 0, 0.1)"),
111            xl: Shadow::new("0", "20px", "25px", "-5px", "rgba(0, 0, 0, 0.1)"),
112            xl2: Shadow::new("0", "25px", "50px", "-12px", "rgba(0, 0, 0, 0.25)"),
113            inner: Shadow::new("inset", "0", "2px", "4px", "rgba(0, 0, 0, 0.06)"),
114        }
115    }
116}