mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(formatter_css): keep css-in-js placeholder as media type (#27639)
Part of #27572. Not fixed completely, just keeps placeholders in `@media` and `@import`.
This commit is contained in:
1 parent
372849ebd1
commit
99bb268da7
5 files changed
+109
-8
No files matched your search
@@ -0,0 +1,19 @@
|
||||
const mobile = "(max-width: 600px)";
|
||||
|
||||
export const A = styled.div`
|
||||
color: red;
|
||||
@media ${mobile} {
|
||||
color: blue;
|
||||
}
|
||||
`;
|
||||
|
||||
export const B = css`
|
||||
@media not ${a} { color: blue; }
|
||||
@media ${a} and (min-width: 1px) { color: blue; }
|
||||
@media ${a}, ${b} { color: blue; }
|
||||
`;
|
||||
|
||||
export const C = createGlobalStyle`
|
||||
@import url(x) ${a};
|
||||
@import url(x) screen, ${b};
|
||||
`;
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
## css-in-js
|
||||
|
||||
### Option 1: 21/23 (91.30%)
|
||||
### Option 1: 22/24 (91.67%)
|
||||
|
||||
```json
|
||||
{"printWidth":80}
|
||||
@@ -61,7 +61,7 @@
|
||||
- [externals/prettier/js/multiparser-css/styled-components.js](diffs/css-in-js/externals__prettier__js__multiparser-css__styled-components.js.md)
|
||||
- apps/oxfmt/DIVERGENCES.md#styled-extend-tag
|
||||
|
||||
### Option 2: 21/23 (91.30%)
|
||||
### Option 2: 22/24 (91.67%)
|
||||
|
||||
```json
|
||||
{"printWidth":100}
|
||||
|
||||
@@ -7,8 +7,8 @@ use cow_utils::CowUtils;
|
||||
use oxc_css_parser::{
|
||||
ast::{
|
||||
AtRule, AtRulePrelude, ComponentValue, CustomMediaValue, Ident, ImportPrelude,
|
||||
ImportPreludeHref, ImportPreludeSupports, ImportPreludeSupportsKind, InterpolableStr,
|
||||
KeyframesName, LessImportOptions, LessImportPrelude, MediaCondition,
|
||||
ImportPreludeHref, ImportPreludeSupports, ImportPreludeSupportsKind, InterpolableIdent,
|
||||
InterpolableStr, KeyframesName, LessImportOptions, LessImportPrelude, MediaCondition,
|
||||
MediaConditionAfterMediaType, MediaConditionKind, MediaFeature, MediaFeatureComparisonKind,
|
||||
MediaFeatureName, MediaInParens, MediaInParensKind, MediaQuery, MediaQueryList,
|
||||
NamespacePreludeUri, SassAtRootKind, SimpleBlock, SupportsAnd, SupportsCondition,
|
||||
@@ -35,7 +35,7 @@ use crate::{
|
||||
print::{
|
||||
CssFormatter, format_with, is_glued, normalize_whitespace, scss, selector, statement,
|
||||
value::{self, ValueContext},
|
||||
write_maybe_lowercase,
|
||||
write_maybe_lowercase, write_placeholder,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1488,8 +1488,10 @@ enum ImportWord<'b, 'a> {
|
||||
LessOptions(&'b LessImportOptions<'a>),
|
||||
Href(&'b ImportPreludeHref<'a>),
|
||||
Supports(&'b ImportPreludeSupports<'a>),
|
||||
/// A media keyword (`screen`, `and`, `not`): lowercased
|
||||
/// A media keyword (`only`, `and`, `not`): lowercased
|
||||
Keyword(oxc_span::Span),
|
||||
/// A media type (`screen`), see `write_media_type`
|
||||
MediaType(&'b InterpolableIdent<'a>),
|
||||
InParens(&'b MediaInParens<'a>),
|
||||
/// `and(...)` / `not(...)`: a function call to Prettier's value parser
|
||||
/// (keyword glued, the inside printed like any `(cond)`); `@media` reads it as one word
|
||||
@@ -1520,6 +1522,7 @@ fn write_import_words<'a>(comma_groups: &[Vec<ImportWord<'_, 'a>>], f: &mut CssF
|
||||
ImportWord::Href(href) => write_import_href(href, f),
|
||||
ImportWord::Supports(supports) => write_import_supports(supports, f),
|
||||
ImportWord::Keyword(span) => write_maybe_lowercase(source.text_for(span), f),
|
||||
ImportWord::MediaType(media_type) => write_media_type(media_type, f),
|
||||
ImportWord::InParens(in_parens) => write_media_in_parens(in_parens, f),
|
||||
ImportWord::GluedCall(keyword, in_parens) => {
|
||||
write_maybe_lowercase(source.text_for(&to_span(keyword.span())), f);
|
||||
@@ -1604,7 +1607,7 @@ fn push_media_query_list_words<'b, 'a>(
|
||||
if let Some(modifier) = &with_type.modifier {
|
||||
words.push(ImportWord::Keyword(to_span(modifier.span())));
|
||||
}
|
||||
words.push(ImportWord::Keyword(to_span(with_type.media_type.span())));
|
||||
words.push(ImportWord::MediaType(&with_type.media_type));
|
||||
if let Some(condition) = &with_type.condition {
|
||||
let kinds = &condition.condition.conditions;
|
||||
// `screen and(...)`: the glued `and` and the first parens are one word
|
||||
@@ -1948,7 +1951,9 @@ fn write_media_query<'a>(query: &MediaQuery<'a>, f: &mut CssFormatter<'_, 'a>) {
|
||||
write_word(to_span(modifier.span()), f);
|
||||
write!(f, space());
|
||||
}
|
||||
write_word(to_span(with_type.media_type.span()), f);
|
||||
value::write_with_comments(to_span(with_type.media_type.span()), query_end, f, |f| {
|
||||
write_media_type(&with_type.media_type, f);
|
||||
});
|
||||
if let Some(condition) = &with_type.condition {
|
||||
write!(f, space());
|
||||
// `screen and(max-width: 1px)`: the glued `and(...)` is one word
|
||||
@@ -1977,6 +1982,16 @@ fn write_media_query<'a>(query: &MediaQuery<'a>, f: &mut CssFormatter<'_, 'a>) {
|
||||
}
|
||||
}
|
||||
|
||||
/// A css-in-js placeholder stays typed, a keyword is lowercased.
|
||||
fn write_media_type<'a>(media_type: &InterpolableIdent<'a>, f: &mut CssFormatter<'_, 'a>) {
|
||||
if let InterpolableIdent::Placeholder(placeholder) = media_type {
|
||||
write_placeholder(placeholder, f);
|
||||
} else {
|
||||
let source = f.context().source_text();
|
||||
write_maybe_lowercase(source.text_for(&to_span(media_type.span())), f);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_media_condition<'a>(condition: &MediaCondition<'a>, f: &mut CssFormatter<'_, 'a>) {
|
||||
write_media_condition_from(condition, 0, f);
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
@media `PLACEHOLDER-0` {
|
||||
color: blue;
|
||||
}
|
||||
@media not `PLACEHOLDER-1` { color: blue; }
|
||||
@media `PLACEHOLDER-2` and (min-width: 1px) { color: blue; }
|
||||
@media `PLACEHOLDER-3`, `PLACEHOLDER-4` { color: blue; }
|
||||
@media `PLACEHOLDER-5` /* c */ and (min-width: 1px) { color: blue; }
|
||||
@import url(x) `PLACEHOLDER-6`;
|
||||
@import url(x) screen, `PLACEHOLDER-7`;
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
---
|
||||
source: crates/oxc_formatter_css/tests/fixtures/mod.rs
|
||||
---
|
||||
==================== Input ====================
|
||||
@media `PLACEHOLDER-0` {
|
||||
color: blue;
|
||||
}
|
||||
@media not `PLACEHOLDER-1` { color: blue; }
|
||||
@media `PLACEHOLDER-2` and (min-width: 1px) { color: blue; }
|
||||
@media `PLACEHOLDER-3`, `PLACEHOLDER-4` { color: blue; }
|
||||
@media `PLACEHOLDER-5` /* c */ and (min-width: 1px) { color: blue; }
|
||||
@import url(x) `PLACEHOLDER-6`;
|
||||
@import url(x) screen, `PLACEHOLDER-7`;
|
||||
|
||||
==================== Output ====================
|
||||
------------------
|
||||
{ printWidth: 80 }
|
||||
------------------
|
||||
@media `PLACEHOLDER-0` {
|
||||
color: blue;
|
||||
}
|
||||
@media not `PLACEHOLDER-1` {
|
||||
color: blue;
|
||||
}
|
||||
@media `PLACEHOLDER-2` and (min-width: 1px) {
|
||||
color: blue;
|
||||
}
|
||||
@media `PLACEHOLDER-3`, `PLACEHOLDER-4` {
|
||||
color: blue;
|
||||
}
|
||||
@media `PLACEHOLDER-5` /* c */ and (min-width: 1px) {
|
||||
color: blue;
|
||||
}
|
||||
@import url(x) `PLACEHOLDER-6`;
|
||||
@import url(x) screen, `PLACEHOLDER-7`;
|
||||
|
||||
-------------------
|
||||
{ printWidth: 100 }
|
||||
-------------------
|
||||
@media `PLACEHOLDER-0` {
|
||||
color: blue;
|
||||
}
|
||||
@media not `PLACEHOLDER-1` {
|
||||
color: blue;
|
||||
}
|
||||
@media `PLACEHOLDER-2` and (min-width: 1px) {
|
||||
color: blue;
|
||||
}
|
||||
@media `PLACEHOLDER-3`, `PLACEHOLDER-4` {
|
||||
color: blue;
|
||||
}
|
||||
@media `PLACEHOLDER-5` /* c */ and (min-width: 1px) {
|
||||
color: blue;
|
||||
}
|
||||
@import url(x) `PLACEHOLDER-6`;
|
||||
@import url(x) screen, `PLACEHOLDER-7`;
|
||||
|
||||
===================== End =====================
|
||||
Reference in new issue
Block a user