diff --git a/.eslintrc b/.eslintrc
index b2a1143..0fc7240 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -15,7 +15,7 @@
"brace-style": 2,
"comma-dangle": [2, "always-multiline"],
"consistent-return": 2,
- "curly": 2,
+ "curly": [2, "multi-line"],
"dot-notation": 2,
"eol-last": 2,
"indent": [2, 2],
@@ -30,7 +30,7 @@
"object-shorthand": 2,
"quotes": [2, "single"],
"space-after-keywords": 2,
- "strict": [2, "global"],
+ "strict": 0,
"vars-on-top": 2,
"wrap-iife": 2,
"react/jsx-boolean-value": [2, "always"],
diff --git a/app/actions/AppActions.js b/app/actions/AppActions.js
index b28e0be..b453762 100644
--- a/app/actions/AppActions.js
+++ b/app/actions/AppActions.js
@@ -1,5 +1,3 @@
-'use strict';
-
import alt from '../alt';
import io from 'socket.io-client';
@@ -8,16 +6,28 @@ if (typeof window !== 'undefined') {
socket = io();
}
-class AppActions {
- constructor() {
- this.generateActions(
- 'updateFocusedMarker',
- 'updateFlowSuccess',
- 'updateInstaData',
- 'updateMarkers',
- 'updateTimeout'
- );
- }
+export default alt.createActions({
+ displayName: 'AppActions',
+
+ updateFocusedMarker(data) {
+ this.dispatch(data);
+ },
+
+ updateFlowSuccess(data) {
+ this.dispatch(data);
+ },
+
+ updateInstaData(data) {
+ this.dispatch(data);
+ },
+
+ updateMarkers(data) {
+ this.dispatch(data);
+ },
+
+ updateTimeout(data) {
+ this.dispatch(data);
+ },
updateFlow(curFlow) {
if (curFlow === 'Pause') {
@@ -25,7 +35,5 @@ class AppActions {
} else {
socket.emit('flow:start', () => this.actions.updateFlowSuccess('Pause'));
}
- }
-}
-
-export default alt.createActions(AppActions);
+ },
+});
diff --git a/app/alt.js b/app/alt.js
index 9478618..ad49b9b 100644
--- a/app/alt.js
+++ b/app/alt.js
@@ -1,5 +1,3 @@
-'use strict';
-
import Alt from 'alt';
export default new Alt();
diff --git a/app/app.js b/app/app.js
index a9465bf..d05c48a 100644
--- a/app/app.js
+++ b/app/app.js
@@ -1,8 +1,8 @@
-'use strict';
-
import React from 'react';
import Iso from 'iso';
-import Wrapper from './components/Wrapper';
+import wrapperFactory from './components/Wrapper';
+
+const Wrapper = wrapperFactory(React);
require('babel/polyfill');
diff --git a/app/components/App.jsx b/app/components/App.jsx
index b476149..b31b5bb 100644
--- a/app/components/App.jsx
+++ b/app/components/App.jsx
@@ -1,15 +1,14 @@
-'use strict';
-
const isBrowser = typeof window !== 'undefined';
-// TODO how to handle the es6 way?
-const GeoMap = isBrowser ? require('./Map') : undefined;
-import React from 'react';
import injectTapEventPlugin from 'react-tap-event-plugin';
-import List from './List';
-import Snackbar from 'material-ui/lib/snackbar';
-import TopBar from './TopBar';
import io from 'socket.io-client';
+import stampit from 'react-stampit';
+import Snackbar from 'material-ui/lib/snackbar';
+
+import listFactory from './List';
+import topBarFactory from './TopBar';
+// TODO how to handle conditional imports in ES6?
+const mapFactory = isBrowser ? require('./Map') : undefined;
let socket;
if (isBrowser) {
@@ -18,79 +17,102 @@ if (isBrowser) {
injectTapEventPlugin();
-class App extends React.Component {
- componentDidMount() {
- socket.on('data:add', this._onNewData.bind(this));
- socket.on('data:timeout', this._onDataTimeout.bind(this));
- }
-
- _getStyles() {
- return {
- root: {
- fontFamily: this.context.muiTheme.contentFontFamily,
- fontSize: '13px',
- lineHeight: '20px',
- WebkitFontSmoothing: 'antialiased',
- },
- list: {
- position: 'absolute',
- top: '56px',
- bottom: '0',
- right: '0',
- width: '290px',
- overflow: 'hidden',
- overflowY: 'scroll',
- },
- map: {
- position: 'absolute',
- top: '56px',
- bottom: '0',
- left: '0',
- right: '290px',
- },
- };
- }
-
- _onNewData(data) {
- this.props.updateInstaData(data);
- }
-
- _onDataTimeout(data) {
- this.props.updateTimeout(data);
- }
-
- _onListItemClick(item) {
- this.props.updateFocusedMarker(item);
- }
-
- render() {
- let styles = this._getStyles();
- // cant be executing client side js on prerender
- let map, alert;
-
- if (isBrowser) {
- map = (
-
- );
- }
-
- if (this.props.timeout) {
- alert = (
-
- );
- }
-
- return (
-
+export default React => {
+ const GeoMap = mapFactory ? mapFactory(React) : mapFactory;
+ const List = listFactory(React);
+ const TopBar = topBarFactory(React);
+
+ return stampit(React, {
+ contextTypes: {
+ muiTheme: React.PropTypes.object,
+ },
+
+ propTypes: {
+ flow: React.PropTypes.string,
+ focusMarker: React.PropTypes.object,
+ imageData: React.PropTypes.array,
+ markers: React.PropTypes.object,
+ newImageData: React.PropTypes.object,
+ timeout: React.PropTypes.bool,
+ updateFlow: React.PropTypes.func,
+ updateFocusedMarker: React.PropTypes.func,
+ updateInstaData: React.PropTypes.func,
+ updateMarkers: React.PropTypes.func,
+ updateTimeout: React.PropTypes.func,
+ },
+
+ componentDidMount() {
+ socket.on('data:add', this._onNewData.bind(this));
+ socket.on('data:timeout', this._onDataTimeout.bind(this));
+ },
+
+ _getStyles() {
+ return {
+ root: {
+ fontFamily: this.context.muiTheme.contentFontFamily,
+ fontSize: '13px',
+ lineHeight: '20px',
+ WebkitFontSmoothing: 'antialiased',
+ },
+ list: {
+ position: 'absolute',
+ top: '56px',
+ bottom: '0',
+ right: '0',
+ width: '290px',
+ overflow: 'hidden',
+ overflowY: 'scroll',
+ },
+ map: {
+ position: 'absolute',
+ top: '56px',
+ bottom: '0',
+ left: '0',
+ right: '290px',
+ },
+ };
+ },
+
+ _onNewData(data) {
+ this.props.updateInstaData(data);
+ },
+
+ _onDataTimeout(data) {
+ this.props.updateTimeout(data);
+ },
+
+ _onListItemClick(item) {
+ this.props.updateFocusedMarker(item);
+ },
+
+ render() {
+ let styles = this._getStyles();
+ // cant be executing client side js on prerender
+ let map, alert;
+
+ if (isBrowser) {
+ map = (
+
+ );
+ }
+
+ if (this.props.timeout) {
+ alert = (
+
+ );
+ }
+
+ return (
+
- );
- }
-}
-
-App.contextTypes = {
- muiTheme: React.PropTypes.object,
-};
-
-App.propTypes = {
- flow: React.PropTypes.string,
- focusMarker: React.PropTypes.object,
- imageData: React.PropTypes.array,
- markers: React.PropTypes.object,
- newImageData: React.PropTypes.object,
- timeout: React.PropTypes.bool,
- updateFlow: React.PropTypes.func,
- updateFocusedMarker: React.PropTypes.func,
- updateInstaData: React.PropTypes.func,
- updateMarkers: React.PropTypes.func,
- updateTimeout: React.PropTypes.func,
+ );
+ },
+ });
};
-
-export default App;
diff --git a/app/components/AuthButton.jsx b/app/components/AuthButton.jsx
index c3a3793..8ae8393 100644
--- a/app/components/AuthButton.jsx
+++ b/app/components/AuthButton.jsx
@@ -1,16 +1,31 @@
-'use strict';
-
-import React from 'react';
+import stampit from 'react-stampit';
import FlatButton from 'material-ui/lib/flat-button';
-class AuthButton extends React.Component {
+export default React => stampit(React, {
+ displayName: 'AuthButton',
+
+ contextTypes: {
+ muiTheme: React.PropTypes.object,
+ },
+
+ propTypes: {
+ label: React.PropTypes.string,
+ onTouchTap: React.PropTypes.func,
+ style: React.PropTypes.object,
+ },
+
+ defaultProps: {
+ label: 'Login',
+ style: {},
+ },
+
_getStyles() {
const theme = this.context.muiTheme.component.flatButton;
return {
hoverColor: theme.hoverColor,
};
- }
+ },
render() {
const styles = this._getStyles.call(this);
@@ -21,22 +36,5 @@ class AuthButton extends React.Component {
hoverColor={styles.hoverColor}
/>
);
- }
-}
-
-AuthButton.contextTypes = {
- muiTheme: React.PropTypes.object,
-};
-
-AuthButton.propTypes = {
- label: React.PropTypes.string,
- onTouchTap: React.PropTypes.func,
- style: React.PropTypes.object,
-};
-
-AuthButton.defaultProps = {
- label: 'Login',
- style: {},
-};
-
-export default AuthButton;
+ },
+});
diff --git a/app/components/FlowButton.jsx b/app/components/FlowButton.jsx
index 3d9808d..cc4e073 100644
--- a/app/components/FlowButton.jsx
+++ b/app/components/FlowButton.jsx
@@ -1,16 +1,31 @@
-'use strict';
-
-import React from 'react';
+import stampit from 'react-stampit';
import FlatButton from 'material-ui/lib/flat-button';
-class FlowButton extends React.Component {
+export default React => stampit(React, {
+ displayName: 'FlowButton',
+
+ contextTypes: {
+ muiTheme: React.PropTypes.object,
+ },
+
+ propTypes: {
+ label: React.PropTypes.string,
+ onTouchTap: React.PropTypes.func,
+ style: React.PropTypes.object,
+ },
+
+ defaultProps: {
+ label: 'Pause',
+ style: {},
+ },
+
_getStyles() {
const theme = this.context.muiTheme.component.flatButton;
return {
hoverColor: theme.hoverColor,
};
- }
+ },
render() {
const styles = this._getStyles.call(this);
@@ -21,22 +36,5 @@ class FlowButton extends React.Component {
hoverColor={styles.hoverColor}
/>
);
- }
-}
-
-FlowButton.contextTypes = {
- muiTheme: React.PropTypes.object,
-};
-
-FlowButton.propTypes = {
- label: React.PropTypes.string,
- onTouchTap: React.PropTypes.func,
- style: React.PropTypes.object,
-};
-
-FlowButton.defaultProps = {
- label: 'Pause',
- style: {},
-};
-
-export default FlowButton;
+ },
+});
diff --git a/app/components/GithubButton.jsx b/app/components/GithubButton.jsx
index 7e961dc..cad137c 100644
--- a/app/components/GithubButton.jsx
+++ b/app/components/GithubButton.jsx
@@ -1,9 +1,22 @@
-'use strict';
-
-import React from 'react';
+import stampit from 'react-stampit';
import IconButton from 'material-ui/lib/icon-button';
-class GithubButton extends React.Component {
+export default React => stampit(React, {
+ displayName: 'GithubButton',
+
+ contextTypes: {
+ muiTheme: React.PropTypes.object,
+ },
+
+ propTypes: {
+ repoUrl: React.PropTypes.string,
+ style: React.PropTypes.object,
+ },
+
+ defaultProps: {
+ style: {},
+ },
+
_getStyle() {
const theme = this.context.muiTheme.component.githubButton;
@@ -14,7 +27,7 @@ class GithubButton extends React.Component {
iconHoverColor: theme.hoverColor,
},
};
- }
+ },
render() {
const styles = this._getStyle();
@@ -29,20 +42,5 @@ class GithubButton extends React.Component {
style={this.props.style}
touchRippleColor={styles.rippleColor} />
);
- }
-}
-
-GithubButton.contextTypes = {
- muiTheme: React.PropTypes.object,
-};
-
-GithubButton.propTypes = {
- repoUrl: React.PropTypes.string,
- style: React.PropTypes.object,
-};
-
-GithubButton.defaultProps = {
- style: {},
-};
-
-export default GithubButton;
+ },
+});
diff --git a/app/components/List.jsx b/app/components/List.jsx
index 15064db..f77be2f 100644
--- a/app/components/List.jsx
+++ b/app/components/List.jsx
@@ -1,76 +1,80 @@
-'use strict';
+import stampit from 'react-stampit';
-import React from 'react';
-import ListItem from './ListItem';
-import ReactCSSTransitionGroup from './TimeoutTransitionGroup';
+import listItemFactory from './ListItem';
+import reactCSSTransitionGroupFactory from './TimeoutTransitionGroup';
import { mergeAndPrefix } from '../utils/stylePropable';
-class List extends React.Component {
- _getStyles() {
- return {
- root: {
- listStyleType: 'none',
- padding: '8px 0',
- margin: '0',
- },
- transition: {
- enter: {
- default: {
- opacity: '0.01',
- transition: 'opacity .3s ease-in',
- },
- active: {
- opacity: '1',
- },
+export default React => {
+ const ListItem = listItemFactory(React);
+ const ReactCSSTransitionGroup = reactCSSTransitionGroupFactory(React);
+
+ return stampit(React, {
+ displayName: 'List',
+
+ propTypes: {
+ itemData: React.PropTypes.array,
+ onClick: React.PropTypes.func,
+ style: React.PropTypes.object,
+ },
+
+ defaultProps: {
+ style: {},
+ },
+
+ _getStyles() {
+ return {
+ root: {
+ listStyleType: 'none',
+ padding: '8px 0',
+ margin: '0',
},
- leave: {
- default: {
- opacity: '1',
- transition: 'opacity .3s ease-in',
+ transition: {
+ enter: {
+ default: {
+ opacity: '0.01',
+ transition: 'opacity .3s ease-in',
+ },
+ active: {
+ opacity: '1',
+ },
},
- active: {
- opacity: '0.01',
+ leave: {
+ default: {
+ opacity: '1',
+ transition: 'opacity .3s ease-in',
+ },
+ active: {
+ opacity: '0.01',
+ },
},
},
- },
- };
- }
-
- render() {
- let styles = this._getStyles();
+ };
+ },
- return (
-
-
- {this.props.itemData.map((obj) => {
- return (
-
- );
- })}
-
-
- );
- }
-}
+ render() {
+ let styles = this._getStyles();
-List.propTypes = {
- itemData: React.PropTypes.array,
- onClick: React.PropTypes.func,
- style: React.PropTypes.object,
+ return (
+
+
+ {this.props.itemData.map((obj) => {
+ return (
+
+ );
+ })}
+
+
+ );
+ },
+ });
};
-
-List.defaultProps = {
- style: {},
-};
-
-export default List;
diff --git a/app/components/ListItem.jsx b/app/components/ListItem.jsx
index 3f254a6..73c7c91 100644
--- a/app/components/ListItem.jsx
+++ b/app/components/ListItem.jsx
@@ -1,17 +1,33 @@
-'use strict';
-
-import React from 'react';
+import stampit from 'react-stampit';
import Paper from 'material-ui/lib/paper';
import transitions from 'material-ui/lib/styles/transitions';
import typography from 'material-ui/lib/styles/typography';
+
import { mergeAndPrefix } from '../utils/stylePropable';
-class ListItem extends React.Component {
- constructor(props) {
- super(props);
+export default React => stampit(React, {
+ displayName: 'ListItem',
+
+ state: { hovered: false },
+
+ contextTypes: {
+ muiTheme: React.PropTypes.object,
+ },
+
+ propTypes: {
+ description: React.PropTypes.string,
+ hoverColor: React.PropTypes.string,
+ icon: React.PropTypes.string,
+ onClick: React.PropTypes.func,
+ onMouseOut: React.PropTypes.func,
+ onMouseOver: React.PropTypes.func,
+ title: React.PropTypes.string,
+ },
- this.state = {hovered: false};
- }
+ defaultProps: {
+ description: '',
+ title: '',
+ },
_getStyles() {
const theme = this.context.muiTheme.component.listItem;
@@ -68,21 +84,21 @@ class ListItem extends React.Component {
borderBottom: `1px solid ${theme.borderColor}`,
},
};
- }
+ },
_handleMouseOver(e) {
this.setState({hovered: true});
if (this.props.onMouseOver) {
this.props.onMouseOver(e);
}
- }
+ },
_handleMouseOut(e) {
this.setState({hovered: false});
if (this.props.onMouseOut) {
this.props.onMouseOut(e);
}
- }
+ },
render() {
const styles = this._getStyles();
@@ -116,26 +132,5 @@ class ListItem extends React.Component {
);
- }
-}
-
-ListItem.contextTypes = {
- muiTheme: React.PropTypes.object,
-};
-
-ListItem.propTypes = {
- description: React.PropTypes.string,
- hoverColor: React.PropTypes.string,
- icon: React.PropTypes.string,
- onClick: React.PropTypes.func,
- onMouseOut: React.PropTypes.func,
- onMouseOver: React.PropTypes.func,
- title: React.PropTypes.string,
-};
-
-ListItem.defaultProps = {
- description: '',
- title: '',
-};
-
-export default ListItem;
+ },
+});
diff --git a/app/components/Map.jsx b/app/components/Map.jsx
index cc732f9..d44158b 100644
--- a/app/components/Map.jsx
+++ b/app/components/Map.jsx
@@ -1,56 +1,59 @@
-'use strict';
-
-import React from 'react';
-import MarkerCluster from './MarkerCluster';
+import stampit from 'react-stampit';
import { Map as LeafletMap, TileLayer } from 'react-leaflet';
-class Map extends React.Component {
- render() {
- return (
-
-
-
-
- );
- }
-}
+import markerClusterFactory from './MarkerCluster';
-Map.propTypes = {
- attribution: React.PropTypes.string,
- center: React.PropTypes.array,
- focusMarker: React.PropTypes.object,
- markers: React.PropTypes.object,
- maxZoom: React.PropTypes.number,
- minZoom: React.PropTypes.number,
- newMarkerData: React.PropTypes.array,
- style: React.PropTypes.object,
- updateMarkers: React.PropTypes.func,
- url: React.PropTypes.string,
- zoom: React.PropTypes.number,
-};
+export default React => {
+ const MarkerCluster = markerClusterFactory(React);
-Map.defaultProps = {
- attribution: 'Imagery from
GIScience Research Group @ University of Heidelberg — Map data ©
OpenStreetMap',
- center: [0, 0],
- maxZoom: 16,
- minZoom: 3,
- style: {},
- url: 'http://openmapsurfer.uni-hd.de/tiles/roadsg/x={x}&y={y}&z={z}',
- zoom: 3,
-};
+ return stampit(React, {
+ displayName: 'GeoMap',
-export default Map;
+ propTypes: {
+ attribution: React.PropTypes.string,
+ center: React.PropTypes.array,
+ focusMarker: React.PropTypes.object,
+ markers: React.PropTypes.object,
+ maxZoom: React.PropTypes.number,
+ minZoom: React.PropTypes.number,
+ newMarkerData: React.PropTypes.array,
+ style: React.PropTypes.object,
+ updateMarkers: React.PropTypes.func,
+ url: React.PropTypes.string,
+ zoom: React.PropTypes.number,
+ },
+
+ defaultProps: {
+ attribution: 'Imagery from
GIScience Research Group @ University of Heidelberg — Map data ©
OpenStreetMap',
+ center: [0, 0],
+ maxZoom: 16,
+ minZoom: 3,
+ style: {},
+ url: 'http://openmapsurfer.uni-hd.de/tiles/roadsg/x={x}&y={y}&z={z}',
+ zoom: 3,
+ },
+
+ render() {
+ return (
+
+
+
+
+ );
+ },
+ });
+};
diff --git a/app/components/MarkerCluster.jsx b/app/components/MarkerCluster.jsx
index a405ded..6fb4ff2 100644
--- a/app/components/MarkerCluster.jsx
+++ b/app/components/MarkerCluster.jsx
@@ -1,83 +1,81 @@
-'use strict';
-
-import React from 'react';
import Leaflet from 'leaflet';
-import MarkerPopup from './MarkerPopup';
-import { MapLayer } from 'react-leaflet';
-
+import stampit from 'react-stampit';
require('leaflet.markercluster');
-class MarkerCluster extends MapLayer {
- componentWillMount() {
- super.componentWillMount();
-
- this.leafletElement = Leaflet.markerClusterGroup();
- }
-
- componentWillReceiveProps(nextProps) {
- super.componentWillReceiveProps(nextProps);
-
- // add markers to cluster layer
- if (nextProps.newMarkerData.length > 0) {
- let markers = Object.assign({}, this.props.markers);
- let newMarkers = [];
-
- nextProps.newMarkerData.forEach((obj) => {
- let markerPopup = React.renderToStaticMarkup(
-
- );
-
- let leafletMarker = Leaflet.marker(obj.latLng)
- .bindPopup(markerPopup, {maxHeight: 350, maxWidth: 250, minWidth: 250})
- .on('click', () => this.props.map.panTo(obj.latLng));
-
- markers[obj.id] = leafletMarker;
- newMarkers.push(leafletMarker);
- });
-
- this.leafletElement.addLayers(newMarkers);
-
- setTimeout(() => {
- this.props.updateMarkers(markers);
- }, 0);
- }
-
- // zoom to particular marker
- if (Object.keys(nextProps.focusMarker).length > 0) {
- let marker = this.props.markers[nextProps.focusMarker.id];
-
- this.leafletElement.zoomToShowLayer(marker, () => {
- this.props.map.panTo(nextProps.focusMarker.latLng);
- marker.openPopup();
- });
- }
- }
-
- shouldComponentUpdate() {
- return false;
- }
-
- render() {
- return null;
- }
-}
-
-MarkerCluster.propTypes = {
- focusMarker: React.PropTypes.object,
- map: React.PropTypes.object,
- markers: React.PropTypes.object,
- newMarkerData: React.PropTypes.array,
- updateMarkers: React.PropTypes.func,
+import leafletMap from './lib/leafletMap';
+import leafletUtil from './lib/leafletUtil';
+import markerPopupFactory from './MarkerPopup';
+
+export default React => {
+ const MarkerPopup = markerPopupFactory(React);
+
+ return stampit(React, {
+ displayName: 'MarkerCluster',
+
+ propTypes: {
+ focusMarker: React.PropTypes.object,
+ markers: React.PropTypes.object,
+ newMarkerData: React.PropTypes.array,
+ updateMarkers: React.PropTypes.func,
+ },
+
+ defaultProps: {
+ markers: {},
+ newMarkerData: [],
+ focusMarker: {},
+ },
+
+ componentWillMount() {
+ this.leafletElement = Leaflet.markerClusterGroup();
+ },
+
+ componentWillReceiveProps(nextProps) {
+ // add markers to cluster layer
+ if (nextProps.newMarkerData.length > 0) {
+ let markers = Object.assign({}, this.props.markers);
+ let newMarkers = [];
+
+ nextProps.newMarkerData.forEach((obj) => {
+ let markerPopup = React.renderToStaticMarkup(
+
+ );
+
+ let leafletMarker = Leaflet.marker(obj.latLng)
+ .bindPopup(markerPopup, {maxHeight: 350, maxWidth: 250, minWidth: 250})
+ .on('click', () => this.props.map.panTo(obj.latLng));
+
+ markers[obj.id] = leafletMarker;
+ newMarkers.push(leafletMarker);
+ });
+
+ this.leafletElement.addLayers(newMarkers);
+
+ setTimeout(() => {
+ this.props.updateMarkers(markers);
+ }, 0);
+ }
+
+ // zoom to particular marker
+ if (Object.keys(nextProps.focusMarker).length > 0) {
+ let marker = this.props.markers[nextProps.focusMarker.id];
+
+ this.leafletElement.zoomToShowLayer(marker, () => {
+ this.props.map.panTo(nextProps.focusMarker.latLng);
+ marker.openPopup();
+ });
+ }
+ },
+
+ shouldComponentUpdate() {
+ return false;
+ },
+
+ render() {
+ return null;
+ },
+ }).compose(leafletUtil, leafletMap);
};
-
-MarkerCluster.defaultProps = {
- markers: {},
- newMarkerData: [],
- focusMarker: {},
-};
-
-export default MarkerCluster;
diff --git a/app/components/MarkerPopup.jsx b/app/components/MarkerPopup.jsx
index 5e8fc97..139050f 100644
--- a/app/components/MarkerPopup.jsx
+++ b/app/components/MarkerPopup.jsx
@@ -1,8 +1,14 @@
-'use strict';
+import stampit from 'react-stampit';
-import React from 'react';
+export default React => stampit(React, {
+ displayName: 'MarkerPopup',
+
+ propTypes: {
+ caption: React.PropTypes.string,
+ imgUrl: React.PropTypes.string,
+ profileUrl: React.PropTypes.string,
+ },
-class MarkerPopup extends React.Component {
_getStyles() {
return {
caption: {
@@ -13,7 +19,7 @@ class MarkerPopup extends React.Component {
margin: 'auto',
},
};
- }
+ },
render() {
const styles = this._getStyles();
@@ -27,13 +33,5 @@ class MarkerPopup extends React.Component {
{this.props.caption}
);
- }
-}
-
-MarkerPopup.propTypes = {
- caption: React.PropTypes.string,
- imgUrl: React.PropTypes.string,
- profileUrl: React.PropTypes.string,
-};
-
-export default MarkerPopup;
+ },
+});
diff --git a/app/components/TimeoutTransitionGroup.jsx b/app/components/TimeoutTransitionGroup.jsx
index d629250..099df8b 100644
--- a/app/components/TimeoutTransitionGroup.jsx
+++ b/app/components/TimeoutTransitionGroup.jsx
@@ -1,5 +1,3 @@
-'use strict';
-
/**
* The CSSTransitionGroup component uses the 'transitionend' event, which
* browsers will not send for any number of reasons, including the
@@ -16,8 +14,7 @@
* addons and under the Apache 2.0 License.
*/
-import React from 'react/addons';
-const ReactTransitionGroup = React.addons.TransitionGroup;
+import stampit from 'react-stampit';
const TICK = 17;
@@ -97,15 +94,7 @@ function removeStyle(element, style) {
return element;
}
-class TimeoutTransitionGroupChild extends React.Component {
- constructor() {
- super();
-
- this._transition = this._transition.bind(this);
- this._queueStyle = this._queueStyle.bind(this);
- this._flushClassNameQueue = this._flushClassNameQueue.bind(this);
- }
-
+const timeoutTransitionGroupChildFactory = React => stampit(React, {
_transition(animationType, finishCallback) {
let node = React.findDOMNode(this);
@@ -133,15 +122,15 @@ class TimeoutTransitionGroupChild extends React.Component {
// Need to do this to actually trigger a transition.
this._queueStyle(this.props.style[animationType].active);
- }
+ },
_queueStyle(style) {
this.styleQueue.push(style);
if (!this.timeout) {
- this.timeout = setTimeout(this._flushClassNameQueue, TICK);
+ this.timeout = setTimeout(this._flushClassNameQueue.bind(this), TICK);
}
- }
+ },
_flushClassNameQueue() {
this.styleQueue.forEach((style) => {
@@ -150,11 +139,11 @@ class TimeoutTransitionGroupChild extends React.Component {
this.styleQueue.length = 0;
this.timeout = null;
- }
+ },
componentWillMount() {
this.styleQueue = [];
- }
+ },
componentWillUnmount() {
if (this.timeout) {
@@ -164,7 +153,7 @@ class TimeoutTransitionGroupChild extends React.Component {
if (this.animationTimeout) {
clearTimeout(this.animationTimeout);
}
- }
+ },
componentWillEnter(done) {
if (this.props.enter) {
@@ -172,7 +161,7 @@ class TimeoutTransitionGroupChild extends React.Component {
} else {
done();
}
- }
+ },
componentWillLeave(done) {
if (this.props.leave) {
@@ -180,59 +169,58 @@ class TimeoutTransitionGroupChild extends React.Component {
} else {
done();
}
- }
+ },
render() {
return React.Children.only(this.props.children);
- }
-}
-
-class TimeoutTransitionGroup extends React.Component {
- constructor() {
- super();
-
- this._wrapChild = this._wrapChild.bind(this);
- }
-
- _wrapChild(child) {
- return (
-