[Lens] 7.9 design cleanup (#71444) (#71573)

* Fix dimension popover layout and color picker “Auto”

* Created ToolbarButton

* Move disabled help text to tooltip for missing values

* Darker side panel backgrounds

* Adding to .asciidoc about where to put the SASS import

* Moving `SASS` guidelines to STYLEGUIDE.md

* Fix keyboard focus of XY settings popover

* Fix dark mode
This commit is contained in:
Caroline Horn 2020-07-14 09:31:33 -04:00 committed by GitHub
parent d80ed1f9e9
commit f74340f6ab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 284 additions and 204 deletions

View file

@ -3,11 +3,18 @@
This guide applies to all development within the Kibana project and is
recommended for the development of all Kibana plugins.
- [General](#general)
- [HTML](#html)
- [API endpoints](#api-endpoints)
- [TypeScript/JavaScript](#typeScript/javaScript)
- [SASS files](#sass-files)
- [React](#react)
Besides the content in this style guide, the following style guides may also apply
to all development within the Kibana project. Please make sure to also read them:
- [Accessibility style guide](https://elastic.github.io/eui/#/guidelines/accessibility)
- [SASS style guide](https://elastic.github.io/eui/#/guidelines/sass)
- [Accessibility style guide (EUI Docs)](https://elastic.github.io/eui/#/guidelines/accessibility)
- [SASS style guide (EUI Docs)](https://elastic.github.io/eui/#/guidelines/sass)
## General
@ -582,6 +589,39 @@ Do not use setters, they cause more problems than they can solve.
[sideeffect]: http://en.wikipedia.org/wiki/Side_effect_(computer_science)
## SASS files
When writing a new component, create a sibling SASS file of the same name and import directly into the **top** of the JS/TS component file. Doing so ensures the styles are never separated or lost on import and allows for better modularization (smaller individual plugin asset footprint).
All SASS (.scss) files will automatically build with the [EUI](https://elastic.github.io/eui/#/guidelines/sass) & Kibana invisibles (SASS variables, mixins, functions) from the [`globals_[theme].scss` file](src/legacy/ui/public/styles/_globals_v7light.scss).
While the styles for this component will only be loaded if the component exists on the page,
the styles **will** be global and so it is recommended to use a three letter prefix on your
classes to ensure proper scope.
**Example:**
```tsx
// component.tsx
import './component.scss';
// All other imports below the SASS import
export const Component = () => {
return (
<div className="plgComponent" />
);
}
```
```scss
// component.scss
.plgComponent { ... }
```
Do not use the underscore `_` SASS file naming pattern when importing directly into a javascript file.
## React
The following style guide rules are specific for working with the React framework.

View file

@ -29,7 +29,7 @@ you can switch to the correct version when using nvm by running:
----
nvm use
----
Install the latest version of https://yarnpkg.com[yarn].
Bootstrap {kib} and install all the dependencies:
@ -93,13 +93,13 @@ yarn es snapshot --license trial
`trial` will give you access to all capabilities.
Read about more options for <<running-elasticsearch>>, like connecting to a remote host, running from source,
preserving data inbetween runs, running remote cluster, etc.
Read about more options for <<running-elasticsearch>>, like connecting to a remote host, running from source,
preserving data inbetween runs, running remote cluster, etc.
[float]
=== Run {kib}
In another terminal window, start up {kib}. Include developer examples by adding an optional `--run-examples` flag.
In another terminal window, start up {kib}. Include developer examples by adding an optional `--run-examples` flag.
[source,bash]
----
@ -125,8 +125,6 @@ cause the {kib} server to reboot.
* <<kibana-debugging>>
* <<kibana-sass>>
* <<building-kibana>>
* <<development-plugin-resources>>
@ -137,8 +135,6 @@ include::sample-data.asciidoc[]
include::debugging.asciidoc[]
include::sass.asciidoc[]
include::building-kibana.asciidoc[]
include::development-plugin-resources.asciidoc[]

View file

@ -1,36 +0,0 @@
[[kibana-sass]]
=== Styling with SASS
When writing a new component, create a sibling SASS file of the same
name and import directly into the JS/TS component file. Doing so ensures
the styles are never separated or lost on import and allows for better
modularization (smaller individual plugin asset footprint).
All SASS (.scss) files will automatically build with the
https://elastic.github.io/eui/#/guidelines/sass[EUI] & {kib} invisibles (SASS variables, mixins, functions) from
the {kib-repo}tree/{branch}/src/legacy/ui/public/styles/_globals_v7light.scss[globals_THEME.scss] file.
*Example:*
[source,tsx]
----
// component.tsx
import './component.scss';
export const Component = () => {
return (
<div className="plgComponent" />
);
}
----
[source,scss]
----
// component.scss
.plgComponent { ... }
----
Do not use the underscore `_` SASS file naming pattern when importing
directly into a javascript file.

View file

@ -1,6 +1,7 @@
.lnsDataPanelWrapper {
flex: 1 0 100%;
overflow: hidden;
background-color: lightOrDarkTheme($euiColorLightestShade, $euiColorInk);
}
.lnsDataPanelWrapper__switchSource {

View file

@ -22,7 +22,7 @@
// Leave out bottom padding so the suggestions scrollbar stays flush to window edge
// Leave out left padding so the left sidebar's focus states are visible outside of content bounds
// This also means needing to add same amount of margin to page content and suggestion items
padding: $euiSize $euiSize 0 0;
padding: $euiSize $euiSize 0;
&:first-child {
padding-left: $euiSize;
@ -40,9 +40,10 @@
.lnsFrameLayout__sidebar--right {
@include euiScrollBar;
min-width: $lnsPanelMinWidth + $euiSize;
background-color: lightOrDarkTheme($euiColorLightestShade, $euiColorInk);
min-width: $lnsPanelMinWidth + $euiSizeXL;
overflow-x: hidden;
overflow-y: scroll;
padding-top: $euiSize;
padding: $euiSize 0 $euiSize $euiSize;
max-height: 100%;
}

View file

@ -2,6 +2,10 @@
margin-bottom: $euiSizeS;
}
.lnsLayerPanel__sourceFlexItem {
max-width: calc(100% - #{$euiSize * 3.625});
}
.lnsLayerPanel__row {
background: $euiColorLightestShade;
padding: $euiSizeS;
@ -32,5 +36,6 @@
}
.lnsLayerPanel__styleEditor {
width: $euiSize * 28;
width: $euiSize * 30;
padding: $euiSizeS;
}

View file

@ -40,8 +40,7 @@ export function DimensionPopover({
}}
button={trigger}
anchorPosition="leftUp"
withTitle
panelPaddingSize="s"
panelPaddingSize="none"
>
{panel}
</EuiPopover>

View file

@ -103,7 +103,7 @@ export function LayerPanel(
</EuiFlexItem>
{layerDatasource && (
<EuiFlexItem className="eui-textTruncate">
<EuiFlexItem className="lnsLayerPanel__sourceFlexItem">
<NativeRenderer
render={layerDatasource.renderLayerPanel}
nativeProps={{
@ -170,18 +170,15 @@ export function LayerPanel(
defaultMessage: 'Quick functions',
}),
content: (
<>
<EuiSpacer size="s" />
<NativeRenderer
render={props.datasourceMap[datasourceId].renderDimensionEditor}
nativeProps={{
...layerDatasourceConfigProps,
core: props.core,
columnId: accessor,
filterOperations: group.filterOperations,
}}
/>
</>
<NativeRenderer
render={props.datasourceMap[datasourceId].renderDimensionEditor}
nativeProps={{
...layerDatasourceConfigProps,
core: props.core,
columnId: accessor,
filterOperations: group.filterOperations,
}}
/>
),
},
];
@ -194,7 +191,6 @@ export function LayerPanel(
}),
content: (
<div className="lnsLayerPanel__styleEditor">
<EuiSpacer size="s" />
<NativeRenderer
render={activeVisualization.renderDimensionEditor}
nativeProps={{

View file

@ -5,10 +5,11 @@
*/
import React, { useState } from 'react';
import { EuiPopover, EuiButtonIcon, EuiToolTip } from '@elastic/eui';
import { EuiPopover, EuiToolTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { NativeRenderer } from '../../../native_renderer';
import { Visualization, VisualizationLayerWidgetProps } from '../../../types';
import { ToolbarButton } from '../../../toolbar_button';
export function LayerSettings({
layerId,
@ -25,6 +26,10 @@ export function LayerSettings({
return null;
}
const a11yText = i18n.translate('xpack.lens.editLayerSettings', {
defaultMessage: 'Edit layer settings',
});
return (
<EuiPopover
id={`lnsLayerPopover_${layerId}`}
@ -36,11 +41,11 @@ export function LayerSettings({
defaultMessage: 'Edit layer settings',
})}
>
<EuiButtonIcon
<ToolbarButton
size="s"
iconType={activeVisualization.getLayerContextMenuIcon?.(layerConfigProps) || 'gear'}
aria-label={i18n.translate('xpack.lens.editLayerSettings', {
defaultMessage: 'Edit layer settings',
})}
aria-label={a11yText}
title={a11yText}
onClick={() => setIsOpen(!isOpen)}
data-test-subj="lns_layer_settings"
/>

View file

@ -5,15 +5,9 @@
}
}
.lnsChartSwitch__triggerButton {
@include euiTitle('xs');
background-color: $euiColorEmptyShade;
border-color: $euiColorLightShade;
}
.lnsChartSwitch__summaryIcon {
margin-right: $euiSizeS;
transform: translateY(-2px);
transform: translateY(-1px);
}
// Targeting img as this won't target normal EuiIcon's only the custom svgs's

View file

@ -4,6 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import './chart_switch.scss';
import React, { useState, useMemo } from 'react';
import {
EuiIcon,
@ -11,7 +12,6 @@ import {
EuiPopoverTitle,
EuiKeyPadMenu,
EuiKeyPadMenuItem,
EuiButton,
} from '@elastic/eui';
import { flatten } from 'lodash';
import { i18n } from '@kbn/i18n';
@ -19,6 +19,7 @@ import { Visualization, FramePublicAPI, Datasource } from '../../../types';
import { Action } from '../state_management';
import { getSuggestions, switchToSuggestion, Suggestion } from '../suggestion_helpers';
import { trackUiEvent } from '../../../lens_ui_telemetry';
import { ToolbarButton } from '../../../toolbar_button';
interface VisualizationSelection {
visualizationId: string;
@ -72,8 +73,6 @@ function VisualizationSummary(props: Props) {
);
}
import './chart_switch.scss';
export function ChartSwitch(props: Props) {
const [flyoutOpen, setFlyoutOpen] = useState<boolean>(false);
@ -202,16 +201,13 @@ export function ChartSwitch(props: Props) {
panelClassName="lnsChartSwitch__popoverPanel"
panelPaddingSize="s"
button={
<EuiButton
className="lnsChartSwitch__triggerButton"
<ToolbarButton
onClick={() => setFlyoutOpen(!flyoutOpen)}
data-test-subj="lnsChartSwitchPopover"
iconSide="right"
iconType="arrowDown"
color="text"
fontWeight="bold"
>
<VisualizationSummary {...props} />
</EuiButton>
</ToolbarButton>
}
isOpen={flyoutOpen}
closePopover={() => setFlyoutOpen(false)}

View file

@ -15,6 +15,7 @@ import {
EuiText,
EuiBetaBadge,
EuiButtonEmpty,
EuiLink,
} from '@elastic/eui';
import { CoreStart, CoreSetup } from 'kibana/public';
import {
@ -208,18 +209,20 @@ export function InnerWorkspacePanel({
/>{' '}
<EuiBetaBadge label="Beta" tooltipContent={tooltipContent} />
</p>
<EuiButtonEmpty
href="https://www.elastic.co/products/kibana/feedback"
iconType="popout"
iconSide="right"
size="xs"
target="_blank"
>
<FormattedMessage
id="xpack.lens.editorFrame.goToForums"
defaultMessage="Make requests and give feedback"
/>
</EuiButtonEmpty>
<p>
<small>
<EuiLink
href="https://www.elastic.co/products/kibana/feedback"
target="_blank"
external
>
<FormattedMessage
id="xpack.lens.editorFrame.goToForums"
defaultMessage="Make requests and give feedback"
/>
</EuiLink>
</small>
</p>
</EuiText>
</div>
);

View file

@ -6,18 +6,13 @@
import { i18n } from '@kbn/i18n';
import React, { useState } from 'react';
import {
EuiButtonEmpty,
EuiPopover,
EuiPopoverTitle,
EuiSelectable,
EuiButtonEmptyProps,
} from '@elastic/eui';
import { EuiPopover, EuiPopoverTitle, EuiSelectable } from '@elastic/eui';
import { EuiSelectableProps } from '@elastic/eui/src/components/selectable/selectable';
import { IndexPatternRef } from './types';
import { trackUiEvent } from '../lens_ui_telemetry';
import { ToolbarButtonProps, ToolbarButton } from '../toolbar_button';
export type ChangeIndexPatternTriggerProps = EuiButtonEmptyProps & {
export type ChangeIndexPatternTriggerProps = ToolbarButtonProps & {
label: string;
title?: string;
};
@ -40,29 +35,24 @@ export function ChangeIndexPattern({
const createTrigger = function () {
const { label, title, ...rest } = trigger;
return (
<EuiButtonEmpty
className="eui-textTruncate"
flush="left"
color="text"
iconSide="right"
iconType="arrowDown"
<ToolbarButton
title={title}
onClick={() => setPopoverIsOpen(!isPopoverOpen)}
fullWidth
{...rest}
>
{label}
</EuiButtonEmpty>
</ToolbarButton>
);
};
return (
<>
<EuiPopover
style={{ width: '100%' }}
button={createTrigger()}
isOpen={isPopoverOpen}
closePopover={() => setPopoverIsOpen(false)}
className="eui-textTruncate"
anchorClassName="eui-textTruncate"
display="block"
panelPaddingSize="s"
ownFocus

View file

@ -7,13 +7,7 @@
.lnsInnerIndexPatternDataPanel__header {
display: flex;
align-items: center;
height: $euiSize * 3;
margin-top: -$euiSizeS;
}
.lnsInnerIndexPatternDataPanel__triggerButton {
@include euiTitle('xs');
line-height: $euiSizeXXL;
margin-bottom: $euiSizeS;
}
/**

View file

@ -424,7 +424,7 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({
label: currentIndexPattern.title,
title: currentIndexPattern.title,
'data-test-subj': 'indexPattern-switch-link',
className: 'lnsInnerIndexPatternDataPanel__triggerButton',
fontWeight: 'bold',
}}
indexPatternId={currentIndexPatternId}
indexPatternRefs={indexPatternRefs}

View file

@ -1,7 +1,6 @@
.lnsIndexPatternDimensionEditor {
flex-grow: 1;
line-height: 0;
overflow: hidden;
width: $euiSize * 30;
padding: $euiSizeS;
}
.lnsIndexPatternDimensionEditor__left,
@ -11,10 +10,7 @@
.lnsIndexPatternDimensionEditor__left {
background-color: $euiPageBackgroundColor;
}
.lnsIndexPatternDimensionEditor__right {
width: $euiSize * 20;
width: $euiSize * 8;
}
.lnsIndexPatternDimensionEditor__operation > button {

View file

@ -299,25 +299,31 @@ export function PopoverEditor(props: PopoverEditorProps) {
</EuiFlexItem>
<EuiFlexItem grow={true} className="lnsIndexPatternDimensionEditor__right">
{incompatibleSelectedOperationType && selectedColumn && (
<EuiCallOut
data-test-subj="indexPattern-invalid-operation"
title={i18n.translate('xpack.lens.indexPattern.invalidOperationLabel', {
defaultMessage: 'To use this function, select a different field.',
})}
color="warning"
size="s"
iconType="sortUp"
/>
<>
<EuiCallOut
data-test-subj="indexPattern-invalid-operation"
title={i18n.translate('xpack.lens.indexPattern.invalidOperationLabel', {
defaultMessage: 'To use this function, select a different field.',
})}
color="warning"
size="s"
iconType="sortUp"
/>
<EuiSpacer size="m" />
</>
)}
{incompatibleSelectedOperationType && !selectedColumn && (
<EuiCallOut
size="s"
data-test-subj="indexPattern-fieldless-operation"
title={i18n.translate('xpack.lens.indexPattern.fieldlessOperationLabel', {
defaultMessage: 'To use this function, select a field.',
})}
iconType="sortUp"
/>
<>
<EuiCallOut
size="s"
data-test-subj="indexPattern-fieldless-operation"
title={i18n.translate('xpack.lens.indexPattern.fieldlessOperationLabel', {
defaultMessage: 'To use this function, select a field.',
})}
iconType="sortUp"
/>
<EuiSpacer size="m" />
</>
)}
{!incompatibleSelectedOperationType && ParamEditor && (
<>

View file

@ -27,7 +27,8 @@ export function LayerPanel({ state, layerId, onChangeIndexPattern }: IndexPatter
label: state.indexPatterns[layer.indexPatternId].title,
title: state.indexPatterns[layer.indexPatternId].title,
'data-test-subj': 'lns_layerIndexPatternLabel',
size: 'xs',
size: 's',
fontWeight: 'normal',
}}
indexPatternId={layer.indexPatternId}
indexPatternRefs={state.indexPatternRefs}

View file

@ -0,0 +1,7 @@
/*
* 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.
*/
export { ToolbarButtonProps, ToolbarButton } from './toolbar_button';

View file

@ -0,0 +1,30 @@
.lnsToolbarButton {
line-height: $euiButtonHeight; // Keeps alignment of text and chart icon
background-color: $euiColorEmptyShade;
border-color: $euiBorderColor;
// Some toolbar buttons are just icons, but EuiButton comes with margin and min-width that need to be removed
min-width: 0;
.lnsToolbarButton__text:empty {
margin: 0;
}
// Toolbar buttons don't look good with centered text when fullWidth
&[class*='fullWidth'] {
text-align: left;
.lnsToolbarButton__content {
justify-content: space-between;
}
}
}
.lnsToolbarButton--bold {
font-weight: $euiFontWeightBold;
}
.lnsToolbarButton--s {
box-shadow: none !important; // sass-lint:disable-line no-important
font-size: $euiFontSizeS;
}

View file

@ -0,0 +1,53 @@
/*
* 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 './toolbar_button.scss';
import React from 'react';
import classNames from 'classnames';
import { EuiButton, PropsOf, EuiButtonProps } from '@elastic/eui';
export type ToolbarButtonProps = PropsOf<typeof EuiButton> & {
/**
* Determines prominence
*/
fontWeight?: 'normal' | 'bold';
/**
* Smaller buttons also remove extra shadow for less prominence
*/
size?: EuiButtonProps['size'];
};
export const ToolbarButton: React.FunctionComponent<ToolbarButtonProps> = ({
children,
className,
fontWeight = 'normal',
size = 'm',
...rest
}) => {
const classes = classNames(
'lnsToolbarButton',
[`lnsToolbarButton--${fontWeight}`, `lnsToolbarButton--${size}`],
className
);
return (
<EuiButton
className={classes}
iconSide="right"
iconType="arrowDown"
color="text"
contentProps={{
className: 'lnsToolbarButton__content',
}}
textProps={{
className: 'lnsToolbarButton__text',
}}
{...rest}
size={size}
>
{children}
</EuiButton>
);
};

View file

@ -4,11 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/
import './xy_config_panel.scss';
import React, { useState } from 'react';
import { i18n } from '@kbn/i18n';
import { debounce } from 'lodash';
import {
EuiButtonEmpty,
EuiButtonGroup,
EuiFlexGroup,
EuiFlexItem,
@ -32,8 +32,7 @@ import { State, SeriesType, visualizationTypes, YAxisMode } from './types';
import { isHorizontalChart, isHorizontalSeries, getSeriesColor } from './state_helpers';
import { trackUiEvent } from '../lens_ui_telemetry';
import { fittingFunctionDefinitions } from './fitting_functions';
import './xy_config_panel.scss';
import { ToolbarButton } from '../toolbar_button';
type UnwrapArray<T> = T extends Array<infer P> ? P : T;
@ -101,17 +100,16 @@ export function XyToolbar(props: VisualizationToolbarProps<State>) {
<EuiFlexItem grow={false}>
<EuiPopover
panelClassName="lnsXyToolbar__popover"
ownFocus
button={
<EuiButtonEmpty
color="text"
iconType="arrowDown"
iconSide="right"
<ToolbarButton
fontWeight="normal"
onClick={() => {
setOpen(!open);
}}
>
{i18n.translate('xpack.lens.xyChart.settingsLabel', { defaultMessage: 'Settings' })}
</EuiButtonEmpty>
</ToolbarButton>
}
isOpen={open}
closePopover={() => {
@ -119,12 +117,9 @@ export function XyToolbar(props: VisualizationToolbarProps<State>) {
}}
anchorPosition="downRight"
>
<EuiFormRow
display="columnCompressed"
label={i18n.translate('xpack.lens.xyChart.fittingLabel', {
defaultMessage: 'Fill missing values',
})}
helpText={
<EuiToolTip
anchorClassName="eui-displayBlock"
content={
!hasNonBarSeries &&
i18n.translate('xpack.lens.xyChart.fittingDisabledHelpText', {
defaultMessage:
@ -132,29 +127,36 @@ export function XyToolbar(props: VisualizationToolbarProps<State>) {
})
}
>
<EuiSuperSelect
compressed
disabled={!hasNonBarSeries}
options={fittingFunctionDefinitions.map(({ id, title, description }) => {
return {
value: id,
dropdownDisplay: (
<>
<strong>{title}</strong>
<EuiText size="xs" color="subdued">
<p>{description}</p>
</EuiText>
</>
),
inputDisplay: title,
};
<EuiFormRow
display="columnCompressed"
label={i18n.translate('xpack.lens.xyChart.fittingLabel', {
defaultMessage: 'Fill missing values',
})}
valueOfSelected={props.state?.fittingFunction || 'None'}
onChange={(value) => props.setState({ ...props.state, fittingFunction: value })}
itemLayoutAlign="top"
hasDividers
/>
</EuiFormRow>
>
<EuiSuperSelect
compressed
disabled={!hasNonBarSeries}
options={fittingFunctionDefinitions.map(({ id, title, description }) => {
return {
value: id,
dropdownDisplay: (
<>
<strong>{title}</strong>
<EuiText size="xs" color="subdued">
<p>{description}</p>
</EuiText>
</>
),
inputDisplay: title,
};
})}
valueOfSelected={props.state?.fittingFunction || 'None'}
onChange={(value) => props.setState({ ...props.state, fittingFunction: value })}
itemLayoutAlign="top"
hasDividers
/>
</EuiFormRow>
</EuiToolTip>
</EuiPopover>
</EuiFlexItem>
</EuiFlexGroup>
@ -183,12 +185,12 @@ export function DimensionEditor(props: VisualizationDimensionEditorProps<State>)
})}
>
<EuiButtonGroup
isFullWidth
legend={i18n.translate('xpack.lens.xyChart.axisSide.label', {
defaultMessage: 'Axis side',
})}
name="axisSide"
buttonSize="compressed"
className="eui-displayInlineBlock"
options={[
{
id: `${idPrefix}auto`,
@ -241,7 +243,7 @@ const tooltipContent = {
}),
disabled: i18n.translate('xpack.lens.configPanel.color.tooltip.disabled', {
defaultMessage:
'Individual series cannot be custom colored when the layer includes a “Break down by“',
'Individual series cannot be custom colored when the layer includes a “Break down by.“',
}),
};
@ -286,6 +288,22 @@ const ColorPicker = ({
[state, layer, accessor, index]
);
const colorPicker = (
<EuiColorPicker
compressed
isClearable
onChange={handleColor}
color={disabled ? '' : color}
disabled={disabled}
placeholder={i18n.translate('xpack.lens.xyChart.seriesColor.auto', {
defaultMessage: 'Auto',
})}
aria-label={i18n.translate('xpack.lens.xyChart.seriesColor.label', {
defaultMessage: 'Series color',
})}
/>
);
return (
<EuiFormRow
display="columnCompressed"
@ -312,25 +330,10 @@ const ColorPicker = ({
delay="long"
anchorClassName="eui-displayBlock"
>
<EuiColorPicker
compressed
onChange={handleColor}
color=""
disabled
aria-label={i18n.translate('xpack.lens.xyChart.seriesColor.label', {
defaultMessage: 'Series color',
})}
/>
{colorPicker}
</EuiToolTip>
) : (
<EuiColorPicker
compressed
onChange={handleColor}
color={color}
aria-label={i18n.translate('xpack.lens.xyChart.seriesColor.label', {
defaultMessage: 'Series color',
})}
/>
colorPicker
)}
</EuiFormRow>
);