-
Notifications
You must be signed in to change notification settings - Fork 5
Code Style Guide
- Linting and Formatting
- Programming Languages
- Styling
- Spacing
- Semicolons
- Console.logs
- Module imports
- Strings
- Default Exports
- React Components
- Props
- index.ts
- Functions vs Classes
- Types Alias vs Interface
- Arrays
- Naming
- JSX
- Git Workflow
- Using Icons
This project uses ESLint and Prettier to define, inspect and automatically correct (when possible) the style and format of source code in the repository.
Before submitting a pull request the linter should be ran and issues fixed.
The linter can be executed with: yarn lint
. Some errors can be automatically corrected with yarn lint-fix
Some aspects of the style guide may not be automatically processed by these tools.
All source files should use TypeScript. JavaScript files will not be accepted into the repository.
That being said, outside contributions using JavaScript are still desired and we will help convert any functionality to TypeScript!
This project uses Sass.
All style sheets should use the .scss
file extension and the SCSS syntax.
Local class names should use camelCase.
This allows styles to be accessed with dot notation cleanly and consistently.
e.g.
// Good
styles.className
// Bad
styles['class-name']
See the CSS Modules README
CSS Module styles should be imported as styles
e.g. from Create React App docs
import React, { Component } from 'react';
import styles from './Button.module.css'; // Import css modules stylesheet as styles
import './another-stylesheet.css'; // Import regular stylesheet
class Button extends Component {
render() {
return <button className={styles.error}>Error Button</button>;
}
}
Default spacing is 2 spaces.
Use semicolons to terminate statements.
console.error
and console.warn
are ok.
Debugging console.logs
are not ok.
Use a relative import if the module is located in the current or a child directory.
Tests should use a relative import for the module they are testing when located in the __tests__
directory in the module.
Otherwise use an absolute import.
e.g.
// Good
import Patient from './Patient'
// Bad
import Patient from 'components/Patient'
// Good
import Practitioner from './doctors/Practitioner'
// Bad
import Practitioner from 'components/hospital/doctors/Practitioner'
// Good
import Combustion from 'engine/Combustion'
// Bad
import Engine from '../engine/Combustion'
// __tests__/App.tsx
// Good
import App from '../App'
// Bad
import App from 'components/App'
Template Literals are preferred.
e.g. use
const name = 'John'
console.log(`Hi ${name}`)
not
const name = 'John'
console.log('Hi ' + name)
Prefer single quotes to double quotes.
Do not break long strings over multiple lines
// Bad
const sentence = `A very long string that should not\
be broken up over multiple lines`;
// Good
const sentence = 'A very long string that should not be broken up over multiple lines';
If a file exports only a single class or function, that export should be marked as default
.
Individual React Components should live in their own directory.
For example a Header
component:
src/
|-- components
|-- Header
|-- Header.module.scss
|-- Header.tsx
|-- index.ts
|-- __tests__
|-- Header.test.tsx
-
Header.tsx
provides the React component. -
index.ts
default exports the component so that other components may include it withimport components/Header
-
Header.module.scss
provides the React component SASS styling
Tests for the component should be included in a __tests__
directory.
Components shall be styled using SASS.
A single file may have multiple React components which need styling. Type and interface declaration names should be prefixed with the name of the ReactComponent they are associated with.
e.g.
interface HeaderProps {
title: string;
logo: string;
}
Do not define functions or classes in any index.ts
files. The index.ts
files are should solely be used to pull together and export functions and classes defined in other files. Example see some of the React components in this project or this example of an index.js
from Material-UI
Prefer functions over classes if the instances of the class would be ephemeral.
Always use React function components, not class components.
For consistency prefer type aliases over interfaces.
Prefer []
over `Array
// Good
let list: number[] = [1, 2, 3];
// Bad
let list: Array<number> = [1, 2, 3];
Function names should use lower camelCase (camelCase). e.g.
function fooBar() {}
Class names should use PascalCase (PascalCase). e.g.
class Foo {
bar: number;
bazQux() { }
}
Variables should use lower camelCase (camelCase). e.g.
const fooBar = 'baz';
Use PascalCase for the name. Use camelCase for the members. e.g.
interface Foo {
barBaz: string;
}
Use PascalCase for the name. Use camelCase for the members. e.g.
type Foo = {
barBaz: string;
}
Use PascalCase for the name. e.g.
namespace Foo {}
Use kebab-case. (e.g. lint-fix
)
A file which exports a single class should have the same name as the class it exports.
A file which exports a single function should have the same name as the function it exports.
A file which exports multiple functions, objects or primitive values shall have an all lowercase name that may include dashes (-). e.g. react-dom
Prefer logical && when else is not needed
e.g.
/** Good **/
<div>
{showTitle && <h1>Good!<h2/> }
</div>
/** Good **/
<div>
{ showTitle ? <h1>Good!<h2/> : <strong>Nice Job!<strong/> }
</div>
/** Bad **/
<div>
{ showTitle ? <h1>Bad!<h2/> : null }
</div>
Before submitting a pull request to merge a feature branch into master
, it should first be rebased with master
. This ensures that there are no conflicts when the feature gets merged and this approach also keeps the commits linear so that it is easier to follow when reading the log.
Here's the workflow:
- Checkout master and pull the latest:
git checkout master
git pull
- Checkout feature branch and rebase with master:
git checkout feature-branch
git rebase master
- Push changes
git push -f
This project uses Font Awesome Icons.
Icons should be explicitly imported.
// Good
import { faCheck } from '@fortawesome/free-solid-svg-icons'
const element = <FontAwesomeIcon icon={faCheck} />
// Bad
const element = <FontAwesomeIcon icon="check" />