mirror of
https://github.com/a-nyx/maputnik-with-pmtiles.git
synced 2025-01-14 17:43:29 +01:00
All important stuff is in CSS now
This commit is contained in:
parent
9ef24428fe
commit
b51354ae1d
22 changed files with 452 additions and 301 deletions
|
@ -30,10 +30,7 @@ export default class DocLabel extends React.Component {
|
|||
onMouseOver={e => this.setState({showDoc: true})}
|
||||
onMouseOut={e => this.setState({showDoc: false})}
|
||||
className="maputnik-doc-target"
|
||||
style={{
|
||||
cursor: 'help',
|
||||
...this.props.cursorTargetStyle,
|
||||
}}
|
||||
style={this.props.cursorTargetStyle}
|
||||
>
|
||||
{this.props.label}
|
||||
</span>
|
||||
|
|
|
@ -13,7 +13,6 @@ import FunctionIcon from 'react-icons/lib/md/functions'
|
|||
import capitalize from 'lodash.capitalize'
|
||||
import input from '../../config/input.js'
|
||||
import colors from '../../config/colors.js'
|
||||
import { margins, fontSizes } from '../../config/scales.js'
|
||||
|
||||
function isZoomField(value) {
|
||||
return typeof value === 'object' && value.stops
|
||||
|
@ -22,7 +21,7 @@ function isZoomField(value) {
|
|||
/** Supports displaying spec field for zoom function objects
|
||||
* https://www.mapbox.com/mapbox-gl-style-spec/#types-function-zoom-property
|
||||
*/
|
||||
export default class ZoomSpecField extends React.Component {
|
||||
export default class ZoomSpecProperty extends React.Component {
|
||||
static propTypes = {
|
||||
onChange: React.PropTypes.func.isRequired,
|
||||
fieldName: React.PropTypes.string.isRequired,
|
||||
|
@ -85,114 +84,90 @@ export default class ZoomSpecField extends React.Component {
|
|||
this.props.onChange(this.props.fieldName, changedValue)
|
||||
}
|
||||
|
||||
render() {
|
||||
if(isZoomField(this.props.value)) {
|
||||
let label = <DocLabel
|
||||
renderZoomProperty() {
|
||||
const label = <div className="maputnik-zoom-spec-property-label">
|
||||
<DocLabel
|
||||
label={labelFromFieldName(this.props.fieldName)}
|
||||
doc={this.props.fieldSpec.doc}
|
||||
style={{
|
||||
width: '50%',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
const zoomFields = this.props.value.stops.map((stop, idx) => {
|
||||
label = <DocLabel
|
||||
doc={this.props.fieldSpec.doc}
|
||||
style={{ width: '41%'}}
|
||||
label={idx > 0 ? "" : labelFromFieldName(this.props.fieldName)}
|
||||
/>
|
||||
const zoomFields = this.props.value.stops.map((stop, idx) => {
|
||||
const zoomLevel = stop[0]
|
||||
const value = stop[1]
|
||||
|
||||
if(idx === 1) {
|
||||
label = <label style={{...input.label, width: '41%'}}>
|
||||
<Button
|
||||
className="maputnik-add-stop"
|
||||
style={{fontSize: fontSizes[5]}}
|
||||
onClick={this.addStop.bind(this)}
|
||||
>
|
||||
Add stop
|
||||
</Button>
|
||||
</label>
|
||||
}
|
||||
return <div key={zoomLevel} className="maputnik-zoom-spec-property-stop-item">
|
||||
{label}
|
||||
<Button
|
||||
className="maputnik-delete-stop"
|
||||
onClick={this.deleteStop.bind(this, idx)}
|
||||
>
|
||||
<DocLabel
|
||||
label={<DeleteIcon />}
|
||||
doc={"Remove zoom level stop."}
|
||||
/>
|
||||
|
||||
const zoomLevel = stop[0]
|
||||
const value = stop[1]
|
||||
|
||||
return <div key={zoomLevel} style={{
|
||||
...input.property,
|
||||
marginLeft: 0,
|
||||
marginRight: 0
|
||||
}}>
|
||||
{label}
|
||||
<Button
|
||||
className="maputnik-delete-stop"
|
||||
style={{backgroundColor: null, verticalAlign: 'top'}}
|
||||
onClick={this.deleteStop.bind(this, idx)}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</Button>
|
||||
</Button>
|
||||
<div className="maputnik-zoom-spec-property-stop-edit">
|
||||
<NumberInput
|
||||
style={{
|
||||
width: '7.5%',
|
||||
verticalAlign: 'top',
|
||||
}}
|
||||
value={zoomLevel}
|
||||
onChange={changedStop => this.changeStop(idx, changedStop, value)}
|
||||
min={0}
|
||||
max={22}
|
||||
/>
|
||||
</div>
|
||||
<div className="maputnik-zoom-spec-property-stop-value">
|
||||
<SpecField
|
||||
fieldName={this.props.fieldName}
|
||||
fieldSpec={this.props.fieldSpec}
|
||||
value={value}
|
||||
onChange={(_, newValue) => this.changeStop(idx, zoomLevel, newValue)}
|
||||
style={{
|
||||
width: '41%',
|
||||
marginLeft: '1.5%',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
})
|
||||
|
||||
return <div style={input.property}>
|
||||
{zoomFields}
|
||||
</div>
|
||||
} else {
|
||||
})
|
||||
|
||||
if(this.props.fieldSpec['zoom-function']) {
|
||||
return <div className="maputnik-zoom-spec-property">
|
||||
{zoomFields}
|
||||
<Button
|
||||
className="maputnik-add-stop"
|
||||
onClick={this.addStop.bind(this)}
|
||||
>
|
||||
Add stop
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return <div style={input.property}
|
||||
className="maputnik-zoom-spec-field"
|
||||
>
|
||||
renderProperty() {
|
||||
return <div className="maputnik-zoom-spec-property">
|
||||
<DocLabel
|
||||
label={labelFromFieldName(this.props.fieldName)}
|
||||
doc={this.props.fieldSpec.doc}
|
||||
style={{
|
||||
width: this.props.fieldSpec['zoom-function'] ? '41%' : '50%',
|
||||
}}
|
||||
/>
|
||||
{this.props.fieldSpec['zoom-function'] &&
|
||||
<Button
|
||||
className="maputnik-make-zoom-function"
|
||||
onClick={this.makeZoomFunction.bind(this)}
|
||||
>
|
||||
<DocLabel
|
||||
label={labelFromFieldName(this.props.fieldName)}
|
||||
doc={this.props.fieldSpec.doc}
|
||||
style={{
|
||||
width: this.props.fieldSpec['zoom-function'] ? '41%' : '50%',
|
||||
}}
|
||||
label={<FunctionIcon />}
|
||||
cursorTargetStyle={{ cursor: 'pointer' }}
|
||||
doc={"Turn property into a zoom function to enable a map feature to change with map's zoom level."}
|
||||
/>
|
||||
{this.props.fieldSpec['zoom-function'] &&
|
||||
<Button
|
||||
className="maputnik-make-zoom-function"
|
||||
style={{
|
||||
verticalAlign: 'top',
|
||||
backgroundColor: null,
|
||||
display: 'inline-block',
|
||||
paddingBottom: 0,
|
||||
paddingTop: 0,
|
||||
}}
|
||||
onClick={this.makeZoomFunction.bind(this)}
|
||||
>
|
||||
<DocLabel
|
||||
label={<FunctionIcon />}
|
||||
cursorTargetStyle={{ cursor: 'pointer' }}
|
||||
doc={"Turn property into a zoom function to enable a map feature to change with map's zoom level."}
|
||||
/>
|
||||
</Button>
|
||||
}
|
||||
<SpecField {...this.props} style={{ width: '50%' } }/>
|
||||
</div>
|
||||
</Button>
|
||||
}
|
||||
<SpecField {...this.props} style={{ width: '50%' } }/>
|
||||
</div>
|
||||
}
|
||||
|
||||
render() {
|
||||
if(isZoomField(this.props.value)) {
|
||||
return this.renderZoomProperty();
|
||||
} else {
|
||||
return this.renderProperty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
import React from 'react'
|
||||
|
||||
import input from '../../config/input.js'
|
||||
import colors from '../../config/colors.js'
|
||||
import { margins, fontSizes } from '../../config/scales.js'
|
||||
import { combiningFilterOps } from '../../libs/filterops.js'
|
||||
|
||||
import GlSpec from 'mapbox-gl-style-spec/reference/latest.js'
|
||||
|
@ -86,41 +82,28 @@ export default class CombiningFilterEditor extends React.Component {
|
|||
|
||||
//TODO: Implement support for nested filter
|
||||
if(hasNestedCombiningFilter(filter)) {
|
||||
return <div style={{
|
||||
fontSize: fontSizes[5],
|
||||
color: colors.midgray,
|
||||
}}>
|
||||
return <div className="maputnik-filter-editor-unsupported">
|
||||
Nested filters are not supported.
|
||||
</div>
|
||||
}
|
||||
|
||||
return <div>
|
||||
<div className="maputnik-filter-editor-compound-select" style={{ marginBottom: margins[1] }}>
|
||||
return <div className="maputnik-filter-editor">
|
||||
<div className="maputnik-filter-editor-compound-select">
|
||||
<DocLabel
|
||||
label={"Compound Filter"}
|
||||
doc={GlSpec.layer.filter.doc + " Combine multiple filters together by using a compound filter."}
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
width: '49%',
|
||||
}}
|
||||
/>
|
||||
<SelectInput
|
||||
value={combiningOp}
|
||||
onChange={this.onFilterPartChanged.bind(this, 0)}
|
||||
options={[["all", "every filter matches"], ["none", "no filter matches"], ["any", "any filter matches"]]}
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
width: '50%',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{editorBlocks}
|
||||
<div className="maputnik-filter-editor-add-wrapper" style={{marginTop: margins[1]}}>
|
||||
<Button onClick={this.addFilterItem.bind(this)} style={{
|
||||
display: 'inline-block',
|
||||
marginLeft: '79%',
|
||||
width: '20%',
|
||||
}}>
|
||||
<div className="maputnik-filter-editor-add-wrapper">
|
||||
<Button
|
||||
className="maputnik-add-filter"
|
||||
onClick={this.addFilterItem.bind(this)}>
|
||||
Add filter
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
@ -10,15 +10,15 @@ class FilterEditorBlock extends React.Component {
|
|||
|
||||
render() {
|
||||
return <div className="maputnik-filter-editor-block">
|
||||
<div className="maputnik-filter-editor-block-action" style={{display: 'inline-block', width: '8%'}}>
|
||||
<div className="maputnik-filter-editor-block-action">
|
||||
<Button
|
||||
style={{backgroundColor: null}}
|
||||
className="maputnik-delete-filter"
|
||||
onClick={this.props.onDelete}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</Button>
|
||||
</div>
|
||||
<div className="maputnik-filter-editor-block-content" style={{display: 'inline-block', width: '92%'}}>
|
||||
<div className="maputnik-filter-editor-block-content">
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React from 'react'
|
||||
|
||||
import { margins, fontSizes } from '../../config/scales.js'
|
||||
import { otherFilterOps } from '../../libs/filterops.js'
|
||||
import StringInput from '../inputs/StringInput'
|
||||
import AutocompleteInput from '../inputs/AutocompleteInput'
|
||||
|
@ -11,7 +10,6 @@ class SingleFilterEditor extends React.Component {
|
|||
filter: React.PropTypes.array.isRequired,
|
||||
onChange: React.PropTypes.func.isRequired,
|
||||
properties: React.PropTypes.object,
|
||||
style: React.PropTypes.object,
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
|
@ -29,12 +27,7 @@ class SingleFilterEditor extends React.Component {
|
|||
const propertyName = f[1]
|
||||
const filterArgs = f.slice(2)
|
||||
|
||||
return <div className="maputnik-filter-editor-single"
|
||||
style={{
|
||||
marginTop: margins[1],
|
||||
marginBottom: margins[1],
|
||||
...this.props.style
|
||||
}}>
|
||||
return <div className="maputnik-filter-editor-single">
|
||||
<div className="maputnik-filter-editor-property">
|
||||
<AutocompleteInput
|
||||
value={propertyName}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import React from 'react'
|
||||
import input from '../../config/input.js'
|
||||
import colors from '../../config/colors'
|
||||
import { margins } from '../../config/scales'
|
||||
|
||||
class CheckboxInput extends React.Component {
|
||||
static propTypes = {
|
||||
|
@ -11,59 +9,16 @@ class CheckboxInput extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const styles = {
|
||||
root: {
|
||||
...input.base,
|
||||
lineHeight: 0.7,
|
||||
padding: 0,
|
||||
position: 'relative',
|
||||
textAlign: 'center ',
|
||||
verticalAlign: 'middle',
|
||||
cursor: 'pointer'
|
||||
},
|
||||
input: {
|
||||
position: 'absolute',
|
||||
zIndex: -1,
|
||||
opacity: 0
|
||||
},
|
||||
box: {
|
||||
display: 'inline-block',
|
||||
textAlign: 'center ',
|
||||
height: 15,
|
||||
width: 15,
|
||||
marginRight: margins[1],
|
||||
marginBottom: null,
|
||||
backgroundColor: colors.gray,
|
||||
borderRadius: 2,
|
||||
borderStyle: 'solid',
|
||||
borderWidth: 2,
|
||||
borderColor: colors.gray,
|
||||
transition: 'background-color .1s ease-out'
|
||||
},
|
||||
icon: {
|
||||
display: this.props.value ? null : 'none',
|
||||
width: '75%',
|
||||
height: '75%',
|
||||
marginTop: 1,
|
||||
fill: colors.lowgray
|
||||
}
|
||||
}
|
||||
|
||||
return <label style={styles.root}>
|
||||
return <label className="maputnik-checkbox-wrapper">
|
||||
<input
|
||||
className="maputnik-checkbox"
|
||||
type="checkbox"
|
||||
style={{
|
||||
...styles.input,
|
||||
...this.props.style,
|
||||
}}
|
||||
style={this.props.style}
|
||||
onChange={e => this.props.onChange(!this.props.value)}
|
||||
checked={this.props.value}
|
||||
/>
|
||||
<div style={styles.box}>
|
||||
<svg
|
||||
viewBox='0 0 32 32'
|
||||
style={styles.icon}>
|
||||
<div className="maputnik-checkbox-box">
|
||||
<svg className="maputnik-checkbox-icon" viewBox='0 0 32 32'>
|
||||
<path d='M1 14 L5 10 L13 18 L27 4 L31 8 L13 26 z' />
|
||||
</svg>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React from 'react'
|
||||
import input from '../../config/input'
|
||||
import DocLabel from '../fields/DocLabel'
|
||||
import { margins } from '../../config/scales'
|
||||
|
||||
/** Wrap a component with a label */
|
||||
class InputBlock extends React.Component {
|
||||
|
@ -29,9 +28,7 @@ class InputBlock extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
return <div style={{
|
||||
...this.props.style,
|
||||
}}
|
||||
return <div style={this.props.style}
|
||||
className="maputnik-input-block"
|
||||
>
|
||||
{this.props.doc &&
|
||||
|
@ -44,11 +41,7 @@ class InputBlock extends React.Component {
|
|||
/>
|
||||
}
|
||||
{!this.props.doc &&
|
||||
<label
|
||||
style={{
|
||||
...input.label,
|
||||
width: '50%',
|
||||
}}>
|
||||
<label className="maputnik-input-block-label">
|
||||
{this.props.label}
|
||||
</label>
|
||||
}
|
||||
|
|
|
@ -18,10 +18,7 @@ class SelectInput extends React.Component {
|
|||
|
||||
return <select
|
||||
className="maputnik-select"
|
||||
style={{
|
||||
...input.select,
|
||||
...this.props.style
|
||||
}}
|
||||
style={this.props.style}
|
||||
value={this.props.value}
|
||||
onChange={e => this.props.onChange(e.target.value)}
|
||||
>
|
||||
|
|
|
@ -12,11 +12,8 @@ import LayerSourceLayerBlock from './LayerSourceLayerBlock'
|
|||
import InputBlock from '../inputs/InputBlock'
|
||||
import MultiButtonInput from '../inputs/MultiButtonInput'
|
||||
|
||||
import input from '../../config/input.js'
|
||||
import { changeType, changeProperty } from '../../libs/layer'
|
||||
import layout from '../../config/layout.json'
|
||||
import { margins, fontSizes } from '../../config/scales'
|
||||
import colors from '../../config/colors'
|
||||
|
||||
class UnsupportedLayer extends React.Component {
|
||||
render() {
|
||||
|
@ -90,8 +87,8 @@ export default class LayerEditor extends React.Component {
|
|||
getChildContext () {
|
||||
return {
|
||||
reactIconBase: {
|
||||
size: fontSizes[4],
|
||||
color: colors.lowgray,
|
||||
size: 14,
|
||||
color: '#8e8e8e',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +132,7 @@ export default class LayerEditor extends React.Component {
|
|||
}
|
||||
</div>
|
||||
case 'filter': return <div>
|
||||
<div style={input.property}>
|
||||
<div className="maputnik-filter-editor-wrapper">
|
||||
<FilterEditor
|
||||
filter={this.props.layer.filter}
|
||||
properties={this.props.vectorLayers[this.props.layer['source-layer']]}
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
import React from 'react'
|
||||
import Color from 'color'
|
||||
import colors from '../../config/colors'
|
||||
import { margins, fontSizes } from '../../config/scales'
|
||||
|
||||
import Collapse from 'react-collapse'
|
||||
import CollapseOpenIcon from 'react-icons/lib/md/arrow-drop-down'
|
||||
|
|
|
@ -2,19 +2,7 @@ import React from 'react'
|
|||
import InputBlock from '../inputs/InputBlock'
|
||||
import StringInput from '../inputs/StringInput'
|
||||
import LayerIcon from '../icons/LayerIcon'
|
||||
import input from '../../config/input'
|
||||
|
||||
import colors from '../../config/colors'
|
||||
import { margins, fontSizes } from '../../config/scales'
|
||||
|
||||
const Panel = (props) => {
|
||||
return <div style={{
|
||||
backgroundColor: colors.gray,
|
||||
padding: margins[0],
|
||||
fontSize: fontSizes[5],
|
||||
lineHeight: 1.2,
|
||||
}}>{props.children}</div>
|
||||
}
|
||||
|
||||
function groupFeaturesBySourceLayer(features) {
|
||||
const sources = {}
|
||||
|
@ -33,26 +21,23 @@ class FeatureLayerPopup extends React.Component {
|
|||
const layers = sources[vectorLayerId].map((feature, idx) => {
|
||||
return <label
|
||||
key={idx}
|
||||
style={{
|
||||
...input.label,
|
||||
display: 'block',
|
||||
width: 'auto',
|
||||
}}>
|
||||
className="maputnik-popup-layer"
|
||||
>
|
||||
<LayerIcon type={feature.layer.type} style={{
|
||||
width: fontSizes[4],
|
||||
height: fontSizes[4],
|
||||
paddingRight: margins[0],
|
||||
width: 14,
|
||||
height: 14,
|
||||
paddingRight: 3
|
||||
}}/>
|
||||
{feature.layer.id}
|
||||
</label>
|
||||
})
|
||||
return <div key={vectorLayerId}>
|
||||
<Panel>{vectorLayerId}</Panel>
|
||||
<div className="maputnik-popup-layer-id">{vectorLayerId}</div>
|
||||
{layers}
|
||||
</div>
|
||||
})
|
||||
|
||||
return <div>
|
||||
return <div className="maputnik-feature-layer-popup">
|
||||
{items}
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -2,9 +2,6 @@ import React from 'react'
|
|||
import InputBlock from '../inputs/InputBlock'
|
||||
import StringInput from '../inputs/StringInput'
|
||||
|
||||
import colors from '../../config/colors'
|
||||
import { margins, fontSizes } from '../../config/scales'
|
||||
|
||||
function displayValue(value) {
|
||||
if (typeof value === 'undefined' || value === null) return value;
|
||||
if (value instanceof Date) return value.toLocaleString();
|
||||
|
@ -17,24 +14,15 @@ function displayValue(value) {
|
|||
function renderProperties(feature) {
|
||||
return Object.keys(feature.properties).map(propertyName => {
|
||||
const property = feature.properties[propertyName]
|
||||
return <InputBlock key={propertyName} label={propertyName} style={{marginTop: 0, marginBottom: 0}}>
|
||||
return <InputBlock key={propertyName} label={propertyName}>
|
||||
<StringInput value={displayValue(property)} style={{backgroundColor: 'transparent'}}/>
|
||||
</InputBlock>
|
||||
})
|
||||
}
|
||||
|
||||
const Panel = (props) => {
|
||||
return <div style={{
|
||||
backgroundColor: colors.gray,
|
||||
padding: margins[0],
|
||||
fontSize: fontSizes[5],
|
||||
lineHeight: 1.2,
|
||||
}}>{props.children}</div>
|
||||
}
|
||||
|
||||
function renderFeature(feature) {
|
||||
return <div key={feature.id}>
|
||||
<Panel>{feature.layer['source-layer']}</Panel>
|
||||
<div className="maputnik-popup-layer-id">{feature.layer['source-layer']}</div>
|
||||
{renderProperties(feature)}
|
||||
</div>
|
||||
}
|
||||
|
@ -43,7 +31,7 @@ class FeaturePropertyPopup extends React.Component {
|
|||
|
||||
render() {
|
||||
const features = this.props.features
|
||||
return <div>
|
||||
return <div className="maputnik-feature-property-popup">
|
||||
{features.map(renderFeature)}
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -78,6 +78,7 @@ class AddModal extends React.Component {
|
|||
onOpenToggle={this.props.onOpenToggle}
|
||||
title={'Add Layer'}
|
||||
>
|
||||
<div className="maputnik-add-layer">
|
||||
<LayerIdBlock
|
||||
value={this.state.id}
|
||||
onChange={v => this.setState({ id: v })}
|
||||
|
@ -103,6 +104,7 @@ class AddModal extends React.Component {
|
|||
<Button className="maputnik-add-layer-button" onClick={this.addLayer.bind(this)}>
|
||||
Add Layer
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import InputBlock from '../inputs/InputBlock'
|
|||
import StringInput from '../inputs/StringInput'
|
||||
import SelectInput from '../inputs/SelectInput'
|
||||
import Modal from './Modal'
|
||||
import colors from '../../config/colors'
|
||||
|
||||
class SettingsModal extends React.Component {
|
||||
static propTypes = {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React from 'react'
|
||||
import GlSpec from 'mapbox-gl-style-spec/reference/latest.js'
|
||||
import Modal from './Modal'
|
||||
import Heading from '../Heading'
|
||||
import Button from '../Button'
|
||||
import Paragraph from '../Paragraph'
|
||||
import InputBlock from '../inputs/InputBlock'
|
||||
|
@ -12,8 +11,6 @@ import SourceTypeEditor from '../sources/SourceTypeEditor'
|
|||
import style from '../../libs/style'
|
||||
import { deleteSource, addSource, changeSource } from '../../libs/source'
|
||||
import publicSources from '../../config/tilesets.json'
|
||||
import colors from '../../config/colors'
|
||||
import { margins, fontSizes } from '../../config/scales'
|
||||
|
||||
import AddIcon from 'react-icons/lib/md/add-circle-outline'
|
||||
import DeleteIcon from 'react-icons/lib/md/delete'
|
||||
|
@ -27,33 +24,18 @@ class PublicSource extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
return <div className="maputnik-public-source" style={{
|
||||
verticalAlign: 'top',
|
||||
marginTop: margins[2],
|
||||
marginRight: margins[2],
|
||||
backgroundColor: colors.gray,
|
||||
display: 'inline-block',
|
||||
width: 240,
|
||||
fontSize: fontSizes[4],
|
||||
color: colors.lowgray,
|
||||
}}>
|
||||
<Button
|
||||
onClick={() => this.props.onSelect(this.props.id)}
|
||||
style={{
|
||||
backgroundColor: 'transparent',
|
||||
padding: margins[2],
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<span style={{fontWeight: 700}}>{this.props.title}</span>
|
||||
<br/>
|
||||
<span style={{fontSize: fontSizes[5]}}>#{this.props.id}</span>
|
||||
</div>
|
||||
<span style={{flexGrow: 1}} />
|
||||
<AddIcon />
|
||||
</Button>
|
||||
return <div className="maputnik-public-source">
|
||||
<Button
|
||||
className="maputnik-public-source-select"
|
||||
onClick={() => this.props.onSelect(this.props.id)}
|
||||
>
|
||||
<div className="maputnik-public-source-info">
|
||||
<p className="maputnik-public-source-name">{this.props.title}</p>
|
||||
<p className="maputnik-public-source-id">#{this.props.id}</p>
|
||||
</div>
|
||||
<span className="maputnik-space" />
|
||||
<AddIcon />
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
@ -81,32 +63,19 @@ class ActiveSourceTypeEditor extends React.Component {
|
|||
|
||||
render() {
|
||||
const inputProps = { }
|
||||
return <div style={{
|
||||
}}>
|
||||
<div className="maputnik-active-source-type-editor"
|
||||
style={{
|
||||
backgroundColor: colors.gray,
|
||||
color: colors.lowgray,
|
||||
padding: margins[1],
|
||||
display: 'flex',
|
||||
fontSize: fontSizes[4],
|
||||
flexDirection: 'row',
|
||||
}}>
|
||||
<span style={{fontWeight: 700, fontSize: fontSizes[4], lineHeight: 2}}>#{this.props.sourceId}</span>
|
||||
<span style={{flexGrow: 1}} />
|
||||
return <div className="maputnik-active-source-type-editor">
|
||||
<div className="maputnik-active-source-type-editor-header">
|
||||
<span className="maputnik-active-source-type-editor-header-id">#{this.props.sourceId}</span>
|
||||
<span className="maputnik-space" />
|
||||
<Button
|
||||
className="maputnik-active-source-type-editor-header-delete"
|
||||
onClick={()=> this.props.onDelete(this.props.sourceId)}
|
||||
style={{backgroundColor: 'transparent'}}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</Button>
|
||||
</div>
|
||||
<div style={{
|
||||
borderColor: colors.gray,
|
||||
borderWidth: 2,
|
||||
borderStyle: 'solid',
|
||||
padding: margins[1],
|
||||
}}>
|
||||
<div className="maputnik-active-source-type-editor-content">
|
||||
<SourceTypeEditor
|
||||
onChange={this.props.onChange}
|
||||
mode={editorMode(this.props.source)}
|
||||
|
@ -163,7 +132,7 @@ class AddSource extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
return <div>
|
||||
return <div className="maputnik-add-source">
|
||||
<InputBlock label={"Source ID"} doc={"Unique ID that identifies the source and is used in the layer to reference the source."}>
|
||||
<StringInput
|
||||
value={this.state.sourceId}
|
||||
|
@ -188,7 +157,9 @@ class AddSource extends React.Component {
|
|||
mode={this.state.mode}
|
||||
source={this.state.source}
|
||||
/>
|
||||
<Button onClick={() => this.props.onAdd(this.state.sourceId, this.state.source)}>
|
||||
<Button
|
||||
className="maputnik-add-source-button"
|
||||
onClick={() => this.props.onAdd(this.state.sourceId, this.state.source)}>
|
||||
Add Source
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -239,21 +210,25 @@ class SourcesModal extends React.Component {
|
|||
onOpenToggle={this.props.onOpenToggle}
|
||||
title={'Sources'}
|
||||
>
|
||||
<Heading level={4}>Active Sources</Heading>
|
||||
<div className="maputnik-modal-section">
|
||||
<h4>Active Sources</h4>
|
||||
{activeSources}
|
||||
|
||||
<Heading level={4}>Add New Source</Heading>
|
||||
<div style={{maxWidth: 300}}>
|
||||
<p style={{color: colors.lowgray, fontSize: fontSizes[5]}}>Add a new source to your style. You can only choose the source type and id at creation time!</p>
|
||||
<AddSource
|
||||
onAdd={(sourceId, source) => this.props.onStyleChanged(addSource(mapStyle, sourceId, source))}
|
||||
/>
|
||||
</div>
|
||||
<div className="maputnik-modal-section">
|
||||
<h4>Add New Source</h4>
|
||||
<p>Add a new source to your style. You can only choose the source type and id at creation time!</p>
|
||||
<AddSource
|
||||
onAdd={(sourceId, source) => this.props.onStyleChanged(addSource(mapStyle, sourceId, source))}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Heading level={4}>Choose Public Source</Heading>
|
||||
<Paragraph>
|
||||
<div className="maputnik-modal-section">
|
||||
<h4>Choose Public Source</h4>
|
||||
<p>
|
||||
Add one of the publicly availble sources to your style.
|
||||
</Paragraph>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div style={{maxwidth: 500}}>
|
||||
{tilesetOptions}
|
||||
</div>
|
||||
|
|
|
@ -24,9 +24,10 @@ html {
|
|||
|
||||
p {
|
||||
font-size: $font-size-6;
|
||||
padding-top: $margin-2;
|
||||
padding-bottom: $margin-2;
|
||||
margin-top: $margin-2;
|
||||
margin-bottom: $margin-2;
|
||||
color: $color-lowgray;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
h1 {
|
||||
|
@ -49,10 +50,21 @@ h4 {
|
|||
margin-bottom: $margin-3;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
input {
|
||||
height: 24px;
|
||||
}
|
||||
input:focus, select:focus {
|
||||
color: $color-white !important;
|
||||
outline: #8e8e8e auto 1px !important;
|
||||
}
|
||||
label:hover {
|
||||
color: $color-white;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
&:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
height: 100%;
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.maputnik-doc-target {
|
||||
cursor: help;
|
||||
}
|
||||
.maputnik-doc-wrapper {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
|
@ -52,6 +56,14 @@
|
|||
margin: $margin-3;
|
||||
}
|
||||
|
||||
.maputnik-input-block-label {
|
||||
display: inline-block;
|
||||
line-height: 2;
|
||||
color: $color-lowgray;
|
||||
user-select: none;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.maputnik-space {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
//COLOR PICKER
|
||||
.maputnik-color {
|
||||
@extend .maputnik-input;
|
||||
height: 26px;
|
||||
}
|
||||
.maputnik-color-wrapper {
|
||||
position: relative;
|
||||
|
@ -32,3 +33,103 @@
|
|||
}
|
||||
.maputnik-color-picker-overlay {
|
||||
}
|
||||
|
||||
.maputnik-checkbox-wrapper {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
padding: 0px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.maputnik-checkbox {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
width: 50%;
|
||||
}
|
||||
.maputnik-checkbox-box {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin-right: $margin-2;
|
||||
background-color: $color-gray;
|
||||
border-radius: 2px;
|
||||
border-style: solid;
|
||||
border-width: 2px;
|
||||
border-color: $color-gray;
|
||||
transition: background-color 0.1s ease-out;
|
||||
}
|
||||
.maputnik-checkbox-icon {
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
margin-top: 1px;
|
||||
fill: $color-lowgray;
|
||||
}
|
||||
|
||||
.maputnik-zoom-spec-property {
|
||||
@extend .clearfix;
|
||||
display: block;
|
||||
margin: $margin-3;
|
||||
}
|
||||
|
||||
.maputnik-zoom-spec-property-label {
|
||||
display: inline-block;
|
||||
width: 41%;
|
||||
}
|
||||
|
||||
.maputnik-zoom-spec-property-stop-item {
|
||||
margin-bottom: $margin-2;
|
||||
margin-top: $margin-2;
|
||||
}
|
||||
|
||||
.maputnik-zoom-spec-property-stop-edit {
|
||||
display: inline-block;
|
||||
width: 7%;
|
||||
margin-right: 1.5%;
|
||||
> * {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.maputnik-zoom-spec-property-stop-value {
|
||||
display: inline-block;
|
||||
width: 41.5%;
|
||||
> * {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.maputnik-delete-stop {
|
||||
background-color: transparent;
|
||||
vertical-align: top;
|
||||
|
||||
.maputnik-doc-wrapper {
|
||||
width: auto;
|
||||
}
|
||||
.maputnik-doc-target {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
svg {
|
||||
fill: $color-white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.maputnik-add-stop {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
margin-right: $margin-2;
|
||||
}
|
||||
|
||||
.maputnik-select {
|
||||
@extend .maputnik-input;
|
||||
height: 2.15em;
|
||||
width: 50%;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
margin: 0;
|
||||
padding-bottom: $margin-5;
|
||||
}
|
||||
|
||||
.maputnik-layer-list-item {
|
||||
font-weight: 400;
|
||||
color: $color-lowgray;
|
||||
|
@ -29,7 +30,7 @@
|
|||
}
|
||||
|
||||
.maputnik-layer-list-item:hover, .maputnik-layer-list-item-selected {
|
||||
background-color: lighten($color-black, 0.8);
|
||||
background-color: lighten($color-black, 2);
|
||||
|
||||
.maputnik-icon-action svg {
|
||||
fill: $color-midgray;
|
||||
|
@ -38,6 +39,11 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.maputnik-layer-list-item-selected {
|
||||
color: $color-white;
|
||||
}
|
||||
|
||||
.maputnik-layer-list-item-id {
|
||||
width: 115px;
|
||||
white-space: nowrap;
|
||||
|
@ -49,7 +55,8 @@
|
|||
.maputnik-layer-editor-group {
|
||||
font-weight: bold;
|
||||
font-size: $font-size-5;
|
||||
background-color: darken($color-gray, 1.5);
|
||||
background-color: lighten($color-black, 2);
|
||||
|
||||
color: $color-lowgray;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
@ -57,18 +64,107 @@
|
|||
display: flex;
|
||||
flex-direction: row;
|
||||
line-height: 20px;
|
||||
|
||||
&:hover {
|
||||
background-color: $color-gray;
|
||||
}
|
||||
}
|
||||
|
||||
.maputnik-filter-editor-wrapper {
|
||||
padding: $margin-3;
|
||||
}
|
||||
|
||||
.maputnik-filter-editor-property {
|
||||
display: inline-block;
|
||||
width: '22%';
|
||||
}
|
||||
|
||||
.maputnik-filter-editor-operator {
|
||||
display: inline-block;
|
||||
width: 19%;
|
||||
margin-left: 2%;
|
||||
}
|
||||
|
||||
.maputnik-filter-editor-args {
|
||||
display: inline-block;
|
||||
width: 54%;
|
||||
margin-left: 2%;
|
||||
}
|
||||
|
||||
.maputnik-make-zoom-function {
|
||||
background-color: transparent;
|
||||
display: inline-block;
|
||||
padding-bottom: 0px;
|
||||
padding-top: 0px;
|
||||
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
svg {
|
||||
fill: $color-white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.maputnik-filter-editor-compound-select {
|
||||
margin-bottom: $margin-2;
|
||||
}
|
||||
|
||||
.maputnik-filter-editor-unsupported {
|
||||
color: $color-midgray;
|
||||
}
|
||||
|
||||
.maputnik-filter-editor {
|
||||
@extend .clearfix;
|
||||
}
|
||||
|
||||
.maputnik-add-filter {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
margin-top: $margin-2;
|
||||
}
|
||||
.maputnik-delete-filter {
|
||||
background-color: transparent;
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
svg {
|
||||
fill: $color-white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.maputnik-filter-editor-block-action {
|
||||
margin-top: $margin-2;
|
||||
margin-bottom: $margin-2;
|
||||
}
|
||||
.maputnik-filter-editor-block-action {
|
||||
display: inline-block;
|
||||
width: 8%;
|
||||
margin-right: 1.5%;
|
||||
}
|
||||
|
||||
.maputnik-filter-editor-block-content {
|
||||
display: inline-block;
|
||||
width: 90.5%;
|
||||
}
|
||||
|
||||
.maputnik-filter-editor-property {
|
||||
display: inline-block;
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.maputnik-filter-editor-operator {
|
||||
display: inline-block;
|
||||
width: 17%;
|
||||
.maputnik-select {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.maputnik-filter-editor-args {
|
||||
display: inline-block;
|
||||
width: 54%;
|
||||
|
||||
.maputnik-string, .maputnik-number {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,6 +90,9 @@
|
|||
max-width: 100%;
|
||||
}
|
||||
|
||||
.maputnik-add-layer{
|
||||
@extend .clearfix;
|
||||
}
|
||||
//ADD MODAL
|
||||
.maputnik-add-layer-button {
|
||||
margin-right: $margin-3;
|
||||
|
@ -100,3 +103,65 @@
|
|||
text-align: right;
|
||||
@extend .maputnik-big-button;
|
||||
}
|
||||
|
||||
//SOURCE MODAL
|
||||
.maputnik-public-source {
|
||||
vertical-align: top;
|
||||
margin-top: 1.5%;
|
||||
margin-right: 1.5%;
|
||||
background-color: $color-gray;
|
||||
width: 48.5%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.maputnik-public-source-select {
|
||||
padding: $margin-3;
|
||||
font-size: $font-size-5;
|
||||
color: $color-lowgray;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.maputnik-public-source-name {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.maputnik-public-source-id {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.maputnik-active-source-type-editor {
|
||||
min-width: 500px;
|
||||
}
|
||||
.maputnik-active-source-type-editor-header {
|
||||
background-color: $color-gray;
|
||||
color: $color-lowgray;
|
||||
padding: $margin-2;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.maputnik-active-source-type-editor-header-id {
|
||||
font-weight: 700;
|
||||
line-height: 2;
|
||||
font-size: $font-size-5;
|
||||
}
|
||||
|
||||
.maputnik-active-source-type-editor-content {
|
||||
border-color: $color-gray;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
padding: $margin-2;
|
||||
}
|
||||
|
||||
.maputnik-add-source {
|
||||
@extend .clearfix;
|
||||
}
|
||||
|
||||
.maputnik-add-source-button {
|
||||
@extend .maputnik-big-button;
|
||||
display: inline-block;
|
||||
margin-top: 0;
|
||||
margin-right: $margin-3;
|
||||
float: right;
|
||||
}
|
||||
|
|
28
src/styles/_popup.scss
Normal file
28
src/styles/_popup.scss
Normal file
|
@ -0,0 +1,28 @@
|
|||
.maputnik-popup-layer {
|
||||
@extend .maputnik-base ;
|
||||
color: $color-lowgray;
|
||||
user-select: none;
|
||||
padding-left: 0;
|
||||
padding-right: $margin-1;
|
||||
line-height: 1.2;
|
||||
padding-left: $margin-2;
|
||||
padding-right: $margin-2;
|
||||
}
|
||||
|
||||
.maputnik-popup-layer-id {
|
||||
padding-left: $margin-2;
|
||||
padding-right: $margin-2;
|
||||
background-color: $color-midgray;
|
||||
color: $color-white;
|
||||
}
|
||||
|
||||
.maputnik-property-layer-popup {
|
||||
}
|
||||
|
||||
.maputnik-feature-property-popup {
|
||||
.maputnik-input-block {
|
||||
margin: 0;
|
||||
margin-left: $margin-2;
|
||||
margin-top: $margin-2;
|
||||
}
|
||||
}
|
|
@ -29,3 +29,4 @@ $toolbar-height: 40px;
|
|||
@import 'layout';
|
||||
@import 'layer';
|
||||
@import 'input';
|
||||
@import 'popup';
|
||||
|
|
Loading…
Reference in a new issue