diff --git a/examples/gh-pages/scripts/components/basics/StyledMap.js b/examples/gh-pages/scripts/components/basics/StyledMap.js index 72634501..95e8d2b8 100644 --- a/examples/gh-pages/scripts/components/basics/StyledMap.js +++ b/examples/gh-pages/scripts/components/basics/StyledMap.js @@ -103,18 +103,16 @@ export default class StyledMap extends Component { }] } + _click_from_children_of_infoBox = (e) => { + console.log("_click_from_children_of_infoBox!!"); + console.log(e); + } + render () { const {props, state} = this, {googleMapsApi, mapStyles, ...otherProps} = props; const myLatLng = new google.maps.LatLng(25.03, 121.6); - const InfoBoxContent = ` -
-
- Taipei -
-
- `; return ( + options={{closeBoxURL: "", enableEventPropagation: true}} + > +
+
+ Taipei +
+
+
); } diff --git a/examples/gh-pages/scripts/components/events/ClosureListeners.js b/examples/gh-pages/scripts/components/events/ClosureListeners.js index 1f76d6fe..71096989 100644 --- a/examples/gh-pages/scripts/components/events/ClosureListeners.js +++ b/examples/gh-pages/scripts/components/events/ClosureListeners.js @@ -50,6 +50,31 @@ export default class ClosureListeners extends Component { this.setState(this.state); } + _render_InfoWindow (ref, marker) { + if (Math.random() > 0.5) { + // Normal version: Pass string as content + return ( + + ) + } else { + // "react-google-maps" extended version: Pass ReactElement as content + return ( + +
+ {marker.content} +
+ The contents of this InfoWindow are actually ReactElements. +
+
+ ) + } + } + render () { const {markers} = this.state; @@ -65,19 +90,12 @@ export default class ClosureListeners extends Component { {markers.map((marker, index) => { const ref = `marker_${index}`; - const content = marker.showInfo ? ( - - ) : null; - return ( - {content} + {marker.showInfo ? this._render_InfoWindow(ref, marker) : null} ); })} diff --git a/src/addons/addonsCreators/InfoBoxCreator.js b/src/addons/addonsCreators/InfoBoxCreator.js index ebe58c86..ca0caa99 100644 --- a/src/addons/addonsCreators/InfoBoxCreator.js +++ b/src/addons/addonsCreators/InfoBoxCreator.js @@ -8,13 +8,14 @@ import {default as InfoBoxEventList} from "../addonsEventLists/InfoBoxEventList" import {default as eventHandlerCreator} from "../../utils/eventHandlerCreator"; import {default as defaultPropsCreator} from "../../utils/defaultPropsCreator"; import {default as composeOptions} from "../../utils/composeOptions"; +import {default as setContentForOptionalReactElement} from "../../utils/setContentForOptionalReactElement"; import {default as componentLifecycleDecorator} from "../../utils/componentLifecycleDecorator"; import {default as GoogleMapHolder} from "../../creators/GoogleMapHolder"; export const infoBoxControlledPropTypes = { // http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/docs/reference.html - content: PropTypes.any, /* TODO: children */ + content: PropTypes.any, options: PropTypes.object, position: PropTypes.any, visible: PropTypes.bool, @@ -24,7 +25,8 @@ export const infoBoxControlledPropTypes = { export const infoBoxDefaultPropTypes = defaultPropsCreator(infoBoxControlledPropTypes); const infoBoxUpdaters = { - content (/* content, component */) { /* TODO: children */ }, + children (children, component) { setContentForOptionalReactElement(children, component.getInfoWindow()); }, + content (content, component) { component.getInfoBox().setContent(content); }, options (options, component) { component.getInfoBox().setOptions(options); }, position (position, component) { component.getInfoBox().setPosition(position); }, visible (visible, component) { component.getInfoBox().setVisible(visible); }, @@ -56,11 +58,16 @@ export default class InfoBoxCreator extends Component { // http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/docs/reference.html const infoBox = new GoogleMapsInfobox(composeOptions(infoBoxProps, [ // https://developers.google.com/maps/documentation/javascript/3.exp/reference - "content", /* TODO: children */ + "content", "position", "visible", "zIndex", ])); + + if (infoBoxProps.children) { + setContentForOptionalReactElement(infoBoxProps.children, infoBox); + } + if (anchorHolderRef) { infoBox.open(mapHolderRef.getMap(), anchorHolderRef.getAnchor()); } else { diff --git a/src/creators/InfoWindowCreator.js b/src/creators/InfoWindowCreator.js index 8b0591cb..708680ae 100644 --- a/src/creators/InfoWindowCreator.js +++ b/src/creators/InfoWindowCreator.js @@ -8,6 +8,7 @@ import {default as InfoWindowEventList} from "../eventLists/InfoWindowEventList" import {default as eventHandlerCreator} from "../utils/eventHandlerCreator"; import {default as defaultPropsCreator} from "../utils/defaultPropsCreator"; import {default as composeOptions} from "../utils/composeOptions"; +import {default as setContentForOptionalReactElement} from "../utils/setContentForOptionalReactElement"; import {default as componentLifecycleDecorator} from "../utils/componentLifecycleDecorator"; import {default as GoogleMapHolder} from "./GoogleMapHolder"; @@ -15,7 +16,7 @@ import {default as GoogleMapHolder} from "./GoogleMapHolder"; export const infoWindowControlledPropTypes = { // [].map.call($0.querySelectorAll("tr>td>code"), function(it){ return it.textContent; }).filter(function(it){ return it.match(/^set/) && !it.match(/^setMap/); }) // https://developers.google.com/maps/documentation/javascript/3.exp/reference#InfoWindow - content: PropTypes.any, /* TODO: children */ + content: PropTypes.any, options: PropTypes.object, position: PropTypes.any, zIndex: PropTypes.number, @@ -24,7 +25,8 @@ export const infoWindowControlledPropTypes = { export const infoWindowDefaultPropTypes = defaultPropsCreator(infoWindowControlledPropTypes); const infoWindowUpdaters = { - content (/* content, component */) { /* TODO: children */ }, + children (children, component) { setContentForOptionalReactElement(children, component.getInfoWindow()); }, + content (content, component) { component.getInfoWindow().setContent(content); }, options (options, component) { component.getInfoWindow().setOptions(options); }, position (position, component) { component.getInfoWindow().setPosition(position); }, zIndex (zIndex, component) { component.getInfoWindow().setZIndex(zIndex); }, @@ -51,11 +53,15 @@ export default class InfoWindowCreator extends Component { // https://developers.google.com/maps/documentation/javascript/3.exp/reference#InfoWindow const infoWindow = new google.maps.InfoWindow(composeOptions(infoWindowProps, [ // https://developers.google.com/maps/documentation/javascript/3.exp/reference#InfoWindowOptions - "content", /* TODO: children */ + "content", "position", "zIndex", ])); + if (infoWindowProps.children) { + setContentForOptionalReactElement(infoWindowProps.children, infoWindow); + } + if (anchorHolderRef) { infoWindow.open(mapHolderRef.getMap(), anchorHolderRef.getAnchor()); } else { diff --git a/src/utils/setContentForOptionalReactElement.js b/src/utils/setContentForOptionalReactElement.js new file mode 100644 index 00000000..0c173888 --- /dev/null +++ b/src/utils/setContentForOptionalReactElement.js @@ -0,0 +1,32 @@ +import { + default as React, + Children, +} from "react"; + +function renderElement ( + contentElement, + prevContent +) { + if ("[object HTMLDivElement]" !== Object.prototype.toString.call(prevContent)) { + prevContent = document.createElement("div"); + } + + React.render(contentElement, prevContent); + return prevContent; +} + +export default function setContentForOptionalReactElement ( + contentOptionalReactElement, + infoWindowLikeInstance +) { + if (React.isValidElement(contentOptionalReactElement)) { + const contentElement = Children.only(contentOptionalReactElement); + const prevContent = infoWindowLikeInstance.getContent(); + + const domEl = renderElement(contentOptionalReactElement, prevContent); + infoWindowLikeInstance.setContent(domEl); + + } else { + infoWindowLikeInstance.setContent(contentOptionalReactElement); + } +}