tailwind-variants icon indicating copy to clipboard operation
tailwind-variants copied to clipboard

intellisense in tv config hangs on project when running process on large tv file

Open binaryartifex opened this issue 1 year ago • 11 comments

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

  1. enable the vscode extensions Prettier and Tailwind CSS Intellisense
  2. 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"]
}
  1. 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/**"
  ]
}
  1. 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

binaryartifex avatar Nov 22 '23 05:11 binaryartifex

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\\(([^)(]*(?:\\([^)(]*(?:\\([^)(]*(?:\\([^)(]*\\)[^)(]*)*\\)[^)(]*)*\\)[^)(]*)*)\\)", "\"(.*?)\""]
]

mskelton avatar Nov 22 '23 17:11 mskelton

better pattern

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:

akomm avatar Feb 06 '24 16:02 akomm

related https://github.com/tailwindlabs/tailwindcss-intellisense/issues/973

Newbie012 avatar May 24 '24 11:05 Newbie012

Any update on this?

bitabs avatar May 26 '24 23:05 bitabs

@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.

mskelton avatar May 27 '24 20:05 mskelton

@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 avatar Jun 19 '24 07:06 ViktorPontinen

@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.

image

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.

FFGFlash avatar Jun 24 '24 18:06 FFGFlash

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.

image

DavidAmyot avatar Aug 13 '24 15:08 DavidAmyot

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.

ViktorPontinen avatar Aug 19 '24 13:08 ViktorPontinen

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.

akomm avatar Aug 29 '24 09:08 akomm