Repository: francoismassart/eslint-plugin-tailwindcss
Pull request #8 (2021-04-15 20:35:30)

ADD support for `CallExpression` (e.g. `ctl(...)`)
# Support using `CallExpression` (e.g. `ctl(...)`)

## Description

This PR allows you to parse `TemplateLiteral` string used as argument in a `CallExpression`.
The callee's name must be whitelisted, the default config accepts `ctl` aka the tiny utility [classnames-template-literals](https://github.com/netlify/classnames-template-literals) from netlify.

You can specify one or more callee names by setting the `callees` option which expects an array of strings.

**Only works for the `classnames-order` rule for now**

FIXES
- [BUG] Single quotes are replaced by double quotes #4

MINOR
- Formatted code using Prettier
- Refact
- `schema` meta

## Type of change

Please delete options that are not relevant.

- [x] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update

## How Has This Been Tested?

`npm test`

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream modules
- [x] I have checked my code and corrected any misspellings



Patch:
diff --git a/.vscode/settings.json b/.vscode/settings.json
index cac0e10..f82fc39 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,3 +1,4 @@
 {
+  "editor.defaultFormatter": "esbenp.prettier-vscode",
   "editor.formatOnSave": true
 }
\ No newline at end of file
diff --git a/lib/config/groups.js b/lib/config/groups.js
index c03f280..c19111d 100644
--- a/lib/config/groups.js
+++ b/lib/config/groups.js
@@ -7,965 +7,985 @@
  */
 module.exports.groups = [
   {
-    type: 'LAYOUT',
+    type: "LAYOUT",
     members: [
       {
-        type: 'Container',
-        members: 'container',
+        type: "Container",
+        members: "container",
       },
       {
-        type: 'Box Decoration Break',
-        members: 'decoration\\-(slice|clone)',
+        type: "Box Decoration Break",
+        members: "decoration\\-(slice|clone)",
       },
       {
-        type: 'Box Sizing',
-        members: 'box\\-(border|content)',
+        type: "Box Sizing",
+        members: "box\\-(border|content)",
       },
       {
-        type: 'Display',
-        members: '(block|flex|grid|flow\\-root|contents|hidden|inline(\\-(block|flex|table|grid))?|table\\-(column|footer|header|row)\\-group|table(\\-(caption|row|cell|column))?|list\\-item)',
+        type: "Display",
+        members:
+          "(block|flex|grid|flow\\-root|contents|hidden|inline(\\-(block|flex|table|grid))?|table\\-(column|footer|header|row)\\-group|table(\\-(caption|row|cell|column))?|list\\-item)",
       },
       {
-        type: 'Floats',
-        members: 'float\\-(right|left|none)',
+        type: "Floats",
+        members: "float\\-(right|left|none)",
       },
       {
-        type: 'Clear',
-        members: 'float\\-(left|right|both|none)',
+        type: "Clear",
+        members: "float\\-(left|right|both|none)",
       },
       {
-        type: 'Isolation',
-        members: '(isolate|isolation\\-auto)',
+        type: "Isolation",
+        members: "(isolate|isolation\\-auto)",
       },
       {
-        type: 'Object Fit',
-        members: 'object\\-(contain|cover|fill|none|scale\\-down)',
+        type: "Object Fit",
+        members: "object\\-(contain|cover|fill|none|scale\\-down)",
       },
       {
-        type: 'Object Position',
-        members: 'object\\-(bottom|center|(left|right)(\\-(bottom|top))?|top)',
+        type: "Object Position",
+        members: "object\\-(bottom|center|(left|right)(\\-(bottom|top))?|top)",
       },
       {
-        type: 'Overflow',
+        type: "Overflow",
         members: [
           {
-            type: 'overflow',
-            members: 'overflow\\-(auto|hidden|visible|scroll)',
+            type: "overflow",
+            members: "overflow\\-(auto|hidden|visible|scroll)",
           },
           {
-            type: 'overflow-x',
-            members: 'overflow\\-x\\-(auto|hidden|visible|scroll)',
+            type: "overflow-x",
+            members: "overflow\\-x\\-(auto|hidden|visible|scroll)",
           },
           {
-            type: 'overflow-y',
-            members: 'overflow\\-y\\-(auto|hidden|visible|scroll)',
+            type: "overflow-y",
+            members: "overflow\\-y\\-(auto|hidden|visible|scroll)",
           },
         ],
       },
       {
-        type: 'Overscroll Behavior',
+        type: "Overscroll Behavior",
         members: [
           {
-            type: 'overscroll',
-            members: 'overscroll\\-(auto|contain|none)',
+            type: "overscroll",
+            members: "overscroll\\-(auto|contain|none)",
           },
           {
-            type: 'overscroll-x',
-            members: 'overscroll\\-x\\-(auto|contain|none)',
+            type: "overscroll-x",
+            members: "overscroll\\-x\\-(auto|contain|none)",
           },
           {
-            type: 'overscroll-y',
-            members: 'overscroll\\-y\\-(auto|contain|none)',
+            type: "overscroll-y",
+            members: "overscroll\\-y\\-(auto|contain|none)",
           },
         ],
       },
       {
-        type: 'Position',
-        members: 'static|fixed|absolute|relative|sticky',
+        type: "Position",
+        members: "static|fixed|absolute|relative|sticky",
       },
       {
-        type: 'Top / Right / Bottom / Left',
+        type: "Top / Right / Bottom / Left",
         members: [
           {
-            type: 'inset',
-            members: '-?inset\\-(\\d\\.?\\/?\\d?|auto|px|full)',
+            type: "inset",
+            members: "-?inset\\-(\\d\\.?\\/?\\d?|auto|px|full)",
           },
           {
-            type: 'inset-y',
-            members: '-?inset\\-y\\-(\\d\\.?\\/?\\d?|auto|px|full)',
+            type: "inset-y",
+            members: "-?inset\\-y\\-(\\d\\.?\\/?\\d?|auto|px|full)",
           },
           {
-            type: 'inset-x',
-            members: '-?inset\\-x\\-(\\d\\.?\\/?\\d?|auto|px|full)',
+            type: "inset-x",
+            members: "-?inset\\-x\\-(\\d\\.?\\/?\\d?|auto|px|full)",
           },
           {
-            type: 'top',
-            members: '-?top\\-(\\d\\.?\\/?\\d?|auto|px|full)',
+            type: "top",
+            members: "-?top\\-(\\d\\.?\\/?\\d?|auto|px|full)",
           },
           {
-            type: 'right',
-            members: '-?right\\-(\\d\\.?\\/?\\d?|auto|px|full)',
+            type: "right",
+            members: "-?right\\-(\\d\\.?\\/?\\d?|auto|px|full)",
           },
           {
-            type: 'bottom',
-            members: '-?bottom\\-(\\d\\.?\\/?\\d?|auto|px|full)',
+            type: "bottom",
+            members: "-?bottom\\-(\\d\\.?\\/?\\d?|auto|px|full)",
           },
           {
-            type: 'left',
-            members: '-?left\\-(\\d\\.?\\/?\\d?|auto|px|full)',
+            type: "left",
+            members: "-?left\\-(\\d\\.?\\/?\\d?|auto|px|full)",
           },
         ],
       },
       {
-        type: 'Visibility',
-        members: '(in)?visible',
+        type: "Visibility",
+        members: "(in)?visible",
       },
       {
-        type: 'Z-Index',
-        members: 'z\\-(0|10|20|30|40|50|auto)',
+        type: "Z-Index",
+        members: "z\\-(0|10|20|30|40|50|auto)",
       },
     ],
   },
   {
-    type: 'FLEXBOX',
+    type: "FLEXBOX",
     members: [
       {
-        type: 'Flex Direction',
-        members: 'flex\\-(row|col)(\\-reverse)?',
+        type: "Flex Direction",
+        members: "flex\\-(row|col)(\\-reverse)?",
       },
       {
-        type: 'Flex Wrap',
-        members: 'flex\\-(wrap(\\-reverse)?|nowrap)',
+        type: "Flex Wrap",
+        members: "flex\\-(wrap(\\-reverse)?|nowrap)",
       },
       {
-        type: 'Flex',
-        members: 'flex\\-(1|auto|initial|none)',
+        type: "Flex",
+        members: "flex\\-(1|auto|initial|none)",
       },
       {
-        type: 'Flex Grow',
-        members: 'flex\\-grow(\\-0)?',
+        type: "Flex Grow",
+        members: "flex\\-grow(\\-0)?",
       },
       {
-        type: 'Flex Shrink',
-        members: 'flex\\-shrink(\\-0)?',
+        type: "Flex Shrink",
+        members: "flex\\-shrink(\\-0)?",
       },
       {
-        type: 'Order',
-        members: 'order\\-(\\d[0-2]?|first|last|none)',
+        type: "Order",
+        members: "order\\-(\\d[0-2]?|first|last|none)",
       },
     ],
   },
   {
-    type: 'GRID',
+    type: "GRID",
     members: [
       {
-        type: 'Grid Template Columns',
-        members: 'grid\\-cols\\-(\\d[0-2]?|none)',
+        type: "Grid Template Columns",
+        members: "grid\\-cols\\-(\\d[0-2]?|none)",
       },
       {
-        type: 'Grid Column Start / End',
+        type: "Grid Column Start / End",
         members: [
           {
-            type: 'grid-column',
-            members: 'col\\-(auto|span\\-(\\d[0-2]?|full))',
+            type: "grid-column",
+            members: "col\\-(auto|span\\-(\\d[0-2]?|full))",
           },
           {
-            type: 'grid-column-start',
-            members: 'col\\-start\\-(auto|\\d[0-3]?)',
+            type: "grid-column-start",
+            members: "col\\-start\\-(auto|\\d[0-3]?)",
           },
           {
-            type: 'grid-column-end',
-            members: 'col\\-end\\-(auto|\\d[0-3]?)',
+            type: "grid-column-end",
+            members: "col\\-end\\-(auto|\\d[0-3]?)",
           },
         ],
       },
       {
-        type: 'Grid Template Rows',
-        members: 'grid\\-rows\\-([1-6]|none)',
+        type: "Grid Template Rows",
+        members: "grid\\-rows\\-([1-6]|none)",
       },
       {
-        type: 'Grid Row Start / End',
+        type: "Grid Row Start / End",
         members: [
           {
-            type: 'grid-row',
-            members: 'row\\-(auto|span\\-([1-6]|full))',
+            type: "grid-row",
+            members: "row\\-(auto|span\\-([1-6]|full))",
           },
           {
-            type: 'grid-row-start',
-            members: 'row\\-start\\-(auto|[1-7])',
+            type: "grid-row-start",
+            members: "row\\-start\\-(auto|[1-7])",
           },
           {
-            type: 'grid-row-end',
-            members: 'row\\-end\\-(auto|[1-7])',
+            type: "grid-row-end",
+            members: "row\\-end\\-(auto|[1-7])",
           },
         ],
       },
       {
-        type: 'Grid Auto Flow',
-        members: 'grid\\-flow\\-(row|col)(\\-dense)?',
+        type: "Grid Auto Flow",
+        members: "grid\\-flow\\-(row|col)(\\-dense)?",
       },
       {
-        type: 'Grid Auto Columns',
-        members: 'auto\\-cols\\-(auto|min|max|fr)',
+        type: "Grid Auto Columns",
+        members: "auto\\-cols\\-(auto|min|max|fr)",
       },
       {
-        type: 'Grid Auto Rows',
-        members: 'auto\\-rows\\-(auto|min|max|fr)',
+        type: "Grid Auto Rows",
+        members: "auto\\-rows\\-(auto|min|max|fr)",
       },
       {
-        type: 'Gap',
+        type: "Gap",
         members: [
           {
-            type: 'gap',
-            members: 'gap\\-(\\d(\\d|(\\.5))?|\\d|px)',
+            type: "gap",
+            members: "gap\\-(\\d(\\d|(\\.5))?|\\d|px)",
           },
           {
-            type: 'column-gap',
-            members: 'gap\\-x\\-(\\d(\\d|(\\.5))?|\\d|px)',
+            type: "column-gap",
+            members: "gap\\-x\\-(\\d(\\d|(\\.5))?|\\d|px)",
           },
           {
-            type: 'row-gap',
-            members: 'gap\\-y\\-(\\d(\\d|(\\.5))?|\\d|px)',
+            type: "row-gap",
+            members: "gap\\-y\\-(\\d(\\d|(\\.5))?|\\d|px)",
           },
         ],
       },
     ],
   },
   {
-    type: 'BOX ALIGNMENT',
+    type: "BOX ALIGNMENT",
     members: [
       {
-        type: 'Justify Content',
-        members: 'justify\\-(start|end|center|between|around|evenly)',
+        type: "Justify Content",
+        members: "justify\\-(start|end|center|between|around|evenly)",
       },
       {
-        type: 'Justify Items',
-        members: 'justify\\-items\\-(auto|start|end|center|stretch)',
+        type: "Justify Items",
+        members: "justify\\-items\\-(auto|start|end|center|stretch)",
       },
       {
-        type: 'Justify Self',
-        members: 'justify\\-self\\-(auto|start|end|center|stretch)',
+        type: "Justify Self",
+        members: "justify\\-self\\-(auto|start|end|center|stretch)",
       },
       {
-        type: 'Align Content',
-        members: 'content\\-(center|start|end|between|around|evenly)',
+        type: "Align Content",
+        members: "content\\-(center|start|end|between|around|evenly)",
       },
       {
-        type: 'Align Items',
-        members: 'items\\-(start|end|center|baseline|stretch)',
+        type: "Align Items",
+        members: "items\\-(start|end|center|baseline|stretch)",
       },
       {
-        type: 'Align Self',
-        members: 'items\\-(auto|start|end|center|stretch)',
+        type: "Align Self",
+        members: "items\\-(auto|start|end|center|stretch)",
       },
       {
-        type: 'Place Content',
-        members: 'place\\-content\\-(center|start|end|between|around|evenly|stretch)',
+        type: "Place Content",
+        members:
+          "place\\-content\\-(center|start|end|between|around|evenly|stretch)",
       },
       {
-        type: 'Place Items',
-        members: 'place\\-items\\-(auto|start|end|center|stretch)',
+        type: "Place Items",
+        members: "place\\-items\\-(auto|start|end|center|stretch)",
       },
       {
-        type: 'Place Self',
-        members: 'place\\-self\\-(auto|start|end|center|stretch)',
+        type: "Place Self",
+        members: "place\\-self\\-(auto|start|end|center|stretch)",
       },
     ],
   },
   {
-    type: 'SPACING',
+    type: "SPACING",
     members: [
       {
-        type: 'Padding',
+        type: "Padding",
         members: [
           {
-            type: 'p',
-            members: 'p\\-(\\d(\\.?\\d)?|px)',
+            type: "p",
+            members: "p\\-(\\d(\\.?\\d)?|px)",
           },
           {
-            type: 'py',
-            members: 'py\\-(\\d(\\.?\\d)?|px)',
+            type: "py",
+            members: "py\\-(\\d(\\.?\\d)?|px)",
           },
           {
-            type: 'px',
-            members: 'px\\-(\\d(\\.?\\d)?|px)',
+            type: "px",
+            members: "px\\-(\\d(\\.?\\d)?|px)",
           },
           {
-            type: 'pt',
-            members: 'pt\\-(\\d(\\.?\\d)?|px)',
+            type: "pt",
+            members: "pt\\-(\\d(\\.?\\d)?|px)",
           },
           {
-            type: 'pr',
-            members: 'pr\\-(\\d(\\.?\\d)?|px)',
+            type: "pr",
+            members: "pr\\-(\\d(\\.?\\d)?|px)",
           },
           {
-            type: 'pb',
-            members: 'pb\\-(\\d(\\.?\\d)?|px)',
+            type: "pb",
+            members: "pb\\-(\\d(\\.?\\d)?|px)",
           },
           {
-            type: 'pl',
-            members: 'pl\\-(\\d(\\.?\\d)?|px)',
+            type: "pl",
+            members: "pl\\-(\\d(\\.?\\d)?|px)",
           },
         ],
       },
       {
-        type: 'Margin',
+        type: "Margin",
         members: [
           {
-            type: 'm',
-            members: '\\-?m\\-(\\d(\\.?\\d)?|auto|px)',
+            type: "m",
+            members: "\\-?m\\-(\\d(\\.?\\d)?|auto|px)",
           },
           {
-            type: 'my',
-            members: '\\-?my\\-(\\d(\\.?\\d)?|auto|px)',
+            type: "my",
+            members: "\\-?my\\-(\\d(\\.?\\d)?|auto|px)",
           },
           {
-            type: 'mx',
-            members: '\\-?mx\\-(\\d(\\.?\\d)?|auto|px)',
+            type: "mx",
+            members: "\\-?mx\\-(\\d(\\.?\\d)?|auto|px)",
           },
           {
-            type: 'mt',
-            members: '\\-?mt\\-(\\d(\\.?\\d)?|auto|px)',
+            type: "mt",
+            members: "\\-?mt\\-(\\d(\\.?\\d)?|auto|px)",
           },
           {
-            type: 'mr',
-            members: '\\-?mr\\-(\\d(\\.?\\d)?|auto|px)',
+            type: "mr",
+            members: "\\-?mr\\-(\\d(\\.?\\d)?|auto|px)",
           },
           {
-            type: 'mb',
-            members: '\\-?mb\\-(\\d(\\.?\\d)?|auto|px)',
+            type: "mb",
+            members: "\\-?mb\\-(\\d(\\.?\\d)?|auto|px)",
           },
           {
-            type: 'ml',
-            members: '\\-?ml\\-(\\d(\\.?\\d)?|auto|px)',
+            type: "ml",
+            members: "\\-?ml\\-(\\d(\\.?\\d)?|auto|px)",
           },
         ],
       },
       {
-        type: 'Space Between',
+        type: "Space Between",
         members: [
           {
-            type: 'space-y',
-            members: '\\-?space\\-y\\-(\\d(\\.?\\d)?|px|reverse)',
+            type: "space-y",
+            members: "\\-?space\\-y\\-(\\d(\\.?\\d)?|px|reverse)",
           },
           {
-            type: 'space-x',
-            members: '\\-?space\\-x\\-(\\d(\\.?\\d)?|px|reverse)',
+            type: "space-x",
+            members: "\\-?space\\-x\\-(\\d(\\.?\\d)?|px|reverse)",
           },
         ],
       },
     ],
   },
   {
-    type: 'SIZING',
+    type: "SIZING",
     members: [
       {
-        type: 'Width',
-        members: 'w\\-(\\d|\\d\\.\\d|\\d\\d|auto|px|\\d\\d?\\/\\d\\d?|full|screen|min|max)',
+        type: "Width",
+        members:
+          "w\\-(\\d|\\d\\.\\d|\\d\\d|auto|px|\\d\\d?\\/\\d\\d?|full|screen|min|max)",
       },
       {
-        type: 'Min-Width',
-        members: 'min\\-w\\-(0|full|min|max)',
+        type: "Min-Width",
+        members: "min\\-w\\-(0|full|min|max)",
       },
       {
-        type: 'Max-Width',
-        members: 'max\\-w\\-(0|none|xs|sm|md|lg|[2-7]?xl|full|min|max|prose|screen\\-(sm|md|lg|2?xl))',
+        type: "Max-Width",
+        members:
+          "max\\-w\\-(0|none|xs|sm|md|lg|[2-7]?xl|full|min|max|prose|screen\\-(sm|md|lg|2?xl))",
       },
       {
-        type: 'Height',
-        members: 'h\\-(\\d(\\.|\\/)?\\d?|auto|px|full|screen)',
+        type: "Height",
+        members: "h\\-(\\d(\\.|\\/)?\\d?|auto|px|full|screen)",
       },
       {
-        type: 'Min-Height',
-        members: 'min\\-h\\-(0|full|screen)',
+        type: "Min-Height",
+        members: "min\\-h\\-(0|full|screen)",
       },
       {
-        type: 'Max-Height',
-        members: 'max\\-h\\-(\\d\\.?\\d?|px|full|screen)',
+        type: "Max-Height",
+        members: "max\\-h\\-(\\d\\.?\\d?|px|full|screen)",
       },
     ],
   },
   {
-    type: 'TYPOGRAPHY',
+    type: "TYPOGRAPHY",
     members: [
       {
-        type: 'Font Family',
-        members: 'font\\-(sans|serif|mono)',
+        type: "Font Family",
+        members: "font\\-(sans|serif|mono)",
       },
       {
-        type: 'Font Size',
-        members: 'text\\-(xs|sm|base|lg|[2-9]?xl)',
+        type: "Font Size",
+        members: "text\\-(xs|sm|base|lg|[2-9]?xl)",
       },
       {
-        type: 'Font Smoothing',
-        members: '(subpixel\\-)?antialiased',
+        type: "Font Smoothing",
+        members: "(subpixel\\-)?antialiased",
       },
       {
-        type: 'Font Style',
-        members: '(not\\-)?italic',
+        type: "Font Style",
+        members: "(not\\-)?italic",
       },
       {
-        type: 'Font Weight',
-        members: 'font\\-(thin|(extra)?light|normal|medium|(semi|extra)?bold|black)',
+        type: "Font Weight",
+        members:
+          "font\\-(thin|(extra)?light|normal|medium|(semi|extra)?bold|black)",
       },
       {
-        type: 'Font Variant Numeric',
-        members: '(normal|lining|oldstyle|proportional|tabular)\\-nums|ordinal|slashed-zero|(diagonal|stacked)\\-fractions',
+        type: "Font Variant Numeric",
+        members:
+          "(normal|lining|oldstyle|proportional|tabular)\\-nums|ordinal|slashed-zero|(diagonal|stacked)\\-fractions",
       },
       {
-        type: 'Letter Spacing',
-        members: 'tracking\\-(tight(er)?|normal|wide(r|st)?)',
+        type: "Letter Spacing",
+        members: "tracking\\-(tight(er)?|normal|wide(r|st)?)",
       },
       {
-        type: 'Line Height',
-        members: 'leading\\-([3-9]|10|none|tight|snug|normal|relaxed|loose)',
+        type: "Line Height",
+        members: "leading\\-([3-9]|10|none|tight|snug|normal|relaxed|loose)",
       },
       {
-        type: 'List Style Type',
-        members: 'list\\-(none|disc|decimal)',
+        type: "List Style Type",
+        members: "list\\-(none|disc|decimal)",
       },
       {
-        type: 'List Style Position',
-        members: 'list\\-(in|out)side',
+        type: "List Style Position",
+        members: "list\\-(in|out)side",
       },
       {
-        type: 'Placeholder Color',
-        members: 'placeholder\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-[1-9]0?0?)',
+        type: "Placeholder Color",
+        members:
+          "placeholder\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-[1-9]0?0?)",
       },
       {
-        type: 'Placeholder Opacity',
-        members: 'placeholder\\-opacity\\-(0|5|[1-9](0|5)0?)',
+        type: "Placeholder Opacity",
+        members: "placeholder\\-opacity\\-(0|5|[1-9](0|5)0?)",
       },
       {
-        type: 'Text Alignment',
-        members: 'text\\-(left|center|right|justify)',
+        type: "Text Alignment",
+        members: "text\\-(left|center|right|justify)",
       },
       {
-        type: 'Text Color',
-        members: 'text\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-[1-9]0?0?)',
+        type: "Text Color",
+        members:
+          "text\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-[1-9]0?0?)",
       },
       {
-        type: 'Text Opacity',
-        members: 'text\\-opacity\\-(0|5|[1-9](0|5)0?)',
+        type: "Text Opacity",
+        members: "text\\-opacity\\-(0|5|[1-9](0|5)0?)",
       },
       {
-        type: 'Text Decoration',
-        members: '(no\\-)?underline|line\\-through',
+        type: "Text Decoration",
+        members: "(no\\-)?underline|line\\-through",
       },
       {
-        type: 'Text Transform',
-        members: '(upper|lower|normal\\-)case|capitalize',
+        type: "Text Transform",
+        members: "(upper|lower|normal\\-)case|capitalize",
       },
       {
-        type: 'Text Overflow',
-        members: 'truncate|overflow\\-(ellipsis|clip)',
+        type: "Text Overflow",
+        members: "truncate|overflow\\-(ellipsis|clip)",
       },
       {
-        type: 'Vertical Alignment',
-        members: 'align\\-(baseline|top|middle|bottom|text\\-(top|bottom))',
+        type: "Vertical Alignment",
+        members: "align\\-(baseline|top|middle|bottom|text\\-(top|bottom))",
       },
       {
-        type: 'Whitespace',
-        members: 'whitespace\\-(normal|nowrap|pre(\\-(line|wrap))?)',
+        type: "Whitespace",
+        members: "whitespace\\-(normal|nowrap|pre(\\-(line|wrap))?)",
       },
       {
-        type: 'Word Break',
-        members: 'break\\-(normal|words|all)',
+        type: "Word Break",
+        members: "break\\-(normal|words|all)",
       },
     ],
   },
   {
-    type: 'BACKGROUNDS',
+    type: "BACKGROUNDS",
     members: [
       {
-        type: 'Background Attachment',
-        members: 'bg\\-(fixed|local|scroll)',
+        type: "Background Attachment",
+        members: "bg\\-(fixed|local|scroll)",
       },
       {
-        type: 'Background Clip',
-        members: 'bg\\-clip\\-(border|padding|content|text)',
+        type: "Background Clip",
+        members: "bg\\-clip\\-(border|padding|content|text)",
       },
       {
-        type: 'Background Color',
-        members: 'bg\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-[1-9]0?0?)',
+        type: "Background Color",
+        members:
+          "bg\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-[1-9]0?0?)",
       },
       {
-        type: 'Background Opacity',
-        members: 'bg\\-opacity\\-(0|5|[1-9](0|5)0?)',
+        type: "Background Opacity",
+        members: "bg\\-opacity\\-(0|5|[1-9](0|5)0?)",
       },
       {
-        type: 'Background Position',
-        members: 'bg\\-(bottom|center|(left|right(\\-(bottom|top))?|top))',
+        type: "Background Position",
+        members: "bg\\-(bottom|center|(left|right(\\-(bottom|top))?|top))",
       },
       {
-        type: 'Background Repeat',
-        members: 'bg\\-(no\\-repeat|repeat(\\-(x|y|round|space))?)',
+        type: "Background Repeat",
+        members: "bg\\-(no\\-repeat|repeat(\\-(x|y|round|space))?)",
       },
       {
-        type: 'Background Size',
-        members: 'bg\\-(auto|cover|contain)',
+        type: "Background Size",
+        members: "bg\\-(auto|cover|contain)",
       },
       {
-        type: 'Background Image',
-        members: 'bg\\-(none|gradient\\-to\\-((t|b)(r|l)?|r|l))',
+        type: "Background Image",
+        members: "bg\\-(none|gradient\\-to\\-((t|b)(r|l)?|r|l))",
       },
       {
-        type: 'Gradient Color Stops',
+        type: "Gradient Color Stops",
         members: [
           {
-            type: 'from',
-            members: 'from\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-([1-9]00|50))',
+            type: "from",
+            members:
+              "from\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-([1-9]00|50))",
           },
           {
-            type: 'via',
-            members: 'via\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-([1-9]00|50))',
+            type: "via",
+            members:
+              "via\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-([1-9]00|50))",
           },
           {
-            type: 'to',
-            members: 'to\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-([1-9]00|50))',
+            type: "to",
+            members:
+              "to\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-([1-9]00|50))",
           },
         ],
       },
     ],
   },
   {
-    type: 'BORDERS',
+    type: "BORDERS",
     members: [
       {
-        type: 'Border Radius',
+        type: "Border Radius",
         members: [
           {
-            type: 'border-radius',
-            members: 'rounded(\\-(none|sm|md|lg|(2|3)?xl|full))?',
+            type: "border-radius",
+            members: "rounded(\\-(none|sm|md|lg|(2|3)?xl|full))?",
           },
           {
-            type: 'border-radius-top',
-            members: 'rounded\\-t(\\-(none|sm|md|lg|(2|3)?xl|full))?',
+            type: "border-radius-top",
+            members: "rounded\\-t(\\-(none|sm|md|lg|(2|3)?xl|full))?",
           },
           {
-            type: 'border-radius-right',
-            members: 'rounded\\-r(\\-(sm|md|lg|(2|3)?xl|full))?',
+            type: "border-radius-right",
+            members: "rounded\\-r(\\-(sm|md|lg|(2|3)?xl|full))?",
           },
           {
-            type: 'border-radius-bottom',
-            members: 'rounded\\-b(\\-(sm|md|lg|(2|3)?xl|full))?',
+            type: "border-radius-bottom",
+            members: "rounded\\-b(\\-(sm|md|lg|(2|3)?xl|full))?",
           },
           {
-            type: 'border-radius-left',
-            members: 'rounded\\-l(\\-(sm|md|lg|(2|3)?xl|full))?',
+            type: "border-radius-left",
+            members: "rounded\\-l(\\-(sm|md|lg|(2|3)?xl|full))?",
           },
           {
-            type: 'border-radius-top-left',
-            members: 'rounded\\-tl(\\-(none|sm|md|lg|(2|3)?xl|full))?',
+            type: "border-radius-top-left",
+            members: "rounded\\-tl(\\-(none|sm|md|lg|(2|3)?xl|full))?",
           },
           {
-            type: 'border-radius-top-right',
-            members: 'rounded\\-tr(\\-(none|sm|md|lg|(2|3)?xl|full))?',
+            type: "border-radius-top-right",
+            members: "rounded\\-tr(\\-(none|sm|md|lg|(2|3)?xl|full))?",
           },
           {
-            type: 'border-radius-bottom-right',
-            members: 'rounded\\-br(\\-(none|sm|md|lg|(2|3)?xl|full))?',
+            type: "border-radius-bottom-right",
+            members: "rounded\\-br(\\-(none|sm|md|lg|(2|3)?xl|full))?",
           },
           {
-            type: 'border-radius-bottom-left',
-            members: 'rounded\\-bl(\\-(none|sm|md|lg|(2|3)?xl|full))?',
+            type: "border-radius-bottom-left",
+            members: "rounded\\-bl(\\-(none|sm|md|lg|(2|3)?xl|full))?",
           },
         ],
       },
       {
-        type: 'Border Width',
+        type: "Border Width",
         members: [
           {
-            type: 'border-width',
-            members: 'border(\\-(0|2|4|8))?',
+            type: "border-width",
+            members: "border(\\-(0|2|4|8))?",
           },
           {
-            type: 'border-top-width',
-            members: 'border\\-t(\\-(0|2|4|8))?',
+            type: "border-top-width",
+            members: "border\\-t(\\-(0|2|4|8))?",
           },
           {
-            type: 'border-right-width',
-            members: 'border\\-r(\\-(0|2|4|8))?',
+            type: "border-right-width",
+            members: "border\\-r(\\-(0|2|4|8))?",
           },
           {
-            type: 'border-bottom-width',
-            members: 'border\\-b(\\-(0|2|4|8))?',
+            type: "border-bottom-width",
+            members: "border\\-b(\\-(0|2|4|8))?",
           },
           {
-            type: 'border-left-width',
-            members: 'border\\-l(\\-(0|2|4|8))?',
+            type: "border-left-width",
+            members: "border\\-l(\\-(0|2|4|8))?",
           },
         ],
       },
       {
-        type: 'Border Color',
-        members: 'border\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-[1-9]0?0?)',
+        type: "Border Color",
+        members:
+          "border\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-[1-9]0?0?)",
       },
       {
-        type: 'Border Opacity',
-        members: 'border\\-opacity\\-(0|5|[1-9](0|5)0?)',
+        type: "Border Opacity",
+        members: "border\\-opacity\\-(0|5|[1-9](0|5)0?)",
       },
       {
-        type: 'Border Style',
-        members: 'border\\-(solid|dashed|dotted|double|none)',
+        type: "Border Style",
+        members: "border\\-(solid|dashed|dotted|double|none)",
       },
       {
-        type: 'Divide Width',
+        type: "Divide Width",
         members: [
           {
-            type: 'divide-y',
-            members: 'divide\\-y(\\-(0|2|4|8))?',
+            type: "divide-y",
+            members: "divide\\-y(\\-(0|2|4|8))?",
           },
           {
-            type: 'divide-x',
-            members: 'divide\\-x(\\-(0|2|4|8))?',
+            type: "divide-x",
+            members: "divide\\-x(\\-(0|2|4|8))?",
           },
           {
-            type: 'divide-y-reverse',
-            members: 'divide\\-y\\-reverse',
+            type: "divide-y-reverse",
+            members: "divide\\-y\\-reverse",
           },
           {
-            type: 'divide-x-reverse',
-            members: 'divide\\-x\\-reverse',
+            type: "divide-x-reverse",
+            members: "divide\\-x\\-reverse",
           },
         ],
       },
       {
-        type: 'Divide Color',
-        members: 'divide\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-[1-9]0?0?)',
+        type: "Divide Color",
+        members:
+          "divide\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-[1-9]0?0?)",
       },
       {
-        type: 'Divide Opacity',
-        members: 'divide\\-opacity\\-(0|5|[1-9](0|5)0?)',
+        type: "Divide Opacity",
+        members: "divide\\-opacity\\-(0|5|[1-9](0|5)0?)",
       },
       {
-        type: 'Divide Style',
-        members: 'divide\\-(solid|dashed|dotted|double|none)',
+        type: "Divide Style",
+        members: "divide\\-(solid|dashed|dotted|double|none)",
       },
       {
-        type: 'Ring Width',
+        type: "Ring Width",
         members: [
           {
-            type: 'ring',
-            members: 'ring(\\-(0|2|4|8))?',
+            type: "ring",
+            members: "ring(\\-(0|2|4|8))?",
           },
           {
-            type: 'ring-inset',
-            members: 'ring\\-inset',
+            type: "ring-inset",
+            members: "ring\\-inset",
           },
         ],
       },
       {
-        type: 'Ring Color',
-        members: 'ring\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-[1-9]0?0?)',
+        type: "Ring Color",
+        members:
+          "ring\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-[1-9]0?0?)",
       },
       {
-        type: 'Ring Opacity',
-        members: 'ring\\-opacity\\-(0|5|[1-9](0|5)0?)',
+        type: "Ring Opacity",
+        members: "ring\\-opacity\\-(0|5|[1-9](0|5)0?)",
       },
       {
-        type: 'Ring Offset Width',
-        members: 'ring\\-offset\\-(0|1|2|4|8)',
+        type: "Ring Offset Width",
+        members: "ring\\-offset\\-(0|1|2|4|8)",
       },
       {
-        type: 'Ring Offset Color',
-        members: 'ring\\-offset\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-[1-9]0?0?)',
+        type: "Ring Offset Color",
+        members:
+          "ring\\-offset\\-(transparent|current|black|white|(gray|red|yellow|green|blue|indigo|purple|pink)\\-[1-9]0?0?)",
       },
     ],
   },
   {
-    type: 'EFFECTS',
+    type: "EFFECTS",
     members: [
       {
-        type: 'Box Shadow',
-        members: 'shadow(\\-(sm|md|lg|2?xl|inner|none))?',
+        type: "Box Shadow",
+        members: "shadow(\\-(sm|md|lg|2?xl|inner|none))?",
       },
       {
-        type: 'Opacity',
-        members: 'opacity\\-(0|5|[1-9](0|5)0?)',
+        type: "Opacity",
+        members: "opacity\\-(0|5|[1-9](0|5)0?)",
       },
       {
-        type: 'Mix Blend Mode',
-        members: 'mix\\-blend\\-(normal|multiply|screen|overlay|darken|lighten|color\\-(burn|dodge)|(hard|soft)\\-light|difference|exclusion|hue|saturation|color|luminosity)',
+        type: "Mix Blend Mode",
+        members:
+          "mix\\-blend\\-(normal|multiply|screen|overlay|darken|lighten|color\\-(burn|dodge)|(hard|soft)\\-light|difference|exclusion|hue|saturation|color|luminosity)",
       },
       {
-        type: 'Background Blend Mode',
-        members: 'bg\\-blend\\-(normal|multiply|screen|overlay|darken|lighten|color\\-(dodge|burn)|(hard|soft)\\-light|difference|exclusion|hue|saturation|color|luminosity)',
+        type: "Background Blend Mode",
+        members:
+          "bg\\-blend\\-(normal|multiply|screen|overlay|darken|lighten|color\\-(dodge|burn)|(hard|soft)\\-light|difference|exclusion|hue|saturation|color|luminosity)",
       },
     ],
   },
   {
-    type: 'FILTERS',
+    type: "FILTERS",
     members: [
       {
-        type: 'Filter',
-        members: 'filter(\\-none)?',
+        type: "Filter",
+        members: "filter(\\-none)?",
       },
       {
-        type: 'Blur',
-        members: 'blur(\\-(0|sm|md|lg|(2|3)?xl))?',
+        type: "Blur",
+        members: "blur(\\-(0|sm|md|lg|(2|3)?xl))?",
       },
       {
-        type: 'Brightness',
-        members: 'bightness\\-(0|50|75|90|95|100|105|110|125|150|200)',
+        type: "Brightness",
+        members: "bightness\\-(0|50|75|90|95|100|105|110|125|150|200)",
       },
       {
-        type: 'Contrast',
-        members: 'contrast\\-(0|50|75|100|125|150|200)',
+        type: "Contrast",
+        members: "contrast\\-(0|50|75|100|125|150|200)",
       },
       {
-        type: 'Drop Shadow',
-        members: 'drop\\-shadow(\\-(sm|md|lg|2?xl|none))?',
+        type: "Drop Shadow",
+        members: "drop\\-shadow(\\-(sm|md|lg|2?xl|none))?",
       },
       {
-        type: 'Grayscale',
-        members: 'grayscale(\\-0)?',
+        type: "Grayscale",
+        members: "grayscale(\\-0)?",
       },
       {
-        type: 'Hue Rotate',
-        members: '(\\-)?hue\\-rotate\\-(0|15|30|60|90|180)',
+        type: "Hue Rotate",
+        members: "(\\-)?hue\\-rotate\\-(0|15|30|60|90|180)",
       },
       {
-        type: 'Invert',
-        members: 'invert(\\-0)?',
+        type: "Invert",
+        members: "invert(\\-0)?",
       },
       {
-        type: 'Saturate',
-        members: 'saturate\\-(0|50|100|150|200)',
+        type: "Saturate",
+        members: "saturate\\-(0|50|100|150|200)",
       },
       {
-        type: 'Sepia',
-        members: 'sepia(\\-0)?',
+        type: "Sepia",
+        members: "sepia(\\-0)?",
       },
       {
-        type: 'Backdrop Filter',
-        members: 'backdrop\\-filter(\\-none)?',
+        type: "Backdrop Filter",
+        members: "backdrop\\-filter(\\-none)?",
       },
       {
-        type: 'Backdrop Blur',
-        members: 'backdrop\\-blur(\\-(0|sm|md|lg|(2|3)?xl))?',
+        type: "Backdrop Blur",
+        members: "backdrop\\-blur(\\-(0|sm|md|lg|(2|3)?xl))?",
       },
       {
-        type: 'Backdrop Brightness',
-        members: 'backdrop\\-bightness\\-(0|50|75|90|95|100|105|110|125|150|200)',
+        type: "Backdrop Brightness",
+        members:
+          "backdrop\\-bightness\\-(0|50|75|90|95|100|105|110|125|150|200)",
       },
       {
-        type: 'Backdrop Contrast',
-        members: 'backdrop\\-contrast\\-(0|50|75|100|125|150|200)',
+        type: "Backdrop Contrast",
+        members: "backdrop\\-contrast\\-(0|50|75|100|125|150|200)",
       },
       {
-        type: 'Backdrop Grayscale',
-        members: 'backdrop\\-grayscale(\\-0)?',
+        type: "Backdrop Grayscale",
+        members: "backdrop\\-grayscale(\\-0)?",
       },
       {
-        type: 'Backdrop Hue Rotate',
-        members: '(\\-)?backdrop\\-hue\\-rotate\\-(0|15|30|60|90|180)',
+        type: "Backdrop Hue Rotate",
+        members: "(\\-)?backdrop\\-hue\\-rotate\\-(0|15|30|60|90|180)",
       },
       {
-        type: 'Backdrop Invert',
-        members: 'backdrop\\-invert(\\-0)?',
+        type: "Backdrop Invert",
+        members: "backdrop\\-invert(\\-0)?",
       },
       {
-        type: 'Backdrop Opacity',
-        members: 'backdrop\\-opacity\\-(0|5|(1-9)0|25|75|95|100)',
+        type: "Backdrop Opacity",
+        members: "backdrop\\-opacity\\-(0|5|(1-9)0|25|75|95|100)",
       },
       {
-        type: 'Backdrop Saturate',
-        members: 'backdrop\\-saturate\\-(0|50|100|150|200)',
+        type: "Backdrop Saturate",
+        members: "backdrop\\-saturate\\-(0|50|100|150|200)",
       },
       {
-        type: 'Backdrop Sepia',
-        members: 'backdrop\\-sepia(\\-0)?',
+        type: "Backdrop Sepia",
+        members: "backdrop\\-sepia(\\-0)?",
       },
     ],
   },
   {
-    type: 'TABLES',
+    type: "TABLES",
     members: [
       {
-        type: 'Border Collapse',
-        members: 'border\\-(collapse|separate)',
+        type: "Border Collapse",
+        members: "border\\-(collapse|separate)",
       },
       {
-        type: 'Table Layout',
-        members: 'table\\-(auto|fixed)',
+        type: "Table Layout",
+        members: "table\\-(auto|fixed)",
       },
     ],
   },
   {
-    type: 'TRANSITIONS AND ANIMATION',
+    type: "TRANSITIONS AND ANIMATION",
     members: [
       {
-        type: 'Transition Property',
-        members: 'transition(\\-(none|all|colors|opacity|shadow|transform))?',
+        type: "Transition Property",
+        members: "transition(\\-(none|all|colors|opacity|shadow|transform))?",
       },
       {
-        type: 'Transition Duration',
-        members: 'duration\\-(75|100|150|[2-3,5,7]00|1000)',
+        type: "Transition Duration",
+        members: "duration\\-(75|100|150|[2-3,5,7]00|1000)",
       },
       {
-        type: 'Transition Timing Function',
-        members: 'ease\\-(linear|in|out|in\\-out)',
+        type: "Transition Timing Function",
+        members: "ease\\-(linear|in|out|in\\-out)",
       },
       {
-        type: 'Transition Delay',
-        members: 'delay\\-(75|100|150|[2,3,5,7]00|1000)',
+        type: "Transition Delay",
+        members: "delay\\-(75|100|150|[2,3,5,7]00|1000)",
       },
       {
-        type: 'Animation',
-        members: 'animate\\-(none|spin|ping|pulse|bounce)',
+        type: "Animation",
+        members: "animate\\-(none|spin|ping|pulse|bounce)",
       },
     ],
   },
   {
-    type: 'TRANSFORMS',
+    type: "TRANSFORMS",
     members: [
       {
-        type: 'Transform',
-        members: 'transform(\\-(gpu|none))?',
+        type: "Transform",
+        members: "transform(\\-(gpu|none))?",
       },
       {
-        type: 'Transform Origin',
-        members: 'origin\\-(center|(top|bottom)(\\-(right|left))?|right|left)',
+        type: "Transform Origin",
+        members: "origin\\-(center|(top|bottom)(\\-(right|left))?|right|left)",
       },
       {
-        type: 'Scale',
+        type: "Scale",
         members: [
           {
-            type: 'scale',
-            members: 'scale\\-(0|50|75|90|95|1(00|05|10|25|50))',
+            type: "scale",
+            members: "scale\\-(0|50|75|90|95|1(00|05|10|25|50))",
           },
           {
-            type: 'scale-y',
-            members: 'scale\\-y\\-(0|50|75|90|95|1(00|05|10|25|50))',
+            type: "scale-y",
+            members: "scale\\-y\\-(0|50|75|90|95|1(00|05|10|25|50))",
           },
           {
-            type: 'scale-x',
-            members: 'scale\\-x\\-(0|50|75|90|95|1(00|05|10|25|50))',
+            type: "scale-x",
+            members: "scale\\-x\\-(0|50|75|90|95|1(00|05|10|25|50))",
           },
         ],
       },
       {
-        type: 'Rotate',
-        members: '\\-?rotate\\-([0-3]|6|12|45|90|180)',
+        type: "Rotate",
+        members: "\\-?rotate\\-([0-3]|6|12|45|90|180)",
       },
       {
-        type: 'Translate',
+        type: "Translate",
         members: [
           {
-            type: 'translate-x',
-            members: '\\-?translate\\-x\\-(\\d\\.?\\/?\\d?|px|full)',
+            type: "translate-x",
+            members: "\\-?translate\\-x\\-(\\d\\.?\\/?\\d?|px|full)",
           },
           {
-            type: 'translate-y',
-            members: '\\-?translate\\-y\\-(\\d\\.?\\/?\\d?|px|full)',
+            type: "translate-y",
+            members: "\\-?translate\\-y\\-(\\d\\.?\\/?\\d?|px|full)",
           },
         ],
       },
       {
-        type: 'Skew',
+        type: "Skew",
         members: [
           {
-            type: 'skew-x',
-            members: '\\-?skew\\-x\\-([0-3]|6|12)',
+            type: "skew-x",
+            members: "\\-?skew\\-x\\-([0-3]|6|12)",
           },
           {
-            type: 'skew-y',
-            members: '\\-?skew\\-y\\-([0-3]|6|12)',
+            type: "skew-y",
+            members: "\\-?skew\\-y\\-([0-3]|6|12)",
           },
         ],
       },
     ],
   },
   {
-    type: 'INTERACTIVITY',
+    type: "INTERACTIVITY",
     members: [
       {
-        type: 'Appearance',
-        members: 'appearance\\-none',
+        type: "Appearance",
+        members: "appearance\\-none",
       },
       {
-        type: 'Cursor',
-        members: 'cursor\\-(auto|default|pointer|wait|text|move|help|not\\-allowed)',
+        type: "Cursor",
+        members:
+          "cursor\\-(auto|default|pointer|wait|text|move|help|not\\-allowed)",
       },
       {
-        type: 'Outline',
-        members: 'outline\\-(none|white|black)',
+        type: "Outline",
+        members: "outline\\-(none|white|black)",
       },
       {
-        type: 'Pointer Events',
-        members: 'pointer\\-events\\-(none|auto)',
+        type: "Pointer Events",
+        members: "pointer\\-events\\-(none|auto)",
       },
       {
-        type: 'Resize',
-        members: 'resize(\\-(none|x|y))?',
+        type: "Resize",
+        members: "resize(\\-(none|x|y))?",
       },
       {
-        type: 'User Select',
-        members: 'select\\-(none|text|all|auto)',
+        type: "User Select",
+        members: "select\\-(none|text|all|auto)",
       },
     ],
   },
   {
-    type: 'SVG',
+    type: "SVG",
     members: [
       {
-        type: 'Fill',
-        members: 'fill\\-current',
+        type: "Fill",
+        members: "fill\\-current",
       },
       {
-        type: 'Stroke',
-        members: 'stroke\\-current',
+        type: "Stroke",
+        members: "stroke\\-current",
       },
       {
-        type: 'Stroke Width',
-        members: 'stroke\\-[0-2]',
+        type: "Stroke Width",
+        members: "stroke\\-[0-2]",
       },
     ],
   },
   {
-    type: 'ACCESSIBILITY',
+    type: "ACCESSIBILITY",
     members: [
       {
-        type: 'Screen Readers',
-        members: '(not\\-)?sr\\-only',
+        type: "Screen Readers",
+        members: "(not\\-)?sr\\-only",
       },
     ],
   },
   {
-    type: 'OFFICIAL PLUGINS',
+    type: "OFFICIAL PLUGINS",
     members: [
       {
-        type: 'Typography',
+        type: "Typography",
         members: [
           {
-            type: 'prose',
-            members: 'prose',
+            type: "prose",
+            members: "prose",
           },
           {
-            type: 'prose-modifier',
-            members: 'prose\\-(sm|lg|2?xl)',
+            type: "prose-modifier",
+            members: "prose\\-(sm|lg|2?xl)",
           },
         ],
       },
       // ('Forms' plugin has no related classnames, only selectors like `input[type='password']`)
       {
-        type: 'Aspect Ratio',
+        type: "Aspect Ratio",
         members: [
           {
-            type: 'aspect-w',
-            members: 'aspect\\-w\\-([1-9]|1[0-6])',
+            type: "aspect-w",
+            members: "aspect\\-w\\-([1-9]|1[0-6])",
           },
           {
-            type: 'aspect-h',
-            members: 'aspect\\-h\\-([1-9]|1[0-6])',
+            type: "aspect-h",
+            members: "aspect\\-h\\-([1-9]|1[0-6])",
           },
         ],
       },
       {
-        type: 'Line Clamp',
-        members: 'line\\-clamp\\-(none|[1-6])',
+        type: "Line Clamp",
+        members: "line\\-clamp\\-(none|[1-6])",
       },
     ],
   },
-];
\ No newline at end of file
+];
diff --git a/lib/index.js b/lib/index.js
index 72a7eef..d934ed6 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -2,18 +2,17 @@
  * @fileoverview Rules enforcing best practices while using Tailwind CSS
  * @author François Massart
  */
