diff --git a/packages/osd-charts/.playground/playground.tsx b/packages/osd-charts/.playground/playground.tsx index 94934b447a9e..7d0a1427dd58 100644 --- a/packages/osd-charts/.playground/playground.tsx +++ b/packages/osd-charts/.playground/playground.tsx @@ -17,91 +17,149 @@ * under the License. */ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - import React from 'react'; -import { - AnnotationDomainTypes, - Axis, - BarSeries, - Chart, - LineAnnotation, - LineAnnotationDatum, - ScaleType, - Settings, -} from '../src'; -import { Icon } from '../src/components/icons/icon'; -import { Position } from '../src/utils/commons'; -import { arrayKnobs } from '../stories/utils/knobs'; - -function generateAnnotationData(values: any[]): LineAnnotationDatum[] { - return values.map((value, index) => ({ dataValue: value, details: `detail-${index}` })); +interface Food { + label: string; + count: number; + actionLabel: string; } -const data = arrayKnobs('data values', [2.5, 7.2]); -const dataValues = generateAnnotationData(data); + +type Foods = Array<Food>; + +type FoodArray = Array<string>; export class Playground extends React.Component { + foods: Foods = [ + { label: 'pie', count: 2, actionLabel: 'tab' }, + { label: 'asparagus', count: 5, actionLabel: 'tab' }, + { label: 'brownies', count: 0, actionLabel: 'enter' }, + { label: 'popsicles', count: 3, actionLabel: 'enter' }, + ]; + + foodsAsAnArray: FoodArray = ['tab', 'tab', 'tab', 'enter']; + + getFoodsArrayAction = (foodsArray: FoodArray) => { + for (let i = 0; i < foodsArray.length; i++) { + if (foodsArray[i] === 'tab') { + // alert('tab!'); + } else if (foodsArray[i] === 'enter') { + // alert('enter!'); + } + } + }; + + getFoodAction = (foodLabel: Food[keyof Food]) => { + // eslint-disable-next-line array-callback-return + return this.foods.map(({ label, count, actionLabel }) => { + if (foodLabel === label && actionLabel === 'tab') { + let c = 0; + while (c < count) { + // alert(`${label} Tab!`); + c++; + } + } else if (foodLabel === label && actionLabel === 'enter') { + let c = 0; + while (c < count) { + // alert(`${label} Enter!`); + c++; + } + } + }); + }; + + makingFood = (ms: number, food: string) => { + return new Promise((resolve) => { + setTimeout(() => { + // console.log(`resolving the promise ${food}`, new Date()); + resolve(`done with ${food}`); + }, ms); + // console.log(`starting the promise ${food}`, new Date()); + }); + }; + + getNumberOfFood = (food: any) => { + return this.makingFood(1000, food).then(() => this.getFoodAction(food)); + }; + + getNumberOfFoodArray = () => { + return this.makingFood(1000, 'apple').then(() => this.getFoodsArrayAction(this.foodsAsAnArray)); + }; + + getAsyncNumberOfFoodArray = async () => { + // const result = await this.makingFood(2000).then(() => this.getFoodsArrayAction(this.foodsAsAnArray)); + // alert(result); + }; + + // forLoop = async () => { + // alert('start'); + // for (let index = 0; index < this.foods.length; index++) { + // const foodLabel = this.foods[index].label; + // const numFood = await this.getFoodNumber(foodLabel); + // alert(numFood); + // } + // const foodsPromiseArray = this.foods.map(async (foodObject) => { + // for (let i = 0; i < foodObject.length; i++) { + // const numFoodAction = foodObject[i].actionLabel; + // if (numFoodAction === 'enter') { + // alert ('Enter!'); + // } else if (numFoodAction === 'tab') { + // alert('tab!'); + // } + // } + // }); + // const numberOfFoods = await Promise.all(foodsPromiseArray); + // alert(numberOfFoods); + // alert('End'); + // }; + + // getFoodArray = + // async() => { + // console.log(await this.makingFood(1000, 'apricot')); + // console.log(await this.makingFood(50, 'apple')); + // const foodTimeArray = [ + // { ms: 1000, food: 'a', count: 2 }, + // { ms: 50, food: 'b', count: 1 }, + // { ms: 500, food: 'c', count: 3 }, + // ]; + + // for (let i = 0; i < foodTimeArray.length; i++) { + // void this.makingFood(foodTimeArray[i].ms, foodTimeArray[i].food); + // } + + // const foodMap = foodTimeArray.map(({ ms, food }) => { + // return this.makingFood(ms, food); + // }); + + // console.log('before the promise'); + // for (const i of foodTimeArray) { + // const j = 0; + // while (j < i.count) { + // await this.makingFood(i.ms, i.food); + // j++; + // } + // } + + // await Promise.all(); + // console.log('after the promise'); + // }; + render() { - return ( - <div className="chart"> - <Chart className="story-chart"> - <Settings showLegend showLegendExtra /> - <LineAnnotation - id="annotation_1" - domainType={AnnotationDomainTypes.XDomain} - dataValues={dataValues} - marker={<Icon type="alert" />} - /> - <LineAnnotation id="1" domainType={AnnotationDomainTypes.YDomain} dataValues={dataValues} /> - <Axis id="horizontal" position={Position.Bottom} title="x-domain axis" /> - <Axis id="left" title="y-domain axis left" position={Position.Left} /> - <Axis id="right" title="y-domain axis right" position={Position.Right} /> - <BarSeries - id="bars" - groupId="group1" - xScaleType={ScaleType.Linear} - yScaleType={ScaleType.Linear} - xAccessor="x" - yAccessors={['y']} - data={[ - { x: 0, y: 0 }, - { x: 1, y: 5 }, - { x: 3, y: 20 }, - ]} - /> - <BarSeries - id="bars1" - groupId="group2" - xScaleType={ScaleType.Linear} - yScaleType={ScaleType.Linear} - xAccessor="x" - yAccessors={['y']} - data={[ - { x: 0, y: 100 }, - { x: 1, y: 50 }, - { x: 3, y: 200 }, - ]} - /> - </Chart> - </div> - ); + // console.log(this.makingFood(1000, 'apricot')); + // console.log(this.makingFood(50, 'apple')); + // void this.getFoodArray(); + + return null; + // <> + // <div className="page" style={{ width: 5000, height: 5000, backgroundColor: 'yellow' }}> + // <div id="root" style={{ backgroundColor: 'blueviolet' }}> + // {/* <div>{this.foods.map(({ label }) => this.getNumberOfFood(label))}</div> */} + // {/* <div>{alert(this.makingFood(50000).then(this.getFoodsArrayAction(this.foodsAsAnArray)))}</div> */} + // {/* <div>{alert(this.getNumberOfFoodArray())}</div> */} + // {/* <div>{alert(this.getAsyncNumberOfFoodArray())}</div> */} + // <div>{this.makingFood(50)}</div> + // </div> + // </div> + // </> } } diff --git a/packages/osd-charts/.storybook/style.scss b/packages/osd-charts/.storybook/style.scss index 38764348d61f..9c9f697192ea 100644 --- a/packages/osd-charts/.storybook/style.scss +++ b/packages/osd-charts/.storybook/style.scss @@ -25,6 +25,19 @@ html { position: relative; box-sizing: border-box; background-color: blanchedalmond; + + &.disable-animations { + *, + *::after, + *::before { + transition-delay: 0s !important; + transition-duration: 0s !important; + animation-delay: -0.0001s !important; + animation-duration: 0s !important; + animation-play-state: paused !important; + caret-color: transparent !important; + } + } } #story-root + div table { diff --git a/packages/osd-charts/integration/page_objects/common.ts b/packages/osd-charts/integration/page_objects/common.ts index 1ec97c3bc075..bf5a2720ce28 100644 --- a/packages/osd-charts/integration/page_objects/common.ts +++ b/packages/osd-charts/integration/page_objects/common.ts @@ -60,6 +60,13 @@ interface ElementBBox { height: number; } +interface KeyboardKey { + key: string; + count: number; +} + +type KeyboardKeys = Array<KeyboardKey>; + /** * Used to get postion from any value of cursor position * @@ -211,6 +218,15 @@ class CommonPage { return buffer; } + /** + * Move mouse + * @param mousePosition + * @param selector + */ + async moveMouse(x: number, y: number) { + await page.mouse.move(x, y); + } + /** * Move mouse relative to element * @@ -220,7 +236,7 @@ class CommonPage { async moveMouseRelativeToDOMElement(mousePosition: MousePosition, selector: string) { const element = await this.getBoundingClientRect(selector); const { x, y } = getCursorPosition(mousePosition, element); - await page.mouse.move(x, y); + await this.moveMouse(x, y); } /** @@ -245,10 +261,10 @@ class CommonPage { const element = await this.getBoundingClientRect(selector); const { x: x0, y: y0 } = getCursorPosition(start, element); const { x: x1, y: y1 } = getCursorPosition(end, element); - await page.mouse.move(x0, y0); + await this.moveMouse(x0, y0); await page.mouse.down(); await page.waitFor(DRAG_DETECTION_TIMEOUT); - await page.mouse.move(x1, y1); + await this.moveMouse(x1, y1); } /** @@ -261,6 +277,30 @@ class CommonPage { await page.mouse.up(); } + /** + * Press keyboard keys + * @param count + * @param key + */ + // eslint-disable-next-line class-methods-use-this + async pressKey(key: string, count: number) { + if (key === 'tab') { + let i = 0; + while (i < count) { + // eslint-disable-next-line eslint-comments/disable-enable-pair + /* eslint-disable no-await-in-loop */ + await page.keyboard.press('Tab'); + i++; + } + } else if (key === 'enter') { + let i = 0; + while (i < count) { + await page.keyboard.press('Enter'); + i++; + } + } + } + /** * Drag and drop mouse relative to element * @@ -341,6 +381,34 @@ class CommonPage { }); } + /** + * Expect a chart given a url from storybook with keyboard events + * @param url + * @param keyboardEvents + * @param options + */ + async expectChartWithKeyboardEventsAtUrlToMatchScreenshot( + url: string, + keyboardEvents: KeyboardKeys, + options?: Omit<ScreenshotElementAtUrlOptions, 'action'>, + ) { + const action = async () => { + await this.disableAnimations(); + // click to focus within the chart + await this.clickMouseRelativeToDOMElement({ top: 0, left: 0 }, this.chartSelector); + // eslint-disable-next-line no-restricted-syntax + for (const actions of keyboardEvents) { + await this.pressKey(actions.key, actions.count); + } + await this.moveMouseRelativeToDOMElement({ top: 0, left: 0 }, this.chartSelector); + }; + + await this.expectChartAtUrlToMatchScreenshot(url, { + ...options, + action, + }); + } + /** * Expect a chart given a url from storybook with mouse move * @@ -383,6 +451,12 @@ class CommonPage { }); } + async disableAnimations() { + await page.evaluate(() => { + document.querySelector('#story-root')!.classList.add('disable-animations'); + }); + } + /** * Wait for an element to be on the DOM * diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-with-negative-and-positive-visually-looks-correct-2-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-with-negative-and-positive-visually-looks-correct-2-snap.png deleted file mode 100644 index 36bba60335f1..000000000000 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-with-negative-and-positive-visually-looks-correct-2-snap.png and /dev/null differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-bar-chart-2-y-2-g-visually-looks-correct-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-bar-chart-2-y-2-g-visually-looks-correct-1-snap.png index 22874ca4c933..d9509ed0523b 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-bar-chart-2-y-2-g-visually-looks-correct-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-bar-chart-2-y-2-g-visually-looks-correct-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-tooltip-series-visibility-visually-looks-correct-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-tooltip-series-visibility-visually-looks-correct-1-snap.png index 22874ca4c933..d9509ed0523b 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-tooltip-series-visibility-visually-looks-correct-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-tooltip-series-visibility-visually-looks-correct-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-clicks-hovers-on-legend-items-bar-chart-visually-looks-correct-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-clicks-hovers-on-legend-items-bar-chart-visually-looks-correct-1-snap.png index 976467cb749d..c0e3eb144071 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-clicks-hovers-on-legend-items-bar-chart-visually-looks-correct-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-clicks-hovers-on-legend-items-bar-chart-visually-looks-correct-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-color-picker-visually-looks-correct-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-color-picker-visually-looks-correct-1-snap.png index 4cec4a1eb2e2..d0a5aaa7702c 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-color-picker-visually-looks-correct-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-color-picker-visually-looks-correct-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-left-visually-looks-correct-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-left-visually-looks-correct-1-snap.png index b6556d130e4e..0b88fad25a16 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-left-visually-looks-correct-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-left-visually-looks-correct-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-right-visually-looks-correct-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-right-visually-looks-correct-1-snap.png index 976467cb749d..c0e3eb144071 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-right-visually-looks-correct-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-right-visually-looks-correct-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-custom-series-colors-via-accessor-function-visually-looks-correct-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-custom-series-colors-via-accessor-function-visually-looks-correct-1-snap.png index 0f3c68dddbad..2a6d5e1f1674 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-custom-series-colors-via-accessor-function-visually-looks-correct-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-custom-series-colors-via-accessor-function-visually-looks-correct-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-custom-series-colors-via-colors-array-visually-looks-correct-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-custom-series-colors-via-colors-array-visually-looks-correct-1-snap.png index d170de7a13ea..92700836cbbf 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-custom-series-colors-via-colors-array-visually-looks-correct-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-custom-series-colors-via-colors-array-visually-looks-correct-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-custom-series-name-config-visually-looks-correct-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-custom-series-name-config-visually-looks-correct-1-snap.png index 6502c79d7840..06fedae2c189 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-custom-series-name-config-visually-looks-correct-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-custom-series-name-config-visually-looks-correct-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-sunburst-sunburst-with-three-layers-visually-looks-correct-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-sunburst-sunburst-with-three-layers-visually-looks-correct-1-snap.png index 9c804c39ac1e..fb8ffb424f0f 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-sunburst-sunburst-with-three-layers-visually-looks-correct-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-sunburst-sunburst-with-three-layers-visually-looks-correct-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-shows-negative-values-with-log-scale-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-shows-negative-values-with-log-scale-1-snap.png new file mode 100644 index 000000000000..cb29697295b2 Binary files /dev/null and b/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-shows-negative-values-with-log-scale-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-shows-only-negative-values-when-hiding-positive-one-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-shows-only-negative-values-when-hiding-positive-one-1-snap.png new file mode 100644 index 000000000000..bef91ab764b0 Binary files /dev/null and b/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-shows-only-negative-values-when-hiding-positive-one-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-shows-only-positive-domain-mixed-polarity-domain-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-shows-only-positive-domain-mixed-polarity-domain-1-snap.png new file mode 100644 index 000000000000..5a5f41d12a68 Binary files /dev/null and b/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-shows-only-positive-domain-mixed-polarity-domain-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-shows-only-positive-values-when-hiding-negative-one-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-shows-only-positive-values-when-hiding-negative-one-1-snap.png new file mode 100644 index 000000000000..cd7385786cd5 Binary files /dev/null and b/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-shows-only-positive-values-when-hiding-negative-one-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-snows-only-negative-values-when-hiding-positive-one-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-snows-only-negative-values-when-hiding-positive-one-1-snap.png deleted file mode 100644 index 4ce636d9eb68..000000000000 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-snows-only-negative-values-when-hiding-positive-one-1-snap.png and /dev/null differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-snows-only-positive-values-when-hiding-negative-one-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-snows-only-positive-values-when-hiding-negative-one-1-snap.png index 41da2502ebe0..cd7385786cd5 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-snows-only-positive-values-when-hiding-negative-one-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-negative-log-areas-snows-only-positive-values-when-hiding-negative-one-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/interactions-test-ts-interactions-tooltips-should-render-corrent-tooltip-for-split-and-y-accessors-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/interactions-test-ts-interactions-tooltips-should-render-corrent-tooltip-for-split-and-y-accessors-1-snap.png index 3eaf8d4c2fb3..25ad2277f2bb 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/interactions-test-ts-interactions-tooltips-should-render-corrent-tooltip-for-split-and-y-accessors-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/interactions-test-ts-interactions-tooltips-should-render-corrent-tooltip-for-split-and-y-accessors-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-keyboard-navigation-should-navigate-to-legend-item-with-tab-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-keyboard-navigation-should-navigate-to-legend-item-with-tab-1-snap.png new file mode 100644 index 000000000000..95f25356538f Binary files /dev/null and b/packages/osd-charts/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-keyboard-navigation-should-navigate-to-legend-item-with-tab-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-should-render-color-picker-on-mouse-click-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-should-render-color-picker-on-mouse-click-1-snap.png index 13941a8a6dfd..455686acf61c 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-should-render-color-picker-on-mouse-click-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-should-render-color-picker-on-mouse-click-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-tooltip-placement-with-legend-should-render-tooltip-with-left-legend-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-tooltip-placement-with-legend-should-render-tooltip-with-left-legend-1-snap.png index bdb10b7b7e42..fa3fcb87742d 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-tooltip-placement-with-legend-should-render-tooltip-with-left-legend-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-tooltip-placement-with-legend-should-render-tooltip-with-left-legend-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-tooltip-placement-with-legend-should-render-tooltip-with-right-legend-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-tooltip-placement-with-legend-should-render-tooltip-with-right-legend-1-snap.png index e41e650e30dc..03c5a105d8b6 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-tooltip-placement-with-legend-should-render-tooltip-with-right-legend-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-tooltip-placement-with-legend-should-render-tooltip-with-right-legend-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/area_stories.test.ts b/packages/osd-charts/integration/tests/area_stories.test.ts index 330a93a84763..60fd1dad3d72 100644 --- a/packages/osd-charts/integration/tests/area_stories.test.ts +++ b/packages/osd-charts/integration/tests/area_stories.test.ts @@ -64,27 +64,33 @@ describe('Area series stories', () => { }); }); describe('Negative log Areas', () => { - it('snows negative values with log scale', async () => { + it('shows negative values with log scale', async () => { await common.expectChartAtUrlToMatchScreenshot( 'http://localhost:9001/?path=/story/area-chart--with-negative-values&knob-Y scale=log', ); }); - it('snows only positive domain mixed polarity domain', async () => { + it('shows only positive domain mixed polarity domain', async () => { await common.expectChartAtUrlToMatchScreenshot( 'http://localhost:9001/?path=/story/area-chart--with-negative-and-positive&knob-Y scale=log', ); }); - it('snows only positive values when hiding negative one', async () => { - const action = async () => await page.click('.echLegendItem:nth-child(2) .echLegendItem__label'); + it('shows only positive values when hiding negative one', async () => { + const action = async () => { + await common.disableAnimations(); + await page.click('.echLegendItem:nth-child(2) .echLegendItem__label'); + }; await common.expectChartAtUrlToMatchScreenshot( 'http://localhost:9001/?path=/story/area-chart--with-negative-and-positive&knob-Y scale=log', { action }, ); }); - it('snows only negative values when hiding positive one', async () => { - const action = async () => await page.click('.echLegendItem:nth-child(1) .echLegendItem__label'); + it('shows only negative values when hiding positive one', async () => { + const action = async () => { + await common.disableAnimations(); + await page.click('.echLegendItem:nth-child(1) .echLegendItem__label'); + }; await common.expectChartAtUrlToMatchScreenshot( 'http://localhost:9001/?path=/story/area-chart--with-negative-and-positive&knob-Y scale=log', { action }, diff --git a/packages/osd-charts/integration/tests/legend_stories.test.ts b/packages/osd-charts/integration/tests/legend_stories.test.ts index 981b152c832c..c5d3ce42440b 100644 --- a/packages/osd-charts/integration/tests/legend_stories.test.ts +++ b/packages/osd-charts/integration/tests/legend_stories.test.ts @@ -92,4 +92,50 @@ describe('Legend stories', () => { }); }); }); + describe('keyboard navigation', () => { + // eslint-disable-next-line jest/expect-expect + it('should navigate to legend item with tab', async () => { + // puts mouse to the bottom left + await common.moveMouse(0, 0); + await common.expectChartWithKeyboardEventsAtUrlToMatchScreenshot( + 'http://localhost:9001/?path=/story/legend--right', + [ + { + key: 'tab', + count: 2, + }, + { + key: 'enter', + count: 1, + }, + ], + ); + }); + it('should change aria label to hidden when clicked', async () => { + await common.loadElementFromURL('http://localhost:9001/?path=/story/legend--right', '.echLegendItem__label'); + await common.clickMouseRelativeToDOMElement( + { + bottom: 180, + left: 330, + }, + '.echChartStatus[data-ech-render-complete=true]', + ); + // Make the first index legend item hidden + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + + const hiddenResults: number[] = []; + // Filter the labels + const labels = page.evaluate(() => + Array.from(document.getElementsByClassName('echLegendItem'), (e) => e.outerHTML), + ); + (await labels).forEach((label, index) => { + if (label.includes('Activate to show series')) { + hiddenResults.push(index); + } + }); + expect(hiddenResults).toEqual([1]); + }); + }); }); diff --git a/packages/osd-charts/src/components/__snapshots__/chart.test.tsx.snap b/packages/osd-charts/src/components/__snapshots__/chart.test.tsx.snap index 47d294136bd5..1e984a129f19 100644 --- a/packages/osd-charts/src/components/__snapshots__/chart.test.tsx.snap +++ b/packages/osd-charts/src/components/__snapshots__/chart.test.tsx.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Chart should render the legend name test 1`] = `"<div class=\\"echChart\\" style=\\"width: 100px; height: 100px;\\"><div class=\\"echChartBackground\\" style=\\"background-color: transparent;\\"></div><div class=\\"echChartStatus\\" data-ech-render-complete=\\"true\\" data-ech-render-count=\\"1\\"></div><div class=\\"echChartResizer\\"></div><div class=\\"echLegend echLegend--right echLegend--debug\\"><div style=\\"width: 50px; max-width: 50px; margin-left: 0px; margin-right: 0px;\\" class=\\"echLegendListContainer\\"><ul style=\\"padding-top: 10px; padding-bottom: 10px;\\" class=\\"echLegendList\\"><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"test\\"><div class=\\"echLegendItem__color\\" aria-label=\\"series color\\" title=\\"series color\\"><div><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#1EA593\\" focusable=\\"false\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div></div><div class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"test\\">test</div></li></ul></div></div><div class=\\"echContainer\\"><div class=\\"echChartPointerContainer\\" style=\\"cursor: default;\\"><div class=\\"echCrosshair\\"><div class=\\"echCrosshair__band\\" style=\\"top: -1px; left: -1px; width: 0px; height: 0px; background: rgb(245, 245, 245);\\"></div></div><canvas class=\\"echCanvasRenderer\\" width=\\"150\\" height=\\"200\\" style=\\"width: 150px; height: 200px;\\"></canvas><svg class=\\"echHighlighter\\"><defs><clipPath id=\\"echHighlighterClipPath__chart1\\"><rect x=\\"0\\" y=\\"0\\" width=\\"130\\" height=\\"180\\"></rect></clipPath></defs><g></g></svg></div></div></div>"`; +exports[`Chart should render the legend name test 1`] = `"<div class=\\"echChart\\" style=\\"width: 100px; height: 100px;\\"><div class=\\"echChartBackground\\" style=\\"background-color: transparent;\\"></div><div class=\\"echChartStatus\\" data-ech-render-complete=\\"true\\" data-ech-render-count=\\"1\\"></div><div class=\\"echChartResizer\\"></div><div class=\\"echLegend echLegend--right echLegend--debug\\"><div style=\\"width: 50px; max-width: 50px; margin-left: 0px; margin-right: 0px;\\" class=\\"echLegendListContainer\\"><ul style=\\"padding-top: 10px; padding-bottom: 10px;\\" class=\\"echLegendList\\"><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"test\\"><div class=\\"echLegendItem__color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#1EA593\\" focusable=\\"false\\" aria-label=\\"series color: #1EA593\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div><button type=\\"button\\" class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"test\\" aria-label=\\"test; Activate to hide series in graph\\">test</button></li></ul></div></div><div class=\\"echContainer\\"><div class=\\"echChartPointerContainer\\" style=\\"cursor: default;\\"><div class=\\"echCrosshair\\"><div class=\\"echCrosshair__band\\" style=\\"top: -1px; left: -1px; width: 0px; height: 0px; background: rgb(245, 245, 245);\\"></div></div><canvas class=\\"echCanvasRenderer\\" width=\\"150\\" height=\\"200\\" style=\\"width: 150px; height: 200px;\\"></canvas><svg class=\\"echHighlighter\\"><defs><clipPath id=\\"echHighlighterClipPath__chart1\\"><rect x=\\"0\\" y=\\"0\\" width=\\"130\\" height=\\"180\\"></rect></clipPath></defs><g></g></svg></div></div></div>"`; diff --git a/packages/osd-charts/src/components/legend/__snapshots__/legend.test.tsx.snap b/packages/osd-charts/src/components/legend/__snapshots__/legend.test.tsx.snap index 4a27e519591f..1eef6397b678 100644 --- a/packages/osd-charts/src/components/legend/__snapshots__/legend.test.tsx.snap +++ b/packages/osd-charts/src/components/legend/__snapshots__/legend.test.tsx.snap @@ -1,9 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Legend #legendColorPicker should match snapshot after onChange is called 1`] = `"<li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splita\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"change series color\\"><div><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" focusable=\\"false\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div></div><div class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splita\\">splita</div></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitb\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"change series color\\"><div><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" focusable=\\"false\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div></div><div class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitb\\">splitb</div></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitc\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"change series color\\"><div><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" focusable=\\"false\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div></div><div class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitc\\">splitc</div></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitd\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"change series color\\"><div><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" focusable=\\"false\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div></div><div class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitd\\">splitd</div></li>"`; +exports[`Legend #legendColorPicker should match snapshot after onChange is called 1`] = `"<li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splita\\"><button type=\\"button\\" class=\\"echLegendItem__color echLegendItem__color--changable\\" title=\\"change series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" focusable=\\"false\\" aria-label=\\"Change series color, currently #0c7b93\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></button><button type=\\"button\\" class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splita\\" aria-label=\\"splita; Activate to hide series in graph\\">splita</button></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitb\\"><button type=\\"button\\" class=\\"echLegendItem__color echLegendItem__color--changable\\" title=\\"change series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" focusable=\\"false\\" aria-label=\\"Change series color, currently #0c7b93\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></button><button type=\\"button\\" class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitb\\" aria-label=\\"splitb; Activate to hide series in graph\\">splitb</button></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitc\\"><button type=\\"button\\" class=\\"echLegendItem__color echLegendItem__color--changable\\" title=\\"change series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" focusable=\\"false\\" aria-label=\\"Change series color, currently #0c7b93\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></button><button type=\\"button\\" class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitc\\" aria-label=\\"splitc; Activate to hide series in graph\\">splitc</button></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitd\\"><button type=\\"button\\" class=\\"echLegendItem__color echLegendItem__color--changable\\" title=\\"change series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" focusable=\\"false\\" aria-label=\\"Change series color, currently #0c7b93\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></button><button type=\\"button\\" class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitd\\" aria-label=\\"splitd; Activate to hide series in graph\\">splitd</button></li>"`; -exports[`Legend #legendColorPicker should match snapshot after onClose is called 1`] = `"<li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splita\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"change series color\\"><div><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div></div><div class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splita\\">splita</div></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitb\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"change series color\\"><div><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div></div><div class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitb\\">splitb</div></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitc\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"change series color\\"><div><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div></div><div class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitc\\">splitc</div></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitd\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"change series color\\"><div><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div></div><div class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitd\\">splitd</div></li>"`; +exports[`Legend #legendColorPicker should match snapshot after onClose is called 1`] = `"<li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splita\\"><button type=\\"button\\" class=\\"echLegendItem__color echLegendItem__color--changable\\" title=\\"change series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\" aria-label=\\"Change series color, currently red\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></button><button type=\\"button\\" class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splita\\" aria-label=\\"splita; Activate to hide series in graph\\">splita</button></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitb\\"><button type=\\"button\\" class=\\"echLegendItem__color echLegendItem__color--changable\\" title=\\"change series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\" aria-label=\\"Change series color, currently red\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></button><button type=\\"button\\" class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitb\\" aria-label=\\"splitb; Activate to hide series in graph\\">splitb</button></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitc\\"><button type=\\"button\\" class=\\"echLegendItem__color echLegendItem__color--changable\\" title=\\"change series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\" aria-label=\\"Change series color, currently red\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></button><button type=\\"button\\" class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitc\\" aria-label=\\"splitc; Activate to hide series in graph\\">splitc</button></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitd\\"><button type=\\"button\\" class=\\"echLegendItem__color echLegendItem__color--changable\\" title=\\"change series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\" aria-label=\\"Change series color, currently red\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></button><button type=\\"button\\" class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitd\\" aria-label=\\"splitd; Activate to hide series in graph\\">splitd</button></li>"`; exports[`Legend #legendColorPicker should render colorPicker when color is clicked 1`] = `"<div id=\\"colorPicker\\"><span>Custom Color Picker</span><button id=\\"change\\" type=\\"button\\">#0c7b93</button><button id=\\"close\\" type=\\"button\\">close</button></div>"`; -exports[`Legend #legendColorPicker should render colorPicker when color is clicked 2`] = `"<li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splita\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"change series color\\"><div><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div></div><div class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splita\\">splita</div></li><div id=\\"colorPicker\\"><span>Custom Color Picker</span><button id=\\"change\\" type=\\"button\\">#0c7b93</button><button id=\\"close\\" type=\\"button\\">close</button></div><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitb\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"change series color\\"><div><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div></div><div class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitb\\">splitb</div></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitc\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"change series color\\"><div><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div></div><div class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitc\\">splitc</div></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitd\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"change series color\\"><div><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div></div><div class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitd\\">splitd</div></li>"`; +exports[`Legend #legendColorPicker should render colorPicker when color is clicked 2`] = `"<li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splita\\"><button type=\\"button\\" class=\\"echLegendItem__color echLegendItem__color--changable\\" title=\\"change series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\" aria-label=\\"Change series color, currently red\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></button><button type=\\"button\\" class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splita\\" aria-label=\\"splita; Activate to hide series in graph\\">splita</button></li><div id=\\"colorPicker\\"><span>Custom Color Picker</span><button id=\\"change\\" type=\\"button\\">#0c7b93</button><button id=\\"close\\" type=\\"button\\">close</button></div><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitb\\"><button type=\\"button\\" class=\\"echLegendItem__color echLegendItem__color--changable\\" title=\\"change series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\" aria-label=\\"Change series color, currently red\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></button><button type=\\"button\\" class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitb\\" aria-label=\\"splitb; Activate to hide series in graph\\">splitb</button></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitc\\"><button type=\\"button\\" class=\\"echLegendItem__color echLegendItem__color--changable\\" title=\\"change series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\" aria-label=\\"Change series color, currently red\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></button><button type=\\"button\\" class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitc\\" aria-label=\\"splitc; Activate to hide series in graph\\">splitc</button></li><li class=\\"echLegendItem echLegendItem--right\\" data-ech-series-name=\\"splitd\\"><button type=\\"button\\" class=\\"echLegendItem__color echLegendItem__color--changable\\" title=\\"change series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" focusable=\\"false\\" aria-label=\\"Change series color, currently red\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></button><button type=\\"button\\" class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"splitd\\" aria-label=\\"splitd; Activate to hide series in graph\\">splitd</button></li>"`; diff --git a/packages/osd-charts/src/components/legend/_legend.scss b/packages/osd-charts/src/components/legend/_legend.scss index d66e8b9c3968..1e48e0c5ee9e 100644 --- a/packages/osd-charts/src/components/legend/_legend.scss +++ b/packages/osd-charts/src/components/legend/_legend.scss @@ -43,5 +43,15 @@ width: 100%; overflow-y: auto; overflow-x: hidden; + + .echLegendItem--right :focus { + margin-right: $euiSizeXS; + } + + :focus { + @include euiFocusRing; + background-color: $euiFocusBackgroundColor; + border-radius: $euiBorderRadius / 2; + } } } diff --git a/packages/osd-charts/src/components/legend/_legend_item.scss b/packages/osd-charts/src/components/legend/_legend_item.scss index 0e736da42e3f..10fbecf533e6 100644 --- a/packages/osd-charts/src/components/legend/_legend_item.scss +++ b/packages/osd-charts/src/components/legend/_legend_item.scss @@ -11,6 +11,8 @@ $legendItemVerticalPadding: $echLegendRowGap / 2; &:not(&--hidden) { .echLegendItem__color--changable { cursor: pointer; + height: 18px; + margin-left: 5px; } } @@ -30,7 +32,9 @@ $legendItemVerticalPadding: $echLegendRowGap / 2; } &__color { + display: flex; margin-right: $euiSizeXS; + line-height: 1.5; .euiPopover { vertical-align: inherit; // prevents color dot from shifting @@ -49,6 +53,9 @@ $legendItemVerticalPadding: $echLegendRowGap / 2; @include euiFontSizeXS; @include euiTextTruncate; flex: 1 1 auto; + text-align: left; + vertical-align: baseline; + letter-spacing: unset; &--clickable { &:hover { @@ -64,6 +71,7 @@ $legendItemVerticalPadding: $echLegendRowGap / 2; flex: 0 0 auto; margin-left: $euiSizeXS; font-feature-settings: 'tnum'; + letter-spacing: unset; &--hidden { display: none; diff --git a/packages/osd-charts/src/components/legend/color.tsx b/packages/osd-charts/src/components/legend/color.tsx index 653d75bae435..0ca937c53009 100644 --- a/packages/osd-charts/src/components/legend/color.tsx +++ b/packages/osd-charts/src/components/legend/color.tsx @@ -17,15 +17,15 @@ * under the License. */ -import classNames from 'classnames'; import React, { MouseEventHandler, forwardRef, memo } from 'react'; import { Icon } from '../icons/icon'; interface ColorProps { color: string; - isSeriesHidden?: boolean; + seriesName: string; hasColorPicker: boolean; + isSeriesHidden?: boolean; onClick?: MouseEventHandler; } @@ -34,32 +34,37 @@ interface ColorProps { * @internal */ export const Color = memo( - forwardRef<HTMLDivElement, ColorProps>(({ color, isSeriesHidden = false, hasColorPicker, onClick }, ref) => { - if (isSeriesHidden) { - return ( - <div className="echLegendItem__color" aria-label="series hidden" title="series hidden"> - {/* changing the default viewBox for the eyeClosed icon to keep the same dimensions */} - <Icon type="eyeClosed" viewBox="-3 -3 22 22" /> - </div> - ); - } + forwardRef<HTMLButtonElement, ColorProps>( + ({ color, seriesName, isSeriesHidden = false, hasColorPicker, onClick }, ref) => { + if (isSeriesHidden) { + return ( + <div className="echLegendItem__color" title="series hidden"> + {/* changing the default viewBox for the eyeClosed icon to keep the same dimensions */} + <Icon type="eyeClosed" viewBox="-3 -3 22 22" aria-label={`series ${seriesName} is hidden`} /> + </div> + ); + } - const colorClasses = classNames('echLegendItem__color', { - 'echLegendItem__color--changable': hasColorPicker, - }); + if (hasColorPicker) { + return ( + <button + type="button" + onClick={onClick} + className="echLegendItem__color echLegendItem__color--changable" + title="change series color" + ref={ref} + > + <Icon type="dot" color={color} aria-label={`Change series color, currently ${color}`} /> + </button> + ); + } - return ( - <div - onClick={hasColorPicker ? onClick : undefined} - className={colorClasses} - aria-label="series color" - title={hasColorPicker ? 'change series color' : 'series color'} - > - <div ref={ref}> - <Icon type="dot" color={color} /> + return ( + <div className="echLegendItem__color" title="series color"> + <Icon type="dot" color={color} aria-label={`series color: ${color}`} /> </div> - </div> - ); - }), + ); + }, + ), ); Color.displayName = 'Color'; diff --git a/packages/osd-charts/src/components/legend/label.tsx b/packages/osd-charts/src/components/legend/label.tsx index 162a72eefa41..6298e0225248 100644 --- a/packages/osd-charts/src/components/legend/label.tsx +++ b/packages/osd-charts/src/components/legend/label.tsx @@ -22,19 +22,28 @@ import React, { MouseEventHandler } from 'react'; interface LabelProps { label: string; + isSeriesHidden?: boolean; onClick?: MouseEventHandler; } /** * Label component used to display text in legend item * @internal */ -export function Label({ label, onClick }: LabelProps) { +export function Label({ label, onClick, isSeriesHidden }: LabelProps) { const labelClassNames = classNames('echLegendItem__label', { 'echLegendItem__label--clickable': Boolean(onClick), }); return ( - <div className={labelClassNames} title={label} onClick={onClick}> + <button + type="button" + className={labelClassNames} + title={label} + onClick={onClick} + aria-label={ + isSeriesHidden ? `${label}; Activate to show series in graph` : `${label}; Activate to hide series in graph` + } + > {label} - </div> + </button> ); } diff --git a/packages/osd-charts/src/components/legend/legend_item.tsx b/packages/osd-charts/src/components/legend/legend_item.tsx index 0219d0d39963..6da2ef66e0ea 100644 --- a/packages/osd-charts/src/components/legend/legend_item.tsx +++ b/packages/osd-charts/src/components/legend/legend_item.tsx @@ -112,7 +112,7 @@ export class LegendListItem extends Component<LegendItemProps, LegendItemState> static displayName = 'LegendItem'; shouldClearPersistedColor = false; - colorRef = createRef<HTMLDivElement>(); + colorRef = createRef<HTMLButtonElement>(); state: LegendItemState = { isOpen: false, actionActive: false, @@ -231,12 +231,13 @@ export class LegendListItem extends Component<LegendItemProps, LegendItemState> <ItemColor ref={this.colorRef} color={color} + seriesName={label} isSeriesHidden={isSeriesHidden} hasColorPicker={hasColorPicker} onClick={this.handleColorClick(hasColorPicker)} /> - <ItemLabel label={label} onClick={this.handleLabelClick(seriesIdentifier)} /> - {showExtra && extra != null && renderExtra(extra, isSeriesHidden)} + <ItemLabel label={label} onClick={this.handleLabelClick(seriesIdentifier)} isSeriesHidden={isSeriesHidden} /> + {showExtra && extra && renderExtra(extra, isSeriesHidden)} {Action && ( <div className="echLegendItem__action"> <Action series={seriesIdentifier} color={color} label={label} /> diff --git a/packages/osd-charts/stories/legend/11_legend_actions.tsx b/packages/osd-charts/stories/legend/11_legend_actions.tsx index 86f94e71313b..d09eb8bb4b31 100644 --- a/packages/osd-charts/stories/legend/11_legend_actions.tsx +++ b/packages/osd-charts/stories/legend/11_legend_actions.tsx @@ -101,7 +101,8 @@ const getAction = (hideActions: boolean, anchorPosition: PopoverAnchorPosition): ]; const Button = ( - <div + <button + type="button" style={{ display: 'flex', justifyContent: 'center', @@ -113,7 +114,7 @@ const getAction = (hideActions: boolean, anchorPosition: PopoverAnchorPosition): onClick={() => setPopoverOpen(!popoverOpen)} > <EuiIcon size="s" type="pencil" /> - </div> + </button> ); return ( @@ -125,6 +126,7 @@ const getAction = (hideActions: boolean, anchorPosition: PopoverAnchorPosition): panelPaddingSize="none" withTitle anchorPosition={anchorPosition} + ownFocus > <EuiContextMenu initialPanelId={0} panels={getPanels(series as XYChartSeriesIdentifier)} /> </EuiPopover> @@ -137,7 +139,7 @@ const renderColorPicker = (anchorPosition: PopoverAnchorPosition): LegendColorPi onClose, onChange, }) => ( - <EuiWrappingPopover isOpen button={anchor} closePopover={onClose} anchorPosition={anchorPosition}> + <EuiWrappingPopover isOpen button={anchor} closePopover={onClose} anchorPosition={anchorPosition} ownFocus> <EuiColorPicker display="inline" color={color} onChange={onChange} /> <EuiSpacer size="m" /> <EuiButton fullWidth size="s" onClick={onClose}> diff --git a/packages/osd-charts/stories/legend/9_color_picker.tsx b/packages/osd-charts/stories/legend/9_color_picker.tsx index aa350d6a6352..fdf865c8e776 100644 --- a/packages/osd-charts/stories/legend/9_color_picker.tsx +++ b/packages/osd-charts/stories/legend/9_color_picker.tsx @@ -46,7 +46,7 @@ export const Example = () => { onChangeAction(c); }; return ( - <EuiWrappingPopover isOpen button={anchor} closePopover={handleClose} anchorPosition="leftCenter"> + <EuiWrappingPopover isOpen button={anchor} closePopover={handleClose} anchorPosition="leftCenter" ownFocus> <EuiColorPicker display="inline" color={color} onChange={handleChange} /> <EuiSpacer size="m" /> <EuiFlexItem grow={false}>