CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-google-maps--api

React.js Google Maps API integration with components and hooks for seamless Google Maps functionality

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

core-map.mddocs/

Core Map Component

The main GoogleMap component that renders the interactive map container and manages the Google Maps instance, along with the useGoogleMap hook for accessing the map instance from child components.

Capabilities

GoogleMap Component

The primary component for rendering Google Maps with comprehensive configuration options and event handling.

/**
 * Main map container component that renders the Google Map
 * All other map components must be rendered as children of GoogleMap
 */
interface GoogleMapProps {
  children?: React.ReactNode;
  id?: string;
  mapContainerStyle?: React.CSSProperties;
  mapContainerClassName?: string;
  options?: google.maps.MapOptions;
  extraMapTypes?: google.maps.MapType[];
  
  // Map configuration
  center?: google.maps.LatLng | google.maps.LatLngLiteral;
  clickableIcons?: boolean;
  heading?: number;
  mapTypeId?: string;
  streetView?: google.maps.StreetViewPanorama;
  tilt?: number;
  zoom?: number;
  
  // Mouse events
  onClick?: (e: google.maps.MapMouseEvent) => void;
  onDblClick?: (e: google.maps.MapMouseEvent) => void;
  onDrag?: () => void;
  onDragEnd?: () => void;
  onDragStart?: () => void;
  onMouseMove?: (e: google.maps.MapMouseEvent) => void;
  onMouseOut?: (e: google.maps.MapMouseEvent) => void;
  onMouseOver?: (e: google.maps.MapMouseEvent) => void;
  onMouseDown?: (e: google.maps.MapMouseEvent) => void;
  onMouseUp?: (e: google.maps.MapMouseEvent) => void;
  onRightClick?: (e: google.maps.MapMouseEvent) => void;
  
  // Map state change events
  onMapTypeIdChanged?: () => void;
  onTilesLoaded?: () => void;
  onBoundsChanged?: () => void;
  onCenterChanged?: () => void;
  onHeadingChanged?: () => void;
  onIdle?: () => void;
  onProjectionChanged?: () => void;
  onResize?: () => void;
  onTiltChanged?: () => void;
  onZoomChanged?: () => void;
  
  // Lifecycle events
  onLoad?: (map: google.maps.Map) => void | Promise<void>;
  onUnmount?: (map: google.maps.Map) => void | Promise<void>;
}

function GoogleMap(props: GoogleMapProps): JSX.Element;

Usage Examples:

import React, { useCallback, useState } from 'react';
import { GoogleMap, LoadScript } from '@react-google-maps/api';

const mapContainerStyle = {
  width: '100%',
  height: '400px'
};

const center = {
  lat: 40.7128,
  lng: -74.0060
};

// Basic map
function BasicMap() {
  return (
    <LoadScript googleMapsApiKey="YOUR_API_KEY">
      <GoogleMap
        mapContainerStyle={mapContainerStyle}
        center={center}
        zoom={10}
      />
    </LoadScript>
  );
}

// Interactive map with events
function InteractiveMap() {
  const [mapCenter, setMapCenter] = useState(center);
  const [mapZoom, setMapZoom] = useState(10);
  
  const onLoad = useCallback((map: google.maps.Map) => {
    console.log('Map loaded:', map);
  }, []);
  
  const onClick = useCallback((e: google.maps.MapMouseEvent) => {
    if (e.latLng) {
      console.log('Clicked at:', e.latLng.toJSON());
      setMapCenter(e.latLng.toJSON());
    }
  }, []);
  
  const onCenterChanged = useCallback(() => {
    console.log('Map center changed');
  }, []);
  
  return (
    <LoadScript googleMapsApiKey="YOUR_API_KEY">
      <GoogleMap
        mapContainerStyle={mapContainerStyle}
        center={mapCenter}
        zoom={mapZoom}
        options={{
          disableDefaultUI: false,
          clickableIcons: true,
          scrollwheel: true,
        }}
        onClick={onClick}
        onLoad={onLoad}
        onCenterChanged={onCenterChanged}
        onZoomChanged={() => console.log('Zoom changed')}
      />
    </LoadScript>
  );
}

// Map with custom styling and options
function StyledMap() {
  const mapOptions: google.maps.MapOptions = {
    disableDefaultUI: true,
    clickableIcons: false,
    scrollwheel: false,
    disableDoubleClickZoom: true,
    mapTypeControl: true,
    mapTypeControlOptions: {
      style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
      position: google.maps.ControlPosition.TOP_CENTER,
    },
    zoomControl: true,
    zoomControlOptions: {
      position: google.maps.ControlPosition.RIGHT_CENTER,
    },
    scaleControl: true,
    streetViewControl: true,
    streetViewControlOptions: {
      position: google.maps.ControlPosition.LEFT_TOP,
    },
    fullscreenControl: false,
    styles: [
      {
        featureType: "all",
        elementType: "geometry",
        stylers: [{ color: "#242f3e" }]
      },
      {
        featureType: "all",
        elementType: "labels.text.stroke",
        stylers: [{ color: "#242f3e" }]
      },
      {
        featureType: "all",
        elementType: "labels.text.fill",
        stylers: [{ color: "#746855" }]
      }
    ]
  };
  
  return (
    <LoadScript googleMapsApiKey="YOUR_API_KEY">
      <GoogleMap
        id="styled-map"
        mapContainerStyle={mapContainerStyle}
        mapContainerClassName="custom-map"
        center={center}
        zoom={10}
        options={mapOptions}
      />
    </LoadScript>
  );
}

Implementation Notes

GoogleMap is implemented as a class component with an internal functional variant (GoogleMapF) that uses React hooks. However, GoogleMapF is not exported from the main package and is not available for direct use. The main GoogleMap component should be used in all cases.