-'use strict';
+"use strict";
 
 //------------------------------------------------------------------------------
 // Requirements
 //------------------------------------------------------------------------------
 
-var requireIndex = require('requireindex');
+var requireIndex = require("requireindex");
 
 //------------------------------------------------------------------------------
 // Plugin Definition
 //------------------------------------------------------------------------------
 
-
 // import all rules in lib/rules
-module.exports.rules = requireIndex(__dirname + '/rules');
+module.exports.rules = requireIndex(__dirname + "/rules");
diff --git a/lib/rules/classnames-order.js b/lib/rules/classnames-order.js
index 7523c7d..04136d7 100644
--- a/lib/rules/classnames-order.js
+++ b/lib/rules/classnames-order.js
@@ -2,14 +2,14 @@
  * @fileoverview Use a consistent orders for the Tailwind CSS classnames, based on property then on variants
  * @author François Massart
  */
-'use strict';
+"use strict";
 
-const docsUrl = require('../util/docsUrl');
-const defaultGroups = require('../config/groups').groups;
-const astUtil = require('../util/ast');
-const attrUtil = require('../util/attr');
-const groupUtil = require('../util/groupMethods');
-const removeDuplicatesFromArray = require('../util/removeDuplicatesFromArray');
+const docsUrl = require("../util/docsUrl");
+const defaultGroups = require("../config/groups").groups;
+const astUtil = require("../util/ast");
+const attrUtil = require("../util/attr");
+const groupUtil = require("../util/groupMethods");
+const removeDuplicatesFromArray = require("../util/removeDuplicatesFromArray");
 
 //------------------------------------------------------------------------------
 // Rule Definition
