{m}
+ const errors = this.props.errors.map((error, idx) => { + let content; + if (error.parsed && error.parsed.type === "layer") { + const {parsed} = error; + const {mapStyle} = this.props; + content = ( + <> + Layer '{mapStyle.layers[parsed.data.index].id}': {parsed.data.message} + > + ); + } + else { + content = error.message; + } + return+ {content} +
}) const infos = this.props.infos.map((m, i) => { diff --git a/src/components/fields/FunctionSpecField.jsx b/src/components/fields/FunctionSpecField.jsx index e2542c5a..a6920442 100644 --- a/src/components/fields/FunctionSpecField.jsx +++ b/src/components/fields/FunctionSpecField.jsx @@ -4,6 +4,9 @@ import PropTypes from 'prop-types' import SpecProperty from './_SpecProperty' import DataProperty from './_DataProperty' import ZoomProperty from './_ZoomProperty' +import ExpressionProperty from './_ExpressionProperty' +import {expression} from '@mapbox/mapbox-gl-style-spec' + function isZoomField(value) { @@ -14,6 +17,24 @@ function isDataField(value) { return typeof value === 'object' && value.stops && typeof value.property !== 'undefined' } +/** + * So here we can't just check is `Array.isArray(value)` because certain + * properties accept arrays as values, for example `text-font`. So we must try + * and create an expression. + */ +function isExpression(value, fieldSpec={}) { + if (!Array.isArray(value)) { + return false; + } + try { + const out = expression.createExpression(value, fieldSpec); + return (out.result === "success"); + } + catch (err) { + return false; + } +} + /** * If we don't have a default value just make one up */ @@ -108,6 +129,11 @@ export default class FunctionSpecProperty extends React.Component { this.props.onChange(this.props.fieldName, zoomFunc) } + makeExpression = () => { + const expression = ["literal", this.props.value || this.props.fieldSpec.default]; + this.props.onChange(this.props.fieldName, expression); + } + makeDataFunction = () => { const functionType = this.getFieldFunctionType(this.props.fieldSpec); const stopValue = functionType === 'categorical' ? '' : 0; @@ -126,9 +152,21 @@ export default class FunctionSpecProperty extends React.Component { const propClass = this.props.fieldSpec.default === this.props.value ? "maputnik-default-property" : "maputnik-modified-property" let specField; - if (isZoomField(this.props.value)) { + if (isExpression(this.props.value, this.props.fieldSpec)) { + specField = ( +