Skip to content

Commit

Permalink
Fix (#13, #14): Render suggestions over (popover) components/elements (
Browse files Browse the repository at this point in the history
…#15)

* Fix: Don't set height on suggestions container (fixes #13)

This commit changes the styling of the suggestions container so that it
no longer has a set height of 200 units. This caused the suggestions
container to take up space when the suggestions container wasn't
rendered.

This commit fixes bug: #13
	modified:   src/MUIPlacesAutocomplete.jsx

* Fix: Render suggestions container over target (fixes #14)

This commit changes the behavior of how we render our suggestions
container. In the past I naively believed that when our suggestions
container was rendered it would magically "hide" elements that came
after it. As I'm learning this isn't the case. As a result of my
inexperience the suggestions container would "blend" with elements of
the same "depth". This is all documented in bug #14.

We now render the suggestions container over a target provided to us. We
now get the desired behavior where the suggestions container renders
over elements and properly receives all of the focus/events. While
fixing how we rendered the suggestions container though I took a big
departure from how I was doing things in the past.

In the past I used the 'react-autosuggest' to provide autocomplete
functionality to our component. When trying to use it to properly render
our suggestions container (i.e. render over/popover a target) I found it
increasingly difficult to work with. As a result I looked for other
solutions and decided to use 'downshift'.

'downshift' was a lot easier to work with and "did more" for me out of
the box. I want to make clear for anyone who may read this in the future
that the 'react-autosuggest' package is great and people ought to look
into using it to meet their needs. If I were more technically adept then
I may have been able to make 'react-autosuggest' work.

In conjunction with 'downshift' we also use 'react-popper' which is a
React wrapper around PopperJS to provide the popover (modal)
functionality of our suggestions container.

This commit fixes bug: #14
	modified:   package.json
	modified:   src/MUIPlacesAutocomplete.jsx
	modified:   src/index.js
	modified:   test/setup-dom.js
	modified:   test/test.jsx
	modified:   test/test.jsx.snap
	modified:   yarn.lock

* Docs: Link to my (Chris') MIT license

This commit modifies the license section of the README to link to my MIT
license hosted at https://mit-license.org/ (via
https://github.com/remy/mit-license).
	modified:   README.md

* Chore: Add test coverage to verify rendered suggestions are unique

This commit adds test coverage to verify that non-unique predictions
returned by the Google Maps Autocomplete Service are rendered as unique
suggestions.

We refactored the code some by moving the logic of creating a list of
unique suggestions out of the 'onInputValueChange()' method into the
'renderSuggestionsContainer()' method. I did this as it allows for more
clear testing of ideas. While adding test coverage I was conflating the
issues of having predictions returned async/React setting state async
and having all rendered suggestions be unique. This caused me to try
some weird testing patterns where I was waiting for the async React
state setting to complete and then verify my suggestions.

It seems doing this is less performant/optimized but maybe I was being
premature in that regard and this is going to lead to better
debugging/maintenance.
	modified:   src/MUIPlacesAutocomplete.jsx
	modified:   test/test.jsx
	modified:   test/test.jsx.snap

* Docs: Update README to show 'renderTarget' prop usage

This commit updates the README to show how to use the 'renderTarget'
prop as it is required. The 'renderTarget' prop takes a function which
renders components/elements that the rendered suggestions list ought to
popover.
	modified:   README.md

* Chore: Update demo to make use of 'renderTarget' prop

Commit e40dbec added a new library
named 'react-popper' (wrapper around PopperJS) to help us render
over/popover the list of suggestions over a component/element. It also
added a prop to the <MUIPlacesAutocomplete> component named
'renderTarget' that renders said components/elements to render the list
of suggestions over.

This commit updates the demo to make use of the newly required
'renderTarget' prop. We simply provided a self-closing <div> which is
unexciting. In the future maybe we can invest sometime in the demo to
provide something like a form for providing address information that
autofills when a suggestion is selected.
	modified:   demo/Demo.jsx

* Docs: Remove erroneous chars in entry in table under Usage->Props

Remove erroneous '[]' chars around the 'renderTarget' entry in the table
that describes the props on the <MUIPlacesAutocomplete> component.
	modified:   README.md
  • Loading branch information
Giners authored Jan 17, 2018
1 parent 81bed66 commit 4ec410a
Show file tree
Hide file tree
Showing 9 changed files with 994 additions and 1,738 deletions.
57 changes: 33 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,50 +21,59 @@ 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).
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](#setup)).

# 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:
1. Enable the Google Places API Web Service
2. Enable the Google Maps JavaScript API
3. Obtain a Google API key

You can do all of these things from your Google developers console here: https://console.developers.google.com
# Demo
**Note that you must have followed the [setup steps](#setup) to run the demo as it depends on services provided by Google.**

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:
To see a demo of this component locally clone this repository and run:

```html
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"></script>
```
yarn demo
```

Be sure that you replace `YOUR_API_KEY` with the one you just created or obtained previously.
or

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`.
```
npm run demo
```

# Usage
```javascript
import React from 'react'
import SomeCoolComponent from 'some-third-party-package'
import MUIPlacesAutocomplete from 'mui-places-autocomplete'

const Example = () => (<MUIPlacesAutocomplete />)
// Use 'renderTarget' prop to render a component/target we want the suggestions to popover
const Example = () => (<MUIPlacesAutocomplete renderTarget={() => (<SomeCoolComponent />)} />)

export default Example
```

# Demo
To see a demo of this component locally clone this repository and run:
<a name="setup"></a>
### 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:
1. Enable the Google Places API Web Service
2. Enable the Google Maps JavaScript API
3. Obtain a Google API key

```
yarn demo
```
You can do all of these things from your Google developers console here: https://console.developers.google.com

or
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:

```html
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"></script>
```
npm run demo
```

Note that you must have followed the setup steps to run the demo as it depends on services provided by Google.
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 |
| :--- | :--- | :---: | :--- |
| `renderTarget` | Function || Renders the components/elements that you would like to have the list of suggestions popover. |

# 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.
Expand All @@ -74,4 +83,4 @@ This was my first open-source project that I undertook while I was teaching myse
* Overview and examples for the Autocomplete features in the Places library: https://developers.google.com/maps/documentation/javascript/places-autocomplete

# License
MIT
[MIT](https://gine.mit-license.org/)
2 changes: 1 addition & 1 deletion demo/Demo.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import MUIPlacesAutocomplete from './../dist'

const Demo = () => (<MUIPlacesAutocomplete />)
const Demo = () => (<MUIPlacesAutocomplete renderTarget={() => (<div />)} />)

export default Demo
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"main": "dist/index.js",
"scripts": {
"test": "yarn test:mocha && yarn test:eslint",
"test:mocha": "mocha --require babel-register --require ignore-styles --require test/setup-dom.js test/test.jsx",
"test:mocha": "mocha --exit --require babel-register --require ignore-styles --require test/setup-dom.js test/test.jsx",
"test:eslint": "eslint --max-warnings 0 --cache --ext .js,.jsx src test demo",
"demo": "webpack-dev-server --config demo/webpack.config.js --content-base dist --hot",
"build": "rm -rf dist/ && webpack",
Expand All @@ -29,8 +29,9 @@
},
"dependencies": {
"autosuggest-highlight": "^3.1.0",
"downshift": "^1.22.5",
"prop-types": "^15.6.0",
"react-autosuggest": "^9.3.2"
"react-popper": "^0.7.4"
},
"peerDependencies": {
"material-ui": "^1.0.0-beta.21",
Expand All @@ -49,7 +50,7 @@
"chai-jest-snapshot": "^1.3.0",
"conventional-changelog-eslint": "^0.2.1",
"enzyme": "^3.1.0",
"enzyme-adapter-react-16": "^1.0.2",
"enzyme-adapter-react-16": "^1.1.0",
"enzyme-to-json": "^3.1.4",
"eslint": "^4.9.0",
"eslint-config-airbnb": "^16.1.0",
Expand All @@ -64,6 +65,7 @@
"jsdom": "^11.3.0",
"material-ui": "^1.0.0-beta.21",
"mocha": "^4.0.1",
"raf": "^3.4.0",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"semantic-release": "^8.2.0",
Expand Down
Loading

0 comments on commit 4ec410a

Please sign in to comment.