CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-google-maps

React.js Google Maps integration component library providing comprehensive Google Maps functionality through React components

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

addons.mddocs/

Addon Extensions

Third-party addon components that extend Google Maps functionality with enhanced features like marker clustering, custom info boxes, and labeled markers. These components require additional dependencies.

Capabilities

InfoBox

Enhanced info window component with advanced styling and positioning options. Requires the google-maps-infobox package.

/**
 * Enhanced info window with advanced styling options
 * Requires: npm install google-maps-infobox
 */
class InfoBox extends Component<InfoBoxProps> {}

interface InfoBoxProps {
  // Default props
  defaultOptions?: InfoBoxOptions;
  defaultPosition?: google.maps.LatLng;
  defaultVisible?: boolean;
  defaultZIndex?: number;
  
  // Controlled props
  options?: InfoBoxOptions;
  position?: google.maps.LatLng;
  visible?: boolean;
  zIndex?: number;
  
  // Event handlers
  onCloseClick?(): void;
  onContentChanged?(): void;
  onDomReady?(): void;
  onPositionChanged?(): void;
  onZindexChanged?(): void;
}

Usage Example:

import InfoBox from "react-google-maps/lib/components/addons/InfoBox";

<GoogleMap defaultZoom={10} defaultCenter={{ lat: 37.7749, lng: -122.4194 }}>
  <Marker position={{ lat: 37.7749, lng: -122.4194 }} />
  
  <InfoBox
    position={{ lat: 37.7749, lng: -122.4194 }}
    options={{
      content: `
        <div style="background: white; padding: 12px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.2);">
          <h3 style="margin: 0 0 8px 0;">San Francisco</h3>
          <p style="margin: 0;">The City by the Bay</p>
        </div>
      `,
      disableAutoPan: false,
      maxWidth: 0,
      pixelOffset: { width: -140, height: 0 },
      zIndex: null,
      boxStyle: {
        background: "url('tipbox.gif') no-repeat",
        opacity: 0.75,
        width: "280px"
      },
      closeBoxMargin: "10px 2px 2px 2px",
      closeBoxURL: "http://www.google.com/intl/en_us/mapfiles/close.gif",
      infoBoxClearance: { width: 50, height: 200 }
    }}
    onCloseClick={() => {
      console.log("InfoBox closed");
    }}
  />
</GoogleMap>

MarkerClusterer

Component for clustering markers when they are close together at low zoom levels. Requires the marker-clusterer-plus package.

/**
 * Marker clustering component for managing large numbers of markers
 * Requires: npm install marker-clusterer-plus
 */
class MarkerClusterer extends Component<MarkerClustererProps> {}

interface MarkerClustererProps {
  // Default clustering options
  defaultAverageCenter?: boolean;
  defaultBatchSizeIE?: number;
  defaultBatchSize?: number;
  defaultCalculator?: Calculator;
  defaultClusterClass?: string;
  defaultEnableRetinaIcons?: boolean;
  defaultGridSize?: number;
  defaultIgnoreHidden?: boolean;
  defaultImageExtension?: string;
  defaultImagePath?: string;
  defaultImageSizes?: number[];
  defaultMaxZoom?: number;
  defaultMinimumClusterSize?: number;
  defaultStyles?: ClusterIconStyle[];
  defaultTitle?: string;
  defaultZoomOnClick?: boolean;
  
  // Controlled clustering options
  averageCenter?: boolean;
  batchSizeIE?: number;
  batchSize?: number;
  calculator?: Calculator;
  clusterClass?: string;
  enableRetinaIcons?: boolean;
  gridSize?: number;
  ignoreHidden?: boolean;
  imageExtension?: string;
  imagePath?: string;
  imageSizes?: number[];
  maxZoom?: number;
  minimumClusterSize?: number;
  styles?: ClusterIconStyle[];
  title?: string;
  zoomOnClick?: boolean;
  
  // Event handlers
  onClick?(cluster: Cluster): void;
  onClusteringBegin?(mc: MarkerClusterer): void;
  onClusteringEnd?(mc: MarkerClusterer): void;
  onMouseOut?(c: Cluster): void;
  onMouseOver?(c: Cluster): void;
}

Usage Example:

import MarkerClusterer from "react-google-maps/lib/components/addons/MarkerClusterer";

const ClusteredMarkers = () => {
  const [markers] = useState([
    { lat: 37.7749, lng: -122.4194, id: 1 },
    { lat: 37.7849, lng: -122.4094, id: 2 },
    { lat: 37.7649, lng: -122.4294, id: 3 },
    // ... many more markers
  ]);

  return (
    <GoogleMap defaultZoom={10} defaultCenter={{ lat: 37.7749, lng: -122.4194 }}>
      <MarkerClusterer
        averageCenter={true}
        enableRetinaIcons={true}
        gridSize={60}
        maxZoom={15}
        minimumClusterSize={2}
        styles={[
          {
            textColor: 'white',
            url: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m1.png',
            height: 53,
            width: 53
          },
          {
            textColor: 'white',
            url: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m2.png',
            height: 56,
            width: 56
          },
          {
            textColor: 'white',
            url: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m3.png',
            height: 66,
            width: 66
          }
        ]}
        onClick={(cluster) => {
          console.log(`Cluster clicked with ${cluster.getMarkers().length} markers`);
        }}
        onClusteringEnd={(markerClusterer) => {
          console.log(`Clustering complete: ${markerClusterer.getClusters().length} clusters`);
        }}
      >
        {markers.map((marker) => (
          <Marker
            key={marker.id}
            position={{ lat: marker.lat, lng: marker.lng }}
            title={`Marker ${marker.id}`}
          />
        ))}
      </MarkerClusterer>
    </GoogleMap>
  );
};