@@ -17,37 +17,50 @@ const removeDuplicatesFromArray = require('../util/removeDuplicatesFromArray');
 
 // Predefine message for use in context.report conditional.
 // messageId will still be usable in tests.
-const INVALID_CLASSNAMES_ORDER_MSG = 'Invalid Tailwind CSS classenames order';
+const INVALID_CLASSNAMES_ORDER_MSG = "Invalid Tailwind CSS classenames order";
 
 module.exports = {
   meta: {
     docs: {
-      description: 'Enforce a consistent and logical order of the Tailwind CSS classnames',
-      category: 'Stylistic Issues',
+      description:
+        "Enforce a consistent and logical order of the Tailwind CSS classnames",
+      category: "Stylistic Issues",
       recommended: false,
-      url: docsUrl('classnames-order'),
+      url: docsUrl("classnames-order"),
     },
     messages: {
-      invalidOrder: INVALID_CLASSNAMES_ORDER_MSG
+      invalidOrder: INVALID_CLASSNAMES_ORDER_MSG,
     },
-    fixable: 'code',
-    schema: [{
-      type: 'object',
-      properties: {
-        prependCustom: {
-          default: false,
-          type: 'boolean',
+    fixable: "code",
+    schema: [
+      {
+        type: "object",
+        properties: {
+          callees: {
+            type: "array",
+            items: { type: "string", minLength: 0 },
+            uniqueItems: true,
+          },
+          groups: {
+            type: "array",
+            items: { type: "object" },
+          },
+          prependCustom: {
+            default: false,
+            type: "boolean",
+          },
+          removeDuplicates: {
+            default: true,
+            type: "boolean",
+          },
         },
-        removeDuplicates: {
-          default: true,
-          type: 'boolean',
-        }
-      }
-    }]
+      },
+    ],
   },
 
   create: function (context) {
     const configuration = context.options[0] || {};
+    const callees = configuration.callees || ["ctl"];
     const groupsConfig = configuration.groups || defaultGroups;
     const prependCustom = configuration.prependCustom || false;
     const removeDuplicates = !(configuration.removeDuplicates === false);
@@ -56,35 +69,86 @@ module.exports = {
     // Helpers
     //----------------------------------------------------------------------
     const getPrefixIndex = (str, arr, beginning = false) => {
-      const start = beginning ? '^' : '';
-      let idx = arr.findIndex(el => {
-
+      const start = beginning ? "^" : "";
+      let idx = arr.findIndex((el) => {
         const pattern = `${start}${el}\:.*`;
         const re = new RegExp(pattern);
-        return re.test(str)
+        return re.test(str);
       }, str);
       return idx;
     };
 
     const pad = (num, size = 2) => {
-      let str = '' + num;
+      let str = "" + num;
       while (str.length < size) {
-        str = '0' + str;
+        str = "0" + str;
       }
       return str;
     };
 
+    const getSortedGroups = (classNames) => {
+      // Init assets before sorting
+      const groups = groupUtil.getGroups(groupsConfig);
+      const sorted = groupUtil.initGroupSlots(groups);
+      const extras = [];
+
+      // Move each classname inside its dedicated group
+      classNames.forEach((className) => {
+        const trimmed = className.replace(/\s{1,}/g, "");
+        const idx = groupUtil.getGroupIndex(trimmed, groups);
+        if (idx > -1) {
+          sorted[idx].push(className);
+        } else {
+          extras.push(className);
+        }
+      });
+
+      // Sorts each groups' classnames
+      sorted.forEach((slot) => {
+        slot.sort(sortTailwindClasses);
+      });
+      return {
+        sorted,
+        extras,
+      };
+    };
+
     const getSpecificity = (val, arr, beginning = false) => {
       // Index can be -1, 0... Adding 1 for better readability
       return pad(getPrefixIndex(val, arr, beginning) + 1, 2);
     };
 
     const sortTailwindClasses = (a, b) => {
-      const responsiveVariants = ['sm', 'md', 'lg', 'xl', '2xl'];
-      const themeVariants = ['dark'];
-      const stateVariants = ['hover', 'focus', 'active', 'group-hover', 'group-focus', 'focus-within', 'focus-visible', 'motion-safe', 'motion-reduce', 'disabled', 'visited', 'checked', 'first', 'last', 'odd', 'even'];
-      const aIdxStr = `${getSpecificity(a, responsiveVariants, true)}${getSpecificity(a, themeVariants)}${getSpecificity(a, stateVariants)}`;
-      const bIdxStr = `${getSpecificity(b, responsiveVariants, true)}${getSpecificity(b, themeVariants)}${getSpecificity(b, stateVariants)}`;
+      const responsiveVariants = ["sm", "md", "lg", "xl", "2xl"];
+      const themeVariants = ["dark"];
+      const stateVariants = [
+        "hover",
+        "focus",
+        "active",
+        "group-hover",
+        "group-focus",
+        "focus-within",
+        "focus-visible",
+        "motion-safe",
+        "motion-reduce",
+        "disabled",
+        "visited",
+        "checked",
+        "first",
+        "last",
+        "odd",
+        "even",
+      ];
+      const aIdxStr = `${getSpecificity(
+        attrUtil.cleanClassname(a),
+        responsiveVariants,
+        true
+      )}${getSpecificity(a, themeVariants)}${getSpecificity(a, stateVariants)}`;
+      const bIdxStr = `${getSpecificity(
+        attrUtil.cleanClassname(b),
+        responsiveVariants,
+        true
+      )}${getSpecificity(b, themeVariants)}${getSpecificity(b, stateVariants)}`;
       const aIdx = parseInt(aIdxStr, 10);
       const bIdx = parseInt(bIdxStr, 10);
       if (aIdx < bIdx) {
@@ -94,7 +158,7 @@ module.exports = {
         return 1;
       }
       return 0;
-    }
+    };
 
     //----------------------------------------------------------------------
     // Public
@@ -106,7 +170,9 @@ module.exports = {
         }
 
         const originalClassNamesValue = node.value.value;
-        let classNames = attrUtil.getClassNamesFromAttribute(originalClassNamesValue);
+        let classNames = attrUtil.getClassNamesFromAttribute(
+          originalClassNamesValue
+        );
         if (removeDuplicates) {
           classNames = removeDuplicatesFromArray(classNames);
         }
@@ -115,40 +181,99 @@ module.exports = {
           return;
         }
 
-        // Init assets before sorting
-        const groups = groupUtil.getGroups(groupsConfig);
-        const sorted = groupUtil.initGroupSlots(groups);
-        const extras = [];
-
-        // Move each classname inside its dedicated group
-        classNames.forEach(className => {
-          const idx = groupUtil.getGroupIndex(className, groups);
-          if (idx > -1) {
-            sorted[idx].push(className);
-          } else {
-            extras.push(className);
-          }
-        });
-
-        // Sorts each groups' classnames
-        sorted.forEach(slot => {
-          slot.sort(sortTailwindClasses);
-        });
+        // Sorting
+        const { sorted, extras } = getSortedGroups(classNames);
 
         // Generates the validated/sorted attribute value
         const flatted = sorted.flat();
-        const union = prependCustom ? [...extras, ...flatted] : [...flatted, ...extras];
-        const validatedClassNamesValue = union.join(' ');
+        const union = prependCustom
+          ? [...extras, ...flatted]
+          : [...flatted, ...extras];
+        const validatedClassNamesValue = union.join(" ");
         if (originalClassNamesValue !== validatedClassNamesValue) {
           context.report({
             node: node,
-            messageId: 'invalidOrder',
+            messageId: "invalidOrder",
             fix: function (fixer) {
-              return fixer.replaceText(node.value, `"${validatedClassNamesValue}"`);
-            }
+              return fixer.replaceTextRange(
+                [node.value.range[0] + 1, node.value.range[1] - 1],
+                validatedClassNamesValue
+              );
+            },
           });
         }
-      }
+      },
+      CallExpression: function (node) {
+        if (callees.findIndex((name) => node.callee.name === name) === -1) {
+          return;
+        }
+        if (node.arguments.length !== 1) {
+          return;
+        }
+        const arg = node.arguments[0];
+        if (arg.type !== "TemplateLiteral" || !arg.quasis.length) {
+          return;
+        }
+        arg.quasis.forEach((quasis) => {
+          // Will sort each quasis in isolation
+          const originalClassNamesValue = quasis.value.raw;
+
+          let classNames = attrUtil.getClassNamesFromAttribute(
+            originalClassNamesValue
+          );
+          const isSingleLine = attrUtil.isSingleLine(originalClassNamesValue);
+          let before = null;
+          let after = null;
+
+          if (!isSingleLine) {
+            const spacesOnly = /^(\s)*$/;
+            if (spacesOnly.test(classNames[0])) {
+              before = classNames.shift();
+            }
+            if (spacesOnly.test(classNames[classNames.length - 1])) {
+              after = classNames.pop();
+            }
+          }
+
+          if (removeDuplicates) {
+            classNames = removeDuplicatesFromArray(classNames);
+          }
+          if (classNames.length <= 1) {
+            // Don't run for a single or empty className
+            return;
+          }
+
+          // Sorting
+          const { sorted, extras } = getSortedGroups(classNames);
+
+          // Generates the validated/sorted attribute value
+          const flatted = sorted.flat();
+          const union = prependCustom
+            ? [...extras, ...flatted]
+            : [...flatted, ...extras];
+          if (before !== null) {
+            union.unshift(before);
+          }
+          if (after !== null) {
+            union.push(after);
+          }
+          const validatedClassNamesValue = union.join(
+            isSingleLine ? " " : "\n"
+          );
+          if (originalClassNamesValue !== validatedClassNamesValue) {
+            context.report({
+              node: node,
+              messageId: "invalidOrder",
+              fix: function (fixer) {
+                return fixer.replaceTextRange(
+                  [quasis.range[0] + 1, quasis.range[1] - 2],
+                  validatedClassNamesValue
+                );
+              },
+            });
+          }
+        });
+      },
     };
-  }
+  },
 };
