npm package: @mappingfactory/sdk-react
Description: React SDK for Michelin's Navigation and Mapping Services.
Author: Michelin
Latest version: 1.0.1

# @mappingfactory/sdk-react

This library provides a set of React hooks for working with the `@mappingfactory/sdk-js`.
The hooks are designed to be easy to use and provide a simple interface for common tasks such as searching for locations, getting directions, displaying and interacting with a map, and displaying a roadsheet.

### Installation

You can install the library using your preferred package manager:

```bash
npm install @mappingfactory/sdk-react
```

```bash
yarn add @mappingfactory/sdk-react
```

### Usage

To use the hooks, you first need to wrap your application in a `MichelinProvider` component.
Once you've wrapped your app in the `MichelinProvider`, you can use any of the provided hooks.

##### Example usage

```javascript
import { MichelinProvider } from '@mappingfactory/sdk-react';

function App() {
	return (
		<MichelinProvider apiKey="YOUR_API_KEY">
			// ... rest of your app
		</MichelinProvider>
	);
}
```

The `MichelinProvider` component accepts the following props:

-   `apiKey` : Your Michelin API key.
-   `locale` : The locale to use for the SDK. Defaults to `en-US`.
-   `uri` : The URI to use for the SDK. Defaults to `https://api.michelin.com`.

> For more information on the `MichelinProvider` component, please refer to the `MichelinSDKClient` inside the `@mappingfactory/sdk-js` library.

### API

### Components

#### MichelinMap

The `MichelinMap` component is a part of `@mappingfactory/sdk-react` that simplifies the process of adding and interacting with a `MapLibre` map in your React application. This component utilizes the `useMapLibre` hook under the hood to manage map-related functionalities.

##### Features

-   Easy integration of MapLibre maps.
-   Customizable map options.
-   Callback function (`onMapInit`) for further map customization after initialization.

##### Props

`options`: A set of options to configure the `MapLibre` instance (excluding the `container` property, which is handled by the component).
`onMapInit`: An optional callback that is invoked with the map instance after the map is initialized and style is loaded. This can be useful for adding layers, sources or even with the `useDirection` hook to add a route to the map.

##### Example Usage

To use the `MichelinMap` component, first ensure your application is wrapped in the `MichelinProvider`.

```tsx
import { MichelinProvider, MichelinMap } from '@mappingfactory/sdk-react';
import type { MapOptions } from 'maplibre-gl';

function App() {
	const mapOptions: Omit<MapOptions, 'container'> = {
		// Define your map options here
		style: 'https://demotiles.maplibre.org/style.json', // Example style URL
		center: [2.3488, 48.8534], // Example center coordinates
		zoom: 4, // Example zoom level
	};

	return (
		<MichelinProvider apiKey="YOUR_API_KEY">
			<MichelinMap
				options={mapOptions}
				onMapInit={(map) => console.log('Map is ready:', map)}
			/>
		</MichelinProvider>
	);
}
```

#### MichelinAutocomplete

The `MichelinAutocomplete` component is a part of `@mappingfactory/sdk-react` designed to provide an easy-to-use interface for implementing autocomplete functionality in your React applications. This component utilizes the `useSearch` hook to manage autocomplete functionalities related to location and address search.

##### Features

-   Autocomplete functionality for searching locations and addresses.
-   Customizable options for search behavior and appearance.
-   Callbacks for various autocomplete events like selection, opening, closing, searching, and more.

##### Props

-   `options`: Custom options to configure the autocomplete behavior and appearance.
-   `onSelect`: Callback fired when an item is selected from the autocomplete suggestions.
-   `onDropdownOpen`: Callback fired when the dropdown opens.
-   `onDropDownClose`: Callback fired when the dropdown closes.
-   `onSearch`: Callback fired when a search is initiated.
-   `onNoResults`: Callback fired when no results are found.
-   `onError`: Callback fired when there is an error in searching.
-   `onSuccess`: Callback fired when a search is successful.
-   `onClear`: Callback fired when the autocomplete input is cleared.
-   `onInit`: Callback fired when the autocomplete manager is initialized.

##### Example Usage

Wrap your application with the `MichelinProvider` and then use the `MichelinAutocomplete` component where needed.

```tsx
import {
	MichelinProvider,
	MichelinAutocomplete,
} from '@mappingfactory/sdk-react';

function App() {
	return (
		<MichelinProvider apiKey="YOUR_API_KEY">
			<div>
				<MichelinAutocomplete
					onSelect={(value) => {
						console.log('Selected value:', value);
					}}
					onInit={(manager) => {
						console.log('Autocomplete initialized:', manager);
					}}
					// Other event callbacks and options here
				/>
			</div>
		</MichelinProvider>
	);
}
```

In this example, the `MichelinAutocomplete` component is used within the `MichelinProvider`. You can customize it by passing different options and handling various events according to your application's needs.

