From 6b5ac8bc8d4f7467f95de7deaf2871f90769e03f Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Mon, 12 Feb 2024 23:43:42 -0500 Subject: [PATCH] Handle light-dark with variables --- node/ast.d.ts | 11 +++++++++++ src/bundler.rs | 4 ++++ src/lib.rs | 12 ++++++++++++ src/properties/custom.rs | 39 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/node/ast.d.ts b/node/ast.d.ts index e33b6d58..05018418 100644 --- a/node/ast.d.ts +++ b/node/ast.d.ts @@ -1003,6 +1003,17 @@ export type UnresolvedColor = */ s: number; type: "hsl"; + } + | { + /** + * The dark value. + */ + dark: TokenOrValue[]; + /** + * The light value. + */ + light: TokenOrValue[]; + type: "light-dark"; }; /** * Defines where the class names referenced in the `composes` property are located. diff --git a/src/bundler.rs b/src/bundler.rs index a7d24083..d73545b8 100644 --- a/src/bundler.rs +++ b/src/bundler.rs @@ -766,6 +766,10 @@ fn visit_vars<'a, 'b>( UnresolvedColor::RGB { alpha, .. } | UnresolvedColor::HSL { alpha, .. } => { stack.push(alpha.0.iter_mut()); } + UnresolvedColor::LightDark { light, dark } => { + stack.push(light.0.iter_mut()); + stack.push(dark.0.iter_mut()); + } }, None => { stack.pop(); diff --git a/src/lib.rs b/src/lib.rs index 54f5f748..02218557 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27036,5 +27036,17 @@ mod tests { ..Browsers::default() } ); + prefix_test( + ".foo { color: light-dark(var(--light), var(--dark)); }", + indoc! { r#" + .foo { + color: var(--lightningcss-light, var(--light)) var(--lightningcss-dark, var(--dark)); + } + "#}, + Browsers { + chrome: Some(90 << 16), + ..Browsers::default() + } + ); } } diff --git a/src/properties/custom.rs b/src/properties/custom.rs index 5ca2c4b7..1e89c11c 100644 --- a/src/properties/custom.rs +++ b/src/properties/custom.rs @@ -509,7 +509,7 @@ fn try_parse_color_token<'i, 't>( input: &mut Parser<'i, 't>, ) -> Option { match_ignore_ascii_case! { &*f, - "rgb" | "rgba" | "hsl" | "hsla" | "hwb" | "lab" | "lch" | "oklab" | "oklch" | "color" | "color-mix" => { + "rgb" | "rgba" | "hsl" | "hsla" | "hwb" | "lab" | "lch" | "oklab" | "oklch" | "color" | "color-mix" | "light-dark" => { let s = input.state(); input.reset(&state); if let Ok(color) = CssColor::parse(input) { @@ -1518,6 +1518,14 @@ pub enum UnresolvedColor<'i> { #[cfg_attr(feature = "serde", serde(borrow))] alpha: TokenList<'i>, }, + /// The light-dark() function. + #[cfg_attr(feature = "serde", serde(rename = "light-dark"))] + LightDark { + /// The light value. + light: TokenList<'i>, + /// The dark value. + dark: TokenList<'i>, + } } impl<'i> UnresolvedColor<'i> { @@ -1550,6 +1558,16 @@ impl<'i> UnresolvedColor<'i> { Ok(UnresolvedColor::HSL { h, s, l, alpha }) }) }, + "light-dark" => { + input.parse_nested_block(|input| { + let light = input.parse_until_before(Delimiter::Comma, |input| + TokenList::parse(input, options, 0) + )?; + input.expect_comma()?; + let dark = TokenList::parse(input, options, 0)?; + Ok(UnresolvedColor::LightDark { light, dark }) + }) + }, _ => Err(input.new_custom_error(ParserError::InvalidValue)) } } @@ -1612,6 +1630,25 @@ impl<'i> UnresolvedColor<'i> { alpha.to_css(dest, is_custom_property)?; dest.write_char(')') } + UnresolvedColor::LightDark { light, dark } => { + if !dest.targets.is_compatible(crate::compat::Feature::LightDark) { + dest.write_str("var(--lightningcss-light")?; + dest.delim(',', false)?; + light.to_css(dest, is_custom_property)?; + dest.write_char(')')?; + dest.whitespace()?; + dest.write_str("var(--lightningcss-dark")?; + dest.delim(',', false)?; + dark.to_css(dest, is_custom_property)?; + return dest.write_char(')') + } + + dest.write_str("light-dark(")?; + light.to_css(dest, is_custom_property)?; + dest.delim(',', false)?; + dark.to_css(dest, is_custom_property)?; + dest.write_char(')') + } } } }