From 1214d003b216a3015c0181804ac5fe1e267a2694 Mon Sep 17 00:00:00 2001
From: Dennis
Date: Wed, 30 Nov 2022 16:36:43 +0100
Subject: [PATCH 1/4] feat: Classnames plugin handles key and value other way
around
---
lib/util/ast.js | 10 +-
tests/lib/rules/no-custom-classname.js | 733 +++++++++++++------------
2 files changed, 391 insertions(+), 352 deletions(-)
diff --git a/lib/util/ast.js b/lib/util/ast.js
index 225f2ba1..ae62098f 100644
--- a/lib/util/ast.js
+++ b/lib/util/ast.js
@@ -209,7 +209,15 @@ function parseNodeRecursive(node, arg, cb, skipConditional = false, isolate = fa
return;
case 'ObjectExpression':
arg.properties.forEach((prop) => {
- parseNodeRecursive(node, prop.key, cb, skipConditional, forceIsolation);
+ const isUsedByClassNamesPlugin = node.callee && node.callee.name === 'classnames';
+
+ parseNodeRecursive(
+ node,
+ isUsedByClassNamesPlugin ? prop.key : prop.value,
+ cb,
+ skipConditional,
+ forceIsolation
+ );
});
return;
case 'Literal':
diff --git a/tests/lib/rules/no-custom-classname.js b/tests/lib/rules/no-custom-classname.js
index 2430e749..59905cf0 100644
--- a/tests/lib/rules/no-custom-classname.js
+++ b/tests/lib/rules/no-custom-classname.js
@@ -67,20 +67,20 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
- Layout utilities
- Container
- Box Sizing
- Display
- Floats
- Clear
- Isolation
- Object Fit
- Overflow
- Overscroll Behavior
- Position
- Visibility
- `,
+
+ Layout utilities
+ Container
+ Box Sizing
+ Display
+ Floats
+ Clear
+ Isolation
+ Object Fit
+ Overflow
+ Overscroll Behavior
+ Position
+ Visibility
+ `,
},
{
code: `Columns
`,
@@ -117,230 +117,230 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
- Flexbox & Grid
- Flex Basis
- Flex Direction
- Flex Wrap
- Flex
- Flex Grow
- Flex Shrink
- Order
-
- Grid Column Start / End
- Grid Template Rows
- Grid Row Start / End
- Grid Auto Flow
- Grid Auto Columns
- Grid Auto Rows
- Gap
- Justify Content
- Justify Items
- Justify Self
- Align Content
- Align Items
- Align Self
- Place Content
- Place Items
- Place Self
- `,
+
+ Flexbox & Grid
+ Flex Basis
+ Flex Direction
+ Flex Wrap
+ Flex
+ Flex Grow
+ Flex Shrink
+ Order
+
+ Grid Column Start / End
+ Grid Template Rows
+ Grid Row Start / End
+ Grid Auto Flow
+ Grid Auto Columns
+ Grid Auto Rows
+ Gap
+ Justify Content
+ Justify Items
+ Justify Self
+ Align Content
+ Align Items
+ Align Self
+ Place Content
+ Place Items
+ Place Self
+ `,
},
{
code: `
-
- Spacing
- Padding
- Margin
- Space Between
- `,
+
+ Spacing
+ Padding
+ Margin
+ Space Between
+ `,
},
{
code: `
-
- Sizing
- Width
- Min-Width
- Max-Width
- Height
- Min-Height
- Max-Height
-
- `,
+
+ Sizing
+ Width
+ Min-Width
+ Max-Width
+ Height
+ Min-Height
+ Max-Height
+
+ `,
},
{
code: `
-
- Typography
- Font Family
- Font Size
- Font Smoothing
- Font Style
-
- Font Variant Numeric
- Letter Spacing
- Line Height
- List Style Type
- List Style Position
- Text Alignment
- Text Color
- Text Decoration
- Text Decoration Color
- Text Decoration Style
- Text Decoration Thickness
- Text Underline Offset
- Text Transform
- Text Overflow
- Text Indent
- Vertical Alignment
- Whitespace
- Word Break
- Content
- `,
+
+ Typography
+ Font Family
+ Font Size
+ Font Smoothing
+ Font Style
+
+ Font Variant Numeric
+ Letter Spacing
+ Line Height
+ List Style Type
+ List Style Position
+ Text Alignment
+ Text Color
+ Text Decoration
+ Text Decoration Color
+ Text Decoration Style
+ Text Decoration Thickness
+ Text Underline Offset
+ Text Transform
+ Text Overflow
+ Text Indent
+ Vertical Alignment
+ Whitespace
+ Word Break
+ Content
+ `,
},
{
code: `
-
- Backgrounds
- Background Attachment
- Background Clip
- Background Color
- Background Origin
- Background Position
- Background Repeat
- Background Size
- Background Image
- Gradient Color Stops
- `,
+
+ Backgrounds
+ Background Attachment
+ Background Clip
+ Background Color
+ Background Origin
+ Background Position
+ Background Repeat
+ Background Size
+ Background Image
+ Gradient Color Stops
+ `,
},
{
code: `
-
- Borders
- Border Radius
- Border Width
- Border Color
- Border Style
- Divide Width
- Divide Color
- Divide Style
- Outline Width
- Outline Color
- Outline Style
- Outline Offset
- Ring Width
- Ring Color
- Ring Offset Width
- Ring Offset Color
- `,
+
+ Borders
+ Border Radius
+ Border Width
+ Border Color
+ Border Style
+ Divide Width
+ Divide Color
+ Divide Style
+ Outline Width
+ Outline Color
+ Outline Style
+ Outline Offset
+ Ring Width
+ Ring Color
+ Ring Offset Width
+ Ring Offset Color
+ `,
},
{
code: `
-
- Effects
- Box Shadow
- Box Shadow Color
- Opacity
- Mix Blend Mode
- Background Blend Mode
- `,
+
+ Effects
+ Box Shadow
+ Box Shadow Color
+ Opacity
+ Mix Blend Mode
+ Background Blend Mode
+ `,
},
{
code: `
-
- Filters
- Blur
- Brightness
- Contrast
- Drop Shadow
- Grayscale
- Hue Rotate
- Invert
- Saturate
- Sepia
- Backdrop Blur
- Backdrop Brightness
- Backdrop Contrast
- Backdrop Grayscale
- Backdrop Hue Rotate
- Backdrop Invert
- Backdrop Opacity
- Backdrop Saturate
- Backdrop Sepia
- `,
+
+ Filters
+ Blur
+ Brightness
+ Contrast
+ Drop Shadow
+ Grayscale
+ Hue Rotate
+ Invert
+ Saturate
+ Sepia
+ Backdrop Blur
+ Backdrop Brightness
+ Backdrop Contrast
+ Backdrop Grayscale
+ Backdrop Hue Rotate
+ Backdrop Invert
+ Backdrop Opacity
+ Backdrop Saturate
+ Backdrop Sepia
+ `,
},
{
code: `
-
- Tables
- Border Collapse
- Table Layout
- `,
+
+ Tables
+ Border Collapse
+ Table Layout
+ `,
},
{
code: `
-
- Transitions & Animation
- Transition Property
- Transition Duration
- Transition Timing Function
- Transition Delay
- Animation
- `,
+
+ Transitions & Animation
+ Transition Property
+ Transition Duration
+ Transition Timing Function
+ Transition Delay
+ Animation
+ `,
},
{
code: `
-
- Transforms
- Scale
- Rotate
- Translate
- Skew
- Transform Origin
- `,
+
+ Transforms
+ Scale
+ Rotate
+ Translate
+ Skew
+ Transform Origin
+ `,
},
{
code: `
-
- Interactivity
- Accent Color
- Appearance
- Cursor
- Caret Color
- Pointer Events
- Resize
- Scroll Behavior
- Scroll Margin
- Scroll Padding
- Scroll Snap Align
- Scroll Snap Stop
- Scroll Snap Type
- Touch Action
- User Select
- Will Change
- `,
+
+ Interactivity
+ Accent Color
+ Appearance
+ Cursor
+ Caret Color
+ Pointer Events
+ Resize
+ Scroll Behavior
+ Scroll Margin
+ Scroll Padding
+ Scroll Snap Align
+ Scroll Snap Stop
+ Scroll Snap Type
+ Touch Action
+ User Select
+ Will Change
+ `,
},
{
code: `
-
- SVG
- Fill
- Stroke
- Stroke Width
- `,
+
+ SVG
+ Fill
+ Stroke
+ Stroke Width
+ `,
},
{
code: `
-
- Accessibility
- Screen Readers
- `,
+
+ Accessibility
+ Screen Readers
+ `,
},
{
code: `
- `,
+ `,
},
{
code: `Only Tailwind CSS classnames
`,
@@ -349,14 +349,14 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
- ctl(\`
- sm:w-6
- w-8
- container
- w-12
- flex
- lg:w-4
- \`);`,
+ ctl(\`
+ sm:w-6
+ w-8
+ container
+ w-12
+ flex
+ lg:w-4
+ \`);`,
},
{
code: `Only Tailwind CSS classnames
`,
@@ -419,16 +419,16 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
-
New Project
-
Create a new project from a variety of starting templates.
-
`,
+
+
New Project
+
Create a new project from a variety of starting templates.
+
`,
},
{
code: `
-
- from css file
-
`,
+
+ from css file
+
`,
options: [
{
cssFiles: ["./tests/**/*.css"],
@@ -437,96 +437,96 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
- myTag\`
- sm:w-6
- w-8
- container
- w-12
- flex
- lg:w-4
- \`;`,
+ myTag\`
+ sm:w-6
+ w-8
+ container
+ w-12
+ flex
+ lg:w-4
+ \`;`,
options: [{ tags: ["myTag"] }],
},
{
code: `
- `,
+ `,
},
{
code: `
-
-
-
-
-
-
2
-
3
+
+
+
+
+
+
2
+
3
+
+
+
+
+
-
-
-
-
-
- `,
+ `,
},
{
code: `
-
- `,
+
+ `,
},
{
code: `
-
- aspect-none is a valid classname
-
`,
+
+ aspect-none is a valid classname
+
`,
},
{
code: `
-
- font-mono is a valid classname
-
`,
+
+ font-mono is a valid classname
+
`,
},
{
code: `
-
Arbitrary alpha suffix
`,
+
Arbitrary alpha suffix
`,
},
{
code: `
-
Important modifier
`,
+
Important modifier
`,
},
{
code: `
-
`,
+
`,
},
{
code: `
-
`,
+
`,
},
{
code: `
-
Negative value with custom config
`,
+
Negative value with custom config
`,
options: [
{
config: {
@@ -541,11 +541,11 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
Disabling transform
`,
+
Disabling transform
`,
},
{
code: `
-
Nasty prefix
`,
+
Nasty prefix
`,
options: [
{
config: {
@@ -556,7 +556,7 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
Issue #101
`,
+
Issue #101
`,
options: [
{
config: {
@@ -573,7 +573,7 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
Issue #100
`,
+
Issue #100
`,
options: [
{
config: {
@@ -591,14 +591,14 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
Using
-
HTML
`,
+
Using
+
HTML
`,
parser: require.resolve("@angular-eslint/template-parser"),
},
{
code: `
-
Using HTML
-
With nasty prefix
`,
+
Using HTML
+
With nasty prefix
`,
options: [
{
config: {
@@ -610,50 +610,50 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
Deprecated classnames yet still supported for now
`,
+
Deprecated classnames yet still supported for now
`,
},
{
code: `
-
Negative arbitrary value
`,
+
Negative arbitrary value
`,
},
{
code: `
-
- https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/97
-
`,
+
+ https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/97
+
`,
options: [
{
config: {
@@ -664,25 +664,25 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
Issue #130
`,
+
Issue #130
`,
},
{
code: `
-
- Issue #148
- https://github.com/tailwindlabs/tailwindcss/releases/tag/v3.1.0
-
`,
+
+ Issue #148
+ https://github.com/tailwindlabs/tailwindcss/releases/tag/v3.1.0
+
`,
},
{
code: `
-
- Support for plugins
-
Not prose
-
-
-
-
Line clamp
-
`,
+
+ Support for plugins
+
Not prose
+
+
+
+
Line clamp
+
`,
options: [
{
config: {
@@ -697,10 +697,10 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
-
Hello, world!
-
- `,
+
+
Hello, world!
+
+ `,
options: [
{
config: {
@@ -711,9 +711,9 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
- https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/145
-
`,
+
+ https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/145
+
`,
options: [
{
config: {
@@ -739,11 +739,11 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
-
PRIMARY using a function
-
SECONDARY using a function
-
See https://github.com/adamwathan/tailwind-css-variable-text-opacity-demo
-
`,
+
+
PRIMARY using a function
+
SECONDARY using a function
+
See https://github.com/adamwathan/tailwind-css-variable-text-opacity-demo
+
`,
options: [
{
config: {
@@ -775,21 +775,21 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
- grid-flow-dense, mix-blend-plus-lighter
-
`,
+
+ grid-flow-dense, mix-blend-plus-lighter
+
`,
},
{
code: `
-
- border-spacing
-
`,
+
+ border-spacing
+
`,
},
{
code: `
No errors while typing
`,
@@ -862,6 +862,37 @@ ruleTester.run("no-custom-classname", rule, {
\`);`,
errors: generateErrors("hello world"),
},
+ {
+ code: `
+ cva({
+ variants: {
+ variant: {
+ primary: ["sm:w-6 w-8 container w-12 flex lg:w-4 hello"],
+ primary: ["sm:w-6 w-8 container w-12 flex lg:w-4 world"],
+ },
+ },
+ });
+ `,
+ options: [
+ {
+ callees: ["cva"],
+ },
+ ],
+ errors: generateErrors("hello world"),
+ },
+ {
+ code: `
+ cva({
+ primary: ["sm:w-6 w-8 container w-12 flex lg:w-4 hello"],
+ });
+ `,
+ options: [
+ {
+ callees: ["cva"],
+ },
+ ],
+ errors: generateErrors("hello"),
+ },
{
code: `
Only Tailwind CSS classnames
`,
options: [
From faeb0903306ae6e48f14e70161e106b95ebaeb33 Mon Sep 17 00:00:00 2001
From: Dennis
Date: Thu, 1 Dec 2022 08:04:51 +0100
Subject: [PATCH 2/4] fix: Formatting
---
tests/lib/rules/no-custom-classname.js | 764 ++++++++++++-------------
1 file changed, 382 insertions(+), 382 deletions(-)
diff --git a/tests/lib/rules/no-custom-classname.js b/tests/lib/rules/no-custom-classname.js
index 59905cf0..5540692c 100644
--- a/tests/lib/rules/no-custom-classname.js
+++ b/tests/lib/rules/no-custom-classname.js
@@ -67,20 +67,20 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
- Layout utilities
- Container
- Box Sizing
- Display
- Floats
- Clear
- Isolation
- Object Fit
- Overflow
- Overscroll Behavior
- Position
- Visibility
- `,
+
+ Layout utilities
+ Container
+ Box Sizing
+ Display
+ Floats
+ Clear
+ Isolation
+ Object Fit
+ Overflow
+ Overscroll Behavior
+ Position
+ Visibility
+ `,
},
{
code: `Columns
`,
@@ -117,230 +117,230 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
- Flexbox & Grid
- Flex Basis
- Flex Direction
- Flex Wrap
- Flex
- Flex Grow
- Flex Shrink
- Order
-
- Grid Column Start / End
- Grid Template Rows
- Grid Row Start / End
- Grid Auto Flow
- Grid Auto Columns
- Grid Auto Rows
- Gap
- Justify Content
- Justify Items
- Justify Self
- Align Content
- Align Items
- Align Self
- Place Content
- Place Items
- Place Self
- `,
+
+ Flexbox & Grid
+ Flex Basis
+ Flex Direction
+ Flex Wrap
+ Flex
+ Flex Grow
+ Flex Shrink
+ Order
+
+ Grid Column Start / End
+ Grid Template Rows
+ Grid Row Start / End
+ Grid Auto Flow
+ Grid Auto Columns
+ Grid Auto Rows
+ Gap
+ Justify Content
+ Justify Items
+ Justify Self
+ Align Content
+ Align Items
+ Align Self
+ Place Content
+ Place Items
+ Place Self
+ `,
},
{
code: `
-
- Spacing
- Padding
- Margin
- Space Between
- `,
+
+ Spacing
+ Padding
+ Margin
+ Space Between
+ `,
},
{
code: `
-
- Sizing
- Width
- Min-Width
- Max-Width
- Height
- Min-Height
- Max-Height
-
- `,
+
+ Sizing
+ Width
+ Min-Width
+ Max-Width
+ Height
+ Min-Height
+ Max-Height
+
+ `,
},
{
code: `
-
- Typography
- Font Family
- Font Size
- Font Smoothing
- Font Style
-
- Font Variant Numeric
- Letter Spacing
- Line Height
- List Style Type
- List Style Position
- Text Alignment
- Text Color
- Text Decoration
- Text Decoration Color
- Text Decoration Style
- Text Decoration Thickness
- Text Underline Offset
- Text Transform
- Text Overflow
- Text Indent
- Vertical Alignment
- Whitespace
- Word Break
- Content
- `,
+
+ Typography
+ Font Family
+ Font Size
+ Font Smoothing
+ Font Style
+
+ Font Variant Numeric
+ Letter Spacing
+ Line Height
+ List Style Type
+ List Style Position
+ Text Alignment
+ Text Color
+ Text Decoration
+ Text Decoration Color
+ Text Decoration Style
+ Text Decoration Thickness
+ Text Underline Offset
+ Text Transform
+ Text Overflow
+ Text Indent
+ Vertical Alignment
+ Whitespace
+ Word Break
+ Content
+ `,
},
{
code: `
-
- Backgrounds
- Background Attachment
- Background Clip
- Background Color
- Background Origin
- Background Position
- Background Repeat
- Background Size
- Background Image
- Gradient Color Stops
- `,
+
+ Backgrounds
+ Background Attachment
+ Background Clip
+ Background Color
+ Background Origin
+ Background Position
+ Background Repeat
+ Background Size
+ Background Image
+ Gradient Color Stops
+ `,
},
{
code: `
-
- Borders
- Border Radius
- Border Width
- Border Color
- Border Style
- Divide Width
- Divide Color
- Divide Style
- Outline Width
- Outline Color
- Outline Style
- Outline Offset
- Ring Width
- Ring Color
- Ring Offset Width
- Ring Offset Color
- `,
+
+ Borders
+ Border Radius
+ Border Width
+ Border Color
+ Border Style
+ Divide Width
+ Divide Color
+ Divide Style
+ Outline Width
+ Outline Color
+ Outline Style
+ Outline Offset
+ Ring Width
+ Ring Color
+ Ring Offset Width
+ Ring Offset Color
+ `,
},
{
code: `
-
- Effects
- Box Shadow
- Box Shadow Color
- Opacity
- Mix Blend Mode
- Background Blend Mode
- `,
+
+ Effects
+ Box Shadow
+ Box Shadow Color
+ Opacity
+ Mix Blend Mode
+ Background Blend Mode
+ `,
},
{
code: `
-
- Filters
- Blur
- Brightness
- Contrast
- Drop Shadow
- Grayscale
- Hue Rotate
- Invert
- Saturate
- Sepia
- Backdrop Blur
- Backdrop Brightness
- Backdrop Contrast
- Backdrop Grayscale
- Backdrop Hue Rotate
- Backdrop Invert
- Backdrop Opacity
- Backdrop Saturate
- Backdrop Sepia
- `,
+
+ Filters
+ Blur
+ Brightness
+ Contrast
+ Drop Shadow
+ Grayscale
+ Hue Rotate
+ Invert
+ Saturate
+ Sepia
+ Backdrop Blur
+ Backdrop Brightness
+ Backdrop Contrast
+ Backdrop Grayscale
+ Backdrop Hue Rotate
+ Backdrop Invert
+ Backdrop Opacity
+ Backdrop Saturate
+ Backdrop Sepia
+ `,
},
{
code: `
-
- Tables
- Border Collapse
- Table Layout
- `,
+
+ Tables
+ Border Collapse
+ Table Layout
+ `,
},
{
code: `
-
- Transitions & Animation
- Transition Property
- Transition Duration
- Transition Timing Function
- Transition Delay
- Animation
- `,
+
+ Transitions & Animation
+ Transition Property
+ Transition Duration
+ Transition Timing Function
+ Transition Delay
+ Animation
+ `,
},
{
code: `
-
- Transforms
- Scale
- Rotate
- Translate
- Skew
- Transform Origin
- `,
+
+ Transforms
+ Scale
+ Rotate
+ Translate
+ Skew
+ Transform Origin
+ `,
},
{
code: `
-
- Interactivity
- Accent Color
- Appearance
- Cursor
- Caret Color
- Pointer Events
- Resize
- Scroll Behavior
- Scroll Margin
- Scroll Padding
- Scroll Snap Align
- Scroll Snap Stop
- Scroll Snap Type
- Touch Action
- User Select
- Will Change
- `,
+
+ Interactivity
+ Accent Color
+ Appearance
+ Cursor
+ Caret Color
+ Pointer Events
+ Resize
+ Scroll Behavior
+ Scroll Margin
+ Scroll Padding
+ Scroll Snap Align
+ Scroll Snap Stop
+ Scroll Snap Type
+ Touch Action
+ User Select
+ Will Change
+ `,
},
{
code: `
-
- SVG
- Fill
- Stroke
- Stroke Width
- `,
+
+ SVG
+ Fill
+ Stroke
+ Stroke Width
+ `,
},
{
code: `
-
- Accessibility
- Screen Readers
- `,
+
+ Accessibility
+ Screen Readers
+ `,
},
{
code: `
- `,
+ `,
},
{
code: `Only Tailwind CSS classnames
`,
@@ -349,14 +349,14 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
- ctl(\`
- sm:w-6
- w-8
- container
- w-12
- flex
- lg:w-4
- \`);`,
+ ctl(\`
+ sm:w-6
+ w-8
+ container
+ w-12
+ flex
+ lg:w-4
+ \`);`,
},
{
code: `Only Tailwind CSS classnames
`,
@@ -419,16 +419,16 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
-
New Project
-
Create a new project from a variety of starting templates.
-
`,
+
+
New Project
+
Create a new project from a variety of starting templates.
+
`,
},
{
code: `
-
- from css file
-
`,
+
+ from css file
+
`,
options: [
{
cssFiles: ["./tests/**/*.css"],
@@ -437,96 +437,96 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
- myTag\`
- sm:w-6
- w-8
- container
- w-12
- flex
- lg:w-4
- \`;`,
+ myTag\`
+ sm:w-6
+ w-8
+ container
+ w-12
+ flex
+ lg:w-4
+ \`;`,
options: [{ tags: ["myTag"] }],
},
{
code: `
- `,
+ `,
},
{
code: `
-
-
-
-
-
-
2
-
3
-
+
+
+
+
+
+
2
+
3
-
-
-
-
- `,
+
+
+
+
+
+ `,
},
{
code: `
-
- `,
+
+ `,
},
{
code: `
-
- aspect-none is a valid classname
-
`,
+
+ aspect-none is a valid classname
+
`,
},
{
code: `
-
- font-mono is a valid classname
-
`,
+
+ font-mono is a valid classname
+
`,
},
{
code: `
-
Arbitrary alpha suffix
`,
+
Arbitrary alpha suffix
`,
},
{
code: `
-
Important modifier
`,
+
Important modifier
`,
},
{
code: `
-
`,
+
`,
},
{
code: `
-
`,
+
`,
},
{
code: `
-
Negative value with custom config
`,
+
Negative value with custom config
`,
options: [
{
config: {
@@ -541,11 +541,11 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
Disabling transform
`,
+
Disabling transform
`,
},
{
code: `
-
Nasty prefix
`,
+
Nasty prefix
`,
options: [
{
config: {
@@ -556,7 +556,7 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
Issue #101
`,
+
Issue #101
`,
options: [
{
config: {
@@ -573,7 +573,7 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
Issue #100
`,
+
Issue #100
`,
options: [
{
config: {
@@ -591,14 +591,14 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
Using
-
HTML
`,
+
Using
+
HTML
`,
parser: require.resolve("@angular-eslint/template-parser"),
},
{
code: `
-
Using HTML
-
With nasty prefix
`,
+
Using HTML
+
With nasty prefix
`,
options: [
{
config: {
@@ -610,50 +610,50 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
Deprecated classnames yet still supported for now
`,
+
Deprecated classnames yet still supported for now
`,
},
{
code: `
-
Negative arbitrary value
`,
+
Negative arbitrary value
`,
},
{
code: `
-
- https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/97
-
`,
+
+ https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/97
+
`,
options: [
{
config: {
@@ -664,25 +664,25 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
Issue #130
`,
+
Issue #130
`,
},
{
code: `
-
- Issue #148
- https://github.com/tailwindlabs/tailwindcss/releases/tag/v3.1.0
-
`,
+
+ Issue #148
+ https://github.com/tailwindlabs/tailwindcss/releases/tag/v3.1.0
+
`,
},
{
code: `
-
- Support for plugins
-
Not prose
-
-
-
-
Line clamp
-
`,
+
+ Support for plugins
+
Not prose
+
+
+
+
Line clamp
+
`,
options: [
{
config: {
@@ -697,10 +697,10 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
-
Hello, world!
-
- `,
+
+
Hello, world!
+
+ `,
options: [
{
config: {
@@ -711,9 +711,9 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
- https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/145
-
`,
+
+ https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/145
+
`,
options: [
{
config: {
@@ -739,11 +739,11 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
-
PRIMARY using a function
-
SECONDARY using a function
-
See https://github.com/adamwathan/tailwind-css-variable-text-opacity-demo
-
`,
+
+
PRIMARY using a function
+
SECONDARY using a function
+
See https://github.com/adamwathan/tailwind-css-variable-text-opacity-demo
+
`,
options: [
{
config: {
@@ -775,21 +775,21 @@ ruleTester.run("no-custom-classname", rule, {
},
{
code: `
-
- grid-flow-dense, mix-blend-plus-lighter
-
`,
+
+ grid-flow-dense, mix-blend-plus-lighter
+
`,
},
{
code: `
-
- border-spacing
-
`,
+
+ border-spacing
+
`,
},
{
code: `
No errors while typing
`,
@@ -862,37 +862,6 @@ ruleTester.run("no-custom-classname", rule, {
\`);`,
errors: generateErrors("hello world"),
},
- {
- code: `
- cva({
- variants: {
- variant: {
- primary: ["sm:w-6 w-8 container w-12 flex lg:w-4 hello"],
- primary: ["sm:w-6 w-8 container w-12 flex lg:w-4 world"],
- },
- },
- });
- `,
- options: [
- {
- callees: ["cva"],
- },
- ],
- errors: generateErrors("hello world"),
- },
- {
- code: `
- cva({
- primary: ["sm:w-6 w-8 container w-12 flex lg:w-4 hello"],
- });
- `,
- options: [
- {
- callees: ["cva"],
- },
- ],
- errors: generateErrors("hello"),
- },
{
code: `
Only Tailwind CSS classnames
`,
options: [
@@ -1103,5 +1072,36 @@ ruleTester.run("no-custom-classname", rule, {
],
errors: generateErrors("bg-404 lg:text-unknown text-color-not-found"),
},
+ {
+ code: `
+ cva({
+ variants: {
+ variant: {
+ primary: ["sm:w-6 w-8 container w-12 flex lg:w-4 hello"],
+ primary: ["sm:w-6 w-8 container w-12 flex lg:w-4 world"],
+ },
+ },
+ });
+ `,
+ options: [
+ {
+ callees: ["cva"],
+ },
+ ],
+ errors: generateErrors("hello world"),
+ },
+ {
+ code: `
+ cva({
+ primary: ["sm:w-6 w-8 container w-12 flex lg:w-4 hello"],
+ });
+ `,
+ options: [
+ {
+ callees: ["cva"],
+ },
+ ],
+ errors: generateErrors("hello"),
+ },
],
});
From 791e847994d5b9f118fbeeb1c2c08aeb5032c28f Mon Sep 17 00:00:00 2001
From: Dennis
Date: Thu, 1 Dec 2022 08:12:02 +0100
Subject: [PATCH 3/4] feat: Also added sorting orders test
---
lib/rules/classnames-order.js | 4 +++-
tests/lib/rules/classnames-order.js | 14 +++++++++++++
tests/lib/rules/no-custom-classname.js | 29 ++++++++++++++++++++++++++
3 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/lib/rules/classnames-order.js b/lib/rules/classnames-order.js
index c011e3d8..67a348ce 100644
--- a/lib/rules/classnames-order.js
+++ b/lib/rules/classnames-order.js
@@ -126,8 +126,10 @@ module.exports = {
});
return;
case 'ObjectExpression':
+ const isUsedByClassNamesPlugin = node.callee && node.callee.name === 'classnames';
+
arg.properties.forEach((prop) => {
- sortNodeArgumentValue(node, prop.key);
+ sortNodeArgumentValue(node, isUsedByClassNamesPlugin ? prop.key : prop.value);
});
return;
case 'Literal':
diff --git a/tests/lib/rules/classnames-order.js b/tests/lib/rules/classnames-order.js
index 79a092be..c17f6ef2 100644
--- a/tests/lib/rules/classnames-order.js
+++ b/tests/lib/rules/classnames-order.js
@@ -491,6 +491,20 @@ ruleTester.run("classnames-order", rule, {
],
errors: errors,
},
+ {
+ code: `cva({
+ primary: ["absolute bottom-0 w-full h-[70px] flex flex-col"],
+ })`,
+ output: `cva({
+ primary: ["absolute bottom-0 flex h-[70px] w-full flex-col"],
+ })`,
+ options: [
+ {
+ callees: ["cva"],
+ },
+ ],
+ errors: errors,
+ },
{
code: `clsx
`,
output: `clsx
`,
diff --git a/tests/lib/rules/no-custom-classname.js b/tests/lib/rules/no-custom-classname.js
index 5540692c..51ad19b5 100644
--- a/tests/lib/rules/no-custom-classname.js
+++ b/tests/lib/rules/no-custom-classname.js
@@ -811,6 +811,35 @@ ruleTester.run("no-custom-classname", rule, {
},
],
},
+ {
+ code: `
+ cva({
+ variants: {
+ variant: {
+ primary: ["sm:w-6 w-8 container w-12 flex lg:w-4"],
+ primary: ["sm:w-6 w-8 container w-12 flex lg:w-4"],
+ },
+ },
+ });
+ `,
+ options: [
+ {
+ callees: ["cva"],
+ },
+ ],
+ },
+ {
+ code: `
+ cva({
+ primary: ["sm:w-6 w-8 container w-12 flex lg:w-4"],
+ });
+ `,
+ options: [
+ {
+ callees: ["cva"],
+ },
+ ],
+ },
],
invalid: [
From ea6031186db6eef08a5ce51db8406a6d74ce3dd7 Mon Sep 17 00:00:00 2001
From: Dennis
Date: Thu, 1 Dec 2022 08:32:47 +0100
Subject: [PATCH 4/4] feat: Also added support for other rules
---
.../enforces-negative-arbitrary-values.js | 4 +++-
lib/rules/enforces-shorthand.js | 4 +++-
lib/rules/no-arbitrary-value.js | 4 +++-
tests/lib/rules/enforces-shorthand.js | 14 ++++++++++++++
tests/lib/rules/no-arbitrary-value.js | 19 +++++++++++++------
tests/lib/rules/no-contradicting-classname.js | 12 ++++++++++++
6 files changed, 48 insertions(+), 9 deletions(-)
diff --git a/lib/rules/enforces-negative-arbitrary-values.js b/lib/rules/enforces-negative-arbitrary-values.js
index 778c5f29..74f1829e 100644
--- a/lib/rules/enforces-negative-arbitrary-values.js
+++ b/lib/rules/enforces-negative-arbitrary-values.js
@@ -101,8 +101,10 @@ module.exports = {
});
return;
case 'ObjectExpression':
+ const isUsedByClassNamesPlugin = node.callee && node.callee.name === 'classnames';
+
arg.properties.forEach((prop) => {
- parseForNegativeArbitraryClassNames(node, prop.key);
+ parseForNegativeArbitraryClassNames(node, isUsedByClassNamesPlugin ? prop.key : prop.value);
});
return;
case 'Literal':
diff --git a/lib/rules/enforces-shorthand.js b/lib/rules/enforces-shorthand.js
index 9adf667b..5bc349e5 100644
--- a/lib/rules/enforces-shorthand.js
+++ b/lib/rules/enforces-shorthand.js
@@ -153,8 +153,10 @@ module.exports = {
});
return;
case 'ObjectExpression':
+ const isUsedByClassNamesPlugin = node.callee && node.callee.name === 'classnames';
+
arg.properties.forEach((prop) => {
- parseForShorthandCandidates(node, prop.key);
+ parseForShorthandCandidates(node, isUsedByClassNamesPlugin ? prop.key : prop.value);
});
return;
case 'Literal':
diff --git a/lib/rules/no-arbitrary-value.js b/lib/rules/no-arbitrary-value.js
index 551543e2..cc9bfaf0 100644
--- a/lib/rules/no-arbitrary-value.js
+++ b/lib/rules/no-arbitrary-value.js
@@ -100,8 +100,10 @@ module.exports = {
});
return;
case 'ObjectExpression':
+ const isUsedByClassNamesPlugin = node.callee && node.callee.name === 'classnames';
+
arg.properties.forEach((prop) => {
- parseForArbitraryValues(node, prop.key);
+ parseForArbitraryValues(node, isUsedByClassNamesPlugin ? prop.key : prop.value);
});
return;
case 'Literal':
diff --git a/tests/lib/rules/enforces-shorthand.js b/tests/lib/rules/enforces-shorthand.js
index bba0e70d..d85567a3 100644
--- a/tests/lib/rules/enforces-shorthand.js
+++ b/tests/lib/rules/enforces-shorthand.js
@@ -465,5 +465,19 @@ ruleTester.run("shorthands", rule, {
`,
errors: [generateError(["p-2", "pl-2", "pr-2"], "p-2")],
},
+ {
+ code: `cva({
+ primary: ["border-l-0 border-r-0"],
+ });`,
+ output: `cva({
+ primary: ["border-x-0"],
+ });`,
+ options: [
+ {
+ callees: ["cva"],
+ },
+ ],
+ errors: [generateError(["border-l-0", "border-r-0"], "border-x-0")],
+ },
],
});
diff --git a/tests/lib/rules/no-arbitrary-value.js b/tests/lib/rules/no-arbitrary-value.js
index ee29e438..0129b9fb 100644
--- a/tests/lib/rules/no-arbitrary-value.js
+++ b/tests/lib/rules/no-arbitrary-value.js
@@ -79,16 +79,11 @@ ruleTester.run("no-arbitrary-value", rule, {
{
code: `
`,
- options: [
- {
- callees: ["cns"],
- },
- ],
errors: generateErrors("p-[3px]"),
},
{
@@ -102,5 +97,17 @@ ruleTester.run("no-arbitrary-value", rule, {
);`,
errors: generateErrors("text-[length:var(--font-size)] rounded-[2em] p-[4vw] leading-[1]"),
},
+ {
+ code: `
+ cva({
+ primary: ["[mask-type:luminance] container flex bg-[rgba(10,20,30,0.5)] w-12 sm:w-6 lg:w-4"],
+ });`,
+ options: [
+ {
+ callees: ["cva"],
+ },
+ ],
+ errors: generateErrors("[mask-type:luminance] bg-[rgba(10,20,30,0.5)]"),
+ },
],
});
diff --git a/tests/lib/rules/no-contradicting-classname.js b/tests/lib/rules/no-contradicting-classname.js
index dcd02f58..4c51a9d5 100644
--- a/tests/lib/rules/no-contradicting-classname.js
+++ b/tests/lib/rules/no-contradicting-classname.js
@@ -608,6 +608,18 @@ ruleTester.run("no-contradicting-classname", rule, {
`,
errors: generateErrors("-outline-offset-2 outline-offset-4"),
},
+ {
+ code: `
+ cva({
+ primary: ["px-2 px-4"],
+ });`,
+ options: [
+ {
+ callees: ["cva"],
+ },
+ ],
+ errors: generateErrors(["px-2 px-4"]),
+ },
// {
// code: `
//