Skip to main content

react_rs_elements/
style.rs

1use std::collections::BTreeMap;
2
3#[derive(Debug, Clone, Default)]
4pub struct Style {
5    properties: BTreeMap<String, String>,
6}
7
8impl Style {
9    pub fn new() -> Self {
10        Self::default()
11    }
12
13    pub fn set(mut self, property: &str, value: &str) -> Self {
14        self.properties
15            .insert(property.to_string(), value.to_string());
16        self
17    }
18
19    pub fn display(self, value: &str) -> Self {
20        self.set("display", value)
21    }
22    pub fn position(self, value: &str) -> Self {
23        self.set("position", value)
24    }
25    pub fn width(self, value: &str) -> Self {
26        self.set("width", value)
27    }
28    pub fn height(self, value: &str) -> Self {
29        self.set("height", value)
30    }
31    pub fn max_width(self, value: &str) -> Self {
32        self.set("max-width", value)
33    }
34    pub fn min_height(self, value: &str) -> Self {
35        self.set("min-height", value)
36    }
37    pub fn margin(self, value: &str) -> Self {
38        self.set("margin", value)
39    }
40    pub fn margin_top(self, value: &str) -> Self {
41        self.set("margin-top", value)
42    }
43    pub fn margin_bottom(self, value: &str) -> Self {
44        self.set("margin-bottom", value)
45    }
46    pub fn padding(self, value: &str) -> Self {
47        self.set("padding", value)
48    }
49    pub fn background(self, value: &str) -> Self {
50        self.set("background", value)
51    }
52    pub fn background_color(self, value: &str) -> Self {
53        self.set("background-color", value)
54    }
55    pub fn color(self, value: &str) -> Self {
56        self.set("color", value)
57    }
58    pub fn font_size(self, value: &str) -> Self {
59        self.set("font-size", value)
60    }
61    pub fn font_weight(self, value: &str) -> Self {
62        self.set("font-weight", value)
63    }
64    pub fn font_family(self, value: &str) -> Self {
65        self.set("font-family", value)
66    }
67    pub fn line_height(self, value: &str) -> Self {
68        self.set("line-height", value)
69    }
70    pub fn text_align(self, value: &str) -> Self {
71        self.set("text-align", value)
72    }
73    pub fn border(self, value: &str) -> Self {
74        self.set("border", value)
75    }
76    pub fn border_radius(self, value: &str) -> Self {
77        self.set("border-radius", value)
78    }
79    pub fn box_shadow(self, value: &str) -> Self {
80        self.set("box-shadow", value)
81    }
82    pub fn cursor(self, value: &str) -> Self {
83        self.set("cursor", value)
84    }
85    pub fn overflow(self, value: &str) -> Self {
86        self.set("overflow", value)
87    }
88    pub fn opacity(self, value: &str) -> Self {
89        self.set("opacity", value)
90    }
91    pub fn transition(self, value: &str) -> Self {
92        self.set("transition", value)
93    }
94    pub fn transform(self, value: &str) -> Self {
95        self.set("transform", value)
96    }
97    pub fn gap(self, value: &str) -> Self {
98        self.set("gap", value)
99    }
100    pub fn flex(self, value: &str) -> Self {
101        self.set("flex", value)
102    }
103    pub fn flex_direction(self, value: &str) -> Self {
104        self.set("flex-direction", value)
105    }
106    pub fn align_items(self, value: &str) -> Self {
107        self.set("align-items", value)
108    }
109    pub fn justify_content(self, value: &str) -> Self {
110        self.set("justify-content", value)
111    }
112    pub fn grid_template_columns(self, value: &str) -> Self {
113        self.set("grid-template-columns", value)
114    }
115
116    pub fn to_css(&self) -> String {
117        self.properties
118            .iter()
119            .map(|(k, v)| format!("{}: {}", k, v))
120            .collect::<Vec<_>>()
121            .join("; ")
122    }
123}
124
125pub fn style() -> Style {
126    Style::new()
127}
128
129#[cfg(test)]
130mod tests {
131    use super::*;
132
133    #[test]
134    fn test_style_builder() {
135        let s = style().display("flex").gap("10px").padding("20px");
136        assert_eq!(s.to_css(), "display: flex; gap: 10px; padding: 20px");
137    }
138
139    #[test]
140    fn test_style_empty() {
141        let s = style();
142        assert_eq!(s.to_css(), "");
143    }
144
145    #[test]
146    fn test_style_single() {
147        let s = style().color("#333");
148        assert_eq!(s.to_css(), "color: #333");
149    }
150
151    #[test]
152    fn test_style_complex() {
153        let s = style()
154            .display("grid")
155            .grid_template_columns("1fr 1fr")
156            .gap("16px")
157            .padding("24px")
158            .background_color("#f8f9fa")
159            .border_radius("8px");
160        let css = s.to_css();
161        assert!(css.contains("display: grid"));
162        assert!(css.contains("grid-template-columns: 1fr 1fr"));
163        assert!(css.contains("border-radius: 8px"));
164    }
165}