Skip to content

Commit

Permalink
Add new EuiSkeleton components; deprecate EuiLoadingContent (#6558)
Browse files Browse the repository at this point in the history
* EuiSkeleton components (#6502)

* Setup EuiSkeleton files and folders structure

* Moved Skeleton under the Display side menu category

* Component variants setup

* feat: skeleton setup [text, rect, circle]

* feat: added skeleton item draft and other minors

* chore: renamed sizes

* feat: added Heading in favor of Rect component

* Update src-docs/src/views/skeleton/skeleton_example.js

Co-authored-by: Elizabet Oliveira <[email protected]>

* Update src-docs/src/views/skeleton/skeleton_example.js

Co-authored-by: Elizabet Oliveira <[email protected]>

* Update src-docs/src/views/skeleton/skeleton_example.js

Co-authored-by: Elizabet Oliveira <[email protected]>

* chore: wrapped p with EuiText and indentation

* chore: removed useless styles

* chore: centralized and renamed skeleton animation keyfram

* refactor: renamed euiSkeletonHeading to euiSkeletonTitle and updated sizes with euiTitle ones

* chore: renamed EuiSkeletonItem to EuiSkeletonRectangle

* Remove hard-coded `euiSkeletonTitleStyles` heights map

- in favor of calling `euiTitle`'s font utils and grabbing `lineHeight` directly from it

* [docs] Add EuiSwitch toggle to EuiSkeletonTitle tests

- this toggle help demonstrates to consumers how to conditionally switch from loading to non-loading components, and also allows us to test heights

* Add `size` prop to `EuiSkeletonText`

+ add calculations & offsets to account for text scale

+ update docs to allow changing size & toggle between text to test visual behavior

* [docs] Add loading toggle for EuiSkeletonCircle

+ prettier fixes

* [PR feedback] Fix incorrect BEM naming; remove extra modifier classes

- BEM: `__` should only be used for children/descendants, and these are parent-level styles and should use regular camelCasing

- modifier classes removal: we're moving away from setting these extra CSS classes, which do not have any actual CSS tied to them (since we're using Emotion CSS-in-JS instead). The top-level className remains as an API for consumers to hook into for overrides if needed.

* [PR feedback] DRY out all `aria`/a11y attributes to reusable helper

- not all components were correctly receiving all the aria attrs they should have been - this helper fixes that

* [PR feedback] Rename` _skeleton` to `utils`, DRY out repeated gradient CSS

- `utils` better matches naming/architecture convention in other components (+ ignore i18n complaint)

+ tweak gradient size and animation for circle and rectangle components to look a bit better

+ rename global animation to a more generic name/usage

* [PR feedback] DRY out repeated CSS between modifiers
- should exist in the base styles instead

+ bonus - DRY out `logicalSizeCSS` to only require 1 input if both sides are the same

* [PR feedback] Avoid dynamic wildcard Emotion classes - use `style` instead

The reason for this is performance - Emotion generates a completely new hash/className for every single possible permutation of width/height passed to it. We want to avoid this for wildcard prop-based styles and use inline styles instead

* [PR feedback] Improve/add unit tests

+ cover all props

+ prefer RTL over Enzyme (part of ongoing migration)

+ fix type issue found during testing

* [docs] Add toggle to EuiSkeletonRectangle example

* [PR feedback] EuiSkeletonRectangle tweaks

- allow numbers as well as strings - now that we're using inline `style`s for the dimensions, React accepts numbers as well (which matches EuiImage API)

- remove image URI in favor of a picsum link

- set width/height on img to prevent page jumping

* [PR feedback] Tweak EuiSkeletonText typing

- for whatever reason, using `|` prints the line numbers in non-ascending order in the props table - using an array and `as const` fixes this, and is reusable in tests

* [PR feedback] Convert docs files to Typescript

+ improve mobile display of demos

* [PR feedback] Documentation copy + order

- move EuiSkeletonCircle slightly lower in docs order - EuiSkeletonText is likely going to be more popular since it already exists

- misc copy tweaks

* [Docs] Set up playgrounds

* DRY out aria-label further

- since `euiLoadingStrings.ariaLabel` already exists, just reuse that instead of making our translators re-translate the same string

* Add fix for Safari workaround

- note: this is already broken on prod as well for `EuiLoadingContent`

* Changelog

* chore: comment typo and zero value for border radius

---------

Co-authored-by: Elizabet Oliveira <[email protected]>
Co-authored-by: Constance Chen <[email protected]>

* Design review (#6560)

* Deprecate `EuiLoadingContent` in favor of `EuiSkeletonText` (#6557)

* Deprecate EuiLoadingContent + dogfood EuiSkeletonText

* Remove unnecessary tests

- leave a basic `is rendered` test in just to confirm the content, but should be deleted in the future

* Update documentation with deprecation notice

* changelog

* Fix Emotion styles var name

* [EuiSkeletonLoading] Improve loading accessibility and bake in `isLoading` API handling (#6562)

* Create reusable `EuiSkeletonLoading` component

- for DRYing out correct accessibility attributes, wrappers, and a simpler loading API

* Convert `EuiSkeletonText` to dogfood new `EuiSkeletonLoading` wrapper

+ update docs/example to how `isLoading`/`children` behavior

* Convert `EuiSkeletonTitle` to dogfood new `EuiSkeletonLoading` wrapper

+ update docs/example to how `isLoading`/`children` behavior

* Convert `EuiSkeletonRectangle` to dogfood new `EuiSkeletonLoading` wrapper

+ update docs/example to how `isLoading`/`children` behavior

* Convert `EuiSkeletonRectangle` to dogfood new `EuiSkeletonLoading` wrapper

+ update docs/example to how `isLoading`/`children` behavior

* Add docs example + a11y callout for `EuiSkeletonLoading`

* Fix annoying Safari bug popping up again

- the new `aria-busy` wrapper appears to make the `z-index` workaround not work, so use `isolation` (https://developer.mozilla.org/en-US/docs/Web/CSS/isolation) instead to force the necessary stacking context

* changelog

* [PR feedback] use `div` instead of `section`

(or in this case, `EuiPanel` for looks

* [PR feedback] Add `children` to playground

- Missed in #6562

- Playground still isn't perfect; but good enough for now

* Tweak default `EuiSkeletonCircle` size to match default `EuiAvatar` size

---------

Co-authored-by: Andrea Della Valle <[email protected]>
Co-authored-by: Elizabet Oliveira <[email protected]>
  • Loading branch information
3 people authored Jan 31, 2023
1 parent f8cfada commit a8de8df
Show file tree
Hide file tree
Showing 42 changed files with 2,094 additions and 456 deletions.
3 changes: 3 additions & 0 deletions src-docs/src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ import { SelectableExample } from './views/selectable/selectable_example';

import { SideNavExample } from './views/side_nav/side_nav_example';

import { SkeletonExample } from './views/skeleton/skeleton_example';

import { SpacerExample } from './views/spacer/spacer_example';

import { StatExample } from './views/stat/stat_example';
Expand Down Expand Up @@ -561,6 +563,7 @@ const navigation = [
LoadingExample,
NotificationEventExample,
ProgressExample,
SkeletonExample,
StatExample,
TextExample,
TimelineExample,
Expand Down
9 changes: 0 additions & 9 deletions src-docs/src/views/loading/loading_content.tsx

This file was deleted.

33 changes: 12 additions & 21 deletions src-docs/src/views/loading/loading_example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,19 @@ import { Link } from 'react-router-dom';
import { GuideSectionTypes } from '../../components';

import {
EuiCode,
EuiText,
EuiLoadingLogo,
EuiLoadingElastic,
EuiLoadingSpinner,
EuiLoadingChart,
EuiLoadingContent,
EuiCallOut,
} from '../../../../src/components';

import {
loadingElasticConfig,
loadingChartConfig,
loadingLogoConfig,
loadingSpinnerConfig,
loadingContentConfig,
// @ts-ignore Importing from JS
} from './playground';

Expand All @@ -40,9 +38,6 @@ const loadingChartSource = require('!!raw-loader!./loading_chart');
import LoadingSpinner from './loading_spinner';
const loadingSpinnerSource = require('!!raw-loader!./loading_spinner');

import LoadingContent from './loading_content';
const loadingContentSource = require('!!raw-loader!./loading_content');

export const LoadingExample = {
title: 'Loading',
intro: (
Expand Down Expand Up @@ -144,23 +139,19 @@ export const LoadingExample = {
},
{
title: 'Text content',
source: [
{
type: GuideSectionTypes.JS,
code: loadingContentSource,
},
],
text: (
<p>
<strong>EuiLoadingContent</strong> is a simple loading animation for
displaying placeholder text content. You can pass in a number of{' '}
<EuiCode>lines</EuiCode> between 1 and 10.
</p>
<EuiCallOut
title="EuiLoadingContent has been deprecated"
iconType="symlink"
>
<p>
<strong>EuiLoadingContent</strong> has been deprecated in favor of{' '}
<strong>EuiSkeletonText</strong>. Head on over to the{' '}
<Link to="/display/skeleton">Skeleton documentation page</Link> to
see more loading skeleton usages.
</p>
</EuiCallOut>
),
props: { EuiLoadingContent },
demo: <LoadingContent />,
snippet: '<EuiLoadingContent lines={3} />',
playground: loadingContentConfig,
},
],
};
29 changes: 0 additions & 29 deletions src-docs/src/views/loading/playground.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import {
EuiLoadingChart,
EuiLoadingLogo,
EuiLoadingSpinner,
EuiLoadingContent,
} from '../../../../src/components/';
import { PropTypes } from 'react-view';

export const loadingElasticConfig = () => {
const docgenInfo = Array.isArray(EuiLoadingElastic.__docgenInfo)
Expand Down Expand Up @@ -99,30 +97,3 @@ export const loadingSpinnerConfig = () => {
},
};
};

export const loadingContentConfig = () => {
const docgenInfo = Array.isArray(EuiLoadingContent.__docgenInfo)
? EuiLoadingContent.__docgenInfo[0]
: EuiLoadingContent.__docgenInfo;
const propsToUse = propUtilityForPlayground(docgenInfo.props);

propsToUse.lines = {
...propsToUse.lines,
type: PropTypes.Number,
};

return {
config: {
componentName: 'EuiLoadingContent',
props: propsToUse,
scope: {
EuiLoadingContent,
},
imports: {
'@elastic/eui': {
named: ['EuiLoadingContent'],
},
},
},
};
};
152 changes: 152 additions & 0 deletions src-docs/src/views/skeleton/playground.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import { PropTypes } from 'react-view';
import {
EuiSkeletonText,
EuiText,
EuiSkeletonTitle,
EuiTitle,
EuiSkeletonCircle,
EuiAvatar,
EuiSkeletonRectangle,
EuiPanel,
} from '../../../../src/components/';
import { propUtilityForPlayground } from '../../services/playground';

export const skeletonTextConfig = () => {
const docgenInfo = Array.isArray(EuiSkeletonText.__docgenInfo)
? EuiSkeletonText.__docgenInfo[0]
: EuiSkeletonText.__docgenInfo;
const propsToUse = propUtilityForPlayground(docgenInfo.props);

propsToUse.lines = {
...propsToUse.lines,
type: PropTypes.Number,
value: 3,
};

propsToUse.children = {
type: PropTypes.ReactNode,
value: `<EuiText>
<p>Hello world</p>
</EuiText>`,
hidden: false,
};

return {
config: {
componentName: 'EuiSkeletonText',
props: propsToUse,
scope: {
EuiSkeletonText,
EuiText,
},
imports: {
'@elastic/eui': {
named: ['EuiSkeletonText', 'EuiText'],
},
},
},
};
};

export const skeletonTitleConfig = () => {
const docgenInfo = Array.isArray(EuiSkeletonTitle.__docgenInfo)
? EuiSkeletonTitle.__docgenInfo[0]
: EuiSkeletonTitle.__docgenInfo;
const propsToUse = propUtilityForPlayground(docgenInfo.props);

propsToUse.children = {
...propsToUse.children,
type: PropTypes.ReactNode,
value: `<EuiTitle>
<h4>Hello world</h4>
</EuiTitle>`,
hidden: false,
};

return {
config: {
componentName: 'EuiSkeletonTitle',
props: propsToUse,
scope: {
EuiSkeletonTitle,
EuiTitle,
},
imports: {
'@elastic/eui': {
named: ['EuiSkeletonTitle', 'EuiTitle'],
},
},
},
};
};

export const skeletonCircleConfig = () => {
const docgenInfo = Array.isArray(EuiSkeletonCircle.__docgenInfo)
? EuiSkeletonCircle.__docgenInfo[0]
: EuiSkeletonCircle.__docgenInfo;
const propsToUse = propUtilityForPlayground(docgenInfo.props);

propsToUse.children = {
...propsToUse.children,
type: PropTypes.ReactNode,
value: '<EuiAvatar name="Hello World" />',
hidden: false,
};

return {
config: {
componentName: 'EuiSkeletonCircle',
props: propsToUse,
scope: {
EuiSkeletonCircle,
EuiAvatar,
},
imports: {
'@elastic/eui': {
named: ['EuiSkeletonCircle', 'EuiAvatar'],
},
},
},
};
};

export const skeletonRectangleConfig = () => {
const docgenInfo = Array.isArray(EuiSkeletonRectangle.__docgenInfo)
? EuiSkeletonRectangle.__docgenInfo[0]
: EuiSkeletonRectangle.__docgenInfo;
const propsToUse = propUtilityForPlayground(docgenInfo.props);

propsToUse.width = {
...propsToUse.value,
type: PropTypes.String,
value: '24px',
};
propsToUse.height = {
...propsToUse.value,
type: PropTypes.String,
value: '24px',
};

propsToUse.children = {
...propsToUse.children,
type: PropTypes.ReactNode,
value: '<EuiPanel color="subdued" />',
hidden: false,
};

return {
config: {
componentName: 'EuiSkeletonRectangle',
props: propsToUse,
scope: {
EuiSkeletonRectangle,
EuiPanel,
},
imports: {
'@elastic/eui': {
named: ['EuiSkeletonRectangle', 'EuiPanel'],
},
},
},
};
};
66 changes: 66 additions & 0 deletions src-docs/src/views/skeleton/skeleton_circle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React, { useState } from 'react';

import {
EuiSkeletonCircle,
EuiAvatar,
EuiFlexGroup,
EuiFlexItem,
EuiSwitch,
EuiSpacer,
} from '../../../../src/components';

export default () => {
const [isLoading, setIsLoading] = useState(true);

return (
<>
<EuiSwitch
label="Toggle loaded state"
checked={isLoading}
onChange={() => setIsLoading(!isLoading)}
/>
<EuiSpacer />
<EuiFlexGroup responsive={false} gutterSize="s" alignItems="center">
<EuiFlexItem grow={false}>
<EuiSkeletonCircle
size="s"
isLoading={isLoading}
contentAriaLabel="Demo skeleton avatar"
>
<EuiAvatar size="s" name="Raphael" />
</EuiSkeletonCircle>
</EuiFlexItem>

<EuiFlexItem grow={false}>
<EuiSkeletonCircle
size="m"
isLoading={isLoading}
contentAriaLabel="Demo skeleton avatar"
>
<EuiAvatar size="m" name="Donatello" />
</EuiSkeletonCircle>
</EuiFlexItem>

<EuiFlexItem grow={false}>
<EuiSkeletonCircle
size="l"
isLoading={isLoading}
contentAriaLabel="Demo skeleton avatar"
>
<EuiAvatar size="l" name="Leonardo" />
</EuiSkeletonCircle>
</EuiFlexItem>

<EuiFlexItem grow={false}>
<EuiSkeletonCircle
size="xl"
isLoading={isLoading}
contentAriaLabel="Demo skeleton avatar"
>
<EuiAvatar size="xl" name="Michelangelo" />
</EuiSkeletonCircle>
</EuiFlexItem>
</EuiFlexGroup>
</>
);
};
Loading

0 comments on commit a8de8df

Please sign in to comment.