Skip to content

Commit

Permalink
Merge branch 'master' of github.com:kpoelhekke/eslint-plugin-tailwind…
Browse files Browse the repository at this point in the history
…css into kpoelhekke-master

# Conflicts:
#	docs/rules/no-custom-classname.md
#	lib/rules/classnames-order.js
#	lib/rules/enforces-negative-arbitrary-values.js
#	lib/rules/enforces-shorthand.js
#	lib/rules/migration-from-tailwind-2.js
#	lib/rules/no-arbitrary-value.js
#	lib/rules/no-contradicting-classname.js
#	lib/rules/no-custom-classname.js
  • Loading branch information
francoismassart committed Dec 29, 2022
2 parents cbbf2db + 937659f commit b63351e
Show file tree
Hide file tree
Showing 19 changed files with 79 additions and 12 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/node_modules
.DS_Store
.idea
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ All these settings have nice default values that are explained in each rules' do
removeDuplicates: true,
skipClassAttribute: false,
whitelist: [],
tags: [],
classRegex: "^class(Name)?$" // can be modified to support custom attributes. E.g. "^tw$" for `twin.macro`
},
},
}
Expand Down
4 changes: 4 additions & 0 deletions docs/rules/classnames-order.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,7 @@ While, this will avoid linting the `class` and `className` attributes, it will s
### `tags` (default: `[]`)

Optional, if you are using tagged templates, you should provide the tags in this array.

### `classRegex` (default: `"^class(Name)?$"`)

Optional, can be used to support custom attribues
4 changes: 4 additions & 0 deletions docs/rules/enforces-negative-arbitrary-values.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,7 @@ While, this will avoid linting the `class` and `className` attributes, it will s
### `tags` (default: `[]`)

Optional, if you are using tagged templates, you should provide the tags in this array.

### `classRegex` (default: `"^class(Name)?$"`)

Optional, can be used to support custom attribues
4 changes: 4 additions & 0 deletions docs/rules/enforces-shorthand.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ While, this will avoid linting the `class` and `className` attributes, it will s

Optional, if you are using tagged templates, you should provide the tags in this array.

### `classRegex` (default: `"^class(Name)?$"`)

Optional, can be used to support custom attribues

## Further Reading

This rule will fix the issue for you.
4 changes: 4 additions & 0 deletions docs/rules/migration-from-tailwind-2.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,7 @@ While, this will avoid linting the `class` and `className` attributes, it will s
### `tags` (default: `[]`)

Optional, if you are using tagged templates, you should provide the tags in this array.

### `classRegex` (default: `"^class(Name)?$"`)

Optional, can be used to support custom attribues
4 changes: 4 additions & 0 deletions docs/rules/no-arbitrary-value.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ While, this will avoid linting the `class` and `className` attributes, it will s

Optional, if you are using tagged templates, you should provide the tags in this array.

### `classRegex` (default: `"^class(Name)?$"`)

Optional, can be used to support custom attribues

## Further Reading

This rule will not fix the issue for you because it cannot guess the correct class candidate.
4 changes: 4 additions & 0 deletions docs/rules/no-contradicting-classname.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ While, this will avoid linting the `class` and `className` attributes, it will s

Optional, if you are using tagged templates, you should provide the tags in this array.

### `classRegex` (default: `"^class(Name)?$"`)

Optional, can be used to support custom attribues

## Further Reading

This rule will not fix the issue but will let you know about the issue.
4 changes: 4 additions & 0 deletions docs/rules/no-custom-classname.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ e.g. I want to allow custom classnames while checking the validity of the `text-
];
```

### `classRegex` (default: `"^class(Name)?$"`)

Optional, can be used to support custom attribues

## Further Reading

