diff --git a/src/components/fields/FunctionSpecField.jsx b/src/components/fields/FunctionSpecField.jsx
index d1e30d3c..fb12a45b 100644
--- a/src/components/fields/FunctionSpecField.jsx
+++ b/src/components/fields/FunctionSpecField.jsx
@@ -45,27 +45,30 @@ function isPrimative (value) {
}
function isArrayOfPrimatives (values) {
- if (Array.isArray(value)) {
+ if (Array.isArray(values)) {
return values.every(isPrimative);
}
return false;
}
-function checkIsExpression (value, fieldSpec={}) {
+function getDataType (value, fieldSpec={}) {
if (value === undefined) {
- return false;
+ return "value";
}
else if (isPrimative(value)) {
- return false;
+ return "value";
}
else if (fieldSpec.type === "array" && isArrayOfPrimatives(value)) {
- return false;
+ return "value";
}
- else if (isZoomField(value) || isDataField(value)) {
- return false;
+ else if (isZoomField(value)) {
+ return "zoom_function";
+ }
+ else if (isDataField(value)) {
+ return "data_function";
}
else {
- return true;
+ return "expression";
}
}
@@ -111,7 +114,21 @@ export default class FunctionSpecProperty extends React.Component {
constructor (props) {
super();
this.state = {
- isExpression: checkIsExpression(props.value, props.fieldSpec),
+ dataType: getDataType(props.value, props.fieldSpec),
+ isEditing: false,
+ }
+ }
+
+ static getDerivedStateFromProps(props, state) {
+ // Because otherwise when editing values we end up accidentally changing field type.
+ if (state.isEditing) {
+ return {};
+ }
+ else {
+ return {
+ isEditing: false,
+ dataType: getDataType(props.value, props.fieldSpec)
+ };
}
}
@@ -150,7 +167,7 @@ export default class FunctionSpecProperty extends React.Component {
const {fieldSpec, fieldName} = this.props;
this.props.onChange(fieldName, fieldSpec.default);
this.setState({
- isExpression: false,
+ dataType: "value",
});
}
@@ -184,25 +201,25 @@ export default class FunctionSpecProperty extends React.Component {
const {value, fieldName} = this.props;
if (isLiteralExpression(value)) {
- this.props.onChange(fieldName, value[1]);
- this.setState({
- isExpression: false
- });
+ this.props.onChange(fieldName, value[1]);
+ this.setState({
+ dataType: "value",
+ });
}
}
canUndo = () => {
- const {value} = this.props;
- return isLiteralExpression(value);
+ const {value, fieldSpec} = this.props;
+ return (
+ isLiteralExpression(value) ||
+ isPrimative(value) ||
+ (Array.isArray(value) && fieldSpec.type === "array")
+ );
}
makeExpression = () => {
const expression = ["literal", this.props.value || this.props.fieldSpec.default];
this.props.onChange(this.props.fieldName, expression);
-
- this.setState({
- isExpression: true,
- });
}
makeDataFunction = () => {
@@ -219,11 +236,20 @@ export default class FunctionSpecProperty extends React.Component {
this.props.onChange(this.props.fieldName, dataFunc)
}
+ onMarkEditing = () => {
+ this.setState({isEditing: true});
+ }
+
+ onUnmarkEditing = () => {
+ this.setState({isEditing: false});
+ }
+
render() {
+ const {dataType} = this.state;
const propClass = this.props.fieldSpec.default === this.props.value ? "maputnik-default-property" : "maputnik-modified-property"
let specField;
- if (this.state.isExpression) {
+ if (dataType === "expression") {
specField = (
);
}
- else if (isZoomField(this.props.value)) {
+ else if (dataType === "zoom_function") {
specField = (
)
}
- else if (isDataField(this.props.value)) {
+ else if (dataType === "data_function") {
specField = (
{},
+ onBlur: () => {},
}
constructor (props) {
@@ -69,6 +71,8 @@ export default class ExpressionProperty extends React.Component {
>
{
- return stringifyPretty(data, {indent: 2, maxLength: 50} );
- }
+ return stringifyPretty(data, {indent: 2, maxLength: 50});
+ },
+ onFocus: () => {},
+ onBlur: () => {},
}
constructor(props) {
super(props)
this.state = {
isEditing: false,
- prevValue: this.getValue(),
+ prevValue: this.props.getValue(this.props.layer),
};
}
- getValue () {
- return this.props.getValue(this.props.layer);
- }
-
componentDidMount () {
this._doc = CodeMirror(this._el, {
- value: this.getValue(),
+ value: this.props.getValue(this.props.layer),
mode: {
name: "javascript",
json: true
@@ -75,12 +73,14 @@ class JSONEditor extends React.Component {
}
onFocus = () => {
+ this.props.onFocus();
this.setState({
isEditing: true
});
}
onBlur = () => {
+ this.props.onBlur();
this.setState({
isEditing: false
});
@@ -96,7 +96,7 @@ class JSONEditor extends React.Component {
if (!this.state.isEditing && prevProps.layer !== this.props.layer) {
this._cancelNextChange = true;
this._doc.setValue(
- this.getValue(),
+ this.props.getValue(this.props.layer),
)
}
}
@@ -104,6 +104,9 @@ class JSONEditor extends React.Component {
onChange = (e) => {
if (this._cancelNextChange) {
this._cancelNextChange = false;
+ this.setState({
+ prevValue: this._doc.getValue(),
+ })
return;
}
const newCode = this._doc.getValue();