Skip to content

Commit

Permalink
Add ignore: ["with-var-inside"] to color-function-notation (#6802)
Browse files Browse the repository at this point in the history
Closes #6620.

---------

Co-authored-by: Masafumi Koba <473530+ybiquitous@users.noreply.github.com>
  • Loading branch information
mattxwang and ybiquitous committed Apr 20, 2023
1 parent b089a42 commit fffbb4c
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/popular-jeans-tap.md
@@ -0,0 +1,5 @@
---
"stylelint": minor
---

Added: `ignore: ["with-var-inside"]` to `color-function-notation`
34 changes: 34 additions & 0 deletions lib/rules/color-function-notation/README.md
Expand Up @@ -116,3 +116,37 @@ a { color: hsla(270, 60%, 50%, 15%) }
```css
a { color: hsl(.75turn, 60%, 70%) }
```

## Optional secondary options

### `ignore: ["with-var-inside"]`

Ignore color functions containing variables.

Given:

```json
["modern", { "ignore": ["with-var-inside"] }]
```

The following patterns are _not_ considered problems:

```css
a {
color: rgba(var(--foo), 0.5);
}
```

Given:

```json
["legacy", { "ignore": ["with-var-inside"] }]
```

The following patterns are _not_ considered problems:

```css
a {
color: rgba(var(--foo) / 0.5);
}
```
30 changes: 30 additions & 0 deletions lib/rules/color-function-notation/__tests__/index.js
Expand Up @@ -461,6 +461,36 @@ testRule({
],
});

testRule({
ruleName,
config: ['modern', { ignore: 'with-var-inside' }],
fix: true,

accept: [
{
code: 'a { color: rgba(var(--bar), 0.5); }',
},
{
code: 'a { color: rgba(VaR(--bar), 0.5); }',
},
],
});

testRule({
ruleName,
config: ['legacy', { ignore: 'with-var-inside' }],
fix: true,

accept: [
{
code: 'a { color: rgb(var(--foo) / 0.5); }',
},
{
code: 'a { color: rgb(VaR(--foo) / 0.5); }',
},
],
});

testRule({
ruleName,
customSyntax: 'postcss-scss',
Expand Down
35 changes: 30 additions & 5 deletions lib/rules/color-function-notation/index.js
Expand Up @@ -10,6 +10,7 @@ const ruleMessages = require('../../utils/ruleMessages');
const setDeclarationValue = require('../../utils/setDeclarationValue');
const { isValueFunction } = require('../../utils/typeGuards');
const validateOptions = require('../../utils/validateOptions');
const optionsMatches = require('../../utils/optionsMatches');

const ruleName = 'color-function-notation';

Expand All @@ -26,15 +27,28 @@ const LEGACY_FUNCS = new Set(['rgba', 'hsla']);
const LEGACY_NOTATION_FUNCS = new Set(['rgb', 'rgba', 'hsl', 'hsla']);

/** @type {import('stylelint').Rule} */
const rule = (primary, _secondaryOptions, context) => {
const rule = (primary, secondaryOptions, context) => {
return (root, result) => {
const validOptions = validateOptions(result, ruleName, {
actual: primary,
possible: ['modern', 'legacy'],
});
const validOptions = validateOptions(
result,
ruleName,
{
actual: primary,
possible: ['modern', 'legacy'],
},
{
actual: secondaryOptions,
possible: {
ignore: ['with-var-inside'],
},
optional: true,
},
);

if (!validOptions) return;

const ignoreWithVarInside = optionsMatches(secondaryOptions, 'ignore', 'with-var-inside');

root.walkDecls((decl) => {
let needsFix = false;
const parsedValue = valueParser(getDeclarationValue(decl));
Expand All @@ -46,6 +60,10 @@ const rule = (primary, _secondaryOptions, context) => {

const { value, sourceIndex, sourceEndIndex, nodes } = node;

if (ignoreWithVarInside && containsVariable(nodes)) {
return;
}

if (!LEGACY_NOTATION_FUNCS.has(value.toLowerCase())) return;

if (primary === 'modern' && !hasCommas(node)) return;
Expand Down Expand Up @@ -112,6 +130,13 @@ function atLeastOneSpace(whitespace) {
return whitespace !== '' ? whitespace : ' ';
}

/**
* @param {import('postcss-value-parser').Node[]} nodes
*/
function containsVariable(nodes) {
return nodes.some(({ type, value }) => type === 'function' && value.toLowerCase() === 'var');
}

/**
* @param {import('postcss-value-parser').Node} node
* @returns {node is import('postcss-value-parser').DivNode}
Expand Down

0 comments on commit fffbb4c

Please sign in to comment.