# Tricks with styles

## Units

StartupJS/UI initially uses an 8-pixel grid for padding. This means that the unit of measurement for padding is unit (u). One unit equals 8px. All styles that could be specified in pixels are specified in units. All sizes in styles should be specified in units. Fractional units (2.5u) should only be specified as a last resort. In situations where you need to specify 1px, for example, you can move away from using units.

For example:

.card
```css
  padding 2u 3u // 16px 24px
  margin 3u // 24px
```

## Mixins
You are already familiar with the implementation of mixins in Stylus so you can now get acquainted with the preset mixins within the @StartupJS/UI package

## font() mixin

The first mixin is `font()`, which takes one of the following parameters `[h1, h2, h3, h4, h5, h6, body1, body2, caption]`, `body2` by default.
`font()` is used within a selector for text elements and is replaced at compile time with `font-size` and `line-height`, depending on the value selected.


**Table of possible values:**

| Value    | font-size | line-height |
| -------- | --------- | ----------- |
| h1       | 72px      | 96px        |
| h2       | 48px      | 64px        |
| h3       | 36px      | 48px        |
| h4       | 24px      | 32px        |
| h5       | 20px      | 28px        |
| h6       | 16px      | 24px        |
| body1    | 16px      | 24px        |
| body2    | 14px      | 20px        |
| caption  | 12px      | 16px        |

## `shadow()` mixin

React Native has its own features when working with shadows(`box-shadow`). To avoid these complexities in everyday life, `StartupJS/UI` provides a set of predefined shadow styles for your components.

The `shadow ()` mixin has 5 levels of shadows and takes a number from `0` to` 4`, by default `1`, which both adjust the shadow level, and expands the` box-shadow` style set into the selector according to the following scheme:

| Value    | Styles                                                  |
| -------- | ------------------------------------------------------- |
| 0        | box-shadow: none и elevation: 0                         |
| 1        | box-shadow: 0 1px 2px rgba(black, 0.2) и elevation: 3   |
| 2        | box-shadow: 0 3px 5px rgba(black, 0.15) и elevation: 6  |
| 3        | box-shadow: 0 5px 8px rgba(black, 0.15) и elevation: 12 |
| 4        | box-shadow: 0 8px 12px rgba(black, 0.2) и elevation: 18 |

> For illustrative examples of how each level of shadow will be displayed, look to the right

## `radius()` mixin
The `radius()` mixin sets the `border-radius` value for the specified element. It is used to keep the design language consistent. It takes the values `[m, l, circle]`, `m` by default.

The `radius()` mixin is extended with the following values:

| Value    | Styles               |
| -------- | -------------------- |
| m        | border-radius 4px    |
| l        | border-radius 8px    |
| circle   | border-radius 9999px |

The `circle` value will make your element assume round shape.

> You can also add your own values or alter the existing ones. This can be done in the `styles/helpers.styl` file. How to edit mixins you can read in the official Stylus documentation - [Mixins](https://stylus-lang.com/docs/mixins.html)

## Screen size and device mixins

In pure ***CSS***, you have the ability to use @media-queries for adding styles only to certain user screen sizes. StartupJS has mixins that are already tailored to match the required user screen sizes and even their devices and systems.

Let's take a closer look:

| Mixins       | Environment                  |
| ------------ | ---------------------------- |
| +tablet()    | min-width >=768px            |
| +desktop()   | min-width >=1024px           |
| +wide()      | min-width >=1280px           |
| +portrait()  | Portrait screen orientation  |
| +landscape() | Landscape screen orientation |
| +web()       | Web environment              |
| +android()   | OS Android                   |
| +ios()       | OS iOS                       |
| +native()    | !web                         |

> Among the mixins there is also a mixin +mobile(), which is styled for the mobile screen size (\<=480px), but since we adhere to the mobile-first principle in development, all styles are set by default for the mobile screen resolution.

> In order to override the value of some mixin yourself, you only need to change it in the `styles/` folder of your project. For example, screen sizes for `tablet, desktop, wide` mixins are located in the `variables.styl` file.

Usage example:
```css
.card
  padding 2u
  margin 0 2u
  +tablet()
    padding 3u
    margin 0 3u
  +desktop()
    padding 4u
    margin 0 4u
```

----------------

## `$UI` object

`$UI` is the `startupjs/ui` configuration object. Changing the configuration variables is the most effective way to match interface to your needs.

### Properties of $UI

- `$UI.palette` - contains the main colors for the user interface. All other basic colors are derived from these.
- `$UI.colors` - contains many colors derived from `$UI.palette`. There is one rule for all colors, except for `$UI.palette.black` (this color splits into two: mainText and secondaryText). Each color has the following counterparts (note that `colorName` and `palleteColorName` may not match):
  - colorName: $UI.palette.palleteColorName,
  - colorNameLight: rgba($UI.palette.palleteColorName, 0.5),
  - colorNameLighter: rgba($UI.palette.palleteColorName, 0.25),
  - colorNameLightest: rgba($UI.palette.palleteColorName, 0.05)
- `$UI.shadows` - contains constants for shadows. For numbers from 0 to 4 values are set by default.
- `$UI.media` - contains screen sizes. These sizes are used for screen size defining mixins (for example tablet()). Here the constants for tablet, desktop and wide are contained.

- `$UI.fontFamilies`:
  - `normal` - specifies font names for body text (component `Span`)
  - `heading` - specifies font names for headers text (components `H1-H6`)

- `$UI.fontSizes` - contains font size constants that can be seen in the table above.
- `$UI.lineHeights` - contains row height constants which can be seen in the table above.

### Extending the global $UI component

The global `$UI` object can be extended and its properties can be overridden. This allows you to implement any design solutions in your project. In order to modify `$UI`, you need to use the [merge](https://stylus-lang.com/docs/hashes.html) function. For example, if you need to add a new color `pink`, you can do this as follows:

```js
$UI = merge($UI, {
  colors: {
    pink: #fc69ff,
  }
}, true)

```

or you can override the `primary` and `warning` colors as relevant for your project and add a new size for the `Button` component:

```js
$UI = merge($UI, {
  colors: {
    primary: #4a76a8,
    warning: #880000
  },
  Button: {
    heights: {
      xxl: 10u
    }
  }
}, true)
```

Such transformations of the `$UI` object should be performed in the main style sheet file of the project, which you can find at the path `styles/index.styl`.


### Export styles to javascript code

You can use `:export` command in the style sheet file to export styles to javascript code.

```js
.root
  height: $this.height
  background-color: $this.bgColor

:export
  colors: $UI.colors
  foobar: 42
```

We exported an object with the `colors` and `height` fields. Now import this object in a javascript file.

```js
import STYLES from './index.styl'

const {
  colors,
  foobar
} = STYLES
```

This is a simple way to get any constants from styles in javascript code.
