# Contributing

## General

### List of components/tasks in Jira

[Jira Tasks](https://jira.kiwi.com/secure/RapidBoard.jspa?rapidView=306&projectKey=ORBIT&view=planning&epics=visible&selectedEpic=ORBIT-201)

- When starting to work on a new component, assign the task to yourself to avoid double work.
- Only components from Jira should go to Orbit. If there is any other possible candidate, discuss in #orbit-react-native with the core team.
- Component specification is usually linked to Storybook (for visual design and interactions), with another link to Orbit.Kiwi for API specification.

### “Experimental components”

"Experimental" components only support features needed for Account.

- The API of "Experimental" components needs to be same as React components. If there is some variation missing, it should be noted (as `@TODO` in the component's code).
- The Orbit core team will extend the API and functionality of these components.

### Release process

- Components won’t be release without reviews.
  - All components are code reviewed by RN devs from Orbit core.
  - Final approval for release is from @vepor, he will check the API, naming consistency, and usage of design tokens.
  - All components need to pass design review from @honza or @will.
- Even that we are working with experimental components and non-stable version according to semver (`0.x.x`), a complete changelog has to be created for every release and prepended to `CHANGELOG.md` and posted to #orbit-react-native channel.

## Technology

- Every component will have Storybook with Playground where you can modify their props.
- Components should respect naming conventions and separation for styles, types, etc.

### Component folder structure

Files should be grouped together as a logical unit:

```
src/Tile/ (component folder)
├── __tests__/ (test folder)
│   ├── Tile.test.js (main component tests)
│   ├── TileExpandable.test.js (related component tests)
│   └── TileHeader.test.js (related component tests)
├── __templates__/ (generated files template folder)
│   └── SomeGeneratedFile.template.js (template for generated file)
├── index.js (export everything here)
├── TileExpandable.js (related component)
├── TileExpandable.web.js (related component's web version)
├── TileHeader.js (related component)
├── Tile.js (main component)
├── Tile.stories.js (Storybook stories)
├── Tile.styles.js (component specific styles)
├── Tile.types.js (Flow types for all components)
└── README.md (Readme.md file with API documentation, check current React components as the example https://github.com/kiwicom/orbit-components/tree/master/src)
```

### Code style

- Most of the time, the monorepo setup will tell you what to do, so the basics are set
  - Never use `$FlowFixMe`, find a way to make Flow work for you.
- Think about readability first, performance second
  - We will fix it later, if it’s very slow or something.
- KISS
  - Don’t import external packages, unless you really need to,
  - Don’t over-engineer anything,
  - Don’t pre-optimize anything, it’s not worth it,
  - If something can be done with a few lines of hand written code, don’t try to construct a 100 line monstrosity to automate it.
- Functions
  - Arrow functions vs named functions
    - Arrow functions whenever there is a loop (outside of render() ),
    - Named functions, whenever you want to explain what your method is doing.
  - Function length
    - Try to use common sense when deciding if a function should be split up into smaller chunks:
      - If it’s one logical unit, keep it as is,
      - If it’s beneficial to name parts of the function, split it up,
      - Do not split something up, just because you want to be able to test it better (we’re not writing code for tests, we’re writing code for our users)
    - If you are unsure, just ask!
  - `__templates__`
    - The files in these folders are running on NodeJS, so use the comment-style Flow styles,
    - Use CommonJS syntax instead of imports.
  - Components
    - When importing components from React Native, import them like `import { Text as RNText } from ‘react-native’;` for consistency,
    - Export the component as `default`, but also as a named export,
    - Use hooks whenever you can,
    - Use `console.warn()` for errors that should be caught during development. (They will be filtered out during build by metro.)
      - (This will change, once we have `@kiwicom/js` imported and working.)
  - Storybook stories
    - Even though the stories are in the same folder as the component files, they belong to the Orbit React Native Docs project.
  - Testing
    - We are following the Lean Testing methodology.
      - https://rbcs-us.com/documents/Why-Most-Unit-Testing-is-Waste.pdf
      - https://blog.usejournal.com/lean-testing-or-why-unit-tests-are-worse-than-you-think-b6500139a009
    - Jest Unit tests
      - Only write unit tests for things that absolutely require it,
      - Try to not mock anything because we want to test the components and units of code, not test mocks.
  - Visual Regression Testing (coming soon)
    - TODO: Each component should have a Storybook page where all the different states and modes are shown, and it will be used for screenshot testing on all supported platforms and browsers. This way we won’t have to write 100 unit tests that will break whenever we refactor code, or change some internal APIs -> we will actually be testing the components as they are being used, instead of testing what the computer sees.

## Things to solve

- Preparing Orbit.Kiwi for RN documentation, so everything is on one place.
