mirror of
https://github.com/maputnik/editor.git
synced 2026-07-02 03:57:25 +00:00
Improve typings of exising components and migrated a few more
This commit is contained in:
@@ -3,17 +3,17 @@ import InputString from './InputString'
|
|||||||
import InputNumber from './InputNumber'
|
import InputNumber from './InputNumber'
|
||||||
|
|
||||||
export type FieldArrayProps = {
|
export type FieldArrayProps = {
|
||||||
value: string[] | number[]
|
value: (string | number | undefined)[]
|
||||||
type?: string
|
type?: string
|
||||||
length?: number
|
length?: number
|
||||||
default?: string[] | number[]
|
default?: (string | number | undefined)[]
|
||||||
onChange?(...args: unknown[]): unknown
|
onChange?(value: (string | number | undefined)[] | undefined): unknown
|
||||||
'aria-label'?: string
|
'aria-label'?: string
|
||||||
label?: string
|
label?: string
|
||||||
};
|
};
|
||||||
|
|
||||||
type FieldArrayState = {
|
type FieldArrayState = {
|
||||||
value: string[] | number[]
|
value: (string | number | undefined)[]
|
||||||
initialPropsValue: unknown[]
|
initialPropsValue: unknown[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ export default class FieldArray extends React.Component<FieldArrayProps, FieldAr
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
changeValue(idx: number, newValue: string) {
|
changeValue(idx: number, newValue: string | number | undefined) {
|
||||||
const value = this.state.value.slice(0);
|
const value = this.state.value.slice(0);
|
||||||
value[idx] = newValue;
|
value[idx] = newValue;
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ export default class FieldArray extends React.Component<FieldArrayProps, FieldAr
|
|||||||
default={containsValues || !this.props.default ? undefined : this.props.default[i] as number}
|
default={containsValues || !this.props.default ? undefined : this.props.default[i] as number}
|
||||||
value={value[i] as number}
|
value={value[i] as number}
|
||||||
required={containsValues ? true : false}
|
required={containsValues ? true : false}
|
||||||
onChange={this.changeValue.bind(this, i)}
|
onChange={(v) => this.changeValue(i, v)}
|
||||||
aria-label={this.props['aria-label'] || this.props.label}
|
aria-label={this.props['aria-label'] || this.props.label}
|
||||||
/>
|
/>
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ import InputUrl from './InputUrl'
|
|||||||
|
|
||||||
|
|
||||||
export type FieldDynamicArrayProps = {
|
export type FieldDynamicArrayProps = {
|
||||||
value?: (string | number)[]
|
value?: (string | number | undefined)[]
|
||||||
type?: 'url' | 'number' | 'enum' | 'string'
|
type?: 'url' | 'number' | 'enum' | 'string'
|
||||||
default?: (string | number)[]
|
default?: (string | number | undefined)[]
|
||||||
onChange?(...args: unknown[]): unknown
|
onChange?(values: (string | number | undefined)[] | undefined): unknown
|
||||||
style?: object
|
style?: object
|
||||||
fieldSpec?: {
|
fieldSpec?: {
|
||||||
values?: any
|
values?: any
|
||||||
@@ -25,7 +25,7 @@ export type FieldDynamicArrayProps = {
|
|||||||
|
|
||||||
|
|
||||||
export default class FieldDynamicArray extends React.Component<FieldDynamicArrayProps> {
|
export default class FieldDynamicArray extends React.Component<FieldDynamicArrayProps> {
|
||||||
changeValue(idx: number, newValue: string | number) {
|
changeValue(idx: number, newValue: string | number | undefined) {
|
||||||
const values = this.values.slice(0)
|
const values = this.values.slice(0)
|
||||||
values[idx] = newValue
|
values[idx] = newValue
|
||||||
if (this.props.onChange) this.props.onChange(values)
|
if (this.props.onChange) this.props.onChange(values)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export type InputNumberProps = {
|
|||||||
default?: number
|
default?: number
|
||||||
min?: number
|
min?: number
|
||||||
max?: number
|
max?: number
|
||||||
onChange?(...args: unknown[]): unknown
|
onChange?(value: number | undefined): unknown
|
||||||
allowRange?: boolean
|
allowRange?: boolean
|
||||||
rangeStep?: number
|
rangeStep?: number
|
||||||
wdKey?: string
|
wdKey?: string
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export type InputSelectProps = {
|
|||||||
"data-wd-key"?: string
|
"data-wd-key"?: string
|
||||||
options: [string, any][] | string[]
|
options: [string, any][] | string[]
|
||||||
style?: object
|
style?: object
|
||||||
onChange(...args: unknown[]): unknown
|
onChange(value: string): unknown
|
||||||
title?: string
|
title?: string
|
||||||
'aria-label'?: string
|
'aria-label'?: string
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ import capitalize from 'lodash.capitalize'
|
|||||||
const iconProperties = ['background-pattern', 'fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'icon-image']
|
const iconProperties = ['background-pattern', 'fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'icon-image']
|
||||||
|
|
||||||
export type SpecFieldProps = {
|
export type SpecFieldProps = {
|
||||||
onChange?(...args: unknown[]): unknown
|
onChange?(fieldName: string | undefined, value: number | undefined | (string | number | undefined)[]): unknown
|
||||||
fieldName?: string
|
fieldName?: string
|
||||||
fieldSpec: {
|
fieldSpec?: {
|
||||||
default?: unknown
|
default?: unknown
|
||||||
type: 'number' | 'enum' | 'resolvedImage' | 'formatted' | 'string' | 'color' | 'boolean' | 'array'
|
type?: 'number' | 'enum' | 'resolvedImage' | 'formatted' | 'string' | 'color' | 'boolean' | 'array'
|
||||||
minimum?: number
|
minimum?: number
|
||||||
maximum?: number
|
maximum?: number
|
||||||
values?: unknown[]
|
values?: unknown[]
|
||||||
@@ -29,9 +29,9 @@ export type SpecFieldProps = {
|
|||||||
/** Override the style of the field */
|
/** Override the style of the field */
|
||||||
style?: object
|
style?: object
|
||||||
'aria-label'?: string
|
'aria-label'?: string
|
||||||
error: unknown[]
|
error?: unknown[]
|
||||||
label: string
|
label?: string
|
||||||
action: ReactElement
|
action?: ReactElement
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Display any field from the Maplibre GL style spec and
|
/** Display any field from the Maplibre GL style spec and
|
||||||
@@ -47,12 +47,12 @@ export default class SpecField extends React.Component<SpecFieldProps> {
|
|||||||
action: this.props.action,
|
action: this.props.action,
|
||||||
style: this.props.style,
|
style: this.props.style,
|
||||||
value: this.props.value,
|
value: this.props.value,
|
||||||
default: this.props.fieldSpec.default,
|
default: this.props.fieldSpec?.default,
|
||||||
name: this.props.fieldName,
|
name: this.props.fieldName,
|
||||||
onChange: (newValue: string) => this.props.onChange!(this.props.fieldName, newValue),
|
onChange: (newValue: number | undefined | (string | number | undefined)[]) => this.props.onChange!(this.props.fieldName, newValue),
|
||||||
'aria-label': this.props['aria-label'],
|
'aria-label': this.props['aria-label'],
|
||||||
}
|
}
|
||||||
switch(this.props.fieldSpec.type) {
|
switch(this.props.fieldSpec?.type) {
|
||||||
case 'number': return (
|
case 'number': return (
|
||||||
<InputNumber
|
<InputNumber
|
||||||
{...commonProps as InputNumberProps}
|
{...commonProps as InputNumberProps}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ export type InputStringProps = {
|
|||||||
value?: string
|
value?: string
|
||||||
style?: object
|
style?: object
|
||||||
default?: string
|
default?: string
|
||||||
onChange?(...args: unknown[]): unknown
|
onChange?(value: string | undefined): unknown
|
||||||
onInput?(...args: unknown[]): unknown
|
onInput?(value: string | undefined): unknown
|
||||||
multi?: boolean
|
multi?: boolean
|
||||||
required?: boolean
|
required?: boolean
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ class AddSource extends React.Component<AddSourceProps, AddSourceState> {
|
|||||||
['image', 'Image'],
|
['image', 'Image'],
|
||||||
['video', 'Video'],
|
['video', 'Video'],
|
||||||
]}
|
]}
|
||||||
onChange={(mode: EditorMode) => this.setState({mode: mode, source: this.defaultSource(mode)})}
|
onChange={mode => this.setState({mode: mode as EditorMode, source: this.defaultSource(mode as EditorMode)})}
|
||||||
value={this.state.mode as string}
|
value={this.state.mode as string}
|
||||||
/>
|
/>
|
||||||
<ModalSourcesTypeEditor
|
<ModalSourcesTypeEditor
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ type SpecFieldProps = InputFieldSpecProps & {
|
|||||||
|
|
||||||
export default class SpecField extends React.Component<SpecFieldProps> {
|
export default class SpecField extends React.Component<SpecFieldProps> {
|
||||||
render() {
|
render() {
|
||||||
const fieldType = this.props.fieldSpec.type;
|
const fieldType = this.props.fieldSpec?.type;
|
||||||
|
|
||||||
const typeBlockFn = typeMap[fieldType];
|
const typeBlockFn = typeMap[fieldType!];
|
||||||
|
|
||||||
let TypeBlock;
|
let TypeBlock;
|
||||||
if (typeBlockFn) {
|
if (typeBlockFn) {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import {mdiFunctionVariant, mdiTableRowPlusAfter} from '@mdi/js';
|
import {mdiFunctionVariant, mdiTableRowPlusAfter} from '@mdi/js';
|
||||||
import {latest} from '@maplibre/maplibre-gl-style-spec'
|
import {latest} from '@maplibre/maplibre-gl-style-spec'
|
||||||
|
|
||||||
@@ -8,7 +7,6 @@ import InputSpec from './InputSpec'
|
|||||||
import InputNumber from './InputNumber'
|
import InputNumber from './InputNumber'
|
||||||
import InputString from './InputString'
|
import InputString from './InputString'
|
||||||
import InputSelect from './InputSelect'
|
import InputSelect from './InputSelect'
|
||||||
import FieldDocLabel from './FieldDocLabel'
|
|
||||||
import Block from './Block'
|
import Block from './Block'
|
||||||
import docUid from '../libs/document-uid'
|
import docUid from '../libs/document-uid'
|
||||||
import sortNumerically from '../libs/sort-numerically'
|
import sortNumerically from '../libs/sort-numerically'
|
||||||
@@ -19,12 +17,12 @@ import DeleteStopButton from './_DeleteStopButton'
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
function setStopRefs(props, state) {
|
function setStopRefs(props: DataPropertyProps, state: DataPropertyState) {
|
||||||
// This is initialsed below only if required to improved performance.
|
// This is initialsed below only if required to improved performance.
|
||||||
let newRefs;
|
let newRefs: {[key: number]: string} | undefined;
|
||||||
|
|
||||||
if(props.value && props.value.stops) {
|
if(props.value && props.value.stops) {
|
||||||
props.value.stops.forEach((val, idx) => {
|
props.value.stops.forEach((_val, idx) => {
|
||||||
if(!state.refs.hasOwnProperty(idx)) {
|
if(!state.refs.hasOwnProperty(idx)) {
|
||||||
if(!newRefs) {
|
if(!newRefs) {
|
||||||
newRefs = {...state};
|
newRefs = {...state};
|
||||||
@@ -37,27 +35,39 @@ function setStopRefs(props, state) {
|
|||||||
return newRefs;
|
return newRefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class DataProperty extends React.Component {
|
type DataPropertyProps = {
|
||||||
static propTypes = {
|
onChange?(fieldName: string, value: any): unknown
|
||||||
onChange: PropTypes.func,
|
onDeleteStop?(...args: unknown[]): unknown
|
||||||
onDeleteStop: PropTypes.func,
|
onAddStop?(...args: unknown[]): unknown
|
||||||
onAddStop: PropTypes.func,
|
onExpressionClick?(...args: unknown[]): unknown
|
||||||
onExpressionClick: PropTypes.func,
|
onChangeToZoomFunction?(...args: unknown[]): unknown
|
||||||
fieldName: PropTypes.string,
|
fieldName: string
|
||||||
fieldType: PropTypes.string,
|
fieldType?: string
|
||||||
fieldSpec: PropTypes.object,
|
fieldSpec?: object
|
||||||
value: PropTypes.oneOfType([
|
value?: DataPropertyValue
|
||||||
PropTypes.object,
|
errors?: object
|
||||||
PropTypes.string,
|
};
|
||||||
PropTypes.number,
|
|
||||||
PropTypes.bool,
|
|
||||||
PropTypes.array
|
|
||||||
]),
|
|
||||||
errors: PropTypes.object,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
type DataPropertyState = {
|
||||||
|
refs: {[key: number]: string}
|
||||||
|
};
|
||||||
|
|
||||||
|
type DataPropertyValue = {
|
||||||
|
default?: any
|
||||||
|
property?: string
|
||||||
|
base?: number
|
||||||
|
type?: string
|
||||||
|
stops: Stops
|
||||||
|
}
|
||||||
|
|
||||||
|
type Stops = [{
|
||||||
|
zoom: number
|
||||||
|
value: number
|
||||||
|
}, number][]
|
||||||
|
|
||||||
|
export default class DataProperty extends React.Component<DataPropertyProps, DataPropertyState> {
|
||||||
state = {
|
state = {
|
||||||
refs: {}
|
refs: {} as {[key: number]: string}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -70,7 +80,7 @@ export default class DataProperty extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static getDerivedStateFromProps(props, state) {
|
static getDerivedStateFromProps(props: DataPropertyProps, state: DataPropertyState) {
|
||||||
const newRefs = setStopRefs(props, state);
|
const newRefs = setStopRefs(props, state);
|
||||||
if(newRefs) {
|
if(newRefs) {
|
||||||
return {
|
return {
|
||||||
@@ -80,7 +90,7 @@ export default class DataProperty extends React.Component {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getFieldFunctionType(fieldSpec) {
|
getFieldFunctionType(fieldSpec: any) {
|
||||||
if (fieldSpec.expression.interpolated) {
|
if (fieldSpec.expression.interpolated) {
|
||||||
return "exponential"
|
return "exponential"
|
||||||
}
|
}
|
||||||
@@ -90,7 +100,7 @@ export default class DataProperty extends React.Component {
|
|||||||
return "categorical"
|
return "categorical"
|
||||||
}
|
}
|
||||||
|
|
||||||
getDataFunctionTypes(fieldSpec) {
|
getDataFunctionTypes(fieldSpec: any) {
|
||||||
if (fieldSpec.expression.interpolated) {
|
if (fieldSpec.expression.interpolated) {
|
||||||
return ["interpolate", "categorical", "interval", "exponential", "identity"]
|
return ["interpolate", "categorical", "interval", "exponential", "identity"]
|
||||||
}
|
}
|
||||||
@@ -100,7 +110,7 @@ export default class DataProperty extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Order the stops altering the refs to reflect their new position.
|
// Order the stops altering the refs to reflect their new position.
|
||||||
orderStopsByZoom(stops) {
|
orderStopsByZoom(stops: Stops) {
|
||||||
const mappedWithRef = stops
|
const mappedWithRef = stops
|
||||||
.map((stop, idx) => {
|
.map((stop, idx) => {
|
||||||
return {
|
return {
|
||||||
@@ -112,7 +122,7 @@ export default class DataProperty extends React.Component {
|
|||||||
.sort((a, b) => sortNumerically(a.data[0].zoom, b.data[0].zoom));
|
.sort((a, b) => sortNumerically(a.data[0].zoom, b.data[0].zoom));
|
||||||
|
|
||||||
// Fetch the new position of the stops
|
// Fetch the new position of the stops
|
||||||
const newRefs = {};
|
const newRefs = {} as {[key: number]: string};
|
||||||
mappedWithRef
|
mappedWithRef
|
||||||
.forEach((stop, idx) =>{
|
.forEach((stop, idx) =>{
|
||||||
newRefs[idx] = stop.ref;
|
newRefs[idx] = stop.ref;
|
||||||
@@ -125,7 +135,7 @@ export default class DataProperty extends React.Component {
|
|||||||
return mappedWithRef.map((item) => item.data);
|
return mappedWithRef.map((item) => item.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange = (fieldName, value) => {
|
onChange = (fieldName: string, value: any) => {
|
||||||
if (value.type === "identity") {
|
if (value.type === "identity") {
|
||||||
value = {
|
value = {
|
||||||
type: value.type,
|
type: value.type,
|
||||||
@@ -139,21 +149,21 @@ export default class DataProperty extends React.Component {
|
|||||||
type: value.type,
|
type: value.type,
|
||||||
// Default props if they don't already exist.
|
// Default props if they don't already exist.
|
||||||
stops: [
|
stops: [
|
||||||
[{zoom: 6, value: stopValue}, findDefaultFromSpec(this.props.fieldSpec)],
|
[{zoom: 6, value: stopValue}, findDefaultFromSpec(this.props.fieldSpec as any)],
|
||||||
[{zoom: 10, value: stopValue}, findDefaultFromSpec(this.props.fieldSpec)]
|
[{zoom: 10, value: stopValue}, findDefaultFromSpec(this.props.fieldSpec as any)]
|
||||||
],
|
],
|
||||||
...value,
|
...value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.props.onChange(fieldName, value);
|
this.props.onChange!(fieldName, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeStop(changeIdx, stopData, value) {
|
changeStop(changeIdx: number, stopData: { zoom: number | undefined, value: number }, value: number) {
|
||||||
const stops = this.props.value.stops.slice(0)
|
const stops = this.props.value?.stops.slice(0) || []
|
||||||
// const changedStop = stopData.zoom === undefined ? stopData.value : stopData
|
// const changedStop = stopData.zoom === undefined ? stopData.value : stopData
|
||||||
stops[changeIdx] = [
|
stops[changeIdx] = [
|
||||||
{
|
{
|
||||||
...stopData,
|
value: stopData.value,
|
||||||
zoom: (stopData.zoom === undefined) ? 0 : stopData.zoom,
|
zoom: (stopData.zoom === undefined) ? 0 : stopData.zoom,
|
||||||
},
|
},
|
||||||
value
|
value
|
||||||
@@ -168,7 +178,7 @@ export default class DataProperty extends React.Component {
|
|||||||
this.onChange(this.props.fieldName, changedValue)
|
this.onChange(this.props.fieldName, changedValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
changeBase(newValue) {
|
changeBase(newValue: number | undefined) {
|
||||||
const changedValue = {
|
const changedValue = {
|
||||||
...this.props.value,
|
...this.props.value,
|
||||||
base: newValue
|
base: newValue
|
||||||
@@ -177,11 +187,11 @@ export default class DataProperty extends React.Component {
|
|||||||
if (changedValue.base === undefined) {
|
if (changedValue.base === undefined) {
|
||||||
delete changedValue["base"];
|
delete changedValue["base"];
|
||||||
}
|
}
|
||||||
this.props.onChange(this.props.fieldName, changedValue)
|
this.props.onChange!(this.props.fieldName, changedValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
changeDataType(propVal) {
|
changeDataType(propVal: string) {
|
||||||
if (propVal === "interpolate") {
|
if (propVal === "interpolate" && this.props.onChangeToZoomFunction) {
|
||||||
this.props.onChangeToZoomFunction();
|
this.props.onChangeToZoomFunction();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -192,41 +202,39 @@ export default class DataProperty extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
changeDataProperty(propName, propVal) {
|
changeDataProperty(propName: "property" | "default", propVal: any) {
|
||||||
if (propVal) {
|
if (propVal) {
|
||||||
this.props.value[propName] = propVal
|
this.props.value![propName] = propVal
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
delete this.props.value[propName]
|
delete this.props.value![propName]
|
||||||
}
|
}
|
||||||
this.onChange(this.props.fieldName, this.props.value)
|
this.onChange(this.props.fieldName, this.props.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {fieldName, fieldType, errors} = this.props;
|
if (typeof this.props.value?.type === "undefined") {
|
||||||
|
this.props.value!.type = this.getFieldFunctionType(this.props.fieldSpec)
|
||||||
if (typeof this.props.value.type === "undefined") {
|
|
||||||
this.props.value.type = this.getFieldFunctionType(this.props.fieldSpec)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let dataFields;
|
let dataFields;
|
||||||
if (this.props.value.stops) {
|
if (this.props.value?.stops) {
|
||||||
dataFields = this.props.value.stops.map((stop, idx) => {
|
dataFields = this.props.value.stops.map((stop, idx) => {
|
||||||
const zoomLevel = typeof stop[0] === 'object' ? stop[0].zoom : undefined;
|
const zoomLevel = typeof stop[0] === 'object' ? stop[0].zoom : undefined;
|
||||||
const key = this.state.refs[idx];
|
const key = this.state.refs[idx];
|
||||||
const dataLevel = typeof stop[0] === 'object' ? stop[0].value : stop[0];
|
const dataLevel = typeof stop[0] === 'object' ? stop[0].value : stop[0];
|
||||||
const value = stop[1]
|
const value = stop[1]
|
||||||
const deleteStopBtn = <DeleteStopButton onClick={this.props.onDeleteStop.bind(this, idx)} />
|
const deleteStopBtn = <DeleteStopButton onClick={this.props.onDeleteStop?.bind(this, idx)} />
|
||||||
|
|
||||||
const dataProps = {
|
const dataProps = {
|
||||||
'aria-label': "Input value",
|
'aria-label': "Input value",
|
||||||
label: "Data value",
|
label: "Data value",
|
||||||
value: dataLevel,
|
value: dataLevel as any,
|
||||||
onChange: newData => this.changeStop(idx, { zoom: zoomLevel, value: newData }, value)
|
onChange: (newData: string | number | undefined) => this.changeStop(idx, { zoom: zoomLevel, value: newData as number }, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
let dataInput;
|
let dataInput;
|
||||||
if(this.props.value.type === "categorical") {
|
if(this.props.value?.type === "categorical") {
|
||||||
dataInput = <InputString {...dataProps} />
|
dataInput = <InputString {...dataProps} />
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -246,16 +254,6 @@ export default class DataProperty extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
const errorKeyStart = `${fieldType}.${fieldName}.stops[${idx}]`;
|
|
||||||
const foundErrors = Object.entries(errors).filter(([key, error]) => {
|
|
||||||
return key.startsWith(errorKeyStart);
|
|
||||||
});
|
|
||||||
|
|
||||||
const message = foundErrors.map(([key, error]) => {
|
|
||||||
return error.message;
|
|
||||||
}).join("");
|
|
||||||
const error = message ? {message} : undefined;
|
|
||||||
|
|
||||||
return <tr key={key}>
|
return <tr key={key}>
|
||||||
<td>
|
<td>
|
||||||
{zoomInput}
|
{zoomInput}
|
||||||
@@ -269,7 +267,7 @@ export default class DataProperty extends React.Component {
|
|||||||
fieldName={this.props.fieldName}
|
fieldName={this.props.fieldName}
|
||||||
fieldSpec={this.props.fieldSpec}
|
fieldSpec={this.props.fieldSpec}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={(_, newValue) => this.changeStop(idx, {zoom: zoomLevel, value: dataLevel}, newValue)}
|
onChange={(_, newValue) => this.changeStop(idx, {zoom: zoomLevel, value: dataLevel}, newValue as number)}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -289,14 +287,14 @@ export default class DataProperty extends React.Component {
|
|||||||
>
|
>
|
||||||
<div className="maputnik-data-spec-property-input">
|
<div className="maputnik-data-spec-property-input">
|
||||||
<InputSelect
|
<InputSelect
|
||||||
value={this.props.value.type}
|
value={this.props.value!.type}
|
||||||
onChange={propVal => this.changeDataType(propVal)}
|
onChange={propVal => this.changeDataType(propVal)}
|
||||||
title={"Select a type of data scale (default is 'categorical')."}
|
title={"Select a type of data scale (default is 'categorical')."}
|
||||||
options={this.getDataFunctionTypes(this.props.fieldSpec)}
|
options={this.getDataFunctionTypes(this.props.fieldSpec)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Block>
|
</Block>
|
||||||
{this.props.value.type !== "identity" &&
|
{this.props.value?.type !== "identity" &&
|
||||||
<Block
|
<Block
|
||||||
label={"Base"}
|
label={"Base"}
|
||||||
key="base"
|
key="base"
|
||||||
@@ -305,8 +303,8 @@ export default class DataProperty extends React.Component {
|
|||||||
<InputSpec
|
<InputSpec
|
||||||
fieldName={"base"}
|
fieldName={"base"}
|
||||||
fieldSpec={latest.function.base}
|
fieldSpec={latest.function.base}
|
||||||
value={this.props.value.base}
|
value={this.props.value?.base}
|
||||||
onChange={(_, newValue) => this.changeBase(newValue)}
|
onChange={(_, newValue) => this.changeBase(newValue as number)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Block>
|
</Block>
|
||||||
@@ -317,8 +315,7 @@ export default class DataProperty extends React.Component {
|
|||||||
>
|
>
|
||||||
<div className="maputnik-data-spec-property-input">
|
<div className="maputnik-data-spec-property-input">
|
||||||
<InputString
|
<InputString
|
||||||
value={this.props.value.property}
|
value={this.props.value?.property}
|
||||||
title={"Input a data property to base styles off of."}
|
|
||||||
onChange={propVal => this.changeDataProperty("property", propVal)}
|
onChange={propVal => this.changeDataProperty("property", propVal)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -331,7 +328,7 @@ export default class DataProperty extends React.Component {
|
|||||||
<InputSpec
|
<InputSpec
|
||||||
fieldName={this.props.fieldName}
|
fieldName={this.props.fieldName}
|
||||||
fieldSpec={this.props.fieldSpec}
|
fieldSpec={this.props.fieldSpec}
|
||||||
value={this.props.value.default}
|
value={this.props.value?.default}
|
||||||
onChange={(_, propVal) => this.changeDataProperty("default", propVal)}
|
onChange={(_, propVal) => this.changeDataProperty("default", propVal)}
|
||||||
/>
|
/>
|
||||||
</Block>
|
</Block>
|
||||||
@@ -344,7 +341,7 @@ export default class DataProperty extends React.Component {
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Zoom</th>
|
<th>Zoom</th>
|
||||||
<th>Input value</th>
|
<th>Input value</th>
|
||||||
<th rowSpan="2">Output value</th>
|
<th rowSpan={2}>Output value</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -357,7 +354,7 @@ export default class DataProperty extends React.Component {
|
|||||||
{dataFields &&
|
{dataFields &&
|
||||||
<InputButton
|
<InputButton
|
||||||
className="maputnik-add-stop"
|
className="maputnik-add-stop"
|
||||||
onClick={this.props.onAddStop.bind(this)}
|
onClick={this.props.onAddStop?.bind(this)}
|
||||||
>
|
>
|
||||||
<svg style={{width:"14px", height:"14px", verticalAlign: "text-bottom"}} viewBox="0 0 24 24">
|
<svg style={{width:"14px", height:"14px", verticalAlign: "text-bottom"}} viewBox="0 0 24 24">
|
||||||
<path fill="currentColor" d={mdiTableRowPlusAfter} />
|
<path fill="currentColor" d={mdiTableRowPlusAfter} />
|
||||||
@@ -366,7 +363,7 @@ export default class DataProperty extends React.Component {
|
|||||||
}
|
}
|
||||||
<InputButton
|
<InputButton
|
||||||
className="maputnik-add-stop"
|
className="maputnik-add-stop"
|
||||||
onClick={this.props.onExpressionClick.bind(this)}
|
onClick={this.props.onExpressionClick?.bind(this)}
|
||||||
>
|
>
|
||||||
<svg style={{width:"14px", height:"14px", verticalAlign: "text-bottom"}} viewBox="0 0 24 24">
|
<svg style={{width:"14px", height:"14px", verticalAlign: "text-bottom"}} viewBox="0 0 24 24">
|
||||||
<path fill="currentColor" d={mdiFunctionVariant} />
|
<path fill="currentColor" d={mdiFunctionVariant} />
|
||||||
@@ -1,45 +1,46 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import {MdDelete, MdUndo} from 'react-icons/md'
|
||||||
|
import stringifyPretty from 'json-stringify-pretty-compact'
|
||||||
|
|
||||||
import Block from './Block'
|
import Block from './Block'
|
||||||
import InputButton from './InputButton'
|
import InputButton from './InputButton'
|
||||||
import {MdDelete, MdUndo} from 'react-icons/md'
|
|
||||||
import FieldString from './FieldString'
|
|
||||||
|
|
||||||
import labelFromFieldName from './_labelFromFieldName'
|
import labelFromFieldName from './_labelFromFieldName'
|
||||||
import stringifyPretty from 'json-stringify-pretty-compact'
|
|
||||||
import FieldJson from './FieldJson'
|
import FieldJson from './FieldJson'
|
||||||
|
|
||||||
|
|
||||||
export default class ExpressionProperty extends React.Component {
|
type ExpressionPropertyProps = {
|
||||||
static propTypes = {
|
onDelete?(...args: unknown[]): unknown
|
||||||
onDelete: PropTypes.func,
|
fieldName: string
|
||||||
fieldName: PropTypes.string,
|
fieldType?: string
|
||||||
fieldType: PropTypes.string,
|
fieldSpec?: object
|
||||||
fieldSpec: PropTypes.object,
|
value?: any
|
||||||
value: PropTypes.any,
|
errors?: {[key: string]: any}
|
||||||
errors: PropTypes.object,
|
onChange?(...args: unknown[]): unknown
|
||||||
onChange: PropTypes.func,
|
onUndo?(...args: unknown[]): unknown
|
||||||
onUndo: PropTypes.func,
|
canUndo?(...args: unknown[]): unknown
|
||||||
canUndo: PropTypes.func,
|
onFocus?(...args: unknown[]): unknown
|
||||||
onFocus: PropTypes.func,
|
onBlur?(...args: unknown[]): unknown
|
||||||
onBlur: PropTypes.func,
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
type ExpressionPropertyState = {
|
||||||
|
jsonError: boolean
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class ExpressionProperty extends React.Component<ExpressionPropertyProps, ExpressionPropertyState> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
errors: {},
|
errors: {},
|
||||||
onFocus: () => {},
|
onFocus: () => {},
|
||||||
onBlur: () => {},
|
onBlur: () => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor (props) {
|
constructor (props:ExpressionPropertyProps) {
|
||||||
super();
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
jsonError: false,
|
jsonError: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
onJSONInvalid = (err) => {
|
onJSONInvalid = (_err: Error) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
jsonError: true,
|
jsonError: true,
|
||||||
})
|
})
|
||||||
@@ -82,11 +83,11 @@ export default class ExpressionProperty extends React.Component {
|
|||||||
|
|
||||||
const fieldKey = fieldType === undefined ? fieldName : `${fieldType}.${fieldName}`;
|
const fieldKey = fieldType === undefined ? fieldName : `${fieldType}.${fieldName}`;
|
||||||
|
|
||||||
const fieldError = errors[fieldKey];
|
const fieldError = errors![fieldKey];
|
||||||
const errorKeyStart = `${fieldKey}[`;
|
const errorKeyStart = `${fieldKey}[`;
|
||||||
const foundErrors = [];
|
const foundErrors = [];
|
||||||
|
|
||||||
function getValue (data) {
|
function getValue(data: any) {
|
||||||
return stringifyPretty(data, {indent: 2, maxLength: 38})
|
return stringifyPretty(data, {indent: 2, maxLength: 38})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,11 +95,11 @@ export default class ExpressionProperty extends React.Component {
|
|||||||
foundErrors.push({message: "Invalid JSON"});
|
foundErrors.push({message: "Invalid JSON"});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Object.entries(errors)
|
Object.entries(errors!)
|
||||||
.filter(([key, error]) => {
|
.filter(([key, _error]) => {
|
||||||
return key.startsWith(errorKeyStart);
|
return key.startsWith(errorKeyStart);
|
||||||
})
|
})
|
||||||
.forEach(([key, error]) => {
|
.forEach(([_key, error]) => {
|
||||||
return foundErrors.push(error);
|
return foundErrors.push(error);
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import {mdiFunctionVariant, mdiTableRowPlusAfter} from '@mdi/js';
|
import {mdiFunctionVariant, mdiTableRowPlusAfter} from '@mdi/js';
|
||||||
import {latest} from '@maplibre/maplibre-gl-style-spec'
|
import {latest} from '@maplibre/maplibre-gl-style-spec'
|
||||||
|
|
||||||
@@ -7,7 +6,6 @@ import InputButton from './InputButton'
|
|||||||
import InputSpec from './InputSpec'
|
import InputSpec from './InputSpec'
|
||||||
import InputNumber from './InputNumber'
|
import InputNumber from './InputNumber'
|
||||||
import InputSelect from './InputSelect'
|
import InputSelect from './InputSelect'
|
||||||
import FieldDocLabel from './FieldDocLabel'
|
|
||||||
import Block from './Block'
|
import Block from './Block'
|
||||||
|
|
||||||
import DeleteStopButton from './_DeleteStopButton'
|
import DeleteStopButton from './_DeleteStopButton'
|
||||||
@@ -22,12 +20,12 @@ import sortNumerically from '../libs/sort-numerically'
|
|||||||
*
|
*
|
||||||
* When the stops are reordered the references are also updated (see this.orderStops) this allows React to use the same key for the element and keep keyboard focus.
|
* When the stops are reordered the references are also updated (see this.orderStops) this allows React to use the same key for the element and keep keyboard focus.
|
||||||
*/
|
*/
|
||||||
function setStopRefs(props, state) {
|
function setStopRefs(props: ZoomPropertyProps, state: ZoomPropertyState) {
|
||||||
// This is initialsed below only if required to improved performance.
|
// This is initialsed below only if required to improved performance.
|
||||||
let newRefs;
|
let newRefs: {[key: number]: string} = {};
|
||||||
|
|
||||||
if(props.value && props.value.stops) {
|
if(props.value && (props.value as ZoomWithStops).stops) {
|
||||||
props.value.stops.forEach((val, idx) => {
|
(props.value as ZoomWithStops).stops.forEach((_val, idx: number) => {
|
||||||
if(!state.refs.hasOwnProperty(idx)) {
|
if(!state.refs.hasOwnProperty(idx)) {
|
||||||
if(!newRefs) {
|
if(!newRefs) {
|
||||||
newRefs = {...state};
|
newRefs = {...state};
|
||||||
@@ -40,32 +38,39 @@ function setStopRefs(props, state) {
|
|||||||
return newRefs;
|
return newRefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ZoomWithStops = {
|
||||||
|
stops: [number | undefined, number][]
|
||||||
|
base?: number
|
||||||
|
}
|
||||||
|
|
||||||
export default class ZoomProperty extends React.Component {
|
|
||||||
static propTypes = {
|
type ZoomPropertyProps = {
|
||||||
onChange: PropTypes.func,
|
onChange?(...args: unknown[]): unknown
|
||||||
onDeleteStop: PropTypes.func,
|
onChangeToDataFunction?(...args: unknown[]): unknown
|
||||||
onAddStop: PropTypes.func,
|
onDeleteStop?(...args: unknown[]): unknown
|
||||||
onExpressionClick: PropTypes.func,
|
onAddStop?(...args: unknown[]): unknown
|
||||||
fieldType: PropTypes.string,
|
onExpressionClick?(...args: unknown[]): unknown
|
||||||
fieldName: PropTypes.string,
|
fieldType?: string
|
||||||
fieldSpec: PropTypes.object,
|
fieldName: string
|
||||||
errors: PropTypes.object,
|
fieldSpec?: {
|
||||||
value: PropTypes.oneOfType([
|
"property-type"?: string
|
||||||
PropTypes.object,
|
"function-type"?: string
|
||||||
PropTypes.string,
|
|
||||||
PropTypes.number,
|
|
||||||
PropTypes.bool,
|
|
||||||
PropTypes.array
|
|
||||||
]),
|
|
||||||
}
|
}
|
||||||
|
errors?: object
|
||||||
|
value?: ZoomWithStops
|
||||||
|
};
|
||||||
|
|
||||||
|
type ZoomPropertyState = {
|
||||||
|
refs: {[key: number]: string}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class ZoomProperty extends React.Component<ZoomPropertyProps, ZoomPropertyState> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
errors: {},
|
errors: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
refs: {}
|
refs: {} as {[key: number]: string}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -78,7 +83,7 @@ export default class ZoomProperty extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static getDerivedStateFromProps(props, state) {
|
static getDerivedStateFromProps(props: ZoomPropertyProps, state: ZoomPropertyState) {
|
||||||
const newRefs = setStopRefs(props, state);
|
const newRefs = setStopRefs(props, state);
|
||||||
if(newRefs) {
|
if(newRefs) {
|
||||||
return {
|
return {
|
||||||
@@ -89,7 +94,7 @@ export default class ZoomProperty extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Order the stops altering the refs to reflect their new position.
|
// Order the stops altering the refs to reflect their new position.
|
||||||
orderStopsByZoom(stops) {
|
orderStopsByZoom(stops: ZoomWithStops["stops"]) {
|
||||||
const mappedWithRef = stops
|
const mappedWithRef = stops
|
||||||
.map((stop, idx) => {
|
.map((stop, idx) => {
|
||||||
return {
|
return {
|
||||||
@@ -98,10 +103,10 @@ export default class ZoomProperty extends React.Component {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
// Sort by zoom
|
// Sort by zoom
|
||||||
.sort((a, b) => sortNumerically(a.data[0], b.data[0]));
|
.sort((a, b) => sortNumerically(a.data[0]!, b.data[0]!));
|
||||||
|
|
||||||
// Fetch the new position of the stops
|
// Fetch the new position of the stops
|
||||||
const newRefs = {};
|
const newRefs: {[key:number]: string} = {};
|
||||||
mappedWithRef
|
mappedWithRef
|
||||||
.forEach((stop, idx) =>{
|
.forEach((stop, idx) =>{
|
||||||
newRefs[idx] = stop.ref;
|
newRefs[idx] = stop.ref;
|
||||||
@@ -114,20 +119,20 @@ export default class ZoomProperty extends React.Component {
|
|||||||
return mappedWithRef.map((item) => item.data);
|
return mappedWithRef.map((item) => item.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeZoomStop(changeIdx, stopData, value) {
|
changeZoomStop(changeIdx: number, stopData: number | undefined, value: number) {
|
||||||
const stops = this.props.value.stops.slice(0);
|
const stops = (this.props.value as ZoomWithStops).stops.slice(0);
|
||||||
stops[changeIdx] = [stopData, value];
|
stops[changeIdx] = [stopData, value];
|
||||||
|
|
||||||
const orderedStops = this.orderStopsByZoom(stops);
|
const orderedStops = this.orderStopsByZoom(stops);
|
||||||
|
|
||||||
const changedValue = {
|
const changedValue = {
|
||||||
...this.props.value,
|
...this.props.value as ZoomWithStops,
|
||||||
stops: orderedStops
|
stops: orderedStops
|
||||||
}
|
}
|
||||||
this.props.onChange(this.props.fieldName, changedValue)
|
this.props.onChange!(this.props.fieldName, changedValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
changeBase(newValue) {
|
changeBase(newValue: number | undefined) {
|
||||||
const changedValue = {
|
const changedValue = {
|
||||||
...this.props.value,
|
...this.props.value,
|
||||||
base: newValue
|
base: newValue
|
||||||
@@ -136,33 +141,21 @@ export default class ZoomProperty extends React.Component {
|
|||||||
if (changedValue.base === undefined) {
|
if (changedValue.base === undefined) {
|
||||||
delete changedValue["base"];
|
delete changedValue["base"];
|
||||||
}
|
}
|
||||||
this.props.onChange(this.props.fieldName, changedValue)
|
this.props.onChange!(this.props.fieldName, changedValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
changeDataType = (type) => {
|
changeDataType = (type: string) => {
|
||||||
if (type !== "interpolate") {
|
if (type !== "interpolate" && this.props.onChangeToDataFunction) {
|
||||||
this.props.onChangeToDataFunction(type);
|
this.props.onChangeToDataFunction(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {fieldName, fieldType, errors} = this.props;
|
const zoomFields = this.props.value?.stops.map((stop, idx) => {
|
||||||
|
|
||||||
const zoomFields = this.props.value.stops.map((stop, idx) => {
|
|
||||||
const zoomLevel = stop[0]
|
const zoomLevel = stop[0]
|
||||||
const key = this.state.refs[idx];
|
const key = this.state.refs[idx];
|
||||||
const value = stop[1]
|
const value = stop[1]
|
||||||
const deleteStopBtn= <DeleteStopButton onClick={this.props.onDeleteStop.bind(this, idx)} />
|
const deleteStopBtn= <DeleteStopButton onClick={this.props.onDeleteStop?.bind(this, idx)} />
|
||||||
|
|
||||||
const errorKeyStart = `${fieldType}.${fieldName}.stops[${idx}]`;
|
|
||||||
const foundErrors = Object.entries(errors).filter(([key, error]) => {
|
|
||||||
return key.startsWith(errorKeyStart);
|
|
||||||
});
|
|
||||||
|
|
||||||
const message = foundErrors.map(([key, error]) => {
|
|
||||||
return error.message;
|
|
||||||
}).join("");
|
|
||||||
const error = message ? {message} : undefined;
|
|
||||||
|
|
||||||
return <tr
|
return <tr
|
||||||
key={key}
|
key={key}
|
||||||
@@ -180,9 +173,9 @@ export default class ZoomProperty extends React.Component {
|
|||||||
<InputSpec
|
<InputSpec
|
||||||
aria-label="Output value"
|
aria-label="Output value"
|
||||||
fieldName={this.props.fieldName}
|
fieldName={this.props.fieldName}
|
||||||
fieldSpec={this.props.fieldSpec}
|
fieldSpec={this.props.fieldSpec as any}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={(_, newValue) => this.changeZoomStop(idx, zoomLevel, newValue)}
|
onChange={(_, newValue) => this.changeZoomStop(idx, zoomLevel, newValue as number)}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -204,7 +197,7 @@ export default class ZoomProperty extends React.Component {
|
|||||||
value={"interpolate"}
|
value={"interpolate"}
|
||||||
onChange={propVal => this.changeDataType(propVal)}
|
onChange={propVal => this.changeDataType(propVal)}
|
||||||
title={"Select a type of data scale (default is 'categorical')."}
|
title={"Select a type of data scale (default is 'categorical')."}
|
||||||
options={this.getDataFunctionTypes(this.props.fieldSpec)}
|
options={this.getDataFunctionTypes(this.props.fieldSpec!)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Block>
|
</Block>
|
||||||
@@ -215,8 +208,8 @@ export default class ZoomProperty extends React.Component {
|
|||||||
<InputSpec
|
<InputSpec
|
||||||
fieldName={"base"}
|
fieldName={"base"}
|
||||||
fieldSpec={latest.function.base}
|
fieldSpec={latest.function.base}
|
||||||
value={this.props.value.base}
|
value={this.props.value?.base}
|
||||||
onChange={(_, newValue) => this.changeBase(newValue)}
|
onChange={(_, newValue) => this.changeBase(newValue as number | undefined)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Block>
|
</Block>
|
||||||
@@ -226,7 +219,7 @@ export default class ZoomProperty extends React.Component {
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Zoom</th>
|
<th>Zoom</th>
|
||||||
<th rowSpan="2">Output value</th>
|
<th rowSpan={2}>Output value</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -237,7 +230,7 @@ export default class ZoomProperty extends React.Component {
|
|||||||
<div className="maputnik-toolbox">
|
<div className="maputnik-toolbox">
|
||||||
<InputButton
|
<InputButton
|
||||||
className="maputnik-add-stop"
|
className="maputnik-add-stop"
|
||||||
onClick={this.props.onAddStop.bind(this)}
|
onClick={this.props.onAddStop?.bind(this)}
|
||||||
>
|
>
|
||||||
<svg style={{width:"14px", height:"14px", verticalAlign: "text-bottom"}} viewBox="0 0 24 24">
|
<svg style={{width:"14px", height:"14px", verticalAlign: "text-bottom"}} viewBox="0 0 24 24">
|
||||||
<path fill="currentColor" d={mdiTableRowPlusAfter} />
|
<path fill="currentColor" d={mdiTableRowPlusAfter} />
|
||||||
@@ -245,7 +238,7 @@ export default class ZoomProperty extends React.Component {
|
|||||||
</InputButton>
|
</InputButton>
|
||||||
<InputButton
|
<InputButton
|
||||||
className="maputnik-add-stop"
|
className="maputnik-add-stop"
|
||||||
onClick={this.props.onExpressionClick.bind(this)}
|
onClick={this.props.onExpressionClick?.bind(this)}
|
||||||
>
|
>
|
||||||
<svg style={{width:"14px", height:"14px", verticalAlign: "text-bottom"}} viewBox="0 0 24 24">
|
<svg style={{width:"14px", height:"14px", verticalAlign: "text-bottom"}} viewBox="0 0 24 24">
|
||||||
<path fill="currentColor" d={mdiFunctionVariant} />
|
<path fill="currentColor" d={mdiFunctionVariant} />
|
||||||
@@ -257,7 +250,10 @@ export default class ZoomProperty extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
getDataFunctionTypes(fieldSpec) {
|
getDataFunctionTypes(fieldSpec: {
|
||||||
|
"property-type"?: string
|
||||||
|
"function-type"?: string
|
||||||
|
}) {
|
||||||
if (fieldSpec['property-type'] === 'data-driven') {
|
if (fieldSpec['property-type'] === 'data-driven') {
|
||||||
return ["interpolate", "categorical", "interval", "exponential", "identity"];
|
return ["interpolate", "categorical", "interval", "exponential", "identity"];
|
||||||
}
|
}
|
||||||
@@ -265,5 +261,4 @@ export default class ZoomProperty extends React.Component {
|
|||||||
return ["interpolate"];
|
return ["interpolate"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* If we don't have a default value just make one up
|
* If we don't have a default value just make one up
|
||||||
*/
|
*/
|
||||||
export function findDefaultFromSpec (spec) {
|
export function findDefaultFromSpec(spec: { type: 'string' | 'color' | 'boolean' | 'array', default?: any }) {
|
||||||
if (spec.hasOwnProperty('default')) {
|
if (spec.hasOwnProperty('default')) {
|
||||||
return spec.default;
|
return spec.default;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user