diff --git a/lib/rules/no-contradicting-classname.js b/lib/rules/no-contradicting-classname.js
index 5919f88..edc4d62 100644
--- a/lib/rules/no-contradicting-classname.js
+++ b/lib/rules/no-contradicting-classname.js
@@ -2,14 +2,14 @@
  * @fileoverview Avoid contradicting Tailwind CSS classnames (e.g. "w-3 w-5")
  * @author François Massart
  */
-'use strict';
+"use strict";
 
-const docsUrl = require('../util/docsUrl');
-const defaultGroups = require('../config/groups').groups;
-const astUtil = require('../util/ast');
-const attrUtil = require('../util/attr');
-const groupUtil = require('../util/groupMethods');
-const removeDuplicatesFromArray = require('../util/removeDuplicatesFromArray');
+const docsUrl = require("../util/docsUrl");
+const defaultGroups = require("../config/groups").groups;
+const astUtil = require("../util/ast");
+const attrUtil = require("../util/attr");
+const groupUtil = require("../util/groupMethods");
+const removeDuplicatesFromArray = require("../util/removeDuplicatesFromArray");
 
 //------------------------------------------------------------------------------
 // Rule Definition
@@ -22,20 +22,20 @@ const CONFLICTING_CLASSNAMES_DETECTED_MSG = `Classnames {{classnames}} are confl
 module.exports = {
   meta: {
     docs: {
-      description: 'Avoid contradicting Tailwind CSS classnames (e.g. "w- 3 w- 5")',
-      category: 'Possible Errors',
+      description:
+        'Avoid contradicting Tailwind CSS classnames (e.g. "w- 3 w- 5")',
+      category: "Possible Errors",
       recommended: false,
-      url: docsUrl('no-contradicting-classname'),
+      url: docsUrl("no-contradicting-classname"),
     },
     messages: {
-      conflictingClassnames: CONFLICTING_CLASSNAMES_DETECTED_MSG
+      conflictingClassnames: CONFLICTING_CLASSNAMES_DETECTED_MSG,
     },
     fixable: null,
-    schema: []
+    schema: [],
   },
 
   create: function (context) {
-
     // variables should be defined here
 
     //----------------------------------------------------------------------
@@ -55,7 +55,9 @@ module.exports = {
         }
 
         const originalClassNamesValue = node.value.value;
-        let classNames = attrUtil.getClassNamesFromAttribute(originalClassNamesValue);
+        let classNames = attrUtil.getClassNamesFromAttribute(
+          originalClassNamesValue
+        );
         classNames = removeDuplicatesFromArray(classNames);
         if (classNames.length <= 1) {
           // Don't run for a single or empty className
@@ -67,49 +69,49 @@ module.exports = {
         const sorted = groupUtil.initGroupSlots(groups);
 
         // Move each classname inside its dedicated group
-        classNames.forEach(className => {
+        classNames.forEach((className) => {
           const idx = groupUtil.getGroupIndex(className, groups);
           if (idx > -1) {
             sorted[idx].push(className);
           }
         });
 
-        classNames = sorted.filter(slot => slot.length > 1);
+        classNames = sorted.filter((slot) => slot.length > 1);
 
         // Sorts each groups' classnames
-        classNames.forEach(slot => {
+        classNames.forEach((slot) => {
           const variants = [];
-          slot.forEach(cls => {
-            const start = cls.lastIndexOf(':') + 1;
+          slot.forEach((cls) => {
+            const start = cls.lastIndexOf(":") + 1;
             const prefix = cls.substr(0, start);
             const name = cls.substr(start);
-            const rePrefix = prefix === '' ? '((?!:).)*$' : prefix;
-            const idx = variants.findIndex(v => v.prefix === rePrefix);
+            const rePrefix = prefix === "" ? "((?!:).)*$" : prefix;
+            const idx = variants.findIndex((v) => v.prefix === rePrefix);
             if (idx === -1) {
               variants.push({
                 prefix: rePrefix,
-                name: [name]
+                name: [name],
               });
             } else {
               variants[idx].name.push(name);
             }
           });
-          const troubles = variants.filter(v => v.name.length > 1);
+          const troubles = variants.filter((v) => v.name.length > 1);
           if (troubles.length) {
-            troubles.forEach(t => {
-              const re = new RegExp('^' + t.prefix);
-              const conflicting = slot.filter(c => re.test(c));
+            troubles.forEach((t) => {
+              const re = new RegExp("^" + t.prefix);
+              const conflicting = slot.filter((c) => re.test(c));
               context.report({
                 node: node,
-                messageId: 'conflictingClassnames',
+                messageId: "conflictingClassnames",
                 data: {
-                  classnames: conflicting.join(', ')
-                }
+                  classnames: conflicting.join(", "),
+                },
               });
             });
           }
         });
-      }
+      },
     };
-  }
+  },
 };
diff --git a/lib/rules/no-custom-classname.js b/lib/rules/no-custom-classname.js
index 500ce93..6c9f124 100644
--- a/lib/rules/no-custom-classname.js
+++ b/lib/rules/no-custom-classname.js
@@ -2,15 +2,14 @@
  * @fileoverview Detect classnames which do not belong to Tailwind CSS
  * @author no-custom-classname
  */
-'use strict';
-
-const docsUrl = require('../util/docsUrl');
-const defaultGroups = require('../config/groups').groups;
-const astUtil = require('../util/ast');
-const attrUtil = require('../util/attr');
-const groupUtil = require('../util/groupMethods');
-const removeDuplicatesFromArray = require('../util/removeDuplicatesFromArray');
+"use strict";
 
+const docsUrl = require("../util/docsUrl");
+const defaultGroups = require("../config/groups").groups;
+const astUtil = require("../util/ast");
+const attrUtil = require("../util/attr");
+const groupUtil = require("../util/groupMethods");
+const removeDuplicatesFromArray = require("../util/removeDuplicatesFromArray");
 
 //------------------------------------------------------------------------------
 // Rule Definition
@@ -23,20 +22,19 @@ const CUSTOM_CLASSNAME_DETECTED_MSG = `Classname '{{classname}}' is not a Tailwi
 module.exports = {
   meta: {
     docs: {
-      description: 'Detect classnames which do not belong to Tailwind CSS',
-      category: 'Best Practices',
+      description: "Detect classnames which do not belong to Tailwind CSS",
+      category: "Best Practices",
       recommended: false,
-      url: docsUrl('no-custom-classname'),
+      url: docsUrl("no-custom-classname"),
     },
     messages: {
-      customClassnameDetected: CUSTOM_CLASSNAME_DETECTED_MSG
+      customClassnameDetected: CUSTOM_CLASSNAME_DETECTED_MSG,
     },
-    fixable: 'code',
-    schema: []
+    fixable: "code",
+    schema: [],
   },
 
   create: function (context) {
-
     // variables should be defined here
 
     //----------------------------------------------------------------------
@@ -56,7 +54,9 @@ module.exports = {
         }
 
         const originalClassNamesValue = node.value.value;
-        let classNames = attrUtil.getClassNamesFromAttribute(originalClassNamesValue);
+        let classNames = attrUtil.getClassNamesFromAttribute(
+          originalClassNamesValue
+        );
         classNames = removeDuplicatesFromArray(classNames);
         if (classNames.length <= 1) {
           // Don't run for a single or empty className
@@ -65,20 +65,19 @@ module.exports = {
 
         const groups = groupUtil.getGroups(defaultGroups);
 
-        classNames.forEach(className => {
+        classNames.forEach((className) => {
           const idx = groupUtil.getGroupIndex(className, groups);
           if (idx === -1) {
             context.report({
               node,
-              messageId: 'customClassnameDetected',
+              messageId: "customClassnameDetected",
               data: {
-                classname: className
-              }
+                classname: className,
+              },
             });
           }
         });
-
       },
     };
-  }
+  },
 };
