{"id":22340843,"url":"https://github.com/fredrikaugust/atlas","last_synced_at":"2026-05-06T15:45:27.514Z","repository":{"id":41727759,"uuid":"235522400","full_name":"FredrikAugust/atlas","owner":"FredrikAugust","description":"A Google Maps React library. Written because I was dissatisfied with fullstackreact/google-maps-react. Will have focus on minimal rerenders, and trying to rely as much as possible on the Google Maps Javascript API (v3).","archived":false,"fork":false,"pushed_at":"2022-12-11T21:33:03.000Z","size":2740,"stargazers_count":2,"open_issues_count":18,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-09T14:51:22.004Z","etag":null,"topics":["gmaps","google-api","google-maps","google-maps-javascript","maps","react","typescript"],"latest_commit_sha":null,"homepage":"https://fredrikaugust.github.io/atlas/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FredrikAugust.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-01-22T07:38:43.000Z","updated_at":"2024-04-09T12:48:01.000Z","dependencies_parsed_at":"2023-01-27T07:30:55.173Z","dependency_job_id":null,"html_url":"https://github.com/FredrikAugust/atlas","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/FredrikAugust/atlas","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FredrikAugust%2Fatlas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FredrikAugust%2Fatlas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FredrikAugust%2Fatlas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FredrikAugust%2Fatlas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FredrikAugust","download_url":"https://codeload.github.com/FredrikAugust/atlas/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FredrikAugust%2Fatlas/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272612196,"owners_count":24964388,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-29T02:00:10.610Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gmaps","google-api","google-maps","google-maps-javascript","maps","react","typescript"],"created_at":"2024-12-04T07:42:04.570Z","updated_at":"2026-05-06T15:45:27.466Z","avatar_url":"https://github.com/FredrikAugust.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Atlas\n\n![atlas the greek god](https://publicdomainvectors.org/photos/atlas-god.png)\n\n\u003e A Google Maps React library. Written because I was dissatisfied with fullstackreact/google-maps-react. Will have focus on minimal rerenders, and trying to rely as much as possible on the Google Maps Javascript API (v3).\n\n[![NPM](https://img.shields.io/npm/v/reactive-atlas.svg)](https://www.npmjs.com/package/reactive-atlas) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)\n\n**[Live demo](https://fredrikaugust.github.io/atlas/)**\n\n#### Notes\n\n- `google.maps.LatLngLiteral` is just an object of type `{ lat: number, lng: number }`\n\n## Install\n\n```bash\nyarn add reactive-atlas\n```\n\n## Usage\n\n### API Provider\n\nFirst of all, you have to setup the global API provider. This is required by\nthe library to work. I recommend you wrap the highest common component of all\ncomponents that require access to the map with this.\n\n```tsx\nimport { GoogleAPIProvider } from \"reactive-atlas\";\n\nconst Root: React.FC = props =\u003e (\n  \u003cGoogleAPIProvider apiKey=\"API_KEY\"\u003e{props.children}\u003c/GoogleAPIProvider\u003e\n);\n```\n\n### `useGoogle`\n\nThis is a hook that returns a `google` object containing all the methods\nexposed to us. Has to be used in a component that is a child of\n`GoogleAPIProvider`;\n\n```tsx\nimport { useGoogle } from \"reactive-atlas\";\n\nconst ComponentThatUsesGoogleAPI: React.FC = props =\u003e {\n  const google = useGoogle();\n\n  // ...\n};\n```\n\n### Map\n\nThe map is the most important object. It has to be a child (though not\ndirect) of `GoogleAPIProvider`.\n\nThe **required** options are `zoom` and `center`. A `number` (0-18 inclusive),\nand `google.maps.LatLng` or `google.maps.LatLngLiteral`, respectively.\n\n```tsx\nimport { Map, useGoogle } from \"reactive-atlas\";\n\nconst Globus = () =\u003e {\n  const google = useGoogle();\n\n  return \u003cMap options={{ zoom: 8, center: new google.maps.LatLng(1, 2) }} /\u003e;\n};\n```\n\nAll `Marker`s and other elements should be children of a map, and you should not nest `Map`s.\n\n### Marker\n\nThe marker is a common object in maps. It has to be a child of a `Map`.\n\n```tsx\nimport { Map, Marker, useGoogle } from \"reactive-atlas\";\n\nconst Globus = () =\u003e {\n  const google = useGoogle();\n\n  return (\n    \u003cMap options={{ zoom: 8, center: new google.maps.LatLng(1, 2) }}\u003e\n      \u003cMarker\n        options={{\n          position: new google.maps.LatLng(63, 10),\n          title: \"Hello, World!\",\n          label: \"B\"\n        }}\n      /\u003e\n    \u003c/Map\u003e\n  );\n};\n```\n\n### InfoWindow (and ref forwarding)\n\nThe InfoWindow can be handy if you want to display extra information about e.g. a `Marker`.\n\n```tsx\nimport { InfoWindow, Marker, Map, useGoogle } from \"reactive-atlas\";\n\nconst IWExample = () =\u003e {\n  const ref = React.useRef\u003cMarker\u003e();\n  const [open, setOpen] = React.useState(false);\n\n  return (\n    \u003cMap options={{ zoom: 8, center: new google.maps.LatLng(1, 2) }}\u003e\n      \u003cMarker\n        ref={ref}\n        options={{\n          position: new google.maps.LatLng(63, 10),\n          title: \"Hello, World!\",\n          label: \"B\"\n        }}\n        eventHandlers={[[\"click\", () =\u003e setOpen(o =\u003e !o)]]}\n      /\u003e\n\n      \u003cInfoWindow\n        open={open}\n        setOpen={setOpen}\n        anchor={() =\u003e ref.current.marker}\n      \u003e\n        \u003cp\u003eHello, World!\u003c/p\u003e\n      \u003c/InfoWindow\u003e\n    \u003c/Map\u003e\n  );\n};\n```\n\nAs you can see, you can pass a ref to the `Marker`, and later get out the\nunderlying `marker` property.\n\n### Circle\n\nExactly the same usage as `Marker`.\n\nRequired `option` keys are `radius: number`, and `center: google.maps.LatLng | google.maps.LatLngLiteral`.\n\n```tsx\nimport { Map, Circle, useGoogle } from \"reactive-atlas\";\n\nconst Globus = () =\u003e {\n  const google = useGoogle();\n\n  return (\n    \u003cMap options={{ zoom: 8, center: new google.maps.LatLng(1, 2) }}\u003e\n      \u003cCircle\n        options={{\n          center: new google.maps.LatLng(63, 10),\n          radius: 128000\n        }}\n      /\u003e\n    \u003c/Map\u003e\n  );\n};\n```\n\n#### Example of resizable and movable circle\n\nFirst you have to wrap it in a Provider and Map of course.\n\nCreate an event handler which simply prints the new location and radius.\n\n```ts\nconst circleChangePosRadius = circle =\u003e\n  console.log(\n    `Circle is at ${circle\n      .getCenter()\n      .toString()} with radius ${circle.getRadius()}.`\n  );\n```\n\nWire it up to print pos/radius every time the radius or center changes.\n\n```tsx\n\u003cCircle\n  options={{\n    editable: true,\n    radius: 100000,\n    center: new google.maps.LatLng(63, 10)\n  }}\n  eventHandlers={[\n    [\"radius_changed\", circleChangePosRadius],\n    [\"center_changed\", circleChangePosRadius]\n  ]}\n/\u003e\n```\n\nThe same principles would be used when making a `Marker` draggable; just\nreplace `radius_changed`/`center_changed` with `dragend`.\n\n### Events\n\nTo retain as much of the original code as possible from the google API, I've\ndecided to opt for a bit strange event handling. Instead of doing like\n`google-maps-react` (the reason I'm making this library) and using \"standard\"\nHTML-like handlers (i.e. `onCenter_changed` (the weird combination of\ncamelCase and snake_case is because google uses snake-case, and HTML uses\ncamelCase)), I've opted to use a list of event handlers you'd like to attach\nto the element. This property can be used on `Map`, `Marker`, and `Circle`\n(as of now).\n\nTo remove an event handler, simply remove the entry from the array of\nhandlers, and the library will remove the listener. It will also clean up all\nlisteners when unmounting.\n\nThe first parameter in the callback function is the object you're operating\non, so in the next example, it's a marker, but if you were to add a listener\nto a circle, it would be the circle. This allows you to operate directly on\nthe google API, which might be desirable.\n\nThe second parameter is a list with one of the following;\n\n1. Nothing, i.e. `[]`\n2. `undefined`, i.e. `[undefined]`\n3. The event (e.g. `MouseEvent`), i.e. `[MouseEvent]`\n\nThis is a bit strange, but it works quite well. I believe it was intended for\npossible expansion, so that you could pass more than one event.\n\n```tsx\nimport { Map, Marker, useGoogle } from \"reactive-atlas\";\n\nconst Globus = () =\u003e {\n  const google = useGoogle();\n\n  return (\n    \u003cMap options={{ zoom: 8, center: new google.maps.LatLng(1, 2) }}\u003e\n      \u003cMarker\n        options={{\n          position: new google.maps.LatLng(pos, pos)\n        }}\n        eventHandlers={[\n          [\n            \"click\",\n            (marker, evt) =\u003e {\n              // Make it jump!\n              marker.setAnimation(google.maps.Animation.BOUNCE);\n              setTimeout(() =\u003e marker.setAnimation(null), 500);\n            }\n          ]\n        ]}\n      /\u003e\n    \u003c/Map\u003e\n  );\n};\n```\n\n### Bounds\n\nOften times, you want to specify the bounds of the place you want to see.\n\nYou can do this using the `bounds` prop on `Map`. Simply send in a\n`google.maps.LatLngBounds | google.maps.LatLngBoundsLiteral` object, and it\nwill scale to that area. If you change the `bounds`, the map will fit to the\nnew area and pan there.\n\n### Styling\n\nFor now, there isn't really much styling on the map. It's container is set to\n`flex-grow: 1`, which means that you should try to use flex to control the\npositioning.\n\n## License\n\nMIT © [fredrikaugust](https://github.com/fredrikaugust)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffredrikaugust%2Fatlas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffredrikaugust%2Fatlas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffredrikaugust%2Fatlas/lists"}