tailwind_css_fixes/modules/background/image/
mod.rs1use super::*;
2
3#[doc=include_str!("readme.md")]
4#[derive(Clone, Debug)]
5pub struct TailwindBackgroundImage {
6 kind: BgImageKind,
8 value: Option<UnitValue>,
10 is_negative: bool,
12}
13
14#[derive(Clone, Debug, PartialEq)]
15enum BgImageKind {
16 None,
17 Url,
18 Linear,
19 Radial,
20 Conic,
21}
22
23impl Display for TailwindBackgroundImage {
24 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
25 if self.is_negative {
26 write!(f, "-")?;
27 }
28
29 match (&self.kind, &self.value) {
30 (BgImageKind::None, _) => write!(f, "bg-none"),
31 (BgImageKind::Url, Some(val)) => write!(f, "bg-[url({})]", val),
32 (BgImageKind::Linear, Some(val)) => write!(f, "bg-linear-{}", val),
33 (BgImageKind::Radial, Some(val)) => write!(f, "bg-radial-{}", val),
34 (BgImageKind::Conic, Some(val)) => write!(f, "bg-conic-{}", val),
35 (BgImageKind::Linear, None) => write!(f, "bg-linear"),
36 (BgImageKind::Radial, None) => write!(f, "bg-radial"),
37 (BgImageKind::Conic, None) => write!(f, "bg-conic"),
38 _ => Ok(()), }
40 }
41}
42
43impl TailwindInstance for TailwindBackgroundImage {
44 fn attributes(&self, _: &TailwindBuilder) -> CssAttributes {
45 match &self.kind {
46 BgImageKind::None => css_attributes! { "background-image" => "none" },
47 BgImageKind::Url => {
48 let url_value = self.value.as_ref().unwrap().to_string();
49 css_attributes! { "background-image" => format!("url({})", url_value) }
50 }
51 BgImageKind::Linear | BgImageKind::Radial | BgImageKind::Conic => {
52 let gradient_type = match self.kind {
53 BgImageKind::Linear => "linear-gradient",
54 BgImageKind::Radial => "radial-gradient",
55 BgImageKind::Conic => "conic-gradient",
56 _ => unreachable!(),
57 };
58
59 let direction_or_angle = match self.value.as_ref() {
60 None => "in oklab".to_string(),
62 Some(UnitValue::Keyword(k)) if k.starts_with("to-") => {
64 let direction = k.strip_prefix("to-").unwrap_or(k);
65 let mut full_direction = String::new();
66 if direction.contains('t') { full_direction.push_str("top "); }
67 if direction.contains('b') { full_direction.push_str("bottom "); }
68 if direction.contains('l') { full_direction.push_str("left "); }
69 if direction.contains('r') { full_direction.push_str("right "); }
70 format!("to {} in oklab", full_direction.trim())
71 }
72 Some(value) => {
74 let inner_value = match value {
76 UnitValue::Arbitrary(a) => a.get_properties(),
77 _ => value.to_string()
78 };
79
80 if self.is_negative {
81 format!("calc({} * -1)", inner_value)
82 } else {
83 format!("{} in oklab", inner_value)
84 }
85 }
86 };
87
88 let image = match self.value.as_ref() {
90 Some(UnitValue::Arbitrary(_)) | Some(UnitValue::Number {..}) | Some(UnitValue::Length(_)) => {
91 format!("{}(var(--tw-gradient-stops, {}))", gradient_type, direction_or_angle)
92 },
93 _ => format!("{}(var(--tw-gradient-stops))", gradient_type)
94 };
95
96 css_attributes! {
97 "--tw-gradient-position" => direction_or_angle,
98 "background-image" => image
99 }
100 }
101 }
102 }
103}
104
105impl TailwindBackgroundImage {
106 pub fn parse(pattern: &[&str], arbitrary: &TailwindArbitrary, neg: Negative) -> Result<Self> {
107 let (kind, rest) = match pattern {
108 ["none"] => (BgImageKind::None, &pattern[1..]),
109 ["gradient", rest @ ..] | ["linear", rest @ ..] => (BgImageKind::Linear, rest),
110 ["radial", rest @ ..] => (BgImageKind::Radial, rest),
111 ["conic", rest @ ..] => (BgImageKind::Conic, rest),
112 [] if arbitrary.as_str().starts_with("url(") => (BgImageKind::Url, pattern),
113 _ => return syntax_error!("Unknown background-image pattern: {}", pattern.join("-")),
114 };
115
116 let value = match kind {
117 BgImageKind::None => None,
118 BgImageKind::Url => {
119 let url = arbitrary.as_str().strip_prefix("url(").and_then(|s| s.strip_suffix(')')).unwrap_or("");
120 Some(UnitValue::Keyword(url.to_string()))
121 }
122 BgImageKind::Linear
123 | BgImageKind::Radial
124 | BgImageKind::Conic => {
125 if rest.is_empty() && arbitrary.is_none() {
126 None
128 } else {
129 let joined = rest.join("-");
130 if joined.starts_with("to-") {
131 Some(UnitValue::Keyword(joined.replace("-b-r", "-br").replace("-b-l", "-bl").replace("-t-r", "-tr").replace("-t-l", "-tl")))
133 } else {
134 Some(UnitValue::negative_parser("bg-image", |_| false, false, false, false)(rest, arbitrary, neg)?)
137 }
138 }
139 }
140 };
141
142 Ok(Self { kind, value, is_negative: neg.0 })
143 }
144}