diff --git a/lib/util/ast.js b/lib/util/ast.js
index 3528e0e..a33802b 100644
--- a/lib/util/ast.js
+++ b/lib/util/ast.js
@@ -2,7 +2,7 @@
  * @fileoverview Utility functions for AST
  */
 
-'use strict';
+"use strict";
 
 /**
  * Find out if node is `class` or `className`
@@ -21,9 +21,9 @@ function isClassAttribute(node) {
  * @returns {Boolean}
  */
 function isLitteralAttributeValue(node) {
-  if (node.value && node.value.type === 'Literal') {
+  if (node.value && node.value.type === "Literal") {
     // No support for dynamic or conditional...
-    return !/\{|\?|\}/.test(node.value.value)
+    return !/\{|\?|\}/.test(node.value.value);
   }
   return false;
 }
@@ -50,4 +50,4 @@ module.exports = {
   isClassAttribute,
   isLitteralAttributeValue,
   isValidJSXAttribute,
-};
\ No newline at end of file
+};
diff --git a/lib/util/attr.js b/lib/util/attr.js
index babc398..8826fa5 100644
--- a/lib/util/attr.js
+++ b/lib/util/attr.js
@@ -1,17 +1,41 @@
 /**
- * Convert a class[Name] attribute's values to an array of classnames
+ * Clean classname from spaces
+ *
+ * @param {string} str The attribute's value
+ * @returns {String}
+ */
+function cleanClassname(str) {
+  return str.replace(/\s{1,}/g, "");
+}
+
+/**
+ * Confirms that attribute value is on a single line
  *
- * @param {string} attr The attribute's value
+ * @param {string} str The attribute's value
  * @returns {Boolean}
  */
