francoismassart / eslint-plugin-tailwindcss

ESLint plugin for Tailwind CSS usage
https://www.npmjs.com/package/eslint-plugin-tailwindcss
MIT License
1.38k stars 65 forks source link

[BUG] 3.15.0 causing "Cannot convert undefined or null to object" error #324

Closed robcaldecott closed 4 months ago

robcaldecott commented 4 months ago

Describe the bug I have just updated eslint-plugin-tailwindcss from 3.14.3 to 3.15.0 and when running eslint from the command-line I am seeing the following error in one of my React components:

eslint . --report-unused-disable-directives --max-warnings 0

Oops! Something went wrong! :(
ESLint: 8.57.0

TypeError: Cannot convert undefined or null to object
Occurred while linting /Users/<me>/Projects/<project>/src/components/select.tsx:19
Rule: "tailwindcss/no-unnecessary-arbitrary-value"
    at Function.keys (<anonymous>)
    at /Users/<me>/Projects/<project>/node_modules/eslint-plugin-tailwindcss/lib/rules/no-unnecessary-arbitrary-value.js:197:44
    at Array.forEach (<anonymous>)
    at parseForArbitraryValues (/Users/<me>/Projects/<project>/node_modules/eslint-plugin-tailwindcss/lib/rules/no-unnecessary-arbitrary-value.js:182:27)
    at /Users/<me>/Projects/<project>/node_modules/eslint-plugin-tailwindcss/lib/rules/no-unnecessary-arbitrary-value.js:311:9
    at Array.forEach (<anonymous>)
    at callExpressionVisitor (/Users/<me>/Projects/<project>/node_modules/eslint-plugin-tailwindcss/lib/rules/no-unnecessary-arbitrary-value.js:310:22)
    at ruleErrorHandler (/Users/<me>/Projects/<project>/node_modules/eslint/lib/linter/linter.js:1076:28)
    at /Users/<me>/Projects/<project>/node_modules/eslint/lib/linter/safe-emitter.js:45:58
    at Array.forEach (<anonymous>)

To Reproduce Here is the code that causes this issue (select.tsx)

import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { clsx } from "clsx";

interface SelectProps extends React.ComponentPropsWithoutRef<"select"> {
  asChild?: boolean;
  error?: boolean;
  fullWidth?: boolean;
}

export const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
  ({ asChild, className, error, fullWidth, children, ...props }, ref) => {
    const T = asChild ? Slot : "select";

    return (
      <T
        ref={ref}
        // eslint-disable-next-line tailwindcss/no-contradicting-classname
        className={clsx(
          "relative h-10 appearance-none truncate rounded-lg border-2 bg-background-tertiary px-4 pr-10 text-[16px] leading-[20px] text-content-primary outline-none invalid:text-content-inverse-tertiary focus:bg-surface disabled:text-content-disabled",
          "bg-[url('/chevron-down.svg')] bg-[size:20px_20px] bg-[position:right_16px_center] bg-no-repeat",
          error
            ? "border-border-negative"
            : "border-background-tertiary focus:border-border-accent",
          fullWidth && "w-full",
          className
        )}
        {...props}
      >
        {children}
      </T>
    );
  }
);
Select.displayName = "Select";

If I uncomment the following then the crash does not occur:

"bg-[url('/chevron-down.svg')] bg-[size:20px_20px] bg-[position:right_16px_center] bg-no-repeat"

Environment (please complete the following information):

eslint config file or live demo

module.exports = {
  root: true,
  env: { browser: true, es2020: true },
  extends: [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:react-hooks/recommended",
    "plugin:react/jsx-runtime",
    "plugin:jsx-a11y/recommended",
    "plugin:tailwindcss/recommended",
    "plugin:@tanstack/eslint-plugin-query/recommended",
    "plugin:storybook/recommended",
    "plugin:@typescript-eslint/recommended-type-checked",
  ],
  plugins: ["react-refresh"],
  parser: "@typescript-eslint/parser",
  parserOptions: {
    ecmaVersion: "latest",
    sourceType: "module",
    project: ["./tsconfig.json", "./tsconfig.node.json"],
    tsconfigRootDir: __dirname,
  },
  ignorePatterns: ["dist", "out", "static", ".eslintrc.cjs"],
  settings: {
    tailwindcss: {
      callees: ["clsx"],
      whitelist: ["destructive"],
    },
    react: {
      version: "detect",
    },
  },
  rules: {
    "@typescript-eslint/no-var-requires": "off",
    "@typescript-eslint/consistent-type-imports": "error",
    "react-refresh/only-export-components": [
      "warn",
      { allowConstantExport: true },
    ],
    "react/prop-types": "off",
  },
  overrides: [
    {
      extends: ["plugin:@typescript-eslint/disable-type-checked"],
      files: ["./**/*.js"],
    },
  ],
};
robcaldecott commented 4 months ago

Note that adding this to the top of the file does not fix the issue (suprisingly)

/* eslint-disable tailwindcss/no-unnecessary-arbitrary-value */
francoismassart commented 4 months ago

Hi @robcaldecott, thank you for reporting the issue, could you please try with

npm i eslint-plugin-tailwindcss@3.15.1-beta.1

Thank you for your time

robcaldecott commented 4 months ago

Hi @robcaldecott, thank you for reporting the issue, could you please try with

npm i eslint-plugin-tailwindcss@3.15.1-beta.1

Yes! This fixes the crash. Thank you for the rapid response 👏

francoismassart commented 4 months ago

fixed in eslint-plugin-tailwindcss@3.15.1