npm package: @siteone/react-maps
Description: This is the Frontend client for our maps solution. It is based on leaflet and react-leaflet.
Author: SiteOne: Adam Bisek
Latest version: 2.1.15

# React maps (for Maps One)
This is the Frontend client for our maps solution.
It is based on leaflet and react-leaflet.

Goal is to provide drop-in solution for our Maps Backend.
You'll also spare time, because React-leaflet and leaflet have part of undocumented API (eg. tile subdomains).
If you need to be more flexible, than this library offers,
please use directly react-leaflet (and feel free to inspire this library).

## Installation

Install this package and all peer dependencies.
```sh
npx install-peerdeps @siteone/react-maps
```
OR
```sh
yarn add @siteone/react-maps leaflet@^1.4.0 leaflet.markercluster@^1.4.1 react-leaflet@^2.2.1
```

Add required styles for leaflet (these will be served from our servers):
```javascript
  <link
    rel="stylesheet"
    href="//cdnjs.cloudflare.com/ajax/libs/leaflet/1.4.0/leaflet.css"
  />
  <link
    rel="stylesheet"
    href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.4.1/MarkerCluster.css"
  />
  <link
    rel="stylesheet"
    href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.4.1/MarkerCluster.Default.css"
  />
  <style dangerouslySetInnerHTML={{__html: `
    .leaflet-container {
      height: 600px;
      width: 80%;
      margin: 0 auto;
    }
  `}} />
```

## Usage
```javascript
import { BasicMap, createIcon } from '@siteone/react-maps'

const markers = Array.from({ length: 1000 }, (v, i) => ({
  position: { lat: 49.210 - (Math.random()*0.4), lng: ((Math.random() > .5 ? 16.5 : 17) - (Math.random()*0.4)) },
  popup: (<span>ahoj</span>),
  icon: createIcon({
    iconUrl: 'https://www.homecredit.cz/logo.svg',
    iconRetinaUrl: 'https://www.homecredit.cz/logo.svg',
    iconAnchor: [5, 55],
    popupAnchor: [25, -55],
    iconSize: [60, 60],
    shadowUrl: './assets/marker-shadow.png',
    shadowSize: [68, 95],
    shadowAnchor: [20, 92],
  })
}))

<BasicMap
  tileUrl="https://{s}-mapsone-tiles-01.siteone.cz/default/{z}/{x}/{y}.png"
  tileSubdomains={['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8']}
  position={{ lat: 49.210, lng: 16.618 }}
  markers={markers}
/>
```

Please see [Examples](/examples)

See API below for whole API reference.

## API
This library exports:

#### Map
Plain map - thin wrapper above `react-leaflet` `Map` component. All props are forwarded.
Its main benefit is providing painless SSR support.
For further API information see [Documentation](https://react-leaflet.js.org/docs/en/components.html#map).

#### BasicMap
- position: `object { lat: number, lng: number }` - coordinates of initial position
- defaultZoom: `int` - initial zoom
- tileUrl: `string` - if you your own map source, in S1 for example "https://{s}-mapsone-tiles-01.siteone.cz/default/{z}/{x}/{y}.png"
- tileSubdomains: `array` - eg. ['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8']
- markers: `array` - see [Examples](/examples) for understanding marker structure
- onMarkerClickMode `string` - what should happen on marker click: "zoom" for zooming, "bounds" for fit to bounds functionality
- onMarkerClickZoom `int` - what in target zoom on click (1 to 17)
- onMarkerClickGetBounds `Function`  -see [Examples](/examples) for understanding

#### createIcon
Icon for marker (see example above).

For full reference see https://leafletjs.com/reference-1.4.0.html#icon

```javascript
const customIcon = createIcon({
  iconUrl: require('./assets/icon-pin-branch.png'),
  iconRetinaUrl: require('./assets/icon-pin-branch.png'),
  iconAnchor: [5, 55],
  popupAnchor: [25, -55],
  iconSize: [60, 60],
  shadowUrl: './assets/marker-shadow.png',
  shadowSize: [68, 95],
  shadowAnchor: [20, 92],
})
```

#### MarkerClusterGroup (TEMPORARILY NOT EXPORTED)
Because react-leaflet doesn't support clustering (but leaflet itself do)
I am exporting this component for usage directly in react-leaflet.
If you use ```BasicMap``` component, you DON'T have to use it (clustering is automatical).

Example:
```javascript
  <MarkerClusterGroup>
    {markers.map(marker => (
      <Marker
        key={JSON.stringify(marker.position)}
        position={marker.position}
        icon={marker.icon}
        onClick={() => this.onMarkerClick(marker)}
      />
    ))}
  </MarkerClusterGroup>
```