Grafana/ui: Create new LoadingBar component (#59508)

* dashboards squad mob! 🔱

lastFile:packages/grafana-ui/src/components/LoadingBar/LoadingBar.tsx

* dashboards squad mob! 🔱

* dashboards squad mob! 🔱

lastFile:packages/grafana-ui/src/components/LoadingBar/LoadingBar.tsx

* user essentials mob! 🔱

* create grafana/ui LoadingBar and set it up in Storybook

* Remove test changes on PanelChrome

* Fix mdx page reference

* make LoadingBar a simple JSX Element; do not use containerWidth; have a wrapper around the loading bar itself;

* fix wrapper around LoadingBar: willChange css prop makes performance of rerendering better

* moving the LoadingBar to core

* Revert "moving the LoadingBar to core"

This reverts commit 11f0f4ff2f.

* do not use internal comment as it doesn't do anything

* Modify annimation to 1 second

Co-authored-by: Alexandra Vargas <alexa1866@gmail.com>
This commit is contained in:
Polina Boneva 2022-12-12 17:16:03 +02:00 committed by GitHub
parent 4374966987
commit be57419540
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 128 additions and 0 deletions

View File

@ -0,0 +1,22 @@
import { Meta, Preview, ArgsTable } from '@storybook/addon-docs/blocks';
import { LoadingBar } from './LoadingBar';
<Meta title="MDX|LoadingBar" component={LoadingBar} />
# LoadingBar
The LoadingBar is used as a simple loading slider animation in the top of its container.
<Preview>
<div style={{ height: '200px', width: '400px' }}>
<LoadingBar containerWidth={400} height={2} width={128} />
</div>
</Preview>
```jsx
<div style={{ height: '200px', width: '400px' }}>
<LoadingBar containerWidth={400} height={2} width={128} />
</div>
```
<ArgsTable of={LoadingBar} />

View File

@ -0,0 +1,56 @@
import { css } from '@emotion/css';
import { ComponentMeta, ComponentStory } from '@storybook/react';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { LoadingBar, LoadingBarProps, useStyles2 } from '@grafana/ui';
import { DashboardStoryCanvas } from '../../utils/storybook/DashboardStoryCanvas';
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
import mdx from './LoadingBar.mdx';
const meta: ComponentMeta<typeof LoadingBar> = {
title: 'General/LoadingBar',
component: LoadingBar,
decorators: [withCenteredStory],
parameters: {
controls: {},
docs: {
page: mdx,
},
},
};
const getStyles = (theme: GrafanaTheme2) => {
const { borderColor } = theme.components.panel;
return {
container: css({
label: 'placeholder-container',
width: '400px',
height: '200px',
border: `1px solid ${borderColor}`,
borderRadius: '3px',
}),
};
};
export const Basic: ComponentStory<typeof LoadingBar> = (args: LoadingBarProps) => {
const styles = useStyles2(getStyles);
return (
<DashboardStoryCanvas>
<div className={styles.container}>
<LoadingBar {...args} />
</div>
</DashboardStoryCanvas>
);
};
Basic.args = {
width: '128px',
height: '2px',
};
export default meta;

View File

@ -0,0 +1,49 @@
import { css, keyframes } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '../../themes';
export interface LoadingBarProps {
width?: string;
height?: string;
ariaLabel?: string;
}
export function LoadingBar({ width, height, ariaLabel = 'Loading bar' }: LoadingBarProps) {
const styles = useStyles2(getStyles(width, height));
return (
<div className={styles.container}>
<div aria-label={ariaLabel} className={styles.bar} />
</div>
);
}
const getStyles = (width?: string, height?: string) => (_: GrafanaTheme2) => {
const barWidth = width ?? '128px';
const loadingHeigth = height ?? '2px';
const loadingAnimation = keyframes({
'0%': {
transform: 'translateX(0)',
},
'100%': {
transform: `translateX(calc(100% - ${barWidth}))`,
},
});
return {
container: css({
width: '100%',
animation: `${loadingAnimation} 1s infinite linear`,
willChange: 'transform',
}),
bar: css({
width: barWidth,
height: loadingHeigth,
background: 'linear-gradient(90deg, rgba(110, 159, 255, 0) 0%, #6E9FFF 80.75%, rgba(110, 159, 255, 0) 100%)',
}),
};
};

View File

@ -24,6 +24,7 @@ export { ButtonCascader } from './ButtonCascader/ButtonCascader';
export { InlineToast } from './InlineToast/InlineToast';
export { LoadingPlaceholder, type LoadingPlaceholderProps } from './LoadingPlaceholder/LoadingPlaceholder';
export { LoadingBar, type LoadingBarProps } from './LoadingBar/LoadingBar';
export { ColorPicker, SeriesColorPicker } from './ColorPicker/ColorPicker';
export { ColorPickerInput } from './ColorPicker/ColorPickerInput';
export { SeriesColorPickerPopover, SeriesColorPickerPopoverWithTheme } from './ColorPicker/SeriesColorPickerPopover';