# @siteone/react-img-microservice

React komponenta pro [obrázkovou mikroslužbu](https://git.siteone.cz/frontend/img). Zjednodušeně řečeno, můžete react-image použít jako náhradu klasického <img />, jen už nemusíte řešit optimalizaci obrázků.

## Obsah

- [Požadavky](#pozadavky)
- [Funkce](#funkce)
- [API](#api)
- [Používání](#pouzivani)
- [Konvence](#konvence)
- [Externí součásti](#externi-soucasti)
- [Správa a rozvoj projektu](#sprava-a-rozvoj-projektu)
- [Přispívání](#prispivani)
- [Licence](#licence)

## Požadavky

- React 16.x.x

## Funkce

- Formát - **automatická detekce podpory webp v prohlížeči**
  - řeší se pouze jednou na úrovni provideru, mikroslužba vždy vrátí webp formát pokud jej prohlížeč podporuje, jinak vrátí původní formát
  - pro SSR by se tato funkcionalita mela vypnout pres `disableWebpSupportCheck`, uzivatel jinak bude stahovat dva obrazky. Ideálně používat siteone CDN, která řeší webp za nás.
- Retina a responsivní obrázky (srcSet)
  - Image componenta si defaultně říká i o retina obrázky. Pokud zadáme width jako pole velikostí, místo retiny se nám srcSet nastaví jako responsivní obrázek
- Změna velikosti
  - můžeme si říct pomocí parametrů _width_ a _height_ jakou přesně velikost obrázku chceme vrátit
  - a za pomoci parametru _scaleMode_ můžeme nastavit jakym způsobem chceme, aby se obrázek oříznul
- Progresivní obrázek (Progressive)

  - [wiki](https://en.wikipedia.org/wiki/Progressive_Graphics_File)
  - v podstatě u většiny prohlížečů už je toto pro nás nepoužitelné, protože webp tuto funkci nepodporuje (je dost rychly i bez toho)

- Rotace (Rotate)

  - násobky 90°

- Převrácení stran (Flip)

  - převrátí buď x nebo y osu

- Rozmazání (Blur)

  - 0.3 - 1000

- Kvalita (Quality)

  - 0 - 100%

- Možnosti, které nám microslužba nabízí, ale ještě je nemáme zapracované:

  - Výřez
  - Overlay image (watermark)

## Používání

### Instalace

    ```bash
    yarn add @siteone/react-img-microservice
    ```

### ImageProvider

Nejprve musíme nadefinovat, kterou microslužbu budeme chtít používat. Budeme mít jednu obecnou **img.siteone.cz**, která bude určená pro testing a malé projekty (např. web S1). Velké projekty budou mít vlastní mikroslužbu na své doméně.

Někde na nejvyšší úrovni aplikace:

```js
import { ImageProvider } from '@siteone/react-img-microservice'

const App = () => (
  <ImageProvider microserviceUrl="https://img.siteone.cz" baseImgComponent="img" baseImgBoxComponent="div">
    // ... layout, children, w/e
  </ImageProvider>
)
```

Pak už můžeme kdekoliv v projektu využívat komponenty Image a ImageBox

```js
import { Image, ImageBox } from '@siteone/react-img-microservice'

const Foo = () => (
  <div>
    <Image src="/assets/image/bar.png" width={600} height={400} alt="foo bar" />
    <ImageBox src="/assets/image/bar.png" width={600} height={400} className="foobar" />
  </div>
)
```

## API

### ImageProvider

Jak název napovídá, ImageProvider je komponenta, která nastavuje context pro všechny obrázky v aplikaci. Nedělá ale jen to, ale i zjišťuje zdali náš prohlížeč podporuje úžasný webp formát a říká komponentám jaký formát obrázku pro výstup má použít.

#### Jaké props komponenta přijámá

**microserviceUrl** : string [required]

url mikroslužby

- každý velký projekt bude mít vlastní službu, abychom rozmělnili náročnost na server a potenciální útoky a abychom měli jistotu, že nám pád jedné služby nerozbije všechny projekty

```js
<ImageProvider microserviceUrl="https://img.siteone.cz" />
```

---
**disableWebpSupportCheck**: boolean [optional]

Provider přestane v prohlížeči kontrolovat zda podporuje webp. Mělo by se používat při SSR, nebo když používáme s1 CDN.

**baseImgComponent** : React.Node | string [optional] (default: `"img"`)

Možnost nastavit celé aplikaci komponentu, která se bude renderovat při použití `<Image />`

- defaultně používáme klasický img tag pro zpětnou kompatibilitu se staršími projekty
- na nových projektech budeme chtít použít proxy komponentu `<Element is="img" />`, abychom mohli `Image` komponentu skinovat stejně jako ostatní komponenty DS
- na AirBank například použijeme proxy komponentu `<Box tag="img" />` z _frack-components_

```js
// AB
const ImgComponent = () => <Box tag="img" />

// DS
const ImgComponent = () => <Element is="img" />

<ImageProvider baseImgComponent={ImgComponent} />
```

---

**baseImgBoxComponent** : React.Node | string [optional] (default: `"div"`)

Stejně jako _baseImgComponent_, máme možnost nadefinovat komponentu, která se bude renderovat při použití `<ImageBox />` komponenty

```js
// AB
import { Box } from 'frack-components'

// DS
const Box = () => <Element is="div" />

<ImageProvider baseImgBoxComponent={Box} />
```

### Image a ImageBox

Kompmonenty, které budeme nejvíce používat. Jsou context consumers a obě přijímají až na pár vyjímek stejné props, které definuji níže.

`<Image />` komponenta je přímá náhrada html tagu `<img />`. Mimo běžných attributů, který běžný `<img />` očekává, přijímá komponenta další, které předá mikroslužbě pro práci s obrázkem.

`<ImageBox />` použijeme, když chceme použít optimalizovaný obrázek jako css pozadí jakékoliv komponenty. Defaultní render komponentu nastavíme v provideru, ale přes attribut _tag_ ji můžeme lokálně přetížit. Render komponenta musí splňovat jedinou podmínku, musí umět přijmout style attribut, kde dostane _background-image_.

#### Jaké props komponenty přijímají

**tag** : React.Node | string [optional] (default: nastavení v provideru)

Možnost lokálně přepsat render komponentu.

**src** : string [required]

Cesta k obrázku

**width** : number | number[] [optional]

**height** : number | number[] [optional]

**rotate** : 0 | 90 | 180 | 270 [optional]

**quality** : number [optional]

v procentech, tedy 0-100

**blur** : number [optional]

0.3 - 1000

**progressive** : boolean [optional]

pro nás už není tolik podstatné, protože webp tuto funkcionalitu nemá, ale pokud u jpegu chceme upřednostnit rychlost načtení před kvalitou.

**scaleMode** :
| 'fit'
| 'downfit'
| 'upfit'
| 'fill'
| 'fillAuto'
| 'fillCenter'
| 'fillNorth'
| 'fillNortheast'
| 'fillNorthwest'
| 'fillEast'
| 'fillWest'
| 'fillSouth'
| 'fillSoutheast'
| 'fillSouthwest' [optional](default: 'fillAuto')

**flip** : 'x' | 'y' [optional]

<!-- ## Konvence -->

## Externí součásti

- https://git.siteone.cz/frontend/img

## Správa a rozvoj projektu

[Tomáš Sláma](mailto:tomas.slama@siteone.cz)

<!-- ## Přispívání

PRs accepted. -->

## Licence

MIT © 2018 SiteOne, s.r.o