-function getClassNamesFromAttribute(attr) {
-  // Fix multiple spaces
-  attr = attr.replace(/\s{2,}/g, ' ');
-  // Array of unique classNames
-  let classesArray = attr.split(' ');
-  return classesArray;
+function isSingleLine(str) {
+  return str.indexOf("\n") === -1;
+}
+
+/**
+ * Convert a class[Name] attribute's values to an array of classnames
+ *
+ * @param {string} attrVal The attribute's value
+ * @returns {Array}
+ */
+function getClassNamesFromAttribute(attrVal) {
+  if (isSingleLine(attrVal)) {
+    // Fix multiple spaces
+    attrVal = attrVal.replace(/\s{2,}/g, " ");
+    return attrVal.split(" ");
+  } else {
+    return attrVal.split("\n");
+  }
 }
 
 module.exports = {
+  cleanClassname,
+  isSingleLine,
   getClassNamesFromAttribute,
-};
\ No newline at end of file
+};
diff --git a/lib/util/docsUrl.js b/lib/util/docsUrl.js
index 496e42c..587764a 100644
--- a/lib/util/docsUrl.js
+++ b/lib/util/docsUrl.js
@@ -1,4 +1,4 @@
-'use strict';
+"use strict";
 
 // Copied from https://github.com/yannickcr/eslint-plugin-react/blob/master/lib/util/docsUrl.js
 function docsUrl(ruleName) {
diff --git a/lib/util/groupMethods.js b/lib/util/groupMethods.js
index 2700b5c..ef85649 100644
--- a/lib/util/groupMethods.js
+++ b/lib/util/groupMethods.js
@@ -2,28 +2,28 @@
  * @fileoverview Utilities used for grouping classnames
  */
 
-'use strict';
+"use strict";
 
 /**
  * Generates a flatten array from the groups config
  *
  * @param {Array} config The array of objects containing the regex
- * @returns {Array} Flatten array 
+ * @returns {Array} Flatten array
  */
 function getGroups(config) {
   const groups = [];
-  config.forEach(group => {
+  config.forEach((group) => {
     // e.g. SIZING or SPACING
-    group.members.forEach(prop => {
+    group.members.forEach((prop) => {
       // e.g. Width or Padding
-      if (typeof prop.members === 'string') {
+      if (typeof prop.members === "string") {
         // Unique property, like `width` limited to one value
         groups.push(prop.members);
       } else {
         // Multiple properties, like `padding`, `padding-top`...
-        prop.members.forEach(subprop => {
+        prop.members.forEach((subprop) => {
           groups.push(subprop.members);
-        })
+        });
       }
     });
   });
@@ -34,11 +34,11 @@ function getGroups(config) {
  * Generates an array of empty arrays prior to grouping
  *
  * @param {Array} groups The array of objects containing the regex
- * @returns {Array} Array of empty arrays 
+ * @returns {Array} Array of empty arrays
  */
 function initGroupSlots(groups) {
   const slots = [];
-  groups.forEach(g => slots.push([]));
+  groups.forEach((g) => slots.push([]));
   return slots;
 }
 
@@ -47,19 +47,19 @@ function initGroupSlots(groups) {
  *
  * @param {Array} name The target classname
  * @param {Array} arr The flatten array containing the regex
- * @returns {Array} Array of empty arrays 
+ * @returns {Array} Array of empty arrays
  */
 function getGroupIndex(name, arr) {
   const classSuffix = getSuffix(name);
-  let idx = arr.findIndex(pattern => {
+  let idx = arr.findIndex((pattern) => {
     const classRe = new RegExp(`^${pattern}$`);
-    return classRe.test(classSuffix)
+    return classRe.test(classSuffix);
   }, classSuffix);
   return idx;
 }
 
 function getSuffix(className) {
-  return className.split(':').pop();
+  return className.split(":").pop();
 }
 
 module.exports = {
diff --git a/lib/util/removeDuplicatesFromArray.js b/lib/util/removeDuplicatesFromArray.js
index 6301fe4..fda64e6 100644
--- a/lib/util/removeDuplicatesFromArray.js
+++ b/lib/util/removeDuplicatesFromArray.js
@@ -1,4 +1,4 @@
-'use strict';
+"use strict";
 
 function removeDuplicatesFromArray(arr) {
   return [...new Set(arr)];


Test patch:
diff --git a/tests/lib/rules/classnames-order.js b/tests/lib/rules/classnames-order.js
index 3a8f346..9a38cd9 100644
--- a/tests/lib/rules/classnames-order.js
+++ b/tests/lib/rules/classnames-order.js
@@ -2,15 +2,14 @@
  * @fileoverview Use a consistent orders for the Tailwind CSS classnames, based on property then on variants
  * @author François Massart
  */
-'use strict';
+"use strict";
 
 //------------------------------------------------------------------------------
 // Requirements
 //------------------------------------------------------------------------------
 
-var rule = require('../../../lib/rules/classnames-order');
-var RuleTester = require('eslint').RuleTester;
-
+var rule = require("../../../lib/rules/classnames-order");
+var RuleTester = require("eslint").RuleTester;
 
 //------------------------------------------------------------------------------
 // Tests
@@ -18,7 +17,7 @@ var RuleTester = require('eslint').RuleTester;
 
 var parserOptions = {
   ecmaVersion: 2019,
-  sourceType: 'module',
+  sourceType: "module",
   ecmaFeatures: {
     jsx: true,
   },
@@ -26,23 +25,39 @@ var parserOptions = {
 
 var ruleTester = new RuleTester({ parserOptions });
 
-var errors = [{
-  messageId: 'invalidOrder',
-}];
+var errors = [
+  {
+    messageId: "invalidOrder",
+  },
+];
 
-ruleTester.run('classnames-order', rule, {
+ruleTester.run("classnames-order", rule, {
   valid: [
     {
       code: `<div class="container box-content lg:box-border custom">Simple, basic</div>`,
     },
+    {
+      code: `<div class='box-content lg:box-border'>Simple quotes</div>`,
+    },
     {
       code: `<div class="p-5 lg:p-4 md:py-2 sm:px-3 xl:px-6">'p', then 'py' then 'px'</div>`,
     },
     {
       code: `<div class="custom another-custom w-12 lg:w-6">prependCustom: true</div>`,
-      options: [{
-        prependCustom: true,
-      }],
+      options: [
+        {
+          prependCustom: true,
+        },
+      ],
+    },
+    {
+      code: `ctl(\`
+        container
+        flex
+        w-12
+        sm:w-6
+        lg:w-4
+      \`)`,
     },
   ],
   invalid: [
@@ -77,9 +92,16 @@ ruleTester.run('classnames-order', rule, {
       errors: errors,
     },
     {
-      options: [{
-        removeDuplicates: false,
-      }],
+      code: `<div class='lg:box-border box-content'>Simple quotes</div>`,
+      output: `<div class='box-content lg:box-border'>Simple quotes</div>`,
+      errors: errors,
+    },
+    {
+      options: [
+        {
+          removeDuplicates: false,
+        },
+      ],
       code: `<div class="w-12 lg:w-6 w-12">removeDuplicates: false</div>`,
       output: `<div class="w-12 w-12 lg:w-6">removeDuplicates: false</div>`,
       errors: errors,
@@ -89,5 +111,77 @@ ruleTester.run('classnames-order', rule, {
       output: `<div class="w-12 lg:w-6">Multiple spaces</div>`,
       errors: errors,
     },
+    {
+      code: `
+      ctl(\`
+        invalid
+        sm:w-6
+        container
+        w-12
+        flex
+        lg:w-4
+      \`);`,
+      output: `
+      ctl(\`
+        container
+        flex
+        w-12
+        sm:w-6
+        lg:w-4
+        invalid
+       \`);`,
+      errors: errors,
+    },
+    {
+      code: `
+      const buttonClasses = ctl(\`
+        \${fullWidth ? "w-12" : "w-6"}
+        container
+        \${fullWidth ? "sm:w-12" : "sm:w-4"}
+        lg:w-4
+        flex
+        \${hasError && "bg-red"}
+      \`);`,
+      output: `
+      const buttonClasses = ctl(\`
+        \${fullWidth ? "w-12" : "w-6"}
+        container
+        \${fullWidth ? "sm:w-12" : "sm:w-4"}
+        flex
+        lg:w-4
+        \${hasError && "bg-red"}
+      \`);`,
+      errors: errors,
+    },
+    {
+      code: `
+      const buttonClasses = ctl(\`
+        \${fullWidth ? "w-12" : "w-6"}
+        flex
+        container
+        \${fullWidth ? "sm:w-12" : "sm:w-4"}
+        lg:py-4
+        sm:py-6
+        \${hasError && "bg-red"}
+      \`);`,
+      output: `
+      const buttonClasses = ctl(\`
+        \${fullWidth ? "w-12" : "w-6"}
+        container
+        flex
+        \${fullWidth ? "sm:w-12" : "sm:w-4"}
+        sm:py-6
+        lg:py-4
+        \${hasError && "bg-red"}
+      \`);`,
+      errors: [
+        {
+          messageId: "invalidOrder",
+        },
+        {
+          messageId: "invalidOrder",
+        },
+      ],
+    },
   ],
 });
diff --git a/tests/lib/rules/no-contradicting-classname.js b/tests/lib/rules/no-contradicting-classname.js
index a626321..560cb46 100644
--- a/tests/lib/rules/no-contradicting-classname.js
+++ b/tests/lib/rules/no-contradicting-classname.js
@@ -2,16 +2,14 @@
  * @fileoverview Avoid contradicting Tailwind CSS classnames (e.g. 'w-3 w-5')
  * @author François Massart
  */
-'use strict';
+"use strict";
 
 //------------------------------------------------------------------------------
 // Requirements
 //------------------------------------------------------------------------------
 
-var rule = require('../../../lib/rules/no-contradicting-classname'),
-
-  RuleTester = require('eslint').RuleTester;
-
+var rule = require("../../../lib/rules/no-contradicting-classname");
+var RuleTester = require("eslint").RuleTester;
 
 //------------------------------------------------------------------------------
 // Tests
@@ -19,7 +17,7 @@ var rule = require('../../../lib/rules/no-contradicting-classname'),
 
 var parserOptions = {
   ecmaVersion: 2019,
-  sourceType: 'module',
+  sourceType: "module",
   ecmaFeatures: {
     jsx: true,
   },
@@ -27,11 +25,11 @@ var parserOptions = {
 
 var ruleTester = new RuleTester({ parserOptions });
 
-ruleTester.run('no-contradicting-classname', rule, {
-
+ruleTester.run("no-contradicting-classname", rule, {
   valid: [
     {
-      code: '<div class="overflow-auto overflow-x-hidden lg:overflow-x-auto lg:dark:overflow-x-visible lg:dark:active:overflow-x-visible active:overflow-auto"></div>',
+      code:
+        '<div class="overflow-auto overflow-x-hidden lg:overflow-x-auto lg:dark:overflow-x-visible lg:dark:active:overflow-x-visible active:overflow-auto"></div>',
     },
     {
       code: '<div class="p-1 px-2 sm:px-3 sm:pt-0">Accepts shorthands</div>',
@@ -43,29 +41,30 @@ ruleTester.run('no-contradicting-classname', rule, {
       code: '<div class="container w-1 w-2"></div>',
       errors: [
         {
-          messageId: 'conflictingClassnames',
+          messageId: "conflictingClassnames",
           data: {
-            classnames: 'w-1, w-2'
-          }
-        }
-      ]
+            classnames: "w-1, w-2",
+          },
+        },
+      ],
     },
     {
-      code: '<div class="flex-1 order-first order-11 sm:order-last flex-none "></div>',
+      code:
+        '<div class="flex-1 order-first order-11 sm:order-last flex-none "></div>',
       errors: [
         {
-          messageId: 'conflictingClassnames',
+          messageId: "conflictingClassnames",
           data: {
-            classnames: 'flex-1, flex-none'
-          }
+            classnames: "flex-1, flex-none",
+          },
         },
         {
-          messageId: 'conflictingClassnames',
+          messageId: "conflictingClassnames",
           data: {
-            classnames: 'order-first, order-11'
-          }
+            classnames: "order-first, order-11",
+          },
         },
-      ]
+      ],
     },
-  ]
+  ],
 });
diff --git a/tests/lib/rules/no-custom-classname.js b/tests/lib/rules/no-custom-classname.js
index 38e4f45..5e53cf1 100644
--- a/tests/lib/rules/no-custom-classname.js
+++ b/tests/lib/rules/no-custom-classname.js
@@ -2,15 +2,14 @@
  * @fileoverview Detect classnames which do not belong to Tailwind CSS
  * @author no-custom-classname
  */
-'use strict';
+"use strict";
 
 //------------------------------------------------------------------------------
 // Requirements
 //------------------------------------------------------------------------------
 
-var rule = require('../../../lib/rules/no-custom-classname');
-var RuleTester = require('eslint').RuleTester;
-
+var rule = require("../../../lib/rules/no-custom-classname");
+var RuleTester = require("eslint").RuleTester;
 
 //------------------------------------------------------------------------------
 // Tests
@@ -18,7 +17,7 @@ var RuleTester = require('eslint').RuleTester;
 
 var parserOptions = {
   ecmaVersion: 2019,
-  sourceType: 'module',
+  sourceType: "module",
   ecmaFeatures: {
     jsx: true,
   },
@@ -26,8 +25,7 @@ var parserOptions = {
 
 var ruleTester = new RuleTester({ parserOptions });
 
-ruleTester.run('no-custom-classname', rule, {
-
+ruleTester.run("no-custom-classname", rule, {
   valid: [
     {
       code: `<div class="container box-content lg:box-border">Only Tailwind CSS classnames</div>`,
@@ -37,29 +35,31 @@ ruleTester.run('no-custom-classname', rule, {
   invalid: [
     {
       code: `<div class="w-12 my-custom">my-custom is not defined in Tailwind CSS!</div>`,
-      errors: [{
-        messageId: 'customClassnameDetected',
-        data: {
-          classname: 'my-custom'
-        }
-      }]
+      errors: [
+        {
+          messageId: "customClassnameDetected",
+          data: {
+            classname: "my-custom",
+          },
+        },
+      ],
     },
     {
       code: `<div class="hello world">2 classnames are not defined in Tailwind CSS!</div>`,
       errors: [
         {
-          messageId: 'customClassnameDetected',
+          messageId: "customClassnameDetected",
           data: {
-            classname: 'hello'
-          }
+            classname: "hello",
+          },
         },
         {
-          messageId: 'customClassnameDetected',
+          messageId: "customClassnameDetected",
           data: {
-            classname: 'world'
-          }
+            classname: "world",
+          },
         },
-      ]
+      ],
     },
-  ]
+  ],
 });