Skip to content

Code Guards

Development Guidelines & Code Guards

Harmony uses ESLint to maintain code consistency and catch common mistakes early. It enforces coding standards and best practices, helping developers avoid common errors while keeping the codebase clean and structured.

For instance, passing all props downstream to child components is not allowed. This rule enhances performance by ensuring that components re-render only with the necessary props, preventing unnecessary updates.

{
  "root": true,
  "parser": "@typescript-eslint/parser",
  "plugins": [
    "@typescript-eslint",
    "jsx-a11y",
    "import",
    "prettier",
    "unused-imports",
    "custom-rules"
  ],
  "settings": {
    "react": {
      "version": "detect" // Tells eslint-plugin-react to automatically detect the version of React to use
    }
  },
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:jsx-a11y/recommended",
    "prettier"
  ],
  "parserOptions": {
    "project": "./tsconfig.json",
    "ecmaVersion": 2020,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "rules": {
    "@typescript-eslint/no-duplicate-enum-values": "off",
    "@typescript-eslint/naming-convention": "off",
    "@typescript-eslint/ban-types": "off",
    "import/extensions": "off",
    "no-debugger": "off",
    "no-underscore-dangle": [
      "error",
      { "allow": ["__REDUX_DEVTOOLS_EXTENSION__", "_default"] }
    ],
    "no-param-reassign": [
      "error",
      { "props": true, "ignorePropertyModificationsFor": ["draft"] }
    ],
    "max-lines-per-function": [
      "error",
      { "max": 150, "skipBlankLines": true, "skipComments": true }
    ],
    "max-lines": [
      "error",
      { "max": 400, "skipBlankLines": true, "skipComments": true }
    ],
    "max-depth": "error",
    "no-multiple-empty-lines": ["error", { "max": 1, "maxEOF": 1 }],
    "react/sort-comp": ["off"],
    "react/display-name": ["off"],
    "react/prefer-stateless-function": ["off"],
    "import/no-named-as-default": ["off"],
    "arrow-body-style": ["off"],
    "func-names": ["off"],
    "guard-for-in": ["off"],
    "lines-between-class-members": ["off"],
    "jsx-a11y/label-has-associated-control": [2, { "depth": 4 }],
    "import/prefer-default-export": "off",
    "import/no-default-export": "off",
    "react/jsx-one-expression-per-line": ["off"],
    "class-methods-use-this": ["off"],
    "max-len": ["error", { "code": 260 }],
    "@typescript-eslint/explicit-function-return-type": ["off"],
    "@typescript-eslint/no-use-before-define": ["off"],
    "@typescript-eslint/no-explicit-any": ["off"],
    "no-trailing-spaces": [
      "error",
      { "skipBlankLines": true, "ignoreComments": true }
    ],
    "react/jsx-props-no-spreadings": ["off"],
    "linebreak-style": 0,
    "global-require": 0,
    "eslint-linebreak-style": [0, "error", "windows"],
    "indent": ["error", "tab", { "SwitchCase": 1 }],
    "no-tabs": ["error", { "allowIndentationTabs": true }],
    "react/jsx-indent-props": ["error", "tab"],
    "react/jsx-indent": ["error", "tab"],
    "comma-dangle": ["error", "only-multiline"],
    "jsx-a11y/alt-text": [2],
    "jsx-a11y/anchor-has-content": [2],
    "jsx-a11y/anchor-is-valid": ["off"],
    "jsx-a11y/aria-props": [2],
    "jsx-a11y/aria-proptypes": [2],
    "jsx-a11y/aria-role": [
      2,
      { "allowedInvalidRoles": ["text"], "ignoreNonDOM": true }
    ],
    "jsx-a11y/aria-unsupported-elements": [2],
    "jsx-a11y/click-events-have-key-events": "off",
    "jsx-a11y/control-has-associated-label": [2, { "depth": 3 }],
    "jsx-a11y/heading-has-content": [2],
    "jsx-a11y/img-redundant-alt": [2],
    "jsx-a11y/no-access-key": [2],
    "jsx-a11y/no-autofocus": [2],
    "jsx-a11y/no-noninteractive-element-interactions": [2],
    "jsx-a11y/no-noninteractive-tabindex": [2],
    "jsx-a11y/tabindex-no-positive": [2],
    "jsx-a11y/no-static-element-interactions": [2],
    "import/no-extraneous-dependencies": ["off"],
    "react/react-in-jsx-scope": ["off"],
    "react/jsx-max-props-per-line": [
      "error",
      { "maximum": 1, "when": "multiline" }
    ],
    "react/jsx-first-prop-new-line": ["error", "multiline-multiprop"],
    "curly": ["error", "all"],
    "brace-style": ["error", "1tbs", { "allowSingleLine": false }],
    "react/jsx-closing-bracket-location": ["error", "line-aligned"],
    "react/self-closing-comp": ["error", { "component": true, "html": true }],
    "react/jsx-key": ["error", { "checkFragmentShorthand": true }],
    "comma-spacing": ["error", { "before": false, "after": true }],
    "no-extra-semi": "error",
    "@typescript-eslint/no-unsafe-function-type": "off",
    "quotes": ["error", "single"],
    "object-curly-spacing": ["error", "always"],
    "@typescript-eslint/no-unused-vars": [
      "error",
      { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }
    ],
    "@typescript-eslint/no-empty-object-type": [
      "error",
      { "allowObjectTypes": "always", "allowInterfaces": "with-single-extends" }
    ],
    "arrow-spacing": ["error", { "before": true, "after": true }],
    "space-before-blocks": ["error", "always"],
    "@typescript-eslint/no-unused-expressions": [
      "error",
      { "allowShortCircuit": true, "allowTernary": true }
    ],
    "keyword-spacing": ["error", { "before": true, "after": true }],
    "semi": ["error", "always"],
    "@typescript-eslint/ban-ts-comment": "off",
    "unused-imports/no-unused-imports": "error"
  },
  "ignorePatterns": [
    ".storybook",
    "node_modules",
    "generator",
    "dist",
    "src/**/__docs__",
    "custom-rules/**",
    "src/**/__test__",
    "src/**/*.stories.ts",
    "src/**/*.stories.tsx"
  ]
}