Unverified Commit 37ff51f7 authored by Marcos Iglesias's avatar Marcos Iglesias Committed by GitHub

docs: Adds documentation and cleans up ESLint rules (#489)

* Cleans up a11y rules and orders ESLint rules

* Updates developer guide docs with accessibility section

* Adds documentation about semantic HTML
parent 14cf1ff3
...@@ -165,6 +165,7 @@ export class OwnerEditor extends React.Component< ...@@ -165,6 +165,7 @@ export class OwnerEditor extends React.Component<
return ( return (
<Modal.Body> <Modal.Body>
<form className="component-form" onSubmit={this.recordAddItem}> <form className="component-form" onSubmit={this.recordAddItem}>
{/* eslint-disable jsx-a11y/no-autofocus */}
<input <input
id="add-item-input" id="add-item-input"
autoFocus autoFocus
...@@ -173,6 +174,7 @@ export class OwnerEditor extends React.Component< ...@@ -173,6 +174,7 @@ export class OwnerEditor extends React.Component<
}`} }`}
ref={this.inputRef} ref={this.inputRef}
/> />
{/* eslint-enable jsx-a11y/no-autofocus */}
<button <button
className="btn btn-default add-button" className="btn btn-default add-button"
type="submit" type="submit"
......
...@@ -196,6 +196,7 @@ export class SearchBar extends React.Component<SearchBarProps, SearchBarState> { ...@@ -196,6 +196,7 @@ export class SearchBar extends React.Component<SearchBarProps, SearchBarState> {
className="search-bar-form" className="search-bar-form"
onSubmit={this.handleValueSubmit} onSubmit={this.handleValueSubmit}
> >
{/* eslint-disable jsx-a11y/no-autofocus */}
<input <input
id="search-input" id="search-input"
required required
...@@ -207,6 +208,7 @@ export class SearchBar extends React.Component<SearchBarProps, SearchBarState> { ...@@ -207,6 +208,7 @@ export class SearchBar extends React.Component<SearchBarProps, SearchBarState> {
autoFocus autoFocus
autoComplete="off" autoComplete="off"
/> />
{/* eslint-enable jsx-a11y/no-autofocus */}
<button className={searchButtonClass} type="submit"> <button className={searchButtonClass} type="submit">
<span className="sr-only">{SEARCH_BUTTON_TEXT}</span> <span className="sr-only">{SEARCH_BUTTON_TEXT}</span>
<img className="icon icon-search" alt="" /> <img className="icon icon-search" alt="" />
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
"lint": "npm run eslint", "lint": "npm run eslint",
"lint-fix": "npm run eslint-fix", "lint-fix": "npm run eslint-fix",
"eslint": "eslint --ignore-path=.eslintignore --ext .js,.jsx,.ts,.tsx .", "eslint": "eslint --ignore-path=.eslintignore --ext .js,.jsx,.ts,.tsx .",
"eslint:errors": "eslint --ignore-path=.eslintignore --quiet --ext .js,.jsx,.ts,.tsx .",
"eslint-fix": "eslint --fix --ignore-path=.eslintignore --ext .js,.jsx,.ts,.tsx .", "eslint-fix": "eslint --fix --ignore-path=.eslintignore --ext .js,.jsx,.ts,.tsx .",
"test:watch": "cross-env TZ=UTC jest --watch", "test:watch": "cross-env TZ=UTC jest --watch",
"tsc": "tsc", "tsc": "tsc",
...@@ -243,6 +244,44 @@ ...@@ -243,6 +244,44 @@
"prettier/prettier": [ "prettier/prettier": [
"error" "error"
], ],
"arrow-parens": [
"off",
"always"
],
"brace-style": [
"off",
"off"
],
"curly": [
"error",
"multi-line"
],
"eqeqeq": [
"error",
"smart"
],
"id-blacklist": [
"error",
"any",
"Number",
"number",
"String",
"string",
"Boolean",
"boolean",
"Undefined",
"undefined"
],
"one-var": [
"error",
"never"
],
"@typescript-eslint/dot-notation": "warn",
"@typescript-eslint/lines-between-class-members": "warn",
"@typescript-eslint/naming-convention": "warn",
"@typescript-eslint/no-unused-expressions": "warn",
"@typescript-eslint/no-unused-vars": "warn",
"@typescript-eslint/no-use-before-define": "warn",
"@typescript-eslint/member-delimiter-style": [ "@typescript-eslint/member-delimiter-style": [
"off", "off",
{ {
...@@ -284,50 +323,80 @@ ...@@ -284,50 +323,80 @@
} }
], ],
"@typescript-eslint/indent": "off", "@typescript-eslint/indent": "off",
"arrow-parens": [ "array-callback-return": "warn",
"off",
"always"
],
"brace-style": [
"off",
"off"
],
"camelcase": "off", "camelcase": "off",
"curly": [ "class-methods-use-this": "off",
"error", "consistent-return": "warn",
"multi-line" "default-case": "warn",
], "func-names": "off",
"eqeqeq": [ "guard-for-in": "off",
"error",
"smart"
],
"id-blacklist": [
"error",
"any",
"Number",
"number",
"String",
"string",
"Boolean",
"boolean",
"Undefined",
"undefined"
],
"id-match": "error", "id-match": "error",
"import/extensions": "off",
"import/first": "warn",
"import/no-cycle": "warn",
"import/no-extraneous-dependencies": "off",
"import/no-named-as-default": "off",
"import/no-unresolved": "off",
"import/order": "warn",
"import/prefer-default-export": "off",
"indent": "off",
"new-cap": "off",
"no-bitwise": "off",
"no-case-declarations": "warn",
"no-confusing-arrow": "off",
"no-continue": "off",
"no-duplicate-imports": "error", "no-duplicate-imports": "error",
"no-eval": "error", "no-eval": "error",
"no-extra-boolean-cast": "warn",
"no-irregular-whitespace": "off", "no-irregular-whitespace": "off",
"no-mixed-operators": "off",
"no-multi-assign": "off",
"no-multi-spaces": "off",
"no-multi-str": "warn",
"no-nested-ternary": "warn",
"no-new-wrappers": "error", "no-new-wrappers": "error",
"no-param-reassign": "warn",
"no-plusplus": "off",
"no-prototype-builtins": "off",
"no-restricted-globals": "warn",
"no-restricted-properties": "off",
"no-restricted-syntax": "off",
"no-script-url": "warn",
"no-shadow": "warn",
"no-undef": "off",
"no-underscore-dangle": "error", "no-underscore-dangle": "error",
"no-unneeded-ternary": "warn",
"no-useless-return": "warn",
"no-var": "error", "no-var": "error",
"no-void": "warn",
"object-shorthand": "error", "object-shorthand": "error",
"one-var": [ "padded-blocks": "off",
"error", "prefer-arrow-callback": "off",
"never"
],
"prefer-const": "error", "prefer-const": "error",
"prefer-destructuring": "warn",
"prefer-promise-reject-errors": "warn",
"prefer-template": "off", "prefer-template": "off",
"radix": "error", "radix": "error",
"react/button-has-type": "warn",
"react/destructuring-assignment": "warn",
"react/forbid-prop-types": "off",
"react/jsx-boolean-value": "warn",
"react/jsx-closing-tag-location": "warn",
"react/jsx-indent": "off",
"react/jsx-no-bind": "off",
"react/jsx-one-expression-per-line": "off",
"react/jsx-props-no-spreading": "warn",
"react/no-access-state-in-setstate": "warn",
"react/no-array-index-key": "off",
"react/no-did-update-set-state": "warn",
"react/no-string-refs": "off",
"react/no-unescaped-entities": "off",
"react/no-unused-prop-types": "off",
"react/prefer-stateless-function": "warn",
"react/require-default-props": "off",
"react/sort-comp": "warn",
"react/state-in-constructor": "off",
"react/static-property-placement": "warn",
"space-in-parens": [ "space-in-parens": [
"off", "off",
"never" "never"
...@@ -341,15 +410,11 @@ ...@@ -341,15 +410,11 @@
] ]
} }
], ],
"new-cap": 0, "jsx-a11y/label-has-associated-control": "warn",
"no-restricted-syntax": 0, "jsx-a11y/control-has-associated-label": "warn",
"guard-for-in": 0, "jsx-a11y/click-events-have-key-events": "warn",
"prefer-arrow-callback": 0, "jsx-a11y/no-noninteractive-element-interactions": "warn",
"func-names": 0, "jsx-a11y/no-static-element-interactions": "warn",
"react/jsx-no-bind": 0,
"no-confusing-arrow": 0,
"jsx-a11y/no-static-element-interactions": 0,
"jsx-a11y/anchor-has-content": 0,
"jsx-a11y/anchor-is-valid": [ "jsx-a11y/anchor-is-valid": [
"error", "error",
{ {
...@@ -367,76 +432,7 @@ ...@@ -367,76 +432,7 @@
"preferButton" "preferButton"
] ]
} }
], ]
"react/require-default-props": 0,
"react/state-in-constructor": 0,
"no-plusplus": 0,
"no-mixed-operators": 0,
"no-continue": 0,
"no-bitwise": 0,
"no-undef": 0,
"no-multi-assign": 0,
"react/no-array-index-key": 0,
"no-restricted-properties": 0,
"no-prototype-builtins": 0,
"jsx-a11y/href-no-hash": 0,
"react/forbid-prop-types": 0,
"class-methods-use-this": 0,
"import/extensions": 0,
"import/no-named-as-default": 0,
"import/no-extraneous-dependencies": 0,
"import/no-unresolved": 0,
"import/prefer-default-export": 0,
"react/no-unescaped-entities": 0,
"react/no-unused-prop-types": 0,
"react/no-string-refs": 0,
"react/jsx-indent": 0,
"indent": 0,
"no-multi-spaces": 0,
"padded-blocks": 0,
"import/no-cycle": "warn",
"import/order": "warn",
"import/first": "warn",
"no-param-reassign": "warn",
"prefer-destructuring": "warn",
"consistent-return": "warn",
"no-shadow": "warn",
"no-extra-boolean-cast": "warn",
"no-restricted-globals": "warn",
"no-case-declarations": "warn",
"prefer-promise-reject-errors": "warn",
"default-case": "warn",
"no-nested-ternary": "warn",
"no-script-url": "warn",
"array-callback-return": "warn",
"no-void": "warn",
"no-multi-str": "warn",
"no-unneeded-ternary": "warn",
"no-useless-return": "warn",
"jsx-a11y/no-autofocus": "warn",
"jsx-a11y/alt-text": "warn",
"jsx-a11y/label-has-associated-control": "warn",
"jsx-a11y/click-events-have-key-events": "warn",
"jsx-a11y/no-redundant-roles": "warn",
"jsx-a11y/no-noninteractive-element-interactions": "warn",
"jsx-a11y/control-has-associated-label": "warn",
"@typescript-eslint/no-use-before-define": "warn",
"@typescript-eslint/dot-notation": "warn",
"@typescript-eslint/lines-between-class-members": "warn",
"@typescript-eslint/naming-convention": "warn",
"@typescript-eslint/no-unused-vars": "warn",
"@typescript-eslint/no-unused-expressions": "warn",
"react/static-property-placement": "warn",
"react/jsx-closing-tag-location": "warn",
"react/no-did-update-set-state": "warn",
"react/no-access-state-in-setstate": "warn",
"react/jsx-one-expression-per-line": "off",
"react/sort-comp": "warn",
"react/jsx-props-no-spreading": "warn",
"react/prefer-stateless-function": "warn",
"react/jsx-boolean-value": "warn",
"react/button-has-type": "warn",
"react/destructuring-assignment": "warn"
}, },
"globals": { "globals": {
"document": true "document": true
......
# Developer Guide # Developer Guide
## Environment ## Environment
Follow the installation instructions in the section [Install standalone application directly from the source](https://github.com/lyft/amundsenfrontendlibrary/blob/master/docs/installation.md#install-standalone-application-directly-from-the-source). Follow the installation instructions in the section [Install standalone application directly from the source](https://github.com/lyft/amundsenfrontendlibrary/blob/master/docs/installation.md#install-standalone-application-directly-from-the-source).
Install the javascript development requirements: Install the javascript development requirements:
```bash ```bash
# in ~/<your-path-to-cloned-repo>/amundsenfrontendlibrary/amundsen_application # in ~/<your-path-to-cloned-repo>/amundsenfrontendlibrary/amundsen_application
$ cd static $ cd static
...@@ -11,6 +13,7 @@ $ npm install --only=dev ...@@ -11,6 +13,7 @@ $ npm install --only=dev
``` ```
To test local changes to the javascript static files: To test local changes to the javascript static files:
```bash ```bash
# in ~/<your-path-to-cloned-repo>/amundsenfrontendlibrary/amundsen_application # in ~/<your-path-to-cloned-repo>/amundsenfrontendlibrary/amundsen_application
$ cd static $ cd static
...@@ -18,51 +21,67 @@ $ npm run dev-build # builds the development bundle ...@@ -18,51 +21,67 @@ $ npm run dev-build # builds the development bundle
``` ```
To test local changes to the python files, re-run the wsgi: To test local changes to the python files, re-run the wsgi:
```bash ```bash
# in ~/<your-path-to-cloned-repo>/amundsenfrontendlibrary/amundsen_application # in ~/<your-path-to-cloned-repo>/amundsenfrontendlibrary/amundsen_application
$ python3 wsgi.py $ python3 wsgi.py
``` ```
## Contributing ## Contributing
We describe our [general contributing process](https://lyft.github.io/amundsen/CONTRIBUTING/) in the main repository of Amundsen, so here we'll cover the items specific to the Frontend library. We describe our [general contributing process](https://lyft.github.io/amundsen/CONTRIBUTING/) in the main repository of Amundsen, so here we'll cover the items specific to the Frontend library.
### Testing Python Code ### Testing Python Code
If changes were made to any python files, run the python unit tests, linter, and type checker. Unit tests are run with `py.test`. They are located in `tests/unit`. Type checks are run with `mypy`. Linting is `flake8`. There are friendly `make` targets for each of these tests: If changes were made to any python files, run the python unit tests, linter, and type checker. Unit tests are run with `py.test`. They are located in `tests/unit`. Type checks are run with `mypy`. Linting is `flake8`. There are friendly `make` targets for each of these tests:
```bash ```bash
# after setting up the environment # after setting up the environment
make test # unit tests in Python 3 make test # unit tests in Python 3
make lint # flake8 make lint # flake8
make mypy # type checks make mypy # type checks
``` ```
Fix all errors before submitting a PR. Fix all errors before submitting a PR.
### Testing Frontend Code ### Testing Frontend Code
`npm run test` runs our Frontend unit tests. Please add unit tests to cover new code additions and fix any test failures before submitting a PR. You can also have a dedicated terminal running `npm run test:watch` while developing, which would continuously run tests over your modified files. `npm run test` runs our Frontend unit tests. Please add unit tests to cover new code additions and fix any test failures before submitting a PR. You can also have a dedicated terminal running `npm run test:watch` while developing, which would continuously run tests over your modified files.
To run specific tests, run `npm run test-nocov -t <regex>`, where `<regex>` is any pattern that matches the names of the test blocks that you want to run. See our [recommendations for writing unit tests](https://github.com/lyft/amundsenfrontendlibrary/blob/master/docs/recommended_practices.md). To run specific tests, run `npm run test-nocov -t <regex>`, where `<regex>` is any pattern that matches the names of the test blocks that you want to run. See our [recommendations for writing unit tests](https://github.com/lyft/amundsenfrontendlibrary/blob/master/docs/recommended_practices.md).
### Frontend Type Checking ### Frontend Type Checking
We use TypeScript in our codebase, so `npm run tsc` conducts type checking. The build commands `npm run build` and `npm run dev-build` also conduct type checking, but are slower because they also build the source code. Run any of these commands and fix all failed checks before submitting a PR. We use TypeScript in our codebase, so `npm run tsc` conducts type checking. The build commands `npm run build` and `npm run dev-build` also conduct type checking, but are slower because they also build the source code. Run any of these commands and fix all failed checks before submitting a PR.
### Frontend Linting and Formatting ### Frontend Linting and Formatting
We have in place two linters – [ESLint][eslint] for our JavaScript and TypeScript files, [Stylelint][stylelint] for our Sass files. If you have both ESLint and Stylelint extensions installed on your IDE, you should get warnings on your editor by default. We have in place two linters – [ESLint][eslint] for our JavaScript and TypeScript files, [Stylelint][stylelint] for our Sass files. If you have both ESLint and Stylelint extensions installed on your IDE, you should get warnings on your editor by default.
We also use [Prettier][prettier] to help us keep consistent formatting on our TypeScript and Sass code. We also use [Prettier][prettier] to help us keep consistent formatting on our TypeScript and Sass code.
Whenever you want to run these tasks manually, you can execute: Whenever you want to run these tasks manually, you can execute:
* `npm run lint` to run ESLint and `npm run lint-fix` to auto-fix most of them. - `npm run lint` to run ESLint and `npm run lint-fix` to auto-fix most of them.
* `npm run stylelint` to run Stylelint and `npm run stylelint-fix` to trigger the auto-fix. - `npm run stylelint` to run Stylelint and `npm run stylelint-fix` to trigger the auto-fix.
* `npm run format` to run Prettier on both the TypeScript and Sass files - `npm run format` to run Prettier on both the TypeScript and Sass files
We also check your changed files and format them when you create a new commit, making it easy for you and for the project to keep a consistent code style. We do this leveraging [Husky][husky] and [Lint-staged][lint-staged]. We also check your changed files and format them when you create a new commit, making it easy for you and for the project to keep a consistent code style. We do this leveraging [Husky][husky] and [Lint-staged][lint-staged].
Looking forward, we aim at setting more strict best practices using ESLint and Stylelint. You can read about our plans to improve our TypeScript, Styles and general code style on these issues: Looking forward, we aim at setting more strict best practices using ESLint and Stylelint. You can read about our plans to improve our TypeScript, Styles and general code style on these issues:
* [Adopt Typescript Recommended Guidelines on the Frontend library][typescript-issue]
* [Adopt Stylelint's Sass Guidelines on the Frontend library][stylelint-issue] - [Adopt Typescript Recommended Guidelines on the Frontend library][typescript-issue]
* [Adopt Airbnb-Typescript Code Guidelines on the Frontend library][airbnb-issue] - [Adopt Stylelint's Sass Guidelines on the Frontend library][stylelint-issue]
- [Adopt Airbnb-Typescript Code Guidelines on the Frontend library][airbnb-issue]
### Accessibility and Semantic Markup
We strive to keep our application accessible. For that, we use the 'airbnb-typescript' preset for ESLint, which includes a bunch of accessibility rules. We also have a set of "jsx-a11y/" prefixed rules, which are currently on a "warn" level, so they don't throw errors. Our goal is to remove that "warn" level and comply with all the accessibility rules we list on [our ESLint configuration][eslintconfig].
We also try to model our application's markup on best practices regarding semantic markup. If you are making large markup changes on one of your PRs, make sure your changes comply with this [HTML semantics checklist][semanticchecklist].
[eslint]: https://eslint.org/ [eslint]: https://eslint.org/
[eslintconfig]: https://github.com/lyft/amundsenfrontendlibrary/blob/master/amundsen_application/static/package.json#L242
[stylelint]: https://stylelint.io/ [stylelint]: https://stylelint.io/
[prettier]: https://prettier.io/ [prettier]: https://prettier.io/
[husky]: https://github.com/typicode/husky [husky]: https://github.com/typicode/husky
...@@ -70,5 +89,4 @@ Looking forward, we aim at setting more strict best practices using ESLint and S ...@@ -70,5 +89,4 @@ Looking forward, we aim at setting more strict best practices using ESLint and S
[typescript-issue]: https://github.com/lyft/amundsen/issues/503 [typescript-issue]: https://github.com/lyft/amundsen/issues/503
[airbnb-issue]: https://github.com/lyft/amundsen/issues/502 [airbnb-issue]: https://github.com/lyft/amundsen/issues/502
[stylelint-issue]: https://github.com/lyft/amundsen/issues/501 [stylelint-issue]: https://github.com/lyft/amundsen/issues/501
[semanticchecklist]: https://learn-the-web.algonquindesign.ca/topics/html-semantics-checklist/
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment