React Package API
The @route-optimization/react package provides React hooks and components for route visualization.
Installation
bash
npm install @route-optimization/react @route-optimization/corePeer Dependencies:
react^18.0.0react-dom^18.0.0
Components
RouteMapView
Main component for displaying routes on a map.
tsx
import { RouteMapView } from '@route-optimization/react';
<RouteMapView apiKey="YOUR_API_KEY" route={route} autoFitBounds />;Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
apiKey | string | Yes | - | Google Maps API key |
route | Route | null | No | null | Route to display |
center | LatLng | No | Bangkok | Initial map center |
zoom | number | No | 12 | Initial zoom level |
height | string | No | '600px' | Map container height |
width | string | No | '100%' | Map container width |
autoFitBounds | boolean | No | false | Auto-fit to route bounds |
onMapReady | (map: google.maps.Map) => void | No | - | Map ready callback |
onRouteRendered | (route: Route) => void | No | - | Route rendered callback |
onError | (error: Error) => void | No | - | Error callback |
renderOptions | RouteRenderOptions | No | - | Route styling options |
Example
tsx
import { RouteMapView } from '@route-optimization/react';
import { useState } from 'react';
function App() {
const [route, setRoute] = useState<Route>({
id: 'route-1',
vehicleId: 'vehicle-1',
stops: [
{
id: 'start',
location: { lat: 13.7563, lng: 100.5018 },
type: 'START',
sequence: 0,
},
{
id: 'delivery',
location: { lat: 13.7467, lng: 100.5342 },
type: 'DELIVERY',
label: 'Customer #1',
sequence: 1,
},
],
});
return (
<RouteMapView
apiKey={process.env.REACT_APP_GOOGLE_MAPS_API_KEY!}
route={route}
autoFitBounds
height="600px"
onMapReady={(map) => console.log('Map ready', map)}
onError={(error) => console.error('Map error', error)}
renderOptions={{
color: '#4CAF50',
polyline: {
strokeWeight: 5,
},
}}
/>
);
}MapControls
Map control buttons for zoom and navigation.
tsx
import { MapControls } from '@route-optimization/react';
<MapControls onZoomIn={() => {}} onZoomOut={() => {}} onReset={() => {}} />;Props
| Prop | Type | Required | Description |
|---|---|---|---|
onZoomIn | () => void | No | Zoom in handler |
onZoomOut | () => void | No | Zoom out handler |
onReset | () => void | No | Reset view handler |
className | string | No | Custom CSS class |
Hooks
useRouteMap
Hook for managing a route map instance.
tsx
const { mapInstance, isLoading, error, renderRoute, clearRoute, fitBounds } = useRouteMap(config);Parameters
typescript
interface UseRouteMapConfig {
apiKey: string;
mapContainer: HTMLElement | null;
center?: LatLng;
zoom?: number;
onMapReady?: (map: google.maps.Map) => void;
onError?: (error: Error) => void;
}Returns
typescript
{
mapInstance: google.maps.Map | null;
isLoading: boolean;
error: Error | null;
renderRoute: (route: Route, options?: RouteRenderOptions) => void;
clearRoute: () => void;
fitBounds: () => void;
}Example
tsx
import { useRouteMap } from '@route-optimization/react';
import { useRef, useEffect } from 'react';
function MapComponent() {
const mapRef = useRef<HTMLDivElement>(null);
const { mapInstance, isLoading, error, renderRoute, clearRoute } = useRouteMap({
apiKey: process.env.REACT_APP_GOOGLE_MAPS_API_KEY!,
mapContainer: mapRef.current,
center: { lat: 13.7563, lng: 100.5018 },
zoom: 12,
});
useEffect(() => {
if (mapInstance && route) {
renderRoute(route);
}
}, [mapInstance, route]);
if (isLoading) return <div>Loading map...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<div ref={mapRef} style={{ width: '100%', height: '600px' }} />
<button onClick={clearRoute}>Clear Route</button>
</div>
);
}useMapControls
Hook for map control functionality.
tsx
const { zoom, canZoomIn, canZoomOut, zoomIn, zoomOut, setZoom, resetZoom } = useMapControls(
mapInstance,
options
);Parameters
typescript
interface UseMapControlsOptions {
initialZoom?: number;
minZoom?: number;
maxZoom?: number;
onZoomChange?: (zoom: number) => void;
}Returns
typescript
{
zoom: number;
canZoomIn: boolean;
canZoomOut: boolean;
zoomIn: () => void;
zoomOut: () => void;
setZoom: (zoom: number) => void;
resetZoom: () => void;
}Example
tsx
import { useMapControls } from '@route-optimization/react';
function Controls({ mapInstance }: { mapInstance: google.maps.Map | null }) {
const { zoom, canZoomIn, canZoomOut, zoomIn, zoomOut, resetZoom } = useMapControls(mapInstance, {
initialZoom: 12,
minZoom: 5,
maxZoom: 20,
onZoomChange: (zoom) => console.log('Zoom:', zoom),
});
return (
<div>
<button onClick={zoomIn} disabled={!canZoomIn}>
+
</button>
<span>Zoom: {zoom}</span>
<button onClick={zoomOut} disabled={!canZoomOut}>
-
</button>
<button onClick={resetZoom}>Reset</button>
</div>
);
}Context API
MapProvider
Provides map context to child components.
tsx
import { MapProvider } from '@route-optimization/react';
<MapProvider apiKey="YOUR_API_KEY">
<YourComponents />
</MapProvider>;useMapContext
Access map context from child components.
tsx
import { useMapContext } from '@route-optimization/react';
function ChildComponent() {
const { mapInstance, renderRoute } = useMapContext();
// Use map instance and methods
}Advanced Examples
Multiple Routes
tsx
function MultiRouteMap() {
const [routes, setRoutes] = useState<Route[]>([]);
const mapRef = useRef<HTMLDivElement>(null);
const { mapInstance, renderRoute } = useRouteMap({
apiKey: process.env.REACT_APP_GOOGLE_MAPS_API_KEY!,
mapContainer: mapRef.current,
});
useEffect(() => {
routes.forEach((route, index) => {
renderRoute(route, {
color: colors[index],
});
});
}, [routes, mapInstance]);
return <div ref={mapRef} style={{ width: '100%', height: '600px' }} />;
}Dynamic Route Updates
tsx
function DynamicRouteMap() {
const [route, setRoute] = useState<Route | null>(null);
return (
<RouteMapView
apiKey={process.env.REACT_APP_GOOGLE_MAPS_API_KEY!}
route={route}
autoFitBounds
onMapReady={(map) => {
// Map is ready
}}
onRouteRendered={(route) => {
console.log('Route rendered:', route);
}}
/>
);
}Custom Loading State
tsx
function CustomLoadingMap() {
const mapRef = useRef<HTMLDivElement>(null);
const { mapInstance, isLoading, error } = useRouteMap({
apiKey: process.env.REACT_APP_GOOGLE_MAPS_API_KEY!,
mapContainer: mapRef.current,
});
return (
<div style={{ position: 'relative', width: '100%', height: '600px' }}>
<div ref={mapRef} style={{ width: '100%', height: '100%' }} />
{isLoading && (
<div
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
background: 'rgba(255,255,255,0.9)',
}}
>
<div>Loading map...</div>
</div>
)}
{error && <div>Error: {error.message}</div>}
</div>
);
}TypeScript
All components and hooks are fully typed:
tsx
import type { Route, RouteRenderOptions } from '@route-optimization/core';
import type { RouteMapViewProps } from '@route-optimization/react';
const props: RouteMapViewProps = {
apiKey: 'YOUR_API_KEY',
route: myRoute,
autoFitBounds: true,
};