Skip to content

Commit

Permalink
Merge pull request #94 from ErrorPro/v3
Browse files Browse the repository at this point in the history
Rework the lib to use hooks, adding additional props and refs, bump 2…
  • Loading branch information
ErrorPro authored Apr 20, 2021
2 parents 1a73a83 + 4597289 commit 7652acc
Show file tree
Hide file tree
Showing 6 changed files with 469 additions and 393 deletions.
102 changes: 88 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
![](https://img.badgesize.io/ErrorPro/react-google-autocomplete/master/lib/index.js?compression=gzip&label=gzip)
![](https://img.badgesize.io/ErrorPro/react-google-autocomplete/master/lib/index.js?compression=brotli&label=brotli)
[![GitHub license](https://img.shields.io/github/license/Naereen/StrapDown.js.svg)](https://GitHub.com/ErrorPro/react-google-autocomplete/master/LICENSE)

## React google autocomplete

This is a simple react component for working with google [autocomplete](https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete)
Expand All @@ -13,11 +17,11 @@ As of version 1.2.4, you can now pass an `apiKey` prop to automatically load the
```js
<AutoComplete
apiKey={YOUR_GOOGLE_MAPS_API_KEY}
onPlaceSelected={() => "do something on select"}
onPlaceSelected={(place) => console.log(place)}
/>
```

Alternatively if not passing the `apiKey` prop, you can include google autocomplete link api in your app. Somewhere in index.html or somewhere else.
Alternatively if not passing the `apiKey` prop, you can include google autocomplete link api in your app. Somewhere in index.html or somewhere else. More info [here](https://developers.google.com/maps/documentation/places/web-service/autocomplete)

```html
<script
Expand All @@ -26,41 +30,111 @@ Alternatively if not passing the `apiKey` prop, you can include google autocompl
></script>
```

## Example
## Props

- `apiKey`: pass to automatically load the Google maps scripts. The api key can be found in your [google cloud console.](https://developers.google.com/maps/documentation/javascript/get-api-key)

- `ref`: [React ref](https://reactjs.org/docs/hooks-reference.html#useref) to be assigned the underlying text input ref.

- `autocompleteRef`: [React ref](https://reactjs.org/docs/hooks-reference.html#useref) to be assigned the [google autocomplete instance](https://developers.google.com/maps/documentation/javascript/reference/places-widget#Autocomplete).

- `onPlaceSelected: (place: `[PlaceResult](https://developers.google.com/maps/documentation/javascript/reference/places-service#PlaceResult)`, inputRef, autocompleteRef) => void`: The function gets invoked every time a user chooses location.

- `options`: [Google autocomplete options.](https://developers.google.com/maps/documentation/javascript/reference/places-widget#AutocompleteOptions)

- `options.types`: By default it uses (cities).
- `options.fields`: By default it uses `address_components`, `geometry.location`, `place_id`, `formatted_address`.

- `inputAutocompleteValue`: Autocomplete value to be set to the underlying input.

- `googleMapsScriptBaseUrl`: Provide custom google maps url. By default `https://maps.googleapis.com/maps/api/js`

- `defaultValue` prop is used for setting up the default value e.g `defaultValue={'Amsterdam'}`.

You can pass any prop specified for the hmtl [input tag](https://www.w3schools.com/tags/tag_input.asp). You can also set [options.fields](https://developers.google.com/maps/documentation/javascript/reference/places-service#PlaceResult) prop if you need extra information, now it defaults to basic data in order to control expenses.

## Examples

### Simple autocomplete with options

```js
import Autocomplete from "react-google-autocomplete";

<Autocomplete
apiKey={YOUR_GOOGLE_MAPS_API_KEY}
style={{ width: "90%" }}
onPlaceSelected={(place) => {
console.log(place);
}}
types={["(regions)"]}
componentRestrictions={{ country: "ru" }}
options={{
types: ["(regions)"],
componentRestrictions: { country: "ru" },
}}
defaultValue="Amsterdam"
/>;
```

## Typescript
### Passing refs

We are planning on adding a full support for TS and Flow in the later releases.
```js
import Autocomplete from "react-google-autocomplete";

const inputRef = useRef(null);

useEffect(() => {
// focus on mount
inputRef.current.focus()
}, [])

<Autocomplete
ref={inputRef}
onPlaceSelected={(place) => {
console.log(place);
}}
/>;

```

### Getting access to the google autocomplete instance

```js
import Autocomplete from "react-google-autocomplete";

const autocompleteRef = useRef(null);

<Autocomplete
autocompleteRef={autocompleteRef}
onPlaceSelected={(place, inputRef, theSameAutocompletRef) => {
console.log(place);
}}
/>;

<button onClick={() => autocompleteRef.current.getPlace()}>Read place</button>;
```

### Typescript

We are planning on adding full support for TS and Flow in the later releases.

```ts
import Autocomplete, {
ReactGoogleAutocomplete,
} from "react-google-autocomplete";

const AutocompleteTS: FC<ReactGoogleAutocomplete> = Autocomplete as FC<ReactGoogleAutocomplete>;

<AutocompleteTS key="123" />
<AutocompleteTS apiKey="123" />;
```

The component has one function called `onPlaceSelected`. The function gets invoked every time a user chooses location.
A `types` props means type of places in [google place API](https://developers.google.com/places/web-service/autocomplete#place_types). By default it uses (cities).
A [componentRestrictions](https://developers.google.com/maps/documentation/javascript/reference#ComponentRestrictions) prop by default is empty.
A [bounds](https://developers.google.com/maps/documentation/javascript/reference#AutocompleteOptions) prop by default is empty.
You also can pass any props you want to the final input. You can also set [fields](https://developers.google.com/maps/documentation/javascript/reference/places-service#PlaceResult) prop if you need extra information, now it defaults to basic data in order to control expenses.
The `options`(optional) prop is the optional configuration to your Autocomplete instance. You can see full options [here](https://developers.google.com/maps/documentation/javascript/places-autocomplete#add_autocomplete)
### More examples(dynamic props, MaterialUI) how to use the lib could be found in `examples/index.js`

[Video of the example](https://api.monosnap.com/file/download?id=vIjRwTxVyMj0Sd2Gjhsfie2SPk1y4l)

### TODO

- Check that it fully works with SSR
- Add eslint config(base-airbnb)
- Rewrite the lib to TS and add flow support

## Contribution

Expand Down
76 changes: 76 additions & 0 deletions examples/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React, { FC, useRef, useState } from "react";
import logo from "./logo.svg";
import "./App.css";
import { Input } from "@material-ui/core";

import ReactGoogleAutocompleteComponent from "../index";

function App() {
const inputRef = useRef(null);
const autocompleteRef = useRef(null);
const [country, setCountry] = useState("us");

return (
<div className="App">
<header className="App-header">
<ReactGoogleAutocompleteComponent
ref={inputRef}
placeholder="Placeholder"
autocompleteRef={autocompleteRef}
apiKey={process.env.GOOGLE_API_KEY}
onPlaceSelected={(selected) => console.log(selected)}
inputAutocompleteValue="country"
/>
<ReactGoogleAutocompleteComponent
apiKey={process.env.GOOGLE_API_KEY}
onPlaceSelected={(selected) => console.log(selected)}
options={{
types: ["(regions)"],
componentRestrictions: { country },
}}
/>
<ReactGoogleAutocompleteComponent
apiKey={process.env.GOOGLE_API_KEY}
onPlaceSelected={(selected) => console.log(selected)}
/>
<select
onChange={(v) => {
setCountry(v.target.value);
}}
>
<option key="1" value="us">
Us
</option>
<option key="2" value="ru">
Ru
</option>
</select>
<Input
color="secondary"
inputComponent={({ inputRef, onFocus, onBlur, ...props }) => (
<ReactGoogleAutocompleteComponent
apiKey={process.env.GOOGLE_API_KEY}
onPlaceSelected={(selected) => console.log(selected)}
{...props}
/>
)}
/>
<img src={logo} className="App-logo" alt="logo" />
<button onClick={() => console.log(autocompleteRef)}>Press me</button>
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}

export default App;
14 changes: 8 additions & 6 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { HTMLProps } from "react";

export type OptionType = {
componentRestrictions?: {};
bounds?: {};
Expand All @@ -9,17 +11,17 @@ export type OptionType = {
types?: string[];
};

export interface ReactGoogleAutocomplete {
export interface ReactGoogleAutocomplete<
T = { current: null },
B = { current: null }
> extends HTMLProps<HTMLInputElement> {
onPlaceSelected?: (
places: Record<string, unknown>,
ref: HTMLInputElement
) => void;
types?: string[];
componentRestrictions?: {};
bounds?: {};
fields?: string[];
inputAutocompleteValue?: string;
options?: OptionType;
apiKey?: string;
style?: CSSStyleDeclaration;
ref?: T;
autocompleteRef?: B;
}
Loading

0 comments on commit 7652acc

Please sign in to comment.