Skip to content
This repository has been archived by the owner on Dec 30, 2022. It is now read-only.

feat(geo): add simple GoogleMaps widget [PART-2] #1189

Merged
merged 28 commits into from
Jun 20, 2018

Conversation

samouss
Copy link
Collaborator

@samouss samouss commented Apr 25, 2018

Summary

This is the second part of the GeoSearch widget. Those are the first building blocks for the widget. It only displays hits on the map. When you trigger a search with the SearchBox the map move accordingly. Right now this is it. The refine behaviour is not implemented it will comes after.

untitled

This PR includes:

  • <GoogleMapsLoader>: the usage of this component is not required. You can load the map with a different strategy it doesn't impact the widget.
  • <Provider>: it's a private component inside the widget to bind the connector to a render props. This component will hold all the logic related to the UI state in a next PR.
  • <GeoSearch>: it's the main component for the GeoSearch widget. It wraps the Provider & GoogleMaps components together.
  • <GoogleMaps>: is s wrapper around the GoogleMaps API. His responsibility is to manage the instance of the map and expose it through the context.
  • <Marker>: is a wrapper around the built-in GoogleMaps Marker. It retrieves the instance of map from the context exposed by GoogleMaps.

Usage

import { GoogleMapsLoader, GeoSearch, Marker } from 'react-instantsearch-dom-geo'; // name will change

<GoogleMapsLoader apiKey="GOOGLE_MAPS_API_KEY">
  {google => (
    <GeoSearch google={google}>
      {({ hits }) => (
        <Fragment>
          {hits.map(hit => <Marker key={hit.objectID} hit={hit} />)}
        </Fragment>
      )}
    </GeoSearch>
  )}
</GoogleMapsLoader>;

Result

You can use the widget in Storybook.

@samouss samouss requested review from vvo, Haroenv and bobylito and removed request for vvo April 25, 2018 07:45
@algobot
Copy link
Contributor

algobot commented Apr 25, 2018

Deploy preview for react-instantsearch ready!

Built with commit 387cd23

https://deploy-preview-1189--react-instantsearch.netlify.com

@@ -0,0 +1,67 @@
{
"name": "react-instantsearch-dom-geo",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name is a bit odd, but descriptive

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not the final name, more a placeholder. Any inputs / ideas are welcome!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

react-instantsearch-maps-dom sounds better to me 😀

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but since the next package will be called react-instantsearch-dom it makes more sense to have react-instantsearch-dom-maps WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd put the specifier of the platform last still, since you'll think "I want the react instantsearch package for maps which works on web"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would go for react-instantsearch-dom-geosearch (endname = widget name). About having dom before or after I have no preference, any examples of libraries named react-dom-xx vs react-xx-dom?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I followed the same name as React Router react-router-dom, react-router-native. Most of the time the libs used for React DOM are just named react-xxx. But for React Native it's common to have react-native-xxx. Since we support both, make sense to follow the convention react-{platform}-xxx.

"jest": "22.4.3",
"react": "16.3.2",
"react-dom": "16.3.2",
"rollup": "0.58.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are those dependencies not top-level ones? or do you prefer the duplication?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the next project structure every package is self-contained so I heavily rely on the deduplication of the Workspaces.

"enzyme-to-json/serializer"
]
},
"bundlesize": []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add that here too?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add it when I have the final size of the package.

import PropTypes from 'prop-types';
// @TODO: Update this import when the package is correctly split:
// import { createClassNames } from 'react-instantsearch-dom';
import createClassNames from '../../react-instantsearch/src/components/createClassNames';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this not be react-instantsearch/src/components/createClassNames?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With an absolute import the file will be the original one (non transpiled). Webpack will complain because we don't the node_modules files are not transpiled. In the next version this issue is fixed with a watch command that build the packages. For now, we can let the import like that.


class GeoSearch extends Component {
static propTypes = {
google: PropTypes.object.isRequired,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it would make sense to accept the google.maps object instead of the whole google object 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At some point if we need an object that is not nested under the maps namespace it will be a breaking change. Not sure that will happen one day but anyway the overhead is inexistent.

});

