[maps] convert VectorStyleEditor to TS (#83582)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Nathan Reese 2020-11-18 18:42:37 -07:00 committed by GitHub
parent 92acf4586e
commit d97ddcd4da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 296 additions and 196 deletions

View file

@ -174,18 +174,18 @@ export type SizeStylePropertyDescriptor =
};
export type VectorStylePropertiesDescriptor = {
[VECTOR_STYLES.SYMBOLIZE_AS]?: SymbolizeAsStylePropertyDescriptor;
[VECTOR_STYLES.FILL_COLOR]?: ColorStylePropertyDescriptor;
[VECTOR_STYLES.LINE_COLOR]?: ColorStylePropertyDescriptor;
[VECTOR_STYLES.LINE_WIDTH]?: SizeStylePropertyDescriptor;
[VECTOR_STYLES.ICON]?: IconStylePropertyDescriptor;
[VECTOR_STYLES.ICON_SIZE]?: SizeStylePropertyDescriptor;
[VECTOR_STYLES.ICON_ORIENTATION]?: OrientationStylePropertyDescriptor;
[VECTOR_STYLES.LABEL_TEXT]?: LabelStylePropertyDescriptor;
[VECTOR_STYLES.LABEL_COLOR]?: ColorStylePropertyDescriptor;
[VECTOR_STYLES.LABEL_SIZE]?: SizeStylePropertyDescriptor;
[VECTOR_STYLES.LABEL_BORDER_COLOR]?: ColorStylePropertyDescriptor;
[VECTOR_STYLES.LABEL_BORDER_SIZE]?: LabelBorderSizeStylePropertyDescriptor;
[VECTOR_STYLES.SYMBOLIZE_AS]: SymbolizeAsStylePropertyDescriptor;
[VECTOR_STYLES.FILL_COLOR]: ColorStylePropertyDescriptor;
[VECTOR_STYLES.LINE_COLOR]: ColorStylePropertyDescriptor;
[VECTOR_STYLES.LINE_WIDTH]: SizeStylePropertyDescriptor;
[VECTOR_STYLES.ICON]: IconStylePropertyDescriptor;
[VECTOR_STYLES.ICON_SIZE]: SizeStylePropertyDescriptor;
[VECTOR_STYLES.ICON_ORIENTATION]: OrientationStylePropertyDescriptor;
[VECTOR_STYLES.LABEL_TEXT]: LabelStylePropertyDescriptor;
[VECTOR_STYLES.LABEL_COLOR]: ColorStylePropertyDescriptor;
[VECTOR_STYLES.LABEL_SIZE]: SizeStylePropertyDescriptor;
[VECTOR_STYLES.LABEL_BORDER_COLOR]: ColorStylePropertyDescriptor;
[VECTOR_STYLES.LABEL_BORDER_SIZE]: LabelBorderSizeStylePropertyDescriptor;
};
export type StyleDescriptor = {

View file

@ -36,6 +36,7 @@ import {
LayerDescriptor,
VectorLayerDescriptor,
VectorSourceRequestMeta,
VectorStylePropertiesDescriptor,
} from '../../../../common/descriptor_types';
import { IVectorSource } from '../../sources/vector_source';
import { LICENSED_FEATURES } from '../../../licensed_features';
@ -79,13 +80,15 @@ function getClusterStyleDescriptor(
clusterSource: ESGeoGridSource
): VectorStyleDescriptor {
const defaultDynamicProperties = getDefaultDynamicProperties();
const clusterStyleDescriptor: VectorStyleDescriptor = {
const clusterStyleDescriptor: Omit<VectorStyleDescriptor, 'properties'> & {
properties: Partial<VectorStylePropertiesDescriptor>;
} = {
type: LAYER_STYLE_TYPE.VECTOR,
properties: {
[VECTOR_STYLES.LABEL_TEXT]: {
type: STYLE_TYPE.DYNAMIC,
options: {
...defaultDynamicProperties[VECTOR_STYLES.LABEL_TEXT]!.options,
...defaultDynamicProperties[VECTOR_STYLES.LABEL_TEXT].options,
field: {
name: COUNT_PROP_NAME,
origin: FIELD_ORIGIN.SOURCE,
@ -95,7 +98,7 @@ function getClusterStyleDescriptor(
[VECTOR_STYLES.ICON_SIZE]: {
type: STYLE_TYPE.DYNAMIC,
options: {
...(defaultDynamicProperties[VECTOR_STYLES.ICON_SIZE]!.options as SizeDynamicOptions),
...(defaultDynamicProperties[VECTOR_STYLES.ICON_SIZE].options as SizeDynamicOptions),
field: {
name: COUNT_PROP_NAME,
origin: FIELD_ORIGIN.SOURCE,
@ -157,7 +160,7 @@ function getClusterStyleDescriptor(
}
});
return clusterStyleDescriptor;
return clusterStyleDescriptor as VectorStyleDescriptor;
}
export interface BlendedVectorLayerArguments {

View file

@ -71,7 +71,7 @@ function createChoroplethLayerDescriptor({
[VECTOR_STYLES.FILL_COLOR]: {
type: STYLE_TYPE.DYNAMIC,
options: {
...(defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR]!.options as ColorDynamicOptions),
...(defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR].options as ColorDynamicOptions),
field: {
name: joinKey,
origin: FIELD_ORIGIN.JOIN,

View file

@ -100,7 +100,7 @@ export function createRegionMapLayerDescriptor({
[VECTOR_STYLES.FILL_COLOR]: {
type: STYLE_TYPE.DYNAMIC,
options: {
...(defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR]!.options as ColorDynamicOptions),
...(defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR].options as ColorDynamicOptions),
field: {
name: joinKey,
origin: FIELD_ORIGIN.JOIN,
@ -108,7 +108,7 @@ export function createRegionMapLayerDescriptor({
color: colorPallette ? colorPallette.value : 'Yellow to Red',
type: COLOR_MAP_TYPE.ORDINAL,
fieldMetaOptions: {
...(defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR]!.options as ColorDynamicOptions)
...(defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR].options as ColorDynamicOptions)
.fieldMetaOptions,
isEnabled: false,
},

View file

@ -113,16 +113,16 @@ export function createTileMapLayerDescriptor({
const colorPallette = NUMERICAL_COLOR_PALETTES.find((pallette) => {
return pallette.value.toLowerCase() === colorSchema.toLowerCase();
});
const styleProperties: VectorStylePropertiesDescriptor = {
const styleProperties: Partial<VectorStylePropertiesDescriptor> = {
[VECTOR_STYLES.FILL_COLOR]: {
type: STYLE_TYPE.DYNAMIC,
options: {
...(defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR]!.options as ColorDynamicOptions),
...(defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR].options as ColorDynamicOptions),
field: metricStyleField,
color: colorPallette ? colorPallette.value : 'Yellow to Red',
type: COLOR_MAP_TYPE.ORDINAL,
fieldMetaOptions: {
...(defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR]!.options as ColorDynamicOptions)
...(defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR].options as ColorDynamicOptions)
.fieldMetaOptions,
isEnabled: false,
},
@ -139,11 +139,11 @@ export function createTileMapLayerDescriptor({
styleProperties[VECTOR_STYLES.ICON_SIZE] = {
type: STYLE_TYPE.DYNAMIC,
options: {
...(defaultDynamicProperties[VECTOR_STYLES.ICON_SIZE]!.options as SizeDynamicOptions),
...(defaultDynamicProperties[VECTOR_STYLES.ICON_SIZE].options as SizeDynamicOptions),
maxSize: 18,
field: metricStyleField,
fieldMetaOptions: {
...(defaultDynamicProperties[VECTOR_STYLES.ICON_SIZE]!.options as SizeDynamicOptions)
...(defaultDynamicProperties[VECTOR_STYLES.ICON_SIZE].options as SizeDynamicOptions)
.fieldMetaOptions,
isEnabled: false,
},

View file

@ -76,11 +76,9 @@ export interface ILayer {
getType(): string | undefined;
isVisible(): boolean;
cloneDescriptor(): Promise<LayerDescriptor>;
renderStyleEditor({
onStyleDescriptorChange,
}: {
onStyleDescriptorChange: (styleDescriptor: StyleDescriptor) => void;
}): ReactElement<any> | null;
renderStyleEditor(
onStyleDescriptorChange: (styleDescriptor: StyleDescriptor) => void
): ReactElement<any> | null;
getInFlightRequestTokens(): symbol[];
getPrevRequestToken(dataId: string): symbol | undefined;
destroy: () => void;
@ -437,16 +435,14 @@ export class AbstractLayer implements ILayer {
return null;
}
renderStyleEditor({
onStyleDescriptorChange,
}: {
onStyleDescriptorChange: (styleDescriptor: StyleDescriptor) => void;
}): ReactElement<any> | null {
renderStyleEditor(
onStyleDescriptorChange: (styleDescriptor: StyleDescriptor) => void
): ReactElement<any> | null {
const style = this.getStyleForEditing();
if (!style) {
return null;
}
return style.renderEditor({ layer: this, onStyleDescriptorChange });
return style.renderEditor(onStyleDescriptorChange);
}
getIndexPatternIds(): string[] {

View file

@ -50,7 +50,7 @@ function createDynamicFillColorDescriptor(
return {
type: STYLE_TYPE.DYNAMIC,
options: {
...(defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR]!.options as ColorDynamicOptions),
...(defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR].options as ColorDynamicOptions),
field,
color:
layer === OBSERVABILITY_LAYER_TYPE.APM_RUM_PERFORMANCE ? 'Green to Red' : 'Yellow to Red',
@ -226,12 +226,12 @@ export function createLayerDescriptor({
origin: FIELD_ORIGIN.SOURCE,
};
const styleProperties: VectorStylePropertiesDescriptor = {
const styleProperties: Partial<VectorStylePropertiesDescriptor> = {
[VECTOR_STYLES.FILL_COLOR]: createDynamicFillColorDescriptor(layer, metricStyleField),
[VECTOR_STYLES.ICON_SIZE]: {
type: STYLE_TYPE.DYNAMIC,
options: {
...(defaultDynamicProperties[VECTOR_STYLES.ICON_SIZE]!.options as SizeDynamicOptions),
...(defaultDynamicProperties[VECTOR_STYLES.ICON_SIZE].options as SizeDynamicOptions),
field: metricStyleField,
},
},

View file

@ -68,7 +68,7 @@ function createSourceLayerDescriptor(indexPatternId: string, indexPatternTitle:
],
});
const styleProperties: VectorStylePropertiesDescriptor = {
const styleProperties: Partial<VectorStylePropertiesDescriptor> = {
[VECTOR_STYLES.FILL_COLOR]: {
type: STYLE_TYPE.STATIC,
options: { color: euiVisColorPalette[1] },
@ -121,7 +121,7 @@ function createDestinationLayerDescriptor(indexPatternId: string, indexPatternTi
],
});
const styleProperties: VectorStylePropertiesDescriptor = {
const styleProperties: Partial<VectorStylePropertiesDescriptor> = {
[VECTOR_STYLES.FILL_COLOR]: {
type: STYLE_TYPE.STATIC,
options: { color: euiVisColorPalette[2] },
@ -168,7 +168,7 @@ function createLineLayerDescriptor(indexPatternId: string, indexPatternTitle: st
],
});
const styleProperties: VectorStylePropertiesDescriptor = {
const styleProperties: Partial<VectorStylePropertiesDescriptor> = {
[VECTOR_STYLES.LINE_COLOR]: {
type: STYLE_TYPE.STATIC,
options: { color: euiVisColorPalette[1] },
@ -176,7 +176,7 @@ function createLineLayerDescriptor(indexPatternId: string, indexPatternTitle: st
[VECTOR_STYLES.LINE_WIDTH]: {
type: STYLE_TYPE.DYNAMIC,
options: {
...(defaultDynamicProperties[VECTOR_STYLES.LINE_WIDTH]!.options as SizeDynamicOptions),
...(defaultDynamicProperties[VECTOR_STYLES.LINE_WIDTH].options as SizeDynamicOptions),
field: {
name: COUNT_PROP_NAME,
origin: FIELD_ORIGIN.SOURCE,

View file

@ -77,7 +77,7 @@ export const clustersLayerWizardConfig: LayerWizard = {
[VECTOR_STYLES.ICON_SIZE]: {
type: STYLE_TYPE.DYNAMIC,
options: {
...(defaultDynamicProperties[VECTOR_STYLES.ICON_SIZE]!.options as SizeDynamicOptions),
...(defaultDynamicProperties[VECTOR_STYLES.ICON_SIZE].options as SizeDynamicOptions),
field: {
name: COUNT_PROP_NAME,
origin: FIELD_ORIGIN.SOURCE,
@ -87,7 +87,7 @@ export const clustersLayerWizardConfig: LayerWizard = {
[VECTOR_STYLES.LABEL_TEXT]: {
type: STYLE_TYPE.DYNAMIC,
options: {
...defaultDynamicProperties[VECTOR_STYLES.LABEL_TEXT]!.options,
...defaultDynamicProperties[VECTOR_STYLES.LABEL_TEXT].options,
field: {
name: COUNT_PROP_NAME,
origin: FIELD_ORIGIN.SOURCE,

View file

@ -41,11 +41,7 @@ export class HeatmapStyle implements IStyle {
return LAYER_STYLE_TYPE.HEATMAP;
}
renderEditor({
onStyleDescriptorChange,
}: {
onStyleDescriptorChange: (styleDescriptor: StyleDescriptor) => void;
}) {
renderEditor(onStyleDescriptorChange: (styleDescriptor: StyleDescriptor) => void) {
const onHeatmapColorChange = ({ colorRampName }: { colorRampName: string }) => {
const styleDescriptor = HeatmapStyle.createDescriptor(colorRampName);
onStyleDescriptorChange(styleDescriptor);

View file

@ -6,15 +6,10 @@
import { ReactElement } from 'react';
import { StyleDescriptor } from '../../../common/descriptor_types';
import { ILayer } from '../layers/layer';
export interface IStyle {
getType(): string;
renderEditor({
layer,
onStyleDescriptorChange,
}: {
layer: ILayer;
onStyleDescriptorChange: (styleDescriptor: StyleDescriptor) => void;
}): ReactElement<any> | null;
renderEditor(
onStyleDescriptorChange: (styleDescriptor: StyleDescriptor) => void
): ReactElement<any> | null;
}

View file

@ -21,7 +21,7 @@ export class TileStyle implements IStyle {
return LAYER_STYLE_TYPE.TILE;
}
renderEditor(/* { layer, onStyleDescriptorChange } */) {
renderEditor(/* onStyleDescriptorChange */) {
return null;
}
}

View file

@ -14,7 +14,11 @@ import { DynamicColorForm } from './dynamic_color_form';
import { StaticColorForm } from './static_color_form';
import { ColorDynamicOptions, ColorStaticOptions } from '../../../../../../common/descriptor_types';
export function VectorStyleColorEditor(props: Props<ColorStaticOptions, ColorDynamicOptions>) {
type ColorEditorProps = Omit<Props<ColorStaticOptions, ColorDynamicOptions>, 'children'> & {
swatches: string[];
};
export function VectorStyleColorEditor(props: ColorEditorProps) {
const colorForm = props.styleProperty.isDynamic() ? (
<DynamicColorForm {...props} />
) : (

View file

@ -6,11 +6,16 @@
import React from 'react';
import { StylePropEditor } from '../style_prop_editor';
import { Props, StylePropEditor } from '../style_prop_editor';
// @ts-expect-error
import { DynamicLabelForm } from './dynamic_label_form';
// @ts-expect-error
import { StaticLabelForm } from './static_label_form';
import { LabelDynamicOptions, LabelStaticOptions } from '../../../../../../common/descriptor_types';
export function VectorStyleLabelEditor(props) {
type LabelEditorProps = Omit<Props<LabelStaticOptions, LabelDynamicOptions>, 'children'>;
export function VectorStyleLabelEditor(props: LabelEditorProps) {
const labelForm = props.styleProperty.isDynamic() ? (
<DynamicLabelForm {...props} />
) : (

View file

@ -6,11 +6,16 @@
import React from 'react';
import { StylePropEditor } from '../style_prop_editor';
import { Props, StylePropEditor } from '../style_prop_editor';
// @ts-expect-error
import { DynamicSizeForm } from './dynamic_size_form';
// @ts-expect-error
import { StaticSizeForm } from './static_size_form';
import { SizeDynamicOptions, SizeStaticOptions } from '../../../../../../common/descriptor_types';
export function VectorStyleSizeEditor(props) {
type SizeEditorProps = Omit<Props<SizeStaticOptions, SizeDynamicOptions>, 'children'>;
export function VectorStyleSizeEditor(props: SizeEditorProps) {
const sizeForm = props.styleProperty.isDynamic() ? (
<DynamicSizeForm {...props} />
) : (

View file

@ -25,12 +25,12 @@ export interface Props<StaticOptions, DynamicOptions> {
customStaticOptionLabel?: string;
defaultStaticStyleOptions: StaticOptions;
defaultDynamicStyleOptions: DynamicOptions;
disabled: boolean;
disabled?: boolean;
disabledBy?: VECTOR_STYLES;
fields: StyleField[];
onDynamicStyleChange: (propertyName: VECTOR_STYLES, options: DynamicOptions) => void;
onStaticStyleChange: (propertyName: VECTOR_STYLES, options: StaticOptions) => void;
styleProperty: IStyleProperty<any>;
styleProperty: IStyleProperty<StaticOptions | DynamicOptions>;
}
export class StylePropEditor<StaticOptions, DynamicOptions> extends Component<
@ -42,7 +42,7 @@ export class StylePropEditor<StaticOptions, DynamicOptions> extends Component<
_onTypeToggle = () => {
if (this.props.styleProperty.isDynamic()) {
// preserve current dynmaic style
this._prevDynamicStyleOptions = this.props.styleProperty.getOptions();
this._prevDynamicStyleOptions = this.props.styleProperty.getOptions() as DynamicOptions;
// toggle to static style
this.props.onStaticStyleChange(
this.props.styleProperty.getStyleName(),
@ -50,7 +50,7 @@ export class StylePropEditor<StaticOptions, DynamicOptions> extends Component<
);
} else {
// preserve current static style
this._prevStaticStyleOptions = this.props.styleProperty.getOptions();
this._prevStaticStyleOptions = this.props.styleProperty.getOptions() as StaticOptions;
// toggle to dynamic style
this.props.onDynamicStyleChange(
this.props.styleProperty.getStyleName(),
@ -61,7 +61,7 @@ export class StylePropEditor<StaticOptions, DynamicOptions> extends Component<
_onFieldMetaOptionsChange = (fieldMetaOptions: FieldMetaOptions) => {
const options = {
...this.props.styleProperty.getOptions(),
...(this.props.styleProperty.getOptions() as DynamicOptions),
fieldMetaOptions,
};
this.props.onDynamicStyleChange(this.props.styleProperty.getStyleName(), options);

View file

@ -6,11 +6,16 @@
import React from 'react';
import { StylePropEditor } from '../style_prop_editor';
import { Props, StylePropEditor } from '../style_prop_editor';
// @ts-expect-error
import { DynamicIconForm } from './dynamic_icon_form';
// @ts-expect-error
import { StaticIconForm } from './static_icon_form';
import { IconDynamicOptions, IconStaticOptions } from '../../../../../../common/descriptor_types';
export function VectorStyleIconEditor(props) {
type IconEditorProps = Omit<Props<IconStaticOptions, IconDynamicOptions>, 'children'>;
export function VectorStyleIconEditor(props: IconEditorProps) {
const iconForm = props.styleProperty.isDynamic() ? (
<DynamicIconForm {...props} />
) : (

View file

@ -7,34 +7,95 @@
import _ from 'lodash';
import React, { Component, Fragment } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiSpacer, EuiButtonGroup, EuiFormRow, EuiSwitch, EuiSwitchEvent } from '@elastic/eui';
import { VectorStyleColorEditor } from './color/vector_style_color_editor';
import { VectorStyleSizeEditor } from './size/vector_style_size_editor';
// @ts-expect-error
import { VectorStyleSymbolizeAsEditor } from './symbol/vector_style_symbolize_as_editor';
import { VectorStyleIconEditor } from './symbol/vector_style_icon_editor';
import { VectorStyleLabelEditor } from './label/vector_style_label_editor';
// @ts-expect-error
import { VectorStyleLabelBorderSizeEditor } from './label/vector_style_label_border_size_editor';
// @ts-expect-error
import { OrientationEditor } from './orientation/orientation_editor';
import { getDefaultDynamicProperties, getDefaultStaticProperties } from '../vector_style_defaults';
import { DEFAULT_FILL_COLORS, DEFAULT_LINE_COLORS } from '../../color_palettes';
import { i18n } from '@kbn/i18n';
import { EuiSpacer, EuiButtonGroup, EuiFormRow, EuiSwitch } from '@elastic/eui';
import {
LABEL_BORDER_SIZES,
VECTOR_STYLES,
STYLE_TYPE,
VECTOR_SHAPE_TYPE,
} from '../../../../../common/constants';
import { createStyleFieldsHelper } from '../style_fields_helper';
import { createStyleFieldsHelper, StyleField, StyleFieldsHelper } from '../style_fields_helper';
import {
ColorDynamicOptions,
ColorStaticOptions,
DynamicStylePropertyOptions,
IconDynamicOptions,
IconStaticOptions,
LabelDynamicOptions,
LabelStaticOptions,
SizeDynamicOptions,
SizeStaticOptions,
StaticStylePropertyOptions,
StylePropertyOptions,
VectorStylePropertiesDescriptor,
} from '../../../../../common/descriptor_types';
import { IStyleProperty } from '../properties/style_property';
import { SymbolizeAsProperty } from '../properties/symbolize_as_property';
import { LabelBorderSizeProperty } from '../properties/label_border_size_property';
import { StaticTextProperty } from '../properties/static_text_property';
import { StaticSizeProperty } from '../properties/static_size_property';
import { IVectorLayer } from '../../../layers/vector_layer/vector_layer';
export class VectorStyleEditor extends Component {
state = {
styleFields: [],
defaultDynamicProperties: getDefaultDynamicProperties(),
defaultStaticProperties: getDefaultStaticProperties(),
supportedFeatures: undefined,
selectedFeature: null,
};
export interface StyleProperties {
[key: string]: IStyleProperty<StylePropertyOptions>;
}
interface Props {
layer: IVectorLayer;
isPointsOnly: boolean;
isLinesOnly: boolean;
onIsTimeAwareChange: (isTimeAware: boolean) => void;
handlePropertyChange: (propertyName: VECTOR_STYLES, stylePropertyDescriptor: unknown) => void;
hasBorder: boolean;
styleProperties: StyleProperties;
isTimeAware: boolean;
showIsTimeAware: boolean;
}
interface State {
styleFields: StyleField[];
defaultDynamicProperties: VectorStylePropertiesDescriptor;
defaultStaticProperties: VectorStylePropertiesDescriptor;
supportedFeatures: VECTOR_SHAPE_TYPE[];
selectedFeature: VECTOR_SHAPE_TYPE;
styleFieldsHelper?: StyleFieldsHelper;
}
export class VectorStyleEditor extends Component<Props, State> {
private _isMounted: boolean = false;
constructor(props: Props) {
super(props);
let selectedFeature = VECTOR_SHAPE_TYPE.POLYGON;
if (props.isPointsOnly) {
selectedFeature = VECTOR_SHAPE_TYPE.POINT;
} else if (props.isLinesOnly) {
selectedFeature = VECTOR_SHAPE_TYPE.LINE;
}
this.state = {
styleFields: [],
defaultDynamicProperties: getDefaultDynamicProperties(),
defaultStaticProperties: getDefaultStaticProperties(),
supportedFeatures: [],
selectedFeature,
};
}
componentWillUnmount() {
this._isMounted = false;
@ -68,36 +129,20 @@ export class VectorStyleEditor extends Component {
async _loadSupportedFeatures() {
const supportedFeatures = await this.props.layer.getSource().getSupportedShapeTypes();
if (!this._isMounted) {
return;
}
if (!_.isEqual(supportedFeatures, this.state.supportedFeatures)) {
if (this._isMounted && !_.isEqual(supportedFeatures, this.state.supportedFeatures)) {
this.setState({ supportedFeatures });
}
if (this.state.selectedFeature === null) {
let selectedFeature = VECTOR_SHAPE_TYPE.POLYGON;
if (this.props.isPointsOnly) {
selectedFeature = VECTOR_SHAPE_TYPE.POINT;
} else if (this.props.isLinesOnly) {
selectedFeature = VECTOR_SHAPE_TYPE.LINE;
}
this.setState({
selectedFeature: selectedFeature,
});
}
}
_handleSelectedFeatureChange = (selectedFeature) => {
this.setState({ selectedFeature });
_handleSelectedFeatureChange = (selectedFeature: string) => {
this.setState({ selectedFeature: selectedFeature as VECTOR_SHAPE_TYPE });
};
_onIsTimeAwareChange = (event) => {
_onIsTimeAwareChange = (event: EuiSwitchEvent) => {
this.props.onIsTimeAwareChange(event.target.checked);
};
_onStaticStyleChange = (propertyName, options) => {
_onStaticStyleChange = (propertyName: VECTOR_STYLES, options: StaticStylePropertyOptions) => {
const styleDescriptor = {
type: STYLE_TYPE.STATIC,
options,
@ -105,7 +150,7 @@ export class VectorStyleEditor extends Component {
this.props.handlePropertyChange(propertyName, styleDescriptor);
};
_onDynamicStyleChange = (propertyName, options) => {
_onDynamicStyleChange = (propertyName: VECTOR_STYLES, options: DynamicStylePropertyOptions) => {
const styleDescriptor = {
type: STYLE_TYPE.DYNAMIC,
options,
@ -115,18 +160,21 @@ export class VectorStyleEditor extends Component {
_hasMarkerOrIcon() {
const iconSize = this.props.styleProperties[VECTOR_STYLES.ICON_SIZE];
return iconSize.isDynamic() || iconSize.getOptions().size > 0;
return iconSize.isDynamic() || (iconSize as StaticSizeProperty).getOptions().size > 0;
}
_hasLabel() {
const label = this.props.styleProperties[VECTOR_STYLES.LABEL_TEXT];
return label.isDynamic()
? label.isComplete()
: label.getOptions().value != null && label.getOptions().value.length;
: (label as StaticTextProperty).getOptions().value != null &&
(label as StaticTextProperty).getOptions().value.length;
}
_hasLabelBorder() {
const labelBorderSize = this.props.styleProperties[VECTOR_STYLES.LABEL_BORDER_SIZE];
const labelBorderSize = this.props.styleProperties[
VECTOR_STYLES.LABEL_BORDER_SIZE
] as LabelBorderSizeProperty;
return labelBorderSize.getOptions().size !== LABEL_BORDER_SIZES.NONE;
}
@ -138,13 +186,18 @@ export class VectorStyleEditor extends Component {
swatches={DEFAULT_FILL_COLORS}
onStaticStyleChange={this._onStaticStyleChange}
onDynamicStyleChange={this._onDynamicStyleChange}
styleProperty={this.props.styleProperties[VECTOR_STYLES.FILL_COLOR]}
fields={this.state.styleFieldsHelper.getFieldsForStyle(VECTOR_STYLES.FILL_COLOR)}
styleProperty={
this.props.styleProperties[VECTOR_STYLES.FILL_COLOR] as IStyleProperty<
ColorDynamicOptions | ColorStaticOptions
>
}
fields={this.state.styleFieldsHelper!.getFieldsForStyle(VECTOR_STYLES.FILL_COLOR)}
defaultStaticStyleOptions={
this.state.defaultStaticProperties[VECTOR_STYLES.FILL_COLOR].options
this.state.defaultStaticProperties[VECTOR_STYLES.FILL_COLOR].options as ColorStaticOptions
}
defaultDynamicStyleOptions={
this.state.defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR].options
this.state.defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR]
.options as ColorDynamicOptions
}
/>
);
@ -159,13 +212,18 @@ export class VectorStyleEditor extends Component {
swatches={DEFAULT_LINE_COLORS}
onStaticStyleChange={this._onStaticStyleChange}
onDynamicStyleChange={this._onDynamicStyleChange}
styleProperty={this.props.styleProperties[VECTOR_STYLES.LINE_COLOR]}
fields={this.state.styleFieldsHelper.getFieldsForStyle(VECTOR_STYLES.LINE_COLOR)}
styleProperty={
this.props.styleProperties[VECTOR_STYLES.LINE_COLOR] as IStyleProperty<
ColorDynamicOptions | ColorStaticOptions
>
}
fields={this.state.styleFieldsHelper!.getFieldsForStyle(VECTOR_STYLES.LINE_COLOR)}
defaultStaticStyleOptions={
this.state.defaultStaticProperties[VECTOR_STYLES.LINE_COLOR].options
this.state.defaultStaticProperties[VECTOR_STYLES.LINE_COLOR].options as ColorStaticOptions
}
defaultDynamicStyleOptions={
this.state.defaultDynamicProperties[VECTOR_STYLES.LINE_COLOR].options
this.state.defaultDynamicProperties[VECTOR_STYLES.LINE_COLOR]
.options as ColorDynamicOptions
}
/>
);
@ -178,13 +236,18 @@ export class VectorStyleEditor extends Component {
disabledBy={VECTOR_STYLES.ICON_SIZE}
onStaticStyleChange={this._onStaticStyleChange}
onDynamicStyleChange={this._onDynamicStyleChange}
styleProperty={this.props.styleProperties[VECTOR_STYLES.LINE_WIDTH]}
fields={this.state.styleFieldsHelper.getFieldsForStyle(VECTOR_STYLES.LINE_WIDTH)}
styleProperty={
this.props.styleProperties[VECTOR_STYLES.LINE_WIDTH] as IStyleProperty<
SizeDynamicOptions | SizeStaticOptions
>
}
fields={this.state.styleFieldsHelper!.getFieldsForStyle(VECTOR_STYLES.LINE_WIDTH)}
defaultStaticStyleOptions={
this.state.defaultStaticProperties[VECTOR_STYLES.LINE_WIDTH].options
this.state.defaultStaticProperties[VECTOR_STYLES.LINE_WIDTH].options as SizeStaticOptions
}
defaultDynamicStyleOptions={
this.state.defaultDynamicProperties[VECTOR_STYLES.LINE_WIDTH].options
this.state.defaultDynamicProperties[VECTOR_STYLES.LINE_WIDTH]
.options as SizeDynamicOptions
}
/>
);
@ -198,13 +261,19 @@ export class VectorStyleEditor extends Component {
<VectorStyleLabelEditor
onStaticStyleChange={this._onStaticStyleChange}
onDynamicStyleChange={this._onDynamicStyleChange}
styleProperty={this.props.styleProperties[VECTOR_STYLES.LABEL_TEXT]}
fields={this.state.styleFieldsHelper.getFieldsForStyle(VECTOR_STYLES.LABEL_TEXT)}
styleProperty={
this.props.styleProperties[VECTOR_STYLES.LABEL_TEXT] as IStyleProperty<
LabelDynamicOptions | LabelStaticOptions
>
}
fields={this.state.styleFieldsHelper!.getFieldsForStyle(VECTOR_STYLES.LABEL_TEXT)}
defaultStaticStyleOptions={
this.state.defaultStaticProperties[VECTOR_STYLES.LABEL_TEXT].options
this.state.defaultStaticProperties[VECTOR_STYLES.LABEL_TEXT]
.options as LabelStaticOptions
}
defaultDynamicStyleOptions={
this.state.defaultDynamicProperties[VECTOR_STYLES.LABEL_TEXT].options
this.state.defaultDynamicProperties[VECTOR_STYLES.LABEL_TEXT]
.options as LabelDynamicOptions
}
/>
<EuiSpacer size="m" />
@ -215,13 +284,19 @@ export class VectorStyleEditor extends Component {
swatches={DEFAULT_LINE_COLORS}
onStaticStyleChange={this._onStaticStyleChange}
onDynamicStyleChange={this._onDynamicStyleChange}
styleProperty={this.props.styleProperties[VECTOR_STYLES.LABEL_COLOR]}
fields={this.state.styleFieldsHelper.getFieldsForStyle(VECTOR_STYLES.LABEL_COLOR)}
styleProperty={
this.props.styleProperties[VECTOR_STYLES.LABEL_COLOR] as IStyleProperty<
ColorDynamicOptions | ColorStaticOptions
>
}
fields={this.state.styleFieldsHelper!.getFieldsForStyle(VECTOR_STYLES.LABEL_COLOR)}
defaultStaticStyleOptions={
this.state.defaultStaticProperties[VECTOR_STYLES.LABEL_COLOR].options
this.state.defaultStaticProperties[VECTOR_STYLES.LABEL_COLOR]
.options as ColorStaticOptions
}
defaultDynamicStyleOptions={
this.state.defaultDynamicProperties[VECTOR_STYLES.LABEL_COLOR].options
this.state.defaultDynamicProperties[VECTOR_STYLES.LABEL_COLOR]
.options as ColorDynamicOptions
}
/>
<EuiSpacer size="m" />
@ -231,13 +306,19 @@ export class VectorStyleEditor extends Component {
disabledBy={VECTOR_STYLES.LABEL_TEXT}
onStaticStyleChange={this._onStaticStyleChange}
onDynamicStyleChange={this._onDynamicStyleChange}
styleProperty={this.props.styleProperties[VECTOR_STYLES.LABEL_SIZE]}
fields={this.state.styleFieldsHelper.getFieldsForStyle(VECTOR_STYLES.LABEL_SIZE)}
styleProperty={
this.props.styleProperties[VECTOR_STYLES.LABEL_SIZE] as IStyleProperty<
SizeDynamicOptions | SizeStaticOptions
>
}
fields={this.state.styleFieldsHelper!.getFieldsForStyle(VECTOR_STYLES.LABEL_SIZE)}
defaultStaticStyleOptions={
this.state.defaultStaticProperties[VECTOR_STYLES.LABEL_SIZE].options
this.state.defaultStaticProperties[VECTOR_STYLES.LABEL_SIZE]
.options as SizeStaticOptions
}
defaultDynamicStyleOptions={
this.state.defaultDynamicProperties[VECTOR_STYLES.LABEL_SIZE].options
this.state.defaultDynamicProperties[VECTOR_STYLES.LABEL_SIZE]
.options as SizeDynamicOptions
}
/>
<EuiSpacer size="m" />
@ -248,13 +329,19 @@ export class VectorStyleEditor extends Component {
swatches={DEFAULT_LINE_COLORS}
onStaticStyleChange={this._onStaticStyleChange}
onDynamicStyleChange={this._onDynamicStyleChange}
styleProperty={this.props.styleProperties[VECTOR_STYLES.LABEL_BORDER_COLOR]}
fields={this.state.styleFieldsHelper.getFieldsForStyle(VECTOR_STYLES.LABEL_BORDER_COLOR)}
styleProperty={
this.props.styleProperties[VECTOR_STYLES.LABEL_BORDER_COLOR] as IStyleProperty<
ColorDynamicOptions | ColorStaticOptions
>
}
fields={this.state.styleFieldsHelper!.getFieldsForStyle(VECTOR_STYLES.LABEL_BORDER_COLOR)}
defaultStaticStyleOptions={
this.state.defaultStaticProperties[VECTOR_STYLES.LABEL_BORDER_COLOR].options
this.state.defaultStaticProperties[VECTOR_STYLES.LABEL_BORDER_COLOR]
.options as ColorStaticOptions
}
defaultDynamicStyleOptions={
this.state.defaultDynamicProperties[VECTOR_STYLES.LABEL_BORDER_COLOR].options
this.state.defaultDynamicProperties[VECTOR_STYLES.LABEL_BORDER_COLOR]
.options as ColorDynamicOptions
}
/>
<EuiSpacer size="m" />
@ -274,7 +361,11 @@ export class VectorStyleEditor extends Component {
const hasMarkerOrIcon = this._hasMarkerOrIcon();
let iconOrientationEditor;
let iconEditor;
if (this.props.styleProperties[VECTOR_STYLES.SYMBOLIZE_AS].isSymbolizedAsIcon()) {
if (
(this.props.styleProperties[
VECTOR_STYLES.SYMBOLIZE_AS
] as SymbolizeAsProperty).isSymbolizedAsIcon()
) {
iconOrientationEditor = (
<Fragment>
<OrientationEditor
@ -283,7 +374,7 @@ export class VectorStyleEditor extends Component {
onStaticStyleChange={this._onStaticStyleChange}
onDynamicStyleChange={this._onDynamicStyleChange}
styleProperty={this.props.styleProperties[VECTOR_STYLES.ICON_ORIENTATION]}
fields={this.state.styleFieldsHelper.getFieldsForStyle(VECTOR_STYLES.ICON_ORIENTATION)}
fields={this.state.styleFieldsHelper!.getFieldsForStyle(VECTOR_STYLES.ICON_ORIENTATION)}
defaultStaticStyleOptions={
this.state.defaultStaticProperties[VECTOR_STYLES.ICON_ORIENTATION].options
}
@ -301,13 +392,17 @@ export class VectorStyleEditor extends Component {
disabledBy={VECTOR_STYLES.ICON_SIZE}
onStaticStyleChange={this._onStaticStyleChange}
onDynamicStyleChange={this._onDynamicStyleChange}
styleProperty={this.props.styleProperties[VECTOR_STYLES.ICON]}
fields={this.state.styleFieldsHelper.getFieldsForStyle(VECTOR_STYLES.ICON)}
styleProperty={
this.props.styleProperties[VECTOR_STYLES.ICON] as IStyleProperty<
IconDynamicOptions | IconStaticOptions
>
}
fields={this.state.styleFieldsHelper!.getFieldsForStyle(VECTOR_STYLES.ICON)}
defaultStaticStyleOptions={
this.state.defaultStaticProperties[VECTOR_STYLES.ICON].options
this.state.defaultStaticProperties[VECTOR_STYLES.ICON].options as IconStaticOptions
}
defaultDynamicStyleOptions={
this.state.defaultDynamicProperties[VECTOR_STYLES.ICON].options
this.state.defaultDynamicProperties[VECTOR_STYLES.ICON].options as IconDynamicOptions
}
/>
<EuiSpacer size="m" />
@ -341,13 +436,18 @@ export class VectorStyleEditor extends Component {
<VectorStyleSizeEditor
onStaticStyleChange={this._onStaticStyleChange}
onDynamicStyleChange={this._onDynamicStyleChange}
styleProperty={this.props.styleProperties[VECTOR_STYLES.ICON_SIZE]}
fields={this.state.styleFieldsHelper.getFieldsForStyle(VECTOR_STYLES.ICON_SIZE)}
styleProperty={
this.props.styleProperties[VECTOR_STYLES.ICON_SIZE] as IStyleProperty<
SizeDynamicOptions | SizeStaticOptions
>
}
fields={this.state.styleFieldsHelper!.getFieldsForStyle(VECTOR_STYLES.ICON_SIZE)}
defaultStaticStyleOptions={
this.state.defaultStaticProperties[VECTOR_STYLES.ICON_SIZE].options
this.state.defaultStaticProperties[VECTOR_STYLES.ICON_SIZE].options as SizeStaticOptions
}
defaultDynamicStyleOptions={
this.state.defaultDynamicProperties[VECTOR_STYLES.ICON_SIZE].options
this.state.defaultDynamicProperties[VECTOR_STYLES.ICON_SIZE]
.options as SizeDynamicOptions
}
/>
<EuiSpacer size="m" />
@ -385,7 +485,7 @@ export class VectorStyleEditor extends Component {
_renderProperties() {
const { supportedFeatures, selectedFeature, styleFieldsHelper } = this.state;
if (!supportedFeatures || !styleFieldsHelper) {
if (supportedFeatures.length === 0 || !styleFieldsHelper) {
return null;
}

View file

@ -34,7 +34,7 @@ export async function createStyleFieldsHelper(fields: IField[]): Promise<StyleFi
return new StyleFieldsHelper(styleFields);
}
class StyleFieldsHelper {
export class StyleFieldsHelper {
private readonly _styleFields: StyleField[];
private readonly _ordinalAndCategoricalFields: StyleField[];
private readonly _numberFields: StyleField[];

View file

@ -8,14 +8,8 @@ import _ from 'lodash';
import React, { ReactElement } from 'react';
import { Map as MbMap, FeatureIdentifier } from 'mapbox-gl';
import { FeatureCollection } from 'geojson';
// @ts-expect-error
import { VectorStyleEditor } from './components/vector_style_editor';
import {
getDefaultProperties,
getDefaultStaticProperties,
LINE_STYLES,
POLYGON_STYLES,
} from './vector_style_defaults';
import { StyleProperties, VectorStyleEditor } from './components/vector_style_editor';
import { getDefaultStaticProperties, LINE_STYLES, POLYGON_STYLES } from './vector_style_defaults';
import {
GEO_JSON_TYPE,
FIELD_ORIGIN,
@ -76,7 +70,6 @@ import { IDynamicStyleProperty } from './properties/dynamic_style_property';
import { IField } from '../../fields/field';
import { IVectorLayer } from '../../layers/vector_layer/vector_layer';
import { IVectorSource } from '../../sources/vector_source';
import { ILayer } from '../../layers/layer';
import { createStyleFieldsHelper } from './style_fields_helper';
const POINTS = [GEO_JSON_TYPE.POINT, GEO_JSON_TYPE.MULTI_POINT];
@ -163,16 +156,19 @@ export class VectorStyle implements IVectorStyle {
private readonly _labelBorderColorStyleProperty: StaticColorProperty | DynamicColorProperty;
private readonly _labelBorderSizeStyleProperty: LabelBorderSizeProperty;
static createDescriptor(properties = {}, isTimeAware = true) {
static createDescriptor(
properties: Partial<VectorStylePropertiesDescriptor> = {},
isTimeAware = true
) {
return {
type: LAYER_STYLE_TYPE.VECTOR,
properties: { ...getDefaultProperties(), ...properties },
properties: { ...getDefaultStaticProperties(), ...properties },
isTimeAware,
};
}
static createDefaultStyleProperties(mapColors: string[]) {
return getDefaultProperties(mapColors);
return getDefaultStaticProperties(mapColors);
}
constructor(
@ -192,7 +188,7 @@ export class VectorStyle implements IVectorStyle {
this._styleMeta = new StyleMeta(this._descriptor.__styleMeta);
this._symbolizeAsStyleProperty = new SymbolizeAsProperty(
this._descriptor.properties[VECTOR_STYLES.SYMBOLIZE_AS]!.options,
this._descriptor.properties[VECTOR_STYLES.SYMBOLIZE_AS].options,
VECTOR_STYLES.SYMBOLIZE_AS
);
this._lineColorStyleProperty = this._makeColorProperty(
@ -237,7 +233,7 @@ export class VectorStyle implements IVectorStyle {
VECTOR_STYLES.LABEL_BORDER_COLOR
);
this._labelBorderSizeStyleProperty = new LabelBorderSizeProperty(
this._descriptor.properties[VECTOR_STYLES.LABEL_BORDER_SIZE]!.options,
this._descriptor.properties[VECTOR_STYLES.LABEL_BORDER_SIZE].options,
VECTOR_STYLES.LABEL_BORDER_SIZE,
this._labelSizeStyleProperty
);
@ -270,16 +266,10 @@ export class VectorStyle implements IVectorStyle {
: (this._lineWidthStyleProperty as StaticSizeProperty).getOptions().size !== 0;
}
renderEditor({
layer,
onStyleDescriptorChange,
}: {
layer: ILayer;
onStyleDescriptorChange: (styleDescriptor: StyleDescriptor) => void;
}) {
renderEditor(onStyleDescriptorChange: (styleDescriptor: StyleDescriptor) => void) {
const rawProperties = this.getRawProperties();
const handlePropertyChange = (propertyName: VECTOR_STYLES, settings: any) => {
rawProperties[propertyName] = settings; // override single property, but preserve the rest
const handlePropertyChange = (propertyName: VECTOR_STYLES, stylePropertyDescriptor: any) => {
rawProperties[propertyName] = stylePropertyDescriptor; // override single property, but preserve the rest
const vectorStyleDescriptor = VectorStyle.createDescriptor(rawProperties, this.isTimeAware());
onStyleDescriptorChange(vectorStyleDescriptor);
};
@ -293,9 +283,8 @@ export class VectorStyle implements IVectorStyle {
return dynamicStyleProp.isFieldMetaEnabled();
});
const styleProperties: VectorStylePropertiesDescriptor = {};
const styleProperties: StyleProperties = {};
this.getAllStyleProperties().forEach((styleProperty) => {
// @ts-expect-error
styleProperties[styleProperty.getStyleName()] = styleProperty;
});
@ -303,7 +292,7 @@ export class VectorStyle implements IVectorStyle {
<VectorStyleEditor
handlePropertyChange={handlePropertyChange}
styleProperties={styleProperties}
layer={layer}
layer={this._layer}
isPointsOnly={this._getIsPointsOnly()}
isLinesOnly={this._getIsLinesOnly()}
onIsTimeAwareChange={onIsTimeAwareChange}
@ -376,7 +365,7 @@ export class VectorStyle implements IVectorStyle {
updatedProperties[key] = {
type: DynamicStyleProperty.type,
options: {
...originalProperties[key]!.options,
...originalProperties[key].options,
},
} as any;
// @ts-expect-error

View file

@ -18,13 +18,13 @@ import { getDefaultStaticProperties } from './vector_style_defaults';
describe('getDefaultStaticProperties', () => {
test('Should use first color in DEFAULT_*_COLORS when no colors are used on the map', () => {
const styleProperties = getDefaultStaticProperties([]);
expect(styleProperties[VECTOR_STYLES.FILL_COLOR]!.options.color).toBe('#54B399');
expect(styleProperties[VECTOR_STYLES.LINE_COLOR]!.options.color).toBe('#41937c');
expect(styleProperties[VECTOR_STYLES.FILL_COLOR].options.color).toBe('#54B399');
expect(styleProperties[VECTOR_STYLES.LINE_COLOR].options.color).toBe('#41937c');
});
test('Should next color in DEFAULT_*_COLORS when colors are used on the map', () => {
const styleProperties = getDefaultStaticProperties(['#54B399']);
expect(styleProperties[VECTOR_STYLES.FILL_COLOR]!.options.color).toBe('#6092C0');
expect(styleProperties[VECTOR_STYLES.LINE_COLOR]!.options.color).toBe('#4379aa');
expect(styleProperties[VECTOR_STYLES.FILL_COLOR].options.color).toBe('#6092C0');
expect(styleProperties[VECTOR_STYLES.LINE_COLOR].options.color).toBe('#4379aa');
});
});

View file

@ -37,22 +37,6 @@ export const POLYGON_STYLES = [
VECTOR_STYLES.LINE_WIDTH,
];
export function getDefaultProperties(mapColors: string[] = []): VectorStylePropertiesDescriptor {
return {
...getDefaultStaticProperties(mapColors),
[VECTOR_STYLES.SYMBOLIZE_AS]: {
options: {
value: SYMBOLIZE_AS_TYPES.CIRCLE,
},
},
[VECTOR_STYLES.LABEL_BORDER_SIZE]: {
options: {
size: LABEL_BORDER_SIZES.SMALL,
},
},
};
}
export function getDefaultStaticProperties(
mapColors: string[] = []
): VectorStylePropertiesDescriptor {
@ -129,6 +113,16 @@ export function getDefaultStaticProperties(
color: isDarkMode ? '#000000' : '#FFFFFF',
},
},
[VECTOR_STYLES.SYMBOLIZE_AS]: {
options: {
value: SYMBOLIZE_AS_TYPES.CIRCLE,
},
},
[VECTOR_STYLES.LABEL_BORDER_SIZE]: {
options: {
size: LABEL_BORDER_SIZES.SMALL,
},
},
};
}
@ -244,5 +238,15 @@ export function getDefaultDynamicProperties(): VectorStylePropertiesDescriptor {
},
},
},
[VECTOR_STYLES.SYMBOLIZE_AS]: {
options: {
value: SYMBOLIZE_AS_TYPES.CIRCLE,
},
},
[VECTOR_STYLES.LABEL_BORDER_SIZE]: {
options: {
size: LABEL_BORDER_SIZES.SMALL,
},
},
};
}

View file

@ -11,9 +11,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiPanel, EuiSpacer } from '@elast
import { FormattedMessage } from '@kbn/i18n/react';
export function StyleSettings({ layer, updateStyleDescriptor }) {
const settingsEditor = layer.renderStyleEditor({
onStyleDescriptorChange: updateStyleDescriptor,
});
const settingsEditor = layer.renderStyleEditor(updateStyleDescriptor);
if (!settingsEditor) {
return null;