diff --git a/src-docs/src/views/loading/loading_chart.tsx b/src-docs/src/views/loading/loading_chart.tsx
index 830b93fe87d..c2270054622 100644
--- a/src-docs/src/views/loading/loading_chart.tsx
+++ b/src-docs/src/views/loading/loading_chart.tsx
@@ -1,6 +1,6 @@
import React from 'react';
-import { EuiLoadingChart } from '../../../../src/components/loading';
+import { EuiLoadingChart } from '../../../../src';
export default () => (
diff --git a/src-docs/src/views/loading/loading_example.js b/src-docs/src/views/loading/loading_example.js
index 5a20c55f077..ec48304f08e 100644
--- a/src-docs/src/views/loading/loading_example.js
+++ b/src-docs/src/views/loading/loading_example.js
@@ -109,7 +109,7 @@ export const LoadingExample = {
),
props: { EuiLoadingChart },
demo: ,
- snippet: '',
+ snippet: ['', ''],
playground: loadingChartConfig,
},
{
diff --git a/src/components/loading/__snapshots__/loading_chart.test.tsx.snap b/src/components/loading/__snapshots__/loading_chart.test.tsx.snap
index b2e1cf89346..87b3ae3dbdc 100644
--- a/src/components/loading/__snapshots__/loading_chart.test.tsx.snap
+++ b/src/components/loading/__snapshots__/loading_chart.test.tsx.snap
@@ -3,96 +3,105 @@
exports[`EuiLoadingChart is rendered 1`] = `
`;
exports[`EuiLoadingChart mono is rendered 1`] = `
`;
exports[`EuiLoadingChart size l is rendered 1`] = `
`;
exports[`EuiLoadingChart size m is rendered 1`] = `
`;
exports[`EuiLoadingChart size xl is rendered 1`] = `
`;
diff --git a/src/components/loading/_index.scss b/src/components/loading/_index.scss
index c2990867ddc..a1074c2e433 100644
--- a/src/components/loading/_index.scss
+++ b/src/components/loading/_index.scss
@@ -1,6 +1,5 @@
@import 'variables';
@import 'loading_elastic';
-@import 'loading_chart';
@import 'loading_content';
@import 'loading_logo';
@import 'loading_spinner';
diff --git a/src/components/loading/_loading_chart.scss b/src/components/loading/_loading_chart.scss
deleted file mode 100644
index 02ebd1f2829..00000000000
--- a/src/components/loading/_loading_chart.scss
+++ /dev/null
@@ -1,118 +0,0 @@
-.euiLoadingChart {
- height: $euiSizeXL;
- z-index: 500;
- overflow: hidden;
- display: inline-block;
-}
-
-/**
- * 1. Without the animation, the bars are all the same height,
- * so we apply transforms only if they can't animate
- */
-.euiLoadingChart__bar {
- height: 100%;
- width: $euiSizeS;
- display: inline-block;
- margin-bottom: -$euiSize;
- margin-left: $euiSizeXS / 2;
-
- // sass-lint:disable-block mixins-before-declarations
- @include euiCanAnimate {
- animation: euiLoadingChart 1s infinite;
- }
-
- &:nth-child(1) {
- background-color: $euiColorVis0;
-
- @include euiCantAnimate {
- transform: translateY(66%); /* 1 */
- }
- }
-
- &:nth-child(2) {
- background-color: $euiColorVis1;
- animation-delay: .1s;
-
- @include euiCantAnimate {
- transform: translateY(44%); /* 1 */
- }
- }
-
- &:nth-child(3) {
- background-color: $euiColorVis2;
- animation-delay: .2s;
-
- @include euiCantAnimate {
- transform: translateY(22%); /* 1 */
- }
- }
-
- &:nth-child(4) {
- background-color: $euiColorVis3;
- animation-delay: .3s;
- }
-}
-
-.euiLoadingChart--mono {
- .euiLoadingChart__bar {
- &:nth-child(1) {
- background-color: $euiColorLightShade;
- }
-
- &:nth-child(2) {
- background-color: shadeOrTint($euiColorLightShade, 4%, 4%);
- }
-
- &:nth-child(3) {
- background-color: shadeOrTint($euiColorLightShade, 8%, 8%);
- }
-
- &:nth-child(4) {
- background-color: shadeOrTint($euiColorLightShade, 12%, 12%);
- }
- }
-}
-
-.euiLoadingChart--medium {
- height: $euiSize;
-
- > span {
- width: $euiSizeXS / 2;
- margin-left: $euiSizeXS / 2;
- margin-bottom: $euiSizeS;
- }
-}
-
-.euiLoadingChart--large {
- height: $euiSizeL;
-
- > span {
- width: $euiSizeXS;
- margin-left: $euiSizeXS / 2;
- margin-bottom: $euiSizeL / 2;
- }
-}
-
-.euiLoadingChart--xLarge {
- height: $euiSizeXL;
-
- > span {
- width: $euiSizeS;
- margin-left: $euiSizeXS;
- margin-bottom: $euiSizeXL / 2;
- }
-}
-
-@keyframes euiLoadingChart {
- 0% {
- transform: translateY(0);
- }
-
- 50% {
- transform: translateY(66%);
- }
-
- 100% {
- transform: translateY(0);
- }
-}
diff --git a/src/components/loading/loading_chart.styles.ts b/src/components/loading/loading_chart.styles.ts
new file mode 100644
index 00000000000..7791b535045
--- /dev/null
+++ b/src/components/loading/loading_chart.styles.ts
@@ -0,0 +1,84 @@
+/*
+ * 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 { css, keyframes } from '@emotion/react';
+import { euiPaletteColorBlind, shadeOrTint, UseEuiTheme } from '../../services';
+import { euiCanAnimate } from '../../global_styling';
+
+export const euiLoadingChartStyles = ({ euiTheme }: UseEuiTheme) => ({
+ euiLoadingChart: css`
+ overflow: hidden;
+ display: inline-flex;
+ `,
+ m: css`
+ height: ${euiTheme.size.base};
+ gap: ${euiTheme.size.xxs};
+ `,
+ l: css`
+ height: ${euiTheme.size.l};
+ gap: ${euiTheme.size.xxs};
+ `,
+ xl: css`
+ height: ${euiTheme.size.xl};
+ gap: ${euiTheme.size.xs};
+ `,
+});
+
+export const euiLoadingChartBarStyles = ({ euiTheme }: UseEuiTheme) => ({
+ euiLoadingChart__bar: css`
+ height: 100%;
+ display: inline-block;
+ `,
+ m: css`
+ width: ${euiTheme.size.xxs};
+ margin-block-end: ${euiTheme.size.s};
+ `,
+ l: css`
+ width: ${euiTheme.size.xs};
+ margin-block-end: ${euiTheme.size.m};
+ `,
+ xl: css`
+ width: ${euiTheme.size.s};
+ margin-block-end: ${euiTheme.size.base};
+ `,
+});
+
+const barAnimation = keyframes`
+ 0% {
+ transform: translateY(0);
+ }
+
+ 50% {
+ transform: translateY(66%);
+ }
+
+ 100% {
+ transform: translateY(0);
+ }
+`;
+
+export const _barIndex = (
+ index: number,
+ mono: boolean,
+ { euiTheme, colorMode }: UseEuiTheme
+) => {
+ const backgroundColor = mono
+ ? shadeOrTint(euiTheme.colors.lightShade, index * 0.04, colorMode)
+ : euiPaletteColorBlind()[index];
+
+ return css`
+ background-color: ${backgroundColor};
+ // Without the animation, the bars are all the same height,
+ // so we apply transforms which are overridden by the animation if animations are allowed
+ transform: translateY(${22 * index}%);
+
+ ${euiCanAnimate} {
+ animation: ${barAnimation} 1s ${`.${index}s`} infinite;
+ }
+ `;
+};
diff --git a/src/components/loading/loading_chart.test.tsx b/src/components/loading/loading_chart.test.tsx
index 7aebef83b8c..bb19647a251 100644
--- a/src/components/loading/loading_chart.test.tsx
+++ b/src/components/loading/loading_chart.test.tsx
@@ -9,10 +9,13 @@
import React from 'react';
import { render } from 'enzyme';
import { requiredProps } from '../../test/required_props';
+import { shouldRenderCustomStyles } from '../../test/internal';
import { EuiLoadingChart, SIZES } from './loading_chart';
describe('EuiLoadingChart', () => {
+ shouldRenderCustomStyles();
+
test('is rendered', () => {
const component = render();
@@ -24,6 +27,7 @@ describe('EuiLoadingChart', () => {
expect(component).toMatchSnapshot();
});
+
describe('size', () => {
SIZES.forEach((size) => {
test(`${size} is rendered`, () => {
diff --git a/src/components/loading/loading_chart.tsx b/src/components/loading/loading_chart.tsx
index f345a3d6e2c..6b2784ee80f 100644
--- a/src/components/loading/loading_chart.tsx
+++ b/src/components/loading/loading_chart.tsx
@@ -9,6 +9,14 @@
import React, { FunctionComponent, HTMLAttributes } from 'react';
import classNames from 'classnames';
import { CommonProps, keysOf } from '../common';
+import { useEuiTheme } from '../../services';
+
+import {
+ euiLoadingChartStyles,
+ euiLoadingChartBarStyles,
+ _barIndex,
+} from './loading_chart.styles';
+import { useEuiI18n } from '../i18n';
const sizeToClassNameMap = {
m: 'euiLoadingChart--medium',
@@ -30,8 +38,14 @@ export const EuiLoadingChart: FunctionComponent = ({
size = 'm',
mono = false,
className,
+ 'aria-label': ariaLabel,
...rest
}) => {
+ const defaultAriaLabel = useEuiI18n('euiLoadingChart.ariaLabel', 'Loading');
+ const euiTheme = useEuiTheme();
+ const styles = euiLoadingChartStyles(euiTheme);
+ const barStyles = euiLoadingChartBarStyles(euiTheme);
+
const classes = classNames(
'euiLoadingChart',
{ 'euiLoadingChart--mono': mono },
@@ -39,12 +53,29 @@ export const EuiLoadingChart: FunctionComponent = ({
sizeToClassNameMap[size]
);
+ const cssStyles = [styles.euiLoadingChart, styles[size]];
+ const cssBarStyles = (index: number) => {
+ return [
+ barStyles.euiLoadingChart__bar,
+ barStyles[size],
+ _barIndex(index, mono, euiTheme),
+ ];
+ };
+
+ const bars = [];
+ for (let index = 0; index < 4; index++) {
+ bars.push();
+ }
+
return (
-
-
-
-
-
+
+ {bars}
);
};
diff --git a/src/services/color/manipulation.ts b/src/services/color/manipulation.ts
index 61b74fc518e..39e1c3a69a1 100644
--- a/src/services/color/manipulation.ts
+++ b/src/services/color/manipulation.ts
@@ -7,6 +7,7 @@
*/
import chroma, { Color } from 'chroma-js';
+import { EuiThemeColorModeStandard } from '../theme';
import { isValidHex } from './is_valid_hex';
const inOriginalFormat = (originalColor: string, newColor: Color) => {
@@ -41,6 +42,34 @@ export const shade = (color: string, ratio: number) => {
return inOriginalFormat(color, shade);
};
+/**
+ * Returns the tinted color for light mode and shaded color for dark mode
+ * @param color - Color to mix with white
+ * @param ratio - Mix weight. From 0-1. Larger value indicates more white.
+ * @param colorMode - Light or dark only
+ */
+export const tintOrShade = (
+ color: string,
+ ratio: number,
+ colorMode: EuiThemeColorModeStandard
+) => {
+ return colorMode === 'DARK' ? shade(color, ratio) : tint(color, ratio);
+};
+
+/**
+ * Returns the shaded color for light mode and tinted color for dark mode
+ * @param color - Color to mix with white
+ * @param ratio - Mix weight. From 0-1. Larger value indicates more white.
+ * @param colorMode - Light or dark only
+ */
+export const shadeOrTint = (
+ color: string,
+ ratio: number,
+ colorMode: EuiThemeColorModeStandard
+) => {
+ return colorMode === 'DARK' ? tint(color, ratio) : shade(color, ratio);
+};
+
/**
* Increases the saturation of a color by manipulating the hsl saturation.
* @param color - Color to manipulate
diff --git a/src/services/index.ts b/src/services/index.ts
index 351641139ba..48902a7eaa0 100644
--- a/src/services/index.ts
+++ b/src/services/index.ts
@@ -62,6 +62,8 @@ export {
transparentize,
tint,
shade,
+ tintOrShade,
+ shadeOrTint,
saturate,
desaturate,
lightness,
diff --git a/upcoming_changelogs/5821.md b/upcoming_changelogs/5821.md
new file mode 100644
index 00000000000..95369cf3da0
--- /dev/null
+++ b/upcoming_changelogs/5821.md
@@ -0,0 +1,5 @@
+- Improved accessibility of `EuiLoadingChart`
+
+**CSS-in-JS conversions**
+
+- Converted `EuiLoadingChart` to Emotion