Skip to content

Commit

Permalink
feat(addons/InfoBox): revamp to PureComponent
Browse files Browse the repository at this point in the history
  • Loading branch information
tomchentw committed Sep 13, 2017
1 parent b92a570 commit 95269d2
Show file tree
Hide file tree
Showing 4 changed files with 231 additions and 175 deletions.
8 changes: 8 additions & 0 deletions src/addons/InfoBox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import warning from "warning"

warning(
false,
`[DEPRECATED] "react-google-maps/lib/addons/InfoBox" has been moved to "react-google-maps/lib/components/addons/InfoBox"`
)

export { default } from "../components/addons/InfoBox"
223 changes: 223 additions & 0 deletions src/components/addons/InfoBox.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
import canUseDOM from "can-use-dom"
import invariant from "invariant"
import React from "react"
import ReactDOM from "react-dom"
import PropTypes from "prop-types"

import {
construct,
componentDidMount,
componentDidUpdate,
componentWillUnmount,
} from "../../utils/MapChildHelper"

import { MAP, ANCHOR, INFO_BOX } from "../../constants"

/**
* @url http://htmlpreview.github.io/?https://github.com/googlemaps/v3-utility-library/blob/master/infobox/docs/reference.html
*/
export class InfoBox extends React.PureComponent {
static propTypes = {
/**
* @type InfoBoxOptions
*/
defaultOptions: PropTypes.any,

/**
* @type LatLng|LatLngLiteral
*/
defaultPosition: PropTypes.any,

/**
* @type boolean
*/
defaultVisible: PropTypes.bool,

/**
* @type number
*/
defaultZIndex: PropTypes.number,

/**
* @type InfoBoxOptions
*/
options: PropTypes.any,

/**
* @type LatLng|LatLngLiteral
*/
position: PropTypes.any,

/**
* @type boolean
*/
visible: PropTypes.bool,

/**
* @type number
*/
zIndex: PropTypes.number,

/**
* function
*/
onCloseClick: PropTypes.func,

/**
* function
*/
onDomReady: PropTypes.func,

/**
* function
*/
onContentChanged: PropTypes.func,

/**
* function
*/
onPositionChanged: PropTypes.func,

/**
* function
*/
onZindexChanged: PropTypes.func,
}

static contextTypes = {
[MAP]: PropTypes.object,
[ANCHOR]: PropTypes.object,
}

state = {
[INFO_BOX]: null,
}

/*
* @url https://developers.google.com/maps/documentation/javascript/3.exp/reference#InfoBox
*/
componentWillMount() {
if (!canUseDOM || this.state[INFO_BOX]) {
return
}
const GoogleMapsInfobox = require(/* "google-maps-infobox" uses "google" as a global variable. Since we don't
* have "google" on the server, we can not use it in server-side rendering.
* As a result, we import "google-maps-infobox" here to prevent an error on
* a isomorphic server.
*/ `google-maps-infobox`)
const infoBox = new GoogleMapsInfobox()
construct(InfoBox.propTypes, updaterMap, this.props, infoBox)
infoBox.setMap(this.context[MAP])
this.state = {
[INFO_BOX]: infoBox,
}
}

componentDidMount() {
componentDidMount(this, this.state[INFO_BOX], eventMap)
const content = document.createElement(`div`)
ReactDOM.unstable_renderSubtreeIntoContainer(
this,
React.Children.only(this.props.children),
content
)
this.state[INFO_BOX].setContent(content)
open(this.state[INFO_BOX], this.context[ANCHOR])
}

componentDidUpdate(prevProps) {
componentDidUpdate(
this,
this.state[INFO_BOX],
eventMap,
updaterMap,
prevProps
)
if (this.props.children !== prevProps.children) {
ReactDOM.unstable_renderSubtreeIntoContainer(
this,
React.Children.only(this.props.children),
this.state[INFO_BOX].getContent()
)
}
open(this.state[INFO_BOX], this.context[ANCHOR])
}

componentWillUnmount() {
componentWillUnmount(this)
const infoBox = this.state[INFO_BOX]
if (infoBox) {
if (infoBox.getContent()) {
ReactDOM.unmountComponentAtNode(infoBox.getContent())
}
infoBox.setMap(null)
}
}

render() {
return false
}

/**
*
* @type LatLng
*/
getPosition() {
return this.state[INFO_BOX].getPosition()
}

/**
*
* @type boolean
*/
getVisible() {
return this.state[INFO_BOX].getVisible()
}

/**
*
* @type number
*/
getZIndex() {
return this.state[INFO_BOX].getZIndex()
}
}

const open = (infoBox, anchor) => {
if (anchor) {
infoBox.open(infoBox.getMap(), anchor)
} else if (infoBox.getPosition()) {
infoBox.open(infoBox.getMap())
} else {
invariant(
false,
`You must provide either an anchor (typically render it inside a <Marker>) or a position props for <InfoBox>.`
)
}
}

const eventMap = {
onCloseClick: "closeclick",
onDomReady: "domready",
onContentChanged: "content_changed",
onPositionChanged: "position_changed",
onZindexChanged: "zindex_changed",
}

const updaterMap = {
options(instance, options) {
instance.setOptions(options)
},

position(instance, position) {
instance.setPosition(position)
},

visible(instance, visible) {
instance.setVisible(visible)
},

zIndex(instance, zIndex) {
instance.setZIndex(zIndex)
},
}
166 changes: 0 additions & 166 deletions src/lib/addons/InfoBox.js

This file was deleted.

Loading

0 comments on commit 95269d2

Please sign in to comment.