heybourn / headwind

An opinionated Tailwind CSS class sorter built for Visual Studio Code
https://marketplace.visualstudio.com/items?itemName=heybourn.headwind
MIT License
1.39k stars 44 forks source link

Here is a regex that works for React and Preact JSX/TSX "class" and "className" with + without brackets =) #85

Open GavinRay97 opened 4 years ago

GavinRay97 commented 4 years ago

Had a friend who writes React ask about this and helped him figure out a working regex, here it is:

"headwind.classRegex": {
  "javascriptreact": "(?:\\b(?:class|className)?\\s*=\\s*{?[\\\"\\']([_a-zA-Z0-9\\s\\-\\:/]+)[\\\"\\']}?)",
  "typescriptreact": "(?:\\b(?:class|className)?\\s*=\\s*{?[\\\"\\']([_a-zA-Z0-9\\s\\-\\:/]+)[\\\"\\']}?)"
}

headwind-regex

aeonthread commented 4 years ago

@GavinRay97 this solved my problem thank you

jlarmstrongiv commented 3 years ago

And for twin.macro while we’re at it:

{
  "headwind.classRegex": {
    "typescriptreact": "(?:\\b(?:class|className|tw)?\\.?\\w?\\s*=*\\s*{?[\\\"\\'\\`]([_a-zA-Z0-9\\s\\-\\:/]+)[\\\"\\'\\`]}?)",
    "javascriptreact": "(?:\\b(?:class|className|tw)?\\.?\\w?\\s*=*\\s*{?[\\\"\\'\\`]([_a-zA-Z0-9\\s\\-\\:/]+)[\\\"\\'\\`]}?)"
  }
}

The debugging example in the README is super helpful and the only thing after that is escaping the regex.

j0hnm4r5 commented 3 years ago

Here's a slightly more full-featured regex for twin.macro:

"headwind.classRegex": {
    "javascript": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]([\\w\\s\\-\\:\\[\\]]+)[\\\"\\'\\`]}?)",
    "javascriptreact": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]([\\w\\s\\-\\:\\[\\]]+)[\\\"\\'\\`]}?)",
    "typescript": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]([\\w\\s\\-\\:\\[\\]]+)[\\\"\\'\\`]}?)",
    "typescriptreact": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]([\\w\\s\\-\\:\\[\\]]+)[\\\"\\'\\`]}?)"
},

I'm new to regex, so I just want to break it down (more for my sanity that anything else):

bbugh commented 3 years ago

That regex is wonderful, thank you @j0hnm4r5! But there's a few problems with it:

Here's one that fixes these issues:

  "headwind.classRegex": {
    "javascript": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]|\\$\\{(.*?)\\})+)[\\\"\\'\\`]}?)",
    "javascriptreact": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]|\\$\\{(.*?)\\})+)[\\\"\\'\\`]}?)",
    "typescript": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]|\\$\\{(.*?)\\})+)[\\\"\\'\\`]}?)",
    "typescriptreact": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]|\\$\\{(.*?)\\})+)[\\\"\\'\\`]}?)"
  },

Here is the regexr for the new regex with all passing tests:

KnifeFed commented 3 years ago

\^ Does this regex sort JIT mode correctly, e.g. w-[10px]?

bbugh commented 2 years ago

@KnifeFed no, headwind itself doesn't support JIT.

valflrt commented 1 year ago

Thank you so much for your regex @bbugh. I'm not a regexpert (aha) but something is missing in your regex:

When some tailwind classes are set as important, the regex doesn't work... (I'm working on tsx files)

Example:

<div className={"!class1 !class2 ..."}></div>

Hope you could fix it ! Thank you again :)

Edit: I think I fixed it myself:

- (?:\b(?:class|className|tw)(?:=(?:{\s*)?)?(?:\.\w*)?(?:\(\s*\w*\s*\))?[\"\'\`]((?:[\w\s\-\/\:\.\[\]]|\$\{(.*?)\})+)[\"\'\`]}?)
+ (?:\b(?:class|className|tw)(?:=(?:{\s*)?)?(?:\.\w*)?(?:\(\s*\w*\s*\))?[\"\'\`]((?:[\w\s\-\/\:\.\[\]]\!?|\$\{(.*?)\}))+[\"\'\`]}?)
  "headwind.classRegex": {
    "javascript": "/(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]\\!?|\\$\\{(.*?)\\}))+[\\\"\\'\\`]}?)/",
    "javascriptreact": "/(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]\\!?|\\$\\{(.*?)\\}))+[\\\"\\'\\`]}?)/",
    "typescript": "/(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]\\!?|\\$\\{(.*?)\\}))+[\\\"\\'\\`]}?)/",
    "typescriptreact": "/(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]\\!?|\\$\\{(.*?)\\}))+[\\\"\\'\\`]}?)/"
  },

Edit 2: I think it doesn't work