# OpenFin UI Library

> React component library for OpenFin Workspace products – Informed by [Spatial](https://www.figma.com/file/0Y3pKZj0tJWuleF12h5Sua/Spatial---Components).

**Storybook:** [cdn.openfin.co/workspace/storybook](https://cdn.openfin.co/workspace/storybook)
**NPM Package:** [@openfin/ui-library](https://www.npmjs.com/package/@openfin/ui-library)

![Release Package](https://github.com/openfin/ui-library/actions/workflows/release-package.yml/badge.svg)

## What is this for?

**TL;DR** – Use this library and write less CSS.

This is an opinionated React component library, built on top of [styled-components](https://styled-components.com/docs), which aims to provide the basic building blocks that you can use in any OpenFin environment. It was built w/ our [Spatial Design System](https://www.figma.com/file/0Y3pKZj0tJWuleF12h5Sua/Spatial---Components) in mind, so it should always reflect OpenFin's latest branding and designs.

## Installation

### 1. Make sure you have @openfin NPM access

- Make sure you have @openfin private NPM registry access
- Log in to npm, preferably via `npm login`.

### 2. Install the package

…along with `styled-components`.

```bash
# Install the latest version
$ yarn add @openfin/ui-library styled-components
# For npm
$ npm i @openfin/ui-library styled-components
```

```bash
# Install a specific version
$ yarn add @openfin/ui-library@v0.8.0
# For npm
$ npm i @openfin/ui-library@0.8.0
```

## Usage

### ThemeProvider

`ThemeProvider` is the component that provides theme information to the `ui-library` components nested deeply within your application. Make sure to include this above your application so your components will be styled properly.

```javascript
import { ThemeProvider } from '@openfin/ui-library';
import MyApp from 'some/cool/place';

const MyCoolAppContainer = () => (
  <ThemeProvider>
    <MyApp />
  </ThemeProvider>
);
```

### Basic Usage

```javascript
import { Box, H1, Icon, TextInput } from '@openfin/ui-library';

export const MyApp = () => (
  <Box flexDirection="column">
    <H1>
      <Icon icon="OpenFinIcon" /> Cool heading
    </H1>

    <TextInput placeholder="Cool stuff goes here" />
  </Box>
);
```

**View the [Full Component Docs](./src/components) for more usage info.**

### Extending Components

Whenever possible, it is prefereable to use the components as-is. However – using [styled-components](https://styled-components.com/docs), it is very easy. Try using the following guiding principles when doing so:

- Familiarize yourself w/ the `theme` prop, and use it whenever possible.
- Avoid hard-coded pixel values.
- Don't _ever_ use hard-coded color values.

```javascript
import { Box, Text } from '@openfin/ui-library';
import styled from 'styled-components';

export const MyCoolComponent = () => (
  <Container flexDirection="column">
    <ImportantText>How cool is this?</ImportantText>
    <Text weight="bold">Super cool</Text>
  </Container>
);

const Container = styled(Box)`
  background: ${({ theme }) => theme.palette.background6};
  border-radius: ${({ theme }) => theme.radius.small};
  margin: ${({ theme }) => `${theme.px.small} 0 ${theme.px.base}`};
`;

const ImportantText = styled(Text)`
  color: ${({ theme }) => theme.palette.statusWarning};
  cursor: pointer;
  font-weight: ${({ theme }) => theme.fontWeight.bold};
`;
```

## Contributing

### Open a pull request 😎

Pull requests are a great way to express an idea or need, if it's easier to "show" instead of "tell", go for it, propose a change!

Also keep in mind, UI Library is a home of centralized common components, **used by several products**. It's reasonable to expect PRs may spark conversations about the **essence of the change** and it's benefits and impact across the application ecosystem.

Meaning: While there are no hard rules about what belongs in _our_ library, if a change is too opinionated or too specialized, it may make sense to leave it out. **A library that does less, is a lot easier to know and work with**.

**Please be sure to update the package version before submitting your pull request.** If you are unsure what the new verison should be, please refer to [Semantic Versioning](https://semver.org/).

### Storybook

Great for exploring and experimenting with UI Library components. It's also used for [testing our components](https://storybook.js.org/docs/react/workflows/unit-testing).

```bash
# Run it locally
$ npm run storybook
```

### Codesandbox.io

Great for developer experimentation without all of the overhead.

The sandbox is currently **private**, request access and [give it a try](https://codesandbox.io/s/openfin-ui-library-39y7c).

### Working locally w/ other apps

Sometimes you may need to work on the `ui-library` alongside your own application. We use [yalc](https://www.npmjs.com/package/yalc) for this. It solves a few problems that `yarn link` creates, and it's pretty intuitive.

#### 1. Install and setup yalc

```bash
# Make sure yalc is installed globally
$ npm i yalc -g

# Set up yalc in ui-library
$ cd ui-library/
$ yalc publish

# Add local ui-library package to your app
$ cd ../myCoolApp/
$ yalc add @openfin/ui-library
```

This links your local copy of UI Library to your app using symlinks and `package.json`.

#### 2. Working with yalc

Once you're setup, subsequent changes in UI Library can be propagated across easily.

After making changes in `ui-library`, run `npm run build && yalc push`. This will apply a version bump to the local yalc package respository. It will also update the package in your app directory, but you will most likely need to restart any development servers to see the changes.

```sh
# push updates from ui-library side to your app
$ npm run build && yalc push
```

#### Known Issues

- Storybook does not pick up changes after a `yalc push` and must be restarted

## Compiling the Library

### `tsonfig.json`

The base Typescript config.

### `tsonfig.bundle.json`

Extending base config used by `tsc` when bundling the library for a new release.

### `tsonfig.storybook.json`

Extending base config used by `Storybook` to quiet some extraneous warnings.

## Testing

```sh
npm run test
```

## Versioning & Releasing

### 1. Bump package version

Once you are ready to make a new release and all PRs meant for a release have been merged into `main` branch, you should now create a new branch to bump the package version (for example name the branch `<yourName>/bump-version/<new-version-number>`). Next, run `npm version [<newversion> | major | minor | patch]` to bump the package version. Now, create a PR into the `main` branch and get that PR approved and merged.

### 2. Create a release branch

Now that the package version is up to date, you should now create a new release branch in github. To do so, go to the [list of branches](https://github.com/openfin/ui-library/branches) and click 'New Branch.' Name the new branch `release/<new-version-number>` (for example `release/0.14.3`) and make sure the branch source is `main`.

### 3. Create a new release on Github

Once you have created the release branch, you should now create a release through github:

- Click [Create a New Release](https://github.com/openfin/ui-library/releases/new)
- Create a new tag, labelled `<new-version-number>`. (for example `0.14.3`)
- Change the target branch to the release branch you just created. (for example `release/0.14.3`)
- Enter the release title to match the tag you just created. (for example `0.14.3`)
- In the description, enter the changelog from the previous tag. (for example if previous tag is `0.14.2` then your description should be "Change log: `https://github.com/openfin/ui-library/compare/0.14.2...0.14.3`") (Don't worry, you can always go back and edit the description later.)

This triggers a Github Action to automatically build the latest version of the `ui-library` and package it for remote installation. You can check the status of this task within this repo's actions tab.
