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
- -
Min-Height
-
Max-Height
-
-
`, +
+

Sizing

+
Width
+
Min-Width
+
Max-Width
+ +
Min-Height
+
Max-Height
+
+
`, }, { code: ` -
-

Typography

-
Font Family
-
Font Size
-
Font Smoothing
-
Font Style
-
Font Weight
-
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 Weight
+
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: ` -
-

Official Plugins

-
-
`, +
+

Official Plugins

+
+
`, }, { code: ``, @@ -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: ` -
-
1
-
2
-
3
-
`, +
+
1
+
2
+
3
+
`, }, { code: ` -
- -
-
- -
2
-
3
+
+ +
+
+ +
2
+
3
+
+ + + + + + +
+
- - - - - - -
-
-
- `, + `, }, { code: ` -
-

border-t-current

-
- `, +
+

border-t-current

+
+ `, }, { 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: ` - -
`, +
+

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
- -
Min-Height
-
Max-Height
-
-
`, +
+

Sizing

+
Width
+
Min-Width
+
Max-Width
+ +
Min-Height
+
Max-Height
+
+
`, }, { code: ` -
-

Typography

-
Font Family
-
Font Size
-
Font Smoothing
-
Font Style
-
Font Weight
-
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 Weight
+
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: ` -
-

Official Plugins

-
-
`, +
+

Official Plugins

+
+
`, }, { code: ``, @@ -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: ` -
-
1
-
2
-
3
-
`, +
+
1
+
2
+
3
+
`, }, { code: ` -
- -
-
- -
2
-
3
-
+
+ +
+
+ +
2
+
3
- - - - - - -
-
- `, + + + + + + +
+
+
+ `, }, { code: ` -
-

border-t-current

-
- `, +
+

border-t-current

+
+ `, }, { 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: ` - -
`, +
+

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: `
`, 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: ` //