maputnik/src/components/layers/JSONEditor.jsx

91 lines
2.3 KiB
React
Raw Normal View History

2016-12-22 15:27:58 +01:00
import React from 'react'
import PropTypes from 'prop-types'
2016-12-22 15:27:58 +01:00
import {Controlled as CodeMirror} from 'react-codemirror2'
2016-12-22 15:27:58 +01:00
import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput'
import 'codemirror/mode/javascript/javascript'
2017-03-08 22:35:19 +01:00
import 'codemirror/addon/lint/lint'
2016-12-22 15:27:58 +01:00
import 'codemirror/lib/codemirror.css'
2017-03-08 22:35:19 +01:00
import 'codemirror/addon/lint/lint.css'
2016-12-22 15:27:58 +01:00
import '../../codemirror-maputnik.css'
2017-03-08 22:35:19 +01:00
import jsonlint from 'jsonlint'
// This is mainly because of this issue <https://github.com/zaach/jsonlint/issues/57> also the API has changed, see comment in file
import '../../vendor/codemirror/addon/lint/json-lint'
2016-12-22 15:27:58 +01:00
class JSONEditor extends React.Component {
static propTypes = {
layer: PropTypes.object.isRequired,
onChange: PropTypes.func,
2016-12-22 15:27:58 +01:00
}
constructor(props) {
super(props)
this.state = {
code: JSON.stringify(props.layer, null, 2)
}
}
2018-05-17 12:24:39 +02:00
UNSAFE_componentWillReceiveProps(nextProps) {
2016-12-22 15:27:58 +01:00
this.setState({
code: JSON.stringify(nextProps.layer, null, 2)
})
}
shouldComponentUpdate(nextProps, nextState) {
try {
const parsedLayer = JSON.parse(this.state.code)
// If the structure is still the same do not update
// because it affects editing experience by reformatting all the time
return nextState.code !== JSON.stringify(parsedLayer, null, 2)
} catch(err) {
return true
}
}
2016-12-22 15:27:58 +01:00
onCodeUpdate(newCode) {
try {
const parsedLayer = JSON.parse(newCode)
this.props.onChange(parsedLayer)
} catch(err) {
console.warn(err)
} finally {
2016-12-22 15:27:58 +01:00
this.setState({
code: newCode
})
}
}
2016-12-31 14:37:40 +01:00
resetValue() {
console.log('reset')
this.setState({
code: JSON.stringify(this.props.layer, null, 2)
})
}
2016-12-22 15:27:58 +01:00
render() {
const codeMirrorOptions = {
mode: {name: "javascript", json: true},
tabSize: 2,
theme: 'maputnik',
viewportMargin: Infinity,
2017-03-08 22:35:19 +01:00
lineNumbers: true,
lint: true,
gutters: ["CodeMirror-lint-markers"],
2016-12-26 11:55:39 +01:00
scrollbarStyle: "null",
2016-12-22 15:27:58 +01:00
}
return <CodeMirror
value={this.state.code}
onBeforeChange={(editor, data, value) => this.onCodeUpdate(value)}
2016-12-31 14:37:40 +01:00
onFocusChange={focused => focused ? true : this.resetValue()}
2016-12-22 15:27:58 +01:00
options={codeMirrorOptions}
/>
}
}
export default JSONEditor