useGoogleMap Hook

React hook that provides access to the current Google Map instance from the React Context within child components.

/**
 * Hook to access current Google Map instance from context
 * Must be used within a GoogleMap component tree
 * @returns The Google Maps instance or null if not available
 */
function useGoogleMap(): google.maps.Map | null;

Usage Examples:

import React, { useEffect } from 'react';
import { GoogleMap, LoadScript, useGoogleMap } from '@react-google-maps/api';

// Custom component that accesses the map instance
function MapControls() {
  const map = useGoogleMap();
  
  useEffect(() => {
    if (map) {
      // Access map instance directly
      console.log('Current map bounds:', map.getBounds());
      console.log('Current zoom level:', map.getZoom());
      
      // Add custom controls or modify map programmatically
      const controlDiv = document.createElement('div');
      controlDiv.innerHTML = '<button>Custom Control</button>';
      map.controls[google.maps.ControlPosition.TOP_CENTER].push(controlDiv);
    }
  }, [map]);
  
  const centerMap = () => {
    if (map) {
      map.setCenter({ lat: 40.7128, lng: -74.0060 });
      map.setZoom(12);
    }
  };
  
  return (
    <div style={{ position: 'absolute', top: 10, left: 10, zIndex: 1 }}>
      <button onClick={centerMap}>Center on NYC</button>
    </div>
  );
}

// Custom marker component that uses map instance
function CustomMapComponent() {
  const map = useGoogleMap();
  
  useEffect(() => {
    if (map) {
      // Create custom marker using native Google Maps API
      const marker = new google.maps.Marker({
        position: { lat: 40.7128, lng: -74.0060 },
        map: map,
        title: 'Custom Marker'
      });
      
      // Cleanup on unmount
      return () => {
        marker.setMap(null);
      };
    }
  }, [map]);
  
  return null; // This component doesn't render anything
}

// Usage within GoogleMap
function AppWithMapAccess() {
  return (
    <LoadScript googleMapsApiKey="YOUR_API_KEY">
      <div style={{ position: 'relative' }}>
        <GoogleMap
          mapContainerStyle={{ width: '100%', height: '400px' }}
          center={{ lat: 40.7128, lng: -74.0060 }}
          zoom={10}
        >
          <MapControls />
          <CustomMapComponent />
        </GoogleMap>
      </div>
    </LoadScript>
  );
}

MapContext

React Context that provides the Google Map instance to child components.

/**
 * React Context for sharing Google Map instance
 * Used internally by useGoogleMap hook
 */
interface MapContextValue {
  map: google.maps.Map | null;
}

const MapContext: React.Context<MapContextValue>;

Usage Examples:

import React, { useContext } from 'react';
import { MapContext } from '@react-google-maps/api';

// Direct context usage (useGoogleMap hook is preferred)
function DirectContextUsage() {
  const { map } = useContext(MapContext);
  
  React.useEffect(() => {
    if (map) {
      console.log('Map instance from context:', map);
    }
  }, [map]);
  
  return null;
}

Advanced Map Configuration

Advanced configuration patterns and map manipulation techniques.

/**
 * Advanced map configuration options
 */
interface AdvancedMapOptions extends google.maps.MapOptions {
  // Restrict map bounds
  restriction?: {
    latLngBounds: google.maps.LatLngBounds;
    strictBounds?: boolean;
  };
  
  // Custom map types
  mapTypeControlOptions?: {
    mapTypeIds?: (google.maps.MapTypeId | string)[];
    style?: google.maps.MapTypeControlStyle;
    position?: google.maps.ControlPosition;
  };
}

Advanced Usage Examples:

// Map with restricted bounds (e.g., for a specific region)
function RestrictedMap() {
  const bounds = new google.maps.LatLngBounds(
    new google.maps.LatLng(40.4774, -74.2591), // SW corner
    new google.maps.LatLng(40.9176, -73.7004)  // NE corner
  );
  
  const restrictedMapOptions: google.maps.MapOptions = {
    restriction: {
      latLngBounds: bounds,
      strictBounds: false
    },
    center: { lat: 40.7128, lng: -74.0060 },
    zoom: 10
  };
  
  return (
    <GoogleMap
      mapContainerStyle={{ width: '100%', height: '400px' }}
      options={restrictedMapOptions}
    />
  );
}

// Map with custom map type
function CustomMapTypeExample() {
  const onLoad = useCallback((map: google.maps.Map) => {
    // Add custom map type
    const customMapType = new google.maps.ImageMapType({
      getTileUrl: function(coord, zoom) {
        return `https://example.com/tiles/${zoom}/${coord.x}/${coord.y}.png`;
      },
      tileSize: new google.maps.Size(256, 256),
      maxZoom: 18,
      minZoom: 0,
      name: 'Custom'
    });
    
    map.mapTypes.set('custom', customMapType);
  }, []);
  
  const mapOptions: google.maps.MapOptions = {
    mapTypeControlOptions: {
      mapTypeIds: ['roadmap', 'satellite', 'hybrid', 'terrain', 'custom'],
      style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
      position: google.maps.ControlPosition.TOP_CENTER
    }
  };
  
  return (
    <GoogleMap
      mapContainerStyle={{ width: '100%', height: '400px' }}
      center={{ lat: 40.7128, lng: -74.0060 }}
      zoom={10}
      options={mapOptions}
      onLoad={onLoad}
    />
  );
}

Install with Tessl CLI

npx tessl i tessl/npm-react-google-maps--api

docs

clustering.md

core-map.md

drawing-shapes.md

index.md

layers.md

markers-overlays.md

places.md

script-loading.md

services.md

tile.json