diff --git a/src/components/FieldEnum.jsx b/src/components/FieldEnum.jsx deleted file mode 100644 index f4268ece..00000000 --- a/src/components/FieldEnum.jsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import InputEnum from './InputEnum' -import Block from './Block'; -import Fieldset from './Fieldset'; - - -export default class FieldEnum extends React.Component { - static propTypes = { - ...InputEnum.propTypes, - } - - render() { - const {props} = this; - - return
- -
- } -} diff --git a/src/components/FieldEnum.tsx b/src/components/FieldEnum.tsx new file mode 100644 index 00000000..054d3d3c --- /dev/null +++ b/src/components/FieldEnum.tsx @@ -0,0 +1,17 @@ +import React from 'react' +import InputEnum, {InputEnumProps} from './InputEnum' +import Fieldset from './Fieldset'; + + +type FieldEnumProps = InputEnumProps & { label : string }; + + +export default class FieldEnum extends React.Component { + render() { + const {props} = this; + + return
+ +
+ } +} \ No newline at end of file diff --git a/src/components/FieldId.jsx b/src/components/FieldId.tsx similarity index 60% rename from src/components/FieldId.jsx rename to src/components/FieldId.tsx index 1ce8cffc..a4dba616 100644 --- a/src/components/FieldId.jsx +++ b/src/components/FieldId.tsx @@ -1,18 +1,17 @@ import React from 'react' -import PropTypes from 'prop-types' import {latest} from '@maplibre/maplibre-gl-style-spec' import Block from './Block' import InputString from './InputString' -export default class FieldId extends React.Component { - static propTypes = { - value: PropTypes.string.isRequired, - wdKey: PropTypes.string.isRequired, - onChange: PropTypes.func.isRequired, - error: PropTypes.object, - } +type FieldIdProps = { + value: string + wdKey: string + onChange(...args: unknown[]): unknown + error?: unknown[] +}; +export default class FieldId extends React.Component { render() { return { static defaultProps = { value: [], default: [], } - constructor (props) { + constructor (props: FieldArrayProps) { super(props); this.state = { value: this.props.value.slice(0), @@ -27,8 +32,8 @@ export default class FieldArray extends React.Component { }; } - static getDerivedStateFromProps(props, state) { - const value = []; + static getDerivedStateFromProps(props: FieldArrayProps, state: FieldArrayState) { + const value: any[] = []; const initialPropsValue = state.initialPropsValue.slice(0); Array(props.length).fill(null).map((_, i) => { @@ -47,24 +52,24 @@ export default class FieldArray extends React.Component { }; } - isComplete (value) { + isComplete(value: unknown[]) { return Array(this.props.length).fill(null).every((_, i) => { const val = value[i] return !(val === undefined || val === ""); }); } - changeValue(idx, newValue) { + changeValue(idx: number, newValue: string) { const value = this.state.value.slice(0); value[idx] = newValue; this.setState({ value, }, () => { - if (this.isComplete(value)) { + if (this.isComplete(value) && this.props.onChange) { this.props.onChange(value); } - else { + else if (this.props.onChange){ // Unset until complete this.props.onChange(undefined); } @@ -85,8 +90,8 @@ export default class FieldArray extends React.Component { if(this.props.type === 'number') { return { sum += label.length @@ -13,18 +12,20 @@ function optionsLabelLength(options) { } -export default class InputEnum extends React.Component { - static propTypes = { - "data-wd-key": PropTypes.string, - value: PropTypes.string, - style: PropTypes.object, - default: PropTypes.string, - name: PropTypes.string, - onChange: PropTypes.func, - options: PropTypes.array, - 'aria-label': PropTypes.string, - } +export type InputEnumProps = { + "data-wd-key"?: string + value?: string + style?: object + default?: string + name: string + onChange(...args: unknown[]): unknown + options: any[] + 'aria-label'?: string + label?: string +}; + +export default class InputEnum extends React.Component { render() { const {options, value, onChange, name, label} = this.props; @@ -32,14 +33,14 @@ export default class InputEnum extends React.Component { return } else { return diff --git a/src/components/InputFont.jsx b/src/components/InputFont.tsx similarity index 72% rename from src/components/InputFont.jsx rename to src/components/InputFont.tsx index 53540840..b015a8ed 100644 --- a/src/components/InputFont.jsx +++ b/src/components/InputFont.tsx @@ -1,17 +1,17 @@ import React from 'react' -import PropTypes from 'prop-types' import InputAutocomplete from './InputAutocomplete' -export default class FieldFont extends React.Component { - static propTypes = { - value: PropTypes.array, - default: PropTypes.array, - fonts: PropTypes.array, - style: PropTypes.object, - onChange: PropTypes.func.isRequired, - 'aria-label': PropTypes.string, - } +type FieldFontProps = { + name: string + value?: string[] + default?: string[] + fonts?: unknown[] + style?: object + onChange(...args: unknown[]): unknown + 'aria-label'?: string +}; +export default class FieldFont extends React.Component { static defaultProps = { fonts: [] } @@ -28,7 +28,7 @@ export default class FieldFont extends React.Component { } } - changeFont(idx, newValue) { + changeFont(idx: number, newValue: string) { const changedValues = this.values.slice(0) changedValues[idx] = newValue const filteredValues = changedValues @@ -46,7 +46,7 @@ export default class FieldFont extends React.Component { [f, f])} + options={this.props.fonts?.map(f => [f, f])} onChange={this.changeFont.bind(this, i)} /> diff --git a/src/components/InputMultiInput.jsx b/src/components/InputMultiInput.tsx similarity index 67% rename from src/components/InputMultiInput.jsx rename to src/components/InputMultiInput.tsx index a9d2aad1..632b8c3b 100644 --- a/src/components/InputMultiInput.jsx +++ b/src/components/InputMultiInput.tsx @@ -1,16 +1,15 @@ import React from 'react' -import PropTypes from 'prop-types' import classnames from 'classnames' -import InputButton from './InputButton' -export default class InputMultiInput extends React.Component { - static propTypes = { - name: PropTypes.string.isRequired, - value: PropTypes.string.isRequired, - options: PropTypes.array.isRequired, - onChange: PropTypes.func.isRequired, - } +type InputMultiInputProps = { + name: string + value: string + options: any[] + onChange(...args: unknown[]): unknown + 'aria-label'?: string +}; +export default class InputMultiInput extends React.Component { render() { let options = this.props.options if(options.length > 0 && !Array.isArray(options[0])) { @@ -25,7 +24,7 @@ export default class InputMultiInput extends React.Component { > this.props.onChange(val)} + onChange={_e => this.props.onChange(val)} value={val} checked={val === selectedValue} /> diff --git a/src/components/InputNumber.jsx b/src/components/InputNumber.tsx similarity index 74% rename from src/components/InputNumber.jsx rename to src/components/InputNumber.tsx index f2562881..c7b044df 100644 --- a/src/components/InputNumber.jsx +++ b/src/components/InputNumber.tsx @@ -1,27 +1,35 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React, { BaseSyntheticEvent } from 'react' let IDX = 0; -export default class InputNumber extends React.Component { - static propTypes = { - value: PropTypes.number, - default: PropTypes.number, - min: PropTypes.number, - max: PropTypes.number, - onChange: PropTypes.func, - allowRange: PropTypes.bool, - rangeStep: PropTypes.number, - wdKey: PropTypes.string, - required: PropTypes.bool, - "aria-label": PropTypes.string, - } +type InputNumberProps = { + value?: number + default?: number + min?: number + max?: number + onChange?(...args: unknown[]): unknown + allowRange?: boolean + rangeStep?: number + wdKey?: string + required?: boolean + "aria-label"?: string +}; +type InputNumberState = { + uuid: number + editing: boolean + editingRange?: boolean + value?: number + dirtyValue?: number +} + +export default class InputNumber extends React.Component { static defaultProps = { rangeStep: 1 } + _keyboardEvent: boolean = false; - constructor(props) { + constructor(props: InputNumberProps) { super(props) this.state = { uuid: IDX++, @@ -31,7 +39,7 @@ export default class InputNumber extends React.Component { } } - static getDerivedStateFromProps(props, state) { + static getDerivedStateFromProps(props: InputNumberProps, state: InputNumberState) { if (!state.editing && props.value !== state.value) { return { value: props.value, @@ -41,16 +49,15 @@ export default class InputNumber extends React.Component { return null; } - changeValue(newValue) { + changeValue(newValue: number | string | undefined) { const value = (newValue === "" || newValue === undefined) ? - undefined : - parseFloat(newValue); + undefined : +newValue; const hasChanged = this.props.value !== value; if(this.isValid(value) && hasChanged) { - this.props.onChange(value) + if (this.props.onChange) this.props.onChange(value) this.setState({ - value: newValue, + value: value, }); } else if (!this.isValid(value) && hasChanged) { @@ -60,25 +67,25 @@ export default class InputNumber extends React.Component { } this.setState({ - dirtyValue: newValue === "" ? undefined : newValue, + dirtyValue: newValue === "" ? undefined : value, }) } - isValid(v) { + isValid(v: number | string | undefined) { if (v === undefined) { return true; } - const value = parseFloat(v) + const value = +v; if(isNaN(value)) { return false } - if(!isNaN(this.props.min) && value < this.props.min) { + if(!isNaN(this.props.min!) && value < this.props.min!) { return false } - if(!isNaN(this.props.max) && value > this.props.max) { + if(!isNaN(this.props.max!) && value > this.props.max!) { return false } @@ -88,7 +95,7 @@ export default class InputNumber extends React.Component { resetValue = () => { this.setState({editing: false}); // Reset explicitly to default value if value has been cleared - if(this.state.value === "") { + if(!this.state.value) { return; } @@ -104,8 +111,8 @@ export default class InputNumber extends React.Component { } } - onChangeRange = (e) => { - let value = parseFloat(e.target.value, 10); + onChangeRange = (e: BaseSyntheticEvent) => { + let value = parseFloat(e.target.value); const step = this.props.rangeStep; let dirtyValue = value; @@ -119,11 +126,11 @@ export default class InputNumber extends React.Component { // for example we might go from 13 to 13.23, however because we know // that came from a keyboard event we always want to increase by a // single step value. - if (value < this.state.dirtyValue) { - value = this.state.value - step; + if (value < this.state.dirtyValue!) { + value = this.state.value! - step; } else { - value = this.state.value + step + value = this.state.value! + step } dirtyValue = value; } @@ -140,10 +147,10 @@ export default class InputNumber extends React.Component { this._keyboardEvent = false; // Clamp between min/max - value = Math.max(this.props.min, Math.min(this.props.max, value)); + value = Math.max(this.props.min!, Math.min(this.props.max!, value)); this.setState({value, dirtyValue}); - this.props.onChange(value); + if (this.props.onChange) this.props.onChange(value); } render() { @@ -196,15 +203,15 @@ export default class InputNumber extends React.Component { type="text" spellCheck="false" className="maputnik-number" - placeholder={this.props.default} + placeholder={this.props.default?.toString()} value={inputValue === undefined ? "" : inputValue} - onFocus={e => { + onFocus={_e => { this.setState({editing: true}); }} onChange={e => { this.changeValue(e.target.value); }} - onBlur={e => { + onBlur={_e => { this.setState({editing: false}); this.resetValue() }} @@ -218,7 +225,7 @@ export default class InputNumber extends React.Component { aria-label={this.props['aria-label']} spellCheck="false" className="maputnik-number" - placeholder={this.props.default} + placeholder={this.props.default?.toString()} value={value === undefined ? "" : value} onChange={e => this.changeValue(e.target.value)} onFocus={() => { diff --git a/src/components/InputString.tsx b/src/components/InputString.tsx index 0b3896f1..75ef8f50 100644 --- a/src/components/InputString.tsx +++ b/src/components/InputString.tsx @@ -5,7 +5,7 @@ type InputStringProps = { value?: string style?: object default?: string - onChange(...args: unknown[]): unknown + onChange?(...args: unknown[]): unknown onInput(...args: unknown[]): unknown multi?: boolean required?: boolean @@ -83,11 +83,11 @@ export default class InputString extends React.Component { if(this.state.value!==this.props.value) { this.setState({editing: false}); - this.props.onChange(this.state.value); + if (this.props.onChange) this.props.onChange(this.state.value); } }, onKeyDown: (e) => { - if (e.keyCode === 13) { + if (e.keyCode === 13 && this.props.onChange) { this.props.onChange(this.state.value); } },