Add babel react preset and migrate react components to jsx (#875)

This commit is contained in:
Hossein Moradi Davijani 2019-09-16 22:52:56 +04:30 committed by Xintong Xia
parent 9e7edb1104
commit 4b44f94f77
14 changed files with 238 additions and 264 deletions

View File

@ -4,7 +4,7 @@ const getBabelConfig = require('ocular-dev-tools/config/babel.config');
module.exports = api => {
const config = getBabelConfig(api);
config.presets = (config.presets || []).concat('@babel/flow');
config.presets = (config.presets || []).concat(['@babel/flow', '@babel/preset-react']);
config.plugins = (config.plugins || []).concat('@babel/proposal-class-properties');
return config;

View File

@ -18,7 +18,7 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import {PureComponent, createElement, createRef} from 'react';
import React, {PureComponent, createRef} from 'react';
import PropTypes from 'prop-types';
import MapContext from './map-context';
@ -126,9 +126,13 @@ export default class BaseControl<
}
render() {
return createElement(MapContext.Consumer, null, context => {
this._context = context;
return this._render();
});
return (
<MapContext.Consumer>
{context => {
this._context = context;
return this._render();
}}
</MapContext.Consumer>
);
}
}

View File

@ -23,7 +23,7 @@
import {document} from '../utils/globals';
import PropTypes from 'prop-types';
import BaseControl from './base-control';
import {createElement} from 'react';
import React from 'react';
import mapboxgl from '../utils/mapboxgl';
import type {BaseControlProps} from './base-control';
@ -106,13 +106,15 @@ export default class FullscreenControl extends BaseControl<
};
_renderButton(type: string, label: string, callback: Function) {
return createElement('button', {
key: type,
className: `mapboxgl-ctrl-icon mapboxgl-ctrl-${type}`,
type: 'button',
title: label,
onClick: callback
});
return (
<button
key={type}
className={`mapboxgl-ctrl-icon mapboxgl-ctrl-${type}`}
type="button"
title={label}
onClick={callback}
/>
);
}
_render() {
@ -125,13 +127,10 @@ export default class FullscreenControl extends BaseControl<
const type = isFullscreen ? 'shrink' : 'fullscreen';
return createElement(
'div',
{
className: `mapboxgl-ctrl mapboxgl-ctrl-group ${className}`,
ref: this._containerRef
},
[this._renderButton(type, 'Toggle fullscreen', this._onClickFullscreen)]
return (
<div className={`mapboxgl-ctrl mapboxgl-ctrl-group ${className}`} ref={this._containerRef}>
{this._renderButton(type, 'Toggle fullscreen', this._onClickFullscreen)}
</div>
);
}
}

View File

@ -1,7 +1,7 @@
// @flow
/* global window */
import {createElement, createRef} from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import WebMercatorViewport from 'viewport-mercator-project';
@ -197,14 +197,16 @@ export default class GeolocateControl extends BaseControl<
};
_renderButton = (type: string, label: string, callback: Function) => {
return createElement('button', {
key: type,
className: `mapboxgl-ctrl-icon mapboxgl-ctrl-${type}`,
ref: this._geolocateButtonRef,
type: 'button',
title: label,
onClick: callback
});
return (
<button
key={type}
className={`mapboxgl-ctrl-icon mapboxgl-ctrl-${type}`}
ref={this._geolocateButtonRef}
type="button"
title={label}
onClick={callback}
/>
);
};
_renderMarker = () => {
@ -214,17 +216,19 @@ export default class GeolocateControl extends BaseControl<
return null;
}
// $FlowFixMe
return createElement(Marker, {
key: 'location-maker',
ref: this._markerRef,
className: 'mapboxgl-user-location-dot',
longitude: markerPosition.longitude,
latitude: markerPosition.latitude,
onContextMenu: e => e.preventDefault(),
captureDrag: false,
captureDoubleClick: false
});
return (
// $FlowFixMe
<Marker
key="location-maker"
ref={this._markerRef}
className="mapboxgl-user-location-dot"
longitude={markerPosition.longitude}
latitude={markerPosition.latitude}
onContextMenu={e => e.preventDefault()}
captureDrag={false}
captureDoubleClick={false}
/>
);
};
_render() {
@ -233,19 +237,19 @@ export default class GeolocateControl extends BaseControl<
}
const {className, style} = this.props;
return createElement('div', null, [
this._renderMarker(),
createElement(
'div',
{
key: 'geolocate-control',
className: `mapboxgl-ctrl mapboxgl-ctrl-group ${className}`,
ref: this._containerRef,
style,
onContextMenu: e => e.preventDefault()
},
this._renderButton('geolocate', 'Geolocate', this._onClickGeolocate)
)
]);
return (
<div>
{this._renderMarker()}
<div
key="geolocate-control"
className={`mapboxgl-ctrl mapboxgl-ctrl-group ${className}`}
ref={this._containerRef}
style={style}
onContextMenu={e => e.preventDefault()}
>
{this._renderButton('geolocate', 'Geolocate', this._onClickGeolocate)}
</div>
</div>
);
}
}

