# Contributing

**Table of contents**

- [Contributing](#contributing)
  - [Colophon](#colophon)
    - [Glossary](#glossary)
    - [Useful links](#useful-links)
    - [Design system team](#design-system-team)
  - [Guidelines and requirements](#guidelines-and-requirements)
    - [Design requirements](#design-requirements)
    - [Front-end guidelines](#front-end-guidelines)
    - [Environment setup](#environment-setup)
  - [Running on Windows](#running-on-windows)
- [Running on MacOS v13+ with Apple Silicon](#running-on-macos-v13-with-apple-silicon)
  - [Code style guide](#code-style-guide)
  - [Component naming and location](#component-naming-and-location)
  - [CSS classnames](#css-classnames)
  - [Storybook requirements](#storybook-requirements)
  - [Component assets](#component-assets)
    - [SVGs](#svgs)
  - [Scripts / Tasks](#scripts--tasks)
  - [Workflow](#workflow)
    - [Create a new branch](#create-a-new-branch)
    - [Create a pull request](#create-a-pull-request)
      - [Linting and testing](#linting-and-testing)
    - [Reviewers](#reviewers)
    - [Manual testing](#manual-testing)
  - [Publishing a component](#publishing-a-component)
  - [Consume a component](#consume-a-component)
    - [Beta and canary](#beta-and-canary)

## Colophon

### Glossary

- **Component library**: A collection of common design components. These are reusable snippets of HTML, CSS, and JavaScript, and documentation about how to use them
- **Design system**: A collection of reusable components and patterns guided by principles and practices that forms the foundation of digital products. Design systems use style guides, component libraries, and guidelines to create a unified visual language and a consistent user experience
- **Docz**: A software tool used to create interactive documentation
- **Plant**: A software tool used to keep a detailed version history of a Sketch file
- **Public-facing website**: An easily browsable reference website of components and documentation that is synchronized with the **component library** and **UI Kit**
- **Sketch**: A vector graphics editor used to create the **UI Kit**
- **UI Kit**: A graphic file, or collection of files, containing user interface (UI) components and patterns. Created and maintained in Sketch. This is synced to Sketch Cloud, a service which enables online browsing of the file as well as providing a way to import UI symbols into Sketch via a [library](https://www.sketch.com/docs/libraries/adding-libraries)
- **Zeplin**: A software tool used to share designs between designers and developers

### Useful links

- [**UI Kit** (Zeplin)](https://zpl.io/25wDqZe). _For access, contact [The Economist IT Service Desk](mailto:itservicedesklon@economist.com)_
- [**UI Kit** (Sketch Cloud)](https://www.sketch.com/s/94f76aac-75c3-4911-8b34-8f0fa937807b). _For access, contact [Mark Mitchell](mailto:markmitchell@economist.com)._
- [**README** (GitHub repository)](README.md)
- [**Front-end guidelines**](FE-GUIDELINES.md)

### Design system team

- **Product owner / Design lead**: Mark Mitchell ([@withoutnations](https://github.com/withoutnations))
- **Engineering manager**: Kristy Nolan ([@kristyanne](https://github.com/kristyanne))
- **Product manager**: Sydnee Watlow
- **Product manager**: Richard Holden

## Guidelines and requirements

### Design requirements

Components must meet the design specifications of the design system **UI Kit**. Design specifications for a component are available in [Sketch Cloud](#useful-links) and [Zeplin](#useful-links).

**Proposed components**

To establish a working process to jointly integrate proposed components into the design system repository and **UI Kit**, either contact the **Product owner** or post to the `#design-system` Slack channel.

### Front-end guidelines

Reviewers will check a component meets the standards of the [Front-end guidelines](FE-GUIDELINES.md).

### Environment setup

We use the following tools to maintain consistency:

- [ESLint](https://eslint.org/)
- [Stylelint](https://stylelint.io/)
- [Prettier](https://prettier.io/)
- [EditorConfig](https://editorconfig.org/)

_**Please make sure your environment and editor is set up correctly to utilise these.**_

## Running on Windows

If running the design system on a Windows machine it is recommended to use `bash` when running the npm scripts instead of the default `cmd.exe`.

This can be accomplished by running the folllowing:

(_86 bit installation_)
`npm config set script-shell "C:\\Program Files (x86)\\git\\bin\\bash.exe"`

(_64 bit installation_)
`npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe"`

**To revert run:**
`npm config delete script-shell`

**Note:** [git for Windows](https://git-scm.com/) is a requirement.

# Running on MacOS v13+ with Apple Silicon

You may see errors when trying to run the Design System on newer Mac devices using apple silicon. This is due to Python v2.7 not being available to the scripts, even if installed.

- To fix this, you need to install [Pyenv](https://github.com/pyenv/pyenv)

- Then follow the instructions to [Set up your shell environment for Pyenv](https://github.com/pyenv/pyenv#set-up-your-shell-environment-for-pyenv)

- Finally, run `pyenv install` while in the Design System directory to install the correct version of python, which will be used when in this directory
  (The version number is pulled from `.python-version` file)

## Code style guide

For CSS, the code style is configured with stylelint using Airbnb rules with modifications. Details can be found in our [Front-end guidelines](FE-GUIDELINES.md#css-linting).

For JavaScript, the code style is configured with ESLint using the [Airbnb JavaScript style guide](https://github.com/airbnb/javascript) and recommended settings from [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react#recommended) with a few local overrides. ESLint is also configured with [Prettier](https://prettier.io/) to maintain consistent code formatting among contributors. Any additional style and linting rules can be found in [.eslintrc.js](.eslintrc.js).

We recommend setting up stylelint, ESLint and [Prettier for your editor](https://prettier.io/docs/en/editors.html)
for automatic formatting. Otherwise, run `npm run lint:fix` to automatically fix JavaScript warnings with ESLint, and `npm run stylelint` to detect CSS warnings.

## Component naming and location

When building a component that is intended for use across all digital Economist products, place it in the `src/common/components/` directory. Place components intended only for use in a specific platform or channel in their respective directory, e.g. `src/EIU/components/component-name`.

Every component must include:

- `component-name.js`
- `component-name.css`
- `component-name.test.js`
- `component-name.stories.js`

Plans are in motion to replace docz with Storybook so for a while we will see `*.docz.mdx` and `*.stories.js` files side-by-side. If you are adding a new component, you only have to worry about Storybook.

When you try to commit components that do not have docz files, you will get asked whether you want to create new docz files for them - hit `n` and the components will be whitelisted, which means this error will not occur again. You will need to do your commit on the command line (rather than in a GUI) for this to be visible.

Alternatively, you can add files to the [whitelist](scripts/whitelist.txt) manually.

The component name should mirror the labels assigned to the component in the **UI Kit**. For example:

```sh
# Button
src/common/components/button/
button.js
button.css
button.test.js
button.stories.js

# Navigation disclosure
src/common/components/navigation-disclosure/
navigation-disclosure.js
navigation-disclosure.css
navigation-disclosure.test.js
navigation-disclosure.stories.js
```

## CSS classnames

Prefix component CSS class names in the design system to avoid conflicts with project-level styling.

For common components, prefix with `ds-`:

```css
.ds-button {
}
```

For a platform or channel, create a two-letter prefix. For example, the EIU might use `eiu-`:

```css
.eiu-button {
}
```

Component CSS classes should follow component names in the design system UI Kit, written as “**Name (_variant_)**”. Use hyphens for spaces, and for each variant add a new modifier class.

**Examples:**

```css
/* Button */
.ds-button {
}

/* Button (inverse) */
.ds-button {
}
.ds-button--inverse {
}

/* Button (inverse, secondary) */
.ds-button {
}
.ds-button--inverse {
}
.ds-button--secondary {
}

/* Navigation disclosure */
.ds-navigation-disclosure {
}

/* Navigation disclosure with icon */
.ds-navigation-disclosure-with-icon {
}

/* Navigation disclosure with icon (inverse) */
.ds-navigation-disclosure-with-icon {
}
.ds-navigation-disclosure-with-icon--inverse {
}

/* Section headline + rule (accent) */
.ds-section-headline {
}
.ds-section-headline--rule-accent {
}
```

## Storybook requirements

As detailed above, each component must include a Storybook file that follows the naming convention of `.stories.js`. This file is used to create a component story for Storybook.

## Component assets

Place component assets (such as images and fonts) in a separate `static` directory. For common components, this is found in `eds://common/static/` and for a platform or channel, follow the same convention `eds://EIU/static/`.

To include an asset in the component JavaScript file:

```js
import AssetName from '../../static/images/icons/asset.svg';
```

To include an asset in the component CSS file:

```css
background-image: url('eds://common/static/images/asset.svg');
```

### SVGs

When adding SVGs to the codebase individually, consider using the [SVGOMG](https://jakearchibald.github.io/svgomg/) online tool to neaten and optimise files.

## Scripts / Tasks

**`npm run docs`**

Used to build and preview all components.
[Docz](https://www.docz.site) is a documentation system that allows developers to browse, organize and test design system components within the browser.

This will eventually be replaced by Storybook

**`npm run storybook`**

Build and open Storybook - this allows you to preview Design System components in isolation

**`npm run dev`**

To preview components as you would in a project, add a component to `/pages/index.js`. By default, this page includes the `<Masthead>` and `<Footer>` components. These can be modified or removed for testing, but do not commit the changes.

**`npm run coverage`**

Checks unit test coverage.

**`npm run test[:watch]`**

Runs Jest unit tests and optionally watch for changes.

**`npm run lint[:fix]`**

Lints all components and optinally will attempt to fix issues.

**`npm run stylelint`**

Lints all CSS.

**`npm run assets:svgr`**

Helpful to quickly create React components from SVGs from `src/common/static/images/svgr` to `src/common/components/assets/svgr` using [gregberge/svgr](https://github.com/gregberge/svgr).

## Workflow

### Create a new branch

To begin work on a new component or issue, create a branch from `master` following the format:

```sh
# Creating new components
feature/component-name

# Add a brief description when modifying existing components
feature/component-name/changes

# Reference the ticket for a specific issue (a brief description is optional)
feature/ds-999
feature/ds-1000-button-a11y
```

### Create a pull request

When raising a pull request, the checklist template should be checked and completed.

When a pull request for a new component is submitted for review, reviewers will test a component's functionality and check that the component meets a set of guidelines and standards.

In your pull request, include a line to indicate the intended version type. Our publishing process uses [Semantic Versioning](https://semver.org/) (semver): releases are categorised as either **major**, **minor**, or **patch**.

#### Linting and testing

Every pull request must pass all linting checks and tests. When a pull request is created, the build process will check that each component passes the configuration defined in `.eslintrc` and `.stylelintrc`.

Components must include unit tests (defined in `component-name.test.js`). Tests use [Jest](https://jestjs.io) & [Enzyme](https://airbnb.io/enzyme/). Some components, such as colour or typography, may be exempt from the tests requirement. Aim to add good test coverage which can be checked by running `npm run coverage`.

Any outstanding errors must be corrected before publishing.

### Reviewers

Pull requests have no set number of reviewers. Generally, it is more important to check that the most relevant people are involved in the process. For the time being, this should always include the **Product owner** and **Tech lead**, but is open to further review and collaboration.

The design system team, as it grows, will refine the governance process and defer to the acceptance criteria of this document and experienced reviewers.

### Manual testing

Reviewers will test a component independently in the design system repository. This is to ensure that the component is functional, that it includes all required styling and interactions and that it does not have any dependencies on other projects.

## Publishing a component

Follow the publishing guidelines in [Maintainers](https://github.com/EconomistDigitalSolutions/design-system/blob/next/MAINTAINERS.md#publishing)

## Consume a component

To import a newly published component into a project, update the npm component in the project to reflect the latest release. This is done in `package.json`, and it is recommended that the person responsible for submitting the component for review also makes the change in the project.

### Beta and canary

To use a beta or canary release component in a project:

```sh
npm i @economist/design-system@beta`
npm i @economist/design-system@canary`
```

The version can also be changed manually in the project's `package.json` file.