This rule will not fix the issue but will let you know about the issue.
3 changes: 2 additions & 1 deletion lib/rules/classnames-order.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ module.exports = {
const skipClassAttribute = getOption(context, 'skipClassAttribute');
const tags = getOption(context, 'tags');
const twConfig = getOption(context, 'config');
const classRegex = getOption(context, 'classRegex');
const removeDuplicates = getOption(context, 'removeDuplicates');

const mergedConfig = customConfig.resolve(twConfig);
Expand Down Expand Up @@ -199,7 +200,7 @@ module.exports = {
//----------------------------------------------------------------------

const attributeVisitor = function (node) {
if (!astUtil.isClassAttribute(node) || skipClassAttribute) {
if (!astUtil.isClassAttribute(node, classRegex) || skipClassAttribute) {
return;
}
if (astUtil.isLiteralAttributeValue(node)) {
Expand Down
4 changes: 2 additions & 2 deletions lib/rules/enforces-negative-arbitrary-values.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const docsUrl = require('../util/docsUrl');
const customConfig = require('../util/customConfig');
const astUtil = require('../util/ast');
const groupUtil = require('../util/groupMethods');
const removeDuplicatesFromClassnamesAndWhitespaces = require('../util/removeDuplicatesFromClassnamesAndWhitespaces');
const getOption = require('../util/settings');
const parserUtil = require('../util/parser');

Expand Down Expand Up @@ -60,6 +59,7 @@ module.exports = {
const skipClassAttribute = getOption(context, 'skipClassAttribute');
const tags = getOption(context, 'tags');
const twConfig = getOption(context, 'config');
const classRegex = getOption(context, 'classRegex');

const mergedConfig = customConfig.resolve(twConfig);

Expand Down Expand Up @@ -145,7 +145,7 @@ module.exports = {
//----------------------------------------------------------------------

const attributeVisitor = function (node) {
if (!astUtil.isClassAttribute(node) || skipClassAttribute) {
if (!astUtil.isClassAttribute(node, classRegex) || skipClassAttribute) {
return;
}
if (astUtil.isLiteralAttributeValue(node)) {
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/enforces-shorthand.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ module.exports = {
const skipClassAttribute = getOption(context, 'skipClassAttribute');
const tags = getOption(context, 'tags');
const twConfig = getOption(context, 'config');
const classRegex = getOption(context, 'classRegex');

const mergedConfig = customConfig.resolve(twConfig);

Expand Down Expand Up @@ -374,7 +375,7 @@ module.exports = {
//----------------------------------------------------------------------

const attributeVisitor = function (node) {
if (!astUtil.isClassAttribute(node) || skipClassAttribute) {
if (!astUtil.isClassAttribute(node, classRegex) || skipClassAttribute) {
return;
}
if (astUtil.isLiteralAttributeValue(node)) {
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/migration-from-tailwind-2.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ module.exports = {
const skipClassAttribute = getOption(context, 'skipClassAttribute');
const tags = getOption(context, 'tags');
const twConfig = getOption(context, 'config');
const classRegex = getOption(context, 'classRegex');

const mergedConfig = customConfig.resolve(twConfig);

Expand Down Expand Up @@ -256,7 +257,7 @@ module.exports = {
//----------------------------------------------------------------------

const attributeVisitor = function (node) {
if (!astUtil.isClassAttribute(node) || skipClassAttribute) {
if (!astUtil.isClassAttribute(node, classRegex) || skipClassAttribute) {
return;
}
if (astUtil.isLiteralAttributeValue(node)) {
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/no-arbitrary-value.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ module.exports = {
const skipClassAttribute = getOption(context, 'skipClassAttribute');
const tags = getOption(context, 'tags');
const twConfig = getOption(context, 'config');
const classRegex = getOption(context, 'classRegex');

const mergedConfig = customConfig.resolve(twConfig);

Expand Down Expand Up @@ -144,7 +145,7 @@ module.exports = {
//----------------------------------------------------------------------

const attributeVisitor = function (node) {
if (!astUtil.isClassAttribute(node) || skipClassAttribute) {
if (!astUtil.isClassAttribute(node, classRegex) || skipClassAttribute) {
return;
}
if (astUtil.isLiteralAttributeValue(node)) {
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/no-contradicting-classname.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ module.exports = {
const skipClassAttribute = getOption(context, 'skipClassAttribute');
const tags = getOption(context, 'tags');
const twConfig = getOption(context, 'config');
const classRegex = getOption(context, 'classRegex');

const mergedConfig = customConfig.resolve(twConfig);

Expand Down Expand Up @@ -153,7 +154,7 @@ module.exports = {
//----------------------------------------------------------------------

const attributeVisitor = function (node) {
if (!astUtil.isClassAttribute(node) || skipClassAttribute) {
if (!astUtil.isClassAttribute(node, classRegex) || skipClassAttribute) {
return;
}
if (astUtil.isLiteralAttributeValue(node)) {
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/no-custom-classname.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ module.exports = {
const cssFiles = getOption(context, 'cssFiles');
const cssFilesRefreshRate = getOption(context, 'cssFilesRefreshRate');
const whitelist = getOption(context, 'whitelist');
const classRegex = getOption(context, 'classRegex');

const mergedConfig = customConfig.resolve(twConfig);
const contextFallback = // Set the created contextFallback in the cache if it does not exist yet.
Expand Down Expand Up @@ -138,7 +139,7 @@ module.exports = {
//----------------------------------------------------------------------

const attributeVisitor = function (node) {
if (!astUtil.isClassAttribute(node) || skipClassAttribute) {
if (!astUtil.isClassAttribute(node, classRegex) || skipClassAttribute) {
return;
}
if (astUtil.isLiteralAttributeValue(node)) {
Expand Down
10 changes: 6 additions & 4 deletions lib/util/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ const removeDuplicatesFromArray = require('./removeDuplicatesFromArray');
* Find out if node is `class` or `className`
*
* @param {ASTNode} node The AST node being checked
* @param {String} classRegex Regex to test the attribute that is being checked against
* @returns {Boolean}
*/
function isClassAttribute(node) {
function isClassAttribute(node, classRegex) {
if (!node.name) {
return false;
}
Expand All @@ -28,7 +29,7 @@ function isClassAttribute(node) {
default:
name = node.name.name;
}
return /^class(Name)?$/.test(name);
return new RegExp(classRegex).test(name);
}

/**
Expand Down Expand Up @@ -81,10 +82,11 @@ function isLiteralAttributeValue(node) {
* Find out if the node is a valid candidate for our rules
*
* @param {ASTNode} node The AST node being checked
* @param {String} classRegex Regex to test the attribute that is being checked against
* @returns {Boolean}
*/
function isValidJSXAttribute(node) {
if (!isClassAttribute(node)) {
function isValidJSXAttribute(node, classRegex) {
if (!isClassAttribute(node, classRegex)) {
// Only run for class[Name] attributes
return false;
}
Expand Down
2 changes: 2 additions & 0 deletions lib/util/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ function getOption(context, name) {
return [];
case 'whitelist':
return [];
case 'classRegex':
return "^class(Name)?$"
}
}

Expand Down
26 changes: 26 additions & 0 deletions tests/lib/rules/classnames-order.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ ruleTester.run("classnames-order", rule, {
{
code: `<div class="custom container box-content lg:box-border">Simple, basic</div>`,
},
{
code: `<div tw="custom container box-content lg:box-border">Simple, using 'tw' prop</div>`,
options: [
{
classRegex: "^tw$",
},
],
},
{
code: "<div className={ctl(`w-full p-10 ${live && 'bg-blue-100 dark:bg-purple-400 sm:rounded-lg'}`)}>ctl + exp</div>",
},
Expand All @@ -101,6 +109,14 @@ ruleTester.run("classnames-order", rule, {
{
code: `<div class="space-y-0.5 ">Extra space at the end</div>`,
},
{
code: `<div tw="space-y-0.5 ">Extra space at the end, but with 'tw' prop</div>`,
options: [
{
classRegex: "^tw$",
},
],
},
{
code: `<div class="p-5 sm:px-3 md:py-2 lg:p-4 xl:px-6">'p', then 'py' then 'px'</div>`,
},
Expand Down Expand Up @@ -310,6 +326,16 @@ ruleTester.run("classnames-order", rule, {
output: `<div class="p-4 sm:py-5 sm:px-7 lg:p-8">Enhancing readability</div>`,
errors: errors,
},
{
code: `<div tw="sm:py-5 p-4 sm:px-7 lg:p-8">Enhancing readability with 'tw' prop</div>`,
output: `<div tw="p-4 sm:py-5 sm:px-7 lg:p-8">Enhancing readability with 'tw' prop</div>`,
options: [
{
classRegex: "^tw$",
},
],
errors: errors,
},
{
code: `<div class="grid grid-cols-1 sm:grid-cols-2 sm:px-8 sm:py-12 sm:gap-x-8 md:py-16">:)...</div>`,
output: `<div class="grid grid-cols-1 sm:grid-cols-2 sm:gap-x-8 sm:px-8 sm:py-12 md:py-16">:)...</div>`,
Expand Down

0 comments on commit b63351e

Please sign in to comment.