Skip to content
Reece Adamson edited this page Mar 4, 2020 · 10 revisions

Table of Contents

Linting and Formatting

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.

Programming Languages

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!

Styling

This project uses Sass. All style sheets should use the .scss file extension and the SCSS syntax.

Style Naming

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

Importing styles

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>;
  }
}

Spacing

Default spacing is 2 spaces.

Semicolons

Use semicolons to terminate statements.

Console.logs

console.error and console.warn are ok.

Debugging console.logs are not ok.

Module imports

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'

Strings

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';

Default Exports

If a file exports only a single class or function, that export should be marked as default.

React Components

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 with import 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.

Props

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;
}

index.ts

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

Functions vs Classes

Prefer functions over classes if the instances of the class would be ephemeral.

Always use React function components, not class components.

Types Alias vs Interface

For consistency prefer type aliases over interfaces.

Arrays

Prefer [] over `Array

// Good
let list: number[] = [1, 2, 3];

// Bad
let list: Array<number> = [1, 2, 3];

Naming

Function Naming

Function names should use lower camelCase (camelCase). e.g.

function fooBar() {}

Class Naming

Class names should use PascalCase (PascalCase). e.g.

class Foo {
  bar: number;
  bazQux() { }
}

Variable Naming

Variables should use lower camelCase (camelCase). e.g.

const fooBar = 'baz';

Interface Naming

Use PascalCase for the name. Use camelCase for the members. e.g.

interface Foo {
  barBaz: string;
}

Type Naming

Use PascalCase for the name. Use camelCase for the members. e.g.

type Foo = {
  barBaz: string;
}

Namespace Naming

Use PascalCase for the name. e.g.

namespace Foo {}

Yarn or NPM scripts

Use kebab-case. (e.g. lint-fix)

File Naming

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

JSX

Logical && vs Conditional Operator

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>

Git Workflow

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:

  1. Checkout master and pull the latest:
git checkout master 
git pull
  1. Checkout feature branch and rebase with master:
git checkout feature-branch
git rebase master
  1. Push changes
git push -f

Using Icons

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" />