tailwind-variants
tailwind-variants copied to clipboard
intellisense in tv config hangs on project when running process on large tv file
Describe the bug
When using a tailwind-variants tv config with a moderate amount of compound variations, the tailwind-intellisense extension hangs indefinitely for the whole project.
To Reproduce The best way i can think of to simulate the issue is the following
- enable the vscode extensions Prettier and Tailwind CSS Intellisense
- have the prettier-plugin-tailwindcss prettier plugin installed with following configuration
{
"arrowParens": "always",
"bracketSameLine": false,
"bracketSpacing": true,
"endOfLine": "auto",
"printWidth": 100,
"singleQuote": false,
"trailingComma": "all",
"tabWidth": 2,
"plugins": ["prettier-plugin-tailwindcss"],
"tailwindConfig": "tailwind-workspace-preset.js",
"tailwindFunctions": ["tv"]
}
- edit vscode settings with the following configuration (relative to your package manager). I work within an NX monorepo, the tailwind-workspace-preset.js is the root config all other tailwind configs inherit from, i think its safe to omit this for the purpose of repeating the issue.
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true,
"source.fixAll": false
},
"editor.inlineSuggest.enabled": true,
"editor.quickSuggestions": {
"strings": true
},
"eslint.validate": ["json"],
"tailwindCSS.validate": false,
"tailwindCSS.codeActions": true,
"tailwindCSS.experimental.configFile": "tailwind-workspace-preset.js",
"tailwindCSS.experimental.classRegex": [
["tv\\((([^()]*|\\([^()]*\\))*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
],
"tailwindCSS.files.exclude": [
"**/.git/**",
"**/node_modules/**",
"**/.hg/**",
"**/.nx/**",
"**/.svn/**",
"**/.husky/**",
"**/pnpm-lock.yaml",
"**/@generated/**"
]
}
- I can predictably repeat the issue with the following tv config. This first snippet should still provide fully functional intellisense and formatting. I lean heavily on CSS variables in my theming so i think some of the css classes will need to be replaced with default tailwind classes
import { tv } from "tailwind-variants";
export const baseButtonStyles = tv({
slots: {
base: [
"group relative flex shrink-0 select-none items-center rounded-base outline-none transition-all ease-in-out",
"data-[focus-visible]:outline-2",
],
spinner: "absolute inset-0 m-auto animate-spin text-current",
},
variants: {
color: {
brand: {},
danger: {},
neutral: {},
success: {},
},
isLoading: {
true: {},
false: {},
},
variant: {
primary: {},
secondary: {},
tertiary: {},
},
},
compoundVariants: [
{
variant: "primary",
color: "brand",
className: {
base: [
"bg-brand text-white",
"data-[hovered]:bg-brand-dark",
"data-[pressed]:bg-brand-darker",
],
},
},
{
variant: "primary",
color: "danger",
className: {
base: [
"bg-danger text-white",
"data-[hovered]:bg-danger-dark",
"data-[pressed]:bg-danger-darker",
],
},
},
{
variant: "primary",
color: "neutral",
className: {
base: [
"bg-neutral text-white",
"data-[hovered]:bg-neutral-dark",
"data-[pressed]:bg-neutral-darker",
],
},
},
{
variant: "primary",
color: "success",
className: {
base: [
"bg-success text-white",
"data-[hovered]:bg-success-dark",
"data-[pressed]:bg-success-darker",
],
},
},
],
});
4a. Now add the following two compoundVariants to the above config. When i try to get intellisense working on any classNames momentarily, the loading tooltip appears and hangs indefinately. furthermore the entire intellisense process seems to hang indefinately on the whole project.
{
variant: "secondary",
color: "brand",
className: {
base: [
"border border-current text-brand",
"data-[hovered]:bg-brand/10",
"data-[pressed]:bg-brand/20",
],
},
},
{
variant: "secondary",
color: "danger",
className: {
base: [
"border border-current text-danger",
"data-[hovered]:bg-danger/10",
"data-[pressed]:bg-danger/20",
],
},
},
Expected behavior Intellisense should continue to work without hanging - i thought at first this was an intellisense issue however having narrowed it down to the tv config i strongly suspect the way that typescript types are generated internally within tailwind-variants is possibly producing a huge amount of variations causing the workspace wide freeze.
Screenshots If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
- OS: [e.g. iOS] Windows 11
- Browser [e.g. chrome, safari] Chrome
- Version [e.g. 22] 119.0.6045.160
- VSCode 1.84.2
- Tailwind CSS Intellisense 0.10.3
- Prettier 10.1.0
- prettier-plugin-tailwindcss 0.5.7
- tailwind-variants 0.1.18
Smartphone (please complete the following information):
- no smartphone usage
Additional context
- no additional information
I'm experimenting with a new regex that is more performant and will update the docs after some more testing and usage.
"tailwindCSS.experimental.classRegex": [
["tv\\(([^)(]*(?:\\([^)(]*(?:\\([^)(]*(?:\\([^)(]*\\)[^)(]*)*\\)[^)(]*)*\\)[^)(]*)*)\\)", "\"(.*?)\""]
]
old post:
The issue is just the regex. I have it in any project. Add the regex, formatting chain hangs, remove the regex, formatting chain works again.
There is no perfect solution, because some weird cases are possible, like brackets in a string, but this one will at least balance the brackets to some depths and is fast:
[
"tv\\((?<=\\()(?:[^()]*|\\([^)]*\\))+(?=\\))\\)",
"[\"'`]([^\"'`]*).*?[\"'`]"
]
I didn't change the second regex that extracts the actual class names, because it doesn't ensure opening and closing string matching, but in normal case where you don't have syntax error in your code it will work, so good enough.
Here example regex101:
related https://github.com/tailwindlabs/tailwindcss-intellisense/issues/973
Any update on this?
@bitabs If there were updates, they would be posted. Please don't post "are there any updates" type of comments. They are not helpful to maintainers.
@binaryartifex @akomm Try the new pattern that was just merged: https://github.com/nextui-org/tailwind-variants-docs/pull/34 https://www.tailwind-variants.org/docs/getting-started#intellisense-setup-optional
@ViktorPontinen this does seem a world of difference more performant, but now it registers everything as tailwind strings, which is frustrating when you define a literal and instead of getting suggested the literals, it suggests class names.
I've also noticed some weird cases, such as object destructuring, it sometimes suggests class names when I'm trying to autocomplete the key of an object, though this is inconsistent and I can't for the life of me remember where this occurred in my codebase.
Glad to know this is being looked at, hopefully some of this was found helpful.
Same issue as @FFGFlash mentioned. Performance is back, but now most strings offer tailwind intellisense when it shouldn't.
Attached is a screenshot example of the intellisense with expo-router for defining a Stack's presentation option.
I'm in the same boat as you guys @FFGFlash @DavidAmyot unfortunately. Also noticed this issue when I changed pattern to the new one. Rather have it working than freezing whole VSCode, but agree it's not optimal as is.
A better regex pattern needs to found/figured and submitted.
I'm currently driving with this one, see video below that it does not spam completion in wrong places:
["tv\\(\\{([^]+?)\\}\\)", "(?:\"([^\"]*?)\")|(?:'([^']*?)')|(?:`[^`]*?`)"]
However in some places there is still utility class spam, but not because of the regex. Its a vscode tailwind plugin bug, as shown in the video: regex-tv-and-bug.webm
I think it thinks z.object is a class selector object on tag z.
I don't have performance issues with this one. It looks long, but it is made so that it skips over invalid content quickly.