mirror of
https://github.com/maputnik/editor.git
synced 2026-07-31 02:07:26 +00:00
Migrate more components
This commit is contained in:
Generated
+10
@@ -69,6 +69,7 @@
|
|||||||
"@storybook/theming": "^7.6.5",
|
"@storybook/theming": "^7.6.5",
|
||||||
"@types/color": "^3.0.6",
|
"@types/color": "^3.0.6",
|
||||||
"@types/cors": "^2.8.17",
|
"@types/cors": "^2.8.17",
|
||||||
|
"@types/lodash.capitalize": "^4.2.9",
|
||||||
"@types/lodash.isequal": "^4.5.8",
|
"@types/lodash.isequal": "^4.5.8",
|
||||||
"@types/lodash.throttle": "^4.1.9",
|
"@types/lodash.throttle": "^4.1.9",
|
||||||
"@types/react": "^16.14.52",
|
"@types/react": "^16.14.52",
|
||||||
@@ -4732,6 +4733,15 @@
|
|||||||
"integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==",
|
"integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/lodash.capitalize": {
|
||||||
|
"version": "4.2.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/lodash.capitalize/-/lodash.capitalize-4.2.9.tgz",
|
||||||
|
"integrity": "sha512-SV1dav/WbuI816SVig4trFz8ID/m5maVzC8I/E/DejPvmlXvIhw7Y0GWxJ03UhU6qaZOj6qQnR1xxC0mP7ZXoQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/lodash": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/lodash.isequal": {
|
"node_modules/@types/lodash.isequal": {
|
||||||
"version": "4.5.8",
|
"version": "4.5.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/lodash.isequal/-/lodash.isequal-4.5.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/lodash.isequal/-/lodash.isequal-4.5.8.tgz",
|
||||||
|
|||||||
@@ -98,6 +98,7 @@
|
|||||||
"@storybook/theming": "^7.6.5",
|
"@storybook/theming": "^7.6.5",
|
||||||
"@types/color": "^3.0.6",
|
"@types/color": "^3.0.6",
|
||||||
"@types/cors": "^2.8.17",
|
"@types/cors": "^2.8.17",
|
||||||
|
"@types/lodash.capitalize": "^4.2.9",
|
||||||
"@types/lodash.isequal": "^4.5.8",
|
"@types/lodash.isequal": "^4.5.8",
|
||||||
"@types/lodash.throttle": "^4.1.9",
|
"@types/lodash.throttle": "^4.1.9",
|
||||||
"@types/react": "^16.14.52",
|
"@types/react": "^16.14.52",
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import React from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import FieldDocLabel from './FieldDocLabel'
|
import FieldDocLabel from './FieldDocLabel'
|
||||||
import Doc from './Doc'
|
import Doc from './Doc'
|
||||||
|
|
||||||
type FieldsetProps = {
|
type FieldsetProps = {
|
||||||
label: string,
|
label: string,
|
||||||
fieldSpec?: { doc?: string },
|
fieldSpec?: { doc?: string },
|
||||||
action?: string,
|
action?: ReactElement,
|
||||||
};
|
};
|
||||||
|
|
||||||
type FieldsetState = {
|
type FieldsetState = {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react'
|
|||||||
import InputString from './InputString'
|
import InputString from './InputString'
|
||||||
import InputNumber from './InputNumber'
|
import InputNumber from './InputNumber'
|
||||||
|
|
||||||
type FieldArrayProps = {
|
export type FieldArrayProps = {
|
||||||
value: string[]
|
value: string[]
|
||||||
type?: string
|
type?: string
|
||||||
length?: number
|
length?: number
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import Autocomplete from 'react-autocomplete'
|
|||||||
|
|
||||||
const MAX_HEIGHT = 140;
|
const MAX_HEIGHT = 140;
|
||||||
|
|
||||||
type InputAutocompleteProps = {
|
export type InputAutocompleteProps = {
|
||||||
value?: string
|
value?: string
|
||||||
options: any[]
|
options: any[]
|
||||||
onChange(...args: unknown[]): unknown
|
onChange(...args: unknown[]): unknown
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
type InputCheckboxProps = {
|
export type InputCheckboxProps = {
|
||||||
value?: boolean
|
value?: boolean
|
||||||
style?: object
|
style?: object
|
||||||
onChange(...args: unknown[]): unknown
|
onChange(...args: unknown[]): unknown
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ function formatColor(color: ColorResult): string {
|
|||||||
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${rgb.a})`
|
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${rgb.a})`
|
||||||
}
|
}
|
||||||
|
|
||||||
type InputColorProps = {
|
export type InputColorProps = {
|
||||||
onChange(...args: unknown[]): unknown
|
onChange(...args: unknown[]): unknown
|
||||||
name?: string
|
name?: string
|
||||||
value?: string
|
value?: string
|
||||||
|
|||||||
@@ -1,30 +1,34 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import capitalize from 'lodash.capitalize'
|
||||||
|
import {MdDelete} from 'react-icons/md'
|
||||||
|
|
||||||
import InputString from './InputString'
|
import InputString from './InputString'
|
||||||
import InputNumber from './InputNumber'
|
import InputNumber from './InputNumber'
|
||||||
import InputButton from './InputButton'
|
import InputButton from './InputButton'
|
||||||
import {MdDelete} from 'react-icons/md'
|
|
||||||
import FieldDocLabel from './FieldDocLabel'
|
import FieldDocLabel from './FieldDocLabel'
|
||||||
import InputEnum from './InputEnum'
|
import InputEnum from './InputEnum'
|
||||||
import capitalize from 'lodash.capitalize'
|
|
||||||
import InputUrl from './InputUrl'
|
import InputUrl from './InputUrl'
|
||||||
|
|
||||||
|
|
||||||
export default class FieldDynamicArray extends React.Component {
|
export type FieldDynamicArrayProps = {
|
||||||
static propTypes = {
|
value?: (string | number)[]
|
||||||
value: PropTypes.array,
|
type?: 'url' | 'number' | 'enum'
|
||||||
type: PropTypes.string,
|
default?: (string | number)[]
|
||||||
default: PropTypes.array,
|
onChange?(...args: unknown[]): unknown
|
||||||
onChange: PropTypes.func,
|
style?: object
|
||||||
style: PropTypes.object,
|
fieldSpec?: {
|
||||||
fieldSpec: PropTypes.object,
|
values?: any
|
||||||
'aria-label': PropTypes.string,
|
|
||||||
}
|
}
|
||||||
|
'aria-label'?: string
|
||||||
|
label: string
|
||||||
|
};
|
||||||
|
|
||||||
changeValue(idx, newValue) {
|
|
||||||
|
export default class FieldDynamicArray extends React.Component<FieldDynamicArrayProps> {
|
||||||
|
changeValue(idx: number, newValue: string | number) {
|
||||||
const values = this.values.slice(0)
|
const values = this.values.slice(0)
|
||||||
values[idx] = newValue
|
values[idx] = newValue
|
||||||
this.props.onChange(values)
|
if (this.props.onChange) this.props.onChange(values)
|
||||||
}
|
}
|
||||||
|
|
||||||
get values() {
|
get values() {
|
||||||
@@ -41,20 +45,20 @@ export default class FieldDynamicArray extends React.Component {
|
|||||||
}
|
}
|
||||||
else if (this.props.type === 'enum') {
|
else if (this.props.type === 'enum') {
|
||||||
const {fieldSpec} = this.props;
|
const {fieldSpec} = this.props;
|
||||||
const defaultValue = Object.keys(fieldSpec.values)[0];
|
const defaultValue = Object.keys(fieldSpec!.values)[0];
|
||||||
values.push(defaultValue);
|
values.push(defaultValue);
|
||||||
} else {
|
} else {
|
||||||
values.push("")
|
values.push("")
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.onChange(values)
|
if (this.props.onChange) this.props.onChange(values)
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteValue(valueIdx) {
|
deleteValue(valueIdx: number) {
|
||||||
const values = this.values.slice(0)
|
const values = this.values.slice(0)
|
||||||
values.splice(valueIdx, 1)
|
values.splice(valueIdx, 1)
|
||||||
|
|
||||||
this.props.onChange(values.length > 0 ? values : undefined);
|
if (this.props.onChange) this.props.onChange(values.length > 0 ? values : undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -63,30 +67,30 @@ export default class FieldDynamicArray extends React.Component {
|
|||||||
let input;
|
let input;
|
||||||
if(this.props.type === 'url') {
|
if(this.props.type === 'url') {
|
||||||
input = <InputUrl
|
input = <InputUrl
|
||||||
value={v}
|
value={v as string}
|
||||||
onChange={this.changeValue.bind(this, i)}
|
onChange={this.changeValue.bind(this, i)}
|
||||||
aria-label={this.props['aria-label'] || this.props.label}
|
aria-label={this.props['aria-label'] || this.props.label}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
else if (this.props.type === 'number') {
|
else if (this.props.type === 'number') {
|
||||||
input = <InputNumber
|
input = <InputNumber
|
||||||
value={v}
|
value={v as number}
|
||||||
onChange={this.changeValue.bind(this, i)}
|
onChange={this.changeValue.bind(this, i)}
|
||||||
aria-label={this.props['aria-label'] || this.props.label}
|
aria-label={this.props['aria-label'] || this.props.label}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
else if (this.props.type === 'enum') {
|
else if (this.props.type === 'enum') {
|
||||||
const options = Object.keys(this.props.fieldSpec.values).map(v => [v, capitalize(v)]);
|
const options = Object.keys(this.props.fieldSpec?.values).map(v => [v, capitalize(v)]);
|
||||||
input = <InputEnum
|
input = <InputEnum
|
||||||
options={options}
|
options={options}
|
||||||
value={v}
|
value={v as string}
|
||||||
onChange={this.changeValue.bind(this, i)}
|
onChange={this.changeValue.bind(this, i)}
|
||||||
aria-label={this.props['aria-label'] || this.props.label}
|
aria-label={this.props['aria-label'] || this.props.label}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
input = <InputString
|
input = <InputString
|
||||||
value={v}
|
value={v as string}
|
||||||
onChange={this.changeValue.bind(this, i)}
|
onChange={this.changeValue.bind(this, i)}
|
||||||
aria-label={this.props['aria-label'] || this.props.label}
|
aria-label={this.props['aria-label'] || this.props.label}
|
||||||
/>
|
/>
|
||||||
@@ -120,11 +124,11 @@ export default class FieldDynamicArray extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeleteValueInputButton extends React.Component {
|
type DeleteValueInputButtonProps = {
|
||||||
static propTypes = {
|
onClick?(...args: unknown[]): unknown
|
||||||
onClick: PropTypes.func,
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
class DeleteValueInputButton extends React.Component<DeleteValueInputButtonProps> {
|
||||||
render() {
|
render() {
|
||||||
return <InputButton
|
return <InputButton
|
||||||
className="maputnik-delete-stop"
|
className="maputnik-delete-stop"
|
||||||
@@ -133,7 +137,7 @@ class DeleteValueInputButton extends React.Component {
|
|||||||
>
|
>
|
||||||
<FieldDocLabel
|
<FieldDocLabel
|
||||||
label={<MdDelete />}
|
label={<MdDelete />}
|
||||||
doc={"Remove array item."}
|
fieldSpec={{doc:" Remove array item."}}
|
||||||
/>
|
/>
|
||||||
</InputButton>
|
</InputButton>
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,7 @@ export type InputEnumProps = {
|
|||||||
value?: string
|
value?: string
|
||||||
style?: object
|
style?: object
|
||||||
default?: string
|
default?: string
|
||||||
name: string
|
name?: string
|
||||||
onChange(...args: unknown[]): unknown
|
onChange(...args: unknown[]): unknown
|
||||||
options: any[]
|
options: any[]
|
||||||
'aria-label'?: string
|
'aria-label'?: string
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import InputAutocomplete from './InputAutocomplete'
|
import InputAutocomplete from './InputAutocomplete'
|
||||||
|
|
||||||
type FieldFontProps = {
|
export type FieldFontProps = {
|
||||||
name: string
|
name: string
|
||||||
value?: string[]
|
value?: string[]
|
||||||
default?: string[]
|
default?: string[]
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react'
|
|||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
|
|
||||||
type InputMultiInputProps = {
|
type InputMultiInputProps = {
|
||||||
name: string
|
name?: string
|
||||||
value: string
|
value: string
|
||||||
options: any[]
|
options: any[]
|
||||||
onChange(...args: unknown[]): unknown
|
onChange(...args: unknown[]): unknown
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React, { BaseSyntheticEvent } from 'react'
|
|||||||
|
|
||||||
let IDX = 0;
|
let IDX = 0;
|
||||||
|
|
||||||
type InputNumberProps = {
|
export type InputNumberProps = {
|
||||||
value?: number
|
value?: number
|
||||||
default?: number
|
default?: number
|
||||||
min?: number
|
min?: number
|
||||||
|
|||||||
@@ -1,139 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
|
|
||||||
import InputColor from './InputColor'
|
|
||||||
import InputNumber from './InputNumber'
|
|
||||||
import InputCheckbox from './InputCheckbox'
|
|
||||||
import InputString from './InputString'
|
|
||||||
import InputSelect from './InputSelect'
|
|
||||||
import InputMultiInput from './InputMultiInput'
|
|
||||||
import InputArray from './InputArray'
|
|
||||||
import InputDynamicArray from './InputDynamicArray'
|
|
||||||
import InputFont from './InputFont'
|
|
||||||
import InputAutocomplete from './InputAutocomplete'
|
|
||||||
import InputEnum from './InputEnum'
|
|
||||||
import capitalize from 'lodash.capitalize'
|
|
||||||
|
|
||||||
const iconProperties = ['background-pattern', 'fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'icon-image']
|
|
||||||
|
|
||||||
function labelFromFieldName(fieldName) {
|
|
||||||
let label = fieldName.split('-').slice(1).join(' ')
|
|
||||||
if(label.length > 0) {
|
|
||||||
label = label.charAt(0).toUpperCase() + label.slice(1);
|
|
||||||
}
|
|
||||||
return label
|
|
||||||
}
|
|
||||||
|
|
||||||
function optionsLabelLength(options) {
|
|
||||||
let sum = 0;
|
|
||||||
options.forEach(([_, label]) => {
|
|
||||||
sum += label.length
|
|
||||||
})
|
|
||||||
return sum
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Display any field from the Maplibre GL style spec and
|
|
||||||
* choose the correct field component based on the @{fieldSpec}
|
|
||||||
* to display @{value}. */
|
|
||||||
export default class SpecField extends React.Component {
|
|
||||||
static propTypes = {
|
|
||||||
onChange: PropTypes.func.isRequired,
|
|
||||||
fieldName: PropTypes.string.isRequired,
|
|
||||||
fieldSpec: PropTypes.object.isRequired,
|
|
||||||
value: PropTypes.oneOfType([
|
|
||||||
PropTypes.string,
|
|
||||||
PropTypes.number,
|
|
||||||
PropTypes.array,
|
|
||||||
PropTypes.bool
|
|
||||||
]),
|
|
||||||
/** Override the style of the field */
|
|
||||||
style: PropTypes.object,
|
|
||||||
'aria-label': PropTypes.string,
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const commonProps = {
|
|
||||||
error: this.props.error,
|
|
||||||
fieldSpec: this.props.fieldSpec,
|
|
||||||
label: this.props.label,
|
|
||||||
action: this.props.action,
|
|
||||||
style: this.props.style,
|
|
||||||
value: this.props.value,
|
|
||||||
default: this.props.fieldSpec.default,
|
|
||||||
name: this.props.fieldName,
|
|
||||||
onChange: newValue => this.props.onChange(this.props.fieldName, newValue),
|
|
||||||
'aria-label': this.props['aria-label'],
|
|
||||||
}
|
|
||||||
|
|
||||||
function childNodes() {
|
|
||||||
switch(this.props.fieldSpec.type) {
|
|
||||||
case 'number': return (
|
|
||||||
<InputNumber
|
|
||||||
{...commonProps}
|
|
||||||
min={this.props.fieldSpec.minimum}
|
|
||||||
max={this.props.fieldSpec.maximum}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
case 'enum':
|
|
||||||
const options = Object.keys(this.props.fieldSpec.values).map(v => [v, capitalize(v)])
|
|
||||||
|
|
||||||
return <InputEnum
|
|
||||||
{...commonProps}
|
|
||||||
options={options}
|
|
||||||
/>
|
|
||||||
case 'resolvedImage':
|
|
||||||
case 'formatted':
|
|
||||||
case 'string':
|
|
||||||
if (iconProperties.indexOf(this.props.fieldName) >= 0) {
|
|
||||||
const options = this.props.fieldSpec.values || [];
|
|
||||||
return <InputAutocomplete
|
|
||||||
{...commonProps}
|
|
||||||
options={options.map(f => [f, f])}
|
|
||||||
/>
|
|
||||||
} else {
|
|
||||||
return <InputString
|
|
||||||
{...commonProps}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
case 'color': return (
|
|
||||||
<InputColor
|
|
||||||
{...commonProps}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
case 'boolean': return (
|
|
||||||
<InputCheckbox
|
|
||||||
{...commonProps}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
case 'array':
|
|
||||||
if(this.props.fieldName === 'text-font') {
|
|
||||||
return <InputFont
|
|
||||||
{...commonProps}
|
|
||||||
fonts={this.props.fieldSpec.values}
|
|
||||||
/>
|
|
||||||
} else {
|
|
||||||
if (this.props.fieldSpec.length) {
|
|
||||||
return <InputArray
|
|
||||||
{...commonProps}
|
|
||||||
type={this.props.fieldSpec.value}
|
|
||||||
length={this.props.fieldSpec.length}
|
|
||||||
/>
|
|
||||||
} else {
|
|
||||||
return <InputDynamicArray
|
|
||||||
{...commonProps}
|
|
||||||
fieldSpec={this.props.fieldSpec}
|
|
||||||
type={this.props.fieldSpec.value}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default: return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div data-wd-key={"spec-field:"+this.props.fieldName}>
|
|
||||||
{childNodes.call(this)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
import React, { ReactElement } from 'react'
|
||||||
|
|
||||||
|
import InputColor, { InputColorProps } from './InputColor'
|
||||||
|
import InputNumber, { InputNumberProps } from './InputNumber'
|
||||||
|
import InputCheckbox, { InputCheckboxProps } from './InputCheckbox'
|
||||||
|
import InputString, { InputStringProps } from './InputString'
|
||||||
|
import InputArray, { FieldArrayProps } from './InputArray'
|
||||||
|
import InputDynamicArray, { FieldDynamicArrayProps } from './InputDynamicArray'
|
||||||
|
import InputFont, { FieldFontProps } from './InputFont'
|
||||||
|
import InputAutocomplete, { InputAutocompleteProps } from './InputAutocomplete'
|
||||||
|
import InputEnum, { InputEnumProps } from './InputEnum'
|
||||||
|
import capitalize from 'lodash.capitalize'
|
||||||
|
|
||||||
|
const iconProperties = ['background-pattern', 'fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'icon-image']
|
||||||
|
|
||||||
|
export type SpecFieldProps = {
|
||||||
|
onChange(...args: unknown[]): unknown
|
||||||
|
fieldName: string
|
||||||
|
fieldSpec: {
|
||||||
|
default?: unknown
|
||||||
|
type: 'number' | 'enum' | 'resolvedImage' | 'formatted' | 'string' | 'color' | 'boolean' | 'array'
|
||||||
|
minimum?: number
|
||||||
|
maximum?: number
|
||||||
|
values?: unknown[]
|
||||||
|
length?: number
|
||||||
|
value?: string
|
||||||
|
}
|
||||||
|
value?: string | number | unknown[] | boolean
|
||||||
|
/** Override the style of the field */
|
||||||
|
style?: object
|
||||||
|
'aria-label'?: string
|
||||||
|
error: unknown[]
|
||||||
|
label: string
|
||||||
|
action: ReactElement
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Display any field from the Maplibre GL style spec and
|
||||||
|
* choose the correct field component based on the @{fieldSpec}
|
||||||
|
* to display @{value}. */
|
||||||
|
export default class SpecField extends React.Component<SpecFieldProps> {
|
||||||
|
|
||||||
|
childNodes() {
|
||||||
|
const commonProps = {
|
||||||
|
error: this.props.error,
|
||||||
|
fieldSpec: this.props.fieldSpec,
|
||||||
|
label: this.props.label,
|
||||||
|
action: this.props.action,
|
||||||
|
style: this.props.style,
|
||||||
|
value: this.props.value,
|
||||||
|
default: this.props.fieldSpec.default,
|
||||||
|
name: this.props.fieldName,
|
||||||
|
onChange: (newValue: string) => this.props.onChange(this.props.fieldName, newValue),
|
||||||
|
'aria-label': this.props['aria-label'],
|
||||||
|
}
|
||||||
|
switch(this.props.fieldSpec.type) {
|
||||||
|
case 'number': return (
|
||||||
|
<InputNumber
|
||||||
|
{...commonProps as InputNumberProps}
|
||||||
|
min={this.props.fieldSpec.minimum}
|
||||||
|
max={this.props.fieldSpec.maximum}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
case 'enum':
|
||||||
|
const options = Object.keys(this.props.fieldSpec.values || []).map(v => [v, capitalize(v)])
|
||||||
|
|
||||||
|
return <InputEnum
|
||||||
|
{...commonProps as Omit<InputEnumProps, "options">}
|
||||||
|
options={options}
|
||||||
|
/>
|
||||||
|
case 'resolvedImage':
|
||||||
|
case 'formatted':
|
||||||
|
case 'string':
|
||||||
|
if (iconProperties.indexOf(this.props.fieldName) >= 0) {
|
||||||
|
const options = this.props.fieldSpec.values || [];
|
||||||
|
return <InputAutocomplete
|
||||||
|
{...commonProps as Omit<InputAutocompleteProps, "options">}
|
||||||
|
options={options.map(f => [f, f])}
|
||||||
|
/>
|
||||||
|
} else {
|
||||||
|
return <InputString
|
||||||
|
{...commonProps as InputStringProps}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
case 'color': return (
|
||||||
|
<InputColor
|
||||||
|
{...commonProps as InputColorProps}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
case 'boolean': return (
|
||||||
|
<InputCheckbox
|
||||||
|
{...commonProps as InputCheckboxProps}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
case 'array':
|
||||||
|
if(this.props.fieldName === 'text-font') {
|
||||||
|
return <InputFont
|
||||||
|
{...commonProps as FieldFontProps}
|
||||||
|
fonts={this.props.fieldSpec.values}
|
||||||
|
/>
|
||||||
|
} else {
|
||||||
|
if (this.props.fieldSpec.length) {
|
||||||
|
return <InputArray
|
||||||
|
{...commonProps as FieldArrayProps}
|
||||||
|
type={this.props.fieldSpec.value}
|
||||||
|
length={this.props.fieldSpec.length}
|
||||||
|
/>
|
||||||
|
} else {
|
||||||
|
return <InputDynamicArray
|
||||||
|
{...commonProps as FieldDynamicArrayProps}
|
||||||
|
fieldSpec={this.props.fieldSpec}
|
||||||
|
type={this.props.fieldSpec.value as FieldDynamicArrayProps['type']}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default: return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div data-wd-key={"spec-field:"+this.props.fieldName}>
|
||||||
|
{this.childNodes()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ export type InputStringProps = {
|
|||||||
style?: object
|
style?: object
|
||||||
default?: string
|
default?: string
|
||||||
onChange?(...args: unknown[]): unknown
|
onChange?(...args: unknown[]): unknown
|
||||||
onInput(...args: unknown[]): unknown
|
onInput?(...args: unknown[]): unknown
|
||||||
multi?: boolean
|
multi?: boolean
|
||||||
required?: boolean
|
required?: boolean
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
@@ -77,7 +77,7 @@ export default class InputString extends React.Component<InputStringProps, Input
|
|||||||
editing: true,
|
editing: true,
|
||||||
value: e.target.value
|
value: e.target.value
|
||||||
}, () => {
|
}, () => {
|
||||||
this.props.onInput(this.state.value);
|
if (this.props.onInput) this.props.onInput(this.state.value);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onBlur: () => {
|
onBlur: () => {
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import Block from './Block'
|
import Block from './Block'
|
||||||
import InputSpec from './InputSpec'
|
import InputSpec, { SpecFieldProps as InputFieldSpecProps } from './InputSpec'
|
||||||
import Fieldset from './Fieldset'
|
import Fieldset from './Fieldset'
|
||||||
|
|
||||||
|
|
||||||
const typeMap = {
|
const typeMap = {
|
||||||
color: () => Block,
|
color: () => Block,
|
||||||
enum: ({fieldSpec}) => (Object.keys(fieldSpec.values).length <= 3 ? Fieldset : Block),
|
enum: ({fieldSpec}: any) => (Object.keys(fieldSpec.values).length <= 3 ? Fieldset : Block),
|
||||||
boolean: () => Block,
|
boolean: () => Block,
|
||||||
array: () => Fieldset,
|
array: () => Fieldset,
|
||||||
resolvedImage: () => Block,
|
resolvedImage: () => Block,
|
||||||
@@ -16,12 +15,11 @@ const typeMap = {
|
|||||||
formatted: () => Block,
|
formatted: () => Block,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class SpecField extends React.Component {
|
type SpecFieldProps = InputFieldSpecProps & {
|
||||||
static propTypes = {
|
name?: string
|
||||||
...InputSpec.propTypes,
|
};
|
||||||
name: PropTypes.string,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
export default class SpecField extends React.Component<SpecFieldProps> {
|
||||||
render() {
|
render() {
|
||||||
const {props} = this;
|
const {props} = this;
|
||||||
|
|
||||||
Reference in New Issue
Block a user