MarkerWithLabel

Enhanced marker component with custom label styling. Requires the markerwithlabel package and extends the standard Marker props.

/**
 * Marker with custom label styling
 * Requires: npm install markerwithlabel
 * Extends MarkerProps with additional label properties
 */
class MarkerWithLabel extends Component<MarkerProps> {}

// Extends MarkerProps with these additional properties:
interface MarkerLabelProps extends MarkerProps {
  /** Custom label class for styling */
  labelClass?: string;
  /** Anchor point for the label */
  labelAnchor?: google.maps.Point;
  /** Text content of the label */
  labelContent?: string;
  /** Inline styles for the label */
  labelStyle?: CSSStyleDeclaration;
  /** Callback when marker with label functionality is ready */
  markerWithLabel?(): void;
}

Usage Example:

import MarkerWithLabel from "react-google-maps/lib/components/addons/MarkerWithLabel";

<GoogleMap defaultZoom={10} defaultCenter={{ lat: 37.7749, lng: -122.4194 }}>
  <MarkerWithLabel
    position={{ lat: 37.7749, lng: -122.4194 }}
    labelAnchor={new google.maps.Point(0, 0)}
    labelContent="San Francisco"
    labelStyle={{
      backgroundColor: "yellow",
      fontSize: "14px",
      padding: "4px",
      borderRadius: "4px",
      border: "1px solid #333"
    }}
    icon={{
      url: "https://maps.google.com/mapfiles/ms/icons/blue-dot.png"
    }}
    onClick={() => {
      console.log("Labeled marker clicked");
    }}
  />
  
  <MarkerWithLabel
    position={{ lat: 37.7649, lng: -122.4294 }}
    labelContent="Custom Location"
    labelClass="custom-label"
    labelAnchor={new google.maps.Point(30, 0)}
    icon={{
      url: "https://maps.google.com/mapfiles/ms/icons/red-dot.png"
    }}
  />
</GoogleMap>

Addon Installation and Setup

Installing Dependencies

Each addon requires its corresponding npm package:

# For InfoBox
npm install google-maps-infobox

# For MarkerClusterer
npm install marker-clusterer-plus

# For MarkerWithLabel
npm install markerwithlabel

# Install all addons
npm install google-maps-infobox marker-clusterer-plus markerwithlabel

Importing Addon Components

Addon components must be imported directly from their specific paths:

// Correct imports for addons
import InfoBox from "react-google-maps/lib/components/addons/InfoBox";
import MarkerClusterer from "react-google-maps/lib/components/addons/MarkerClusterer";
import MarkerWithLabel from "react-google-maps/lib/components/addons/MarkerWithLabel";

// These will NOT work - addons are not in main exports
import { InfoBox, MarkerClusterer, MarkerWithLabel } from "react-google-maps"; // ❌

Advanced Addon Patterns

Combining Clustering with Custom InfoBox

const AdvancedMarkerMap = () => {
  const [selectedMarker, setSelectedMarker] = useState(null);
  const [markers] = useState(/* large array of markers */);

  return (
    <GoogleMap defaultZoom={10} defaultCenter={{ lat: 37.7749, lng: -122.4194 }}>
      <MarkerClusterer
        onClick={(cluster) => {
          // Zoom into cluster
          const bounds = new google.maps.LatLngBounds();
          cluster.getMarkers().forEach(marker => {
            bounds.extend(marker.getPosition());
          });
          map.fitBounds(bounds);
        }}
      >
        {markers.map((marker) => (
          <Marker
            key={marker.id}
            position={marker.position}
            onClick={() => setSelectedMarker(marker)}
          />
        ))}
      </MarkerClusterer>
      
      {selectedMarker && (
        <InfoBox
          position={selectedMarker.position}
          options={{
            content: `
              <div class="custom-infobox">
                <h3>${selectedMarker.title}</h3>
                <p>${selectedMarker.description}</p>
                <button onclick="closeInfoBox()">Close</button>
              </div>
            `
          }}
          onCloseClick={() => setSelectedMarker(null)}
        />
      )}
    </GoogleMap>
  );
};

Custom Cluster Styling

const customClusterStyles = [
  {
    textColor: 'white',
    textSize: 11,
    url: 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(`
      <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40">
        <circle cx="20" cy="20" r="18" fill="#ff6b6b" stroke="#fff" stroke-width="2"/>
      </svg>
    `),
    height: 40,
    width: 40
  },
  {
    textColor: 'white',
    textSize: 12,
    url: 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(`
      <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50">
        <circle cx="25" cy="25" r="23" fill="#4ecdc4" stroke="#fff" stroke-width="2"/>
      </svg>
    `),
    height: 50,
    width: 50
  }
];

<MarkerClusterer
  styles={customClusterStyles}
  calculator={(markers, numStyles) => {
    const count = markers.length;
    let index = 0;
    if (count > 10) index = 1;
    if (count > 100) index = 2;
    return { text: count, index: index };
  }}
>
  {/* markers */}
</MarkerClusterer>

Install with Tessl CLI

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

docs

addons.md

advanced.md

core-components.md

drawing.md

hocs.md

index.md

layers.md

places.md

shapes.md

visualization.md

tile.json