MUIPlacesAutocomplete
Features
- Easy-to-use component for searching for places
- Place suggestions displayed in realtime
- Input state can be controlled externally
- Google Material Design styling provided by next version of Material-UI (v1)
- Safe to render on the server (SSR)
- Integrates with other 3rd party libraries (e.g. Redux Form)
- Thoroughly tested
Installation
To install this component run the following command:
yarn add mui-places-autocomplete --ignore-scripts
or
npm install mui-places-autocomplete --save --ignore-scripts
Note that if you exclude the --ignore-scripts
option when installing a package then the prepublish
script in package.json
is ran after installing locally. Tests are ran as part of the prepublish
script and they will fail if you haven't yet set a Google API key to the enivronment variable GOOGLE_API_KEY
(see setup section).
Demo
Note that you must have followed the setup steps to run the demo as it depends on services provided by Google.
To see a demo of this component locally clone this repository and run:
yarn demo
or
npm run demo
Usage
import React from 'react'
import SomeCoolComponent from 'some-cool-component'
import MUIPlacesAutocomplete from 'mui-places-autocomplete'
class Example extends React.Component {
constructor() {
super()
this.onSuggestionSelected = this.onSuggestionSelected.bind(this)
}
onSuggestionSelected(suggestion) {
console.log('Selected suggestion:', suggestion)
}
render() {
return (
<MUIPlacesAutocomplete
onSuggestionSelected={this.onSuggestionSelected}
renderTarget={() => (<SomeCoolComponent />)}
/>
)
}
}
export default Example
Advanced Usage
- DemoControlledInput.jsx - Example that shows how to control the
<input>
element as well as integrate with Redux Form.
Setup
This component relies on some basic setup before usage. It makes use of services provided by Google. To properly make use of the services you will need to do three things:
- Enable the Google Places API Web Service
- Enable the Google Maps JavaScript API
- Obtain a Google API key
You can do all of these things from your Google developers console here: https://console.developers.google.com
The component relies on the Places library in the Google Maps JavaScript API. To load the Places library on the client you must add the following to the HTML document you deliver to your clients:
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"></script>
Be sure that you replace YOUR_API_KEY
with the one you just created or obtained previously.
This component also has testing which makes use of the Places library in the Google Maps JavaScript API. Rather than loading the Places library it uses a module provided by Google. It also requires an API key. This key can be provided to a file @ test/api-key.js
. If you would like it can also be provided as an environment variable named GOOGLE_API_KEY
.
Props
Prop | Type | Required | Description |
---|
onSuggestionSelected | Function | ✓ | Callback that provides the selected suggestion. |
renderTarget | Function | ✓ | Renders the components/elements that you would like to have the list of suggestions popover. |
createAutocompleteRequest | Function | | Returns an object that modifies which suggestions are shown to the user. |
textFieldProps | Object | | Props that will be spread onto a <TextField> MUI component that is responsible for rendering the <input> element. If you would like to control the state of the <input> element externally you must set the value key on the object passed to textFieldProps . |
onSuggestionSelected (required)
This function will be called everytime a user has selected a suggestion. It has the following signature:
function onSuggestionSelected(suggestion)
renderTarget (required)
This function is invoked during rendering. It ought to return the components/elements that you want the list of suggestions to render (pop) over.
createAutocompleteRequest
<MUIPlacesAutocomplete>
leverages the Google Places API Web Service to provide place suggestions that a user may select from based on the users input. The requests made to the Google Places API Web Service are very simple by default. This results in a wider breadth in the types of suggestions (i.e. an establishment, city/locality, specific address, etc.) returned when the user first starts searching for a place. The set of returned suggestions may also not be geospatially tight ("close to each other"). As the users search becomes more specific the types of suggestions returned start to narrow as well as tighten geospatially around each other.
Depending on your use case you may wish to:
- Specify (i.e. narrow) the types of suggestions returned by the Google Places API Web Service
- Bias/restrict the suggestions returned by the Google Places API Web Service to a specific area
You can achieve this by providing a function to the createAutocompleteRequest
prop. The function is called everytime a request for suggestions is made to the Google Places API Web Service. The function passed to the createAutocompleteRequest
prop ought to have the following signature:
function createAutocompleteRequest(inputValue)
Where:
inputValue
- The users current search value
It ought to return an object that specifies what suggestions (i.e. types and bias/area restrictions) should be returned by the Google Places API Web Service. For example:
function createAutocompleteRequest(inputValue) {
return {
input: inputValue,
types: ['address'],
location: { lat: () => 48.7519, lng: () => 122.4787 },
radius: 5000,
}
}
The properties that are allowed on the returned object are documented here: AutocompleteRequest API object specification
Note: There is no validation for what is returned from the function provided to the createAutocompleteRequest
prop. So if you don't return an object or set the properties incorrectly then things are going to go poorly.
textFieldProps
A MUI <TextField>
component is used to render the <input>
element. It can be customized to meet your needs by supplying an object to the textFieldProps
prop. All properties on the object supplied to the textFieldProps
prop will be spread onto the <TextField>
component. You can read more about the props that the <TextField>
component accepts here: <TextField>
API documentation
textFieldProps.value
<input>
control prop
To help meet your needs the state of the <input>
element can be controlled externally. It is also useful if you would like to integrate <MUIPlacesAutocomplete>
with other 3rd party libraries such as Redux Form. To control the state of the <input>
element you must set the value
property on the object passed to the textFieldProps
prop.
const { inputValue } = getState()
<MUIPlacesAutocomplete textFieldProps={{ value: inputValue }} />
If you would like to have consistency between the controlled <input>
elements state as well as any suggestions that are selected then you need to update the controlled state of the <input>
element when a suggestion is selected. There is an example of how to do this in the advanced usage section.
Feedback
This was my first open-source project that I undertook while I was teaching myself full-stack development (JS (ES6)/HTML/CSS, Node, Express, NoSQL (DynamoDB), GraphQL, React, Redux, Material-UI, etc.). I'm very interested in taking feedback to either improve my skills (i.e. correct errors :)) or to make this component more useful in general/for your use case. Please feel free to provide feedback by opening an issue or messaging me.
References
License
MIT