Remember to replace `"YOUR_API_KEY"` with your actual Michelin API key.

### Hooks

#### `useDirection`

Return an object containing a `DirectionWrapper` instance and an error property.
The `DirectionWrapper` provides methods for getting directions between two or more locations.

##### Example usage

> In this example, we use the `useDirection` hook to get directions between two locations.

```javascript
import { useDirection } from '@mappingfactory/sdk-react';

const DEFAULT_OPTIONS = {
	coordinates: [
		{ latitude: 48.8566, longitude: 2.3522 }, // Paris, France
		{ latitude: 51.5074, longitude: -0.1278 }, // London, UK
	],
	mode: 'fastest',
	language: 'en',
};

const Page = () => {
	const { direction, error } = useDirection(DEFAULT_OPTIONS);

	const getDirections = async () => {
		const results = await direction.client.search();
		console.log(results);
	};

	if (error) {
		return <div>Something went wrong</div>;
	}

	return (
		<div>
			<button onClick={getDirections}>Get directions</button>
		</div>
	);
};
```

#### `useMapLibre`

Return an object containing a `MapLibreWrapper` instance and an error property.
The `MapLibreWrapper` provides a `client` property that is a reference to the `maplibre-gl` class.

##### Example usage

> In this example, we use the `useMapLibre` hook to create a map and display it in a React component.

```javascript
import { useRef, useEffect } from 'react';
import { useMapLibre } from '@mappingfactory/sdk-react';

const Page = () => {
	const { mapLibre, error } = useMapLibre();

	const mapContainerRef = useRef(null);
	const mapRef = useRef(null);

	/**
	 * Create a map and add it to the DOM when the component mounts.
	 */
	useEffect(() => {
		if (!mapLibre) return;

		const Map = mapLibre._client.Map;

		mapRef.current = new Map({
			container: mapContainerRef.current,
			style: 'https://demotiles.maplibre.org/style.json',
			center: [2.3488, 48.8534],
			zoom: 4,
		});
	}, []);

	return <div ref={mapContainerRef} />;
};
```

#### `useRoadsheet`

Return an object containing a `RoadSheetWrapper` instance and an error property.
The `RoadSheetWrapper` provides methods for getting a complete roadsheet HTML for a route.

##### Example usage

> In this example, we use the `useRoadsheet` hook to get a roadsheet for a route using the `useDirection` hook.

```javascript
import { useRef, useEffect, useState } from 'react';
import { useRoadsheet, useDirection } from '@mappingfactory/sdk-react';

const DEFAULT_OPTIONS = {
	coordinates: [
		{ latitude: 48.8566, longitude: 2.3522 }, // Paris, France
		{ latitude: 51.5074, longitude: -0.1278 }, // London, UK
	],
};

const Page = () => {
	const { direction } = useDirection(DEFAULT_OPTIONS);
	const { roadsheet } = useRoadsheet();

	const [html, setHTML] = useState(null);

	useEffect(() => {
		if (!direction || !roadsheet) return;

		const getRoadsheet = async () => {
			const results = await direction.client.search();
			const route = results.routes[0];
			const waypoints = results.waypoints;

			const htmlRoadsheet = await roadsheet.client.getHtml(
				route,
				waypoints,
			);

			setHTML(htmlRoadsheet);
		};

		getRoadsheet();
	}, [direction, roadsheet]);

	return <div dangerouslySetInnerHTML={{ __html: html }} />;
};
```

#### `useSearch`

Return an object containing a `Search` instance and an error property.
The `Search` instance provides methods for building autocomplete or geocoding search inputs.

##### Example usage

> In this example, we use the `useSearch` hook to construct an autocomplete.

```javascript
import { useRef, useEffect } from 'react';
import { useSearch } from '@mappingfactory/sdk-react';

const Page = () => {
	const { search } = useSearch();

	const autocompleteRef = useRef(null);

	useEffect(() => {
		if (!search) return;

		const initAutocomplete = async () => {
			const autocompleteManager = await search.autocomplete(
				autocompleteRef.current,
			);

			autocompleteManager._on('selected', (value) => {
				console.log('Autocomplete selected value: ', value);
			});
		};

		initAutocomplete();
	}, [search]);

	return (
		<div>
			<span>Check the console for more details.</span>
			<div id="autocomplete" ref={autocompleteRef} />
		</div>
	);
};
```

#### `useMichelinContext`

Return an object containing the main SDK context and some functions to set the different wrappers.
This hook is useful if you need to access the SDK context directly.

##### Example usage

> In this example, we use the `useMichelinContext` hook to access some options

```javascript
import { useRef, useEffect } from 'react';
import { useMichelinContext } from '@mappingfactory/sdk-react';

const Page = () => {
	const { sdk } = useMichelinContext();

	useEffect(() => {
		if (!sdk) return;

		const options = sdk.getOptions();
		console.log(options);
	}, [sdk]);

	return <div>Check the console.</div>;
};
```