Migrate more components

This commit is contained in:
HarelM
2023-12-21 15:16:41 +02:00
parent c633368a9a
commit df65cc3eff
4 changed files with 85 additions and 65 deletions

19
package-lock.json generated
View File

@@ -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",

View File

@@ -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",

View File

@@ -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;
}

View File

@@ -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>
}
}