npm package: @sygniacoza/components
Description: Sygnia UI Component Library
Latest version: 0.0.1

# Sygnia React Components

A React component library for [Sygnia](https://www.sygnia.co.za), powered by [Storybook](https://storybook.js.org/).

## Table of contents

- [Library Usage](#library-usage)
  - [Import desired component into your project](#import-desired-component-into-your-project)
- [Development](#development)
  - [Switch to the correct version of Node (using NVM)](#switch-to-the-correct-version-of-node-using-nvm)
  - [Install dependencies](#install-dependencies)
  - [Run Storybook](#run-storybook)
  - [Example component directory structure](#example-component-directory-structure)
  - [Component principles](#component-principles)
  - [Adding a new component](#adding-a-new-component)
  - [Adding new Storybook documentation](#adding-new-storybook-documentation)
- [Testing](#testing)
  - [Run tests](#run-tests)
- [Building](#building)
  - [Create a build of the library](#create-a-build-of-the-library)
- [Commits](#commits)

## Library Usage

### Import desired component into your project

```js
import { ComponentName } from '@sygnia/components';
```

## Development

### Switch to the correct version of Node (using NVM)

```bash
nvm use
```

### Install dependencies

```bash
yarn
```

### Run Storybook

[Storybook](https://storybook.js.org/) is a UI development environment we are using to power our component library. Using Storybook allows us to work on components in isolation.

```bash
yarn start
```

Using Storybook requires you to wrap your component in a story. Look in the `src/components` directory for an example `.stories.js` file. Storybook has been configured to automatically include any files with the `.stories.js` file extension.

Storybook is setup using its own Webpack configuration file located at [`tools/.storybook/webpack.config.js`](./tools/.storybook/webpack.config.js).

#### Component Structure:

- Comments appear as documentation in Storybook
- Use comments to describe Component and PropTypes
- Ensure PropTypes and DefaultProps are added and up to date
- Ensure Prettier set up as per Wiki: https://gitlab.com/plusplusminus/code-snippets/wikis/Prettier-ESLint-Setup-Create-react-app
- Do not leave `console.log` in committed code unless comments explain why
- Fix linting warnings and errors as you go
- All components should be checked for responsive viewports

#### Storybook structure:

- Use folders to group similar Components
- Use group to organise individual stories
- A generic story of a component with props can be made availible as the first story eg _Hero_
- Ensure that each version of the Component with the collection of props as per design implementation exists as separate story eg _Hero with title, intros and color_ to ensure we can get visual snapshot testing on each reuired version of the component

### Example component directory structure

A component's directory should resemble the following:

```
YourComponent
├── index.js                 // A file for exporting your component
├── YourComponent.js         // Your React component
├── YourComponent.css        // Component styles
├── YourComponent.stories.js // Storybook for the component
└── YourComponent.test.js.   // Component tests
```

### Component principles

We follow a number of principles when creating our components:

1.  **A component is responsible for only its internal spacing**

We follow the principle that a component should only be responsible for its own internal spacing - never external spacing. This means that we're flexible in where our components can be used without having to override margins.

2.  **Use descriptive PropTypes**

We recommend the following naming convention for PropTypes to make them as clear as possible:

- Number - use a prefix or suffix to imply that the prop accepts a number. E.g. `numItems`, `itemCount`, `itemIndex`
- Boolean - use the prefix 'is'/'can'/'has'. E.g. `isVisible`, `canExpand`, `hasImage`
- Array - use a plural noun. E.g. `items`
- Object - use a noun. E.g. `item`
- Node - use the suffix 'Node'. E.g. `containerNode`
- Element - use the suffix 'Element'. E.g. `triggerElement`
- Event handler functions - use the prefix 'on'. E.g. `onOpen`, `onClick`

### Adding a new component

You can use [Plop](https://plopjs.com/) to scaffold new components. Run `yarn add-component` and follow the steps in the CLI to create a component. Using your input here, Plop will generate the relevant files and add the relevant imports/exports to the main `src/index.js` file required to make the component available when publishing the library.

Here is the example output of running the `yarn add-component` command:

```
? What is the name of your component? button
[SUCCESS] add /src/components/Button/Button.js
[SUCCESS] add /src/components/Button/Button.css
[SUCCESS] add /src/components/Button/Button.test.js
[SUCCESS] add /src/components/Button/Button.stories.js
[SUCCESS] modify /src/index.js
[SUCCESS] modify /src/index.js
```

### Adding new Storybook documentation

You can also use [Plop](https://plopjs.com/) to scaffold documentation sections in Storybook. Run `yarn add-documentation` and follow the steps in the CLI to create new documentation. Using your input here, Plop will generate the relevant files required to make the documentation show in Storybook.

Here is the example output of running the `yarn add-documentation` command:

```
? What is the title of your documentation? general
[SUCCESS] add /.storybook/docs/General/General.md
[SUCCESS] add /.storybook/docs/General/General.stories.js
```

## Testing

### Run tests

```bash
yarn test
```

It is recommended to run tests in development with the optional `--watch` flag.

```bash
yarn test --watch
```

## Building (WIP)

We are using a combination of [Webpack](https://webpack.js.org/) and [Babel](https://babeljs.io/) to create builds of our component library. We use Webpack with the `tools/webpack.production.config.js`

### Create a build of the library

```bash
yarn build
```

## Commits

This project uses the [Angular JS Commit Message Conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit), via semantic-release. See the semantic-release [Default Commit Message Format](https://github.com/semantic-release/semantic-release#default-commit-message-format) section for more details.

You can commit the changes by running

```bash
yarn commit
```