reactjsgoogle-mapsgoogle-placeschakra-ui

StopPropagation react google maps autocomplete


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>

Solution

  • 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>
        </>
      );
    }