import type { FC, ChangeEvent } from "react"; import { KeyboardEvent, useState } from "react"; import usePlacesAutocomplete from "use-places-autocomplete"; import useOnclickOutside from "react-cool-onclickoutside"; import GitHubCorner from "../GitHubCorner"; import styles from "./styles.module.scss"; let cachedVal = ""; const acceptedKeys = ["ArrowUp", "ArrowDown", "Escape", "Enter"]; type Suggestion = google.maps.places.AutocompletePrediction; const App: FC = () => { const [currIndex, setCurrIndex] = useState(null); const { ready, value, suggestions: { status, data }, setValue, clearSuggestions, } = usePlacesAutocomplete({ callbackName: "initMap" }); const hasSuggestions = status === "OK"; const dismissSuggestions = () => { setCurrIndex(null); clearSuggestions(); }; const ref = useOnclickOutside(dismissSuggestions); const handleInput = (e: ChangeEvent) => { setValue(e.target.value); cachedVal = e.target.value; }; const handleSelect = ({ description }: Suggestion) => () => { setValue(description, false); dismissSuggestions(); }; const handleEnter = (idx: number) => () => { setCurrIndex(idx); }; const handleLeave = () => { setCurrIndex(null); }; const handleKeyDown = (e: KeyboardEvent) => { if (!hasSuggestions || !acceptedKeys.includes(e.key)) return; if (e.key === "Enter" || e.key === "Escape") { dismissSuggestions(); return; } let nextIndex: number | null; if (e.key === "ArrowUp") { e.preventDefault(); nextIndex = currIndex ?? data.length; nextIndex = nextIndex && nextIndex > 0 ? nextIndex - 1 : null; } else { nextIndex = currIndex ?? -1; nextIndex = nextIndex < data.length - 1 ? nextIndex + 1 : null; } setCurrIndex(nextIndex); // @ts-ignore setValue(data[nextIndex] ? data[nextIndex].description : cachedVal, false); }; const renderSuggestions = (): JSX.Element => { const suggestions = data.map((suggestion: Suggestion, idx: number) => { const { place_id, structured_formatting: { main_text, secondary_text }, } = suggestion; return ( // eslint-disable-next-line jsx-a11y/click-events-have-key-events
  • {main_text} {secondary_text}
  • ); }); return ( <> {suggestions}
  • Powered by Google
  • ); }; return (

    USE-PLACES-AUTOCOMPLETE

    React hook for Google Maps Places Autocomplete.

    {hasSuggestions && (
      {renderSuggestions()}
    )}
    ); }; export default App;