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

Commit

Permalink
feat(DOMMaps): expose withGoogleMaps HOC [PART-1] (#2000)
Browse files Browse the repository at this point in the history
* feat(DOMMaps): use withGoogleMaps for CustomMarker [PART-2] (#2001)

* feat(DOMMaps): use withGoogleMaps for Marker [PART-3] (#2002)

* feat(DOMMaps): use withGoogleMaps for Redo [PART-4] (#2003)

* feat(DOMMaps): use withGoogleMaps for Control [PART-5] (#2004)

* feat(DOMMaps): drop usage of GOOGLE_MAPS_CONTEXT [PART-6] (#2005)
  • Loading branch information
samouss committed Feb 12, 2019
1 parent 789f4aa commit 2ae1dea
Show file tree
Hide file tree
Showing 16 changed files with 381 additions and 253 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -52,6 +52,7 @@
"@types/classnames": "^2.2.7",
"@types/enzyme": "^3.1.15",
"@types/enzyme-adapter-react-16": "^1.0.3",
"@types/googlemaps": "^3.30.16",
"@types/jest": "^24.0.0",
"@types/prop-types": "^15.5.8",
"@types/react": "^16.7.18",
Expand Down
17 changes: 5 additions & 12 deletions packages/react-instantsearch-dom-maps/src/Control.js
Expand Up @@ -2,12 +2,13 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { createClassNames, translatable } from 'react-instantsearch-dom';
import { STATE_CONTEXT } from './Provider';
import { GOOGLE_MAPS_CONTEXT } from './GoogleMaps';
import withGoogleMaps from './withGoogleMaps';

const cx = createClassNames('GeoSearch');

export class Control extends Component {
static propTypes = {
googleMapsInstance: PropTypes.object.isRequired,
translate: PropTypes.func.isRequired,
};

Expand All @@ -18,22 +19,14 @@ export class Control extends Component {
hasMapMoveSinceLastRefine: PropTypes.bool.isRequired,
refineWithInstance: PropTypes.func.isRequired,
}).isRequired,
[GOOGLE_MAPS_CONTEXT]: PropTypes.shape({
instance: PropTypes.object.isRequired,
}).isRequired,
};

getStateContext() {
return this.context[STATE_CONTEXT];
}

getGoogleMapsContext() {
return this.context[GOOGLE_MAPS_CONTEXT];
}

render() {
const { translate } = this.props;
const { instance } = this.getGoogleMapsContext();
const { googleMapsInstance, translate } = this.props;
const {
isRefineOnMapMove,
hasMapMoveSinceLastRefine,
Expand All @@ -56,7 +49,7 @@ export class Control extends Component {
) : (
<button
className={cx('redo')}
onClick={() => refineWithInstance(instance)}
onClick={() => refineWithInstance(googleMapsInstance)}
>
{translate('redo')}
</button>
Expand All @@ -69,4 +62,4 @@ export class Control extends Component {
export default translatable({
control: 'Search as I move the map',
redo: 'Redo search here',
})(Control);
})(withGoogleMaps(Control));
20 changes: 7 additions & 13 deletions packages/react-instantsearch-dom-maps/src/CustomMarker.js
Expand Up @@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import createHTMLMarker from './elements/createHTMLMarker';
import { registerEvents, createListenersPropTypes } from './utils';
import { GeolocHitPropType } from './propTypes';
import { GOOGLE_MAPS_CONTEXT } from './GoogleMaps';
import withGoogleMaps from './withGoogleMaps';

const eventTypes = {
onClick: 'click',
Expand All @@ -18,25 +18,20 @@ const eventTypes = {
onMouseUp: 'mouseup',
};

class CustomMarker extends Component {
export class CustomMarker extends Component {
static propTypes = {
...createListenersPropTypes(eventTypes),
hit: GeolocHitPropType.isRequired,
children: PropTypes.node.isRequired,
google: PropTypes.object.isRequired,
googleMapsInstance: PropTypes.object.isRequired,
className: PropTypes.string,
anchor: PropTypes.shape({
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired,
}),
};

static contextTypes = {
[GOOGLE_MAPS_CONTEXT]: PropTypes.shape({
google: PropTypes.object,
instance: PropTypes.object,
}),
};

static defaultProps = {
className: '',
anchor: {
Expand All @@ -54,15 +49,14 @@ class CustomMarker extends Component {
};

componentDidMount() {
const { hit, className, anchor } = this.props;
const { google, instance } = this.context[GOOGLE_MAPS_CONTEXT];
const { hit, google, googleMapsInstance, className, anchor } = this.props;
// Not the best way to create the reference of the CustomMarker
// but since the Google object is required didn't find another
// solution. Ideas?
const Marker = createHTMLMarker(google);

const marker = new Marker({
map: instance,
map: googleMapsInstance,
position: hit._geoloc,
className,
anchor,
Expand Down Expand Up @@ -114,4 +108,4 @@ class CustomMarker extends Component {
}
}

export default CustomMarker;
export default withGoogleMaps(CustomMarker);
8 changes: 4 additions & 4 deletions packages/react-instantsearch-dom-maps/src/GoogleMaps.js
Expand Up @@ -5,8 +5,6 @@ import { LatLngPropType, BoundingBoxPropType } from './propTypes';

const cx = createClassNames('GeoSearch');

export const GOOGLE_MAPS_CONTEXT = '__ais_geo_search__google_maps__';

class GoogleMaps extends Component {
static propTypes = {
google: PropTypes.object.isRequired,
Expand All @@ -22,7 +20,8 @@ class GoogleMaps extends Component {
};

static childContextTypes = {
[GOOGLE_MAPS_CONTEXT]: PropTypes.shape({
// eslint-disable-next-line camelcase
__ais_geo_search__google_maps__: PropTypes.shape({
google: PropTypes.object,
instance: PropTypes.object,
}),
Expand All @@ -40,7 +39,8 @@ class GoogleMaps extends Component {
const { google } = this.props;

return {
[GOOGLE_MAPS_CONTEXT]: {
// eslint-disable-next-line camelcase
__ais_geo_search__google_maps__: {
instance: this.instance,
google,
},
Expand Down
20 changes: 7 additions & 13 deletions packages/react-instantsearch-dom-maps/src/Marker.js
Expand Up @@ -6,7 +6,7 @@ import {
createFilterProps,
} from './utils';
import { GeolocHitPropType } from './propTypes';
import { GOOGLE_MAPS_CONTEXT } from './GoogleMaps';
import withGoogleMaps from './withGoogleMaps';

const eventTypes = {
onClick: 'click',
Expand All @@ -20,26 +20,20 @@ const eventTypes = {
const excludes = ['children'].concat(Object.keys(eventTypes));
const filterProps = createFilterProps(excludes);

class Marker extends Component {
export class Marker extends Component {
static propTypes = {
...createListenersPropTypes(eventTypes),
google: PropTypes.object.isRequired,
googleMapsInstance: PropTypes.object.isRequired,
hit: GeolocHitPropType.isRequired,
};

static contextTypes = {
[GOOGLE_MAPS_CONTEXT]: PropTypes.shape({
google: PropTypes.object,
instance: PropTypes.object,
}),
};

componentDidMount() {
const { hit, ...props } = this.props;
const { google, instance } = this.context[GOOGLE_MAPS_CONTEXT];
const { google, googleMapsInstance, hit, ...props } = this.props;

this.instance = new google.maps.Marker({
...filterProps(props),
map: instance,
map: googleMapsInstance,
position: hit._geoloc,
});

Expand Down Expand Up @@ -69,4 +63,4 @@ class Marker extends Component {
}
}

export default Marker;
export default withGoogleMaps(Marker);
17 changes: 5 additions & 12 deletions packages/react-instantsearch-dom-maps/src/Redo.js
Expand Up @@ -2,12 +2,13 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { createClassNames, translatable } from 'react-instantsearch-dom';
import { STATE_CONTEXT } from './Provider';
import { GOOGLE_MAPS_CONTEXT } from './GoogleMaps';
import withGoogleMaps from './withGoogleMaps';

const cx = createClassNames('GeoSearch');

export class Redo extends Component {
static propTypes = {
googleMapsInstance: PropTypes.object.isRequired,
translate: PropTypes.func.isRequired,
};

Expand All @@ -16,22 +17,14 @@ export class Redo extends Component {
hasMapMoveSinceLastRefine: PropTypes.bool.isRequired,
refineWithInstance: PropTypes.func.isRequired,
}).isRequired,
[GOOGLE_MAPS_CONTEXT]: PropTypes.shape({
instance: PropTypes.object.isRequired,
}).isRequired,
};

getStateContext() {
return this.context[STATE_CONTEXT];
}

getGoogleMapsContext() {
return this.context[GOOGLE_MAPS_CONTEXT];
}

render() {
const { translate } = this.props;
const { instance } = this.getGoogleMapsContext();
const { googleMapsInstance, translate } = this.props;
const {
hasMapMoveSinceLastRefine,
refineWithInstance,
Expand All @@ -42,7 +35,7 @@ export class Redo extends Component {
<button
className={cx('redo', !hasMapMoveSinceLastRefine && 'redo--disabled')}
disabled={!hasMapMoveSinceLastRefine}
onClick={() => refineWithInstance(instance)}
onClick={() => refineWithInstance(googleMapsInstance)}
>
{translate('redo')}
</button>
Expand All @@ -53,4 +46,4 @@ export class Redo extends Component {

export default translatable({
redo: 'Redo search here',
})(Redo);
})(withGoogleMaps(Redo));
15 changes: 4 additions & 11 deletions packages/react-instantsearch-dom-maps/src/__tests__/Control.js
Expand Up @@ -3,13 +3,13 @@ import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { createFakeMapInstance } from '../../test/mockGoogleMaps';
import { STATE_CONTEXT } from '../Provider';
import { GOOGLE_MAPS_CONTEXT } from '../GoogleMaps';
import { Control } from '../Control';

Enzyme.configure({ adapter: new Adapter() });

describe('Control', () => {
const defaultProps = {
googleMapsInstance: createFakeMapInstance(),
translate: x => x,
};

Expand All @@ -20,13 +20,9 @@ describe('Control', () => {
toggleRefineOnMapMove: () => {},
refineWithInstance: () => {},
},
[GOOGLE_MAPS_CONTEXT]: {
instance: createFakeMapInstance(),
},
};

const getStateContext = context => context[STATE_CONTEXT];
const getGoogleMapsContext = context => context[GOOGLE_MAPS_CONTEXT];

it('expect to render correctly with refine on map move', () => {
const props = {
Expand Down Expand Up @@ -116,10 +112,11 @@ describe('Control', () => {
});

it('expect to call refineWithInstance on button click', () => {
const instance = createFakeMapInstance();
const mapInstance = createFakeMapInstance();

const props = {
...defaultProps,
googleMapsInstance: mapInstance,
};

const context = {
Expand All @@ -130,10 +127,6 @@ describe('Control', () => {
hasMapMoveSinceLastRefine: true,
refineWithInstance: jest.fn(),
},
[GOOGLE_MAPS_CONTEXT]: {
...getGoogleMapsContext(defaultContext),
instance,
},
};

const wrapper = shallow(<Control {...props} />, {
Expand All @@ -147,6 +140,6 @@ describe('Control', () => {
wrapper.find('button').simulate('click');

expect(refineWithInstance).toHaveBeenCalledTimes(1);
expect(refineWithInstance).toHaveBeenCalledWith(instance);
expect(refineWithInstance).toHaveBeenCalledWith(mapInstance);
});
});

0 comments on commit 2ae1dea

Please sign in to comment.