-
Notifications
You must be signed in to change notification settings - Fork 105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add onClick event for map #52
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First of all, thanks so much for taking the time and contributing to this project. Also congratulations, you are the very first outside contributor here 🎉
Adding the map-events was actually something that I had on my todo list for the next week, but I would be more than happy to hand this task over to you or collaborate in this PR to get it done.
I left a number of comments for you to consider with the overall vision for the event-support in mind. If you need any help, feel free to let me know, otherwise I'd try to pick it up from here and add to this PR.
@@ -127,6 +127,7 @@ interface MapProps extends google.maps.MapOptions { | |||
id?: string; | |||
style?: CSSProperties; | |||
className?: string; | |||
onClick?: (event: google.maps.Map) => void; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the events we add here should use the same signatures as the events defined in the google maps API, see here: https://developers.google.com/maps/documentation/javascript/reference/map#Map-Events
At least for now I don't think we need anything on top of providing a props-version for the events coming from the maps-API.
So in this case that would be
onClick?: (event: google.maps.Map) => void; | |
onClick?: (event: google.maps.MapMouseEvent | google.maps.MapIconEvent) => void; |
/** | ||
* Callback function that is called when the map is clicked | ||
*/ | ||
onClick?: (event: google.maps.Map) => void; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see my note above:
onClick?: (event: google.maps.Map) => void; | |
onClick?: (event: google.maps.MapMouseEvent | google.maps.MapIconEvent) => void; |
}; | ||
|
||
/** | ||
* Component to render a Google Maps map | ||
*/ | ||
export const Map = (props: PropsWithChildren<MapProps>) => { | ||
export const Map = (props: MapProps & ComponentPropsWithRef<'div'>) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite understand why this is added here. As far as I understand it, ComponentPropsWithRef
is supposed to be used when a component wraps a regular HTML-element, but that isn't what is happening here.
If anything, we're wrapping the google.maps.Map
instance (using forwardRef
to expose the map-object is something I wanted to add).
@@ -160,6 +165,14 @@ function useMapInstanceHandlerEffects( | |||
}); | |||
} | |||
|
|||
if (onClick) { | |||
google.maps.event.addListenerOnce(newMap, 'idle', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the reasoning for waiting for the idle-event before adding the click-event?
@@ -160,6 +165,14 @@ function useMapInstanceHandlerEffects( | |||
}); | |||
} | |||
|
|||
if (onClick) { | |||
google.maps.event.addListenerOnce(newMap, 'idle', () => { | |||
google.maps.event.addListener(newMap, 'click', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is missing some code to remove the event-listener on unmount. For this, we could store the returned google.maps.MapsEventListener
object and call it's remove()
method.
Since there's going to be a lot of events, I think this should be extracted into a separate internal hook (for example useMapEventHandlers()
that takes care of adding and removing event-handlers based on the props. Something similar has been done in src/components/advanced-marker.tsx.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's going to be a lot more events added and I would like to have a single example to demonstrate them. With that in mind, could you rename the example to map-events
or similar?
As for the unit-tests, that's a bit complicated since we don't actually have a real map-instance to work with (everything google-maps related comes from the What we need to do here is to mock emitting the events, which can get a bit complicated. I'd try the following:
Something similar can be done to validate that event-listeners are removed on unmount and re-render. Unfortunately we need to be very specific here about which parts of the maps-api are used since the |
@usefulthink Thank you Martin for the feedback. I will pick it up and will revert. |
I'm very sorry for this, but I had to move on with this topic since it's one of the biggest bits of functionality currently missing. The implementation for full event-support is almost ready in this PR: #64 |
Still missing tests and documentation, but the main functionality for events is now merged and available in v0.3. |
No worries! I have been quite busy recently so it was hard to take time out. Appreciate the update as you went along. I will be glad to contribute to any other parts of this repo! |
Hi,
This PR adds
onClick
event support for the map. This addresses the #49.As part of this PR I have:
Unit tests
I have tried to put a basic unit test but it just won't work so I would appreciate the help/feedback with this. Here is the example I tried with: