{
  "root": true,
  "overrides": [
    {
      // Files containing TypeScript code.
      "files": ["*.ts", "*.tsx", "*.astro"],
      "extends": ["plugin:@typescript-eslint/recommended"],
      "parser": "@typescript-eslint/parser",
      "parserOptions": {
        "project": "./tsconfig.eslint.json",
        "extraFileExtensions": [".astro"]
      },
      "settings": {
        "import/resolver": {
          "typescript": { "project": "./tsconfig.eslint.json" }
        }
      },
      "rules": {
        // Create empty interface only when it extends other interface.
        "@typescript-eslint/no-empty-interface": [2, { "allowSingleExtends": true }]
      }
    },
    {
      "files": ["*.tsx"],
      "extends": [
        "airbnb",
        "airbnb-typescript",
        "airbnb/hooks",
        "plugin:react/jsx-runtime",
        "plugin:@typescript-eslint/recommended-requiring-type-checking"
      ],
      "rules": {
        // Write all components as arrow functions.
        "react/function-component-definition": [
          2,
          { "namedComponents": "arrow-function", "unnamedComponents": "arrow-function" }
        ],

        // We use props spreading to pass props to the html elements under custom components.
        "react/jsx-props-no-spreading": 0,

        // Define values for optional props as by providing default arguments.
        "react/require-default-props": [2, { "functions": "defaultArguments" }]
      }
    },
    {
      "files": ["*.ts"],
      "extends": [
        "airbnb/base",
        "airbnb-typescript/base",
        "plugin:@typescript-eslint/recommended-requiring-type-checking"
      ]
    },
    {
      "files": ["*.astro"],
      "globals": {
        "astroHTML": true
      },
      "extends": ["airbnb/base", "airbnb-typescript/base", "plugin:astro/all", "plugin:astro/jsx-a11y-strict"],
      "parser": "astro-eslint-parser",
      "parserOptions": {
        "parser": "@typescript-eslint/parser"
      },
      "rules": {
        "astro/jsx-a11y/alt-text": [2, { "img": ["Image", "Picture"] }]
      }
    },
    {
      "files": ["*.cjs"],
      "extends": ["airbnb/base"]
    },
    {
      // All linted files.
      "files": ["*.ts", "*.tsx", "*.astro", "*.cjs"],
      "plugins": ["file-progress", "simple-import-sort"],
      "extends": ["plugin:eslint-comments/recommended", "plugin:prettier/recommended"],
      "rules": {
        // Shows information about currently processing file in the console.
        "file-progress/activate": 1,

        // Removes eslint-disable comments when they are not needed.
        "eslint-comments/no-unused-disable": 2,

        // Ensure each eslint-disable has a description comment.
        "eslint-comments/require-description": [2, { "ignore": ["eslint-enable"] }],

        // Allow devDependencies in some files.
        "import/no-extraneous-dependencies": [2, { "devDependencies": ["astro.config.ts", "tailwind.config.cjs"] }],

        // Imports and exports order.
        "simple-import-sort/imports": [
          2,
          {
            "groups": [
              ["^\\u0000"], // Side effects
              ["^@?\\w"], // Packages
              ["^"], // Absolute imports
              ["^\\."] // Relative imports
            ]
          }
        ],
        "simple-import-sort/exports": 2
      }
    }
  ]
}
