mirror of
https://github.com/maputnik/editor.git
synced 2026-03-01 07:50:00 +00:00
Refactor Field components with const arrow functions (#1261)
## Summary - convert all remaining Field components to const arrow functions - document the refactor in the CHANGELOG ## Testing - `npm run lint` - `npm run build` ------ https://chatgpt.com/codex/tasks/task_e_68684db1b6b88331837307a54e3f9dc1
This commit is contained in:
@@ -111,296 +111,268 @@ type FieldFunctionProps = {
|
||||
value?: any
|
||||
};
|
||||
|
||||
type FieldFunctionState = {
|
||||
dataType: string
|
||||
isEditing: boolean
|
||||
}
|
||||
|
||||
/** Supports displaying spec field for zoom function objects
|
||||
* https://www.mapbox.com/mapbox-gl-style-spec/#types-function-zoom-property
|
||||
*/
|
||||
export default class FieldFunction extends React.Component<FieldFunctionProps, FieldFunctionState> {
|
||||
constructor (props: FieldFunctionProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
dataType: getDataType(props.value, props.fieldSpec),
|
||||
isEditing: false,
|
||||
}
|
||||
}
|
||||
const FieldFunction: React.FC<FieldFunctionProps> = (props) => {
|
||||
const [dataType, setDataType] = React.useState(
|
||||
getDataType(props.value, props.fieldSpec)
|
||||
);
|
||||
const [isEditing, setIsEditing] = React.useState(false);
|
||||
|
||||
static getDerivedStateFromProps(props: Readonly<FieldFunctionProps>, state: FieldFunctionState) {
|
||||
// Because otherwise when editing values we end up accidentally changing field type.
|
||||
if (state.isEditing) {
|
||||
return {};
|
||||
React.useEffect(() => {
|
||||
if (!isEditing) {
|
||||
setDataType(getDataType(props.value, props.fieldSpec));
|
||||
}
|
||||
else {
|
||||
return {
|
||||
isEditing: false,
|
||||
dataType: getDataType(props.value, props.fieldSpec)
|
||||
};
|
||||
}
|
||||
}
|
||||
}, [props.value, props.fieldSpec, isEditing]);
|
||||
|
||||
getFieldFunctionType(fieldSpec: any) {
|
||||
const getFieldFunctionType = (fieldSpec: any) => {
|
||||
if (fieldSpec.expression.interpolated) {
|
||||
return "exponential"
|
||||
return 'exponential';
|
||||
}
|
||||
if (fieldSpec.type === "number") {
|
||||
return "interval"
|
||||
if (fieldSpec.type === 'number') {
|
||||
return 'interval';
|
||||
}
|
||||
return "categorical"
|
||||
}
|
||||
return 'categorical';
|
||||
};
|
||||
|
||||
addStop = () => {
|
||||
const stops = this.props.value.stops.slice(0)
|
||||
const lastStop = stops[stops.length - 1]
|
||||
if (typeof lastStop[0] === "object") {
|
||||
const addStop = () => {
|
||||
const stops = props.value.stops.slice(0);
|
||||
const lastStop = stops[stops.length - 1];
|
||||
if (typeof lastStop[0] === 'object') {
|
||||
stops.push([
|
||||
{zoom: lastStop[0].zoom + 1, value: lastStop[0].value},
|
||||
lastStop[1]
|
||||
])
|
||||
}
|
||||
else {
|
||||
stops.push([lastStop[0] + 1, lastStop[1]])
|
||||
{ zoom: lastStop[0].zoom + 1, value: lastStop[0].value },
|
||||
lastStop[1],
|
||||
]);
|
||||
} else {
|
||||
stops.push([lastStop[0] + 1, lastStop[1]]);
|
||||
}
|
||||
|
||||
const changedValue = {
|
||||
...this.props.value,
|
||||
...props.value,
|
||||
stops: stops,
|
||||
}
|
||||
};
|
||||
|
||||
this.props.onChange(this.props.fieldName, changedValue)
|
||||
}
|
||||
props.onChange(props.fieldName, changedValue);
|
||||
};
|
||||
|
||||
deleteExpression = () => {
|
||||
const {fieldSpec, fieldName} = this.props;
|
||||
this.props.onChange(fieldName, fieldSpec.default);
|
||||
this.setState({
|
||||
dataType: "value",
|
||||
});
|
||||
}
|
||||
const deleteExpression = () => {
|
||||
const { fieldSpec, fieldName } = props;
|
||||
props.onChange(fieldName, fieldSpec.default);
|
||||
setDataType('value');
|
||||
};
|
||||
|
||||
deleteStop = (stopIdx: number) => {
|
||||
const stops = this.props.value.stops.slice(0)
|
||||
stops.splice(stopIdx, 1)
|
||||
const deleteStop = (stopIdx: number) => {
|
||||
const stops = props.value.stops.slice(0);
|
||||
stops.splice(stopIdx, 1);
|
||||
|
||||
let changedValue = {
|
||||
...this.props.value,
|
||||
let changedValue: any = {
|
||||
...props.value,
|
||||
stops: stops,
|
||||
};
|
||||
|
||||
if (stops.length === 1) {
|
||||
changedValue = stops[0][1];
|
||||
}
|
||||
|
||||
if(stops.length === 1) {
|
||||
changedValue = stops[0][1]
|
||||
}
|
||||
props.onChange(props.fieldName, changedValue);
|
||||
};
|
||||
|
||||
this.props.onChange(this.props.fieldName, changedValue)
|
||||
}
|
||||
const makeZoomFunction = () => {
|
||||
const { value } = props;
|
||||
|
||||
makeZoomFunction = () => {
|
||||
const {value} = this.props;
|
||||
|
||||
let zoomFunc;
|
||||
if (typeof(value) === "object") {
|
||||
let zoomFunc: any;
|
||||
if (typeof value === 'object') {
|
||||
if (value.stops) {
|
||||
zoomFunc = {
|
||||
base: value.base,
|
||||
stops: value.stops.map((stop: Stop) => {
|
||||
return [stop[0].zoom, stop[1] || findDefaultFromSpec(this.props.fieldSpec)];
|
||||
})
|
||||
}
|
||||
}
|
||||
else {
|
||||
return [stop[0].zoom, stop[1] || findDefaultFromSpec(props.fieldSpec)];
|
||||
}),
|
||||
};
|
||||
} else {
|
||||
zoomFunc = {
|
||||
base: value.base,
|
||||
stops: [
|
||||
[6, findDefaultFromSpec(this.props.fieldSpec)],
|
||||
[10, findDefaultFromSpec(this.props.fieldSpec)]
|
||||
]
|
||||
}
|
||||
[6, findDefaultFromSpec(props.fieldSpec)],
|
||||
[10, findDefaultFromSpec(props.fieldSpec)],
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
zoomFunc = {
|
||||
stops: [
|
||||
[6, value || findDefaultFromSpec(this.props.fieldSpec)],
|
||||
[10, value || findDefaultFromSpec(this.props.fieldSpec)]
|
||||
]
|
||||
}
|
||||
[6, value || findDefaultFromSpec(props.fieldSpec)],
|
||||
[10, value || findDefaultFromSpec(props.fieldSpec)],
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
this.props.onChange(this.props.fieldName, zoomFunc)
|
||||
}
|
||||
props.onChange(props.fieldName, zoomFunc);
|
||||
};
|
||||
|
||||
undoExpression = () => {
|
||||
const {value, fieldName} = this.props;
|
||||
const undoExpression = () => {
|
||||
const { value, fieldName } = props;
|
||||
|
||||
if (isGetExpression(value)) {
|
||||
this.props.onChange(fieldName, {
|
||||
"type": "identity",
|
||||
"property": value[1]
|
||||
});
|
||||
this.setState({
|
||||
dataType: "value",
|
||||
props.onChange(fieldName, {
|
||||
type: 'identity',
|
||||
property: value[1],
|
||||
});
|
||||
setDataType('value');
|
||||
} else if (isLiteralExpression(value)) {
|
||||
props.onChange(fieldName, value[1]);
|
||||
setDataType('value');
|
||||
}
|
||||
else if (isLiteralExpression(value)) {
|
||||
this.props.onChange(fieldName, value[1]);
|
||||
this.setState({
|
||||
dataType: "value",
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
canUndo = () => {
|
||||
const {value, fieldSpec} = this.props;
|
||||
const canUndo = () => {
|
||||
const { value, fieldSpec } = props;
|
||||
return (
|
||||
isGetExpression(value) ||
|
||||
isLiteralExpression(value) ||
|
||||
isPrimative(value) ||
|
||||
(Array.isArray(value) && fieldSpec.type === "array")
|
||||
(Array.isArray(value) && fieldSpec.type === 'array')
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
makeExpression = () => {
|
||||
const {value, fieldSpec} = this.props;
|
||||
const makeExpression = () => {
|
||||
const { value, fieldSpec } = props;
|
||||
let expression;
|
||||
|
||||
if (typeof(value) === "object" && 'stops' in value) {
|
||||
if (typeof value === 'object' && 'stops' in value) {
|
||||
expression = styleFunction.convertFunction(value, fieldSpec);
|
||||
} else if (isIdentityProperty(value)) {
|
||||
expression = ['get', value.property];
|
||||
} else {
|
||||
expression = ['literal', value || props.fieldSpec.default];
|
||||
}
|
||||
else if (isIdentityProperty(value)) {
|
||||
expression = ["get", value.property];
|
||||
}
|
||||
else {
|
||||
expression = ["literal", value || this.props.fieldSpec.default];
|
||||
}
|
||||
this.props.onChange(this.props.fieldName, expression);
|
||||
}
|
||||
props.onChange(props.fieldName, expression);
|
||||
};
|
||||
|
||||
makeDataFunction = () => {
|
||||
const functionType = this.getFieldFunctionType(this.props.fieldSpec);
|
||||
const makeDataFunction = () => {
|
||||
const functionType = getFieldFunctionType(props.fieldSpec);
|
||||
const stopValue = functionType === 'categorical' ? '' : 0;
|
||||
const {value} = this.props;
|
||||
const { value } = props;
|
||||
let dataFunc;
|
||||
|
||||
if (typeof(value) === "object") {
|
||||
if (typeof value === 'object') {
|
||||
if (value.stops) {
|
||||
dataFunc = {
|
||||
property: "",
|
||||
property: '',
|
||||
type: functionType,
|
||||
base: value.base,
|
||||
stops: value.stops.map((stop: Stop) => {
|
||||
return [{zoom: stop[0], value: stopValue}, stop[1] || findDefaultFromSpec(this.props.fieldSpec)];
|
||||
})
|
||||
}
|
||||
}
|
||||
else {
|
||||
return [{ zoom: stop[0], value: stopValue }, stop[1] || findDefaultFromSpec(props.fieldSpec)];
|
||||
}),
|
||||
};
|
||||
} else {
|
||||
dataFunc = {
|
||||
property: "",
|
||||
property: '',
|
||||
type: functionType,
|
||||
base: value.base,
|
||||
stops: [
|
||||
[{zoom: 6, value: stopValue}, findDefaultFromSpec(this.props.fieldSpec)],
|
||||
[{zoom: 10, value: stopValue}, findDefaultFromSpec(this.props.fieldSpec)]
|
||||
]
|
||||
}
|
||||
[{ zoom: 6, value: stopValue }, findDefaultFromSpec(props.fieldSpec)],
|
||||
[{ zoom: 10, value: stopValue }, findDefaultFromSpec(props.fieldSpec)],
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
dataFunc = {
|
||||
property: "",
|
||||
property: '',
|
||||
type: functionType,
|
||||
base: value.base,
|
||||
stops: [
|
||||
[{zoom: 6, value: stopValue}, this.props.value || findDefaultFromSpec(this.props.fieldSpec)],
|
||||
[{zoom: 10, value: stopValue}, this.props.value || findDefaultFromSpec(this.props.fieldSpec)]
|
||||
]
|
||||
}
|
||||
[{ zoom: 6, value: stopValue }, props.value || findDefaultFromSpec(props.fieldSpec)],
|
||||
[{ zoom: 10, value: stopValue }, props.value || findDefaultFromSpec(props.fieldSpec)],
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
this.props.onChange(this.props.fieldName, dataFunc)
|
||||
props.onChange(props.fieldName, dataFunc);
|
||||
};
|
||||
|
||||
const onMarkEditing = () => {
|
||||
setIsEditing(true);
|
||||
};
|
||||
|
||||
const onUnmarkEditing = () => {
|
||||
setIsEditing(false);
|
||||
};
|
||||
|
||||
const propClass =
|
||||
props.fieldSpec.default === props.value ? 'maputnik-default-property' : 'maputnik-modified-property';
|
||||
|
||||
let specField;
|
||||
|
||||
if (dataType === 'expression') {
|
||||
specField = (
|
||||
<ExpressionProperty
|
||||
errors={props.errors}
|
||||
onChange={props.onChange.bind(null, props.fieldName)}
|
||||
canUndo={canUndo}
|
||||
onUndo={undoExpression}
|
||||
onDelete={deleteExpression}
|
||||
fieldType={props.fieldType}
|
||||
fieldName={props.fieldName}
|
||||
fieldSpec={props.fieldSpec}
|
||||
value={props.value}
|
||||
onFocus={onMarkEditing}
|
||||
onBlur={onUnmarkEditing}
|
||||
/>
|
||||
);
|
||||
} else if (dataType === 'zoom_function') {
|
||||
specField = (
|
||||
<ZoomProperty
|
||||
errors={props.errors}
|
||||
onChange={props.onChange.bind(null)}
|
||||
fieldType={props.fieldType}
|
||||
fieldName={props.fieldName}
|
||||
fieldSpec={props.fieldSpec}
|
||||
value={props.value}
|
||||
onDeleteStop={deleteStop}
|
||||
onAddStop={addStop}
|
||||
onChangeToDataFunction={makeDataFunction}
|
||||
onExpressionClick={makeExpression}
|
||||
/>
|
||||
);
|
||||
} else if (dataType === 'data_function') {
|
||||
specField = (
|
||||
<DataProperty
|
||||
errors={props.errors}
|
||||
onChange={props.onChange.bind(null)}
|
||||
fieldType={props.fieldType}
|
||||
fieldName={props.fieldName}
|
||||
fieldSpec={props.fieldSpec}
|
||||
value={props.value}
|
||||
onDeleteStop={deleteStop}
|
||||
onAddStop={addStop}
|
||||
onChangeToZoomFunction={makeZoomFunction}
|
||||
onExpressionClick={makeExpression}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
specField = (
|
||||
<SpecProperty
|
||||
errors={props.errors}
|
||||
onChange={props.onChange.bind(null)}
|
||||
fieldType={props.fieldType}
|
||||
fieldName={props.fieldName}
|
||||
fieldSpec={props.fieldSpec}
|
||||
value={props.value}
|
||||
onZoomClick={makeZoomFunction}
|
||||
onDataClick={makeDataFunction}
|
||||
onExpressionClick={makeExpression}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
onMarkEditing = () => {
|
||||
this.setState({isEditing: true});
|
||||
}
|
||||
|
||||
onUnmarkEditing = () => {
|
||||
this.setState({isEditing: false});
|
||||
}
|
||||
|
||||
render() {
|
||||
const {dataType} = this.state;
|
||||
const propClass = this.props.fieldSpec.default === this.props.value ? "maputnik-default-property" : "maputnik-modified-property"
|
||||
let specField;
|
||||
|
||||
if (dataType === "expression") {
|
||||
specField = (
|
||||
<ExpressionProperty
|
||||
errors={this.props.errors}
|
||||
onChange={this.props.onChange.bind(this, this.props.fieldName)}
|
||||
canUndo={this.canUndo}
|
||||
onUndo={this.undoExpression}
|
||||
onDelete={this.deleteExpression}
|
||||
fieldType={this.props.fieldType}
|
||||
fieldName={this.props.fieldName}
|
||||
fieldSpec={this.props.fieldSpec}
|
||||
value={this.props.value}
|
||||
onFocus={this.onMarkEditing}
|
||||
onBlur={this.onUnmarkEditing}
|
||||
/>
|
||||
);
|
||||
}
|
||||
else if (dataType === "zoom_function") {
|
||||
specField = (
|
||||
<ZoomProperty
|
||||
errors={this.props.errors}
|
||||
onChange={this.props.onChange.bind(this)}
|
||||
fieldType={this.props.fieldType}
|
||||
fieldName={this.props.fieldName}
|
||||
fieldSpec={this.props.fieldSpec}
|
||||
value={this.props.value}
|
||||
onDeleteStop={this.deleteStop}
|
||||
onAddStop={this.addStop}
|
||||
onChangeToDataFunction={this.makeDataFunction}
|
||||
onExpressionClick={this.makeExpression}
|
||||
/>
|
||||
)
|
||||
}
|
||||
else if (dataType === "data_function") {
|
||||
// TODO: Rename to FieldFunction **this file** shouldn't be called that
|
||||
specField = (
|
||||
<DataProperty
|
||||
errors={this.props.errors}
|
||||
onChange={this.props.onChange.bind(this)}
|
||||
fieldType={this.props.fieldType}
|
||||
fieldName={this.props.fieldName}
|
||||
fieldSpec={this.props.fieldSpec}
|
||||
value={this.props.value}
|
||||
onDeleteStop={this.deleteStop}
|
||||
onAddStop={this.addStop}
|
||||
onChangeToZoomFunction={this.makeZoomFunction}
|
||||
onExpressionClick={this.makeExpression}
|
||||
/>
|
||||
)
|
||||
}
|
||||
else {
|
||||
specField = (
|
||||
<SpecProperty
|
||||
errors={this.props.errors}
|
||||
onChange={this.props.onChange.bind(this)}
|
||||
fieldType={this.props.fieldType}
|
||||
fieldName={this.props.fieldName}
|
||||
fieldSpec={this.props.fieldSpec}
|
||||
value={this.props.value}
|
||||
onZoomClick={this.makeZoomFunction}
|
||||
onDataClick={this.makeDataFunction}
|
||||
onExpressionClick={this.makeExpression}
|
||||
/>
|
||||
)
|
||||
}
|
||||
return <div className={propClass} data-wd-key={"spec-field-container:"+this.props.fieldName}>
|
||||
return (
|
||||
<div className={propClass} data-wd-key={'spec-field-container:' + props.fieldName}>
|
||||
{specField}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default FieldFunction;
|
||||
|
||||
Reference in New Issue
Block a user