Skip to content

Commit

Permalink
New [EuiLoaderLogo] and other loader updates (#4835)
Browse files Browse the repository at this point in the history
* NEW: EuiLoadingLogo

* Pausing animations when `prefers-reduced-motion` is on

* Updating text content loader color to be lighter

* [EuiEmptyPrompt] Added `icon` for custom icon

And cleaned up spacing

* Move `null` role to fix a11y tests and allow overriding

In EuiPageTemplate when `centeredContent` and no sidebar
  • Loading branch information
cchaos authored Jun 1, 2021
1 parent 92cc223 commit aff9828
Show file tree
Hide file tree
Showing 28 changed files with 690 additions and 208 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
- Added `color` and `size` props and added support for click event to `EuiBetaBadge` ([#4798](https://github.com/elastic/eui/pull/4798))
- Added `documentation` and `layers` glyphs to `EuiIcon` ([#4833](https://github.com/elastic/eui/pull/4833))
- Updated `EuiTourStep`'s `title` and `subtitle` prop type from `string` to `ReactNode` ([#4841](https://github.com/elastic/eui/pull/4841))
- Added `euiCantAnimate` Sass mixin ([#4835](https://github.com/elastic/eui/pull/4835))
- Added new `EuiLoadingLogo` component ([#4835](https://github.com/elastic/eui/pull/4835))
- Added `icon` props to `EuiEmptyPrompt` for custom icons ([#4835](https://github.com/elastic/eui/pull/4835))
- Deprecated `EuiLoadingKibana` ([#4835](https://github.com/elastic/eui/pull/4135))
- Paused animations when `prefers-reduced-motion` is on for loader components ([#4835](https://github.com/elastic/eui/pull/4135))

**Bug fixes**

Expand Down
17 changes: 17 additions & 0 deletions src-docs/src/views/empty_prompt/empty_prompt_error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';

import { EuiEmptyPrompt } from '../../../../src/components';

export default () => (
<EuiEmptyPrompt
iconType="alert"
iconColor="danger"
title={<h2>Error loading Dashboards</h2>}
body={
<p>
There was an error loading the Dashboard application. Contact your
administrator for help.
</p>
}
/>
);
131 changes: 107 additions & 24 deletions src-docs/src/views/empty_prompt/empty_prompt_example.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { Fragment } from 'react';

import { renderToHtml } from '../../services';
import { Link } from 'react-router-dom';

import { GuideSectionTypes } from '../../components';

Expand All @@ -10,7 +9,6 @@ import emptyPromptConfig from './playground';

import EmptyPrompt from './empty_prompt';
const emptyPromptSource = require('!!raw-loader!./empty_prompt');
const emptyPromptHtml = renderToHtml(EmptyPrompt);
const emptyPromptSnippet = `<EuiEmptyPrompt
iconType="editorStrike"
title={<h2>You have no spice</h2>}
Expand All @@ -20,7 +18,6 @@ const emptyPromptSnippet = `<EuiEmptyPrompt

import Custom from './custom';
const customSource = require('!!raw-loader!./custom');
const customHtml = renderToHtml(Custom);
const customSnippet = `<EuiEmptyPrompt
iconType="editorStrike"
title={<h2>You have no spice</h2>}
Expand All @@ -31,12 +28,29 @@ const customSnippet = `<EuiEmptyPrompt

import Simple from './simple';
const simpleSource = require('!!raw-loader!./simple');
const simpleHtml = renderToHtml(Simple);
const simpleSnippet = `<EuiEmptyPrompt
title={<h2>You have no spice</h2>}
actions={multipleActions}
/>`;

import Loading from './empty_prompt_loading';
const loadingSource = require('!!raw-loader!./empty_prompt_loading');
const loadingSnippet = `<EuiEmptyPrompt
icon={<EuiLoadingLogo logo="logoKibana" size="xl" />}
title={<h2>Loading</h2>}
/>`;

import Error from './empty_prompt_error';
const errorSource = require('!!raw-loader!./empty_prompt_error');
const errorSnippet = `<EuiEmptyPrompt
iconType="alert"
iconColor="danger"
title={<h2>There was an error</h2>}
/>`;

import States from './empty_prompt_states';
const statesSource = require('!!raw-loader!./empty_prompt_states');

export const EmptyPromptExample = {
title: 'Empty prompt',
sections: [
Expand All @@ -46,20 +60,18 @@ export const EmptyPromptExample = {
type: GuideSectionTypes.JS,
code: emptyPromptSource,
},
{
type: GuideSectionTypes.HTML,
code: emptyPromptHtml,
},
],
text: (
<p>
Use the <strong>EuiEmptyPrompt</strong> as a placeholder for an empty
table or list of content.
Use the <strong>EuiEmptyPrompt</strong> as a placeholder for any type
of empty content. They are especially helpful for replacing entire
pages that contain no content.
</p>
),
props: { EuiEmptyPrompt },
demo: <EmptyPrompt />,
snippet: emptyPromptSnippet,
playground: emptyPromptConfig,
},
{
title: 'Custom sizes and colors',
Expand All @@ -68,15 +80,12 @@ export const EmptyPromptExample = {
type: GuideSectionTypes.JS,
code: customSource,
},
{
type: GuideSectionTypes.HTML,
code: customHtml,
},
],
text: (
<p>
You can control sizes and colors with the <EuiCode>iconColor</EuiCode>
, and <EuiCode>titleSize</EuiCode> props.
You can control the title size and icon color with the{' '}
<EuiCode>titleSize</EuiCode> and <EuiCode>iconColor</EuiCode> props
respectively.
</p>
),
props: { EuiEmptyPrompt },
Expand All @@ -90,24 +99,98 @@ export const EmptyPromptExample = {
type: GuideSectionTypes.JS,
code: simpleSource,
},
{
type: GuideSectionTypes.HTML,
code: simpleHtml,
},
],
text: (
<Fragment>
<p>You can remove parts of the prompt to simplify it, if you wish.</p>
<p>You can remove parts of the prompt to simplify it.</p>
<p>
You can also provide an array of multiple actions. Be sure to list
primary actions first and secondary actions last.
primary actions first and secondary actions as empty buttons.
</p>
</Fragment>
),
props: { EuiEmptyPrompt },
demo: <Simple />,
snippet: simpleSnippet,
},
{
title: 'Loading and error prompts',
source: [
{
type: GuideSectionTypes.JS,
code: loadingSource,
},
],
text: (
<>
<p>
Empty prompts can also be used to emulate loading and error states,
by utilizing the same patterns.
</p>
<p>
For <strong>loading</strong> states, you can simply replace the{' '}
<EuiCode>iconType</EuiCode> with a custom <EuiCode>icon</EuiCode> by
passing in one of our{' '}
<Link to="/display/loading">loading components</Link>.
</p>
</>
),
props: { EuiEmptyPrompt },
demo: <Loading />,
snippet: loadingSnippet,
},
{
source: [
{
type: GuideSectionTypes.JS,
code: errorSource,
},
],
text: (
<>
<p>
For <strong>error</strong> states, you can simply set the{' '}
<EuiCode>iconColor</EuiCode> to <EuiCode>danger</EuiCode> and/or
wrap the whole prompt in a <EuiCode>danger</EuiCode> colored{' '}
<Link to="/display/panel">
<strong>EuiPanel</strong>
</Link>
.
</p>
</>
),
props: { EuiEmptyPrompt },
demo: <Error />,
snippet: errorSnippet,
},
{
source: [
{
type: GuideSectionTypes.JS,
code: statesSource,
},
],
text: (
<>
<p>
You can then tie all three states together to create a seamless
loading to empty or loading to error experience. The following
example shows how to encorprate these states with{' '}
<Link to="/layout/page#simple-layout-with-centered-content">
<strong>EuiPageTemplate</strong>
</Link>{' '}
using <EuiCode>{'template="centeredContent"'}</EuiCode> and passing{' '}
<EuiCode>{'color="danger"'}</EuiCode> to the{' '}
<EuiCode>pageContentProps</EuiCode> for the error state.
</p>
</>
),
props: { EuiEmptyPrompt },
demo: (
<div className="guideDemo__highlightLayout">
<States />
</div>
),
},
],
playground: emptyPromptConfig,
};
10 changes: 10 additions & 0 deletions src-docs/src/views/empty_prompt/empty_prompt_loading.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';

import { EuiEmptyPrompt, EuiLoadingLogo } from '../../../../src/components';

export default () => (
<EuiEmptyPrompt
icon={<EuiLoadingLogo logo="logoKibana" size="xl" />}
title={<h2>Loading Dashboards</h2>}
/>
);
74 changes: 74 additions & 0 deletions src-docs/src/views/empty_prompt/empty_prompt_states.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { useState, useEffect } from 'react';

import {
EuiEmptyPrompt,
EuiPageTemplate,
EuiLoadingLogo,
EuiButton,
} from '../../../../src/components';

export default () => {
const states = ['loading1', 'error', 'loading2', 'empty'];

const [currentState, setCurrentState] = useState(states[0]);

const searchTimeout = setTimeout(() => {
// Cycle through the array of states
const index = states.indexOf(currentState);
setCurrentState(index < states.length - 1 ? states[index + 1] : states[0]);
}, 3000);

useEffect(() => {
return () => {
clearTimeout(searchTimeout);
};
});

let emptyPromptProps;
switch (currentState) {
case 'error':
emptyPromptProps = {
iconType: 'alert',
iconColor: 'danger',
title: <h2>Error loading Dashboards</h2>,
body: (
<p>
There was an error loading the Dashboard application. Contact your
administrator for help.
</p>
),
};
break;
case 'empty':
emptyPromptProps = {
iconType: 'dashboardApp',
iconColor: 'default',
title: <h2>Dashboards</h2>,
body: <p>You don&apos;t have any dashboards yet.</p>,
actions: [
<EuiButton fill iconType="plusInCircleFilled">
Create new dashboard
</EuiButton>,
],
};
break;

default:
emptyPromptProps = {
icon: <EuiLoadingLogo logo="logoKibana" size="xl" />,
title: <h2>Loading Dashboards</h2>,
};
break;
}

return (
<EuiPageTemplate
template="centeredContent"
pageContentProps={{
color: currentState === 'error' ? 'danger' : 'subdued',
role: null, // For passing a11y tests in EUI docs only
}}>
<EuiEmptyPrompt {...emptyPromptProps} />
</EuiPageTemplate>
);
};
7 changes: 3 additions & 4 deletions src-docs/src/views/empty_prompt/playground.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default () => {

propsToUse.title = {
...propsToUse.title,
value: '<>You have no spice</>',
value: '<h2>You have no spice</h2>',
type: PropTypes.ReactNode,
};

Expand All @@ -36,10 +36,9 @@ export default () => {
propsToUse.body.type = PropTypes.String;
propsToUse.body.value = `Navigators use massive amounts of spice to gain a limited form of
prescience. This allows them to safely navigate interstellar space,
enabling trade and travel throughout the galaxy.
`;
enabling trade and travel throughout the galaxy.`;

propsToUse.iconType = iconValidator(propsToUse.iconType);
propsToUse.iconType = iconValidator(propsToUse.iconType, 'editorStrike');

return {
config: {
Expand Down
5 changes: 4 additions & 1 deletion src-docs/src/views/loading/loading_elastic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import { EuiLoadingElastic } from '../../../../src/components/loading';

export default () => (
<div>
<EuiLoadingElastic size="m" />
<EuiLoadingElastic />
&emsp;
<EuiLoadingElastic size="l" />
&emsp;
<EuiLoadingElastic size="xl" />
&emsp;
<EuiLoadingElastic size="xxl" />
</div>
);
Loading

0 comments on commit aff9828

Please sign in to comment.