View File

@ -1,5 +1,5 @@
// @flow
import {PureComponent, createElement, createRef} from 'react';
import React, {PureComponent, createRef} from 'react';
import PropTypes from 'prop-types';
import StaticMap from './static-map';
@ -499,29 +499,22 @@ export default class InteractiveMap extends PureComponent<InteractiveMapProps, S
cursor: getCursor(this.state)
});
return createElement(
MapContext.Provider,
{value: this._interactiveContext},
createElement(
'div',
{
key: 'event-canvas',
ref: this._eventCanvasRef,
style: eventCanvasStyle
},
createElement(
StaticMap,
Object.assign({}, this.props, {
width: '100%',
height: '100%',
style: null,
onResize: this._onResize,
onLoad: this._onLoad,
ref: this._staticMapRef,
children: this.props.children
})
)
)
return (
<MapContext.Provider value={this._interactiveContext}>
<div key="event-canvas" ref={this._eventCanvasRef} style={eventCanvasStyle}>
<StaticMap
{...this.props}
width="100%"
height="100%"
style={null}
onResize={this._onResize}
onLoad={this._onLoad}
ref={this._staticMapRef}
>
{this.props.children}
</StaticMap>
</div>
</MapContext.Provider>
);
}
}

View File

@ -18,7 +18,7 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import {createElement} from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import DraggableControl from './draggable-control';
@ -83,11 +83,14 @@ export default class Marker extends DraggableControl<MarkerProps> {
cursor: draggable ? (dragPos ? 'grabbing' : 'grab') : 'auto'
};
return createElement('div', {
className: `mapboxgl-marker ${className}`,
ref: this._containerRef,
style: containerStyle,
children: this.props.children
});
return (
<div
className={`mapboxgl-marker ${className}`}
ref={this._containerRef}
style={containerStyle}
>
{this.props.children}
</div>
);
}
}

View File

@ -1,5 +1,5 @@
// @flow
import {createElement} from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import BaseControl from './base-control';
@ -95,38 +95,35 @@ export default class NavigationControl extends BaseControl<
_renderCompass() {
const {bearing} = this._context.viewport;
return createElement('span', {
className: 'mapboxgl-ctrl-compass-arrow',
style: {transform: `rotate(${-bearing}deg)`}
});
return (
<span className="mapboxgl-ctrl-compass-arrow" style={{transform: `rotate(${-bearing}deg)`}} />
);
}
_renderButton(type: string, label: string, callback: Function, children: any) {
return createElement('button', {
key: type,
className: `mapboxgl-ctrl-icon mapboxgl-ctrl-${type}`,
type: 'button',
title: label,
onClick: callback,
children
});
return (
<button
key={type}
className={`mapboxgl-ctrl-icon mapboxgl-ctrl-${type}`}
type="button"
title={label}
onClick={callback}
>
{children}
</button>
);
}
_render() {
const {className, showCompass, showZoom} = this.props;
return createElement(
'div',
{
className: `mapboxgl-ctrl mapboxgl-ctrl-group ${className}`,
ref: this._containerRef
},
[
showZoom && this._renderButton('zoom-in', 'Zoom In', this._onZoomIn),
showZoom && this._renderButton('zoom-out', 'Zoom Out', this._onZoomOut),
showCompass &&
this._renderButton('compass', 'Reset North', this._onResetNorth, this._renderCompass())
]
return (
<div className={`mapboxgl-ctrl mapboxgl-ctrl-group ${className}`} ref={this._containerRef}>
{showZoom && this._renderButton('zoom-in', 'Zoom In', this._onZoomIn)}
{showZoom && this._renderButton('zoom-out', 'Zoom Out', this._onZoomOut)}
{showCompass &&
this._renderButton('compass', 'Reset North', this._onResetNorth, this._renderCompass())}
</div>
);
}
}

View File

@ -18,7 +18,7 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import {createElement, createRef} from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import BaseControl from './base-control';
@ -182,11 +182,7 @@ export default class Popup extends BaseControl<PopupProps, *, HTMLDivElement> {
_renderTip(positionType: PositionType) {
const {tipSize} = this.props;
return createElement('div', {
key: 'tip',
className: 'mapboxgl-popup-tip',
style: {borderWidth: tipSize}
});
return <div key="tip" className="mapboxgl-popup-tip" style={{borderWidth: tipSize}} />;
}
_renderContent() {
@ -194,27 +190,20 @@ export default class Popup extends BaseControl<PopupProps, *, HTMLDivElement> {
// If eventManager does not exist (using with static map), listen to React event
const onClick = this._context.eventManager ? null : this._onClick;
return createElement(
'div',
{
key: 'content',
ref: this._contentRef,
className: 'mapboxgl-popup-content',
onClick
},
[
closeButton &&
createElement(
'button',
{
key: 'close-button',
className: 'mapboxgl-popup-close-button',
type: 'button'
},
'×'
),
children
]
return (
<div
key="content"
ref={this._contentRef}
className="mapboxgl-popup-content"
onClick={onClick}
>
{closeButton && (
<button key="close-button" className="mapboxgl-popup-close-button" type="button">
×
</button>
)}
{children}
</div>
);
}
@ -226,14 +215,15 @@ export default class Popup extends BaseControl<PopupProps, *, HTMLDivElement> {
const positionType = this._getPosition(x, y);
const containerStyle = this._getContainerStyle(x, y, z, positionType);
return createElement(
'div',
{
className: `mapboxgl-popup mapboxgl-popup-anchor-${positionType} ${className}`,
style: containerStyle,
ref: this._containerRef
},
[this._renderTip(positionType), this._renderContent()]
return (
<div
className={`mapboxgl-popup mapboxgl-popup-anchor-${positionType} ${className}`}
style={containerStyle}
ref={this._containerRef}
>
{this._renderTip(positionType)}
{this._renderContent()}
</div>
);
}
}

View File

@ -18,7 +18,7 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import {PureComponent, createElement, createRef} from 'react';
import React, {PureComponent, createRef} from 'react';
import PropTypes from 'prop-types';
import {normalizeStyle} from '../utils/style-utils';
@ -242,11 +242,15 @@ export default class StaticMap extends PureComponent<StaticMapProps, State> {
left: 0,
top: 0
};
return createElement('div', {key: 'warning', id: 'no-token-warning', style}, [
createElement('h3', {key: 'header'}, NO_TOKEN_WARNING),
createElement('div', {key: 'text'}, 'For information on setting up your basemap, read'),
createElement('a', {key: 'link', href: TOKEN_DOC_URL}, 'Note on Map Tokens')
]);
return (
<div key="warning" id="no-token-warning" style={style}>
<h3 key="header">NO_TOKEN_WARNING</h3>
<div key="text">For information on setting up your basemap, read</div>
<a key="link" href={TOKEN_DOC_URL}>
Note on Map Tokens
</a>
</div>
);
}
return null;
@ -256,30 +260,31 @@ export default class StaticMap extends PureComponent<StaticMapProps, State> {
const {width = Number(this.props.width), height = Number(this.props.height)} = dimensions;
this._updateMapSize(width, height);
return createElement(MapContext.Consumer, null, interactiveContext => {
const context = Object.assign({}, interactiveContext, {
viewport: new WebMercatorViewport(
// $FlowFixMe
Object.assign({}, this.props, this.props.viewState, {
width,
height
})
),
map: this._map,
mapContainer: interactiveContext.mapContainer || this._mapContainerRef.current
});
return createElement(
MapContext.Provider,
{value: context},
createElement('div', {
key: 'map-overlays',
className: 'overlays',
style: CONTAINER_STYLE,
children: this.props.children
})
);
});
return (
<MapContext.Consumer>
{interactiveContext => {
const context = {
...interactiveContext,
// $FlowFixMe
viewport: new WebMercatorViewport({
...this.props,
...this.props.viewState,
width,
height
}),
map: this._map,
mapContainer: interactiveContext.mapContainer || this._mapContainerRef.current
};
return (
<MapContext.Provider value={context}>
<div key="map-overlays" className="overlays" style={CONTAINER_STYLE}>
{this.props.children}
</div>
</MapContext.Provider>
);
}}
</MapContext.Consumer>
);
}
render() {
@ -297,31 +302,21 @@ export default class StaticMap extends PureComponent<StaticMapProps, State> {
visibility: visible ? 'inherit' : 'hidden'
});
return createElement('div', {
key: 'map-container',
style: mapContainerStyle,
ref: this._mapContainerRef,
children: [
createElement('div', {
key: 'map-mapbox',
ref: this._mapboxMapRef,
style: mapStyle,
className
}),
// AutoSizer is a pure component and does not rerender when map props change
// rebind the callback so that it's triggered every render pass
createElement(
AutoSizer,
{
key: 'autosizer',
disableWidth: Number.isFinite(width),
disableHeight: Number.isFinite(height),
onResize: this.props.onResize
},
this._renderOverlays.bind(this)
),
this._renderNoTokenWarning()
]
});
return (
<div key="map-container" style={mapContainerStyle} ref={this._mapContainerRef}>
<div key="map-mapbox" ref={this._mapboxMapRef} style={mapStyle} className={className} />
{/* AutoSizer is a pure component and does not rerender when map props change */}
{/* rebind the callback so that it's triggered every render pass */}
<AutoSizer
key="autosizer"
disableWidth={Number.isFinite(width)}
disableHeight={Number.isFinite(height)}
onResize={this.props.onResize}
>
{this._renderOverlays.bind(this)}
</AutoSizer>
{this._renderNoTokenWarning()}
</div>
);
}
}

View File

@ -19,7 +19,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import {createElement} from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import BaseControl from '../components/base-control';
import {window} from '../utils/globals';
@ -87,17 +87,19 @@ export default class CanvasOverlay extends BaseControl<CanvasOverlayProps, *, HT
} = this._context;
this._redraw();
return createElement('canvas', {
ref: this._containerRef,
width: width * pixelRatio,
height: height * pixelRatio,
style: {
width: `${width}px`,
height: `${height}px`,
position: 'absolute',
left: 0,
top: 0
}
});
return (
<canvas
ref={this._containerRef}
width={width * pixelRatio}
height={height * pixelRatio}
style={{
width: `${width}px`,
height: `${height}px`,
position: 'absolute',
left: 0,
top: 0
}}
/>
);
}
}

View File

@ -20,7 +20,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import {createElement} from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import BaseControl from '../components/base-control';
@ -60,19 +60,16 @@ export default class HTMLOverlay extends BaseControl<HTMLOverlayProps, *, HTMLDi
this.props.style
);
return createElement(
'div',
{
ref: this._containerRef,
style
},
this.props.redraw({
width: viewport.width,
height: viewport.height,
isDragging,
project: viewport.project.bind(viewport),
unproject: viewport.unproject.bind(viewport)
})
return (
<div ref={this._containerRef} style={style}>
{this.props.redraw({
width: viewport.width,
height: viewport.height,
isDragging,
project: viewport.project.bind(viewport),
unproject: viewport.unproject.bind(viewport)
})}
</div>
);
}
}

View File

@ -20,7 +20,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import {createElement} from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import BaseControl from '../components/base-control';
@ -58,21 +58,16 @@ export default class SVGOverlay extends BaseControl<SVGOverlayProps, *, Element>
this.props.style
);
return createElement(
'svg',
{
width: viewport.width,
height: viewport.height,
ref: this._containerRef,
style
},
this.props.redraw({
width: viewport.width,
height: viewport.height,
isDragging,
project: viewport.project.bind(viewport),
unproject: viewport.unproject.bind(viewport)
})
return (
<svg width={viewport.width} height={viewport.height} ref={this._containerRef} style={style}>
{this.props.redraw({
width: viewport.width,
height: viewport.height,
isDragging,
project: viewport.project.bind(viewport),
unproject: viewport.unproject.bind(viewport)
})}
</svg>
);
}
}

View File

@ -1,6 +1,6 @@
/* global setTimeout, clearTimeout */
import MapGL, {InteractiveMap} from 'react-map-gl';
import {createElement} from 'react';
import React from 'react';
import ReactTestUtils from 'react-test-renderer/shallow';
import ReactTestRenderer from 'react-test-renderer';
import sinon from 'sinon';
@ -81,7 +81,7 @@ const TEST_CASES = [
test('InteractiveMap#default export', t => {
t.ok(MapGL, 'InteractiveMap is defined');
const map = createElement(MapGL, defaultProps);
const map = <MapGL {...defaultProps} />;
const result = ReactTestUtils.createRenderer().render(map);
t.ok(result, 'InteractiveMap rendered');
@ -91,7 +91,7 @@ test('InteractiveMap#default export', t => {
test('InteractiveMap#named export', t => {
t.ok(InteractiveMap, 'InteractiveMap is defined');
const map = createElement(InteractiveMap, defaultProps);
const map = <InteractiveMap {...defaultProps} />;
const result = ReactTestUtils.createRenderer().render(map);
t.ok(result, 'InteractiveMap rendered');
@ -139,7 +139,7 @@ TEST_CASES.forEach(testCase => {
const props = Object.assign({}, testCase.props, {onLoad});
const map = createElement(InteractiveMap, props);
const map = <InteractiveMap {...props} />;
result = ReactTestRenderer.create(map);
@ -157,8 +157,8 @@ TEST_CASES.forEach(testCase => {
// children are no longer rendered on first pass due to auto sizer
test.skip('Interactive map renders children on first render', t => {
const childComponent = sinon.spy(() => null);
const child = createElement(childComponent);
const map = createElement(InteractiveMap, defaultProps, child);
const child = <childComponent />;
const map = <InteractiveMap {...defaultProps}>{child}</InteractiveMap>;
try {
const result = ReactTestRenderer.create(map);
// Unmount the component to avoid creating too many maps
@ -178,7 +178,7 @@ test('Interactive map#call transformRequest callback when provided', t => {
const props = Object.assign({}, defaultProps, {transformRequest});
const map = createElement(InteractiveMap, props);
const map = <InteractiveMap {...props} />;
// const result = ReactTestUtils.createRenderer().render(map);
const result = ReactTestRenderer.create(map);

View File

@ -26,19 +26,14 @@ const mockInteractiveContext = Object.assign({}, mockStaticContext, {
test('Marker#renders children', t => {
t.ok(Marker, 'Marker is defined');
const marker = React.createElement(
Marker,
{
latitude: 37,
longitude: -122
},
React.createElement('div', {className: 'test-marker'}, ['hello'])
const marker = (
<Marker latitude={37} longitude={-122}>
<div className="test-marker">hello</div>
</Marker>
);
const staticUsage = React.createElement(MapContext.Provider, {value: mockStaticContext}, marker);
const interactiveUsage = React.createElement(
MapContext.Provider,
{value: mockInteractiveContext},
marker
const staticUsage = <MapContext.Provider value={mockStaticContext}>{marker}</MapContext.Provider>;
const interactiveUsage = (
<MapContext.Provider value={mockInteractiveContext}>{marker}</MapContext.Provider>
);
const result = ReactTestRenderer.create(staticUsage);