diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js index bf57306df5697d..eadaf42ca694da 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js @@ -99,6 +99,7 @@ export class ColorMapSelect extends Component { ); } else @@ -108,6 +109,7 @@ export class ColorMapSelect extends Component { field={this.props.styleProperty.getField()} getValueSuggestions={this.props.styleProperty.getValueSuggestions} onChange={this._onCustomColorMapChange} + swatches={this.props.swatches} /> ); diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops.js index 059543d705fc73..20fd97a229352c 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops.js @@ -8,61 +8,8 @@ import _ from 'lodash'; import React from 'react'; import { removeRow, isColorInvalid } from './color_stops_utils'; import { i18n } from '@kbn/i18n'; -import { EuiButtonIcon, EuiColorPicker, EuiFlexGroup, EuiFlexItem, EuiFormRow } from '@elastic/eui'; - -function getColorStopRow({ index, errors, stopInput, onColorChange, color, deleteButton, onAdd }) { - const colorPickerButtons = ( -
- {deleteButton} - -
- ); - return ( - - - - {stopInput} - - - - - - - ); -} - -export function getDeleteButton(onRemove) { - return ( - - ); -} +import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiFormRow } from '@elastic/eui'; +import { MbValidatedColorPicker } from './mb_validated_color_picker'; export const ColorStops = ({ onChange, @@ -72,6 +19,7 @@ export const ColorStops = ({ renderStopInput, addNewRow, canDeleteStop, + swatches, }) => { function getStopInput(stop, index) { const onStopChange = newStopValue => { @@ -134,10 +82,56 @@ export const ColorStops = ({ isInvalid: isStopsInvalid(newColorStops), }); }; - deleteButton = getDeleteButton(onRemove); + deleteButton = ( + + ); } - return getColorStopRow({ index, errors, stopInput, onColorChange, color, deleteButton, onAdd }); + const colorPickerButtons = ( +
+ {deleteButton} + +
+ ); + return ( + + + + {stopInput} + + + + + + + ); }); return
{rows}
; diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops_categorical.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops_categorical.js index edf230b0a945c0..0656173e5c4113 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops_categorical.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops_categorical.js @@ -27,6 +27,7 @@ export const ColorStopsCategorical = ({ field, onChange, getValueSuggestions, + swatches, }) => { const getStopError = (stop, index) => { let count = 0; @@ -81,6 +82,7 @@ export const ColorStopsCategorical = ({ renderStopInput={renderStopInput} canDeleteStop={canDeleteStop} addNewRow={addCategoricalRow} + swatches={swatches} /> ); }; diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops_ordinal.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops_ordinal.js index 0f6a0583d3dbcc..4e2d07b9dfea02 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops_ordinal.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops_ordinal.js @@ -20,6 +20,7 @@ import { i18n } from '@kbn/i18n'; export const ColorStopsOrdinal = ({ colorStops = [{ stop: 0, color: DEFAULT_CUSTOM_COLOR }], onChange, + swatches, }) => { const getStopError = (stop, index) => { let error; @@ -69,6 +70,7 @@ export const ColorStopsOrdinal = ({ renderStopInput={renderStopInput} canDeleteStop={canDeleteStop} addNewRow={addOrdinalRow} + swatches={swatches} /> ); }; diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/dynamic_color_form.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/dynamic_color_form.js index 5e8f720fcc5e35..460e7379920c46 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/dynamic_color_form.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/dynamic_color_form.js @@ -18,6 +18,7 @@ export function DynamicColorForm({ onDynamicStyleChange, staticDynamicSelect, styleProperty, + swatches, }) { const styleOptions = styleProperty.getOptions(); @@ -101,6 +102,7 @@ export function DynamicColorForm({ useCustomColorMap={_.get(styleOptions, 'useCustomColorRamp', false)} styleProperty={styleProperty} showColorMapTypeToggle={showColorMapTypeToggle} + swatches={swatches} /> ); } else if (styleProperty.isCategorical()) { @@ -118,6 +120,7 @@ export function DynamicColorForm({ useCustomColorMap={_.get(styleOptions, 'useCustomColorPalette', false)} styleProperty={styleProperty} showColorMapTypeToggle={showColorMapTypeToggle} + swatches={swatches} /> ); } diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/mb_validated_color_picker.tsx b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/mb_validated_color_picker.tsx new file mode 100644 index 00000000000000..b4fad6690b9ac8 --- /dev/null +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/mb_validated_color_picker.tsx @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { Component } from 'react'; +import { isValidHex, EuiColorPicker, EuiFormControlLayoutProps } from '@elastic/eui'; + +export const RGBA_0000 = 'rgba(0,0,0,0)'; + +interface Props { + onChange: (color: string) => void; + color: string; + swatches?: string[]; + append?: EuiFormControlLayoutProps['append']; +} + +interface State { + colorInputValue: string; +} + +// EuiColorPicker treats '' or invalid colors as transparent. +// Mapbox logs errors for '' or invalid colors. +// MbValidatedColorPicker is a wrapper around EuiColorPicker that reconciles the behavior difference +// between the two by returning a Mapbox safe RGBA_0000 for '' or invalid colors +// while keeping invalid state local so EuiColorPicker's input properly handles text input. +export class MbValidatedColorPicker extends Component { + state = { + colorInputValue: this.props.color === RGBA_0000 ? '' : this.props.color, + }; + + _onColorChange = (color: string) => { + // reflect all user input, whether valid or not + this.setState({ colorInputValue: color }); + // Only surface mapbox valid input to caller + this.props.onChange(isValidHex(color) ? color : RGBA_0000); + }; + + render() { + return ( + + ); + } +} diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/static_color_form.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/static_color_form.js index ab1634a53a966a..a295556ee3126d 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/static_color_form.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/static_color_form.js @@ -5,7 +5,8 @@ */ import React from 'react'; -import { EuiColorPicker, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { MbValidatedColorPicker } from './mb_validated_color_picker'; export function StaticColorForm({ onStaticStyleChange, @@ -23,11 +24,10 @@ export function StaticColorForm({ {staticDynamicSelect} - diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js index 146bc40aa8531b..e671f00b783819 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js @@ -18,11 +18,10 @@ import { EuiTextColor, } from '@elastic/eui'; import { Category } from '../components/legend/category'; -import { COLOR_MAP_TYPE } from '../../../../../common/constants'; +import { COLOR_MAP_TYPE, RGBA_0000 } from '../../../../../common/constants'; import { isCategoricalStopsInvalid } from '../components/color/color_stops_utils'; const EMPTY_STOPS = { stops: [], defaultColor: null }; -const RGBA_0000 = 'rgba(0,0,0,0)'; export class DynamicColorProperty extends DynamicStyleProperty { syncCircleColorWithMb(mbLayerId, mbMap, alpha) { diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index bd4406ef5ce634..f3997f741a1bfe 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -213,3 +213,5 @@ export enum SCALING_TYPES { CLUSTERS = 'CLUSTERS', TOP_HITS = 'TOP_HITS', } + +export const RGBA_0000 = 'rgba(0,0,0,0)';