UNPKG

google-maps-react-markers

Version:

Google Maps library that accepts markers as react components, works with React 18+ and it is fully typed.

229 lines (182 loc) 13.5 kB
<h1 align="center">Google Maps React Markers</h1> <p align="center"> <a href="https://www.npmjs.com/package/google-maps-react-markers" target="_blank"> <img src="https://img.shields.io/npm/v/google-maps-react-markers.svg?style=for-the-badge&labelColor=000000" alt="NPM" /> </a> <a href="https://npm-stat.com/charts.html?package=google-maps-react-markers" target="_blank"> <img src="https://img.shields.io/npm/dt/google-maps-react-markers.svg?style=for-the-badge&labelColor=000000" alt="NPM total downloads" title="last year"> </a> <img src="https://img.shields.io/badge/Maintained%3F-yes-green.svg?style=for-the-badge&labelColor=000000" alt="Maintained" /> <a href="https://github.com/giorgiabosello/google-maps-react-markers/blob/master/LICENCE.md" target="_blank"> <img src="https://img.shields.io/github/license/giorgiabosello/google-maps-react-markers?style=for-the-badge&labelColor=000000" alt="GitHub license: MIT" /> </a> <img src="https://img.shields.io/github/stars/giorgiabosello/google-maps-react-markers?style=for-the-badge&labelColor=000000" alt="GitHub stars" /> <a href="https://github.com/giorgiabosello/google-maps-react-markers/issues" target="_blank"> <img src="https://img.shields.io/github/issues/giorgiabosello/google-maps-react-markers?style=for-the-badge&labelColor=000000" alt="GitHub open issues" /> </a> <a href="https://makeapullrequest.com/"> <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge&labelColor=000000" alt="PRs welcome" /> </a> </p> Google Maps library that accepts markers as react components and works with React 18+. It supports a small set of the props of [Google Map React](https://github.com/google-map-react/google-map-react). Clustering also is possible. The library implements [Google Maps Custom Overlays](https://developers.google.com/maps/documentation/javascript/customoverlays) official library. **If you like this library, please consider supporting me ❤️** [![Buy me a Coffee](https://img.shields.io/badge/Buy_Me_A_Coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/giorgiabosello) [![PayPal](https://img.shields.io/badge/PayPal-00457C?style=for-the-badge&logo=paypal&logoColor=white)](https://www.paypal.me/giorgiabosello) ## 💬 Discussion > **Released TypeScript version of the library!** Feedbacks are welcome in [this discussion](https://github.com/giorgiabosello/google-maps-react-markers/discussions/109). ## 🚀 Demo <a href="https://giorgiabosello.github.io/google-maps-react-markers/" target="blank"> <img src="https://img.shields.io/website?url=https%3A%2F%2Fgiorgiabosello.github.io%2Fgoogle-maps-react-markers&logo=github&style=for-the-badge&labelColor=000000" /> </a> See it in action [here](https://giorgiabosello.github.io/google-maps-react-markers/) _(API KEY not provided)_. Demo source code is available [here](https://github.com/giorgiabosello/google-maps-react-markers/tree/master/docs/src). ## 🛠 Install ```bash pnpm add google-maps-react-markers ``` or ```bash yarn add google-maps-react-markers ``` or ```bash npm install --save google-maps-react-markers ``` ## 💻 Usage ```jsx import GoogleMap from 'google-maps-react-markers' const App = () => { const mapRef = useRef(null) const [mapReady, setMapReady] = useState(false) /** * @description This function is called when the map is ready * @param {Object} map - reference to the map instance * @param {Object} maps - reference to the maps library */ const onGoogleApiLoaded = ({ map, maps }) => { mapRef.current = map setMapReady(true) } const onMarkerClick = (e, { markerId, lat, lng }) => { console.log('This is ->', markerId) // inside the map instance you can call any google maps method mapRef.current.setCenter({ lat, lng }) // ref. https://developers.google.com/maps/documentation/javascript/reference?hl=it } return ( <> {mapReady && <div>Map is ready. See for logs in developer console.</div>} <GoogleMap apiKey="" defaultCenter={{ lat: 45.4046987, lng: 12.2472504 }} defaultZoom={5} options={mapOptions} mapMinHeight="100vh" onGoogleApiLoaded={onGoogleApiLoaded} onChange={(map) => console.log('Map moved', map)} > {coordinates.map(({ lat, lng, name }, index) => ( <Marker key={index} lat={lat} lng={lng} markerId={name} onClick={onMarkerClick} // you need to manage this prop on your Marker component! // draggable={true} // onDragStart={(e, { latLng }) => {}} // onDrag={(e, { latLng }) => {}} // onDragEnd={(e, { latLng }) => {}} /> ))} </GoogleMap> </> ) } export default App ``` ## 🧐 Props ### GoogleMap component | Prop | Type | Required | Default | Description | | -------------------- | -------- | -------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **apiKey** | string | **yes** | `''` | API Key to load Google Maps | | **defaultCenter** | object | **yes** | `{ lat: 0, lng: 0 }` | Default center of the map | | **defaultZoom** | number | **yes** | `1-20` | Default zoom of the map | | libraries | array | no | `['places', 'geometry']` | Libraries to load | | options | object | no | `{}` | Options for the map | | onGoogleApiLoaded | function | no | `() => {}` | Callback when the map is loaded | | onChange | function | no | `() => {}` | Callback when the map has changed | | events | array | no | `[]` | Array of objects name/handler of [DOM events](https://en.wikipedia.org/wiki/DOM_event) to pass down to the `div` overlay. Example: `events: [{ name: 'onClick', handler: () => {} }]` | | children | node | no | `null` | Markers of the map | | loadScriptExternally | bool | no | `false` | Whether to load the Google Maps script externally.<br>If `true`, the `status` prop is required and it will be used to control the loading of the script | | status | string | no | `idle` | The forced status of the Google Maps script. Depends on `loadScriptExternally`.<br>It can be one of `idle`, `loading`, `ready`, `error` | | loadingContent | node | no | `'Google Maps is loading'` | Content to show while the map is loading | | idleContent | node | no | `'Google Maps is on idle'` | Content to show when the map is idle | | errorContent | node | no | `'Google Maps is on error'` | Content to show when the map has an error | | mapMinHeight | string | no | `'unset'` | Min height of the map | | containerProps | object | no | `{}` | Props for the div container of the map | | scriptCallback | function | no | `() => {}` | window global callback passed to the Google Script | | externalApiParams | object | no | `undefined` | Optional params to pass to the Google API script. Eg. `{region: 'IT', language: 'it'}` | ### Markers | Prop | Type | Required | Default | Description | | ----------- | ------ | -------- | ----------- | -------------------------------------------------------------------------------------------------------- | | **lat** | number | **yes** | `undefined` | Latitude of the marker | | **lng** | number | **yes** | `undefined` | Longitude of the marker | | draggable | bool | no | `false` | If true, the marker can be dragged | | onDragStart | func | no | `() => {}` | This event is fired when the user starts dragging the marker | | onDrag | func | no | `() => {}` | This event is repeatedly fired while the user drags the marker | | onDragEnd | func | no | `() => {}` | This event is fired when the user stops dragging the marker | | zIndex | number | no | 0 | The z-index of the marker. To bring the marker to the front, e.g. when it is active, set a higher value. | ## 📍 Clustering For clustering, follow this [guide](https://www.leighhalliday.com/google-maps-clustering) using [useSupercluster Hook](https://github.com/leighhalliday/use-supercluster), but use bounds in this way: ```jsx const [mapBounds, setMapBounds] = useState({ bounds: [0, 0, 0, 0], zoom: 0, }) const onMapChange = ({ bounds, zoom }) => { const ne = bounds.getNorthEast() const sw = bounds.getSouthWest() /** * useSupercluster accepts bounds in the form of [westLng, southLat, eastLng, northLat] * const { clusters, supercluster } = useSupercluster({ * points: points, * bounds: mapBounds.bounds, * zoom: mapBounds.zoom, * }) */ setMapBounds({ ...mapBounds, bounds: [sw.lng(), sw.lat(), ne.lng(), ne.lat()], zoom }) } ``` ## 👥 Contributing To run the project locally, clone the repo and run: ```bash # in the root directory yarn --frozen-install yarn dev ``` ```bash # in another tab (with NextJS and SSR) cd docs yarn install yarn dev ``` Do your changes to `src/` or `docs/src` directory, commits all files in the root directory (`yarn.lock` and ones in `dist` too) and open a PR. ## 💻 Built with - [React](https://reactjs.org/) - [TypeScript](https://www.typescriptlang.org/) - [Google Maps Custom Overlays](https://developers.google.com/maps/documentation/javascript/customoverlays) - [tsup](https://github.com/egoist/tsup): for bundling - [ESLint](https://eslint.org/): for linting - [Prettier](https://prettier.io/): for code formatting ## 🗒 License MIT © [giorgiabosello](https://github.com/giorgiabosello) ## 🙏 Support [![Buy me a Coffee](https://img.shields.io/badge/Buy_Me_A_Coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/giorgiabosello) [![PayPal](https://img.shields.io/badge/PayPal-00457C?style=for-the-badge&logo=paypal&logoColor=white)](https://www.paypal.me/giorgiabosello) <hr> <p align="center"> Developed with ❤️ in Italy 🇮🇹 </p>