1pub fn linear_gradient(colors: &[&str], direction: &str) -> String {
3 format!("background: linear-gradient({}, {});", direction, colors.join(", "))
4}
5
6pub fn radial_gradient(colors: &[&str], shape: &str) -> String {
8 format!("background: radial-gradient({}, {});", shape, colors.join(", "))
9}
10
11pub fn box_shadow(x: i32, y: i32, blur: i32, spread: i32, color: &str) -> String {
13 format!("box-shadow: {}px {}px {}px {}px {};", x, y, blur, spread, color)
14}
15
16pub fn text_shadow(x: i32, y: i32, blur: i32, color: &str) -> String {
18 format!("text-shadow: {}px {}px {}px {};", x, y, blur, color)
19}
20
21pub fn border_radius(radii: &[u32]) -> String {
23 let vals: Vec<String> = radii.iter().map(|r| format!("{}px", r)).collect();
24 format!("border-radius: {};", vals.join(" "))
25}
26
27pub fn flexbox(direction: &str, justify: &str, align: &str, wrap: &str, gap: Option<&str>) -> String {
29 let mut lines = vec![
30 "display: flex".to_string(),
31 format!("flex-direction: {}", direction),
32 format!("justify-content: {}", justify),
33 format!("align-items: {}", align),
34 format!("flex-wrap: {}", wrap),
35 ];
36 if let Some(g) = gap { lines.push(format!("gap: {}", g)); }
37 lines.join(";\n") + ";"
38}
39
40pub fn grid(columns: u32, gap: &str, min_width: Option<&str>) -> String {
42 let col = match min_width {
43 Some(mw) => format!("repeat(auto-fit, minmax({}, 1fr))", mw),
44 None => format!("repeat({}, 1fr)", columns),
45 };
46 format!("display: grid;\ngrid-template-columns: {};\ngap: {};", col, gap)
47}
48
49pub fn transform(rotate: Option<f64>, scale: Option<f64>, tx: Option<f64>, ty: Option<f64>) -> String {
51 let mut parts = Vec::new();
52 if let Some(r) = rotate { parts.push(format!("rotate({}deg)", r)); }
53 if let Some(s) = scale { parts.push(format!("scale({})", s)); }
54 if let Some(x) = tx { parts.push(format!("translateX({}px)", x)); }
55 if let Some(y) = ty { parts.push(format!("translateY({}px)", y)); }
56 format!("transform: {};", parts.join(" "))
57}
58
59pub fn transition(property: &str, duration: &str, easing: &str, delay: Option<&str>) -> String {
61 let mut val = format!("{} {} {}", property, duration, easing);
62 if let Some(d) = delay { val.push(' '); val.push_str(d); }
63 format!("transition: {};", val)
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn test_linear_gradient() {
72 let css = linear_gradient(&["#ff0000", "#0000ff"], "to right");
73 assert!(css.contains("linear-gradient"));
74 assert!(css.contains("#ff0000"));
75 }
76
77 #[test]
78 fn test_box_shadow() {
79 let css = box_shadow(0, 4, 6, 0, "rgba(0,0,0,0.1)");
80 assert_eq!(css, "box-shadow: 0px 4px 6px 0px rgba(0,0,0,0.1);");
81 }
82
83 #[test]
84 fn test_border_radius() {
85 assert_eq!(border_radius(&[8]), "border-radius: 8px;");
86 assert_eq!(border_radius(&[8, 16]), "border-radius: 8px 16px;");
87 }
88
89 #[test]
90 fn test_grid() {
91 let css = grid(3, "1rem", None);
92 assert!(css.contains("repeat(3, 1fr)"));
93 }
94}