I would like to stopPropagation of https://react-google-maps-api-docs.netlify.app/#autocomplete.
The autocomplete works well but I need to use it in a popover and when I select a place the popover automatically closes.
If there is another library that works well with popovers and modals
const [autocomplete, setAutocomplete] = useState<any>(null);
const onLoad = (auto: any) => {
if (!autocomplete) {
setAutocomplete(auto);
}
};
const onPlaceChanged = () => {
if (autocomplete) {
console.log(autocomplete?.getPlace());
} else {
console.log('Autocomplete is not loaded yet!');
}
};
<Autocomplete
onLoad={onLoad}
onPlaceChanged={onPlaceChanged}
>
<chakra.input
type='text'
as={Input}
placeholder='Customized your placeholder'
style={{
boxSizing: `border-box`,
border: `1px solid transparent`,
width: `240px`,
height: `32px`,
padding: `0 12px`,
borderRadius: `3px`,
boxShadow: `0 2px 6px rgba(0, 0, 0, 0.3)`,
fontSize: `14px`,
outline: `none`,
textOverflow: `ellipses`,
position: 'absolute',
left: '50%',
marginLeft: '-120px',
animationName: 'none',
zIndex: 9999,
}}
/>
</Autocomplete>
I'm using chakraUI, I get help from discord(dodas user) here is the solution he make. Basically he catch the mousedown event(google block click event) and when the popover is open, select item or click trigger button just do nothing for others events just close popovers.
https://codesandbox.io/s/popovergoogle-autocomplete-6nvtb?file=/src/App.js:0-3329
import React, { useState, useEffect, useRef } from "react";
import {
Button,
Stack,
Popover,
PopoverTrigger,
PopoverContent,
PopoverHeader,
PopoverBody,
PopoverArrow,
PopoverCloseButton,
Box,
Portal,
PopoverFooter,
useRadioGroup,
useRadio
} from "@chakra-ui/core";
import { useEvent } from "react-use";
import {
GoogleMap,
useJsApiLoader,
Autocomplete
} from "@react-google-maps/api";
let autoComplete;
export function App() {
const { isLoaded, loadError } = useJsApiLoader({
googleMapsApiKey: "YOUR_KEY", // ,
libraries: ["places"]
// ...otherOptions
});
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const openPopover = () => setIsPopoverOpen(true);
const closePopover = () => setIsPopoverOpen(false);
const triggerRef = useRef(null);
const popoverContentRef = useRef(null);
const [autocomplete, setAutocomplete] = useState(null);
const onLoad = (autocompleteInstance) => {
console.log("autocomplete: ", autocomplete);
setAutocomplete(autocompleteInstance);
};
const onPlaceChanged = () => {
if (autocomplete) {
console.log(autocomplete.getPlace());
} else {
console.log("Autocomplete is not loaded yet!");
}
};
useEvent("mousedown", (ev) => {
if (!isPopoverOpen) {
return;
}
const clickedInsideTrigger = triggerRef.current.contains(ev.target);
const clickedInsidePopover = popoverContentRef.current.contains(ev.target);
const clickedInsideAutocomplete =
ev.target.closest(".pac-container") != null;
if (
clickedInsideTrigger ||
clickedInsidePopover ||
clickedInsideAutocomplete
) {
return;
}
closePopover();
});
return (
<>
<Box width="100vw" height="100vh">
<Popover
isOpen={isPopoverOpen}
onOpen={openPopover}
onClose={closePopover}
closeOnBlur={false}
isLazy
placement="bottom-end"
>
<PopoverTrigger>
<Button ref={triggerRef}>Trigger</Button>
</PopoverTrigger>
<PopoverContent ref={popoverContentRef}>
<PopoverArrow />
<PopoverCloseButton />
<PopoverHeader>Confirmation!</PopoverHeader>
<PopoverBody minH="20rem">
{isLoaded && (
<Autocomplete onLoad={onLoad} onPlaceChanged={onPlaceChanged}>
<input
type="text"
placeholder="Customized your placeholder"
style={{
boxSizing: `border-box`,
border: `1px solid transparent`,
width: `240px`,
height: `32px`,
padding: `0 12px`,
borderRadius: `3px`,
boxShadow: `0 2px 6px rgba(0, 0, 0, 0.3)`,
fontSize: `14px`,
outline: `none`,
textOverflow: `ellipses`,
position: "absolute",
left: "50%",
marginLeft: "-120px"
}}
/>
</Autocomplete>
)}
</PopoverBody>
</PopoverContent>
</Popover>
</Box>
</>
);
}