Merge pull request #556 from orangemug/feature/add-new-mgljs-features

Added new features from the mapbox-gl spec
This commit is contained in:
Orange Mug 2019-10-14 10:04:42 +01:00 committed by GitHub
commit e219dcd332
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 89 additions and 17 deletions

View file

@ -645,6 +645,7 @@ export default class App extends React.Component {
/> />
const layerEditor = selectedLayer ? <LayerEditor const layerEditor = selectedLayer ? <LayerEditor
key={selectedLayer.id}
layer={selectedLayer} layer={selectedLayer}
layerIndex={this.state.selectedLayerIndex} layerIndex={this.state.selectedLayerIndex}
isFirstLayer={this.state.selectedLayerIndex < 1} isFirstLayer={this.state.selectedLayerIndex < 1}

View file

@ -11,6 +11,7 @@ import ArrayInput from '../inputs/ArrayInput'
import DynamicArrayInput from '../inputs/DynamicArrayInput' import DynamicArrayInput from '../inputs/DynamicArrayInput'
import FontInput from '../inputs/FontInput' import FontInput from '../inputs/FontInput'
import IconInput from '../inputs/IconInput' import IconInput from '../inputs/IconInput'
import EnumInput from '../inputs/SelectInput'
import capitalize from 'lodash.capitalize' import capitalize from 'lodash.capitalize'
const iconProperties = ['background-pattern', 'fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'icon-image'] const iconProperties = ['background-pattern', 'fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'icon-image']
@ -70,17 +71,10 @@ export default class SpecField extends React.Component {
case 'enum': case 'enum':
const options = Object.keys(this.props.fieldSpec.values).map(v => [v, capitalize(v)]) const options = Object.keys(this.props.fieldSpec.values).map(v => [v, capitalize(v)])
if(options.length <= 3 && optionsLabelLength(options) <= 20) { return <EnumInput
return <MultiButtonInput {...commonProps}
{...commonProps} options={options}
options={options} />
/>
} else {
return <SelectInput
{...commonProps}
options={options}
/>
}
case 'formatted': case 'formatted':
case 'string': case 'string':
if(iconProperties.indexOf(this.props.fieldName) >= 0) { if(iconProperties.indexOf(this.props.fieldName) >= 0) {
@ -119,6 +113,7 @@ export default class SpecField extends React.Component {
} else { } else {
return <DynamicArrayInput return <DynamicArrayInput
{...commonProps} {...commonProps}
fieldSpec={this.props.fieldSpec}
type={this.props.fieldSpec.value} type={this.props.fieldSpec.value}
/> />
} }

View file

@ -5,6 +5,8 @@ import NumberInput from './NumberInput'
import Button from '../Button' import Button from '../Button'
import {MdDelete} from 'react-icons/md' import {MdDelete} from 'react-icons/md'
import DocLabel from '../fields/DocLabel' import DocLabel from '../fields/DocLabel'
import EnumInput from '../inputs/SelectInput'
import capitalize from 'lodash.capitalize'
class DynamicArrayInput extends React.Component { class DynamicArrayInput extends React.Component {
@ -14,6 +16,7 @@ class DynamicArrayInput extends React.Component {
default: PropTypes.array, default: PropTypes.array,
onChange: PropTypes.func, onChange: PropTypes.func,
style: PropTypes.object, style: PropTypes.object,
fieldSpec: PropTypes.object,
} }
changeValue(idx, newValue) { changeValue(idx, newValue) {
@ -31,6 +34,11 @@ class DynamicArrayInput extends React.Component {
const values = this.values.slice(0) const values = this.values.slice(0)
if (this.props.type === 'number') { if (this.props.type === 'number') {
values.push(0) values.push(0)
}
else if (this.props.type === 'enum') {
const {fieldSpec} = this.props;
const defaultValue = Object.keys(fieldSpec.values)[0];
values.push(defaultValue);
} else { } else {
values.push("") values.push("")
} }
@ -48,15 +56,28 @@ class DynamicArrayInput extends React.Component {
render() { render() {
const inputs = this.values.map((v, i) => { const inputs = this.values.map((v, i) => {
const deleteValueBtn= <DeleteValueButton onClick={this.deleteValue.bind(this, i)} /> const deleteValueBtn= <DeleteValueButton onClick={this.deleteValue.bind(this, i)} />
const input = this.props.type === 'number' let input;
? <NumberInput if (this.props.type === 'number') {
input = <NumberInput
value={v} value={v}
onChange={this.changeValue.bind(this, i)} onChange={this.changeValue.bind(this, i)}
/> />
: <StringInput }
else if (this.props.type === 'enum') {
const options = Object.keys(this.props.fieldSpec.values).map(v => [v, capitalize(v)]);
input = <EnumInput
options={options}
value={v} value={v}
onChange={this.changeValue.bind(this, i)} onChange={this.changeValue.bind(this, i)}
/> />
}
else {
input = <StringInput
value={v}
onChange={this.changeValue.bind(this, i)}
/>
}
return <div return <div
style={this.props.style} style={this.props.style}

View file

@ -0,0 +1,45 @@
import React from 'react'
import PropTypes from 'prop-types'
import SelectInput from '../inputs/SelectInput'
import MultiButtonInput from '../inputs/MultiButtonInput'
function optionsLabelLength(options) {
let sum = 0;
options.forEach(([_, label]) => {
sum += label.length
})
return sum
}
class EnumInput extends React.Component {
static propTypes = {
"data-wd-key": PropTypes.string,
value: PropTypes.string,
style: PropTypes.object,
default: PropTypes.string,
onChange: PropTypes.func,
options: PropTypes.array,
}
render() {
const {options, value, onChange} = this.props;
if(options.length <= 3 && optionsLabelLength(options) <= 20) {
return <MultiButtonInput
options={options}
value={value}
onChange={onChange}
/>
} else {
return <SelectInput
options={options}
value={value}
onChange={onChange}
/>
}
}
}
export default StringInput

View file

@ -24,11 +24,14 @@ class NumberInput extends React.Component {
value: props.value value: props.value
}; };
} }
return {};
} }
changeValue(newValue) { changeValue(newValue) {
this.setState({editing: true}); this.setState({editing: true});
const value = parseFloat(newValue) const value = (newValue === "" || newValue === undefined) ?
undefined :
parseFloat(newValue);
const hasChanged = this.state.value !== value const hasChanged = this.state.value !== value
if(this.isValid(value) && hasChanged) { if(this.isValid(value) && hasChanged) {
@ -38,6 +41,10 @@ class NumberInput extends React.Component {
} }
isValid(v) { isValid(v) {
if (v === undefined) {
return true;
}
const value = parseFloat(v) const value = parseFloat(v)
if(isNaN(value)) { if(isNaN(value)) {
return false return false
@ -76,7 +83,7 @@ class NumberInput extends React.Component {
spellCheck="false" spellCheck="false"
className="maputnik-number" className="maputnik-number"
placeholder={this.props.default} placeholder={this.props.default}
value={this.state.value} value={this.state.value || ""}
onChange={e => this.changeValue(e.target.value)} onChange={e => this.changeValue(e.target.value)}
onBlur={this.resetValue} onBlur={this.resetValue}
/> />

View file

@ -128,11 +128,14 @@
"text-justify", "text-justify",
"text-anchor", "text-anchor",
"text-max-angle", "text-max-angle",
"text-writing-mode",
"text-rotate", "text-rotate",
"text-keep-upright", "text-keep-upright",
"text-transform", "text-transform",
"text-offset", "text-offset",
"text-optional" "text-optional",
"text-variable-anchor",
"text-radial-offset"
] ]
}, },
{ {