mirror of
https://github.com/maputnik/editor.git
synced 2026-09-10 14:27:26 +00:00
a22476cab2
Adds lint to CI and fixes errors. I'm not sure I'm fully proud of all the solutions there. But there's no lint issues and the lint is being checked as part of the CI. --------- Co-authored-by: Yuri Astrakhan <yuriastrakhan@gmail.com>
145 lines
3.8 KiB
TypeScript
145 lines
3.8 KiB
TypeScript
import React from 'react'
|
|
import capitalize from 'lodash.capitalize'
|
|
import {MdDelete} from 'react-icons/md'
|
|
|
|
import InputString from './InputString'
|
|
import InputNumber from './InputNumber'
|
|
import InputButton from './InputButton'
|
|
import FieldDocLabel from './FieldDocLabel'
|
|
import InputEnum from './InputEnum'
|
|
import InputUrl from './InputUrl'
|
|
|
|
|
|
export type FieldDynamicArrayProps = {
|
|
value?: (string | number | undefined)[]
|
|
type?: 'url' | 'number' | 'enum' | 'string'
|
|
default?: (string | number | undefined)[]
|
|
onChange?(values: (string | number | undefined)[] | undefined): unknown
|
|
style?: object
|
|
fieldSpec?: {
|
|
values?: any
|
|
}
|
|
'aria-label'?: string
|
|
label: string
|
|
};
|
|
|
|
|
|
export default class FieldDynamicArray extends React.Component<FieldDynamicArrayProps> {
|
|
changeValue(idx: number, newValue: string | number | undefined) {
|
|
const values = this.values.slice(0)
|
|
values[idx] = newValue
|
|
if (this.props.onChange) this.props.onChange(values)
|
|
}
|
|
|
|
get values() {
|
|
return this.props.value || this.props.default || []
|
|
}
|
|
|
|
addValue = () => {
|
|
const values = this.values.slice(0)
|
|
if (this.props.type === 'number') {
|
|
values.push(0)
|
|
}
|
|
else if (this.props.type === 'url') {
|
|
values.push("");
|
|
}
|
|
else if (this.props.type === 'enum') {
|
|
const {fieldSpec} = this.props;
|
|
const defaultValue = Object.keys(fieldSpec!.values)[0];
|
|
values.push(defaultValue);
|
|
} else {
|
|
values.push("")
|
|
}
|
|
|
|
if (this.props.onChange) this.props.onChange(values)
|
|
}
|
|
|
|
deleteValue(valueIdx: number) {
|
|
const values = this.values.slice(0)
|
|
values.splice(valueIdx, 1)
|
|
|
|
if (this.props.onChange) this.props.onChange(values.length > 0 ? values : undefined);
|
|
}
|
|
|
|
render() {
|
|
const inputs = this.values.map((v, i) => {
|
|
const deleteValueBtn= <DeleteValueInputButton onClick={this.deleteValue.bind(this, i)} />
|
|
let input;
|
|
if(this.props.type === 'url') {
|
|
input = <InputUrl
|
|
value={v as string}
|
|
onChange={this.changeValue.bind(this, i)}
|
|
aria-label={this.props['aria-label'] || this.props.label}
|
|
/>
|
|
}
|
|
else if (this.props.type === 'number') {
|
|
input = <InputNumber
|
|
value={v as number}
|
|
onChange={this.changeValue.bind(this, i)}
|
|
aria-label={this.props['aria-label'] || this.props.label}
|
|
/>
|
|
}
|
|
else if (this.props.type === 'enum') {
|
|
const options = Object.keys(this.props.fieldSpec?.values).map(v => [v, capitalize(v)]);
|
|
input = <InputEnum
|
|
options={options}
|
|
value={v as string}
|
|
onChange={this.changeValue.bind(this, i)}
|
|
aria-label={this.props['aria-label'] || this.props.label}
|
|
/>
|
|
}
|
|
else {
|
|
input = <InputString
|
|
value={v as string}
|
|
onChange={this.changeValue.bind(this, i)}
|
|
aria-label={this.props['aria-label'] || this.props.label}
|
|
/>
|
|
}
|
|
|
|
return <div
|
|
style={this.props.style}
|
|
key={i}
|
|
className="maputnik-array-block"
|
|
>
|
|
<div className="maputnik-array-block-action">
|
|
{deleteValueBtn}
|
|
</div>
|
|
<div className="maputnik-array-block-content">
|
|
{input}
|
|
</div>
|
|
</div>
|
|
})
|
|
|
|
return (
|
|
<div className="maputnik-array">
|
|
{inputs}
|
|
<InputButton
|
|
className="maputnik-array-add-value"
|
|
onClick={this.addValue}
|
|
>
|
|
Add value
|
|
</InputButton>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
type DeleteValueInputButtonProps = {
|
|
onClick?(...args: unknown[]): unknown
|
|
};
|
|
|
|
class DeleteValueInputButton extends React.Component<DeleteValueInputButtonProps> {
|
|
render() {
|
|
return <InputButton
|
|
className="maputnik-delete-stop"
|
|
onClick={this.props.onClick}
|
|
title="Remove array item"
|
|
>
|
|
<FieldDocLabel
|
|
label={<MdDelete />}
|
|
/>
|
|
</InputButton>
|
|
}
|
|
}
|
|
|