Skip to content

Commit

Permalink
New plugin: new-color-vars-have-fallback (#376)
Browse files Browse the repository at this point in the history
* babys first solo stylelint plugin

* lint

* Create beige-cobras-reflect.md

* try adding severity

* fix tests
  • Loading branch information
langermank committed Nov 30, 2023
1 parent 4bc52ee commit a31e0d3
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/beige-cobras-reflect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/stylelint-config": minor
---

Adds new plugin: `new-color-vars-have-fallback` to check that if new Primitive v8 colors are used, they have a fallback value.
24 changes: 24 additions & 0 deletions __tests__/new-color-vars-have-fallback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const {ruleName} = require('../plugins/new-color-vars-have-fallback')

// eslint-disable-next-line no-undef
testRule({
plugins: ['./plugins/new-color-vars-have-fallback'],
customSyntax: 'postcss-scss',
ruleName,
config: [true],
accept: [
{
code: '.x { color: var(--fgColor-default, var(--color-fg-default)); }',
description: 'Variable has fallback',
},
],
reject: [
{
code: '.x { color: var(--fgColor-default); }',
message:
'Expected a fallback value for CSS variable --fgColor-default. New color variables fallbacks, check primer.style/primitives to find the correct value (primer/new-color-vars-have-fallback)',
line: 1,
column: 6,
},
],
})
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ module.exports = {
'./plugins/spacing',
'./plugins/typography',
'./plugins/utilities',
'./plugins/new-color-vars-have-fallback',
],
rules: {
'alpha-value-notation': 'number',
Expand Down Expand Up @@ -75,6 +76,7 @@ module.exports = {
'primer/spacing': true,
'primer/typography': true,
'primer/utilities': null,
'primer/new-color-vars-have-fallback': [true, {severity: 'error'}],
'scss/at-extend-no-missing-placeholder': true,
'scss/at-rule-no-unknown': true,
'scss/declaration-nested-properties-no-divided-groups': true,
Expand Down
52 changes: 52 additions & 0 deletions plugins/new-color-vars-have-fallback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const stylelint = require('stylelint')

const ruleName = 'primer/new-color-vars-have-fallback'
const messages = stylelint.utils.ruleMessages(ruleName, {
expectedFallback: variable =>
`Expected a fallback value for CSS variable ${variable}. New color variables fallbacks, check primer.style/primitives to find the correct value`,
})

const fs = require('fs')
const path = require('path')

const jsonFilePath = 'node_modules/@primer/primitives/tokens-next-private/docs/functional/themes/light.json'
let jsonContent

try {
const fileContent = fs.readFileSync(path.resolve(jsonFilePath), 'utf8')
jsonContent = JSON.parse(fileContent)
// console.log('JSON content:', jsonContent) // Log to see the content
} catch (error) {
// eslint-disable-next-line no-console
console.error('Error reading JSON file:', error)
}

module.exports = stylelint.createPlugin(ruleName, enabled => {
if (!enabled) {
return noop
}

return (root, result) => {
root.walkDecls(decl => {
for (const key of Object.keys(jsonContent)) {
if (decl.value.includes(`var(--${key})`)) {
// Check if the declaration uses a CSS variable from the JSON
const match = decl.value.match(/var\(--\w+,(.*)\)/)
if (!match || match[1].trim() === '') {
stylelint.utils.report({
ruleName,
result,
node: decl,
message: messages.expectedFallback(`--${key}`),
})
}
}
}
})
}
})

function noop() {}

module.exports.ruleName = ruleName
module.exports.messages = messages

0 comments on commit a31e0d3

Please sign in to comment.