Support displaying basic zoom fields

This commit is contained in:
Lukas Martinelli 2016-12-17 17:40:44 +01:00
parent a91a1e99e0
commit 7fae257130

View file

@ -1,94 +1,148 @@
import React from 'react' import React from 'react'
import Immutable from 'immutable' import Immutable from 'immutable'
import color from 'color'
import GlSpec from 'mapbox-gl-style-spec/reference/latest.min.js' import GlSpec from 'mapbox-gl-style-spec/reference/latest.min.js'
import NumberField from './number' import NumberField from './number'
import EnumField from './enum' import EnumField from './enum'
import ColorField from './color' import ColorField from './color'
import StringField from './string' import StringField from './string'
import inputStyle from './input.js'
import theme from '../theme.js'
class SpecField extends React.Component { function isZoomField(value) {
static propTypes = { return Immutable.Map.isMap(value)
onChange: React.PropTypes.func.isRequired, }
fieldName: React.PropTypes.string.isRequired,
fieldSpec: React.PropTypes.object.isRequired, const specFieldProps = {
value: React.PropTypes.oneOfType([ onChange: React.PropTypes.func.isRequired,
fieldName: React.PropTypes.string.isRequired,
fieldSpec: React.PropTypes.object.isRequired,
}
/** Supports displaying spec field for zoom function objects
* https://www.mapbox.com/mapbox-gl-style-spec/#types-function-zoom-property
*/
class ZoomSpecField extends React.Component {
static propTypes = {
...specFieldProps,
value: React.PropTypes.oneOfType([
React.PropTypes.object, React.PropTypes.object,
React.PropTypes.string, React.PropTypes.string,
React.PropTypes.number, React.PropTypes.number,
]).isRequired, ]),
} }
onValueChanged(property, value) { render() {
return this.props.onChange(property, value) if(isZoomField(this.props.value)) {
} const zoomFields = this.props.value.get('stops').map(stop => {
console.log(stop)
const zoomLevel = stop.get(0)
const value = stop.get(1)
console.log(zoomLevel, value)
render() { return <div key={zoomLevel}>
switch(this.props.fieldSpec.type) { <b><span style={inputStyle.label}>Zoom Level {zoomLevel}</span></b>
case 'number': return ( <SpecField {...this.props} value={value} />
<NumberField </div>
onChange={this.onValueChanged.bind(this, this.props.fieldName)} }).toSeq()
value={this.props.value} return <div style={{
name={this.props.fieldName} border: 1,
default={this.props.fieldSpec.default} borderStyle: 'solid',
min={this.props.fieldSpec.min} borderColor: color(theme.colors.gray).lighten(0.1).hexString(),
max={this.props.fieldSpec.max} padding: theme.scale[1],
unit={this.props.fieldSpec.unit} }}>
doc={this.props.fieldSpec.doc} {zoomFields}
/> </div>
) } else {
case 'enum': return ( return <SpecField {...this.props} />
<EnumField }
onChange={this.onValueChanged.bind(this, this.props.fieldName)} }
value={this.props.value} }
name={this.props.fieldName}
allowedValues={this.props.fieldSpec.values} /** Display any field from the Mapbox GL style spec and
doc={this.props.fieldSpec.doc} * choose the correct field component based on the @{fieldSpec}
/> * to display @{value}. */
) class SpecField extends React.Component {
case 'string': return ( static propTypes = {
<StringField ...specFieldProps,
onChange={this.onValueChanged.bind(this, this.props.fieldName)} value: React.PropTypes.oneOfType([
value={this.props.value} React.PropTypes.string,
name={this.props.fieldName} React.PropTypes.number,
doc={this.props.fieldSpec.doc} ]),
/> }
)
case 'color': return ( onValueChanged(property, value) {
<ColorField return this.props.onChange(property, value)
onChange={this.onValueChanged.bind(this, this.props.fieldName)} }
value={this.props.value}
name={this.props.fieldName} render() {
doc={this.props.fieldSpec.doc} switch(this.props.fieldSpec.type) {
/> case 'number': return (
) <NumberField
default: return null onChange={this.onValueChanged.bind(this, this.props.fieldName)}
} value={this.props.value}
} name={this.props.fieldName}
default={this.props.fieldSpec.default}
min={this.props.fieldSpec.min}
max={this.props.fieldSpec.max}
unit={this.props.fieldSpec.unit}
doc={this.props.fieldSpec.doc}
/>
)
case 'enum': return (
<EnumField
onChange={this.onValueChanged.bind(this, this.props.fieldName)}
value={this.props.value}
name={this.props.fieldName}
allowedValues={this.props.fieldSpec.values}
doc={this.props.fieldSpec.doc}
/>
)
case 'string': return (
<StringField
onChange={this.onValueChanged.bind(this, this.props.fieldName)}
value={this.props.value}
name={this.props.fieldName}
doc={this.props.fieldSpec.doc}
/>
)
case 'color': return (
<ColorField
onChange={this.onValueChanged.bind(this, this.props.fieldName)}
value={this.props.value}
name={this.props.fieldName}
doc={this.props.fieldSpec.doc}
/>
)
default: return null
}
}
} }
export class PropertyGroup extends React.Component { export class PropertyGroup extends React.Component {
static propTypes = { static propTypes = {
onChange: React.PropTypes.func.isRequired, onChange: React.PropTypes.func.isRequired,
properties: React.PropTypes.instanceOf(Immutable.Map).isRequired, properties: React.PropTypes.instanceOf(Immutable.Map).isRequired,
layerType: React.PropTypes.oneOf(['fill', 'background', 'line', 'symbol']).isRequired, layerType: React.PropTypes.oneOf(['fill', 'background', 'line', 'symbol']).isRequired,
groupType: React.PropTypes.oneOf(['paint', 'layout']).isRequired, groupType: React.PropTypes.oneOf(['paint', 'layout']).isRequired,
} }
render() { render() {
const layerTypeSpec = GlSpec[this.props.groupType + "_" + this.props.layerType] const layerTypeSpec = GlSpec[this.props.groupType + "_" + this.props.layerType]
const specFields = Object.keys(layerTypeSpec).map(propName => { const specFields = Object.keys(layerTypeSpec).map(propName => {
const fieldSpec = layerTypeSpec[propName] const fieldSpec = layerTypeSpec[propName]
const propValue = this.props.properties.get(propName) const propValue = this.props.properties.get(propName)
return <SpecField return <ZoomSpecField
onChange={this.props.onChange} onChange={this.props.onChange}
key={propName} key={propName}
value={propValue} value={propValue}
fieldName={propName} fieldName={propName}
fieldSpec={fieldSpec} fieldSpec={fieldSpec}
/> />
}) })
return <div> return <div>
{specFields} {specFields}
</div> </div>
} }
} }