diff --git a/packages/kbn-coloring/BUILD.bazel b/packages/kbn-coloring/BUILD.bazel
index 656807d8ba2c1..cbbb4d2b7d3e8 100644
--- a/packages/kbn-coloring/BUILD.bazel
+++ b/packages/kbn-coloring/BUILD.bazel
@@ -49,6 +49,8 @@ RUNTIME_DEPS = [
"@npm//@elastic/eui",
"@npm//react-use",
"@npm//react",
+ "@npm//@emotion/react",
+ "@npm//@emotion/css",
]
# In this array place dependencies necessary to build the types, which will include the
@@ -71,6 +73,8 @@ TYPES_DEPS = [
"@npm//@types/react",
"@npm//@elastic/eui",
"@npm//react-use",
+ "@npm//@emotion/react",
+ "@npm//@emotion/css",
]
jsts_transpiler(
diff --git a/packages/kbn-coloring/src/shared_components/coloring/palette_configuration.scss b/packages/kbn-coloring/src/shared_components/coloring/palette_configuration.scss
deleted file mode 100644
index 82165b172eab9..0000000000000
--- a/packages/kbn-coloring/src/shared_components/coloring/palette_configuration.scss
+++ /dev/null
@@ -1,8 +0,0 @@
-.lnsPalettePanel__section {
- padding: $euiSize;
-}
-
-.lnsPalettePanel__section--shaded {
- background-color: $euiColorLightestShade;
- border-bottom: $euiBorderThin;
-}
\ No newline at end of file
diff --git a/packages/kbn-coloring/src/shared_components/coloring/palette_configuration.tsx b/packages/kbn-coloring/src/shared_components/coloring/palette_configuration.tsx
index beb7e828c1435..5db80ba80446c 100644
--- a/packages/kbn-coloring/src/shared_components/coloring/palette_configuration.tsx
+++ b/packages/kbn-coloring/src/shared_components/coloring/palette_configuration.tsx
@@ -8,7 +8,8 @@
import { i18n } from '@kbn/i18n';
import React, { useReducer, useMemo } from 'react';
import useDebounce from 'react-use/lib/useDebounce';
-import { EuiFormRow, htmlIdGenerator, EuiButtonGroup, EuiIconTip } from '@elastic/eui';
+import { css } from '@emotion/react';
+import { EuiFormRow, htmlIdGenerator, EuiButtonGroup, EuiIconTip, useEuiTheme } from '@elastic/eui';
import { PalettePicker } from './palette_picker';
import {
PaletteOutput,
@@ -19,8 +20,6 @@ import {
RequiredPaletteParamTypes,
} from '../../palettes';
-import './palette_configuration.scss';
-
import { toColorRanges } from './utils';
import { ColorRanges, ColorRangesContext } from './color_ranges';
import { isAllColorRangesValid } from './color_ranges/color_ranges_validation';
@@ -72,8 +71,19 @@ export const CustomizablePalette = ({
[localState]
);
+ const { euiTheme } = useEuiTheme();
+
+ const styles = useMemo(
+ () => css`
+ padding: ${euiTheme.size.base};
+ background-color: ${euiTheme.colors.lightestShade};
+ border-bottom: ${euiTheme.border.thin};
+ `,
+ [euiTheme.size.base, euiTheme.colors.lightestShade, euiTheme.border.thin]
+ );
+
return (
-
+
) => (
-
-);
+export const HorizontalBulletIcon = ({ title, titleId, ...props }: Omit) => {
+ const { chartIcon } = useCommonChartStyles();
+
+ return (
+
+ );
+};
diff --git a/src/plugins/chart_expressions/expression_gauge/public/components/icons/vertical_bullet_icon.tsx b/src/plugins/chart_expressions/expression_gauge/public/components/icons/vertical_bullet_icon.tsx
index 99f4976d5f38f..49a1e2a817cf7 100644
--- a/src/plugins/chart_expressions/expression_gauge/public/components/icons/vertical_bullet_icon.tsx
+++ b/src/plugins/chart_expressions/expression_gauge/public/components/icons/vertical_bullet_icon.tsx
@@ -8,25 +8,30 @@
import React from 'react';
import type { EuiIconProps } from '@elastic/eui';
+import { useCommonChartStyles } from '@kbn/charts-plugin/public';
-export const VerticalBulletIcon = ({ title, titleId, ...props }: Omit) => (
-
-);
+export const VerticalBulletIcon = ({ title, titleId, ...props }: Omit) => {
+ const { chartIcon } = useCommonChartStyles();
+
+ return (
+
+ );
+};
diff --git a/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.test.tsx b/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.test.tsx
index 6b073b07d4841..4f3e77b8f1d6e 100644
--- a/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.test.tsx
+++ b/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.test.tsx
@@ -27,6 +27,17 @@ jest.mock('@elastic/charts', () => {
};
});
+const actWithTimeout = (action: Function, timer: number = 1) =>
+ act(
+ () =>
+ new Promise((resolve) =>
+ setTimeout(async () => {
+ await action();
+ resolve();
+ }, timer)
+ )
+ );
+
const chartsThemeService = chartPluginMock.createSetupContract().theme;
const palettesRegistry = chartPluginMock.createPaletteRegistry();
const formatService = fieldFormatsServiceMock.createStartContract();
@@ -110,6 +121,9 @@ describe('HeatmapComponent', function () {
it('renders the legend toggle component if uiState is set', async () => {
const component = mountWithIntl();
+ await actWithTimeout(async () => {
+ await component.update();
+ });
await act(async () => {
expect(findTestSubject(component, 'vislibToggleLegend').length).toBe(1);
});
@@ -118,6 +132,9 @@ describe('HeatmapComponent', function () {
it('not renders the legend toggle component if uiState is undefined', async () => {
const newProps = { ...wrapperProps, uiState: undefined } as unknown as HeatmapRenderProps;
const component = mountWithIntl();
+ await actWithTimeout(async () => {
+ await component.update();
+ });
await act(async () => {
expect(findTestSubject(component, 'vislibToggleLegend').length).toBe(0);
});
@@ -125,6 +142,9 @@ describe('HeatmapComponent', function () {
it('renders the legendColorPicker if uiState is set', async () => {
const component = mountWithIntl();
+ await actWithTimeout(async () => {
+ await component.update();
+ });
await act(async () => {
expect(component.find(Settings).prop('legendColorPicker')).toBeDefined();
});
@@ -133,6 +153,9 @@ describe('HeatmapComponent', function () {
it('not renders the legendColorPicker if uiState is undefined', async () => {
const newProps = { ...wrapperProps, uiState: undefined } as unknown as HeatmapRenderProps;
const component = mountWithIntl();
+ await actWithTimeout(async () => {
+ await component.update();
+ });
await act(async () => {
expect(component.find(Settings).prop('legendColorPicker')).toBeUndefined();
});
diff --git a/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_icon.tsx b/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_icon.tsx
index 410f8a268bff7..7a49d53222946 100644
--- a/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_icon.tsx
+++ b/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_icon.tsx
@@ -8,25 +8,30 @@
import { EuiIconProps } from '@elastic/eui';
import React from 'react';
+import { useCommonChartStyles } from '@kbn/charts-plugin/public';
-export const HeatmapIcon = ({ title, titleId, ...props }: Omit) => (
-
-);
+export const HeatmapIcon = ({ title, titleId, ...props }: Omit) => {
+ const { chartIcon } = useCommonChartStyles();
+
+ return (
+
+ );
+};
diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap b/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap
index 2df18b5813473..3c48d3cb36771 100644
--- a/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap
+++ b/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap
@@ -228,7 +228,7 @@ exports[`PartitionVisComponent should render correct structure for donut 1`] = `
}
}
>
-
-
-
-
- {
};
});
+const actWithTimeout = (action: Function, timer: number = 1) =>
+ act(
+ () =>
+ new Promise((resolve) =>
+ setTimeout(async () => {
+ await action();
+ resolve();
+ }, timer)
+ )
+ );
+
const chartsThemeService = chartPluginMock.createSetupContract().theme;
const palettesRegistry = chartPluginMock.createPaletteRegistry();
const visParams = createMockPieParams();
@@ -131,13 +142,12 @@ describe('PartitionVisComponent', function () {
expect(component).toMatchSnapshot();
});
- it('renders the legend on the correct position', () => {
- const component = shallow();
- expect(component.find(Settings).prop('legendPosition')).toEqual('right');
- });
-
it('renders the legend toggle component', async () => {
const component = mount();
+ await actWithTimeout(async () => {
+ await component.update();
+ });
+
await act(async () => {
expect(findTestSubject(component, 'vislibToggleLegend').length).toBe(1);
});
@@ -145,6 +155,9 @@ describe('PartitionVisComponent', function () {
it('hides the legend if the legend toggle is clicked', async () => {
const component = mount();
+ await actWithTimeout(async () => {
+ await component.update();
+ });
findTestSubject(component, 'vislibToggleLegend').simulate('click');
await act(async () => {
expect(component.find(Settings).prop('showLegend')).toEqual(false);
diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/icons/donut.tsx b/src/plugins/chart_expressions/expression_partition_vis/public/icons/donut.tsx
index 5846fe0e7e8ba..3101164bfe88d 100644
--- a/src/plugins/chart_expressions/expression_partition_vis/public/icons/donut.tsx
+++ b/src/plugins/chart_expressions/expression_partition_vis/public/icons/donut.tsx
@@ -8,25 +8,30 @@
import React from 'react';
import { EuiIconProps } from '@elastic/eui';
+import { useCommonChartStyles } from '@kbn/charts-plugin/public';
-export const DonutIcon = ({ title, titleId, ...props }: Omit) => (
-
-);
+export const DonutIcon = ({ title, titleId, ...props }: Omit) => {
+ const { chartIcon } = useCommonChartStyles();
+
+ return (
+
+ );
+};
diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/icons/mosaic.tsx b/src/plugins/chart_expressions/expression_partition_vis/public/icons/mosaic.tsx
index f8582495f2e0c..1f5c99702f869 100644
--- a/src/plugins/chart_expressions/expression_partition_vis/public/icons/mosaic.tsx
+++ b/src/plugins/chart_expressions/expression_partition_vis/public/icons/mosaic.tsx
@@ -8,25 +8,30 @@
import React from 'react';
import type { EuiIconProps } from '@elastic/eui';
+import { useCommonChartStyles } from '@kbn/charts-plugin/public';
-export const MosaicIcon = ({ title, titleId, ...props }: Omit) => (
-
-);
+export const MosaicIcon = ({ title, titleId, ...props }: Omit) => {
+ const { chartIcon } = useCommonChartStyles();
+
+ return (
+
+ );
+};
diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/icons/pie.tsx b/src/plugins/chart_expressions/expression_partition_vis/public/icons/pie.tsx
index 9176ac3fdd5c1..5824b8f40b6e6 100644
--- a/src/plugins/chart_expressions/expression_partition_vis/public/icons/pie.tsx
+++ b/src/plugins/chart_expressions/expression_partition_vis/public/icons/pie.tsx
@@ -8,25 +8,30 @@
import React from 'react';
import { EuiIconProps } from '@elastic/eui';
+import { useCommonChartStyles } from '@kbn/charts-plugin/public';
-export const PieIcon = ({ title, titleId, ...props }: Omit) => (
-
-);
+export const PieIcon = ({ title, titleId, ...props }: Omit) => {
+ const { chartIcon } = useCommonChartStyles();
+
+ return (
+
+ );
+};
diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/icons/treemap.tsx b/src/plugins/chart_expressions/expression_partition_vis/public/icons/treemap.tsx
index 1860132fa9ffd..781b79505384d 100644
--- a/src/plugins/chart_expressions/expression_partition_vis/public/icons/treemap.tsx
+++ b/src/plugins/chart_expressions/expression_partition_vis/public/icons/treemap.tsx
@@ -8,29 +8,34 @@
import React from 'react';
import { EuiIconProps } from '@elastic/eui';
+import { useCommonChartStyles } from '@kbn/charts-plugin/public';
-export const TreemapIcon = ({ title, titleId, ...props }: Omit) => (
-
-);
+export const TreemapIcon = ({ title, titleId, ...props }: Omit) => {
+ const { chartIcon } = useCommonChartStyles();
+
+ return (
+
+ );
+};
diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/icons/waffle.tsx b/src/plugins/chart_expressions/expression_partition_vis/public/icons/waffle.tsx
index 30f05dd57f348..21e26facd8e15 100644
--- a/src/plugins/chart_expressions/expression_partition_vis/public/icons/waffle.tsx
+++ b/src/plugins/chart_expressions/expression_partition_vis/public/icons/waffle.tsx
@@ -8,25 +8,30 @@
import React from 'react';
import type { EuiIconProps } from '@elastic/eui';
+import { useCommonChartStyles } from '@kbn/charts-plugin/public';
-export const WaffleIcon = ({ title, titleId, ...props }: Omit) => (
-
-);
+export const WaffleIcon = ({ title, titleId, ...props }: Omit) => {
+ const { chartIcon } = useCommonChartStyles();
+
+ return (
+
+ );
+};
diff --git a/src/plugins/charts/common/constants.ts b/src/plugins/charts/common/constants.ts
index 01fdb5e545bb4..6d895dcba26ed 100644
--- a/src/plugins/charts/common/constants.ts
+++ b/src/plugins/charts/common/constants.ts
@@ -20,3 +20,23 @@ export const paletteIds = [
'warm',
'gray',
];
+
+// This set of defaults originated in Canvas, which, at present, is the primary
+// consumer of this function. Changing this default requires a change in Canvas
+// logic, which would likely be a breaking change in 7.x.
+export const defaultCustomColors = [
+ '#882E72',
+ '#B178A6',
+ '#D6C1DE',
+ '#1965B0',
+ '#5289C7',
+ '#7BAFDE',
+ '#4EB265',
+ '#90C987',
+ '#CAE0AB',
+ '#F7EE55',
+ '#F6C141',
+ '#F1932D',
+ '#E8601C',
+ '#DC050C',
+];
diff --git a/src/plugins/charts/common/expressions/palette/index.ts b/src/plugins/charts/common/expressions/palette/index.ts
new file mode 100644
index 0000000000000..cb03733a15df5
--- /dev/null
+++ b/src/plugins/charts/common/expressions/palette/index.ts
@@ -0,0 +1,18 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+export { palette } from './palette';
+
+export { systemPalette } from './system_palette';
+export type { SystemPaletteArguments } from './system_palette';
+
+export type {
+ CustomPaletteArguments,
+ CustomPaletteState,
+ PaletteExpressionFunctionDefinition,
+} from './types';
diff --git a/src/plugins/charts/common/palette.test.ts b/src/plugins/charts/common/expressions/palette/palette.test.ts
similarity index 54%
rename from src/plugins/charts/common/palette.test.ts
rename to src/plugins/charts/common/expressions/palette/palette.test.ts
index b2f26db26757f..771e26ab4aa48 100644
--- a/src/plugins/charts/common/palette.test.ts
+++ b/src/plugins/charts/common/expressions/palette/palette.test.ts
@@ -6,14 +6,9 @@
* Side Public License, v 1.
*/
import type { PaletteOutput } from '@kbn/coloring';
-import {
- palette,
- defaultCustomColors,
- systemPalette,
- CustomPaletteState,
- CustomPaletteArguments,
-} from './palette';
import { functionWrapper } from '@kbn/expressions-plugin/common/expression_functions/specs/tests/utils';
+import { palette, CustomPaletteState, CustomPaletteArguments } from '.';
+import { defaultCustomColors } from '../../constants';
describe('palette', () => {
const fn = functionWrapper(palette()) as (
@@ -21,70 +16,70 @@ describe('palette', () => {
args?: Partial
) => PaletteOutput;
- it('results a palette', () => {
- const result = fn(null);
+ it('results a palette', async () => {
+ const result = await fn(null);
expect(result).toHaveProperty('type', 'palette');
});
describe('args', () => {
describe('color', () => {
- it('sets colors', () => {
- const result = fn(null, { color: ['red', 'green', 'blue'] });
+ it('sets colors', async () => {
+ const result = await fn(null, { color: ['red', 'green', 'blue'] });
expect(result.params!.colors).toEqual(['red', 'green', 'blue']);
});
- it('defaults to pault_tor_14 colors', () => {
- const result = fn(null);
+ it('defaults to pault_tor_14 colors', async () => {
+ const result = await fn(null);
expect(result.params!.colors).toEqual(defaultCustomColors);
});
});
describe('stop', () => {
- it('sets stops', () => {
- const result = fn(null, { color: ['red', 'green', 'blue'], stop: [1, 2, 3] });
+ it('sets stops', async () => {
+ const result = await fn(null, { color: ['red', 'green', 'blue'], stop: [1, 2, 3] });
expect(result.params!.stops).toEqual([1, 2, 3]);
});
- it('defaults to pault_tor_14 colors', () => {
- const result = fn(null);
+ it('defaults to pault_tor_14 colors', async () => {
+ const result = await fn(null);
expect(result.params!.colors).toEqual(defaultCustomColors);
});
});
describe('gradient', () => {
- it('sets gradient', () => {
- let result = fn(null, { gradient: true });
+ it('sets gradient', async () => {
+ let result = await fn(null, { gradient: true });
expect(result.params).toHaveProperty('gradient', true);
- result = fn(null, { gradient: false });
+ result = await fn(null, { gradient: false });
expect(result.params).toHaveProperty('gradient', false);
});
- it('defaults to false', () => {
- const result = fn(null);
+ it('defaults to false', async () => {
+ const result = await fn(null);
expect(result.params).toHaveProperty('gradient', false);
});
});
describe('reverse', () => {
- it('reverses order of the colors', () => {
- const result = fn(null, { reverse: true });
+ it('reverses order of the colors', async () => {
+ const result = await fn(null, { reverse: true });
expect(result.params!.colors).toEqual(defaultCustomColors.reverse());
});
- it('keeps the original order of the colors', () => {
- const result = fn(null, { reverse: false });
+ it('keeps the original order of the colors', async () => {
+ const result = await fn(null, { reverse: false });
expect(result.params!.colors).toEqual(defaultCustomColors);
});
- it(`defaults to 'false`, () => {
- const result = fn(null);
+ it(`defaults to 'false`, async () => {
+ const result = await fn(null);
expect(result.params!.colors).toEqual(defaultCustomColors);
});
- it('keeps the stops order pristine when set', () => {
+ it('keeps the stops order pristine when set', async () => {
const stops = [1, 2, 3];
- const result = fn(null, {
+ const result = await fn(null, {
color: ['red', 'green', 'blue'],
stop: [1, 2, 3],
reverse: true,
@@ -94,20 +89,3 @@ describe('palette', () => {
});
});
});
-
-describe('system_palette', () => {
- const fn = functionWrapper(systemPalette()) as (
- context: null,
- args: { name: string; params?: unknown }
- ) => PaletteOutput;
-
- it('results a palette', () => {
- const result = fn(null, { name: 'test' });
- expect(result).toHaveProperty('type', 'palette');
- });
-
- it('returns the name', () => {
- const result = fn(null, { name: 'test' });
- expect(result).toHaveProperty('name', 'test');
- });
-});
diff --git a/src/plugins/charts/common/expressions/palette/palette.ts b/src/plugins/charts/common/expressions/palette/palette.ts
new file mode 100644
index 0000000000000..1875f89020963
--- /dev/null
+++ b/src/plugins/charts/common/expressions/palette/palette.ts
@@ -0,0 +1,92 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { i18n } from '@kbn/i18n';
+import type { PaletteExpressionFunctionDefinition } from './types';
+
+export function palette(): PaletteExpressionFunctionDefinition {
+ return {
+ name: 'palette',
+ aliases: [],
+ type: 'palette',
+ inputTypes: ['null'],
+ help: i18n.translate('charts.functions.paletteHelpText', {
+ defaultMessage: 'Creates a color palette.',
+ }),
+ args: {
+ color: {
+ aliases: ['_'],
+ multi: true,
+ types: ['string'],
+ help: i18n.translate('charts.functions.palette.args.colorHelpText', {
+ defaultMessage:
+ 'The palette colors. Accepts an {html} color name, {hex}, {hsl}, {hsla}, {rgb}, or {rgba}.',
+ values: {
+ html: 'HTML',
+ rgb: 'RGB',
+ rgba: 'RGBA',
+ hex: 'HEX',
+ hsl: 'HSL',
+ hsla: 'HSLA',
+ },
+ }),
+ required: false,
+ },
+ stop: {
+ multi: true,
+ types: ['number'],
+ help: i18n.translate('charts.functions.palette.args.stopHelpText', {
+ defaultMessage:
+ 'The palette color stops. When used, it must be associated with each color.',
+ }),
+ required: false,
+ },
+ continuity: {
+ types: ['string'],
+ options: ['above', 'below', 'all', 'none'],
+ default: 'above',
+ help: '',
+ },
+ rangeMin: {
+ types: ['number'],
+ help: '',
+ },
+ rangeMax: {
+ types: ['number'],
+ help: '',
+ },
+ range: {
+ types: ['string'],
+ options: ['number', 'percent'],
+ default: 'percent',
+ help: '',
+ },
+ gradient: {
+ types: ['boolean'],
+ default: false,
+ help: i18n.translate('charts.functions.palette.args.gradientHelpText', {
+ defaultMessage: 'Make a gradient palette where supported?',
+ }),
+ options: [true, false],
+ },
+ reverse: {
+ types: ['boolean'],
+ default: false,
+ help: i18n.translate('charts.functions.palette.args.reverseHelpText', {
+ defaultMessage: 'Reverse the palette?',
+ }),
+ options: [true, false],
+ },
+ },
+ async fn(...args) {
+ /** Build optimization: prevent adding extra code into initial bundle **/
+ const { paletteExpressionFn } = await import('./palette_fn');
+ return paletteExpressionFn(...args);
+ },
+ };
+}
diff --git a/src/plugins/charts/common/expressions/palette/palette_fn.ts b/src/plugins/charts/common/expressions/palette/palette_fn.ts
new file mode 100644
index 0000000000000..1702c95ab76e7
--- /dev/null
+++ b/src/plugins/charts/common/expressions/palette/palette_fn.ts
@@ -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
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { last } from 'lodash';
+import { checkIsMaxContinuity, checkIsMinContinuity } from '@kbn/coloring';
+import type { PaletteExpressionFunctionDefinition } from './types';
+import { defaultCustomColors } from '../../constants';
+
+export const paletteExpressionFn: PaletteExpressionFunctionDefinition['fn'] = async (
+ input,
+ args
+) => {
+ const { color, continuity, reverse, gradient, stop, range, rangeMin, rangeMax } = args;
+ const colors = ([] as string[]).concat(color || defaultCustomColors);
+ const stops = ([] as number[]).concat(stop || []);
+ if (stops.length > 0 && colors.length !== stops.length) {
+ throw Error('When stop is used, each color must have an associated stop value.');
+ }
+
+ // If the user has defined stops, choose rangeMin/Max, provided by user or range,
+ // taken from first/last element of ranges or default range (0 or 100).
+ const calculateRange = (
+ userRange: number | undefined,
+ stopsRange: number | undefined,
+ defaultRange: number
+ ) => userRange ?? stopsRange ?? defaultRange;
+
+ const rangeMinDefault = 0;
+ const rangeMaxDefault = 100;
+
+ return {
+ type: 'palette',
+ name: 'custom',
+ params: {
+ colors: reverse ? colors.reverse() : colors,
+ stops,
+ range: range ?? 'percent',
+ gradient,
+ continuity,
+ rangeMin: checkIsMinContinuity(continuity)
+ ? Number.NEGATIVE_INFINITY
+ : calculateRange(rangeMin, stops[0], rangeMinDefault),
+ rangeMax: checkIsMaxContinuity(continuity)
+ ? Number.POSITIVE_INFINITY
+ : calculateRange(rangeMax, last(stops), rangeMaxDefault),
+ },
+ };
+};
diff --git a/src/plugins/charts/common/expressions/palette/system_palette.test.ts b/src/plugins/charts/common/expressions/palette/system_palette.test.ts
new file mode 100644
index 0000000000000..82c55f99723ea
--- /dev/null
+++ b/src/plugins/charts/common/expressions/palette/system_palette.test.ts
@@ -0,0 +1,27 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+import type { PaletteOutput } from '@kbn/coloring';
+import { functionWrapper } from '@kbn/expressions-plugin/common/expression_functions/specs/tests/utils';
+import { systemPalette } from './system_palette';
+
+describe('system_palette', () => {
+ const fn = functionWrapper(systemPalette()) as (
+ context: null,
+ args: { name: string; params?: unknown }
+ ) => PaletteOutput;
+
+ it('results a palette', () => {
+ const result = fn(null, { name: 'test' });
+ expect(result).toHaveProperty('type', 'palette');
+ });
+
+ it('returns the name', () => {
+ const result = fn(null, { name: 'test' });
+ expect(result).toHaveProperty('name', 'test');
+ });
+});
diff --git a/src/plugins/charts/common/expressions/palette/system_palette.ts b/src/plugins/charts/common/expressions/palette/system_palette.ts
new file mode 100644
index 0000000000000..e4bfed538570e
--- /dev/null
+++ b/src/plugins/charts/common/expressions/palette/system_palette.ts
@@ -0,0 +1,48 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { i18n } from '@kbn/i18n';
+import type { ExpressionFunctionDefinition } from '@kbn/expressions-plugin/common';
+import type { PaletteOutput } from './types';
+import { paletteIds } from '../../constants';
+
+export interface SystemPaletteArguments {
+ name: string;
+}
+
+export function systemPalette(): ExpressionFunctionDefinition<
+ 'system_palette',
+ null,
+ SystemPaletteArguments,
+ PaletteOutput
+> {
+ return {
+ name: 'system_palette',
+ aliases: [],
+ type: 'palette',
+ inputTypes: ['null'],
+ help: i18n.translate('charts.functions.systemPaletteHelpText', {
+ defaultMessage: 'Creates a dynamic color palette.',
+ }),
+ args: {
+ name: {
+ types: ['string'],
+ help: i18n.translate('charts.functions.systemPalette.args.nameHelpText', {
+ defaultMessage: 'Name of the palette in the palette list',
+ }),
+ options: paletteIds,
+ },
+ },
+ fn: (input, args) => {
+ return {
+ type: 'palette',
+ name: args.name,
+ };
+ },
+ };
+}
diff --git a/src/plugins/charts/common/expressions/palette/types.ts b/src/plugins/charts/common/expressions/palette/types.ts
new file mode 100644
index 0000000000000..12fef842674f1
--- /dev/null
+++ b/src/plugins/charts/common/expressions/palette/types.ts
@@ -0,0 +1,43 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+import type { PaletteContinuity } from '@kbn/coloring';
+import type { ExpressionFunctionDefinition } from '@kbn/expressions-plugin/common';
+
+export interface PaletteOutput {
+ type: 'palette' | 'system_palette';
+ name: string;
+ params?: T;
+}
+
+export interface CustomPaletteArguments {
+ color?: string[];
+ gradient: boolean;
+ reverse?: boolean;
+ stop?: number[];
+ range?: 'number' | 'percent';
+ rangeMin?: number;
+ rangeMax?: number;
+ continuity?: PaletteContinuity;
+}
+
+export interface CustomPaletteState {
+ colors: string[];
+ gradient: boolean;
+ stops: number[];
+ range: 'number' | 'percent';
+ rangeMin: number;
+ rangeMax: number;
+ continuity?: PaletteContinuity;
+}
+
+export type PaletteExpressionFunctionDefinition = ExpressionFunctionDefinition<
+ 'palette',
+ null,
+ CustomPaletteArguments,
+ Promise>
+>;
diff --git a/src/plugins/charts/common/index.ts b/src/plugins/charts/common/index.ts
index 5ad9eb264e78b..74389ce43990f 100644
--- a/src/plugins/charts/common/index.ts
+++ b/src/plugins/charts/common/index.ts
@@ -9,11 +9,14 @@
export const COLOR_MAPPING_SETTING = 'visualization:colorMapping';
export const LEGACY_TIME_AXIS = 'visualization:useLegacyTimeAxis';
-export type { CustomPaletteArguments, CustomPaletteState, SystemPaletteArguments } from './palette';
+export type {
+ CustomPaletteArguments,
+ CustomPaletteState,
+ SystemPaletteArguments,
+} from './expressions/palette';
+export { palette, systemPalette } from './expressions/palette';
-export { defaultCustomColors, palette, systemPalette } from './palette';
-
-export { paletteIds } from './constants';
+export { paletteIds, defaultCustomColors } from './constants';
export type { ColorSchema, RawColorSchema, ColorMap } from './static';
export {
ColorSchemas,
@@ -29,11 +32,3 @@ export {
} from './static';
export type { ColorSchemaParams, Labels, Style } from './types';
-
-/** @deprecated **/
-/** Please import directly from @kbn/coloring **/
-export { checkIsMinContinuity, checkIsMaxContinuity } from '@kbn/coloring';
-
-/** @deprecated **/
-/** Please import directly from @kbn/coloring **/
-export type { PaletteOutput, PaletteContinuity } from '@kbn/coloring';
diff --git a/src/plugins/charts/common/palette.ts b/src/plugins/charts/common/palette.ts
deleted file mode 100644
index ebb4d3dff9e59..0000000000000
--- a/src/plugins/charts/common/palette.ts
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import type { ExpressionFunctionDefinition } from '@kbn/expressions-plugin/common';
-import type { PaletteContinuity } from '@kbn/coloring';
-import { i18n } from '@kbn/i18n';
-import { checkIsMaxContinuity, checkIsMinContinuity } from '@kbn/coloring';
-import { last } from 'lodash';
-import { paletteIds } from './constants';
-
-export interface CustomPaletteArguments {
- color?: string[];
- gradient: boolean;
- reverse?: boolean;
- stop?: number[];
- range?: 'number' | 'percent';
- rangeMin?: number;
- rangeMax?: number;
- continuity?: PaletteContinuity;
-}
-
-export interface CustomPaletteState {
- colors: string[];
- gradient: boolean;
- stops: number[];
- range: 'number' | 'percent';
- rangeMin: number;
- rangeMax: number;
- continuity?: PaletteContinuity;
-}
-
-export interface SystemPaletteArguments {
- name: string;
-}
-
-export interface PaletteOutput {
- type: 'palette' | 'system_palette';
- name: string;
- params?: T;
-}
-
-export const defaultCustomColors = [
- // This set of defaults originated in Canvas, which, at present, is the primary
- // consumer of this function. Changing this default requires a change in Canvas
- // logic, which would likely be a breaking change in 7.x.
- '#882E72',
- '#B178A6',
- '#D6C1DE',
- '#1965B0',
- '#5289C7',
- '#7BAFDE',
- '#4EB265',
- '#90C987',
- '#CAE0AB',
- '#F7EE55',
- '#F6C141',
- '#F1932D',
- '#E8601C',
- '#DC050C',
-];
-
-export function palette(): ExpressionFunctionDefinition<
- 'palette',
- null,
- CustomPaletteArguments,
- PaletteOutput
-> {
- return {
- name: 'palette',
- aliases: [],
- type: 'palette',
- inputTypes: ['null'],
- help: i18n.translate('charts.functions.paletteHelpText', {
- defaultMessage: 'Creates a color palette.',
- }),
- args: {
- color: {
- aliases: ['_'],
- multi: true,
- types: ['string'],
- help: i18n.translate('charts.functions.palette.args.colorHelpText', {
- defaultMessage:
- 'The palette colors. Accepts an {html} color name, {hex}, {hsl}, {hsla}, {rgb}, or {rgba}.',
- values: {
- html: 'HTML',
- rgb: 'RGB',
- rgba: 'RGBA',
- hex: 'HEX',
- hsl: 'HSL',
- hsla: 'HSLA',
- },
- }),
- required: false,
- },
- stop: {
- multi: true,
- types: ['number'],
- help: i18n.translate('charts.functions.palette.args.stopHelpText', {
- defaultMessage:
- 'The palette color stops. When used, it must be associated with each color.',
- }),
- required: false,
- },
- continuity: {
- types: ['string'],
- options: ['above', 'below', 'all', 'none'],
- default: 'above',
- help: '',
- },
- rangeMin: {
- types: ['number'],
- help: '',
- },
- rangeMax: {
- types: ['number'],
- help: '',
- },
- range: {
- types: ['string'],
- options: ['number', 'percent'],
- default: 'percent',
- help: '',
- },
- gradient: {
- types: ['boolean'],
- default: false,
- help: i18n.translate('charts.functions.palette.args.gradientHelpText', {
- defaultMessage: 'Make a gradient palette where supported?',
- }),
- options: [true, false],
- },
- reverse: {
- types: ['boolean'],
- default: false,
- help: i18n.translate('charts.functions.palette.args.reverseHelpText', {
- defaultMessage: 'Reverse the palette?',
- }),
- options: [true, false],
- },
- },
- fn: (input, args) => {
- const { color, continuity, reverse, gradient, stop, range, rangeMin, rangeMax } = args;
- const colors = ([] as string[]).concat(color || defaultCustomColors);
- const stops = ([] as number[]).concat(stop || []);
- if (stops.length > 0 && colors.length !== stops.length) {
- throw Error('When stop is used, each color must have an associated stop value.');
- }
-
- // If the user has defined stops, choose rangeMin/Max, provided by user or range,
- // taken from first/last element of ranges or default range (0 or 100).
- const calculateRange = (
- userRange: number | undefined,
- stopsRange: number | undefined,
- defaultRange: number
- ) => userRange ?? stopsRange ?? defaultRange;
-
- const rangeMinDefault = 0;
- const rangeMaxDefault = 100;
-
- return {
- type: 'palette',
- name: 'custom',
- params: {
- colors: reverse ? colors.reverse() : colors,
- stops,
- range: range ?? 'percent',
- gradient,
- continuity,
- rangeMin: checkIsMinContinuity(continuity)
- ? Number.NEGATIVE_INFINITY
- : calculateRange(rangeMin, stops[0], rangeMinDefault),
- rangeMax: checkIsMaxContinuity(continuity)
- ? Number.POSITIVE_INFINITY
- : calculateRange(rangeMax, last(stops), rangeMaxDefault),
- },
- };
- },
- };
-}
-
-export function systemPalette(): ExpressionFunctionDefinition<
- 'system_palette',
- null,
- SystemPaletteArguments,
- PaletteOutput
-> {
- return {
- name: 'system_palette',
- aliases: [],
- type: 'palette',
- inputTypes: ['null'],
- help: i18n.translate('charts.functions.systemPaletteHelpText', {
- defaultMessage: 'Creates a dynamic color palette.',
- }),
- args: {
- name: {
- types: ['string'],
- help: i18n.translate('charts.functions.systemPalette.args.nameHelpText', {
- defaultMessage: 'Name of the palette in the palette list',
- }),
- options: paletteIds,
- },
- },
- fn: (input, args) => {
- return {
- type: 'palette',
- name: args.name,
- };
- },
- };
-}
diff --git a/src/plugins/charts/public/index.ts b/src/plugins/charts/public/index.ts
index 666bd1cc9ad4f..d6cae90d50057 100644
--- a/src/plugins/charts/public/index.ts
+++ b/src/plugins/charts/public/index.ts
@@ -42,7 +42,3 @@ export {
LabelRotation,
defaultCountLabel,
} from '../common';
-
-/** @deprecated **/
-/** Please import directly from @kbn/coloring **/
-export type { SeriesLayer, PaletteRegistry, PaletteOutput, PaletteDefinition } from '@kbn/coloring';
diff --git a/src/plugins/charts/public/static/components/color_picker.scss b/src/plugins/charts/public/static/components/color_picker.scss
deleted file mode 100644
index 5def2b75a4c50..0000000000000
--- a/src/plugins/charts/public/static/components/color_picker.scss
+++ /dev/null
@@ -1,30 +0,0 @@
-$visColorPickerWidth: $euiSizeL * 8; // 8 columns
-
-.visColorPicker__value {
- width: $visColorPickerWidth;
-}
-
-.visColorPicker__colorBtn {
- position: relative;
-
- input[type='radio'] {
- position: absolute;
- top: 50%;
- left: 50%;
- opacity: 0;
- transform: translate(-50%, -50%);
- }
-}
-
-.visColorPicker__valueDot {
- cursor: pointer;
-
- &:hover {
- transform: scale(1.4);
- }
-
- &-isSelected {
- border: $euiSizeXS solid;
- border-radius: 100%;
- }
-}
diff --git a/src/plugins/charts/public/static/components/color_picker.tsx b/src/plugins/charts/public/static/components/color_picker.tsx
index 25c210b87a0e1..edd68ce6dbbba 100644
--- a/src/plugins/charts/public/static/components/color_picker.tsx
+++ b/src/plugins/charts/public/static/components/color_picker.tsx
@@ -6,9 +6,8 @@
* Side Public License, v 1.
*/
-import classNames from 'classnames';
-import React, { BaseSyntheticEvent } from 'react';
-
+import React, { BaseSyntheticEvent, useMemo } from 'react';
+import { css } from '@emotion/react';
import {
EuiButtonEmpty,
EuiFlexItem,
@@ -16,10 +15,10 @@ import {
euiPaletteColorBlind,
EuiScreenReaderOnly,
EuiFlexGroup,
+ useEuiTheme,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { lightenColor } from '../../services/palettes/lighten_color';
-import './color_picker.scss';
export const legacyColors: string[] = [
'#3F6833',
@@ -80,7 +79,7 @@ export const legacyColors: string[] = [
'#DEDAF7',
];
-interface ColorPickerProps {
+export interface ColorPickerProps {
/**
* Label that characterizes the color that is going to change
*/
@@ -116,6 +115,24 @@ interface ColorPickerProps {
}
const euiColors = euiPaletteColorBlind({ rotations: 4, order: 'group' });
+const visColorPickerColorBtnStyle = css`
+ position: relative;
+ input[type='radio'] {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ opacity: 0;
+ transform: translate(-50%, -50%);
+ }
+`;
+
+const visColorPickerValueDotStyle = css`
+ cursor: pointer;
+ &:hover {
+ transform: scale(1.4);
+ }
+`;
+
export const ColorPicker = ({
onChange,
color: selectedColor,
@@ -127,6 +144,22 @@ export const ColorPicker = ({
layerIndex,
}: ColorPickerProps) => {
const legendColors = useLegacyColors ? legacyColors : euiColors;
+ const { euiTheme } = useEuiTheme();
+
+ const visColorPickerValueStyle = useMemo(
+ () => css`
+ width: calc(${euiTheme.size.l} * 8);
+ `,
+ [euiTheme.size.l]
+ );
+
+ const visColorPickerValueDotSelectedStyle = useMemo(
+ () => css`
+ border: ${euiTheme.size.xs} solid;
+ border-radius: 100%;
+ `,
+ [euiTheme.size.xs]
+ );
return (
@@ -140,9 +173,18 @@ export const ColorPicker = ({
/>
-
+
{legendColors.map((color) => (
-