use crate::parser::CssProperty;
pub fn parse(utility: &str) -> Option<Vec<CssProperty>> {
if let Some(val) = utility.strip_prefix("rounded-") {
let value = match val {
"none" => "0px",
"sm" => "0.125rem",
"md" => "0.375rem",
"lg" => "0.5rem",
"xl" => "0.75rem",
"2xl" => "1rem",
"3xl" => "1.5rem",
"full" => "9999px",
"t-none" => {
return Some(vec![
CssProperty::new("border-top-left-radius", "0px"),
CssProperty::new("border-top-right-radius", "0px"),
])
}
"t-sm" => {
return Some(vec![
CssProperty::new("border-top-left-radius", "0.125rem"),
CssProperty::new("border-top-right-radius", "0.125rem"),
])
}
"t-md" => {
return Some(vec![
CssProperty::new("border-top-left-radius", "0.375rem"),
CssProperty::new("border-top-right-radius", "0.375rem"),
])
}
"t-lg" => {
return Some(vec![
CssProperty::new("border-top-left-radius", "0.5rem"),
CssProperty::new("border-top-right-radius", "0.5rem"),
])
}
"b-none" => {
return Some(vec![
CssProperty::new("border-bottom-left-radius", "0px"),
CssProperty::new("border-bottom-right-radius", "0px"),
])
}
"b-lg" => {
return Some(vec![
CssProperty::new("border-bottom-left-radius", "0.5rem"),
CssProperty::new("border-bottom-right-radius", "0.5rem"),
])
}
"l-lg" => {
return Some(vec![
CssProperty::new("border-top-left-radius", "0.5rem"),
CssProperty::new("border-bottom-left-radius", "0.5rem"),
])
}
"r-lg" => {
return Some(vec![
CssProperty::new("border-top-right-radius", "0.5rem"),
CssProperty::new("border-bottom-right-radius", "0.5rem"),
])
}
_ => return None,
};
return Some(vec![CssProperty::new("border-radius", value)]);
}
if utility == "rounded" {
return Some(vec![CssProperty::new("border-radius", "0.25rem")]);
}
if utility == "border" {
return Some(vec![CssProperty::new("border-width", "1px")]);
}
if let Some(val) = utility.strip_prefix("border-") {
let value = match val {
"0" => "0px",
"2" => "2px",
"4" => "4px",
"8" => "8px",
"t" | "r" | "b" | "l" => return Some(vec![CssProperty::new("border-width", "1px")]),
"t-0" | "r-0" | "b-0" | "l-0" => {
return Some(vec![CssProperty::new("border-width", "0px")])
}
"t-2" | "r-2" | "b-2" | "l-2" => {
return Some(vec![CssProperty::new("border-width", "2px")])
}
"solid" => return Some(vec![CssProperty::new("border-style", "solid")]),
"dashed" => return Some(vec![CssProperty::new("border-style", "dashed")]),
"dotted" => return Some(vec![CssProperty::new("border-style", "dotted")]),
"double" => return Some(vec![CssProperty::new("border-style", "double")]),
"hidden" => return Some(vec![CssProperty::new("border-style", "hidden")]),
"none" => return Some(vec![CssProperty::new("border-style", "none")]),
_ => return None,
};
return Some(vec![CssProperty::new("border-width", value)]);
}
if utility == "outline" {
return Some(vec![CssProperty::new("outline-style", "solid")]);
}
if utility == "outline-none" {
return Some(vec![
CssProperty::new("outline", "2px solid transparent"),
CssProperty::new("outline-offset", "2px"),
]);
}
if utility == "ring" {
return Some(vec![CssProperty::new(
"box-shadow",
"0 0 0 3px rgba(59, 130, 246, 0.5)",
)]);
}
if let Some(val) = utility.strip_prefix("ring-") {
let value = match val {
"0" => "0 0 0 0px",
"1" => "0 0 0 1px",
"2" => "0 0 0 2px",
"4" => "0 0 0 4px",
"8" => "0 0 0 8px",
"inset" => return Some(vec![CssProperty::new("--tw-ring-inset", "inset")]),
"offset-0" => return Some(vec![CssProperty::new("--tw-ring-offset-width", "0px")]),
"offset-1" => return Some(vec![CssProperty::new("--tw-ring-offset-width", "1px")]),
"offset-2" => return Some(vec![CssProperty::new("--tw-ring-offset-width", "2px")]),
"offset-4" => return Some(vec![CssProperty::new("--tw-ring-offset-width", "4px")]),
"offset-8" => return Some(vec![CssProperty::new("--tw-ring-offset-width", "8px")]),
_ => return None,
};
return Some(vec![CssProperty::new("box-shadow", value)]);
}
if let Some(val) = utility.strip_prefix("divide-x-") {
let width = match val {
"0" => "0px",
"2" => "2px",
"4" => "4px",
"8" => "8px",
"reverse" => return Some(vec![CssProperty::new("--tw-divide-x-reverse", "1")]),
_ => return None,
};
return Some(vec![
CssProperty::new("--tw-divide-x-reverse", "0"),
CssProperty::new(
"border-right-width",
&format!("calc({} * var(--tw-divide-x-reverse))", width),
),
CssProperty::new(
"border-left-width",
&format!("calc({} * calc(1 - var(--tw-divide-x-reverse)))", width),
),
]);
}
if utility == "divide-x" {
return Some(vec![
CssProperty::new("--tw-divide-x-reverse", "0"),
CssProperty::new(
"border-right-width",
"calc(1px * var(--tw-divide-x-reverse))",
),
CssProperty::new(
"border-left-width",
"calc(1px * calc(1 - var(--tw-divide-x-reverse)))",
),
]);
}
if let Some(val) = utility.strip_prefix("divide-y-") {
let width = match val {
"0" => "0px",
"2" => "2px",
"4" => "4px",
"8" => "8px",
"reverse" => return Some(vec![CssProperty::new("--tw-divide-y-reverse", "1")]),
_ => return None,
};
return Some(vec![
CssProperty::new("--tw-divide-y-reverse", "0"),
CssProperty::new(
"border-top-width",
&format!("calc({} * calc(1 - var(--tw-divide-y-reverse)))", width),
),
CssProperty::new(
"border-bottom-width",
&format!("calc({} * var(--tw-divide-y-reverse))", width),
),
]);
}
if utility == "divide-y" {
return Some(vec![
CssProperty::new("--tw-divide-y-reverse", "0"),
CssProperty::new(
"border-top-width",
"calc(1px * calc(1 - var(--tw-divide-y-reverse)))",
),
CssProperty::new(
"border-bottom-width",
"calc(1px * var(--tw-divide-y-reverse))",
),
]);
}
if let Some(val) = utility.strip_prefix("divide-") {
let style = match val {
"solid" => "solid",
"dashed" => "dashed",
"dotted" => "dotted",
"double" => "double",
"none" => "none",
_ => return None,
};
return Some(vec![CssProperty::new("border-style", style)]);
}
None
}
pub fn parse_arbitrary(prefix: &str, value: &str) -> Option<Vec<CssProperty>> {
let property = match prefix {
"rounded" => "border-radius",
"border" => "border-width",
_ => return None,
};
Some(vec![CssProperty::new(property, value)])
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rounded() {
let props = parse("rounded").unwrap();
assert_eq!(props[0].property, "border-radius");
assert_eq!(props[0].value, "0.25rem");
}
#[test]
fn test_rounded_lg() {
let props = parse("rounded-lg").unwrap();
assert_eq!(props[0].property, "border-radius");
assert_eq!(props[0].value, "0.5rem");
}
#[test]
fn test_rounded_full() {
let props = parse("rounded-full").unwrap();
assert_eq!(props[0].property, "border-radius");
assert_eq!(props[0].value, "9999px");
}
#[test]
fn test_border() {
let props = parse("border").unwrap();
assert_eq!(props[0].property, "border-width");
assert_eq!(props[0].value, "1px");
}
#[test]
fn test_border_2() {
let props = parse("border-2").unwrap();
assert_eq!(props[0].property, "border-width");
assert_eq!(props[0].value, "2px");
}
#[test]
fn test_ring() {
let props = parse("ring").unwrap();
assert_eq!(props[0].property, "box-shadow");
}
#[test]
fn test_ring_2() {
let props = parse("ring-2").unwrap();
assert_eq!(props[0].property, "box-shadow");
assert_eq!(props[0].value, "0 0 0 2px");
}
#[test]
fn test_divide_y() {
let props = parse("divide-y").unwrap();
assert!(props.len() >= 2);
}
#[test]
fn test_divide_x_2() {
let props = parse("divide-x-2").unwrap();
assert!(props.len() >= 2);
}
}