diff --git a/packages/grafana-ui/src/components/BigValue/BigValue.mdx b/packages/grafana-ui/src/components/BigValue/BigValue.mdx index d9a83cd0c08..b76c0f7baca 100644 --- a/packages/grafana-ui/src/components/BigValue/BigValue.mdx +++ b/packages/grafana-ui/src/components/BigValue/BigValue.mdx @@ -42,14 +42,7 @@ An example usage is in the [Stat panel](https://grafana.com/docs/grafana/latest/ ```tsx import { DisplayValue } from '@grafana/data'; -import { - BigValue, - BigValueColorMode, - BigValueGraphMode, - BigValueJustifyMode, - BigValueTextMode, - useTheme, -} from '@grafana/ui'; +import { BigValue, BigValueColorMode, BigValueJustifyMode, BigValueTextMode, useTheme } from '@grafana/ui'; const bigValue: DisplayValue = { color: 'red', @@ -62,7 +55,6 @@ return ( = ({ width={width} height={height} colorMode={colorMode} - graphMode={graphMode} textMode={textMode} justifyMode={justifyMode} value={{ @@ -109,6 +108,18 @@ export const ApplyNoValue: StoryFn = ({ ); }; +ApplyNoValue.args = { + valueText: '$5022', + title: 'Total Earnings', + colorMode: BigValueColorMode.Value, + graphMode: BigValueGraphMode.Area, + justifyMode: BigValueJustifyMode.Auto, + width: 400, + height: 300, + color: 'red', + textMode: BigValueTextMode.Auto, +}; + export const Basic: StoryFn = ({ valueText, title, @@ -137,7 +148,6 @@ export const Basic: StoryFn = ({ width={width} height={height} colorMode={colorMode} - graphMode={graphMode} textMode={textMode} justifyMode={justifyMode} value={{ @@ -163,14 +173,53 @@ Basic.args = { textMode: BigValueTextMode.Auto, }; -ApplyNoValue.args = { +export const Flexible: StoryFn = ({ + valueText, + title, + colorMode, + graphMode, + height, + width, + color, + textMode, + justifyMode, +}) => { + const theme = useTheme2(); + const sparkline: FieldSparkline = { + y: { + name: '', + values: [1, 2, 3, 4, 3], + type: FieldType.number, + state: { range: { min: 1, max: 4, delta: 3 } }, + config: {}, + }, + }; + + return ( + + ); +}; + +Flexible.args = { valueText: '$5022', title: 'Total Earnings', colorMode: BigValueColorMode.Value, graphMode: BigValueGraphMode.Area, justifyMode: BigValueJustifyMode.Auto, - width: 400, - height: 300, color: 'red', textMode: BigValueTextMode.Auto, }; diff --git a/packages/grafana-ui/src/components/BigValue/BigValue.test.tsx b/packages/grafana-ui/src/components/BigValue/BigValue.test.tsx index d69bc2d2635..2237ab9044f 100644 --- a/packages/grafana-ui/src/components/BigValue/BigValue.test.tsx +++ b/packages/grafana-ui/src/components/BigValue/BigValue.test.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react'; import { createTheme } from '@grafana/data'; -import { BigValue, BigValueColorMode, BigValueGraphMode, Props } from './BigValue'; +import { BigValue, BigValueColorMode, BigValueProps } from './BigValue'; const valueObject = { text: '25', @@ -10,10 +10,9 @@ const valueObject = { color: 'red', }; -function getProps(propOverrides?: Partial): Props { - const props: Props = { +function getProps(propOverrides?: Partial): BigValueProps { + const props: BigValueProps = { colorMode: BigValueColorMode.Background, - graphMode: BigValueGraphMode.Line, height: 300, width: 300, value: valueObject, diff --git a/packages/grafana-ui/src/components/BigValue/BigValue.tsx b/packages/grafana-ui/src/components/BigValue/BigValue.tsx index 870d350ba95..3fb371c0e95 100644 --- a/packages/grafana-ui/src/components/BigValue/BigValue.tsx +++ b/packages/grafana-ui/src/components/BigValue/BigValue.tsx @@ -1,5 +1,6 @@ import { cx } from '@emotion/css'; import { memo, type MouseEventHandler } from 'react'; +import { useMeasure } from 'react-use'; import { DisplayValue, DisplayValueAlignmentFactors, FieldSparkline } from '@grafana/data'; import { PercentChangeColorMode, VizTextDisplayOptions } from '@grafana/schema'; @@ -18,6 +19,7 @@ export enum BigValueColorMode { Value = 'value', } +/** @deprecated use `sparkline` to configure the graph */ export enum BigValueGraphMode { None = 'none', Line = 'line', @@ -40,11 +42,11 @@ export enum BigValueTextMode { None = 'none', } -export interface Props extends Themeable2 { +export interface BigValueProps extends Themeable2 { /** Height of the component */ - height: number; + height?: number; /** Width of the component */ - width: number; + width?: number; /** Value displayed as Big Value */ value: DisplayValue; /** Sparkline values for showing a graph under/behind the value */ @@ -55,8 +57,6 @@ export interface Props extends Themeable2 { className?: string; /** Color mode for coloring the value or the background */ colorMode: BigValueColorMode; - /** Show a graph behind/under the value */ - graphMode: BigValueGraphMode; /** Auto justify value and text or center it */ justifyMode?: BigValueJustifyMode; /** Factors that should influence the positioning of the text */ @@ -80,6 +80,9 @@ export interface Props extends Themeable2 { * Disable the wide layout for the BigValue */ disableWideLayout?: boolean; + + /** @deprecated use `sparkline` to configure the graph */ + graphMode?: BigValueGraphMode; } /** @@ -87,10 +90,22 @@ export interface Props extends Themeable2 { * * https://developers.grafana.com/ui/latest/index.html?path=/docs/plugins-bigvalue--docs */ -export const BigValue = memo((props) => { - const { onClick, className, hasLinks, theme, justifyMode = BigValueJustifyMode.Auto } = props; +export const BigValue = memo((props) => { + const { + onClick, + className, + hasLinks, + theme, + justifyMode = BigValueJustifyMode.Auto, + height: propsHeight, + width: propsWidth, + } = props; + const [wrapperRef, { width: calcWidth, height: calcHeight }] = useMeasure(); - const layout = buildLayout({ ...props, justifyMode }); + const height = propsHeight ?? calcHeight; + const width = propsWidth ?? calcWidth; + + const layout = buildLayout({ ...props, justifyMode, height, width }); const panelStyles = layout.getPanelStyles(); const valueAndTitleContainerStyles = layout.getValueAndTitleContainerStyles(); const valueStyles = layout.getValueStyles(); @@ -105,7 +120,7 @@ export const BigValue = memo((props) => { if (!onClick) { return ( -
+
{textValues.title &&
{textValues.title}
} @@ -129,7 +144,7 @@ export const BigValue = memo((props) => { onClick={onClick} title={tooltip} > -
+
{textValues.title &&
{textValues.title}
}
diff --git a/packages/grafana-ui/src/components/BigValue/BigValueLayout.test.tsx b/packages/grafana-ui/src/components/BigValue/BigValueLayout.test.tsx index 462e1f5e3dd..004f96d04ef 100644 --- a/packages/grafana-ui/src/components/BigValue/BigValueLayout.test.tsx +++ b/packages/grafana-ui/src/components/BigValue/BigValueLayout.test.tsx @@ -3,19 +3,19 @@ import { CSSProperties } from 'react'; import { createTheme, FieldType } from '@grafana/data'; import { PercentChangeColorMode } from '@grafana/schema'; -import { Props, BigValueColorMode, BigValueGraphMode, BigValueTextMode } from './BigValue'; +import { BigValueProps, BigValueColorMode, BigValueTextMode } from './BigValue'; import { buildLayout, getPercentChangeColor, StackedWithChartLayout, StackedWithNoChartLayout, WideWithChartLayout, + BigValuePropsWithHeightAndWidth, } from './BigValueLayout'; -function getProps(propOverrides?: Partial): Props { - const props: Props = { +function getProps(propOverrides?: Partial): BigValuePropsWithHeightAndWidth { + const props: BigValuePropsWithHeightAndWidth = { colorMode: BigValueColorMode.Background, - graphMode: BigValueGraphMode.Area, height: 300, width: 300, value: { @@ -105,7 +105,7 @@ describe('BigValueLayout', () => { ['wide layout', {}], ['non-wide layout', { disableWideLayout: true }], ])('should shrink the value if percent change is shown for %s', (_, propsOverride) => { - const baseProps: Partial = { + const baseProps: Partial = { width: 300, height: 100, sparkline: undefined, diff --git a/packages/grafana-ui/src/components/BigValue/BigValueLayout.tsx b/packages/grafana-ui/src/components/BigValue/BigValueLayout.tsx index 8eee4b3ad12..0585747a28e 100644 --- a/packages/grafana-ui/src/components/BigValue/BigValueLayout.tsx +++ b/packages/grafana-ui/src/components/BigValue/BigValueLayout.tsx @@ -9,13 +9,15 @@ import { getTextColorForAlphaBackground } from '../../utils/colors'; import { calculateFontSize } from '../../utils/measureText'; import { Sparkline } from '../Sparkline/Sparkline'; -import { BigValueColorMode, Props, BigValueJustifyMode, BigValueTextMode } from './BigValue'; +import { BigValueColorMode, BigValueProps, BigValueJustifyMode, BigValueTextMode } from './BigValue'; import { percentChangeString } from './PercentChange'; const LINE_HEIGHT = 1.2; const MAX_TITLE_SIZE = 30; const VALUE_FONT_WEIGHT = 500; +export type BigValuePropsWithHeightAndWidth = BigValueProps & Required>; + export abstract class BigValueLayout { titleFontSize: number; valueFontSize: number; @@ -31,7 +33,7 @@ export abstract class BigValueLayout { maxTextHeight: number; textValues: BigValueTextValues; - constructor(private props: Props) { + constructor(private props: BigValuePropsWithHeightAndWidth) { const { width, height, value, text } = props; this.valueColor = value.color ?? 'gray'; @@ -288,7 +290,7 @@ export abstract class BigValueLayout { } export class WideNoChartLayout extends BigValueLayout { - constructor(props: Props) { + constructor(props: BigValuePropsWithHeightAndWidth) { super(props); const valueWidthPercent = this.titleToAlignTo?.length ? 0.3 : 1.0; @@ -350,7 +352,7 @@ export class WideNoChartLayout extends BigValueLayout { } export class WideWithChartLayout extends BigValueLayout { - constructor(props: Props) { + constructor(props: BigValuePropsWithHeightAndWidth) { super(props); const { width, height } = props; @@ -406,7 +408,7 @@ export class WideWithChartLayout extends BigValueLayout { } export class StackedWithChartLayout extends BigValueLayout { - constructor(props: Props) { + constructor(props: BigValuePropsWithHeightAndWidth) { super(props); const { width, height } = props; @@ -464,7 +466,7 @@ export class StackedWithChartLayout extends BigValueLayout { } export class StackedWithNoChartLayout extends BigValueLayout { - constructor(props: Props) { + constructor(props: BigValuePropsWithHeightAndWidth) { super(props); const { height } = props; @@ -523,7 +525,7 @@ export class StackedWithNoChartLayout extends BigValueLayout { } } -export function buildLayout(props: Props): BigValueLayout { +export function buildLayout(props: BigValuePropsWithHeightAndWidth): BigValueLayout { const { width, height, sparkline } = props; const useWideLayout = width / height > 2.5 && !props.disableWideLayout; @@ -557,7 +559,7 @@ export interface BigValueTextValues extends DisplayValue { tooltip?: string; } -function getTextValues(props: Props): BigValueTextValues { +function getTextValues(props: BigValuePropsWithHeightAndWidth): BigValueTextValues { const { value, alignmentFactors, count } = props; let { textMode } = props;