this.setState(() => ({
isMapAlreadyRender: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isMapAlreadyRendered

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace with isMapReady, makes more sense at the end (especially with the future changes).

const { google } = this.props;

const latLngBounds = hits.reduce(
(acc, hit) => acc.extend(hit._geoloc),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a question: where does extend come from?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, I see, google maps bounds


return (
<GoogleMaps
testID="GoogleMaps"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's this used for? when you mock GoogleMaps?

Copy link
Collaborator Author

@samouss samouss Apr 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope it avoid with Enzyme to target the component by reference .find(GoogleMaps) or by className or more generally everything that is subject to change in a test case .find('[testID="GoogleMaps"]') won't change at all.

https://blog.kentcdodds.com/making-your-ui-tests-resilient-to-change-d37a6ee37269

};

static childContextTypes = {
[GOOGLE_MAPS_CONTEXT]: PropTypes.shape({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be nice t here use the new context, and give it as a limitation to use new React, maybe?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The full version of InstantSearch is compatible with lower version than React 16.3. Plus I didn't find a official substitute for the new API (other than create-react-context). For now I prefer to stick with the old API. In the next version of the lib the question worth asking.

import PropTypes from 'prop-types';
import injectScript from 'scriptjs';

class GoogleMapsLoader extends Component {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome!

@samouss samouss force-pushed the feat/geo-part-2-simple-map branch 2 times, most recently from a3edc66 to 0af5667 Compare May 2, 2018 08:10
@samouss samouss force-pushed the feat/geo-part-2-simple-map branch from 0af5667 to 3dc3e71 Compare May 4, 2018 08:41
@samouss samouss force-pushed the feat/geo-part-2-simple-map branch 2 times, most recently from f0cec76 to 05f6e6d Compare May 14, 2018 13:08
@samouss samouss force-pushed the feat/geo-part-one branch 2 times, most recently from 6c0c4c5 to 1e1201d Compare June 19, 2018 13:40
@samouss samouss force-pushed the feat/geo-part-2-simple-map branch from 05f6e6d to 5d66ea9 Compare June 19, 2018 13:50
@samouss samouss force-pushed the feat/geo-part-one branch from 1e1201d to 23769fc Compare June 19, 2018 16:25
@samouss samouss force-pushed the feat/geo-part-2-simple-map branch from 5d66ea9 to 479cdc1 Compare June 19, 2018 16:26
@samouss samouss force-pushed the feat/geo-part-one branch from 23769fc to e6f3918 Compare June 20, 2018 07:51
@samouss samouss force-pushed the feat/geo-part-2-simple-map branch from 125f026 to 7dfc345 Compare June 20, 2018 07:58
* feat(geo): add Redo component [PART-4] (#1201)

* feat(geo): add Control component [PART-5] (#1205)

* feat(geo): refactor & external update [PART-6] (#1207)

* feat(geo): custom Marker [PART-7] (#1214)

* feat(geo): add Marker & HTMLMarker interactions [PART-8] (#1227)

* feat(geo): add stories [PART-9] (#1236)

* feat(geo): add docs [PART-10] (#1289)
@samouss samouss merged commit 33e22ca into feat/geo-part-one Jun 20, 2018
@samouss samouss deleted the feat/geo-part-2-simple-map branch June 20, 2018 19:32
samouss added a commit that referenced this pull request Jun 21, 2018
* feat(geo): add simple GoogleMaps widget [PART-2] (#1189)

* feat(geo): add refine on interaction [PART-3] (#1192)

* feat(geo): add Redo component [PART-4] (#1201)

* feat(geo): add Control component [PART-5] (#1205)

* feat(geo): refactor & external update [PART-6] (#1207)

* feat(geo): custom Marker [PART-7] (#1214)

* feat(geo): add Marker & HTMLMarker interactions [PART-8] (#1227)

* feat(geo): add stories [PART-9] (#1236)

* feat(geo): add docs [PART-10] (#1289)
samouss added a commit that referenced this pull request Jul 4, 2018
<a name="5.2.0"></a>
# [5.2.0](v5.2.0-beta.2...v5.2.0) (2018-07-04)

### Bug Fixes

* **translatable:** avoid create a new function on every render ([#1383](#1383)) ([1285b3b](1285b3b))

### Features

* **core:** export translatable ([#1351](#1351)) ([6d5a89d](6d5a89d))
* **maps:** add connector & widget ([#1171](#1171)) ([16e288a](16e288a)), closes [#1189](#1189) [#1192](#1192) [#1201](#1201) [#1205](#1205) [#1207](#1207) [#1214](#1214) [#1227](#1227) [#1236](#1236) [#1289](#1289)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants