diff --git a/packages/grafana-ui/src/components/LoadingBar/LoadingBar.story.tsx b/packages/grafana-ui/src/components/LoadingBar/LoadingBar.story.tsx new file mode 100644 index 00000000000..ae86ba742ae --- /dev/null +++ b/packages/grafana-ui/src/components/LoadingBar/LoadingBar.story.tsx @@ -0,0 +1,45 @@ +import { action } from '@storybook/addon-actions'; +import { ComponentMeta, ComponentStory } from '@storybook/react'; +import React, { CSSProperties, useState, ReactNode } from 'react'; + +import { LoadingBar, LoadingBarProps } from '@grafana/ui'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +const meta: ComponentMeta = { + title: 'General/LoadingBar', + component: LoadingBar, + decorators: [withCenteredStory], + parameters: { + controls: {}, + docs: {}, + }, +}; + +function getContentStyle(): CSSProperties { + return { + backgroundColor: '#181B1F', + width: '400px', + height: '200px', + border: '1px solid rgba(204, 204, 220, 0.25)', + borderRadius: '1px', + }; +} + +export const Basic: ComponentStory = (args: LoadingBarProps) => { + const contentStyle = getContentStyle(); + + return ( +
+ +
+ ); +}; + +Basic.args = { + width: 128, + height: 2, + containerWidth: 400, +}; + +export default meta; diff --git a/packages/grafana-ui/src/components/LoadingBar/LoadingBar.tsx b/packages/grafana-ui/src/components/LoadingBar/LoadingBar.tsx index 6d7c7305955..4a5f939f148 100644 --- a/packages/grafana-ui/src/components/LoadingBar/LoadingBar.tsx +++ b/packages/grafana-ui/src/components/LoadingBar/LoadingBar.tsx @@ -1,21 +1,17 @@ -import { css } from '@emotion/css'; -import React, { CSSProperties, ReactNode } from 'react'; +import { css, keyframes } from '@emotion/css'; +import React from 'react'; import { GrafanaTheme2 } from '@grafana/data'; -import { useStyles2, useTheme2 } from '../../themes'; -import { IconName } from '../../types/icon'; -import { Dropdown } from '../Dropdown/Dropdown'; -import { Icon } from '../Icon/Icon'; -import { IconButton, IconButtonVariant } from '../IconButton/IconButton'; -import { PopoverContent, Tooltip } from '../Tooltip'; +import { useTheme2 } from '../../themes'; /** * @internal */ export interface LoadingBarProps { - width: number; - height: number; + containerWidth: number; + width?: number; + height?: number; ariaLabel?: string; barColor?: string; } @@ -24,25 +20,41 @@ export interface LoadingBarProps { * @internal */ export const LoadingBar: React.FC = ({ + containerWidth, width, height, ariaLabel = 'Loading bar', barColor = 'blue', }) => { const theme = useTheme2(); - const loadingStyles = getLoadingStyes(theme, width, height) - return
; + const loadingStyles = getLoadingStyes(theme, containerWidth, width, height, barColor); + return
; }; -const getLoadingStyes = (theme: GrafanaTheme2, width, height) => { +const getLoadingStyes = ( + theme: GrafanaTheme2, + containerWidth: number, + width?: number, + height?: number, + barColor?: string +) => { + const loadingWidth = width ?? 128; + const loadingAnimation = keyframes({ + '0%': { + transform: 'translateX(0)', + }, + '100%': { + transform: `translateX(${containerWidth - loadingWidth}px)`, + }, + }); return { - loading: css ({ - width: "80px", - height: "10px", - backgroundColor: "blue"; - position: "absolute"; - animation: animate 1s infinite linear; - willChange: transform;:w - }) - }; + loading: css({ + width: `${loadingWidth}px`, + height: `${height ?? 2}px`, + background: 'linear-gradient(90deg, rgba(110, 159, 255, 0) 0%, #6E9FFF 80.75%, rgba(110, 159, 255, 0) 100%)', + position: 'absolute', + animation: `${loadingAnimation} 2s infinite linear`, + willChange: 'transform', + }), + }; }; diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx index 685261d1870..6b989b3f98f 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx @@ -8,6 +8,7 @@ import { IconName } from '../../types/icon'; import { Dropdown } from '../Dropdown/Dropdown'; import { Icon } from '../Icon/Icon'; import { IconButton, IconButtonVariant } from '../IconButton/IconButton'; +import { LoadingBar } from '../LoadingBar/LoadingBar'; import { PopoverContent, Tooltip } from '../Tooltip'; /** @@ -88,6 +89,7 @@ export const PanelChrome: React.FC = ({ return (
+ {hasHeader && !hoverHeader && (
{title && ( diff --git a/packages/grafana-ui/src/components/index.ts b/packages/grafana-ui/src/components/index.ts index be1987ed037..0bb4c5a62bc 100644 --- a/packages/grafana-ui/src/components/index.ts +++ b/packages/grafana-ui/src/components/index.ts @@ -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';