FusionWorks / react-admin-google-maps

28 stars 11 forks source link

Consider updating google maps package to react-google-maps-api #7

Open UltimateForm opened 4 years ago

UltimateForm commented 4 years ago

react-google-maps-api

Why? react-google-maps has been unmaintained for 2 years and every new issue seems to be followed by this https://github.com/tomchentw/react-google-maps/issues/1020#issuecomment-562797063

I've tested react-google-maps-api on my side and it works quite well with new react-admin version, most importantly 3.0.0

here's an example implementation of a viewer (i've written the input as well but it's a bit longer and dirtier):

/* eslint-disable */
import React from "react";
import {
    GoogleMap,
    Data,
    GoogleMapProps,
    DataProps,
    useLoadScript,
} from "@react-google-maps/api";
import { googleMapsApiKey } from "../config";
var debug = require("debug")("app:components:googlemaps");

const defaultCenter = {
    lat: 38.805470223177466,
    lng: -118.76220703125
};

interface IGoogleMapsProps {
    apiKey?: string;
    center?: typeof defaultCenter;
    ignoreUserLocation?: boolean;
    mapContainerStyle?: any;
    mapProps?: Partial<GoogleMapProps>;
    dataProps?: Partial<DataProps>;
    children?: any;
    onClick?: (e: any) => void;
    onLoad?: (map: any) => void;
}

const Map: React.FC<IGoogleMapsProps> = (props: IGoogleMapsProps) => {
    const {
        apiKey,
        center,
        children,
        mapProps,
        dataProps,
        onClick,
        onLoad,
        ignoreUserLocation
    } = props;
    const { isLoaded, loadError } = useLoadScript({
        googleMapsApiKey: apiKey || googleMapsApiKey
    });
    const G = React.useRef<any>(undefined);
    const MAP = React.useRef<any>(undefined);
    if (!G.current) {
        G.current = (window as any).google;
    }
    const centerValid = typeof center === "object" && center.lat && center.lng;
    React.useMemo(() => {
        if (centerValid || ignoreUserLocation) return;
        navigator.geolocation.getCurrentPosition(
            pos => {
                if (MAP.current)
                    MAP.current.panTo({
                        lat: pos.coords.latitude,
                        lng: pos.coords.longitude
                    });
                else {
                    defaultCenter.lat = pos.coords.latitude;
                    defaultCenter.lng = pos.coords.longitude;
                }
            },
            error => {
                console.error("ERROR RETRIEVING USER LOCATION", error);
            }
        );
    }, []);
    return isLoaded ? (
        <GoogleMap
            zoom={16}
            id="google-map"
            center={centerValid ? center : defaultCenter}
            mapContainerStyle={{ width: "100%", height: "100%" }}
            {...mapProps}
            onClick={e => {
                if (MAP.current) {
                    MAP.current.panTo(e.latLng);
                    onClick && onClick(e);
                }
            }}
            onLoad={map => {
                MAP.current = map;
                onLoad && onLoad(MAP.current);
            }}
        >
            <Data {...dataProps} />
            {children}
        </GoogleMap>
    ) : (
        <div>loadError</div>
    );
};

export default Map;
MathiasBerwig commented 4 years ago

i've written the input as well but it's a bit longer and dirtier

@UltimateForm would you mind sharing it as well?

AdamDocherty commented 4 years ago

@UltimateForm - +2 for what @MathiasBerwig said!

UltimateForm commented 4 years ago

@MathiasBerwig
https://codesandbox.io/s/wizardly-dijkstra-6br6x (you will need to set your google maps API key at config.js)

this is a somewhat rushed impl, but still better than what i have locally (mine has other extra stuff like geoHash conversion i.e). Everything you need is at the "googleMaps" folder and the forms on post/index.tsx, the rest is just what I copied from react-admin's demo

UltimateForm commented 4 years ago

@MathiasBerwig @AdamDocherty also note that on my impl i separated the input from the map viewer because at some points I need only the viewer, a purely input usage can combine the two for better readability

m7xedhoward commented 3 years ago

@UltimateForm Great work, could you please share a { PostShow } example