diff --git a/packages/grafana-ui/src/components/Icon/Icon.tsx b/packages/grafana-ui/src/components/Icon/Icon.tsx index 8920290a259..b0388e6da11 100644 --- a/packages/grafana-ui/src/components/Icon/Icon.tsx +++ b/packages/grafana-ui/src/components/Icon/Icon.tsx @@ -58,14 +58,7 @@ export const Icon = React.forwardRef( width={svgWid} height={svgHgt} title={title} - className={cx( - styles.icon, - { - 'fa-spin': iconName === 'spinner', - }, - className, - type === 'mono' ? { [styles.orange]: name === 'favorite' } : '' - )} + className={cx(styles.icon, className, type === 'mono' ? { [styles.orange]: name === 'favorite' } : '')} style={style} {...rest} /> diff --git a/packages/grafana-ui/src/components/Spinner/Spinner.story.tsx b/packages/grafana-ui/src/components/Spinner/Spinner.story.tsx index 31bc76c83a8..99b4a0a547d 100644 --- a/packages/grafana-ui/src/components/Spinner/Spinner.story.tsx +++ b/packages/grafana-ui/src/components/Spinner/Spinner.story.tsx @@ -49,7 +49,7 @@ export const Basic: Story = (args) => { Basic.args = { backgroundColor: 'white', color: 'red', - size: 34, + size: 'xl', withStyle: false, }; diff --git a/packages/grafana-ui/src/components/Spinner/Spinner.tsx b/packages/grafana-ui/src/components/Spinner/Spinner.tsx index a6a68d5cccc..6867bdde0c2 100644 --- a/packages/grafana-ui/src/components/Spinner/Spinner.tsx +++ b/packages/grafana-ui/src/components/Spinner/Spinner.tsx @@ -1,34 +1,108 @@ import { cx, css } from '@emotion/css'; import React from 'react'; +import SVG from 'react-inlinesvg'; -import { stylesFactory } from '../../themes'; -import { Icon } from '../Icon/Icon'; +import { GrafanaTheme2 } from '@grafana/data'; -const getStyles = stylesFactory((size: number | string, inline: boolean) => { - return css([ - { - fontSize: typeof size === 'string' ? size : `${size}px`, - }, - inline && { display: 'inline-block' }, - ]); -}); +import { useStyles2 } from '../../themes'; +import { IconSize, isIconSize } from '../../types'; +import { Icon } from '../Icon/Icon'; +import { getIconRoot, getIconSubDir } from '../Icon/utils'; -export type Props = { +export interface Props { className?: string; style?: React.CSSProperties; iconClassName?: string; inline?: boolean; + size?: IconSize; +} + +/** + * @deprecated + * use a predefined size, e.g. 'md' or 'lg' instead + */ +interface PropsWithDeprecatedSize extends Omit { size?: number | string; -}; +} /** * @public */ -export const Spinner = ({ className, inline = false, iconClassName, style, size = 16 }: Props) => { - const styles = getStyles(size, inline); +export const Spinner = ({ + className, + inline = false, + iconClassName, + style, + size = 'md', +}: Props | PropsWithDeprecatedSize) => { + const styles = useStyles2(getStyles); + + const deprecatedStyles = useStyles2(getDeprecatedStyles, size); + + // this entire if statement is handling the deprecated size prop + // TODO remove once we fully remove the deprecated type + if (typeof size !== 'string' || !isIconSize(size)) { + const iconRoot = getIconRoot(); + const iconName = 'spinner'; + const subDir = getIconSubDir(iconName, 'default'); + const svgPath = `${iconRoot}${subDir}/${iconName}.svg`; + return ( +
+ +
+ ); + } + return ( -
- +
+
); }; + +const getStyles = (theme: GrafanaTheme2) => ({ + inline: css({ + display: 'inline-block', + }), +}); + +// TODO remove once we fully remove the deprecated type +const getDeprecatedStyles = (theme: GrafanaTheme2, size: number | string) => ({ + wrapper: css({ + fontSize: typeof size === 'string' ? size : `${size}px`, + }), + icon: css({ + display: 'inline-block', + fill: 'currentColor', + flexShrink: 0, + label: 'Icon', + // line-height: 0; is needed for correct icon alignment in Safari + lineHeight: 0, + verticalAlign: 'middle', + }), +}); diff --git a/packages/grafana-ui/src/types/icon.ts b/packages/grafana-ui/src/types/icon.ts index f383e120002..5fdf4d3661a 100644 --- a/packages/grafana-ui/src/types/icon.ts +++ b/packages/grafana-ui/src/types/icon.ts @@ -8,6 +8,9 @@ export { toIconName } from '@grafana/data'; export type IconType = 'mono' | 'default' | 'solid'; export type IconSize = ComponentSize | 'xl' | 'xxl' | 'xxxl'; +export const isIconSize = (value: string): value is IconSize => { + return ['xs', 'sm', 'md', 'lg', 'xl', 'xxl', 'xxxl'].includes(value); +}; // function remains for backwards compatibility export const getAvailableIcons = () => Object.keys(availableIconsIndex); diff --git a/public/app/core/components/RolePicker/RolePicker.tsx b/public/app/core/components/RolePicker/RolePicker.tsx index 185d86187ff..41592ae22a0 100644 --- a/public/app/core/components/RolePicker/RolePicker.tsx +++ b/public/app/core/components/RolePicker/RolePicker.tsx @@ -156,7 +156,7 @@ export const RolePicker = ({ return (
Loading... - +
); } diff --git a/public/app/features/alerting/unified/components/rules/CloudRules.tsx b/public/app/features/alerting/unified/components/rules/CloudRules.tsx index 08e17437649..398fcea48b9 100644 --- a/public/app/features/alerting/unified/components/rules/CloudRules.tsx +++ b/public/app/features/alerting/unified/components/rules/CloudRules.tsx @@ -77,7 +77,7 @@ export const CloudRules = ({ namespaces, expandAll }: Props) => { {!hasDataSourcesConfigured &&

There are no Prometheus or Loki data sources configured.

} {hasDataSourcesConfigured && !hasDataSourcesLoading && !hasNamespaces &&

No rules found.

} - {!hasSomeResults && hasDataSourcesLoading && } + {!hasSomeResults && hasDataSourcesLoading && } { /> ))} {hasResult && namespacesFormat?.length === 0 &&

No rules found.

} - {!hasResult && loading && } + {!hasResult && loading && } - {isFirstHistoryEntry && } + {isFirstHistoryEntry && } {!hasHistory && ( - +
) : (
diff --git a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.tsx b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.tsx index 9237ad5c5e9..746885fa058 100644 --- a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.tsx +++ b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.tsx @@ -20,7 +20,7 @@ const Loader = () => { <> Loading configuration - + ); diff --git a/public/app/features/manage-dashboards/DashboardImportPage.tsx b/public/app/features/manage-dashboards/DashboardImportPage.tsx index 9e9561f4407..16266303ca3 100644 --- a/public/app/features/manage-dashboards/DashboardImportPage.tsx +++ b/public/app/features/manage-dashboards/DashboardImportPage.tsx @@ -238,7 +238,7 @@ class UnthemedDashboardImport extends PureComponent { {loadingState === LoadingState.Loading && ( - + )} diff --git a/public/app/features/plugins/sql/components/query-editor-raw/QueryValidator.tsx b/public/app/features/plugins/sql/components/query-editor-raw/QueryValidator.tsx index df8de15c515..0cbad6702a8 100644 --- a/public/app/features/plugins/sql/components/query-editor-raw/QueryValidator.tsx +++ b/public/app/features/plugins/sql/components/query-editor-raw/QueryValidator.tsx @@ -79,7 +79,7 @@ export function QueryValidator({ db, query, onValidate, range }: QueryValidatorP <> {state.loading && (
- Validating query... + Validating query...
)} {!state.loading && state.value && ( diff --git a/public/app/features/variables/inspect/VariablesUnknownTable.tsx b/public/app/features/variables/inspect/VariablesUnknownTable.tsx index b1d0a95d562..1c7e68f552c 100644 --- a/public/app/features/variables/inspect/VariablesUnknownTable.tsx +++ b/public/app/features/variables/inspect/VariablesUnknownTable.tsx @@ -58,7 +58,7 @@ export function VariablesUnknownTable({ variables, dashboard }: VariablesUnknown Loading... - + )} diff --git a/public/app/plugins/panel/gettingstarted/GettingStarted.tsx b/public/app/plugins/panel/gettingstarted/GettingStarted.tsx index 2a1351dc0fe..19753cabb63 100644 --- a/public/app/plugins/panel/gettingstarted/GettingStarted.tsx +++ b/public/app/plugins/panel/gettingstarted/GettingStarted.tsx @@ -86,7 +86,7 @@ export class GettingStarted extends PureComponent { {!checksDone ? (
Checking completed setup steps
- +
) : ( <>