import React, { type ReactElement } from "react"; import InputColor, { type InputColorProps } from "./InputColor"; import InputNumber, { type InputNumberProps } from "./InputNumber"; import InputCheckbox, { type InputCheckboxProps } from "./InputCheckbox"; import InputString, { type InputStringProps } from "./InputString"; import InputArray, { type InputArrayProps } from "./InputArray"; import InputDynamicArray, { type InputDynamicArrayProps } from "./InputDynamicArray"; import InputFont, { type InputFontProps } from "./InputFont"; import InputAutocomplete, { type InputAutocompleteProps } from "./InputAutocomplete"; import InputEnum, { type InputEnumProps } from "./InputEnum"; import capitalize from "lodash.capitalize"; const iconProperties = ["background-pattern", "fill-pattern", "line-pattern", "fill-extrusion-pattern", "icon-image"]; export type FieldSpecType = "number" | "enum" | "resolvedImage" | "formatted" | "string" | "color" | "boolean" | "array" | "numberArray" | "padding" | "colorArray" | "variableAnchorOffsetCollection"; export type InputSpecProps = { onChange?(fieldName: string | undefined, value: number | undefined | (string | number | undefined)[]): unknown fieldName?: string fieldSpec?: { default?: unknown type?: FieldSpecType 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 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 InputSpec extends React.Component { childNodes() { const commonProps = { 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, "data-wd-key": "spec-field-input:" + this.props.fieldName, onChange: (newValue: number | undefined | (string | number | undefined)[]) => this.props.onChange!(this.props.fieldName, newValue), "aria-label": this.props["aria-label"], }; switch(this.props.fieldSpec?.type) { case "number": return ( ); case "enum": { const options = Object.keys(this.props.fieldSpec.values || []).map(v => [v, capitalize(v)]); return } options={options} />; } case "resolvedImage": case "formatted": case "string": if (iconProperties.indexOf(this.props.fieldName!) >= 0) { const options = this.props.fieldSpec.values || []; return } options={options.map(f => [f, f])} />; } else { return ; } case "color": return ( ); case "boolean": return ( ); case "array": if(this.props.fieldName === "text-font") { return ; } else { if (this.props.fieldSpec.length) { return ; } else { return ; } } case "numberArray": return ( ); case "colorArray": return ( ); case "padding": return ( ); default: console.warn(`No proper field input for ${this.props.fieldName} type: ${this.props.fieldSpec?.type}`); return null; } } render() { return (
{this.childNodes()}
); } }