How to customize Regex for Headwind

Photo by Andy Holmes on Unsplash

How to customize Regex for Headwind

ยท

2 min read

The situation

I've just worked with Tailwind CSS recently. But found managing a bunch of className is a nightmare. And I found Headwind as a solution. It helps organize Tailwind className in a specific order, removes duplication.

Headwind is an opinionated Tailwind CSS class sorter for Visual Studio Code. It enforces consistent ordering of classes by parsing your code and reprinting class tags to follow a given order.

Tested with some tailwind components out there on the internet, it works great but when comes to my code, it does not work. Then, i found that it does not implement to recognize className in clsx function.

First effort

Reading the README.MD, I decided to add a custom regex for clsx to my vscode workspace at .vscode\settings.json:

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

I tested with regex101.com, but it failed to work. After searching headwind repo, I found that... I must reload the window (ctrl+shift+p => type: reload window)

Come to check again if it works or not. Bummm... ๐Ÿ’ฅ it works BUT... it now does not recognize the original cases with class and className. hmm, it seem my headwind use the method replace but not combine the custom regex with their default regex.

Second effort

No problem, after search headwin repo again, I found their default regex at https://github.com/heybourn/headwind/blob/master/package.json. Then, I tried to update my setting.json again as following:

{
    ...
    "headwind.classRegex": {
        "javascriptreact": [
            "(?:\\b(?:class(?:Name)?|tw)\\s*=\\s*(?:(?:{([\\w\\d\\s!?_\\-:/${}()[\\]\"'`,]+)})|([\"'`][\\w\\d\\s_\\-:/]+[\"'`])))",
            "(?:[\"'`]([\\.\\w\\d\\s_\\-:/${}()[\\]]+)[\"'`])",
            "(?:\\bclsx\\s*\\(\\s*{?[\"\\']([_a-zA-Z0-9\\s\\-\\:\/]+)[\"\\'])|(?:\btw\\s*([_a-zA-Z0-9\\s\\-\\:\/]*))"
        ],
        "typescriptreact": [
            "(?:\\b(?:class(?:Name)?|tw)\\s*=\\s*(?:(?:{([\\w\\d\\s!?_\\-:/${}()[\\]\"'`,]+)})|([\"'`][\\w\\d\\s_\\-:/]+[\"'`])))",
            "(?:[\"'`]([\\.\\w\\d\\s_\\-:/${}()[\\]]+)[\"'`])",
            "(?:\\bclsx\\s*\\(\\s*{?[\"\\']([_a-zA-Z0-9\\s\\-\\:\/]+)[\"\\'])|(?:\btw\\s*([_a-zA-Z0-9\\s\\-\\:\/]*))"
        ]
    }
}

Reload the window, then do the testing... bumm... ๐Ÿ’ฅ it broken... it did not work for any case. It seems strange, for they do declaration in their doc that

A multi-step regex can be specified by using an array of regexes to be executed in order.

Third effort

I don't know why it does not work. After a little confusion, I decided to come back to my first success case which uses a string, not an array of strings. Combine every cases into 1 regex string only. And of course, it works. My final regex as below:

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

Tested with regex101.com

Note that I remove the case of "class" because I don't work with tailwind in html but only tailwind in JavaScript or TypeScript.

So, that's it.

Thank you for your reading. Happy coding ๐ŸŒป๐ŸŒป๐ŸŒป

ย