UNPKG

@vis.gl/react-google-maps

Version:

React components and hooks for the Google Maps JavaScript API

1,283 lines (1,248 loc) 52.4 kB
import React, { DetailedHTMLProps, HTMLAttributes, CSSProperties, PropsWithChildren, FunctionComponent, Ref, ReactNode } from 'react'; import { importLibrary } from '@googlemaps/js-api-loader'; /** * Maps base Google Maps types to their broader "write" equivalents. * * This is used to handle the fact that many Google Maps API properties * accept a wider range of types in their setters than what their getters return. */ type GmpBaseWritableElementType<V> = // Handle unions by distributing the mapping over each member V extends unknown ? // 1. Path/Array patterns (support Iterable for performance where possible) V extends Array<Array<infer U>> ? Iterable<Iterable<GmpBaseWritableElementType<U>>> : V extends Array<infer U> ? Iterable<GmpBaseWritableElementType<U>> : // 2. Geometry & Coordinate patterns (3D) // Some 3D elements specifically want Altitude variants V extends google.maps.LatLngAltitude ? | google.maps.LatLng | google.maps.LatLngLiteral | google.maps.LatLngAltitude | google.maps.LatLngAltitudeLiteral | string : // 3. Geometry & Coordinate patterns (2D) V extends google.maps.LatLng ? google.maps.LatLng | google.maps.LatLngLiteral | string : V extends google.maps.LatLngBounds ? google.maps.LatLngBounds | google.maps.LatLngBoundsLiteral : V extends google.maps.Circle ? google.maps.Circle | google.maps.CircleLiteral : // 4. Specialized Classes/Interfaces V extends google.maps.Orientation3D ? google.maps.Orientation3D | google.maps.Orientation3DLiteral : V extends google.maps.Vector3D ? | google.maps.Vector3D | google.maps.Vector3DLiteral | number : V extends google.maps.places.Place ? google.maps.places.Place | string : V extends URL ? URL | string : // 5. Default Fallback V : never; /** * The final writable type for a GMP property, ensuring support * for the expanded types plus null and undefined. */ type GmpWritableElementProp<V> = | GmpBaseWritableElementType<NonNullable<V>> | null | undefined; /** * Transforms a type T into its writable counterpart for use with custom elements. */ type GmpWritableElement<T> = { [K in keyof T]?: GmpWritableElementProp<T[K]>; }; type ReactIntrinsicElementBridge<Element, EventMap, ReactProps> = { [K in keyof EventMap as `on${string & K}`]?: (event: EventMap[K]) => void; } & Omit<GmpWritableElement<Element>, keyof ReactProps> & ReactProps; type ReactIntrinsicElementBridgeMap< ElementTagNameMap, ElementEventMapByTagName extends Record<keyof ElementTagNameMap, unknown> > = { [K in keyof ElementTagNameMap]: ReactIntrinsicElementBridge< ElementTagNameMap[K], ElementEventMapByTagName[K], DetailedHTMLProps< HTMLAttributes<ElementTagNameMap[K]>, ElementTagNameMap[K] > >; }; declare module 'react' { namespace JSX { // eslint-disable-next-line @typescript-eslint/no-empty-object-type interface IntrinsicElements extends ReactIntrinsicElementBridgeMap< google.maps.HTMLElementTagNameMap, google.maps.HTMLElementEventMapTagNameMap > {} } // eslint-disable-next-line @typescript-eslint/no-empty-object-type interface CSSProperties extends google.maps.CSSProperties {} } declare const VERSION = "__PACKAGE_VERSION__"; interface AdvancedMarkerContextValue { marker: google.maps.marker.AdvancedMarkerElement; } /** * Copy of the `google.maps.CollisionBehavior` constants. * They have to be duplicated here since we can't wait for the maps API to load to be able to use them. */ declare const CollisionBehavior: { readonly REQUIRED: "REQUIRED"; readonly REQUIRED_AND_HIDES_OPTIONAL: "REQUIRED_AND_HIDES_OPTIONAL"; readonly OPTIONAL_AND_HIDES_LOWER_PRIORITY: "OPTIONAL_AND_HIDES_LOWER_PRIORITY"; }; type CollisionBehavior = (typeof CollisionBehavior)[keyof typeof CollisionBehavior]; declare const AdvancedMarkerContext: React.Context<AdvancedMarkerContextValue | null>; /** * @deprecated Using `anchorPosition` is deprecated. * Use `anchorLeft` and `anchorTop` instead. */ declare const AdvancedMarkerAnchorPoint: { readonly TOP_LEFT: readonly ["0%", "0%"]; readonly TOP_CENTER: readonly ["50%", "0%"]; readonly TOP: readonly ["50%", "0%"]; readonly TOP_RIGHT: readonly ["100%", "0%"]; readonly LEFT_CENTER: readonly ["0%", "50%"]; readonly LEFT_TOP: readonly ["0%", "0%"]; readonly LEFT: readonly ["0%", "50%"]; readonly LEFT_BOTTOM: readonly ["0%", "100%"]; readonly RIGHT_TOP: readonly ["100%", "0%"]; readonly RIGHT: readonly ["100%", "50%"]; readonly RIGHT_CENTER: readonly ["100%", "50%"]; readonly RIGHT_BOTTOM: readonly ["100%", "100%"]; readonly BOTTOM_LEFT: readonly ["0%", "100%"]; readonly BOTTOM_CENTER: readonly ["50%", "100%"]; readonly BOTTOM: readonly ["50%", "100%"]; readonly BOTTOM_RIGHT: readonly ["100%", "100%"]; readonly CENTER: readonly ["50%", "50%"]; }; type AdvancedMarkerAnchorPoint = (typeof AdvancedMarkerAnchorPoint)[keyof typeof AdvancedMarkerAnchorPoint]; type AdvancedMarkerEventProps = { onClick?: (e: google.maps.marker.AdvancedMarkerClickEvent) => void; onKeyDown?: (e: KeyboardEvent) => void; onKeyUp?: (e: KeyboardEvent) => void; onMouseEnter?: (e: google.maps.MapMouseEvent['domEvent']) => void; onMouseLeave?: (e: google.maps.MapMouseEvent['domEvent']) => void; onDrag?: (e: google.maps.MapMouseEvent) => void; onDragStart?: (e: google.maps.MapMouseEvent) => void; onDragEnd?: (e: google.maps.MapMouseEvent) => void; }; type AdvancedMarkerProps = PropsWithChildren<Omit<google.maps.marker.AdvancedMarkerElementOptions, 'gmpDraggable' | 'gmpClickable' | 'content' | 'map' | 'collisionBehavior'> & AdvancedMarkerEventProps & { draggable?: boolean; clickable?: boolean; collisionBehavior?: CollisionBehavior; /** * @deprecated Use `anchorLeft` and `anchorTop` instead. * * The anchor point for the Advanced Marker. * Either use one of the predefined anchor point from the "AdvancedMarkerAnchorPoint" export * or provide a string tuple in the form of ["xPosition", "yPosition"]. * The position is measured from the top-left corner and * can be anything that can be consumed by a CSS translate() function. * For example in percent ("50%") or in pixels ("20px"). */ anchorPoint?: AdvancedMarkerAnchorPoint | [string, string]; /** * A CSS length-percentage value which is used to offset the anchor point of the marker from the top left corner of the marker. This is useful when using a visual which has an anchor point that is different than the typical bottom center point of the default marker. The default value is "-%50". */ anchorLeft?: string; /** * A CSS length-percentage value which is used to offset the anchor point of the marker from the top left corner of the marker. This is useful when using a visual which has an anchor point that is different than the typical bottom center point of the default marker. The default value is "-%100". */ anchorTop?: string; /** * A className for the content element. * (can only be used with HTML Marker content) */ className?: string; /** * Additional styles to apply to the content element. */ style?: CSSProperties; }>; declare const AdvancedMarker: React.ForwardRefExoticComponent<Omit<google.maps.marker.AdvancedMarkerElementOptions, "gmpDraggable" | "gmpClickable" | "content" | "map" | "collisionBehavior"> & AdvancedMarkerEventProps & { draggable?: boolean; clickable?: boolean; collisionBehavior?: CollisionBehavior; /** * @deprecated Use `anchorLeft` and `anchorTop` instead. * * The anchor point for the Advanced Marker. * Either use one of the predefined anchor point from the "AdvancedMarkerAnchorPoint" export * or provide a string tuple in the form of ["xPosition", "yPosition"]. * The position is measured from the top-left corner and * can be anything that can be consumed by a CSS translate() function. * For example in percent ("50%") or in pixels ("20px"). */ anchorPoint?: AdvancedMarkerAnchorPoint | [string, string]; /** * A CSS length-percentage value which is used to offset the anchor point of the marker from the top left corner of the marker. This is useful when using a visual which has an anchor point that is different than the typical bottom center point of the default marker. The default value is "-%50". */ anchorLeft?: string; /** * A CSS length-percentage value which is used to offset the anchor point of the marker from the top left corner of the marker. This is useful when using a visual which has an anchor point that is different than the typical bottom center point of the default marker. The default value is "-%100". */ anchorTop?: string; /** * A className for the content element. * (can only be used with HTML Marker content) */ className?: string; /** * Additional styles to apply to the content element. */ style?: CSSProperties; } & { children?: React.ReactNode | undefined; } & React.RefAttributes<google.maps.marker.AdvancedMarkerElement>>; declare function useAdvancedMarkerRef(): readonly [(m: AdvancedMarkerRef | null) => void, google.maps.marker.AdvancedMarkerElement | null]; declare function isAdvancedMarker(marker: google.maps.Marker | google.maps.marker.AdvancedMarkerElement): marker is google.maps.marker.AdvancedMarkerElement; type CustomMarkerContent = HTMLDivElement | null; type AdvancedMarkerRef = google.maps.marker.AdvancedMarkerElement | null; declare const APILoadingStatus: { readonly NOT_LOADED: "NOT_LOADED"; readonly LOADING: "LOADING"; readonly LOADED: "LOADED"; readonly FAILED: "FAILED"; readonly AUTH_FAILURE: "AUTH_FAILURE"; }; type APILoadingStatus = (typeof APILoadingStatus)[keyof typeof APILoadingStatus]; type LoadedLibraries = Partial<google.maps.ImportLibraryMap>; interface APIProviderContextValue { status: APILoadingStatus; loadedLibraries: LoadedLibraries; importLibrary: typeof importLibrary; mapInstances: Record<string, google.maps.Map>; addMapInstance: (map: google.maps.Map, id?: string) => void; removeMapInstance: (id?: string) => void; clearMapInstances: () => void; map3dInstances: Record<string, google.maps.maps3d.Map3DElement>; addMap3DInstance: (map3d: google.maps.maps3d.Map3DElement, id?: string) => void; removeMap3DInstance: (id?: string) => void; clearMap3DInstances: () => void; internalUsageAttributionIds: string[] | null; } declare const APIProviderContext: React.Context<APIProviderContextValue | null>; type APIProviderProps = PropsWithChildren<{ /** * apiKey must be provided to load the Google Maps JavaScript API. To create an API key, see: https://developers.google.com/maps/documentation/javascript/get-api-key * Part of: */ apiKey: string; /** * A custom id to reference the script tag can be provided. The default is set to 'google-maps-api' * @default 'google-maps-api' */ libraries?: Array<string>; /** * A specific version of the Google Maps JavaScript API can be used. * Read more about versioning: https://developers.google.com/maps/documentation/javascript/versions * Part of: https://developers.google.com/maps/documentation/javascript/url-params */ version?: string; /** * Sets the map to a specific region. * Read more about localizing the Map: https://developers.google.com/maps/documentation/javascript/localization * Part of: https://developers.google.com/maps/documentation/javascript/url-params */ region?: string; /** * Use a specific language for the map. * Read more about localizing the Map: https://developers.google.com/maps/documentation/javascript/localization * Part of: https://developers.google.com/maps/documentation/javascript/url-params */ language?: string; /** * auth_referrer_policy can be set to 'origin'. * Part of: https://developers.google.com/maps/documentation/javascript/url-params */ authReferrerPolicy?: string; /** * To track usage of Google Maps JavaScript API via numeric channels. * The only acceptable channel values are numbers from 0-999. * Read more in the * [documentation](https://developers.google.com/maps/reporting-and-monitoring/reporting#usage-tracking-per-channel) */ channel?: number; /** * To understand usage and ways to improve our solutions, Google includes the * `solution_channel` query parameter in API calls to gather information about * code usage. You may opt out at any time by setting this attribute to an * empty string. Read more in the * [documentation](https://developers.google.com/maps/reporting-and-monitoring/reporting#solutions-usage). */ solutionChannel?: string; /** * To help Google understand which libraries and samples are helpful to developers, such as usage of this library. * To opt out of sending the usage attribution ID, use this boolean prop. Read more in the * [documentation](https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.internalUsageAttributionIds). */ disableUsageAttribution?: boolean; /** * A function that can be used to execute code after the Google Maps JavaScript API has been loaded. */ onLoad?: () => void; /** * A function that will be called if there was an error when loading the Google Maps JavaScript API. */ onError?: (error: unknown) => void; /** * A function that returns a Promise resolving to an App Check token. * When provided, it will be set on `google.maps.Settings.getInstance().fetchAppCheckToken` * after the Google Maps JavaScript API has been loaded. */ fetchAppCheckToken?: () => Promise<google.maps.MapsAppCheckTokenResult>; }>; /** * Component to wrap the components from this library and load the Google Maps JavaScript API */ declare const APIProvider: FunctionComponent<APIProviderProps>; /** * @internal * Resets module-level state for testing purposes only. * This should never be used in production code. */ declare function __resetModuleState(): void; type CircleEventProps = { onClick?: (e: google.maps.MapMouseEvent) => void; onDrag?: (e: google.maps.MapMouseEvent) => void; onDragStart?: (e: google.maps.MapMouseEvent) => void; onDragEnd?: (e: google.maps.MapMouseEvent) => void; onMouseOver?: (e: google.maps.MapMouseEvent) => void; onMouseOut?: (e: google.maps.MapMouseEvent) => void; onRadiusChanged?: (radius: number) => void; onCenterChanged?: (center: google.maps.LatLng | null | undefined) => void; }; type CircleProps = Omit<google.maps.CircleOptions, 'map' | 'center' | 'radius'> & CircleEventProps & { /** Controlled center position */ center?: google.maps.LatLngLiteral | google.maps.LatLng; /** Uncontrolled initial center position */ defaultCenter?: google.maps.LatLngLiteral | google.maps.LatLng; /** Controlled radius in meters */ radius?: number; /** Uncontrolled initial radius in meters */ defaultRadius?: number; }; type CircleRef = Ref<google.maps.Circle | null>; declare const Circle: React.ForwardRefExoticComponent<Omit<google.maps.CircleOptions, "map" | "center" | "radius"> & CircleEventProps & { /** Controlled center position */ center?: google.maps.LatLngLiteral | google.maps.LatLng; /** Uncontrolled initial center position */ defaultCenter?: google.maps.LatLngLiteral | google.maps.LatLng; /** Controlled radius in meters */ radius?: number; /** Uncontrolled initial radius in meters */ defaultRadius?: number; } & React.RefAttributes<google.maps.Circle>>; type InfoWindowProps = Omit<google.maps.InfoWindowOptions, 'headerContent' | 'content' | 'pixelOffset'> & { style?: CSSProperties; className?: string; anchor?: google.maps.Marker | google.maps.marker.AdvancedMarkerElement | null; pixelOffset?: [number, number]; shouldFocus?: boolean; onClose?: () => void; onCloseClick?: () => void; headerContent?: ReactNode; }; /** * Component to render an Info Window with the Maps JavaScript API */ declare const InfoWindow: FunctionComponent<PropsWithChildren<InfoWindowProps>>; /** * Handlers for all events that could be emitted by map-instances. */ type MapEventProps = Partial<{ onBoundsChanged: (event: MapCameraChangedEvent) => void; onCenterChanged: (event: MapCameraChangedEvent) => void; onHeadingChanged: (event: MapCameraChangedEvent) => void; onTiltChanged: (event: MapCameraChangedEvent) => void; onZoomChanged: (event: MapCameraChangedEvent) => void; onCameraChanged: (event: MapCameraChangedEvent) => void; onClick: (event: MapMouseEvent) => void; onDblclick: (event: MapMouseEvent) => void; onContextmenu: (event: MapMouseEvent) => void; onMousemove: (event: MapMouseEvent) => void; onMouseover: (event: MapMouseEvent) => void; onMouseout: (event: MapMouseEvent) => void; onDrag: (event: MapEvent) => void; onDragend: (event: MapEvent) => void; onDragstart: (event: MapEvent) => void; onTilesLoaded: (event: MapEvent) => void; onIdle: (event: MapEvent) => void; onProjectionChanged: (event: MapEvent) => void; onIsFractionalZoomEnabledChanged: (event: MapEvent) => void; onMapCapabilitiesChanged: (event: MapEvent) => void; onMapTypeIdChanged: (event: MapEvent) => void; onRenderingTypeChanged: (event: MapEvent) => void; }>; type MapEvent<T = unknown> = { type: string; map: google.maps.Map; detail: T; stoppable: boolean; stop: () => void; domEvent?: MouseEvent | TouchEvent | PointerEvent | KeyboardEvent | Event; }; type MapMouseEvent = MapEvent<{ latLng: google.maps.LatLngLiteral | null; placeId: string | null; }>; type MapCameraChangedEvent = MapEvent<{ center: google.maps.LatLngLiteral; bounds: google.maps.LatLngBoundsLiteral; zoom: number; heading: number; tilt: number; }>; type DeckGlCompatProps = { /** * Viewport from deck.gl */ viewport?: unknown; /** * View state from deck.gl */ viewState?: Record<string, unknown>; /** * Initial View State from deck.gl */ initialViewState?: Record<string, unknown>; }; interface GoogleMapsContextValue { map: google.maps.Map | null; } declare const GoogleMapsContext: React.Context<GoogleMapsContextValue | null>; type MapCameraProps = { center: google.maps.LatLngLiteral; zoom: number; heading?: number; tilt?: number; }; declare const ColorScheme: { readonly DARK: "DARK"; readonly LIGHT: "LIGHT"; readonly FOLLOW_SYSTEM: "FOLLOW_SYSTEM"; }; type ColorScheme = (typeof ColorScheme)[keyof typeof ColorScheme]; declare const RenderingType: { readonly VECTOR: "VECTOR"; readonly RASTER: "RASTER"; readonly UNINITIALIZED: "UNINITIALIZED"; }; type RenderingType = (typeof RenderingType)[keyof typeof RenderingType]; /** * Props for the Map Component */ type MapProps = PropsWithChildren<Omit<google.maps.MapOptions, 'renderingType' | 'colorScheme'> & MapEventProps & DeckGlCompatProps & { /** * An id for the map, this is required when multiple maps are present * in the same APIProvider context. */ id?: string; /** * Additional style rules to apply to the map dom-element. */ style?: CSSProperties; /** * Additional css class-name to apply to the element containing the map. */ className?: string; /** * The color-scheme to use for the map. */ colorScheme?: ColorScheme; /** * The rendering-type to be used. */ renderingType?: RenderingType; /** * Indicates that the map will be controlled externally. Disables all controls provided by the map itself. */ controlled?: boolean; /** * Enable caching of map-instances created by this component. */ reuseMaps?: boolean; defaultCenter?: google.maps.LatLngLiteral; defaultZoom?: number; defaultHeading?: number; defaultTilt?: number; /** * Alternative way to specify the default camera props as a geographic region that should be fully visible */ defaultBounds?: google.maps.LatLngBoundsLiteral & { padding?: number | google.maps.Padding; }; }>; declare const Map: FunctionComponent<MapProps>; type PolygonEventProps = { onClick?: (e: google.maps.MapMouseEvent) => void; onDrag?: (e: google.maps.MapMouseEvent) => void; onDragStart?: (e: google.maps.MapMouseEvent) => void; onDragEnd?: (e: google.maps.MapMouseEvent) => void; onMouseOver?: (e: google.maps.MapMouseEvent) => void; onMouseOut?: (e: google.maps.MapMouseEvent) => void; onPathsChanged?: (paths: google.maps.LatLng[][]) => void; }; type PathsType = google.maps.MVCArray<google.maps.MVCArray<google.maps.LatLng>> | google.maps.MVCArray<google.maps.LatLng> | Array<google.maps.LatLng | google.maps.LatLngLiteral> | Array<Array<google.maps.LatLng | google.maps.LatLngLiteral>>; type PolygonProps = Omit<google.maps.PolygonOptions, 'map' | 'paths'> & PolygonEventProps & { /** * An existing Polygon instance to use instead of creating a new one. * Other props will still be applied to this instance. */ polygon?: google.maps.Polygon; /** * An array of encoded polyline strings as created by the encoding algorithm. * (https://developers.google.com/maps/documentation/utilities/polylinealgorithm) * When provided, will be decoded and used as the paths. * Takes precedence over the `paths` prop if both are specified. */ encodedPaths?: string[]; /** Controlled paths */ paths?: PathsType; /** Uncontrolled initial paths */ defaultPaths?: PathsType; }; type PolygonRef = Ref<google.maps.Polygon | null>; declare const Polygon: React.ForwardRefExoticComponent<Omit<google.maps.PolygonOptions, "map" | "paths"> & PolygonEventProps & { /** * An existing Polygon instance to use instead of creating a new one. * Other props will still be applied to this instance. */ polygon?: google.maps.Polygon; /** * An array of encoded polyline strings as created by the encoding algorithm. * (https://developers.google.com/maps/documentation/utilities/polylinealgorithm) * When provided, will be decoded and used as the paths. * Takes precedence over the `paths` prop if both are specified. */ encodedPaths?: string[]; /** Controlled paths */ paths?: PathsType; /** Uncontrolled initial paths */ defaultPaths?: PathsType; } & React.RefAttributes<google.maps.Polygon>>; type PolylineEventProps = { onClick?: (e: google.maps.MapMouseEvent) => void; onDrag?: (e: google.maps.MapMouseEvent) => void; onDragStart?: (e: google.maps.MapMouseEvent) => void; onDragEnd?: (e: google.maps.MapMouseEvent) => void; onMouseOver?: (e: google.maps.MapMouseEvent) => void; onMouseOut?: (e: google.maps.MapMouseEvent) => void; onPathChanged?: (path: google.maps.LatLng[]) => void; }; type PathType = google.maps.MVCArray<google.maps.LatLng> | Array<google.maps.LatLng | google.maps.LatLngLiteral>; type PolylineProps = Omit<google.maps.PolylineOptions, 'map' | 'path'> & PolylineEventProps & { /** * An existing Polyline instance to use instead of creating a new one. * Other props will still be applied to this instance. */ polyline?: google.maps.Polyline; /** * An encoded polyline string as created by the encoding algorithm. * (https://developers.google.com/maps/documentation/utilities/polylinealgorithm) * When provided, will be decoded and used as the path. * Takes precedence over the `path` prop if both are specified. */ encodedPath?: string; /** Controlled path */ path?: PathType; /** Uncontrolled initial path */ defaultPath?: PathType; }; type PolylineRef = Ref<google.maps.Polyline | null>; declare const Polyline: React.ForwardRefExoticComponent<Omit<google.maps.PolylineOptions, "map" | "path"> & PolylineEventProps & { /** * An existing Polyline instance to use instead of creating a new one. * Other props will still be applied to this instance. */ polyline?: google.maps.Polyline; /** * An encoded polyline string as created by the encoding algorithm. * (https://developers.google.com/maps/documentation/utilities/polylinealgorithm) * When provided, will be decoded and used as the path. * Takes precedence over the `path` prop if both are specified. */ encodedPath?: string; /** Controlled path */ path?: PathType; /** Uncontrolled initial path */ defaultPath?: PathType; } & React.RefAttributes<google.maps.Polyline>>; /** * Base event type for all Map3D events. */ interface Map3DEvent { type: string; map3d: google.maps.maps3d.Map3DElement; } /** * Event fired when a camera property changes. */ interface Map3DCameraChangedEvent extends Map3DEvent { detail: { center: google.maps.LatLngAltitudeLiteral; range: number; heading: number; tilt: number; roll: number; }; } /** * Event fired when the map is clicked. */ interface Map3DClickEvent extends Map3DEvent { detail: { position: google.maps.LatLngAltitude | null; placeId?: string; }; } /** * Event fired when the map's steady state changes. */ interface Map3DSteadyChangeEvent extends Map3DEvent { detail: { isSteady: boolean; }; } /** * Props for Map3D event handlers. */ interface Map3DEventProps { /** Called when the center property changes. */ onCenterChanged?: (event: Map3DCameraChangedEvent) => void; /** Called when the heading property changes. */ onHeadingChanged?: (event: Map3DCameraChangedEvent) => void; /** Called when the tilt property changes. */ onTiltChanged?: (event: Map3DCameraChangedEvent) => void; /** Called when the range property changes. */ onRangeChanged?: (event: Map3DCameraChangedEvent) => void; /** Called when the roll property changes. */ onRollChanged?: (event: Map3DCameraChangedEvent) => void; /** Called when any camera property changes (aggregated). */ onCameraChanged?: (event: Map3DCameraChangedEvent) => void; /** Called when the map is clicked. */ onClick?: (event: Map3DClickEvent) => void; /** Called when the map's steady state changes. */ onSteadyChange?: (event: Map3DSteadyChangeEvent) => void; /** Called when a fly animation ends. */ onAnimationEnd?: (event: Map3DEvent) => void; /** Called when a map error occurs. */ onError?: (event: Map3DEvent) => void; } /** * MapMode for specifying how the 3D map should be rendered. * This mirrors google.maps.maps3d.MapMode but is available without waiting for the API to load. */ declare const MapMode: { /** This map mode displays a transparent layer of major streets on satellite imagery. */ readonly HYBRID: "HYBRID"; /** This map mode displays satellite or photorealistic imagery. */ readonly SATELLITE: "SATELLITE"; }; type MapMode = (typeof MapMode)[keyof typeof MapMode]; /** * GestureHandling for specifying how gesture events should be handled on the map. * This mirrors google.maps.maps3d.GestureHandling but is available without waiting for the API to load. */ declare const GestureHandling: { /** * This lets the map choose whether to use cooperative or greedy gesture handling. * This is the default behavior if not specified. */ readonly AUTO: "AUTO"; /** * This forces cooperative mode, where modifier keys or two-finger gestures * are required to scroll the map. */ readonly COOPERATIVE: "COOPERATIVE"; /** * This forces greedy mode, where the host page cannot be scrolled from user * events on the map element. */ readonly GREEDY: "GREEDY"; }; type GestureHandling = (typeof GestureHandling)[keyof typeof GestureHandling]; /** * Context value for Map3D, providing access to the Map3DElement instance. */ interface GoogleMaps3DContextValue { map3d: google.maps.maps3d.Map3DElement | null; } /** * React context for accessing the Map3D instance from child components. */ declare const GoogleMaps3DContext: React.Context<GoogleMaps3DContextValue | null>; /** * Ref handle exposed by Map3D for imperative actions. */ interface Map3DRef { /** The underlying Map3DElement instance. */ map3d: google.maps.maps3d.Map3DElement | null; /** Fly the camera around a center point. */ flyCameraAround: (options: google.maps.maps3d.FlyAroundAnimationOptions) => void; /** Fly the camera to a destination. */ flyCameraTo: (options: google.maps.maps3d.FlyToAnimationOptions) => void; /** Stop any ongoing camera animation. */ stopCameraAnimation: () => void; } /** * Props for the Map3D component. */ type Map3DProps = PropsWithChildren<Omit<google.maps.maps3d.Map3DElementOptions, 'center' | 'mode' | 'gestureHandling'> & Map3DEventProps & { /** * An id for the map, this is required when multiple maps are present * in the same APIProvider context. */ id?: string; /** * Additional style rules to apply to the map container element. */ style?: CSSProperties; /** * Additional CSS class name to apply to the map container element. */ className?: string; /** * The center of the map. Can be a LatLngAltitude or LatLngAltitudeLiteral. */ center?: google.maps.LatLngAltitude | google.maps.LatLngAltitudeLiteral; /** * Specifies a mode the map should be rendered in. * Import MapMode from '@vis.gl/react-google-maps' to use this. */ mode: MapMode; /** * Specifies how gesture events should be handled on the map. * Import GestureHandling from '@vis.gl/react-google-maps' to use this. */ gestureHandling?: GestureHandling; defaultLabelsDisabled?: boolean; defaultCenter?: google.maps.LatLngAltitudeLiteral; defaultHeading?: number; defaultTilt?: number; defaultRange?: number; defaultRoll?: number; }>; /** * A React component that renders a 3D map using the Google Maps JavaScript API. * * @example * ```tsx * <APIProvider apiKey={API_KEY}> * <Map3D * defaultCenter={{ lat: 37.7749, lng: -122.4194, altitude: 1000 }} * defaultRange={5000} * defaultHeading={0} * defaultTilt={45} * /> * </APIProvider> * ``` */ declare const Map3D: React.ForwardRefExoticComponent<Omit<google.maps.maps3d.Map3DElementOptions, "center" | "gestureHandling" | "mode"> & Map3DEventProps & { /** * An id for the map, this is required when multiple maps are present * in the same APIProvider context. */ id?: string; /** * Additional style rules to apply to the map container element. */ style?: CSSProperties; /** * Additional CSS class name to apply to the map container element. */ className?: string; /** * The center of the map. Can be a LatLngAltitude or LatLngAltitudeLiteral. */ center?: google.maps.LatLngAltitude | google.maps.LatLngAltitudeLiteral; /** * Specifies a mode the map should be rendered in. * Import MapMode from '@vis.gl/react-google-maps' to use this. */ mode: MapMode; /** * Specifies how gesture events should be handled on the map. * Import GestureHandling from '@vis.gl/react-google-maps' to use this. */ gestureHandling?: GestureHandling; defaultLabelsDisabled?: boolean; defaultCenter?: google.maps.LatLngAltitudeLiteral; defaultHeading?: number; defaultTilt?: number; defaultRange?: number; defaultRoll?: number; } & { children?: React.ReactNode | undefined; } & React.RefAttributes<Map3DRef>>; /** * Context for Marker3D component, providing access to the marker element. */ interface Marker3DContextValue { marker: google.maps.maps3d.Marker3DElement | google.maps.maps3d.Marker3DInteractiveElement | null; /** Set to true by child components (like Pin) that handle their own content */ setContentHandledExternally: (handled: boolean) => void; } declare const Marker3DContext: React.Context<Marker3DContextValue | null>; /** * Hook to access the Marker3D context. */ declare function useMarker3D(): Marker3DContextValue | null; /** * AltitudeMode for specifying how altitude is interpreted for 3D elements. * This mirrors google.maps.maps3d.AltitudeMode but is available without waiting for the API to load. */ declare const AltitudeMode: { /** Allows to express objects relative to the average mean sea level. */ readonly ABSOLUTE: "ABSOLUTE"; /** Allows to express objects placed on the ground. */ readonly CLAMP_TO_GROUND: "CLAMP_TO_GROUND"; /** Allows to express objects relative to the ground surface. */ readonly RELATIVE_TO_GROUND: "RELATIVE_TO_GROUND"; /** Allows to express objects relative to the highest of ground+building+water surface. */ readonly RELATIVE_TO_MESH: "RELATIVE_TO_MESH"; }; type AltitudeMode = (typeof AltitudeMode)[keyof typeof AltitudeMode]; /** * Event props for Marker3D component. */ type Marker3DEventProps = { /** Click handler. When provided, the interactive variant (Marker3DInteractiveElement) is used. */ onClick?: (e: Event) => void; }; /** * Props for the Marker3D component. */ type Marker3DProps = PropsWithChildren<Omit<google.maps.maps3d.Marker3DElementOptions, 'collisionBehavior' | 'altitudeMode'> & Marker3DEventProps & { /** * Specifies how the altitude component of the position is interpreted. * @default AltitudeMode.CLAMP_TO_GROUND */ altitudeMode?: AltitudeMode; /** * An enumeration specifying how a Marker3DElement should behave when it * collides with another Marker3DElement or with the basemap labels. * @default CollisionBehavior.REQUIRED */ collisionBehavior?: CollisionBehavior; /** * Rollover text (only used when onClick is provided). */ title?: string; }>; /** * Marker3D component for displaying markers on a Map3D. * * Automatically uses Marker3DInteractiveElement when onClick is provided, * otherwise uses Marker3DElement. * * Children can include: * - `<img>` elements (automatically wrapped in <template>) * - `<svg>` elements (automatically wrapped in <template>) * - PinElement instances (passed through directly) * * @example * ```tsx * // Basic marker * <Marker3D position={{ lat: 37.7749, lng: -122.4194 }} label="SF" /> * * // Interactive marker * <Marker3D * position={{ lat: 37.7749, lng: -122.4194 }} * onClick={() => console.log('clicked')} * title="Click me" * /> * * // Custom marker with image * <Marker3D position={{ lat: 37.7749, lng: -122.4194 }}> * <img src="/icon.png" width={32} height={32} /> * </Marker3D> * ``` */ declare const Marker3D: React.ForwardRefExoticComponent<Omit<google.maps.maps3d.Marker3DElementOptions, "collisionBehavior" | "altitudeMode"> & Marker3DEventProps & { /** * Specifies how the altitude component of the position is interpreted. * @default AltitudeMode.CLAMP_TO_GROUND */ altitudeMode?: AltitudeMode; /** * An enumeration specifying how a Marker3DElement should behave when it * collides with another Marker3DElement or with the basemap labels. * @default CollisionBehavior.REQUIRED */ collisionBehavior?: CollisionBehavior; /** * Rollover text (only used when onClick is provided). */ title?: string; } & { children?: React.ReactNode | undefined; } & React.RefAttributes<google.maps.maps3d.Marker3DElement | google.maps.maps3d.Marker3DInteractiveElement>>; /** * Event props for the Popover component. */ type PopoverEventProps = { /** Called when the popover is closed via 'light dismiss' (click outside). */ onClose?: () => void; /** * Content to render in the header slot of the popover. */ headerContent?: ReactNode; }; /** * Props for the Popover component. */ type PopoverProps = PropsWithChildren<Omit<google.maps.maps3d.PopoverElementOptions, 'altitudeMode' | 'positionAnchor'> & PopoverEventProps & { /** * Specifies how the altitude component of the position is interpreted. * @default AltitudeMode.CLAMP_TO_GROUND */ altitudeMode?: AltitudeMode; /** * The position at which to display this popover. * Can be a LatLng position or LatLngAltitude position. */ position?: google.maps.LatLngLiteral | google.maps.LatLngAltitudeLiteral; /** * A Marker3DInteractiveElement to anchor the popover to. * When specified, the popover will be positioned relative to the marker. */ anchor?: google.maps.maps3d.Marker3DInteractiveElement | null; /** * A string ID referencing a Marker3DInteractiveElement to anchor the popover to. */ anchorId?: string; style?: CSSProperties; className?: string; }>; /** * Popover component for displaying info windows on a Map3D. * * Similar to InfoWindow for 2D maps, Popover provides a way to show * contextual information at a specific location or attached to a marker * on a 3D map. * * @example * ```tsx * // Basic popover at position * <Popover * position={{ lat: 37.7749, lng: -122.4194 }} * open={isOpen} * > * <div>Hello from San Francisco!</div> * </Popover> * * // Popover anchored to a marker (place as sibling, use anchor prop) * <Marker3D * ref={markerRef} * position={{ lat: 37.7749, lng: -122.4194 }} * onClick={() => setOpen(true)} * /> * <Popover * anchor={markerRef.current} * open={isOpen} * onClose={() => setOpen(false)} * > * <div>Marker info</div> * </Popover> * ``` */ declare const Popover: React.ForwardRefExoticComponent<Omit<google.maps.maps3d.PopoverElementOptions, "altitudeMode" | "positionAnchor"> & PopoverEventProps & { /** * Specifies how the altitude component of the position is interpreted. * @default AltitudeMode.CLAMP_TO_GROUND */ altitudeMode?: AltitudeMode; /** * The position at which to display this popover. * Can be a LatLng position or LatLngAltitude position. */ position?: google.maps.LatLngLiteral | google.maps.LatLngAltitudeLiteral; /** * A Marker3DInteractiveElement to anchor the popover to. * When specified, the popover will be positioned relative to the marker. */ anchor?: google.maps.maps3d.Marker3DInteractiveElement | null; /** * A string ID referencing a Marker3DInteractiveElement to anchor the popover to. */ anchorId?: string; style?: CSSProperties; className?: string; } & { children?: ReactNode | undefined; } & React.RefAttributes<google.maps.maps3d.PopoverElement>>; type StaticMapsLocation = google.maps.LatLngLiteral | string; type StaticMapsMarker = { location: StaticMapsLocation; color?: string; size?: 'tiny' | 'mid' | 'small'; label?: string; icon?: string; anchor?: string; scale?: 1 | 2 | 4; }; type StaticMapsPath = { coordinates: Array<StaticMapsLocation> | string; weight?: number; color?: string; fillcolor?: string; geodesic?: boolean; }; type StaticMapsApiOptions = { apiKey: string; width: number; height: number; center?: StaticMapsLocation; zoom?: number; scale?: number; format?: 'png' | 'png8' | 'png32' | 'gif' | 'jpg' | 'jpg-baseline'; mapType?: google.maps.MapTypeId; language?: string; region?: string; mapId?: string; markers?: Array<StaticMapsMarker>; paths?: Array<StaticMapsPath>; visible?: Array<StaticMapsLocation>; style?: google.maps.MapTypeStyle[]; }; /** * Creates a URL for the Google Static Maps API with the specified parameters. * * @param {Object} options - The configuration options for the static map * @param {string} options.apiKey - Your Google Maps API key (required) * @param {number} options.width - The width of the map image in pixels (required) * @param {number} options.height - The height of the map image in pixels (required) * @param {StaticMapsLocation} [options.center] - The center point of the map (lat/lng or address). * Required if no markers or paths or "visible locations" are provided. * @param {number} [options.zoom] - The zoom level of the map. Required if no markers or paths or "visible locations" are provided. * @param {1|2|4} [options.scale] - The resolution of the map (1, 2, or 4) * @param {string} [options.format] - The image format (png, png8, png32, gif, jpg, jpg-baseline) * @param {string} [options.mapType] - The type of map (roadmap, satellite, terrain, hybrid) * @param {string} [options.language] - The language of the map labels * @param {string} [options.region] - The region code for the map * @param {string} [options.map_id] - The Cloud-based map style ID * @param {StaticMapsMarker[]} [options.markers=[]] - Array of markers to display on the map * @param {StaticMapsPath[]} [options.paths=[]] - Array of paths to display on the map * @param {StaticMapsLocation[]} [options.visible=[]] - Array of locations that should be visible on the map * @param {MapTypeStyle[]} [options.style=[]] - Array of style objects to customize the map appearance * * @returns {string} The complete Google Static Maps API URL * * @throws {Error} If API key is not provided * @throws {Error} If width or height is not provided * * @example * const url = createStaticMapsUrl({ * apiKey: 'YOUR_API_KEY', * width: 600, * height: 400, * center: { lat: 40.714728, lng: -73.998672 }, * zoom: 12, * markers: [ * { * location: { lat: 40.714728, lng: -73.998672 }, * color: 'red', * label: 'A' * } * ], * paths: [ * { * coordinates: [ * { lat: 40.714728, lng: -73.998672 }, * { lat: 40.719728, lng: -73.991672 } * ], * color: '0x0000ff', * weight: 5 * } * ], * style: [ * { * featureType: 'road', * elementType: 'geometry', * stylers: [{color: '#00ff00'}] * } * ] * }); * * // Results in URL similar to: * // https://maps.googleapis.com/maps/api/staticmap?key=YOUR_API_KEY * // &size=600x400 * // &center=40.714728,-73.998672&zoom=12 * // &markers=color:red|label:A|40.714728,-73.998672 * // &path=color:0x0000ff|weight:5|40.714728,-73.998672|40.719728,-73.991672 * // &style=feature:road|element:geometry|color:0x00ff00 */ declare function createStaticMapsUrl({ apiKey, width, height, center, zoom, scale, format, mapType, language, region, mapId, markers, paths, visible, style }: StaticMapsApiOptions): string; /** * Props for the StaticMap component */ type StaticMapProps = { url: string; className?: string; }; declare const StaticMap: (props: StaticMapProps) => React.JSX.Element; type MapControlProps = PropsWithChildren<{ position: ControlPosition; className?: string; }>; /** * Copy of the `google.maps.ControlPosition` constants. * They have to be duplicated here since we can't wait for the maps API to load to be able to use them. */ declare const ControlPosition: { readonly TOP_LEFT: 1; readonly TOP_CENTER: 2; readonly TOP: 2; readonly TOP_RIGHT: 3; readonly LEFT_CENTER: 4; readonly LEFT_TOP: 5; readonly LEFT: 5; readonly LEFT_BOTTOM: 6; readonly RIGHT_TOP: 7; readonly RIGHT: 7; readonly RIGHT_CENTER: 8; readonly RIGHT_BOTTOM: 9; readonly BOTTOM_LEFT: 10; readonly BOTTOM_CENTER: 11; readonly BOTTOM: 11; readonly BOTTOM_RIGHT: 12; readonly CENTER: 13; readonly BLOCK_START_INLINE_START: 14; readonly BLOCK_START_INLINE_CENTER: 15; readonly BLOCK_START_INLINE_END: 16; readonly INLINE_START_BLOCK_CENTER: 17; readonly INLINE_START_BLOCK_START: 18; readonly INLINE_START_BLOCK_END: 19; readonly INLINE_END_BLOCK_START: 20; readonly INLINE_END_BLOCK_CENTER: 21; readonly INLINE_END_BLOCK_END: 22; readonly BLOCK_END_INLINE_START: 23; readonly BLOCK_END_INLINE_CENTER: 24; readonly BLOCK_END_INLINE_END: 25; }; type ControlPosition = (typeof ControlPosition)[keyof typeof ControlPosition]; declare const MapControl: FunctionComponent<MapControlProps>; type MarkerEventProps = { onClick?: (e: google.maps.MapMouseEvent) => void; onDrag?: (e: google.maps.MapMouseEvent) => void; onDragStart?: (e: google.maps.MapMouseEvent) => void; onDragEnd?: (e: google.maps.MapMouseEvent) => void; onMouseOver?: (e: google.maps.MapMouseEvent) => void; onMouseOut?: (e: google.maps.MapMouseEvent) => void; }; type MarkerProps = Omit<google.maps.MarkerOptions, 'map'> & MarkerEventProps; type MarkerRef = Ref<google.maps.Marker | null>; /** * Component to render a marker on a map */ declare const Marker: React.ForwardRefExoticComponent<Omit<google.maps.MarkerOptions, "map"> & MarkerEventProps & React.RefAttributes<google.maps.Marker>>; declare function useMarkerRef(): readonly [(m: google.maps.Marker | null) => void, google.maps.Marker | null]; /** * Props for the Pin component */ type PinProps = PropsWithChildren<google.maps.marker.PinElementOptions>; /** * Component to configure the appearance of an AdvancedMarker or Marker3D. * * Automatically detects the Maps API version and uses the appropriate implementation: * - Legacy implementation (< 3.62): Uses the original PinElement API with glyph property * - Modern implementation (≥ 3.62): Uses the new custom element API with glyphSrc/glyphText * * @example * ```tsx * // Basic usage * <AdvancedMarker position={{lat: 0, lng: 0}}> * <Pin background="#FF0000" glyphColor="#FFFFFF" /> * </AdvancedMarker> * * // With custom glyph (legacy) * <Pin glyph="📍" /> * * // With custom glyph (modern, recommended for Maps API 3.62+) * <Pin glyphText="📍" /> * <Pin glyphSrc="https://example.com/icon.png" /> * * // With React children as glyph * <Pin> * <CustomIcon /> * </Pin> * ``` */ declare const Pin: FunctionComponent<PinProps>; type RectangleEventProps = { onClick?: (e: google.maps.MapMouseEvent) => void; onDrag?: (e: google.maps.MapMouseEvent) => void; onDragStart?: (e: google.maps.MapMouseEvent) => void; onDragEnd?: (e: google.maps.MapMouseEvent) => void; onMouseOver?: (e: google.maps.MapMouseEvent) => void; onMouseOut?: (e: google.maps.MapMouseEvent) => void; onBoundsChanged?: (bounds: google.maps.LatLngBounds | null | undefined) => void; }; type RectangleProps = Omit<google.maps.RectangleOptions, 'map' | 'bounds'> & RectangleEventProps & { /** Controlled bounds */ bounds?: google.maps.LatLngBoundsLiteral | google.maps.LatLngBounds; /** Uncontrolled initial bounds */ defaultBounds?: google.maps.LatLngBoundsLiteral | google.maps.LatLngBounds; }; type RectangleRef = Ref<google.maps.Rectangle | null>; declare const Rectangle: React.ForwardRefExoticComponent<Omit<google.maps.RectangleOptions, "map" | "bounds"> & RectangleEventProps & { /** Controlled bounds */ bounds?: google.maps.LatLngBoundsLiteral | google.maps.LatLngBounds; /** Uncontrolled initial bounds */ defaultBounds?: google.maps.LatLngBoundsLiteral | google.maps.LatLngBounds; } & React.RefAttributes<google.maps.Rectangle>>; declare function useApiLoadingStatus(): APILoadingStatus; /** * Hook to check if the Maps JavaScript API is loaded */ declare function useApiIsLoaded(): boolean; type LibraryName = keyof google.maps.ImportLibraryMap; declare function useMapsLibrary<K extends LibraryName>(name: K): google.maps.ImportLibraryMap[K] | null; /** * Retrieves a map-instance from the context. This is either an instance * identified by id or the parent map instance if no id is specified. * Returns null if neither can be found. */ declare const useMap: (id?: string | null) => google.maps.Map | null; /** * Hook to retrieve a Map3DElement instance from context. * * When called without an id, it returns the map from the nearest parent Map3D * component. When called with an id, it retrieves the map with that id from * the APIProvider context. * * @param id - Optional id of the map to retrieve. If not specified, returns * the parent map instance or the default map instance. * * @example * ```tsx * // Get the parent Map3D instance * function MyComponent() { * const map3d = useMap3D(); * // ... * } * * // Get a specific Map3D instance by id * function ControlPanel() { * const mainMap = useMap3D('main-map'); * const miniMap = useMap3D('mini-map'); * // ... * } * ``` */ declare function useMap3D(id?: string | null): google.maps.maps3d.Map3DElement | null; declare function isLatLngLiteral(obj: unknown): obj is google.maps.LatLngLiteral; declare function latLngEquals(a: google.maps.LatLngLiteral | google.maps.LatLng | undefined | null, b: google.maps.LatLngLiteral | google.maps.LatLng | undefined | null): boolean; declare function toLatLngLiteral(obj: google.maps.LatLngLiteral | google.maps.LatLng): google.maps.LatLngLiteral; declare function toLatLngBoundsLiteral(obj: google.maps.LatLngBoundsLiteral | google.maps.LatLngBounds): google.maps.L