Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: noValueAtRule css lint rule #3293

Merged
merged 12 commits into from
Jul 18, 2024
119 changes: 69 additions & 50 deletions crates/biome_configuration/src/linter/rules.rs

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions crates/biome_css_analyze/src/lint/nursery.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 72 additions & 0 deletions crates/biome_css_analyze/src/lint/nursery/no_value_at_rule.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use biome_analyze::{context::RuleContext, declare_lint_rule, Ast, Rule, RuleDiagnostic};
use biome_console::markup;
use biome_css_syntax::CssAtRule;
use biome_rowan::AstNode;

declare_lint_rule! {
/// Disallow use of `@value` rule in css modules.
///
/// Use of CSS variables is recommended instead of `@value` rule.
///
/// ## Examples
///
/// ### Invalid
///
/// ```css,expect_diagnostic
/// @value red: #FF0000;
/// ```
///
/// ### Valid
///
/// ```css
/// :root {
/// --red: #FF0000
/// }
///
/// p {
/// background-color: var(--red);
/// }
/// ```
///
pub NoValueAtRule {
version: "1.8.0",
name: "noValueAtRule",
language: "css",
recommended: false,
}
}

impl Rule for NoValueAtRule {
type Query = Ast<CssAtRule>;
type State = CssAtRule;
type Signals = Option<Self::State>;
type Options = ();

fn run(ctx: &RuleContext<Self>) -> Option<Self::State> {
let node = ctx.query();

if node.rule().ok()?.as_css_value_at_rule().is_some() {
return Some(node.clone());
}

None
}

fn diagnostic(_: &RuleContext<Self>, node: &Self::State) -> Option<RuleDiagnostic> {
let span = node.range();
Some(
RuleDiagnostic::new(
rule_category!(),
span,
markup! {
"Use of "<Emphasis>"@value"</Emphasis>" rule is disallowed"
},
)
.note(markup! {
"Using @value is not recommended, consider using CSS variables instead."
}).note(markup! {
"See "<Hyperlink href="https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties">"MDN web docs"</Hyperlink>" for more details."
}),
)
}
}
2 changes: 2 additions & 0 deletions crates/biome_css_analyze/src/options.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 11 additions & 2 deletions crates/biome_css_analyze/tests/spec_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ fn run_test(input: &'static str, _: &str, _: &str, _: &str) {
let mut snapshot = String::new();
let extension = input_file.extension().unwrap_or_default();

let parser_options = if file_name.ends_with(".module.css") {
CssParserOptions {
css_modules: true,
..CssParserOptions::default()
}
} else {
CssParserOptions::default()
};

let input_code = read_to_string(input_file)
.unwrap_or_else(|err| panic!("failed to read {input_file:?}: {err:?}"));
let quantity_diagnostics = if let Some(scripts) = scripts_from_json(extension, &input_code) {
Expand All @@ -55,7 +64,7 @@ fn run_test(input: &'static str, _: &str, _: &str, _: &str) {
file_name,
input_file,
CheckActionType::Lint,
CssParserOptions::default(),
parser_options,
);
}

Expand All @@ -72,7 +81,7 @@ fn run_test(input: &'static str, _: &str, _: &str, _: &str) {
file_name,
input_file,
CheckActionType::Lint,
CssParserOptions::default(),
parser_options,
)
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* css variables */
@value primary: #BF4040;
@value secondary: #1F4F7F;

/* breakpoints */
@value small: (max-width: 599px);
@value medium: (min-width: 600px) and (max-width: 959px);
@value large: (min-width: 960px);

/* alias paths for other values or composition */
@value colors: "./colors.css";
/* import multiple from a single file */
@value primary, secondary from colors;
/* make local aliases to imported values */
@value small as bp-small, large as bp-large from "./breakpoints.css";
/* value as selector name */
@value selectorValue: secondary-color;
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
---
source: crates/biome_css_analyze/tests/spec_tests.rs
expression: invalid.module.css
---
# Input
```css
/* css variables */
@value primary: #BF4040;
@value secondary: #1F4F7F;

/* breakpoints */
@value small: (max-width: 599px);
@value medium: (min-width: 600px) and (max-width: 959px);
@value large: (min-width: 960px);

/* alias paths for other values or composition */
@value colors: "./colors.css";
/* import multiple from a single file */
@value primary, secondary from colors;
/* make local aliases to imported values */
@value small as bp-small, large as bp-large from "./breakpoints.css";
/* value as selector name */
@value selectorValue: secondary-color;

```

# Diagnostics
```
invalid.module.css:2:1 lint/nursery/noValueAtRule ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Use of @value rule is disallowed

1 │ /* css variables */
> 2 │ @value primary: #BF4040;
│ ^^^^^^^^^^^^^^^^^^^^^^^^
3 │ @value secondary: #1F4F7F;
4 │

i Using @value is not recommended, consider using CSS variables instead.

i See MDN web docs for more details.


```

```
invalid.module.css:3:1 lint/nursery/noValueAtRule ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Use of @value rule is disallowed

1 │ /* css variables */
2 │ @value primary: #BF4040;
> 3 │ @value secondary: #1F4F7F;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^
4 │
5 │ /* breakpoints */

i Using @value is not recommended, consider using CSS variables instead.

i See MDN web docs for more details.


```

```
invalid.module.css:6:1 lint/nursery/noValueAtRule ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Use of @value rule is disallowed

5 │ /* breakpoints */
> 6 │ @value small: (max-width: 599px);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7 │ @value medium: (min-width: 600px) and (max-width: 959px);
8 │ @value large: (min-width: 960px);

i Using @value is not recommended, consider using CSS variables instead.

i See MDN web docs for more details.


```

```
invalid.module.css:7:1 lint/nursery/noValueAtRule ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Use of @value rule is disallowed

5 │ /* breakpoints */
6 │ @value small: (max-width: 599px);
> 7 │ @value medium: (min-width: 600px) and (max-width: 959px);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8 │ @value large: (min-width: 960px);
9 │

i Using @value is not recommended, consider using CSS variables instead.

i See MDN web docs for more details.


```

```
invalid.module.css:8:1 lint/nursery/noValueAtRule ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Use of @value rule is disallowed

6 │ @value small: (max-width: 599px);
7 │ @value medium: (min-width: 600px) and (max-width: 959px);
> 8 │ @value large: (min-width: 960px);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9 │
10 │ /* alias paths for other values or composition */

i Using @value is not recommended, consider using CSS variables instead.

i See MDN web docs for more details.


```

```
invalid.module.css:11:1 lint/nursery/noValueAtRule ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Use of @value rule is disallowed

10 │ /* alias paths for other values or composition */
> 11 │ @value colors: "./colors.css";
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12 │ /* import multiple from a single file */
13 │ @value primary, secondary from colors;

i Using @value is not recommended, consider using CSS variables instead.

i See MDN web docs for more details.


```

```
invalid.module.css:13:1 lint/nursery/noValueAtRule ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Use of @value rule is disallowed

11 │ @value colors: "./colors.css";
12 │ /* import multiple from a single file */
> 13 │ @value primary, secondary from colors;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14 │ /* make local aliases to imported values */
15 │ @value small as bp-small, large as bp-large from "./breakpoints.css";

i Using @value is not recommended, consider using CSS variables instead.

i See MDN web docs for more details.


```

```
invalid.module.css:15:1 lint/nursery/noValueAtRule ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Use of @value rule is disallowed

13 │ @value primary, secondary from colors;
14 │ /* make local aliases to imported values */
> 15 │ @value small as bp-small, large as bp-large from "./breakpoints.css";
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16 │ /* value as selector name */
17 │ @value selectorValue: secondary-color;

i Using @value is not recommended, consider using CSS variables instead.

i See MDN web docs for more details.


```

```
invalid.module.css:17:1 lint/nursery/noValueAtRule ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Use of @value rule is disallowed

15 │ @value small as bp-small, large as bp-large from "./breakpoints.css";
16 │ /* value as selector name */
> 17 │ @value selectorValue: secondary-color;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18 │

i Using @value is not recommended, consider using CSS variables instead.

i See MDN web docs for more details.


```
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@import "./colors.module.css";
:root {
--main-color: red;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
source: crates/biome_css_analyze/tests/spec_tests.rs
expression: valid.module.css
---
# Input
```css
@import "./colors.module.css";
:root {
--main-color: red;
}
```
1 change: 1 addition & 0 deletions crates/biome_diagnostics_categories/src/categories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ define_categories! {
"lint/nursery/noUnusedFunctionParameters": "https://biomejs.dev/linter/rules/no-unused-function-parameters",
"lint/nursery/noUselessStringConcat": "https://biomejs.dev/linter/rules/no-useless-string-concat",
"lint/nursery/noUselessUndefinedInitialization": "https://biomejs.dev/linter/rules/no-useless-undefined-initialization",
"lint/nursery/noValueAtRule": "https://biomejs.dev/linter/rules/no-value-at-rule",
"lint/nursery/noYodaExpression": "https://biomejs.dev/linter/rules/no-yoda-expression",
"lint/nursery/useAdjacentOverloadSignatures": "https://biomejs.dev/linter/rules/use-adjacent-overload-signatures",
"lint/nursery/useBiomeSuppressionComment": "https://biomejs.dev/linter/rules/use-biome-suppression-comment",
Expand Down
5 changes: 5 additions & 0 deletions packages/@biomejs/backend-jsonrpc/src/workspace.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading