diff --git a/src/App.css b/src/App.css index 9aad549..5bfab5a 100644 --- a/src/App.css +++ b/src/App.css @@ -107,6 +107,7 @@ label .badge{position:relative;top:2px;} .drop-menu{position:absolute;background-color:#FFF;color:#273237; padding:0.25rem;border-radius:0.25rem;z-index:999;border:1px solid #8FA3AE; left:0;right:0;} +.drop-menu-locations{top:6px;right:45px;left:auto;width:140px;position:fixed;z-index:10000;} .content-title-options .drop-menu{top:20px;right:0;} .drop-item{color:#273237;white-space:nowrap;font-size:0.8rem;padding:0.25rem 0.5rem;cursor:pointer;} @@ -115,11 +116,6 @@ label .badge{position:relative;top:2px;} .dropdown-cover{position:fixed;top:0;bottom:0;left:0;right:0;background-color:transparent;} -.dropdown-menu{padding:0;} -.dropdown-menu a{padding:0.25rem 0.5rem;font-size:0.8rem;} -.dropdown-menu a.active{background-color:#EEEEEE;color:#273237;} -.dropdown-divider{margin:0.15rem 0;} - .exp-ml{margin-left:12px;} .exp-arrow{left:-16px;top:10px;border-radius:4px;width:14px;height:14px; position:relative;color:#FFFFFF;background-color:#273237;cursor:pointer;} @@ -228,7 +224,7 @@ label .badge{position:relative;top:2px;} .mapboxgl-ctrl-icon.active{background-color:#00ACC1;color:#FFF;} .mapboxgl-ctrl-icon.active:hover{background-color:#0197A7!important;color:#FFF;} -.mapboxgl-ctrl-icon i{position:relative;top:-1px;} +.mapboxgl-ctrl-icon i{position:relative;top:1px;font-size:1rem;} .mapboxgl-popup-close-button{color:#AEAEAE;} .mapboxgl-popup-close-button:hover{color:#747474;} @@ -312,6 +308,7 @@ label .badge{position:relative;top:2px;} .tooltip{font-size:0.7rem;} .tooltip-source{position:absolute;bottom:0;left:0;right:0;text-align:center;height:0;} +.tooltip-source.tooltip-origin-left{bottom:0;left:0;top:0;text-align:center;width:0;} .tooltip-point{display:inline-block;position:relative;} .tooltip-bubble{position:absolute;right:-11px;z-index:1000;top:-4px; @@ -330,6 +327,10 @@ label .badge{position:relative;top:2px;} .tooltip-trigger:hover .tooltip-source:hover .tooltip-bubble{display:none;} .tooltip-trigger{position:relative;} +.tooltip-source.tooltip-origin-left .tooltip-bubble {right:11px;top:-15px;} +.tooltip-source.tooltip-origin-left .tooltip-bubble span:after{right:-8px;top:11px;width:6px;height:8px; + border-left:4px solid #1B2124;border-bottom:4px solid transparent;border-top:4px solid transparent;} + .w-max-500{max-width:500px;} #map{position:absolute;top:0;bottom:0;left:0;right:0;width:100%;} diff --git a/src/component/Field/FieldAC.jsx b/src/component/Field/FieldAC.jsx index 01ef9fc..ffc1bfb 100644 --- a/src/component/Field/FieldAC.jsx +++ b/src/component/Field/FieldAC.jsx @@ -159,39 +159,39 @@ class FieldAC extends React.Component {
{label && }
- this.handleBlur(false)} open={focused}> - - {focused && ( -
- {options.map((exp,i)=>{ - - if (exp.value.indexOf(inputValue) === -1) return null - count++ - if (count > maxDropdowns) return null - - let className = 'drop-item' - if (selected === exp.value) className += ' active' - - return ( -
{this.handleSelect(exp.value)}} - key={exp.value}> - - {exp.value} -
- ) - })} -
- )} - -
+ this.handleBlur(false)} open={focused}> + + {focused && ( +
+ {options.map((exp,i)=>{ + + if (exp.value.indexOf(inputValue) === -1) return null + count++ + if (count > maxDropdowns) return null + + let className = 'drop-item' + if (selected === exp.value) className += ' active' + + return ( +
{this.handleSelect(exp.value)}} + key={exp.value}> + + {exp.value} +
+ ) + })} +
+ )} + +
diff --git a/src/component/Icon/constants.js b/src/component/Icon/constants.js index 01ad398..6c59888 100644 --- a/src/component/Icon/constants.js +++ b/src/component/Icon/constants.js @@ -30,7 +30,8 @@ const icons = { 'layer-line': 'fa-pen-nib', 'layer-raster': 'fa-satellite', 'layer-symbol': 'fa-text', - 'layer-fill-extrusion': 'fa-text', + location: 'fa-location', + 'map-focus': 'fa-map-marker', refresh: 'fa-redo', remove: 'fa-trash', diff --git a/src/component/Map/MapMapbox.jsx b/src/component/Map/MapMapbox.jsx index c6cc5fe..7ba49a4 100644 --- a/src/component/Map/MapMapbox.jsx +++ b/src/component/Map/MapMapbox.jsx @@ -10,14 +10,17 @@ import modelStyle from '../../model/style' import MapboxGl from 'mapbox-gl' import 'mapbox-gl/dist/mapbox-gl.css' +import constants from './constants' import utilUrl from '../../utility/utilUrl' +import Dropdown from '../Dropdown' import MapMapboxControls from './MapMapboxControls' class CustomControls { + handleLocationToggle = null onAdd(map) { this._container = document.createElement('div') - ReactDOM.render(,this._container) + ReactDOM.render(,this._container) return this._container } onRemove() { @@ -110,8 +113,10 @@ class MapMapbox extends React.Component { hash:true }) + const Controls = new CustomControls({}) + Controls.handleLocationToggle = this.handleLocationToggle - map.addControl(new CustomControls({})) + map.addControl(Controls) map.addControl(new MapboxGl.AttributionControl({ compact: true @@ -221,6 +226,7 @@ class MapMapbox extends React.Component { this.state = { debugLines: null, mapLoaded: false, + locationShow: false, } this.container = null // node to put map in @@ -238,6 +244,29 @@ class MapMapbox extends React.Component { modelMap.actions.setFocus({point}) } + handleLocationSelect = (location)=>{ + this.map.flyTo({ + center: [location.lng, location.lat], + zoom: location.zoom + }) + } + + handleLocationClose = ()=>{ + this.setState({ + locationShow:false + }) + } + + handleLocationToggle = (show)=>{ + const {locationShow} = this.state + + if (locationShow){ + this.setState({locationShow:false}) + } else { + this.setState({locationShow:true}) + } + } + handleMapError = (error)=>{ const {style} = this.props @@ -288,8 +317,31 @@ class MapMapbox extends React.Component { } render (){ + const {locationShow} = this.state + return ( -
this.container = el}>
+ +
this.container = el}>
+ this.handleLocationClose()} open={locationShow}> + {locationShow && ( +
+ {constants.locations.map((loc,i)=>{ + + const className = 'drop-item interactive' + return ( +
{this.handleLocationSelect(loc)}} + key={i}> + + {loc.label} +
+ ) + })} +
+ )} +
+
) } diff --git a/src/component/Map/MapMapboxControls.jsx b/src/component/Map/MapMapboxControls.jsx index d9ddd19..5848dfc 100644 --- a/src/component/Map/MapMapboxControls.jsx +++ b/src/component/Map/MapMapboxControls.jsx @@ -1,55 +1,58 @@ import React from 'react' import PropTypes from 'prop-types' import Icon from '../Icon' +import Tooltip from '../Tooltip' -export default class MapMapboxControls extends React.Component { - static propTypes = { - map:PropTypes.object - } +class MapMapboxControls extends React.Component { constructor (props){ super(props) - const {map} = props this.state = { - debugLines:false - } - - this.handle = { - debugLinesToggle:()=>{ - if (this.state.debugLines){ - this.setState({debugLines:false}) - map.showTileBoundaries = false - } else { - this.setState({debugLines:true}) - map.showTileBoundaries = true - } - } - } - - for (let i in this.handle){ - this.handle[i] = this.handle[i].bind(this) + debugLines:false, } } - componentDidMount(){ - this.tooltip() - } + handleDebugLinesToggle = ()=>{ + const {map} = this.props, + {debugLines} = this.state - tooltip(){ - //console.log('ref:',) - //window.$(this.tooltipsRef).children().tooltip() + if (debugLines){ + this.setState({debugLines:false}) + map.showTileBoundaries = false + } else { + this.setState({debugLines:true}) + map.showTileBoundaries = true + } } render (){ - - const className = 'mapboxgl-ctrl-icon'+(this.state.debugLines? ' active': '') - - return
this.tooltipsRef = ref}> - -
+ const {handleLocationToggle} = this.props, + {debugLines} = this.state + + return ( + +
+ + +
+
+ + +
+
+ ) } } + +MapMapboxControls.propTypes = { + handleLocationToggle: PropTypes.func, + map:PropTypes.object, +} + +export default MapMapboxControls diff --git a/src/component/Map/constants.js b/src/component/Map/constants.js new file mode 100644 index 0000000..eb3a196 --- /dev/null +++ b/src/component/Map/constants.js @@ -0,0 +1,53 @@ +const locations = [{ + "key":"sd", + "label":"San Diego", + "lat":32.72, + "lng":-117.15, + "zoom":11 +},{ + "key":"la", + "label":"Los Angeles", + "lat":34.04, + "lng":-118.31, + "zoom":11 +},{ + "key":"sf", + "label":"San Francisco", + "lat":37.77, + "lng":-122.40, + "zoom":11 +},{ + "key":"ny", + "label":"New York", + "lat":40.74, + "lng":-74.0, + "zoom":11 +},{ + "key":"dc", + "label":"Washington, DC", + "lat":38.88, + "lng":-77.04, + "zoom":11 +},{ + "key":"bs", + "label":"Boston", + "lat":42.36, + "lng":-71.05, + "zoom":11 +},{ + "key":"br", + "label":"Berlin", + "lat":52.51, + "lng":13.36, + "zoom":11 +},{ + "key":"tk", + "label":"Tokyo", + "lat":35.69, + "lng":139.73, + "zoom":11 +}] + +export default { + locations, +} \ No newline at end of file diff --git a/src/component/Map/index.jsx b/src/component/Map/index.jsx index fc3abbf..880c95c 100644 --- a/src/component/Map/index.jsx +++ b/src/component/Map/index.jsx @@ -10,7 +10,9 @@ class Map extends React.Component { render (){ const {focus, style} = this.props - return + return ( + + ) } } diff --git a/src/component/Style/StyleLayers.jsx b/src/component/Style/StyleLayers.jsx index 2336d3e..e672c92 100644 --- a/src/component/Style/StyleLayers.jsx +++ b/src/component/Style/StyleLayers.jsx @@ -259,7 +259,7 @@ class StyleLayers extends React.Component { StyleLayers.propTypes = { error: PropTypes.object, - focusLayers: PropTypes.array, + focusLayers: PropTypes.object, layers: PropTypes.object, match: PropTypes.object, path: PropTypes.array, diff --git a/src/component/Tooltip/index.jsx b/src/component/Tooltip/index.jsx index 88c127e..0fa0ec1 100644 --- a/src/component/Tooltip/index.jsx +++ b/src/component/Tooltip/index.jsx @@ -4,14 +4,17 @@ import PropTypes from 'prop-types' class Tooltip extends React.Component { render (){ - const {direction, message} = this.props + const {direction, message, origin} = this.props + + const originClass = origin? `tooltip-origin-${origin}`: 'tooltip-origin-bottom' + const bubbleDirectionClass = direction? `tooltip-bubble-${direction}`: 'tooltip-bubble-left' const textClass = message.length > 20? 'tooltip-text-long': 'tooltip-text-short' return ( -
+
-
+
{message} @@ -24,10 +27,18 @@ class Tooltip extends React.Component { Tooltip.propTypes = { + align: PropTypes.oneOf([ + 'left', + 'right', + ]), direction: PropTypes.oneOf([ 'left', 'right', ]), + origin: PropTypes.oneOf([ + 'bottom', + 'left', + ]), message: PropTypes.string, }