React.js Google Maps integration component library providing comprehensive Google Maps functionality through React components
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Specialized components for custom overlays, directions, Street View, and advanced Google Maps features that provide enhanced functionality beyond basic mapping.
Component for creating custom overlays that render React elements at specific geographic positions on the map.
/**
* Custom overlay component for rendering React elements on the map
*/
class OverlayView extends Component<OverlayViewProps> {
/** Predefined map pane constants */
static FLOAT_PANE: string;
static MAP_PANE: string;
static MARKER_LAYER: string;
static OVERLAY_LAYER: string;
static OVERLAY_MOUSE_TARGET: string;
/** Returns the map panes for positioning */
getPanes(): google.maps.MapPanes;
/** Returns the map projection for coordinate conversion */
getProjection(): google.maps.MapCanvasProjection;
}
interface OverlayViewProps {
/** Geographic bounds for the overlay (alternative to position) */
bounds?: google.maps.LatLngBounds | google.maps.LatLngBoundsLiteral;
/** React children to render in the overlay */
children?: ReactNode;
/** Function to adjust pixel positioning */
getPixelPositionOffset?: (width: number, height: number) => { x?: number, y?: number };
/** Map pane to render the overlay in */
mapPaneName?: string;
/** Geographic position for the overlay */
position?: google.maps.LatLng | google.maps.LatLngLiteral;
}Usage Example:
import { OverlayView } from "react-google-maps";
const CustomOverlay = ({ position, children }) => (
<OverlayView
position={position}
mapPaneName={OverlayView.OVERLAY_MOUSE_TARGET}
getPixelPositionOffset={(width, height) => ({
x: -(width / 2),
y: -(height / 2),
})}
>
<div style={{
background: "white",
border: "1px solid #ccc",
padding: "10px",
borderRadius: "4px",
boxShadow: "0 2px 4px rgba(0,0,0,0.2)"
}}>
{children}
</div>
</OverlayView>
);
// Usage
<GoogleMap defaultZoom={10} defaultCenter={{ lat: 37.7749, lng: -122.4194 }}>
<CustomOverlay position={{ lat: 37.7749, lng: -122.4194 }}>
<h3>Custom Overlay</h3>
<p>This is a React component rendered on the map!</p>
<button onClick={() => alert("Clicked!")}>Click me</button>
</CustomOverlay>
</GoogleMap>Component for displaying directions and routes on the map with support for waypoints and custom styling.
/**
* Directions renderer component for displaying routes
*/
class DirectionsRenderer extends Component<DirectionsRendererProps> {
/** Returns the current directions result */
getDirections(): google.maps.DirectionsResult;
/** Returns the panel element for text directions */
getPanel(): Node;
/** Returns the current route index */
getRouteIndex(): number;
}
interface DirectionsRendererProps {
// Default props
defaultDirections?: google.maps.DirectionsResult;
defaultOptions?: google.maps.DirectionsRendererOptions;
defaultPanel?: Node;
defaultRouteIndex?: number;
// Controlled props
directions?: google.maps.DirectionsResult;
options?: google.maps.DirectionsRendererOptions;
panel?: Node;
routeIndex?: number;
// Event handlers
onDirectionsChanged?(): void;
}Usage Example:
import { DirectionsRenderer } from "react-google-maps";
const DirectionsMap = () => {
const [directions, setDirections] = useState(null);
const [directionsService] = useState(new google.maps.DirectionsService());
useEffect(() => {
directionsService.route(
{
origin: { lat: 37.7749, lng: -122.4194 }, // San Francisco
destination: { lat: 37.4419, lng: -122.1430 }, // Palo Alto
travelMode: google.maps.TravelMode.DRIVING,
waypoints: [
{ location: { lat: 37.6879, lng: -122.4074 }, stopover: true } // SFO
],
optimizeWaypoints: true
},
(result, status) => {
if (status === google.maps.DirectionsStatus.OK) {
setDirections(result);
}
}
);
}, [directionsService]);
return (
<GoogleMap defaultZoom={10} defaultCenter={{ lat: 37.6, lng: -122.3 }}>
{directions && (
<DirectionsRenderer
directions={directions}
options={{
suppressMarkers: false,
suppressInfoWindows: false,
polylineOptions: {
strokeColor: "#ff0000",
strokeWeight: 4
}
}}
onDirectionsChanged={() => {
console.log("Directions changed");
}}
/>
)}
</GoogleMap>
);
};Component for displaying Google Street View panoramas either as standalone components or integrated with maps.
/**
* Street View panorama component
*/
class StreetViewPanorama extends Component<StreetViewPanoramaProps> {
/** Returns the panorama's navigation links */
getLinks(): google.maps.StreetViewLink[];
/** Returns the panorama's location information */
getLocation(): google.maps.StreetViewLocation;
/** Returns whether motion tracking is enabled */
getMotionTracking(): boolean;
/** Returns the panorama ID */
getPano(): string;
/** Returns the photographer's point of view */
getPhotographerPov(): google.maps.StreetViewPov;
/** Returns the panorama's position */
getPosition(): google.maps.LatLng;
/** Returns the current point of view */
getPov(): google.maps.StreetViewPov;
/** Returns the panorama's status */
getStatus(): google.maps.StreetViewStatus;
/** Returns whether the panorama is visible */
getVisible(): boolean;
/** Returns the current zoom level */
getZoom(): number;
}
interface StreetViewPanoramaProps {
// Default props
defaultLinks?: google.maps.StreetViewLink[];
defaultMotionTracking?: boolean;
defaultOptions?: google.maps.StreetViewPanoramaOptions;
defaultPano?: string;
defaultPosition?: google.maps.LatLng | google.maps.LatLngLiteral;
defaultPov?: google.maps.StreetViewPov;
defaultVisible?: boolean;
defaultZoom?: number;
// Controlled props
links?: google.maps.StreetViewLink[];
motionTracking?: boolean;
options?: google.maps.StreetViewPanoramaOptions;
pano?: string;
position?: google.maps.LatLng | google.maps.LatLngLiteral;
pov?: google.maps.StreetViewPov;
visible?: boolean;
zoom?: number;
// Event handlers
onCloseClick?(e: Event): void;
onPanoChanged?(): void;
onPositionChanged?(): void;
onPovChanged?(): void;
onResize?(): void;
onStatusChanged?(): void;
onVisibleChanged?(): void;
onZoomChanged?(): void;
}Usage Example:
import { StreetViewPanorama } from "react-google-maps";
const StreetViewMap = () => {
const [streetViewVisible, setStreetViewVisible] = useState(false);
return (
<div style={{ display: "flex", height: "400px" }}>
<GoogleMap
defaultZoom={14}
defaultCenter={{ lat: 37.7749, lng: -122.4194 }}
style={{ flex: 1 }}
>
<Marker
position={{ lat: 37.7749, lng: -122.4194 }}
onClick={() => setStreetViewVisible(true)}
/>
</GoogleMap>
{streetViewVisible && (
<StreetViewPanorama
position={{ lat: 37.7749, lng: -122.4194 }}
pov={{ heading: 34, pitch: 10 }}
zoom={1}
options={{
position: { lat: 37.7749, lng: -122.4194 },
pov: { heading: 34, pitch: 10 },
zoom: 1,
visible: true
}}
onCloseClick={() => setStreetViewVisible(false)}
onPovChanged={() => {
console.log("Street View POV changed");
}}
style={{ flex: 1 }}
/>
)}
</div>
);
};Create interactive overlays that respond to map events:
const InteractiveOverlay = ({ position, onMove }) => {
const [isDragging, setIsDragging] = useState(false);
return (
<OverlayView
position={position}
mapPaneName={OverlayView.OVERLAY_MOUSE_TARGET}
>
<div
style={{
background: isDragging ? "#ff0000" : "#0000ff",
color: "white",
padding: "8px",
borderRadius: "4px",
cursor: "move",
userSelect: "none"
}}
onMouseDown={() => setIsDragging(true)}
onMouseUp={() => setIsDragging(false)}
onClick={(e) => {
e.stopPropagation();
if (onMove) {
// Calculate new position based on mouse event
onMove(/* new position */);
}
}}
>
Draggable Overlay
</div>
</OverlayView>
);
};Display and switch between multiple route options:
const MultiRouteDirections = () => {
const [directions, setDirections] = useState([]);
const [selectedRoute, setSelectedRoute] = useState(0);
// Calculate multiple routes with different options
useEffect(() => {
const directionsService = new google.maps.DirectionsService();
const routeOptions = [
{ travelMode: google.maps.TravelMode.DRIVING, avoidHighways: false },
{ travelMode: google.maps.TravelMode.DRIVING, avoidHighways: true },
{ travelMode: google.maps.TravelMode.TRANSIT }
];
Promise.all(
routeOptions.map(options =>
new Promise(resolve => {
directionsService.route({
origin: origin,
destination: destination,
...options
}, resolve);
})
)
).then(setDirections);
}, []);
return (
<GoogleMap defaultZoom={10} defaultCenter={center}>
{directions[selectedRoute] && (
<DirectionsRenderer
directions={directions[selectedRoute]}
routeIndex={0}
options={{
polylineOptions: {
strokeColor: selectedRoute === 0 ? "#0000ff" :
selectedRoute === 1 ? "#ff0000" : "#00ff00"
}
}}
/>
)}
<div style={{ position: "absolute", top: "10px", left: "10px" }}>
{directions.map((_, index) => (
<button
key={index}
onClick={() => setSelectedRoute(index)}
style={{
backgroundColor: selectedRoute === index ? "#0066cc" : "#ccc"
}}
>
Route {index + 1}
</button>
))}
</div>
</GoogleMap>
);
};Synchronize Street View with map marker positions:
const SynchronizedStreetView = () => {
const [markerPosition, setMarkerPosition] = useState({ lat: 37.7749, lng: -122.4194 });
const [streetViewPov, setStreetViewPov] = useState({ heading: 34, pitch: 10 });
return (
<div style={{ display: "flex", height: "500px" }}>
<GoogleMap
defaultZoom={14}
center={markerPosition}
style={{ flex: 1 }}
>
<Marker
position={markerPosition}
draggable={true}
onDragEnd={(event) => {
const newPos = {
lat: event.latLng.lat(),
lng: event.latLng.lng()
};
setMarkerPosition(newPos);
}}
/>
</GoogleMap>
<StreetViewPanorama
position={markerPosition}
pov={streetViewPov}
zoom={1}
onPovChanged={() => {
// Update POV state when user changes view
}}
style={{ flex: 1 }}
/>
</div>
);
};Install with Tessl CLI
npx tessl i tessl/npm-react-google-maps