Skip to main content

peasy_css/
engine.rs

1/// Generate a CSS linear gradient.
2pub fn linear_gradient(colors: &[&str], direction: &str) -> String {
3    format!("background: linear-gradient({}, {});", direction, colors.join(", "))
4}
5
6/// Generate a CSS radial gradient.
7pub fn radial_gradient(colors: &[&str], shape: &str) -> String {
8    format!("background: radial-gradient({}, {});", shape, colors.join(", "))
9}
10
11/// Generate a CSS box shadow.
12pub 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
16/// Generate a CSS text shadow.
17pub 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
21/// Generate CSS border-radius.
22pub 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
27/// Generate CSS flexbox layout.
28pub 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
40/// Generate CSS grid layout.
41pub 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
49/// Generate CSS transform.
50pub 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
59/// Generate CSS transition.
60pub 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}