# Rewards-FE-Design-System

[![github release version](https://img.shields.io/github/v/release/nhn/tui.editor.svg?include_prereleases)](https://github.com/nhn/tui.editor/releases/latest) [![npm version](https://img.shields.io/npm/v/@toast-ui/editor.svg)](https://www.npmjs.com/package/@toast-ui/editor) [![license](https://img.shields.io/github/license/nhn/tui.editor.svg)](https://github.com/nhn/tui.editor/blob/master/LICENSE)

## ⚡️ Table of Contents

- [Packages](#-relevant-packages)
- [Rewards](#-rewards)
- [Storybook](#-storybook)
- [How to create a story](#-how-to-create-a-story)
- [How to test your component](#-how-to-test-your-component)
- [Pull Request Steps](#-pull-request)
- [Build](#-build)
- [Deployment](#-deployment)
- [Contributors](#-contributors)

# 📦 Relevant Packages

| Name                                                                          | Description                             |
| ----------------------------------------------------------------------------- | --------------------------------------- |
| [`rollup`](https://github.com/rollup/rollup)                                  | ES Module bundler                       |
| [`storybook`](https://github.com/storybookjs/storybook)                       | Component Library builder               |
| [`jest`](https://jestjs.io/docs/configuration)                                | Unit testing library                    |
| [`node-sass`](https://github.com/sass/node-sass)                              | Provides binding for Node.js to LibSass |
| [`styled-components`](https://github.com/styled-components/styled-components) | Component Styling Library               |
| [`react`](https://github.com/facebook/react)                                  | Frontend Framework for Web              |
| [`react-native`](https://github.com/facebook/react-native)                    | Frontend Framewrok for Mobile apps      |
| [`typescript`](https://github.com/microsoft/TypeScript)                       | Static Typing Programming Language      |
|                                                                               |

# ⭐️ Rewards

Currently at the company we have several projects that are built with React and React-Native frameworks. Each project has several components that sometimes they are duplicated from other projects. This is a bad practice because we are basically duplicating a lot of code through our projects. The solution to this is a component library.

### 📖 What is a component library?

A component library is a set of reusable components that can be used on multiple projects just by importing them. Our library offers the chance to standardize development, reduce code duplications, improve collaboration between teams, and drive scalability.

# 📚 Storybook

Storybook is a library for building component libraries for mobile and web. To create our component library we used storybook to achieve it.

### 🏃‍♂️ How to run the project

1. The first step is to clone the project using this command on your terminal

````
git clone git@github.com:ab-inbev-global-martech/Rewards-FE-Design-System.git ```
````

2. Then run yarn to install all the package dependencies of the project

```
yarn
```

3. After all the packages are installed run this command to start storybook

```
yarn run storybook
```

4. That's all! You should be able to see this screen:
   <img width="1438" alt="Screen Shot 2022-05-11 at 12 22 49" src="https://user-images.githubusercontent.com/16018384/168408045-c506c787-de83-4fc9-b4b3-91a7377c7486.png">

## 🤯 Exploring Storybook

# Left Sided Menu

This menu is used mainly to navigate through the different components that exist in the component library.

![Screen Shot 2022-05-12 at 10 26 46](https://user-images.githubusercontent.com/16018384/168111538-530b55d2-8d41-4c1a-8a73-16801c8f0e03.png)

# Canvas

The canvas is used to display the component with it's corresponding properties provided in the controls.

![Screen Shot 2022-05-12 at 10 27 12](https://user-images.githubusercontent.com/16018384/168111631-d1368528-3d02-45f8-9bc7-44a6e31de5d5.png)

# Docs

In the docs screen you can visualize the canvas itself, some tools, the properties of the component and the specific code you need to use to implement the component in your project.

![Screen Shot 2022-05-12 at 10 27 34](https://user-images.githubusercontent.com/16018384/168111791-c282967d-f8c7-493e-a91e-0bb06e3832e0.png)

# Controls, Actions and Interactions

We have the controls where you can see the different properties that the components have, you can play with those properties and see how the component changes in the canvas. If you want to see any interaction or action within the component you can go to the other pages of the menu (Actions and Interactions).

![Screen Shot 2022-05-12 at 10 27 51](https://user-images.githubusercontent.com/16018384/168111855-52d270c5-7024-4e99-a4af-f79468642060.png)

# Top Side Bar

On this top side bar you can change between the Canvas and the documentation of the component. Also, you have several tools such like a Zoom in and Zoom out buttons, a ruler, a grid and more...
![Screen Shot 2022-05-12 at 10 28 03](https://user-images.githubusercontent.com/16018384/168111886-07fa38ca-ee13-4b58-a383-bc4b9000d74a.png)

# 🏰 How to create a story

### What is a story?

A story captures the rendered state of a UI component. Developers write multiple stories per component that describe all the “interesting” states a component can support. A story is a function that describes how to render the component in question.

The first step is to create a story file such like this: (This example is for a button default component)

`ButtonDefault.stories.tsx`

1. First import the following elements:

```
import React from 'react';
import { ComponentMeta, ComponentStory } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { AtomButtonDefault } from 'native/atoms/Buttons/Default';
```

2. Then create an object that will contain the information about the story such as the title, component, argument types and parameters

```
export default {
  title: 'React Native/atoms/Button/Default', // The location of the b
  component: AtomButtonDefault, // The component that will be rendered
  argTypes: {},
  parameters: {
    controls: { expanded: true },
  },
} as ComponentMeta<typeof AtomButtonDefault>;
```

3. Then you create your component story and return the button component with the corresponding props/arguments

```
// By passing using the Args format for exported stories, you can control the props for a component for reuse in a test
// https://storybook.js.org/docs/react/workflows/unit-testing
export const Default: ComponentStory<typeof AtomButtonDefault> = (args) => (
  <AtomButtonDefault {...args} />
);
```

4. This object defines the default values that the button will have in the story.

```
Default.args = {
  disabled: false,
  onPress: action('Event Click'),
  styles: 'primary',
  text: 'Text',
  width: '144',
  customStyle: 'tertiary',
};

```

Complete code:

```
// stories/MyButton.stories.tsx
import React from 'react';
import { ComponentMeta, ComponentStory } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { AtomButtonDefault } from 'native/atoms/Buttons/Default';

export default {
  title: 'React Native/atoms/Button/Default',
  component: AtomButtonDefault,
  argTypes: {},
  parameters: {
    controls: { expanded: true },
  },
} as ComponentMeta<typeof AtomButtonDefault>;

// By passing using the Args format for exported stories, you can control the props for a component for reuse in a test
// https://storybook.js.org/docs/react/workflows/unit-testing
export const Default: ComponentStory<typeof AtomButtonDefault> = (args) => (
  <AtomButtonDefault {...args} />
);

Default.args = {
  disabled: false,
  onPress: action('Event Click'),
  styles: 'primary',
  text: 'Text',
  width: '144',
  customStyle: 'tertiary',
};
```

Now that we created the story, we need to create our component for that story so that we can play with it in our storybook interface.

`ButtonDefault.tsx`

```
import React, { FunctionComponent } from 'react';
import { theme } from 'data/dataMx';
import { GeneralStyledButton } from './styles';
import { IProps } from '../ButtonProps';

export const ButtonDefault: FunctionComponent<IProps> = ({
  disabled,
  onClick,
  styles,
  text,
  type,
  width = '144px',
  outline = 'auto',
  customStyle = 'tertiary',
}) => {
  return (
    <GeneralStyledButton
      disabled={disabled}
      onClick={onClick}
      styles={styles}
      width={width}
      outline={outline}
      theme={theme}
      type={type}
      color={customStyle}
      customStyle={customStyle}
    >
      {text && <h1>{text}</h1>}
    </GeneralStyledButton>
  );
};
```

Congrats! You created your first story 🥳

# 💥 How to test your component

For unit testing the components we use Jest and React testing library, those libraries are widely used for unit testing web and mobile components.

To test our Button component we need to create a .test.tsx file for that specific component.

`index.test.tsx`

```
import React from 'react';
import '@testing-library/jest-dom';
import { ButtonDefault } from './index';
import { render, fireEvent } from '@testing-library/react';

describe('[React] ButtonDefault', () => {
  test('Render button', () => {
    const body = { // Props
      disabled: false,
      styles: 'secondary',
      text: 'Accept',
      type: 'button',
      width: '144px',
      outline: 'auto',
    } as const;
    // We create our component
    let component = render(<ButtonDefault {...body} />);
    // We check if the component exists in the DOM.
    component.getByText(body.text);
  });
});

```

We use the `describe()` function to wrap our different unit tests, then we create our test using `test()` and write it depending on what we want to test.

### But how do we run our test?

## Mac OS

### React

```
yarn run test:react
```

### React Native

```
yarn run test:native
```

## Windows

### React

```
yarn run test:react-windows
```

### React Native

```
yarn run test:native-windows
```

# 🔎 Pull Request

Pull request guidelines:

1. A pull request should contain just one component with its corresponding styles, test file, and story.
2. The title of the PR should be the name of the ticket that corresponds to the component being developed (ex. JESS-1320)
3. The description of the PR should contain a brief description of the component being developed.

# 🔨 Build

Finally, to build the component library so that it can be published to yarn or npm we run:

```
yarn build
```

Running this command will generate the `dist` and `native` folder that contains the builded content of the component library. To modify the configuration of the build, you can look into the file `rollup.config.js`

# 🐥 Deployment

[TO DO - Add steps for deployment]

# 💪 Contributors

[TO DO - List contributors]
