mirror of
https://github.com/maputnik/editor.git
synced 2026-02-06 04:30:01 +00:00
Migrate more components
This commit is contained in:
19
package-lock.json
generated
19
package-lock.json
generated
@@ -67,6 +67,7 @@
|
||||
"@storybook/react": "^7.6.5",
|
||||
"@storybook/react-vite": "^7.6.5",
|
||||
"@storybook/theming": "^7.6.5",
|
||||
"@types/codemirror": "^5.60.15",
|
||||
"@types/color": "^3.0.6",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/lodash.capitalize": "^4.2.9",
|
||||
@@ -4589,6 +4590,15 @@
|
||||
"@types/chai": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/codemirror": {
|
||||
"version": "5.60.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.15.tgz",
|
||||
"integrity": "sha512-dTOvwEQ+ouKJ/rE9LT1Ue2hmP6H1mZv5+CCnNWu2qtiOe2LQa9lCprEY20HxiDmV/Bxh+dXjywmy5aKvoGjULA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/tern": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/color": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.6.tgz",
|
||||
@@ -4976,6 +4986,15 @@
|
||||
"integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/tern": {
|
||||
"version": "0.23.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz",
|
||||
"integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/uuid": {
|
||||
"version": "9.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz",
|
||||
|
||||
@@ -96,6 +96,7 @@
|
||||
"@storybook/react": "^7.6.5",
|
||||
"@storybook/react-vite": "^7.6.5",
|
||||
"@storybook/theming": "^7.6.5",
|
||||
"@types/codemirror": "^5.60.15",
|
||||
"@types/color": "^3.0.6",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/lodash.capitalize": "^4.2.9",
|
||||
|
||||
@@ -1,47 +1,45 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import classnames from 'classnames';
|
||||
|
||||
import Block from './Block'
|
||||
import FieldString from './FieldString'
|
||||
import CodeMirror from 'codemirror';
|
||||
import CodeMirror, { ModeSpec } from 'codemirror';
|
||||
|
||||
import 'codemirror/mode/javascript/javascript'
|
||||
import 'codemirror/addon/lint/lint'
|
||||
import 'codemirror/addon/edit/matchbrackets'
|
||||
import 'codemirror/lib/codemirror.css'
|
||||
import 'codemirror/addon/lint/lint.css'
|
||||
import jsonlint from 'jsonlint'
|
||||
import stringifyPretty from 'json-stringify-pretty-compact'
|
||||
import '../util/codemirror-mgl';
|
||||
|
||||
|
||||
export default class InputJson extends React.Component {
|
||||
static propTypes = {
|
||||
layer: PropTypes.any.isRequired,
|
||||
maxHeight: PropTypes.number,
|
||||
onChange: PropTypes.func,
|
||||
lineNumbers: PropTypes.bool,
|
||||
lineWrapping: PropTypes.bool,
|
||||
getValue: PropTypes.func,
|
||||
gutters: PropTypes.array,
|
||||
className: PropTypes.string,
|
||||
onFocus: PropTypes.func,
|
||||
onBlur: PropTypes.func,
|
||||
onJSONValid: PropTypes.func,
|
||||
onJSONInvalid: PropTypes.func,
|
||||
mode: PropTypes.object,
|
||||
lint: PropTypes.oneOfType([
|
||||
PropTypes.bool,
|
||||
PropTypes.object,
|
||||
]),
|
||||
}
|
||||
type InputJsonProps = {
|
||||
layer: any
|
||||
maxHeight?: number
|
||||
onChange?(...args: unknown[]): unknown
|
||||
lineNumbers?: boolean
|
||||
lineWrapping?: boolean
|
||||
getValue(data: any): string
|
||||
gutters?: string[]
|
||||
className?: string
|
||||
onFocus?(...args: unknown[]): unknown
|
||||
onBlur?(...args: unknown[]): unknown
|
||||
onJSONValid?(...args: unknown[]): unknown
|
||||
onJSONInvalid?(...args: unknown[]): unknown
|
||||
mode?: ModeSpec<any>
|
||||
lint?: boolean | object
|
||||
};
|
||||
|
||||
type InputJsonState = {
|
||||
isEditing: boolean
|
||||
showMessage: boolean
|
||||
prevValue: string
|
||||
};
|
||||
|
||||
export default class InputJson extends React.Component<InputJsonProps, InputJsonState> {
|
||||
static defaultProps = {
|
||||
lineNumbers: true,
|
||||
lineWrapping: false,
|
||||
gutters: ["CodeMirror-lint-markers"],
|
||||
getValue: (data) => {
|
||||
getValue: (data: any) => {
|
||||
return stringifyPretty(data, {indent: 2, maxLength: 40});
|
||||
},
|
||||
onFocus: () => {},
|
||||
@@ -49,8 +47,12 @@ export default class InputJson extends React.Component {
|
||||
onJSONInvalid: () => {},
|
||||
onJSONValid: () => {},
|
||||
}
|
||||
_keyEvent: string;
|
||||
_doc: CodeMirror.Editor | undefined;
|
||||
_el: HTMLDivElement | null = null;
|
||||
_cancelNextChange: boolean = false;
|
||||
|
||||
constructor(props) {
|
||||
constructor(props: InputJsonProps) {
|
||||
super(props);
|
||||
this._keyEvent = "keyboard";
|
||||
this.state = {
|
||||
@@ -61,7 +63,7 @@ export default class InputJson extends React.Component {
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this._doc = CodeMirror(this._el, {
|
||||
this._doc = CodeMirror(this._el!, {
|
||||
value: this.props.getValue(this.props.layer),
|
||||
mode: this.props.mode || {
|
||||
name: "mgl",
|
||||
@@ -84,12 +86,12 @@ export default class InputJson extends React.Component {
|
||||
this._doc.on('blur', this.onBlur);
|
||||
}
|
||||
|
||||
onPointerDown = (cm, e) => {
|
||||
onPointerDown = () => {
|
||||
this._keyEvent = "pointer";
|
||||
}
|
||||
|
||||
onFocus = (cm, e) => {
|
||||
this.props.onFocus();
|
||||
onFocus = () => {
|
||||
if (this.props.onFocus) this.props.onFocus();
|
||||
this.setState({
|
||||
isEditing: true,
|
||||
showMessage: (this._keyEvent === "keyboard"),
|
||||
@@ -98,7 +100,7 @@ export default class InputJson extends React.Component {
|
||||
|
||||
onBlur = () => {
|
||||
this._keyEvent = "keyboard";
|
||||
this.props.onBlur();
|
||||
if (this.props.onBlur) this.props.onBlur();
|
||||
this.setState({
|
||||
isEditing: false,
|
||||
showMessage: false,
|
||||
@@ -106,29 +108,29 @@ export default class InputJson extends React.Component {
|
||||
}
|
||||
|
||||
componentWillUnMount () {
|
||||
this._doc.off('change', this.onChange);
|
||||
this._doc.off('focus', this.onFocus);
|
||||
this._doc.off('blur', this.onBlur);
|
||||
this._doc!.off('change', this.onChange);
|
||||
this._doc!.off('focus', this.onFocus);
|
||||
this._doc!.off('blur', this.onBlur);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
componentDidUpdate(prevProps: InputJsonProps) {
|
||||
if (!this.state.isEditing && prevProps.layer !== this.props.layer) {
|
||||
this._cancelNextChange = true;
|
||||
this._doc.setValue(
|
||||
this._doc!.setValue(
|
||||
this.props.getValue(this.props.layer),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
onChange = (e) => {
|
||||
onChange = (_e: unknown) => {
|
||||
if (this._cancelNextChange) {
|
||||
this._cancelNextChange = false;
|
||||
this.setState({
|
||||
prevValue: this._doc.getValue(),
|
||||
prevValue: this._doc!.getValue(),
|
||||
})
|
||||
return;
|
||||
}
|
||||
const newCode = this._doc.getValue();
|
||||
const newCode = this._doc!.getValue();
|
||||
|
||||
if (this.state.prevValue !== newCode) {
|
||||
let parsedLayer, err;
|
||||
@@ -139,12 +141,12 @@ export default class InputJson extends React.Component {
|
||||
console.warn(_err)
|
||||
}
|
||||
|
||||
if (err) {
|
||||
if (err && this.props.onJSONInvalid) {
|
||||
this.props.onJSONInvalid();
|
||||
}
|
||||
else {
|
||||
this.props.onChange(parsedLayer)
|
||||
this.props.onJSONValid();
|
||||
if (this.props.onChange) this.props.onChange(parsedLayer)
|
||||
if (this.props.onJSONValid) this.props.onJSONValid();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +157,7 @@ export default class InputJson extends React.Component {
|
||||
|
||||
render() {
|
||||
const {showMessage} = this.state;
|
||||
const style = {};
|
||||
const style = {} as {maxHeight?: number};
|
||||
if (this.props.maxHeight) {
|
||||
style.maxHeight = this.props.maxHeight;
|
||||
}
|
||||
@@ -1,18 +1,17 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import {otherFilterOps} from '../libs/filterops'
|
||||
import InputString from './InputString'
|
||||
import InputAutocomplete from './InputAutocomplete'
|
||||
import InputSelect from './InputSelect'
|
||||
|
||||
function tryParseInt(v) {
|
||||
function tryParseInt(v: string | number) {
|
||||
if (v === '') return v
|
||||
if (isNaN(v)) return v
|
||||
return parseFloat(v)
|
||||
if (isNaN(v as number)) return v
|
||||
return parseFloat(v as string)
|
||||
}
|
||||
|
||||
function tryParseBool(v) {
|
||||
function tryParseBool(v: string | boolean) {
|
||||
const isString = (typeof(v) === "string");
|
||||
if(!isString) {
|
||||
return v;
|
||||
@@ -29,24 +28,24 @@ function tryParseBool(v) {
|
||||
}
|
||||
}
|
||||
|
||||
function parseFilter(v) {
|
||||
v = tryParseInt(v);
|
||||
v = tryParseBool(v);
|
||||
function parseFilter(v: string | boolean | number) {
|
||||
v = tryParseInt(v as any);
|
||||
v = tryParseBool(v as any);
|
||||
return v;
|
||||
}
|
||||
|
||||
export default class SingleFilterEditor extends React.Component {
|
||||
static propTypes = {
|
||||
filter: PropTypes.array.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
properties: PropTypes.object,
|
||||
}
|
||||
type SingleFilterEditorProps = {
|
||||
filter: any[]
|
||||
onChange(...args: unknown[]): unknown
|
||||
properties?: {[key: string]: string}
|
||||
};
|
||||
|
||||
export default class SingleFilterEditor extends React.Component<SingleFilterEditorProps> {
|
||||
static defaultProps = {
|
||||
properties: {},
|
||||
}
|
||||
|
||||
onFilterPartChanged(filterOp, propertyName, filterArgs) {
|
||||
onFilterPartChanged(filterOp: string, propertyName: string, filterArgs: string[]) {
|
||||
let newFilter = [filterOp, propertyName, ...filterArgs.map(parseFilter)]
|
||||
if(filterOp === 'has' || filterOp === '!has') {
|
||||
newFilter = [filterOp, propertyName]
|
||||
@@ -67,15 +66,15 @@ export default class SingleFilterEditor extends React.Component {
|
||||
<InputAutocomplete
|
||||
aria-label="key"
|
||||
value={propertyName}
|
||||
options={Object.keys(this.props.properties).map(propName => [propName, propName])}
|
||||
onChange={newPropertyName => this.onFilterPartChanged(filterOp, newPropertyName, filterArgs)}
|
||||
options={Object.keys(this.props.properties!).map(propName => [propName, propName])}
|
||||
onChange={(newPropertyName: string) => this.onFilterPartChanged(filterOp, newPropertyName, filterArgs)}
|
||||
/>
|
||||
</div>
|
||||
<div className="maputnik-filter-editor-operator">
|
||||
<InputSelect
|
||||
aria-label="function"
|
||||
value={filterOp}
|
||||
onChange={newFilterOp => this.onFilterPartChanged(newFilterOp, propertyName, filterArgs)}
|
||||
onChange={(newFilterOp: string) => this.onFilterPartChanged(newFilterOp, propertyName, filterArgs)}
|
||||
options={otherFilterOps}
|
||||
/>
|
||||
</div>
|
||||
@@ -84,12 +83,11 @@ export default class SingleFilterEditor extends React.Component {
|
||||
<InputString
|
||||
aria-label="value"
|
||||
value={filterArgs.join(',')}
|
||||
onChange={ v=> this.onFilterPartChanged(filterOp, propertyName, v.split(','))}
|
||||
onChange={(v: string) => this.onFilterPartChanged(filterOp, propertyName, v.split(','))}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user