Files
editor/src/components/_ExpressionProperty.jsx
orangemug 624ccb5b00 Tidy of components
- Moved all components into a single directory like nextjs
 - Made component names consistent with each other
 - Made component names consistent with their export class names
 - Added storybook for a few components with the aim to extend this further.
2020-06-01 16:09:32 +01:00

138 lines
3.2 KiB
JavaScript

import React from 'react'
import PropTypes from 'prop-types'
import Block from './Block'
import Button from './Button'
import {MdDelete, MdUndo} from 'react-icons/md'
import FieldString from './FieldString'
import labelFromFieldName from './_labelFromFieldName'
import stringifyPretty from 'json-stringify-pretty-compact'
import FieldJsonEditor from './FieldJsonEditor'
export default class ExpressionProperty extends React.Component {
static propTypes = {
onDelete: PropTypes.func,
fieldName: PropTypes.string,
fieldType: PropTypes.string,
fieldSpec: PropTypes.object,
value: PropTypes.any,
errors: PropTypes.object,
onChange: PropTypes.func,
onUndo: PropTypes.func,
canUndo: PropTypes.func,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
}
static defaultProps = {
errors: {},
onFocus: () => {},
onBlur: () => {},
}
constructor (props) {
super();
this.state = {
jsonError: false,
};
}
onJSONInvalid = (err) => {
this.setState({
jsonError: true,
})
}
onJSONValid = () => {
this.setState({
jsonError: false,
})
}
render() {
const {errors, fieldName, fieldType, value, canUndo} = this.props;
const {jsonError} = this.state;
const undoDisabled = canUndo ? !canUndo() : true;
const deleteStopBtn = (
<>
{this.props.onUndo &&
<Button
key="undo_action"
onClick={this.props.onUndo}
disabled={undoDisabled}
className="maputnik-delete-stop"
title="Revert from expression"
>
<MdUndo />
</Button>
}
<Button
key="delete_action"
onClick={this.props.onDelete}
className="maputnik-delete-stop"
title="Delete expression"
>
<MdDelete />
</Button>
</>
);
const fieldKey = fieldType === undefined ? fieldName : `${fieldType}.${fieldName}`;
const fieldError = errors[fieldKey];
const errorKeyStart = `${fieldKey}[`;
const foundErrors = [];
function getValue (data) {
return stringifyPretty(data, {indent: 2, maxLength: 38})
}
if (jsonError) {
foundErrors.push({message: "Invalid JSON"});
}
else {
Object.entries(errors)
.filter(([key, error]) => {
return key.startsWith(errorKeyStart);
})
.forEach(([key, error]) => {
return foundErrors.push(error);
})
if (fieldError) {
foundErrors.push(fieldError);
}
}
return <Block
error={foundErrors}
fieldSpec={this.props.fieldSpec}
label={labelFromFieldName(this.props.fieldName)}
action={deleteStopBtn}
wideMode={true}
>
<FieldJsonEditor
mode={{name: "mgl"}}
lint={{
context: "expression",
spec: this.props.fieldSpec,
}}
className="maputnik-expression-editor"
onFocus={this.props.onFocus}
onBlur={this.props.onBlur}
onJSONInvalid={this.onJSONInvalid}
onJSONValid={this.onJSONValid}
layer={value}
lineNumbers={false}
maxHeight={200}
lineWrapping={true}
getValue={getValue}
onChange={this.props.onChange}
/>
</Block>
}
}