diff --git a/CHANGELOG.md b/CHANGELOG.md
index bc1044a07be..782831a7a38 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
- Added i18n to `EuiTableHeaderCell` ([#3094](https://github.com/elastic/eui/pull/3094))
- Added `number` and `string` to `size` type of `EuiImage` for setting custom sizes ([#3012](https://github.com/elastic/eui/pull/3012))
- Improved `EuiButtonEmpty` focus state when the `color` type is `text` ([#3135](https://github.com/elastic/eui/pull/3135))
+- Added `EuiLoadingElastic` component ([#3017](https://github.com/elastic/eui/pull/3017))
**Bug Fixes**
diff --git a/src-docs/src/views/loading/loading_elastic.tsx b/src-docs/src/views/loading/loading_elastic.tsx
new file mode 100644
index 00000000000..6b589fea615
--- /dev/null
+++ b/src-docs/src/views/loading/loading_elastic.tsx
@@ -0,0 +1,12 @@
+import React from 'react';
+
+import { EuiLoadingElastic } from '../../../../src/components/loading';
+
+export default () => (
+
+
+
+
+
+
+);
diff --git a/src-docs/src/views/loading/loading_example.js b/src-docs/src/views/loading/loading_example.js
index 7a6e767f43d..37a35f692f4 100644
--- a/src-docs/src/views/loading/loading_example.js
+++ b/src-docs/src/views/loading/loading_example.js
@@ -7,6 +7,7 @@ import { GuideSectionTypes } from '../../components';
import {
EuiCode,
EuiLoadingKibana,
+ EuiLoadingElastic,
EuiLoadingSpinner,
EuiLoadingChart,
EuiLoadingContent,
@@ -16,6 +17,10 @@ import LoadingKibana from './loading_kibana';
const loadingKibanaSource = require('!!raw-loader!./loading_kibana');
const loadingKibanaHtml = renderToHtml(LoadingKibana);
+import LoadingElastic from './loading_elastic';
+const loadingElasticSource = require('!!raw-loader!./loading_elastic');
+const loadingElasticHtml = renderToHtml(LoadingElastic);
+
import LoadingChart from './loading_chart';
const loadingChartSource = require('!!raw-loader!./loading_chart');
const loadingChartHtml = renderToHtml(LoadingChart);
@@ -53,6 +58,28 @@ export const LoadingExample = {
demo: ,
snippet: '',
},
+ {
+ title: 'Elastic',
+ source: [
+ {
+ type: GuideSectionTypes.JS,
+ code: loadingElasticSource,
+ },
+ {
+ type: GuideSectionTypes.HTML,
+ code: loadingElasticHtml,
+ },
+ ],
+ text: (
+
+ Elastic logo based load. Should only be used in very large panels,
+ like bootup screens.
+
+ ),
+ props: { EuiLoadingElastic },
+ demo: ,
+ snippet: '',
+ },
{
title: 'Chart',
source: [
diff --git a/src/components/index.js b/src/components/index.js
index 91080c4ccbf..9efdf29620a 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -171,6 +171,7 @@ export { EuiI18n, EuiI18nNumber } from './i18n';
export {
EuiLoadingKibana,
+ EuiLoadingElastic,
EuiLoadingChart,
EuiLoadingContent,
EuiLoadingSpinner,
diff --git a/src/components/loading/_index.scss b/src/components/loading/_index.scss
index c34857f75c8..75bfa724f35 100644
--- a/src/components/loading/_index.scss
+++ b/src/components/loading/_index.scss
@@ -1,5 +1,6 @@
@import 'variables';
@import 'loading_kibana';
+@import 'loading_elastic';
@import 'loading_chart';
@import 'loading_content';
@import 'loading_spinner';
diff --git a/src/components/loading/_loading_elastic.scss b/src/components/loading/_loading_elastic.scss
new file mode 100644
index 00000000000..0dbd804074b
--- /dev/null
+++ b/src/components/loading/_loading_elastic.scss
@@ -0,0 +1,83 @@
+.euiLoadingElastic {
+ position: relative;
+ display: inline-block;
+}
+
+.euiLoadingElastic--medium {
+ width: $euiSize;
+}
+
+.euiLoadingElastic--large {
+ width: $euiSizeL;
+}
+
+.euiLoadingElastic--xLarge {
+ width: $euiSizeXL;
+}
+
+.euiLoadingElastic--xxLarge {
+ width: $euiSizeXXL;
+}
+
+
+.euiLoadingElastic path {
+ animation-name: euiLoadingElastic;
+ animation-fill-mode: forwards;
+ animation-direction: alternate;
+ transform-style: preserve-3d;
+ animation-duration: 1s;
+ animation-timing-function: cubic-bezier(0, .63, .49, 1);
+ animation-iteration-count: infinite;
+ transform-origin: 50% 50%;
+}
+
+.euiLoadingElastic path:nth-of-type(1) {
+ animation-delay: 0s;
+}
+
+.euiLoadingElastic path:nth-of-type(2) {
+ animation-delay: .035s;
+}
+
+.euiLoadingElastic path:nth-of-type(3) {
+ animation-delay: .125s;
+}
+
+.euiLoadingElastic path:nth-of-type(4) {
+ animation-delay: .155s;
+}
+
+.euiLoadingElastic path:nth-of-type(5) {
+ animation-delay: .075s;
+}
+
+.euiLoadingElastic path:nth-of-type(6) {
+ animation-delay: .06s;
+};
+
+
+@keyframes euiLoadingElastic {
+ 0% {
+ transform: scale3d(0, 0, -.7);
+ opacity: 0;
+ }
+
+ 40% {
+ transform: scale3d(1, 1, 2);
+ opacity: 1;
+ }
+
+ 50% {
+ transform: scale3d(.99, .99, 2);
+ }
+
+ 70% {
+ transform: scale3d(.96, .96, -2.5);
+ }
+
+ 100% {
+ transform: scale3d(.98, .98, 2);
+ }
+
+}
+
diff --git a/src/components/loading/index.ts b/src/components/loading/index.ts
index cc4fb89ef07..154666d4f40 100644
--- a/src/components/loading/index.ts
+++ b/src/components/loading/index.ts
@@ -1,4 +1,5 @@
export { EuiLoadingKibana } from './loading_kibana';
+export { EuiLoadingElastic } from './loading_elastic';
export { EuiLoadingChart } from './loading_chart';
export { EuiLoadingContent } from './loading_content';
export { EuiLoadingSpinner } from './loading_spinner';
diff --git a/src/components/loading/loading_elastic.tsx b/src/components/loading/loading_elastic.tsx
new file mode 100644
index 00000000000..4ab6968e668
--- /dev/null
+++ b/src/components/loading/loading_elastic.tsx
@@ -0,0 +1,33 @@
+import React, { HTMLAttributes, FunctionComponent } from 'react';
+import classNames from 'classnames';
+import { CommonProps, keysOf } from '../common';
+import { EuiIcon } from '../icon';
+
+const sizeToClassNameMap = {
+ m: 'euiLoadingElastic--medium',
+ l: 'euiLoadingElastic--large',
+ xl: 'euiLoadingElastic--xLarge',
+ xxl: 'euiLoadingElastic--xxLarge',
+};
+
+export const SIZES = keysOf(sizeToClassNameMap);
+
+export interface EuiLoadingElasticProps {
+ size?: keyof typeof sizeToClassNameMap;
+}
+
+export const EuiLoadingElastic: FunctionComponent<
+ CommonProps & HTMLAttributes & EuiLoadingElasticProps
+> = ({ size = 'm', className, ...rest }) => {
+ const classes = classNames(
+ 'euiLoadingElastic',
+ sizeToClassNameMap[size],
+ className
+ );
+
+ return (
+
+
+
+ );
+};