# 1. UI components library

### Introduction

Agrofy’s UI Components library is a **React UI** kit which contains a number of basic elements such as buttons and links. It implement **Atomic Design** principles.

The terminology Atomic Design is an analogy from biochemistry. It’s all about “Atoms”, “Molecules” and “Organisms”.

Atomic Design is a methodology used to create web designs.

**Atoms** are the basic building blocks of all matter. Each chemical element has distinct properties, and they can’t be broken down further without losing their meaning. (Yes, it’s true atoms are composed of even smaller bits like protons, electrons, and neutrons, but atoms are the smallest functional unit.)

**Molecules** are groups of two or more atoms held together by chemical bonds. These combinations of atoms take on their own unique properties, and become more tangible and operational than atoms.

**Organisms** are assemblies of molecules functioning together as a unit. These relatively complex structures can range from single-celled organisms all the way up to incredibly sophisticated organisms like human beings.

**More info:** <http://atomicdesign.bradfrost.com/>

### Developer’s guide

#### Function Components

React components can be created as Classes or Functions but this library use **only** functional components in order to use the latest react strategy for building components.

```jsx
// atoms/AgroSpinner/AgroSpinner.js

import React from 'react';

const AgroSpinner = ({width, height}) => {
  return (
    <div width={width} height={height}/>
  );
};

export default AgroSpinner;
```

**More info:**

* <https://reactjs.org/>
* <https://reactjs.org/docs/hooks-intro.html>

#### Styled-components

Styled-components lets you write CSS in your JavaScript:

```jsx
// atoms/AgroSpinner/AgroSpinner.js

import React from 'react';
import styled, {keyframes} from 'styled-components';

/* Animation */
const rotate = keyframes`
  to {
    transform: rotate(360deg);
  }
`;

/* Styles */
const Spinner = styled.div`
  width: ${props => props.width ? props.width : '40px'};
  height: ${props => props.height ? props.height : '40px'};
  border-radius: 50%;
  background: transparent;
  border-top: 3px solid #fff;
  border-right: 3px solid #fff;
  border-bottom: 3px solid #ffffff5e;
  border-left: 3px solid #ffffff5e;
    animation: ${rotate} 1.2s infinite linear;
`;

const AgroSpinner = ({width, height}) => {
  return (
    <Spinner width={width} height={height}/>
  );
};

export default AgroSpinner;
```

#### Storybook

The library uses **Storybook** to organize UI components and let you interact with the components props.

**More info:** <https://storybook.js.org/>

#### Build Storybook

```bash
yarn build-storybook
```

This will build the storybook configured in the Storybook directory into a static web app and place it inside the **.out** directory. Now you can deploy the content in the .out directory wherever you want.

To test it locally:

```bash
npx http-server .out
```

#### Jest

Jest is a JavaScript **testing framework** designed to ensure correctness of any JavaScript codebase. It allows you to write tests with an approachable, familiar and feature-rich API that gives you results quickly.

```jsx
// atoms/AgroSpinner/AgroSpinner.test.js

import React from 'react';
import renderer from 'react-test-renderer';
import AgroSpinner from './AgroSpinner';

describe('AgroSpinner Component', () => {
  it('Render AgroSpinner correctly', () => {
    const component = renderer.create(<AgroSpinner />).toJSON();
    expect(component).toMatchSnapshot();
  });
  it('AgroSpinner with size', () => {
    const component = renderer.create(<AgroSpinner width='10px' height='10px'/>).toJSON();
    expect(component).toMatchSnapshot();
  });
});
```

**More info:** <https://jestjs.io/>

### How to install the library

#### Install

After cloning the repository do the following steps:

```bash
cd agrofy-ui-components/
npm install
yarn start

# (in another tab) 
cd agrofy-ui-components/example
yarn install
yarn start
```

This will allow you to run an **example** site to check your component and it’s changes.

#### Test

Run the following commands:

```bash
yarn test -u

# Watch changes
yarn test --watch -u

# Check coverage
yarn test --coverage
```

#### Storybook

Run the following commands:

```bash
yarn storybook
```

### How to create a component

First you have to use Atomic design principes to decide if the component you are about to build is an Atom, Molecule or Organisms.

For example if we create a simple spinner which we call **AgroSpinner** we create a folder with the same name inside the atoms folder:

```
src
└── atoms
    └── AgroSpinner
        └── AgroSpinner
```

Then you have to create two files:

* **AgroSppiner.js** with your component code.
* **AgroSpinner.test.js** with the testing code.

```
src
└── atoms
    └── AgroSpinner
        └── AgroSpinner
            ├── AgroSppiner.js
            └── AgroSpinner.test.js
```

Add the new component at **index.js** export file:

```jsx
import AgroButton from './atoms/AgroButton/AgroButton';
import AgroSpinner from './atoms/AgroSpinner/AgroSpinner';
import GlobalStyle from './theme/GlobalStyle';

export {AgroButton, AgroSpinner, GlobalStyle};

export default {AgroButton, AgroSpinner, GlobalStyle};
```

This step is really important because it allows you to use the component outside the library.

Finally create a story on **.storybook/stories** folder:

```
.storybook
└── stories
    └── AgroSpinner.js
```

And add it as required in **.storybook/config.js**

```jsx
import {configure} from '@storybook/react';
import {addDecorator} from '@storybook/react';
import {withInfo} from '@storybook/addon-info';

function loadStories() {
  require('./stories/AgroSpinner.js');
}
configure(loadStories, module);
addDecorator(withInfo);
```

### How to use the library in a proyect

```bash
npm install --save agrofy-ui-components
```

#### Components usage

```jsx
import React from 'react'
import {AgroButton} from 'agrofy-ui-components'

const Example = () => {
  return (
    <AgroButton text='Example Button'/>
  )
}
```

### License

© [Agrofy](https://bitbucket.org/agrofydev)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://agrofy-front-end.gitbook.io/projects/1.-ui-components-library.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
