Skip to content

Commit

Permalink
Fix unit-disallowed-list false negatives with percentages (#7018)
Browse files Browse the repository at this point in the history
* Fix `unit-disallowed-list` false negatives with percentages

* cleanup

* Create angry-mails-give.md

* cleanup
  • Loading branch information
romainmenke committed Jun 30, 2023
1 parent 3065425 commit 66c4d50
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/angry-mails-give.md
@@ -0,0 +1,5 @@
---
"stylelint": patch
---

Fixed: `unit-disallowed-list` false negatives with percentages
8 changes: 8 additions & 0 deletions lib/rules/unit-disallowed-list/__tests__/index.js
Expand Up @@ -641,6 +641,14 @@ testRule({
endLine: 1,
endColumn: 80,
},
{
code: 'a { color: rgb(10% 127 127) }',
message: messages.rejected('%'),
line: 1,
column: 18,
endLine: 1,
endColumn: 19,
},
],
});

Expand Down
19 changes: 12 additions & 7 deletions lib/rules/unit-disallowed-list/index.js
Expand Up @@ -119,7 +119,7 @@ const rule = (primary, secondaryOptions) => {

if (!hasDimension(params)) return;

parseFromTokens(tokenizeWithoutPercentageTokens(params)).forEach((mediaQuery) => {
parseFromTokens(tokenizeWithoutPercentages(params)).forEach((mediaQuery) => {
/** @type {{ mediaFeatureName: string | undefined }} */
const initialState = {
mediaFeatureName: undefined,
Expand Down Expand Up @@ -154,7 +154,7 @@ const rule = (primary, secondaryOptions) => {

if (!hasDimension(value)) return;

parseListOfComponentValues(tokenize({ css: value })).forEach((componentValue) => {
parseListOfComponentValues(tokenizeWithoutPercentages(value)).forEach((componentValue) => {
if (isTokenNode(componentValue)) {
check(
decl,
Expand Down Expand Up @@ -194,15 +194,20 @@ const rule = (primary, secondaryOptions) => {
};

/**
* @param {string} value
* In the CSS syntax percentages are a different token type than dimensions.
* For CSS authors however this distinction doesn't make sense, so we convert
* percentage tokens to dimension tokens with a unit of "%".
*
* Percentage tokens also aren't valid in media queries.
* Converting percentage tokens to dimension tokens simplifies any code checking for units.
*
* @param {string} css
* @returns {Array<import('@csstools/css-tokenizer').CSSToken>}
*/
function tokenizeWithoutPercentageTokens(value) {
return tokenize({ css: value }).map((x) => {
function tokenizeWithoutPercentages(css) {
return tokenize({ css }).map((x) => {
if (x[0] !== TokenType.Percentage) return x;

// Percentage values are not valid in media queries, so we can't parse them and get something valid back.
// Dimension tokens with a unit of "%" work just fine.
return [
TokenType.Dimension,
x[1],
Expand Down

0 comments on commit 66c4d50

Please sign in to comment.