# Quick start

Hive UI-Kit is a comprehensive design system created to build advanced user interfaces for Sinch SMB products.

## Before start

Create a basic React app using the Typescript template and install the Hive UI-Kit library.

```shell
npx create-react-app test-app --template typescript
cd test-app
npm i @sinchsmb/ui-kit
```

## Install required dependencies

- `npm i date-fns` — date utility library
- `npm i formik` — form library
- `npm i i18next react-i18next` — internationalization framework

## HiveUIStarter

It is a starter wrapper around the `HiveUI` with a pre-configured theme, translation, localization, and pre-defined `linkComponent`. 
It is designed as an introduction to the HiveUI system and **can't be configured**.

Feel free to use it as a playground to better understand the system or for simple projects. 
Avoid using it in complex production as it can't be customized.

**Example**

```tsx
import { HiveUIStarter } from '@sinchsmb/ui-kit/HiveUIStarter';
import { Button } from '@sinchsmb/ui-kit';

<HiveUIStarter>
  <Button>Start</Button>
</HiveUIStarter>
```

## Custom theme, links, translation and locales

To unleash the full power of the Hive UI-Kit library, we will need to replace the `<HiveUIStarter>` wrapper with a more advanced `<HiveUI>`. But before doing that we should do some preparations.

### Generate required theme

[Hive Design Tokens](https://github.com/varzin/hive-design-tokens) repository contains design constants for all the available themes. Follow the steps from its readme to generate required ones. Then put the final theme files somewhere in your `src` folder.

### Links
Hive UI is router agnostic. You can use any router library. But in some cases, Hive UI creates links. 
To create them based on router-specific links, you should configure the `HiveUI` component by passing the `linkComponent` prop.
You can use the react-router `Link` component or a custom if you want.

**Example**

```tsx
import { Link } from 'react-router-dom';

<HiveUI linkComponent={Link} {...otherProps}>{/* UI code */}</HiveUI>
```

**Example**

```tsx
import { HiveUI, LinkComponent, LinkComponentProps } from '@sinchsmb/ui-kit'

const Link: LinkComponent = forwardRef<HTMLAnchorElement, LinkComponentProps>(({ to, children, ...rest }, ref) => {
  return (<a href={to} ref={ref} {...rest}>{children}</a>);
});

<HiveUI linkComponent={Link} {...otherProps}>{/* UI code */}</HiveUI>
```


### Prepare translations and locales

Firstly, you need to prepare your translations.

You can use external services, such as [Ditto](https://www.dittowords.com), [Lokalise](https://lokalise.com), or [Locize](https://locize.com), to sync all your translations. Alternatively you can store your translations in files using [i18next documentation](https://i18next.com) format. Let's go with the second option for now.

Let's say our application supports the locales:

- English (US)
- French (Canada)

Configure language files in a similar manner:

**Example**

```ts
// src/language/fr/index.ts
import translation from './translation.json';
export const fr = translation;
```

```json
// src/language/fr/translation.json
{
  "general": {
    "loading": "Chargement ...",
    "greeting": "Bonjour"
  },
  "forms": {
    "login": "Connexion",
    "password": "Mot de passe",
    "account": "Compte",
    "save": "Save",
    "cancel": "Annuler",
    "signin": "S'identifier"
  }
}
```

Do the same for English as well. Or, if built-in English translation is suitable, you can import it; see the example below

### Update the App.tsx first

As almost everything is ready, it's time to update the `App.tsx` in the following way:

```tsx
import { useMemo } from 'react';
import { HiveUI, LanguageConfig, Button, ButtonAppearance, FormikTextField } from '@sinchsmb/ui-kit';
import { createInstance } from 'i18next';
import { I18nextProvider, useTranslation } from 'react-i18next';
import { BrowserRouter, Link } from 'react-router-dom';
import { Form, Formik } from 'formik';

import { en } from '@sinchsmb/ui-kit/locale'; // use built-in English translation
import { fr } from './fr';

import theme from './messageMediaTheme.json';

import en_US from 'date-fns/locale/en-US';
import fr_CA from 'date-fns/locale/fr-CA';

function App() {
  const i18n = useMemo(() => {
    const instance = createInstance();

    instance.init({
      resources: {
        // All the used translations
        en: {
          translation: en
        },
        fr: {
          translation: fr
        },
      },
      lng: 'en',
      fallbackLng: 'en',
      interpolation: {
        escapeValue: false, // React is already protected from XSS => https://www.i18next.com/translation-function/interpolation#unescape
      },
    });

    return instance;
  }, []);

  const languages = useMemo(
    () =>
      [
        {
          language: 'en',
          defaultLocale: 'en_US',
          locales: {
            en_US: {
              dateFns: en_US,
            },
          },
        },
        {
          language: 'fr',
          defaultLocale: 'fr_CA',
          locales: {
            fr_CA: {
              dateFns: fr_CA,
            },
          },
        },
      ] as LanguageConfig[],
    [],
  );

  return (
    <BrowserRouter>
      <HiveUI i18n={i18n} theme={theme} languages={languages} linkComponent={Link}>
        <LoginUI />
      </HiveUI>
    </BrowserRouter>
  );
}

export default App;
```

### Create new UI for `<LoginUI />` component

As a final touch let's add the following code to the `App.tsx` file,

```tsx
function LoginUI() {
  const { t } = useTranslation();

  return (
    <Formik initialValues={{}} onSubmit={() => {}}>
      <Form>
        <FormikTextField label={t('forms.login')} name="login" />
        <FormikTextField label={t('forms.password')} name="pass" obscureText />
        <Button appearance={ButtonAppearance.Primary}>{t('forms.signin')}</Button>
      </Form>
    </Formik>
  );
}
```

## Conclusion

Now you have working UI that supports translation and visual themes. You can find more components and examples in [Hive Storybook](https://hive.simpletexting.com).
