mirror of
https://github.com/maputnik/editor.git
synced 2025-12-26 16:10:01 +00:00
Merge remote-tracking branch 'upstream/master' into fix/web-driver-tests-v7
Conflicts: config/webpack.production.config.js package-lock.json package.json
This commit is contained in:
@@ -22,6 +22,10 @@ import tokens from '../config/tokens.json'
|
||||
import isEqual from 'lodash.isequal'
|
||||
import Debug from '../libs/debug'
|
||||
|
||||
import MapboxGl from 'mapbox-gl'
|
||||
import mapboxUtil from 'mapbox-gl/src/util/mapbox'
|
||||
|
||||
|
||||
function updateRootSpec(spec, fieldName, newValues) {
|
||||
return {
|
||||
...spec,
|
||||
@@ -112,7 +116,9 @@ export default class App extends React.Component {
|
||||
updateFonts(urlTemplate) {
|
||||
const metadata = this.state.mapStyle.metadata || {}
|
||||
const accessToken = metadata['maputnik:openmaptiles_access_token'] || tokens.openmaptiles
|
||||
downloadGlyphsMetadata(urlTemplate.replace('{key}', accessToken), fonts => {
|
||||
|
||||
let glyphUrl = (typeof urlTemplate === 'string')? urlTemplate.replace('{key}', accessToken): urlTemplate;
|
||||
downloadGlyphsMetadata(glyphUrl, fonts => {
|
||||
this.setState({ spec: updateRootSpec(this.state.spec, 'glyphs', fonts)})
|
||||
})
|
||||
}
|
||||
@@ -124,15 +130,17 @@ export default class App extends React.Component {
|
||||
}
|
||||
|
||||
onStyleChanged(newStyle, save=true) {
|
||||
if(newStyle.glyphs !== this.state.mapStyle.glyphs) {
|
||||
this.updateFonts(newStyle.glyphs)
|
||||
}
|
||||
if(newStyle.sprite !== this.state.mapStyle.sprite) {
|
||||
this.updateIcons(newStyle.sprite)
|
||||
}
|
||||
|
||||
const errors = styleSpec.validate(newStyle, styleSpec.latest)
|
||||
if(errors.length === 0) {
|
||||
|
||||
if(newStyle.glyphs !== this.state.mapStyle.glyphs) {
|
||||
this.updateFonts(newStyle.glyphs)
|
||||
}
|
||||
if(newStyle.sprite !== this.state.mapStyle.sprite) {
|
||||
this.updateIcons(newStyle.sprite)
|
||||
}
|
||||
|
||||
this.revisionStore.addRevision(newStyle)
|
||||
if(save) this.saveStyle(newStyle)
|
||||
this.setState({
|
||||
@@ -215,13 +223,23 @@ export default class App extends React.Component {
|
||||
layers: []
|
||||
};
|
||||
|
||||
if(!this.state.sources.hasOwnProperty(key) && val.type === "vector") {
|
||||
const url = val.url;
|
||||
if(!this.state.sources.hasOwnProperty(key) && val.type === "vector" && val.hasOwnProperty("url")) {
|
||||
let url = val.url;
|
||||
try {
|
||||
url = mapboxUtil.normalizeSourceURL(url, MapboxGl.accessToken);
|
||||
} catch(err) {
|
||||
console.warn("Failed to normalizeSourceURL: ", err);
|
||||
}
|
||||
|
||||
fetch(url)
|
||||
.then((response) => {
|
||||
return response.json();
|
||||
})
|
||||
.then((json) => {
|
||||
if(!json.hasOwnProperty("vector_layers")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new objects before setState
|
||||
const sources = Object.assign({}, this.state.sources);
|
||||
|
||||
@@ -250,7 +268,7 @@ export default class App extends React.Component {
|
||||
|
||||
mapRenderer() {
|
||||
const mapProps = {
|
||||
mapStyle: style.replaceAccessToken(this.state.mapStyle),
|
||||
mapStyle: style.replaceAccessToken(this.state.mapStyle, {allowFallback: true}),
|
||||
onDataChange: (e) => {
|
||||
this.layerWatcher.analyzeMap(e.map)
|
||||
this.fetchSources();
|
||||
|
||||
@@ -22,6 +22,7 @@ import SettingsModal from './modals/SettingsModal'
|
||||
import ExportModal from './modals/ExportModal'
|
||||
import SourcesModal from './modals/SourcesModal'
|
||||
import OpenModal from './modals/OpenModal'
|
||||
import pkgJson from '../../package.json'
|
||||
|
||||
import style from '../libs/style'
|
||||
|
||||
@@ -137,7 +138,9 @@ export default class Toolbar extends React.Component {
|
||||
className="maputnik-toolbar-logo"
|
||||
>
|
||||
<img src={logoImage} alt="Maputnik" />
|
||||
<h1>Maputnik</h1>
|
||||
<h1>Maputnik
|
||||
<span className="maputnik-toolbar-version">v{pkgJson.version}</span>
|
||||
</h1>
|
||||
</ToolbarLink>
|
||||
<div className="maputnik-toolbar__actions">
|
||||
<ToolbarAction wdKey="nav:open" onClick={this.toggleModal.bind(this, 'open')}>
|
||||
|
||||
@@ -18,6 +18,8 @@ class LayerIcon extends React.Component {
|
||||
switch(this.props.type) {
|
||||
case 'fill-extrusion': return <BackgroundIcon {...iconProps} />
|
||||
case 'raster': return <FillIcon {...iconProps} />
|
||||
case 'hillshade': return <FillIcon {...iconProps} />
|
||||
case 'heatmap': return <FillIcon {...iconProps} />
|
||||
case 'fill': return <FillIcon {...iconProps} />
|
||||
case 'background': return <BackgroundIcon {...iconProps} />
|
||||
case 'line': return <LineIcon {...iconProps} />
|
||||
|
||||
@@ -112,6 +112,11 @@ export default class LayerEditor extends React.Component {
|
||||
comment = this.props.layer.metadata['maputnik:comment']
|
||||
}
|
||||
|
||||
let sourceLayerIds;
|
||||
if(this.props.sources.hasOwnProperty(this.props.layer.source)) {
|
||||
sourceLayerIds = this.props.sources[this.props.layer.source].layers;
|
||||
}
|
||||
|
||||
switch(type) {
|
||||
case 'layer': return <div>
|
||||
<LayerIdBlock
|
||||
@@ -129,8 +134,9 @@ export default class LayerEditor extends React.Component {
|
||||
onChange={v => this.changeProperty(null, 'source', v)}
|
||||
/>
|
||||
}
|
||||
{this.props.layer.type !== 'raster' && this.props.layer.type !== 'background' && <LayerSourceLayerBlock
|
||||
sourceLayerIds={this.props.sources[this.props.layer.source].layers}
|
||||
{['background', 'raster', 'hillshade', 'heatmap'].indexOf(this.state.type) < 0 &&
|
||||
<LayerSourceLayerBlock
|
||||
sourceLayerIds={sourceLayerIds}
|
||||
value={this.props.layer['source-layer']}
|
||||
onChange={v => this.changeProperty(null, 'source-layer', v)}
|
||||
/>
|
||||
|
||||
@@ -25,6 +25,8 @@ class LayerTypeBlock extends React.Component {
|
||||
['raster', 'Raster'],
|
||||
['circle', 'Circle'],
|
||||
['fill-extrusion', 'Fill Extrusion'],
|
||||
['hillshade', 'Hillshade'],
|
||||
['heatmap', 'Heatmap'],
|
||||
]}
|
||||
onChange={this.props.onChange}
|
||||
value={this.props.value}
|
||||
|
||||
@@ -38,7 +38,7 @@ function buildInspectStyle(originalMapStyle, coloredLayers, highlightedLayer) {
|
||||
const sources = {}
|
||||
Object.keys(originalMapStyle.sources).forEach(sourceId => {
|
||||
const source = originalMapStyle.sources[sourceId]
|
||||
if(source.type !== 'raster') {
|
||||
if(source.type !== 'raster' && source.type !== 'raster-dem') {
|
||||
sources[sourceId] = source
|
||||
}
|
||||
})
|
||||
|
||||
@@ -3,66 +3,8 @@ import PropTypes from 'prop-types'
|
||||
import style from '../../libs/style.js'
|
||||
import isEqual from 'lodash.isequal'
|
||||
import { loadJSON } from '../../libs/urlopen'
|
||||
import 'openlayers/dist/ol.css'
|
||||
import 'ol/ol.css'
|
||||
|
||||
function suitableVectorSource(mapStyle) {
|
||||
const sources = Object.keys(mapStyle.sources)
|
||||
.map(sourceId => {
|
||||
return {
|
||||
id: sourceId,
|
||||
source: mapStyle.sources[sourceId]
|
||||
}
|
||||
})
|
||||
.filter(({source}) => (source.type === 'vector' || source.type === 'geojson'))
|
||||
return sources[0]
|
||||
}
|
||||
|
||||
function toVectorLayer(source, tilegrid, cb) {
|
||||
function newMVTLayer(tileUrl) {
|
||||
const ol = require('openlayers')
|
||||
return new ol.layer.VectorTile({
|
||||
source: new ol.source.VectorTile({
|
||||
format: new ol.format.MVT(),
|
||||
tileGrid: tilegrid,
|
||||
tilePixelRatio: 8,
|
||||
url: tileUrl
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function newGeoJSONLayer(sourceUrl) {
|
||||
const ol = require('openlayers')
|
||||
return new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
format: new ol.format.GeoJSON(),
|
||||
url: sourceUrl
|
||||
})
|
||||
})
|
||||
}
|
||||
if (source.type === 'vector') {
|
||||
if(!source.tiles) {
|
||||
sourceFromTileJSON(source.url, tileSource => {
|
||||
cb(newMVTLayer(tileSource.tiles[0]))
|
||||
})
|
||||
} else {
|
||||
cb(newMVTLayer(source.tiles[0]))
|
||||
}
|
||||
} else if (source.type === 'geojson') {
|
||||
cb(newGeoJSONLayer(source.data))
|
||||
}
|
||||
}
|
||||
|
||||
function sourceFromTileJSON(url, cb) {
|
||||
loadJSON(url, null, tilejson => {
|
||||
if(!tilejson) return
|
||||
cb({
|
||||
type: 'vector',
|
||||
tiles: tilejson.tiles,
|
||||
minzoom: tilejson.minzoom,
|
||||
maxzoom: tilejson.maxzoom,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
class OpenLayers3Map extends React.Component {
|
||||
static propTypes = {
|
||||
@@ -79,49 +21,17 @@ class OpenLayers3Map extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.tilegrid = null
|
||||
this.resolutions = null
|
||||
this.layer = null
|
||||
this.map = null
|
||||
}
|
||||
|
||||
updateStyle(newMapStyle) {
|
||||
const oldSource = suitableVectorSource(this.props.mapStyle)
|
||||
const newSource = suitableVectorSource(newMapStyle)
|
||||
const resolutions = this.resolutions
|
||||
|
||||
function setStyleFunc(map, layer) {
|
||||
const olms = require('ol-mapbox-style')
|
||||
const styleFunc = olms.getStyleFunction(newMapStyle, newSource.id, resolutions)
|
||||
layer.setStyle(styleFunc)
|
||||
//NOTE: We need to mark the source as changed in order
|
||||
//to trigger a rerender
|
||||
layer.getSource().changed()
|
||||
map.render()
|
||||
}
|
||||
|
||||
if(newSource) {
|
||||
if(this.layer && !isEqual(oldSource, newSource)) {
|
||||
this.map.removeLayer(this.layer)
|
||||
this.layer = null
|
||||
}
|
||||
|
||||
if(!this.layer) {
|
||||
var self = this
|
||||
toVectorLayer(newSource.source, this.tilegrid, vectorLayer => {
|
||||
self.layer = vectorLayer
|
||||
self.map.addLayer(self.layer)
|
||||
setStyleFunc(self.map, self.layer)
|
||||
})
|
||||
} else {
|
||||
setStyleFunc(this.map, this.layer)
|
||||
}
|
||||
}
|
||||
const olms = require('ol-mapbox-style');
|
||||
const styleFunc = olms.apply(this.map, newMapStyle)
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
require.ensure(["openlayers", "ol-mapbox-style"], () => {
|
||||
if(!this.map || !this.resolutions) return
|
||||
require.ensure(["ol", "ol-mapbox-style"], () => {
|
||||
if(!this.map) return
|
||||
this.updateStyle(nextProps.mapStyle)
|
||||
})
|
||||
}
|
||||
@@ -129,24 +39,22 @@ class OpenLayers3Map extends React.Component {
|
||||
componentDidMount() {
|
||||
//Load OpenLayers dynamically once we need it
|
||||
//TODO: Make this more convenient
|
||||
require.ensure(["openlayers", "ol-mapbox-style"], ()=> {
|
||||
require.ensure(["ol", "ol/map", "ol/view", "ol/control/zoom", "ol-mapbox-style"], ()=> {
|
||||
console.log('Loaded OpenLayers3 renderer')
|
||||
|
||||
const ol = require('openlayers')
|
||||
const olms = require('ol-mapbox-style')
|
||||
const olMap = require('ol/map').default
|
||||
const olView = require('ol/view').default
|
||||
const olZoom = require('ol/control/zoom').default
|
||||
|
||||
this.tilegrid = ol.tilegrid.createXYZ({tileSize: 512, maxZoom: 22})
|
||||
this.resolutions = this.tilegrid.getResolutions()
|
||||
|
||||
const map = new ol.Map({
|
||||
const map = new olMap({
|
||||
target: this.container,
|
||||
layers: [],
|
||||
view: new ol.View({
|
||||
view: new olView({
|
||||
zoom: 2,
|
||||
center: [52.5, -78.4]
|
||||
})
|
||||
})
|
||||
map.addControl(new ol.control.Zoom())
|
||||
map.addControl(new olZoom())
|
||||
this.map = map
|
||||
this.updateStyle(this.props.mapStyle)
|
||||
})
|
||||
|
||||
@@ -142,7 +142,7 @@ class AddModal extends React.Component {
|
||||
onChange={v => this.setState({ source: v })}
|
||||
/>
|
||||
}
|
||||
{this.state.type !== 'background' && this.state.type !== 'raster' &&
|
||||
{['background', 'raster', 'hillshade', 'heatmap'].indexOf(this.state.type) < 0 &&
|
||||
<LayerSourceLayerBlock
|
||||
isFixed={true}
|
||||
sourceLayerIds={layers}
|
||||
|
||||
@@ -25,6 +25,7 @@ class Gist extends React.Component {
|
||||
super(props);
|
||||
this.state = {
|
||||
preview: false,
|
||||
public: false,
|
||||
saving: false,
|
||||
latestGist: null,
|
||||
}
|
||||
@@ -42,7 +43,10 @@ class Gist extends React.Component {
|
||||
...this.state,
|
||||
saving: true
|
||||
});
|
||||
const preview = this.state.preview && (this.props.mapStyle.metadata || {})['maputnik:openmaptiles_access_token'];
|
||||
|
||||
const preview = this.state.preview;
|
||||
|
||||
const mapboxToken = (this.props.mapStyle.metadata || {})['maputnik:mapbox_access_token'];
|
||||
|
||||
const mapStyleStr = preview ?
|
||||
styleSpec.format(stripAccessTokens(style.replaceAccessToken(this.props.mapStyle))) :
|
||||
@@ -55,8 +59,8 @@ class Gist extends React.Component {
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>`+styleTitle+` Preview</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://api.mapbox.com/mapbox-gl-js/v0.43.0/mapbox-gl.css" />
|
||||
<script src="https://api.mapbox.com/mapbox-gl-js/v0.43.0/mapbox-gl.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="https://api.mapbox.com/mapbox-gl-js/v0.44.0/mapbox-gl.css" />
|
||||
<script src="https://api.mapbox.com/mapbox-gl-js/v0.44.0/mapbox-gl.js"></script>
|
||||
<style>
|
||||
body { margin:0; padding:0; }
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
@@ -65,6 +69,7 @@ class Gist extends React.Component {
|
||||
<body>
|
||||
<div id='map'></div>
|
||||
<script>
|
||||
mapboxgl.accessToken = '${mapboxToken}';
|
||||
var map = new mapboxgl.Map({
|
||||
container: 'map',
|
||||
style: 'style.json',
|
||||
@@ -89,7 +94,7 @@ class Gist extends React.Component {
|
||||
const gh = new GitHub();
|
||||
let gist = gh.getGist(); // not a gist yet
|
||||
gist.create({
|
||||
public: true,
|
||||
public: this.state.public,
|
||||
description: styleTitle,
|
||||
files: files
|
||||
}).then(function({data}) {
|
||||
@@ -110,6 +115,13 @@ class Gist extends React.Component {
|
||||
})
|
||||
}
|
||||
|
||||
onPublicChange(value) {
|
||||
this.setState({
|
||||
...this.state,
|
||||
public: value
|
||||
})
|
||||
}
|
||||
|
||||
changeMetadataProperty(property, value) {
|
||||
const changedStyle = {
|
||||
...this.props.mapStyle,
|
||||
@@ -162,13 +174,22 @@ class Gist extends React.Component {
|
||||
<MdFileDownload />
|
||||
Save to Gist (anonymous)
|
||||
</Button>
|
||||
{' '}
|
||||
<CheckboxInput
|
||||
value={this.state.preview}
|
||||
name='gist-style-preview'
|
||||
onChange={this.onPreviewChange.bind(this)}
|
||||
/>
|
||||
<span> Include preview</span>
|
||||
<div className="maputnik-modal-sub-section">
|
||||
<CheckboxInput
|
||||
value={this.state.public}
|
||||
name='gist-style-public'
|
||||
onChange={this.onPublicChange.bind(this)}
|
||||
/>
|
||||
<span> Public gist</span>
|
||||
</div>
|
||||
<div className="maputnik-modal-sub-section">
|
||||
<CheckboxInput
|
||||
value={this.state.preview}
|
||||
name='gist-style-preview'
|
||||
onChange={this.onPreviewChange.bind(this)}
|
||||
/>
|
||||
<span> Include preview</span>
|
||||
</div>
|
||||
{this.state.preview ?
|
||||
<div>
|
||||
<InputBlock
|
||||
@@ -177,6 +198,12 @@ class Gist extends React.Component {
|
||||
value={(this.props.mapStyle.metadata || {})['maputnik:openmaptiles_access_token']}
|
||||
onChange={this.changeMetadataProperty.bind(this, "maputnik:openmaptiles_access_token")}/>
|
||||
</InputBlock>
|
||||
<InputBlock
|
||||
label={"Mapbox Access Token: "}>
|
||||
<StringInput
|
||||
value={(this.props.mapStyle.metadata || {})['maputnik:mapbox_access_token']}
|
||||
onChange={this.changeMetadataProperty.bind(this, "maputnik:mapbox_access_token")}/>
|
||||
</InputBlock>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://openmaptiles.com/hosting/">Get your free access token</a>
|
||||
</div>
|
||||
: null}
|
||||
|
||||
@@ -45,6 +45,10 @@ function editorMode(source) {
|
||||
if(source.tiles) return 'tilexyz_raster'
|
||||
return 'tilejson_raster'
|
||||
}
|
||||
if(source.type === 'raster-dem') {
|
||||
if(source.tiles) return 'tilexyz_raster-dem'
|
||||
return 'tilejson_raster-dem'
|
||||
}
|
||||
if(source.type === 'vector') {
|
||||
if(source.tiles) return 'tilexyz_vector'
|
||||
return 'tilejson_vector'
|
||||
@@ -127,6 +131,16 @@ class AddSource extends React.Component {
|
||||
minzoom: source.minzoom || 0,
|
||||
maxzoom: source.maxzoom || 14
|
||||
}
|
||||
case 'tilejson_raster-dem': return {
|
||||
type: 'raster-dem',
|
||||
url: source.url || 'http://localhost:3000/tilejson.json'
|
||||
}
|
||||
case 'tilexyz_raster-dem': return {
|
||||
type: 'raster-dem',
|
||||
tiles: source.tiles || ['http://localhost:3000/{x}/{y}/{z}.pbf'],
|
||||
minzoom: source.minzoom || 0,
|
||||
maxzoom: source.maxzoom || 14
|
||||
}
|
||||
default: return {}
|
||||
}
|
||||
}
|
||||
@@ -147,6 +161,8 @@ class AddSource extends React.Component {
|
||||
['tilexyz_vector', 'Vector (XYZ URLs)'],
|
||||
['tilejson_raster', 'Raster (TileJSON URL)'],
|
||||
['tilexyz_raster', 'Raster (XYZ URL)'],
|
||||
['tilejson_raster-dem', 'Raster DEM (TileJSON URL)'],
|
||||
['tilexyz_raster-dem', 'Raster DEM (XYZ URLs)'],
|
||||
]}
|
||||
onChange={mode => this.setState({mode: mode, source: this.defaultSource(mode)})}
|
||||
value={this.state.mode}
|
||||
|
||||
@@ -115,6 +115,8 @@ class SourceTypeEditor extends React.Component {
|
||||
case 'tilexyz_vector': return <TileURLSourceEditor {...commonProps} />
|
||||
case 'tilejson_raster': return <TileJSONSourceEditor {...commonProps} />
|
||||
case 'tilexyz_raster': return <TileURLSourceEditor {...commonProps} />
|
||||
case 'tilejson_raster-dem': return <TileJSONSourceEditor {...commonProps} />
|
||||
case 'tilexyz_raster-dem': return <TileURLSourceEditor {...commonProps} />
|
||||
default: return null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,8 @@
|
||||
"circle-stroke-width",
|
||||
"circle-pitch-scale",
|
||||
"circle-translate",
|
||||
"circle-translate-anchor"
|
||||
"circle-translate-anchor",
|
||||
"circle-pitch-alignment"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -147,7 +148,9 @@
|
||||
"icon-rotate",
|
||||
"icon-padding",
|
||||
"icon-keep-upright",
|
||||
"icon-offset"
|
||||
"icon-offset",
|
||||
"icon-anchor",
|
||||
"icon-pitch-alignment"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -194,5 +197,35 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"hillshade": {
|
||||
"groups": [
|
||||
{
|
||||
"title": "Paint properties",
|
||||
"type": "properties",
|
||||
"fields": [
|
||||
"hillshade-illumination-direction",
|
||||
"hillshade-illumination-anchor",
|
||||
"hillshade-exaggeration",
|
||||
"hillshade-shadow-color",
|
||||
"hillshade-highlight-color",
|
||||
"hillshade-accent-color"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"heatmap": {
|
||||
"groups": [
|
||||
{
|
||||
"title": "Paint properties",
|
||||
"type": "properties",
|
||||
"fields": [
|
||||
"heatmap-radius",
|
||||
"heatmap-weight",
|
||||
"heatmap-intensity",
|
||||
"heatmap-opacity"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,12 +54,23 @@ function indexOfLayer(layers, layerId) {
|
||||
return null
|
||||
}
|
||||
|
||||
function replaceAccessToken(mapStyle) {
|
||||
function replaceAccessToken(mapStyle, opts={}) {
|
||||
const omtSource = mapStyle.sources.openmaptiles
|
||||
if(!omtSource) return mapStyle
|
||||
if(!omtSource.hasOwnProperty("url")) return mapStyle
|
||||
|
||||
const metadata = mapStyle.metadata || {}
|
||||
const accessToken = metadata['maputnik:openmaptiles_access_token'] || tokens.openmaptiles
|
||||
let accessToken = metadata['maputnik:openmaptiles_access_token'];
|
||||
|
||||
if(opts.allowFallback && !accessToken) {
|
||||
accessToken = tokens.openmaptiles;
|
||||
}
|
||||
|
||||
if(!accessToken) {
|
||||
// Early exit.
|
||||
return mapStyle;
|
||||
}
|
||||
|
||||
const changedSources = {
|
||||
...mapStyle.sources,
|
||||
openmaptiles: {
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
// BUTTON
|
||||
.maputnik-button {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
background-color: $color-midgray;
|
||||
color: $color-lowgray;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
background-color: $color-black;
|
||||
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.3);
|
||||
z-index: 3;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.maputnik-modal-section {
|
||||
@@ -20,6 +21,10 @@
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.maputnik-modal-sub-section {
|
||||
margin-top: $margin-1;
|
||||
}
|
||||
|
||||
.maputnik-modal-section--shrink {
|
||||
flex-shrink: 1;
|
||||
}
|
||||
@@ -75,6 +80,7 @@
|
||||
position: fixed;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 9;
|
||||
|
||||
@include flex-row;
|
||||
}
|
||||
|
||||
@@ -36,12 +36,24 @@
|
||||
cursor: pointer;
|
||||
color: $color-white;
|
||||
text-decoration: none;
|
||||
line-height: 20px;
|
||||
|
||||
h1 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $color-midgray;
|
||||
}
|
||||
}
|
||||
|
||||
.maputnik-toolbar-version {
|
||||
position: absolute;
|
||||
font-size: 10px;
|
||||
bottom: -2px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.maputnik-toolbar-action {
|
||||
@extend .maputnik-toolbar-link;
|
||||
}
|
||||
@@ -56,7 +68,7 @@
|
||||
}
|
||||
|
||||
.maputnik-toolbar-logo {
|
||||
flex: 0 0 140px;
|
||||
flex: 0 0 170px;
|
||||
}
|
||||
|
||||
.maputnik-toolbar__inner {
|
||||
|
||||
Reference in New Issue
Block a user