import js from "@eslint/js"; import tseslint from "typescript-eslint"; import react from "eslint-plugin-react"; import reactHooks from "eslint-plugin-react-hooks"; import reactRefresh from "eslint-plugin-react-refresh"; import importX from "eslint-plugin-import-x"; import tailwindcss from "eslint-plugin-tailwindcss"; import unusedImports from "eslint-plugin-unused-imports"; import globals from "globals"; export default tseslint.config( { ignores: ["dist/**", "node_modules/**", "public/**"], }, { files: ["src/**/*.{ts,tsx,js,jsx}"], extends: [js.configs.recommended, ...tseslint.configs.recommended], plugins: { react, "react-hooks": reactHooks, // for following React rules such as dependencies in hooks, keys in lists, etc. "react-refresh": reactRefresh, // for Vite HMR compatibility "import-x": importX, // for import order/sorting. It also detercts circular dependencies and duplicate imports. tailwindcss, // for detecting invalid Tailwind classnames and enforcing classname order "unused-imports": unusedImports, // for detecting unused imports }, languageOptions: { globals: { ...globals.browser, }, parserOptions: { ecmaFeatures: { jsx: true }, }, }, settings: { react: { version: "detect" }, }, rules: { // --- Unused imports/vars --- "unused-imports/no-unused-imports": "warn", "unused-imports/no-unused-vars": [ "warn", { vars: "all", varsIgnorePattern: "^_", args: "after-used", argsIgnorePattern: "^_", }, ], "no-unused-vars": "off", "@typescript-eslint/no-unused-vars": "off", // --- React --- "react/jsx-key": "warn", "react/jsx-no-duplicate-props": "error", "react/jsx-no-undef": "error", "react/no-children-prop": "warn", "react/no-danger-with-children": "error", "react/no-direct-mutation-state": "error", "react/no-unknown-property": "warn", "react/react-in-jsx-scope": "off", // --- React Hooks --- "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn", // --- React Refresh (Vite HMR) --- "react-refresh/only-export-components": [ "warn", { allowConstantExport: true }, ], // --- Import ordering & hygiene --- "import-x/no-duplicates": "warn", "import-x/order": [ "warn", { groups: [ "builtin", "external", "internal", "parent", "sibling", "index", ], "newlines-between": "never", }, ], // --- Tailwind CSS --- "tailwindcss/classnames-order": "warn", "tailwindcss/no-contradicting-classname": "warn", "tailwindcss/no-unnecessary-arbitrary-value": "warn", // --- Disabled base rules --- "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-require-imports": "off", "no-case-declarations": "off", "no-control-regex": "off", "no-useless-escape": "off", }, } );